xref: /freebsd-src/stand/ficl/float.c (revision 2a63c3be158216222d89a073dcbd6a72ee4aab5a)
1ca987d46SWarner Losh /*******************************************************************
2ca987d46SWarner Losh ** f l o a t . c
3ca987d46SWarner Losh ** Forth Inspired Command Language
4ca987d46SWarner Losh ** ANS Forth FLOAT word-set written in C
5ca987d46SWarner Losh ** Author: Guy Carver & John Sadler (john_sadler@alum.mit.edu)
6ca987d46SWarner Losh ** Created: Apr 2001
7ca987d46SWarner Losh ** $Id: float.c,v 1.8 2001/12/05 07:21:34 jsadler Exp $
8ca987d46SWarner Losh *******************************************************************/
9ca987d46SWarner Losh /*
10ca987d46SWarner Losh ** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
11ca987d46SWarner Losh ** All rights reserved.
12ca987d46SWarner Losh **
13ca987d46SWarner Losh ** Get the latest Ficl release at http://ficl.sourceforge.net
14ca987d46SWarner Losh **
15ca987d46SWarner Losh ** I am interested in hearing from anyone who uses ficl. If you have
16ca987d46SWarner Losh ** a problem, a success story, a defect, an enhancement request, or
17ca987d46SWarner Losh ** if you would like to contribute to the ficl release, please
18ca987d46SWarner Losh ** contact me by email at the address above.
19ca987d46SWarner Losh **
20ca987d46SWarner Losh ** L I C E N S E  and  D I S C L A I M E R
21ca987d46SWarner Losh **
22ca987d46SWarner Losh ** Redistribution and use in source and binary forms, with or without
23ca987d46SWarner Losh ** modification, are permitted provided that the following conditions
24ca987d46SWarner Losh ** are met:
25ca987d46SWarner Losh ** 1. Redistributions of source code must retain the above copyright
26ca987d46SWarner Losh **    notice, this list of conditions and the following disclaimer.
27ca987d46SWarner Losh ** 2. Redistributions in binary form must reproduce the above copyright
28ca987d46SWarner Losh **    notice, this list of conditions and the following disclaimer in the
29ca987d46SWarner Losh **    documentation and/or other materials provided with the distribution.
30ca987d46SWarner Losh **
31ca987d46SWarner Losh ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
32ca987d46SWarner Losh ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33ca987d46SWarner Losh ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34ca987d46SWarner Losh ** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
35ca987d46SWarner Losh ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36ca987d46SWarner Losh ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37ca987d46SWarner Losh ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38ca987d46SWarner Losh ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39ca987d46SWarner Losh ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40ca987d46SWarner Losh ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41ca987d46SWarner Losh ** SUCH DAMAGE.
42ca987d46SWarner Losh */
43ca987d46SWarner Losh 
44ca987d46SWarner Losh 
4565b8a300SWarner Losh #include "ficl.h"
4665b8a300SWarner Losh 
4765b8a300SWarner Losh #if FICL_WANT_FLOAT
48ca987d46SWarner Losh #include <stdlib.h>
49ca987d46SWarner Losh #include <stdio.h>
50ca987d46SWarner Losh #include <string.h>
51ca987d46SWarner Losh #include <ctype.h>
52ca987d46SWarner Losh #include <math.h>
53ca987d46SWarner Losh 
54ca987d46SWarner Losh /*******************************************************************
55ca987d46SWarner Losh ** Do float addition r1 + r2.
56ca987d46SWarner Losh ** f+ ( r1 r2 -- r )
57ca987d46SWarner Losh *******************************************************************/
Fadd(FICL_VM * pVM)58ca987d46SWarner Losh static void Fadd(FICL_VM *pVM)
59ca987d46SWarner Losh {
60ca987d46SWarner Losh     FICL_FLOAT f;
61ca987d46SWarner Losh 
62ca987d46SWarner Losh #if FICL_ROBUST > 1
63ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 1);
64ca987d46SWarner Losh #endif
65ca987d46SWarner Losh 
66ca987d46SWarner Losh     f = POPFLOAT();
67ca987d46SWarner Losh     f += GETTOPF().f;
68ca987d46SWarner Losh     SETTOPF(f);
69ca987d46SWarner Losh }
70ca987d46SWarner Losh 
71ca987d46SWarner Losh /*******************************************************************
72ca987d46SWarner Losh ** Do float subtraction r1 - r2.
73ca987d46SWarner Losh ** f- ( r1 r2 -- r )
74ca987d46SWarner Losh *******************************************************************/
Fsub(FICL_VM * pVM)75ca987d46SWarner Losh static void Fsub(FICL_VM *pVM)
76ca987d46SWarner Losh {
77ca987d46SWarner Losh     FICL_FLOAT f;
78ca987d46SWarner Losh 
79ca987d46SWarner Losh #if FICL_ROBUST > 1
80ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 1);
81ca987d46SWarner Losh #endif
82ca987d46SWarner Losh 
83ca987d46SWarner Losh     f = POPFLOAT();
84ca987d46SWarner Losh     f = GETTOPF().f - f;
85ca987d46SWarner Losh     SETTOPF(f);
86ca987d46SWarner Losh }
87ca987d46SWarner Losh 
88ca987d46SWarner Losh /*******************************************************************
89ca987d46SWarner Losh ** Do float multiplication r1 * r2.
90ca987d46SWarner Losh ** f* ( r1 r2 -- r )
91ca987d46SWarner Losh *******************************************************************/
Fmul(FICL_VM * pVM)92ca987d46SWarner Losh static void Fmul(FICL_VM *pVM)
93ca987d46SWarner Losh {
94ca987d46SWarner Losh     FICL_FLOAT f;
95ca987d46SWarner Losh 
96ca987d46SWarner Losh #if FICL_ROBUST > 1
97ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 1);
98ca987d46SWarner Losh #endif
99ca987d46SWarner Losh 
100ca987d46SWarner Losh     f = POPFLOAT();
101ca987d46SWarner Losh     f *= GETTOPF().f;
102ca987d46SWarner Losh     SETTOPF(f);
103ca987d46SWarner Losh }
104ca987d46SWarner Losh 
105ca987d46SWarner Losh /*******************************************************************
106ca987d46SWarner Losh ** Do float negation.
107ca987d46SWarner Losh ** fnegate ( r -- r )
108ca987d46SWarner Losh *******************************************************************/
Fnegate(FICL_VM * pVM)109ca987d46SWarner Losh static void Fnegate(FICL_VM *pVM)
110ca987d46SWarner Losh {
111ca987d46SWarner Losh     FICL_FLOAT f;
112ca987d46SWarner Losh 
113ca987d46SWarner Losh #if FICL_ROBUST > 1
114ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 1);
115ca987d46SWarner Losh #endif
116ca987d46SWarner Losh 
117ca987d46SWarner Losh     f = -GETTOPF().f;
118ca987d46SWarner Losh     SETTOPF(f);
119ca987d46SWarner Losh }
120ca987d46SWarner Losh 
121ca987d46SWarner Losh /*******************************************************************
122ca987d46SWarner Losh ** Do float division r1 / r2.
123ca987d46SWarner Losh ** f/ ( r1 r2 -- r )
124ca987d46SWarner Losh *******************************************************************/
Fdiv(FICL_VM * pVM)125ca987d46SWarner Losh static void Fdiv(FICL_VM *pVM)
126ca987d46SWarner Losh {
127ca987d46SWarner Losh     FICL_FLOAT f;
128ca987d46SWarner Losh 
129ca987d46SWarner Losh #if FICL_ROBUST > 1
130ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 1);
131ca987d46SWarner Losh #endif
132ca987d46SWarner Losh 
133ca987d46SWarner Losh     f = POPFLOAT();
134ca987d46SWarner Losh     f = GETTOPF().f / f;
135ca987d46SWarner Losh     SETTOPF(f);
136ca987d46SWarner Losh }
137ca987d46SWarner Losh 
138ca987d46SWarner Losh /*******************************************************************
139ca987d46SWarner Losh ** Do float + integer r + n.
140ca987d46SWarner Losh ** f+i ( r n -- r )
141ca987d46SWarner Losh *******************************************************************/
Faddi(FICL_VM * pVM)142ca987d46SWarner Losh static void Faddi(FICL_VM *pVM)
143ca987d46SWarner Losh {
144ca987d46SWarner Losh     FICL_FLOAT f;
145ca987d46SWarner Losh 
146ca987d46SWarner Losh #if FICL_ROBUST > 1
147ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 1);
148ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
149ca987d46SWarner Losh #endif
150ca987d46SWarner Losh 
151ca987d46SWarner Losh     f = (FICL_FLOAT)POPINT();
152ca987d46SWarner Losh     f += GETTOPF().f;
153ca987d46SWarner Losh     SETTOPF(f);
154ca987d46SWarner Losh }
155ca987d46SWarner Losh 
156ca987d46SWarner Losh /*******************************************************************
157ca987d46SWarner Losh ** Do float - integer r - n.
158ca987d46SWarner Losh ** f-i ( r n -- r )
159ca987d46SWarner Losh *******************************************************************/
Fsubi(FICL_VM * pVM)160ca987d46SWarner Losh static void Fsubi(FICL_VM *pVM)
161ca987d46SWarner Losh {
162ca987d46SWarner Losh     FICL_FLOAT f;
163ca987d46SWarner Losh 
164ca987d46SWarner Losh #if FICL_ROBUST > 1
165ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 1);
166ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
167ca987d46SWarner Losh #endif
168ca987d46SWarner Losh 
169ca987d46SWarner Losh     f = GETTOPF().f;
170ca987d46SWarner Losh     f -= (FICL_FLOAT)POPINT();
171ca987d46SWarner Losh     SETTOPF(f);
172ca987d46SWarner Losh }
173ca987d46SWarner Losh 
174ca987d46SWarner Losh /*******************************************************************
175ca987d46SWarner Losh ** Do float * integer r * n.
176ca987d46SWarner Losh ** f*i ( r n -- r )
177ca987d46SWarner Losh *******************************************************************/
Fmuli(FICL_VM * pVM)178ca987d46SWarner Losh static void Fmuli(FICL_VM *pVM)
179ca987d46SWarner Losh {
180ca987d46SWarner Losh     FICL_FLOAT f;
181ca987d46SWarner Losh 
182ca987d46SWarner Losh #if FICL_ROBUST > 1
183ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 1);
184ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
185ca987d46SWarner Losh #endif
186ca987d46SWarner Losh 
187ca987d46SWarner Losh     f = (FICL_FLOAT)POPINT();
188ca987d46SWarner Losh     f *= GETTOPF().f;
189ca987d46SWarner Losh     SETTOPF(f);
190ca987d46SWarner Losh }
191ca987d46SWarner Losh 
192ca987d46SWarner Losh /*******************************************************************
193ca987d46SWarner Losh ** Do float / integer r / n.
194ca987d46SWarner Losh ** f/i ( r n -- r )
195ca987d46SWarner Losh *******************************************************************/
Fdivi(FICL_VM * pVM)196ca987d46SWarner Losh static void Fdivi(FICL_VM *pVM)
197ca987d46SWarner Losh {
198ca987d46SWarner Losh     FICL_FLOAT f;
199ca987d46SWarner Losh 
200ca987d46SWarner Losh #if FICL_ROBUST > 1
201ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 1);
202ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
203ca987d46SWarner Losh #endif
204ca987d46SWarner Losh 
205ca987d46SWarner Losh     f = GETTOPF().f;
206ca987d46SWarner Losh     f /= (FICL_FLOAT)POPINT();
207ca987d46SWarner Losh     SETTOPF(f);
208ca987d46SWarner Losh }
209ca987d46SWarner Losh 
210ca987d46SWarner Losh /*******************************************************************
211ca987d46SWarner Losh ** Do integer - float n - r.
212ca987d46SWarner Losh ** i-f ( n r -- r )
213ca987d46SWarner Losh *******************************************************************/
isubf(FICL_VM * pVM)214ca987d46SWarner Losh static void isubf(FICL_VM *pVM)
215ca987d46SWarner Losh {
216ca987d46SWarner Losh     FICL_FLOAT f;
217ca987d46SWarner Losh 
218ca987d46SWarner Losh #if FICL_ROBUST > 1
219ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 1);
220ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
221ca987d46SWarner Losh #endif
222ca987d46SWarner Losh 
223ca987d46SWarner Losh     f = (FICL_FLOAT)POPINT();
224ca987d46SWarner Losh     f -= GETTOPF().f;
225ca987d46SWarner Losh     SETTOPF(f);
226ca987d46SWarner Losh }
227ca987d46SWarner Losh 
228ca987d46SWarner Losh /*******************************************************************
229ca987d46SWarner Losh ** Do integer / float n / r.
230ca987d46SWarner Losh ** i/f ( n r -- r )
231ca987d46SWarner Losh *******************************************************************/
idivf(FICL_VM * pVM)232ca987d46SWarner Losh static void idivf(FICL_VM *pVM)
233ca987d46SWarner Losh {
234ca987d46SWarner Losh     FICL_FLOAT f;
235ca987d46SWarner Losh 
236ca987d46SWarner Losh #if FICL_ROBUST > 1
237ca987d46SWarner Losh     vmCheckFStack(pVM, 1,1);
238ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
239ca987d46SWarner Losh #endif
240ca987d46SWarner Losh 
241ca987d46SWarner Losh     f = (FICL_FLOAT)POPINT();
242ca987d46SWarner Losh     f /= GETTOPF().f;
243ca987d46SWarner Losh     SETTOPF(f);
244ca987d46SWarner Losh }
245ca987d46SWarner Losh 
246ca987d46SWarner Losh /*******************************************************************
247ca987d46SWarner Losh ** Do integer to float conversion.
248ca987d46SWarner Losh ** int>float ( n -- r )
249ca987d46SWarner Losh *******************************************************************/
itof(FICL_VM * pVM)250ca987d46SWarner Losh static void itof(FICL_VM *pVM)
251ca987d46SWarner Losh {
252ca987d46SWarner Losh     float f;
253ca987d46SWarner Losh 
254ca987d46SWarner Losh #if FICL_ROBUST > 1
255ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
256ca987d46SWarner Losh     vmCheckFStack(pVM, 0, 1);
257ca987d46SWarner Losh #endif
258ca987d46SWarner Losh 
259ca987d46SWarner Losh     f = (float)POPINT();
260ca987d46SWarner Losh     PUSHFLOAT(f);
261ca987d46SWarner Losh }
262ca987d46SWarner Losh 
263ca987d46SWarner Losh /*******************************************************************
264ca987d46SWarner Losh ** Do float to integer conversion.
265ca987d46SWarner Losh ** float>int ( r -- n )
266ca987d46SWarner Losh *******************************************************************/
Ftoi(FICL_VM * pVM)267ca987d46SWarner Losh static void Ftoi(FICL_VM *pVM)
268ca987d46SWarner Losh {
269ca987d46SWarner Losh     FICL_INT i;
270ca987d46SWarner Losh 
271ca987d46SWarner Losh #if FICL_ROBUST > 1
272ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
273ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
274ca987d46SWarner Losh #endif
275ca987d46SWarner Losh 
276ca987d46SWarner Losh     i = (FICL_INT)POPFLOAT();
277ca987d46SWarner Losh     PUSHINT(i);
278ca987d46SWarner Losh }
279ca987d46SWarner Losh 
280ca987d46SWarner Losh /*******************************************************************
281ca987d46SWarner Losh ** Floating point constant execution word.
282ca987d46SWarner Losh *******************************************************************/
FconstantParen(FICL_VM * pVM)283ca987d46SWarner Losh void FconstantParen(FICL_VM *pVM)
284ca987d46SWarner Losh {
285ca987d46SWarner Losh     FICL_WORD *pFW = pVM->runningWord;
286ca987d46SWarner Losh 
287ca987d46SWarner Losh #if FICL_ROBUST > 1
288ca987d46SWarner Losh     vmCheckFStack(pVM, 0, 1);
289ca987d46SWarner Losh #endif
290ca987d46SWarner Losh 
291ca987d46SWarner Losh     PUSHFLOAT(pFW->param[0].f);
292ca987d46SWarner Losh }
293ca987d46SWarner Losh 
294ca987d46SWarner Losh /*******************************************************************
295ca987d46SWarner Losh ** Create a floating point constant.
296ca987d46SWarner Losh ** fconstant ( r -"name"- )
297ca987d46SWarner Losh *******************************************************************/
Fconstant(FICL_VM * pVM)298ca987d46SWarner Losh static void Fconstant(FICL_VM *pVM)
299ca987d46SWarner Losh {
300ca987d46SWarner Losh     FICL_DICT *dp = vmGetDict(pVM);
301ca987d46SWarner Losh     STRINGINFO si = vmGetWord(pVM);
302ca987d46SWarner Losh 
303ca987d46SWarner Losh #if FICL_ROBUST > 1
304ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
305ca987d46SWarner Losh #endif
306ca987d46SWarner Losh 
307ca987d46SWarner Losh     dictAppendWord2(dp, si, FconstantParen, FW_DEFAULT);
308ca987d46SWarner Losh     dictAppendCell(dp, stackPop(pVM->fStack));
309ca987d46SWarner Losh }
310ca987d46SWarner Losh 
311ca987d46SWarner Losh /*******************************************************************
312ca987d46SWarner Losh ** Display a float in decimal format.
313ca987d46SWarner Losh ** f. ( r -- )
314ca987d46SWarner Losh *******************************************************************/
FDot(FICL_VM * pVM)315ca987d46SWarner Losh static void FDot(FICL_VM *pVM)
316ca987d46SWarner Losh {
317ca987d46SWarner Losh     float f;
318ca987d46SWarner Losh 
319ca987d46SWarner Losh #if FICL_ROBUST > 1
320ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
321ca987d46SWarner Losh #endif
322ca987d46SWarner Losh 
323ca987d46SWarner Losh     f = POPFLOAT();
324ca987d46SWarner Losh     sprintf(pVM->pad,"%#f ",f);
325ca987d46SWarner Losh     vmTextOut(pVM, pVM->pad, 0);
326ca987d46SWarner Losh }
327ca987d46SWarner Losh 
328ca987d46SWarner Losh /*******************************************************************
329ca987d46SWarner Losh ** Display a float in engineering format.
330ca987d46SWarner Losh ** fe. ( r -- )
331ca987d46SWarner Losh *******************************************************************/
EDot(FICL_VM * pVM)332ca987d46SWarner Losh static void EDot(FICL_VM *pVM)
333ca987d46SWarner Losh {
334ca987d46SWarner Losh     float f;
335ca987d46SWarner Losh 
336ca987d46SWarner Losh #if FICL_ROBUST > 1
337ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
338ca987d46SWarner Losh #endif
339ca987d46SWarner Losh 
340ca987d46SWarner Losh     f = POPFLOAT();
341ca987d46SWarner Losh     sprintf(pVM->pad,"%#e ",f);
342ca987d46SWarner Losh     vmTextOut(pVM, pVM->pad, 0);
343ca987d46SWarner Losh }
344ca987d46SWarner Losh 
345ca987d46SWarner Losh /**************************************************************************
346ca987d46SWarner Losh                         d i s p l a y FS t a c k
347ca987d46SWarner Losh ** Display the parameter stack (code for "f.s")
348ca987d46SWarner Losh ** f.s ( -- )
349ca987d46SWarner Losh **************************************************************************/
displayFStack(FICL_VM * pVM)350ca987d46SWarner Losh static void displayFStack(FICL_VM *pVM)
351ca987d46SWarner Losh {
352ca987d46SWarner Losh     int d = stackDepth(pVM->fStack);
353ca987d46SWarner Losh     int i;
354ca987d46SWarner Losh     CELL *pCell;
355ca987d46SWarner Losh 
356ca987d46SWarner Losh     vmCheckFStack(pVM, 0, 0);
357ca987d46SWarner Losh 
358ca987d46SWarner Losh     vmTextOut(pVM, "F:", 0);
359ca987d46SWarner Losh 
360ca987d46SWarner Losh     if (d == 0)
361ca987d46SWarner Losh         vmTextOut(pVM, "[0]", 0);
362ca987d46SWarner Losh     else
363ca987d46SWarner Losh     {
364ca987d46SWarner Losh         ltoa(d, &pVM->pad[1], pVM->base);
365ca987d46SWarner Losh         pVM->pad[0] = '[';
366ca987d46SWarner Losh         strcat(pVM->pad,"] ");
367ca987d46SWarner Losh         vmTextOut(pVM,pVM->pad,0);
368ca987d46SWarner Losh 
369ca987d46SWarner Losh         pCell = pVM->fStack->sp - d;
370ca987d46SWarner Losh         for (i = 0; i < d; i++)
371ca987d46SWarner Losh         {
372ca987d46SWarner Losh             sprintf(pVM->pad,"%#f ",(*pCell++).f);
373ca987d46SWarner Losh             vmTextOut(pVM,pVM->pad,0);
374ca987d46SWarner Losh         }
375ca987d46SWarner Losh     }
376ca987d46SWarner Losh }
377ca987d46SWarner Losh 
378ca987d46SWarner Losh /*******************************************************************
379ca987d46SWarner Losh ** Do float stack depth.
380ca987d46SWarner Losh ** fdepth ( -- n )
381ca987d46SWarner Losh *******************************************************************/
Fdepth(FICL_VM * pVM)382ca987d46SWarner Losh static void Fdepth(FICL_VM *pVM)
383ca987d46SWarner Losh {
384ca987d46SWarner Losh     int i;
385ca987d46SWarner Losh 
386ca987d46SWarner Losh #if FICL_ROBUST > 1
387ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
388ca987d46SWarner Losh #endif
389ca987d46SWarner Losh 
390ca987d46SWarner Losh     i = stackDepth(pVM->fStack);
391ca987d46SWarner Losh     PUSHINT(i);
392ca987d46SWarner Losh }
393ca987d46SWarner Losh 
394ca987d46SWarner Losh /*******************************************************************
395ca987d46SWarner Losh ** Do float stack drop.
396ca987d46SWarner Losh ** fdrop ( r -- )
397ca987d46SWarner Losh *******************************************************************/
Fdrop(FICL_VM * pVM)398ca987d46SWarner Losh static void Fdrop(FICL_VM *pVM)
399ca987d46SWarner Losh {
400ca987d46SWarner Losh #if FICL_ROBUST > 1
401ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
402ca987d46SWarner Losh #endif
403ca987d46SWarner Losh 
404ca987d46SWarner Losh     DROPF(1);
405ca987d46SWarner Losh }
406ca987d46SWarner Losh 
407ca987d46SWarner Losh /*******************************************************************
408ca987d46SWarner Losh ** Do float stack 2drop.
409ca987d46SWarner Losh ** f2drop ( r r -- )
410ca987d46SWarner Losh *******************************************************************/
FtwoDrop(FICL_VM * pVM)411ca987d46SWarner Losh static void FtwoDrop(FICL_VM *pVM)
412ca987d46SWarner Losh {
413ca987d46SWarner Losh #if FICL_ROBUST > 1
414ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 0);
415ca987d46SWarner Losh #endif
416ca987d46SWarner Losh 
417ca987d46SWarner Losh     DROPF(2);
418ca987d46SWarner Losh }
419ca987d46SWarner Losh 
420ca987d46SWarner Losh /*******************************************************************
421ca987d46SWarner Losh ** Do float stack dup.
422ca987d46SWarner Losh ** fdup ( r -- r r )
423ca987d46SWarner Losh *******************************************************************/
Fdup(FICL_VM * pVM)424ca987d46SWarner Losh static void Fdup(FICL_VM *pVM)
425ca987d46SWarner Losh {
426ca987d46SWarner Losh #if FICL_ROBUST > 1
427ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 2);
428ca987d46SWarner Losh #endif
429ca987d46SWarner Losh 
430ca987d46SWarner Losh     PICKF(0);
431ca987d46SWarner Losh }
432ca987d46SWarner Losh 
433ca987d46SWarner Losh /*******************************************************************
434ca987d46SWarner Losh ** Do float stack 2dup.
435ca987d46SWarner Losh ** f2dup ( r1 r2 -- r1 r2 r1 r2 )
436ca987d46SWarner Losh *******************************************************************/
FtwoDup(FICL_VM * pVM)437ca987d46SWarner Losh static void FtwoDup(FICL_VM *pVM)
438ca987d46SWarner Losh {
439ca987d46SWarner Losh #if FICL_ROBUST > 1
440ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 4);
441ca987d46SWarner Losh #endif
442ca987d46SWarner Losh 
443ca987d46SWarner Losh     PICKF(1);
444ca987d46SWarner Losh     PICKF(1);
445ca987d46SWarner Losh }
446ca987d46SWarner Losh 
447ca987d46SWarner Losh /*******************************************************************
448ca987d46SWarner Losh ** Do float stack over.
449ca987d46SWarner Losh ** fover ( r1 r2 -- r1 r2 r1 )
450ca987d46SWarner Losh *******************************************************************/
Fover(FICL_VM * pVM)451ca987d46SWarner Losh static void Fover(FICL_VM *pVM)
452ca987d46SWarner Losh {
453ca987d46SWarner Losh #if FICL_ROBUST > 1
454ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 3);
455ca987d46SWarner Losh #endif
456ca987d46SWarner Losh 
457ca987d46SWarner Losh     PICKF(1);
458ca987d46SWarner Losh }
459ca987d46SWarner Losh 
460ca987d46SWarner Losh /*******************************************************************
461ca987d46SWarner Losh ** Do float stack 2over.
462ca987d46SWarner Losh ** f2over ( r1 r2 r3 -- r1 r2 r3 r1 r2 )
463ca987d46SWarner Losh *******************************************************************/
FtwoOver(FICL_VM * pVM)464ca987d46SWarner Losh static void FtwoOver(FICL_VM *pVM)
465ca987d46SWarner Losh {
466ca987d46SWarner Losh #if FICL_ROBUST > 1
467ca987d46SWarner Losh     vmCheckFStack(pVM, 4, 6);
468ca987d46SWarner Losh #endif
469ca987d46SWarner Losh 
470ca987d46SWarner Losh     PICKF(3);
471ca987d46SWarner Losh     PICKF(3);
472ca987d46SWarner Losh }
473ca987d46SWarner Losh 
474ca987d46SWarner Losh /*******************************************************************
475ca987d46SWarner Losh ** Do float stack pick.
476ca987d46SWarner Losh ** fpick ( n -- r )
477ca987d46SWarner Losh *******************************************************************/
Fpick(FICL_VM * pVM)478ca987d46SWarner Losh static void Fpick(FICL_VM *pVM)
479ca987d46SWarner Losh {
480ca987d46SWarner Losh     CELL c = POP();
481ca987d46SWarner Losh 
482ca987d46SWarner Losh #if FICL_ROBUST > 1
483ca987d46SWarner Losh     vmCheckFStack(pVM, c.i+1, c.i+2);
484ca987d46SWarner Losh #endif
485ca987d46SWarner Losh 
486ca987d46SWarner Losh     PICKF(c.i);
487ca987d46SWarner Losh }
488ca987d46SWarner Losh 
489ca987d46SWarner Losh /*******************************************************************
490ca987d46SWarner Losh ** Do float stack ?dup.
491ca987d46SWarner Losh ** f?dup ( r -- r )
492ca987d46SWarner Losh *******************************************************************/
FquestionDup(FICL_VM * pVM)493ca987d46SWarner Losh static void FquestionDup(FICL_VM *pVM)
494ca987d46SWarner Losh {
495ca987d46SWarner Losh     CELL c;
496ca987d46SWarner Losh 
497ca987d46SWarner Losh #if FICL_ROBUST > 1
498ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 2);
499ca987d46SWarner Losh #endif
500ca987d46SWarner Losh 
501ca987d46SWarner Losh     c = GETTOPF();
502ca987d46SWarner Losh     if (c.f != 0)
503ca987d46SWarner Losh         PICKF(0);
504ca987d46SWarner Losh }
505ca987d46SWarner Losh 
506ca987d46SWarner Losh /*******************************************************************
507ca987d46SWarner Losh ** Do float stack roll.
508ca987d46SWarner Losh ** froll ( n -- )
509ca987d46SWarner Losh *******************************************************************/
Froll(FICL_VM * pVM)510ca987d46SWarner Losh static void Froll(FICL_VM *pVM)
511ca987d46SWarner Losh {
512ca987d46SWarner Losh     int i = POP().i;
513ca987d46SWarner Losh     i = (i > 0) ? i : 0;
514ca987d46SWarner Losh 
515ca987d46SWarner Losh #if FICL_ROBUST > 1
516ca987d46SWarner Losh     vmCheckFStack(pVM, i+1, i+1);
517ca987d46SWarner Losh #endif
518ca987d46SWarner Losh 
519ca987d46SWarner Losh     ROLLF(i);
520ca987d46SWarner Losh }
521ca987d46SWarner Losh 
522ca987d46SWarner Losh /*******************************************************************
523ca987d46SWarner Losh ** Do float stack -roll.
524ca987d46SWarner Losh ** f-roll ( n -- )
525ca987d46SWarner Losh *******************************************************************/
FminusRoll(FICL_VM * pVM)526ca987d46SWarner Losh static void FminusRoll(FICL_VM *pVM)
527ca987d46SWarner Losh {
528ca987d46SWarner Losh     int i = POP().i;
529ca987d46SWarner Losh     i = (i > 0) ? i : 0;
530ca987d46SWarner Losh 
531ca987d46SWarner Losh #if FICL_ROBUST > 1
532ca987d46SWarner Losh     vmCheckFStack(pVM, i+1, i+1);
533ca987d46SWarner Losh #endif
534ca987d46SWarner Losh 
535ca987d46SWarner Losh     ROLLF(-i);
536ca987d46SWarner Losh }
537ca987d46SWarner Losh 
538ca987d46SWarner Losh /*******************************************************************
539ca987d46SWarner Losh ** Do float stack rot.
540ca987d46SWarner Losh ** frot ( r1 r2 r3  -- r2 r3 r1 )
541ca987d46SWarner Losh *******************************************************************/
Frot(FICL_VM * pVM)542ca987d46SWarner Losh static void Frot(FICL_VM *pVM)
543ca987d46SWarner Losh {
544ca987d46SWarner Losh #if FICL_ROBUST > 1
545ca987d46SWarner Losh     vmCheckFStack(pVM, 3, 3);
546ca987d46SWarner Losh #endif
547ca987d46SWarner Losh 
548ca987d46SWarner Losh     ROLLF(2);
549ca987d46SWarner Losh }
550ca987d46SWarner Losh 
551ca987d46SWarner Losh /*******************************************************************
552ca987d46SWarner Losh ** Do float stack -rot.
553ca987d46SWarner Losh ** f-rot ( r1 r2 r3  -- r3 r1 r2 )
554ca987d46SWarner Losh *******************************************************************/
Fminusrot(FICL_VM * pVM)555ca987d46SWarner Losh static void Fminusrot(FICL_VM *pVM)
556ca987d46SWarner Losh {
557ca987d46SWarner Losh #if FICL_ROBUST > 1
558ca987d46SWarner Losh     vmCheckFStack(pVM, 3, 3);
559ca987d46SWarner Losh #endif
560ca987d46SWarner Losh 
561ca987d46SWarner Losh     ROLLF(-2);
562ca987d46SWarner Losh }
563ca987d46SWarner Losh 
564ca987d46SWarner Losh /*******************************************************************
565ca987d46SWarner Losh ** Do float stack swap.
566ca987d46SWarner Losh ** fswap ( r1 r2 -- r2 r1 )
567ca987d46SWarner Losh *******************************************************************/
Fswap(FICL_VM * pVM)568ca987d46SWarner Losh static void Fswap(FICL_VM *pVM)
569ca987d46SWarner Losh {
570ca987d46SWarner Losh #if FICL_ROBUST > 1
571ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 2);
572ca987d46SWarner Losh #endif
573ca987d46SWarner Losh 
574ca987d46SWarner Losh     ROLLF(1);
575ca987d46SWarner Losh }
576ca987d46SWarner Losh 
577ca987d46SWarner Losh /*******************************************************************
578ca987d46SWarner Losh ** Do float stack 2swap
579ca987d46SWarner Losh ** f2swap ( r1 r2 r3 r4  -- r3 r4 r1 r2 )
580ca987d46SWarner Losh *******************************************************************/
FtwoSwap(FICL_VM * pVM)581ca987d46SWarner Losh static void FtwoSwap(FICL_VM *pVM)
582ca987d46SWarner Losh {
583ca987d46SWarner Losh #if FICL_ROBUST > 1
584ca987d46SWarner Losh     vmCheckFStack(pVM, 4, 4);
585ca987d46SWarner Losh #endif
586ca987d46SWarner Losh 
587ca987d46SWarner Losh     ROLLF(3);
588ca987d46SWarner Losh     ROLLF(3);
589ca987d46SWarner Losh }
590ca987d46SWarner Losh 
591ca987d46SWarner Losh /*******************************************************************
592ca987d46SWarner Losh ** Get a floating point number from a variable.
593ca987d46SWarner Losh ** f@ ( n -- r )
594ca987d46SWarner Losh *******************************************************************/
Ffetch(FICL_VM * pVM)595ca987d46SWarner Losh static void Ffetch(FICL_VM *pVM)
596ca987d46SWarner Losh {
597ca987d46SWarner Losh     CELL *pCell;
598ca987d46SWarner Losh 
599ca987d46SWarner Losh #if FICL_ROBUST > 1
600ca987d46SWarner Losh     vmCheckFStack(pVM, 0, 1);
601ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
602ca987d46SWarner Losh #endif
603ca987d46SWarner Losh 
604ca987d46SWarner Losh     pCell = (CELL *)POPPTR();
605ca987d46SWarner Losh     PUSHFLOAT(pCell->f);
606ca987d46SWarner Losh }
607ca987d46SWarner Losh 
608ca987d46SWarner Losh /*******************************************************************
609ca987d46SWarner Losh ** Store a floating point number into a variable.
610ca987d46SWarner Losh ** f! ( r n -- )
611ca987d46SWarner Losh *******************************************************************/
Fstore(FICL_VM * pVM)612ca987d46SWarner Losh static void Fstore(FICL_VM *pVM)
613ca987d46SWarner Losh {
614ca987d46SWarner Losh     CELL *pCell;
615ca987d46SWarner Losh 
616ca987d46SWarner Losh #if FICL_ROBUST > 1
617ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
618ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
619ca987d46SWarner Losh #endif
620ca987d46SWarner Losh 
621ca987d46SWarner Losh     pCell = (CELL *)POPPTR();
622ca987d46SWarner Losh     pCell->f = POPFLOAT();
623ca987d46SWarner Losh }
624ca987d46SWarner Losh 
625ca987d46SWarner Losh /*******************************************************************
626ca987d46SWarner Losh ** Add a floating point number to contents of a variable.
627ca987d46SWarner Losh ** f+! ( r n -- )
628ca987d46SWarner Losh *******************************************************************/
FplusStore(FICL_VM * pVM)629ca987d46SWarner Losh static void FplusStore(FICL_VM *pVM)
630ca987d46SWarner Losh {
631ca987d46SWarner Losh     CELL *pCell;
632ca987d46SWarner Losh 
633ca987d46SWarner Losh #if FICL_ROBUST > 1
634ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
635ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
636ca987d46SWarner Losh #endif
637ca987d46SWarner Losh 
638ca987d46SWarner Losh     pCell = (CELL *)POPPTR();
639ca987d46SWarner Losh     pCell->f += POPFLOAT();
640ca987d46SWarner Losh }
641ca987d46SWarner Losh 
642ca987d46SWarner Losh /*******************************************************************
643ca987d46SWarner Losh ** Floating point literal execution word.
644ca987d46SWarner Losh *******************************************************************/
fliteralParen(FICL_VM * pVM)645ca987d46SWarner Losh static void fliteralParen(FICL_VM *pVM)
646ca987d46SWarner Losh {
647ca987d46SWarner Losh #if FICL_ROBUST > 1
648ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
649ca987d46SWarner Losh #endif
650ca987d46SWarner Losh 
651ca987d46SWarner Losh     PUSHFLOAT(*(float*)(pVM->ip));
652ca987d46SWarner Losh     vmBranchRelative(pVM, 1);
653ca987d46SWarner Losh }
654ca987d46SWarner Losh 
655ca987d46SWarner Losh /*******************************************************************
656ca987d46SWarner Losh ** Compile a floating point literal.
657ca987d46SWarner Losh *******************************************************************/
fliteralIm(FICL_VM * pVM)658ca987d46SWarner Losh static void fliteralIm(FICL_VM *pVM)
659ca987d46SWarner Losh {
660ca987d46SWarner Losh     FICL_DICT *dp = vmGetDict(pVM);
661ca987d46SWarner Losh     FICL_WORD *pfLitParen = ficlLookup(pVM->pSys, "(fliteral)");
662ca987d46SWarner Losh 
663ca987d46SWarner Losh #if FICL_ROBUST > 1
664ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
665ca987d46SWarner Losh #endif
666ca987d46SWarner Losh 
667ca987d46SWarner Losh     dictAppendCell(dp, LVALUEtoCELL(pfLitParen));
668ca987d46SWarner Losh     dictAppendCell(dp, stackPop(pVM->fStack));
669ca987d46SWarner Losh }
670ca987d46SWarner Losh 
671ca987d46SWarner Losh /*******************************************************************
672ca987d46SWarner Losh ** Do float 0= comparison r = 0.0.
673ca987d46SWarner Losh ** f0= ( r -- T/F )
674ca987d46SWarner Losh *******************************************************************/
FzeroEquals(FICL_VM * pVM)675ca987d46SWarner Losh static void FzeroEquals(FICL_VM *pVM)
676ca987d46SWarner Losh {
677ca987d46SWarner Losh     CELL c;
678ca987d46SWarner Losh 
679ca987d46SWarner Losh #if FICL_ROBUST > 1
680ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);                   /* Make sure something on float stack. */
681ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);                    /* Make sure room for result. */
682ca987d46SWarner Losh #endif
683ca987d46SWarner Losh 
684ca987d46SWarner Losh     c.i = FICL_BOOL(POPFLOAT() == 0);
685ca987d46SWarner Losh     PUSH(c);
686ca987d46SWarner Losh }
687ca987d46SWarner Losh 
688ca987d46SWarner Losh /*******************************************************************
689ca987d46SWarner Losh ** Do float 0< comparison r < 0.0.
690ca987d46SWarner Losh ** f0< ( r -- T/F )
691ca987d46SWarner Losh *******************************************************************/
FzeroLess(FICL_VM * pVM)692ca987d46SWarner Losh static void FzeroLess(FICL_VM *pVM)
693ca987d46SWarner Losh {
694ca987d46SWarner Losh     CELL c;
695ca987d46SWarner Losh 
696ca987d46SWarner Losh #if FICL_ROBUST > 1
697ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);                   /* Make sure something on float stack. */
698ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);                    /* Make sure room for result. */
699ca987d46SWarner Losh #endif
700ca987d46SWarner Losh 
701ca987d46SWarner Losh     c.i = FICL_BOOL(POPFLOAT() < 0);
702ca987d46SWarner Losh     PUSH(c);
703ca987d46SWarner Losh }
704ca987d46SWarner Losh 
705ca987d46SWarner Losh /*******************************************************************
706ca987d46SWarner Losh ** Do float 0> comparison r > 0.0.
707ca987d46SWarner Losh ** f0> ( r -- T/F )
708ca987d46SWarner Losh *******************************************************************/
FzeroGreater(FICL_VM * pVM)709ca987d46SWarner Losh static void FzeroGreater(FICL_VM *pVM)
710ca987d46SWarner Losh {
711ca987d46SWarner Losh     CELL c;
712ca987d46SWarner Losh 
713ca987d46SWarner Losh #if FICL_ROBUST > 1
714ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
715ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
716ca987d46SWarner Losh #endif
717ca987d46SWarner Losh 
718ca987d46SWarner Losh     c.i = FICL_BOOL(POPFLOAT() > 0);
719ca987d46SWarner Losh     PUSH(c);
720ca987d46SWarner Losh }
721ca987d46SWarner Losh 
722ca987d46SWarner Losh /*******************************************************************
723ca987d46SWarner Losh ** Do float = comparison r1 = r2.
724ca987d46SWarner Losh ** f= ( r1 r2 -- T/F )
725ca987d46SWarner Losh *******************************************************************/
FisEqual(FICL_VM * pVM)726ca987d46SWarner Losh static void FisEqual(FICL_VM *pVM)
727ca987d46SWarner Losh {
728ca987d46SWarner Losh     float x, y;
729ca987d46SWarner Losh 
730ca987d46SWarner Losh #if FICL_ROBUST > 1
731ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 0);
732ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
733ca987d46SWarner Losh #endif
734ca987d46SWarner Losh 
735ca987d46SWarner Losh     x = POPFLOAT();
736ca987d46SWarner Losh     y = POPFLOAT();
737ca987d46SWarner Losh     PUSHINT(FICL_BOOL(x == y));
738ca987d46SWarner Losh }
739ca987d46SWarner Losh 
740ca987d46SWarner Losh /*******************************************************************
741ca987d46SWarner Losh ** Do float < comparison r1 < r2.
742ca987d46SWarner Losh ** f< ( r1 r2 -- T/F )
743ca987d46SWarner Losh *******************************************************************/
FisLess(FICL_VM * pVM)744ca987d46SWarner Losh static void FisLess(FICL_VM *pVM)
745ca987d46SWarner Losh {
746ca987d46SWarner Losh     float x, y;
747ca987d46SWarner Losh 
748ca987d46SWarner Losh #if FICL_ROBUST > 1
749ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 0);
750ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
751ca987d46SWarner Losh #endif
752ca987d46SWarner Losh 
753ca987d46SWarner Losh     y = POPFLOAT();
754ca987d46SWarner Losh     x = POPFLOAT();
755ca987d46SWarner Losh     PUSHINT(FICL_BOOL(x < y));
756ca987d46SWarner Losh }
757ca987d46SWarner Losh 
758ca987d46SWarner Losh /*******************************************************************
759ca987d46SWarner Losh ** Do float > comparison r1 > r2.
760ca987d46SWarner Losh ** f> ( r1 r2 -- T/F )
761ca987d46SWarner Losh *******************************************************************/
FisGreater(FICL_VM * pVM)762ca987d46SWarner Losh static void FisGreater(FICL_VM *pVM)
763ca987d46SWarner Losh {
764ca987d46SWarner Losh     float x, y;
765ca987d46SWarner Losh 
766ca987d46SWarner Losh #if FICL_ROBUST > 1
767ca987d46SWarner Losh     vmCheckFStack(pVM, 2, 0);
768ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
769ca987d46SWarner Losh #endif
770ca987d46SWarner Losh 
771ca987d46SWarner Losh     y = POPFLOAT();
772ca987d46SWarner Losh     x = POPFLOAT();
773ca987d46SWarner Losh     PUSHINT(FICL_BOOL(x > y));
774ca987d46SWarner Losh }
775ca987d46SWarner Losh 
776ca987d46SWarner Losh 
777ca987d46SWarner Losh /*******************************************************************
778ca987d46SWarner Losh ** Move float to param stack (assumes they both fit in a single CELL)
779ca987d46SWarner Losh ** f>s
780ca987d46SWarner Losh *******************************************************************/
FFrom(FICL_VM * pVM)781ca987d46SWarner Losh static void FFrom(FICL_VM *pVM)
782ca987d46SWarner Losh {
783ca987d46SWarner Losh     CELL c;
784ca987d46SWarner Losh 
785ca987d46SWarner Losh #if FICL_ROBUST > 1
786ca987d46SWarner Losh     vmCheckFStack(pVM, 1, 0);
787ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
788ca987d46SWarner Losh #endif
789ca987d46SWarner Losh 
790ca987d46SWarner Losh     c = stackPop(pVM->fStack);
791ca987d46SWarner Losh     stackPush(pVM->pStack, c);
792ca987d46SWarner Losh     return;
793ca987d46SWarner Losh }
794ca987d46SWarner Losh 
ToF(FICL_VM * pVM)795ca987d46SWarner Losh static void ToF(FICL_VM *pVM)
796ca987d46SWarner Losh {
797ca987d46SWarner Losh     CELL c;
798ca987d46SWarner Losh 
799ca987d46SWarner Losh #if FICL_ROBUST > 1
800ca987d46SWarner Losh     vmCheckFStack(pVM, 0, 1);
801ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
802ca987d46SWarner Losh #endif
803ca987d46SWarner Losh 
804ca987d46SWarner Losh     c = stackPop(pVM->pStack);
805ca987d46SWarner Losh     stackPush(pVM->fStack, c);
806ca987d46SWarner Losh     return;
807ca987d46SWarner Losh }
808ca987d46SWarner Losh 
809ca987d46SWarner Losh 
810ca987d46SWarner Losh /**************************************************************************
811ca987d46SWarner Losh                      F l o a t P a r s e S t a t e
812*54c1a657SGordon Bergling ** Enum to determine the current segment of a floating point number
813ca987d46SWarner Losh ** being parsed.
814ca987d46SWarner Losh **************************************************************************/
815ca987d46SWarner Losh #define NUMISNEG 1
816ca987d46SWarner Losh #define EXPISNEG 2
817ca987d46SWarner Losh 
818ca987d46SWarner Losh typedef enum _floatParseState
819ca987d46SWarner Losh {
820ca987d46SWarner Losh     FPS_START,
821ca987d46SWarner Losh     FPS_ININT,
822ca987d46SWarner Losh     FPS_INMANT,
823ca987d46SWarner Losh     FPS_STARTEXP,
824ca987d46SWarner Losh     FPS_INEXP
825ca987d46SWarner Losh } FloatParseState;
826ca987d46SWarner Losh 
827ca987d46SWarner Losh /**************************************************************************
828ca987d46SWarner Losh                      f i c l P a r s e F l o a t N u m b e r
829ca987d46SWarner Losh ** pVM -- Virtual Machine pointer.
830ca987d46SWarner Losh ** si -- String to parse.
831ca987d46SWarner Losh ** Returns 1 if successful, 0 if not.
832ca987d46SWarner Losh **************************************************************************/
ficlParseFloatNumber(FICL_VM * pVM,STRINGINFO si)833ca987d46SWarner Losh int ficlParseFloatNumber( FICL_VM *pVM, STRINGINFO si )
834ca987d46SWarner Losh {
835ca987d46SWarner Losh     unsigned char ch, digit;
836ca987d46SWarner Losh     char *cp;
837ca987d46SWarner Losh     FICL_COUNT count;
838ca987d46SWarner Losh     float power;
839ca987d46SWarner Losh     float accum = 0.0f;
840ca987d46SWarner Losh     float mant = 0.1f;
841ca987d46SWarner Losh     FICL_INT exponent = 0;
842ca987d46SWarner Losh     char flag = 0;
843ca987d46SWarner Losh     FloatParseState estate = FPS_START;
844ca987d46SWarner Losh 
845ca987d46SWarner Losh #if FICL_ROBUST > 1
846ca987d46SWarner Losh     vmCheckFStack(pVM, 0, 1);
847ca987d46SWarner Losh #endif
848ca987d46SWarner Losh 
849ca987d46SWarner Losh     /*
850ca987d46SWarner Losh     ** floating point numbers only allowed in base 10
851ca987d46SWarner Losh     */
852ca987d46SWarner Losh     if (pVM->base != 10)
853ca987d46SWarner Losh         return(0);
854ca987d46SWarner Losh 
855ca987d46SWarner Losh 
856ca987d46SWarner Losh     cp = SI_PTR(si);
857ca987d46SWarner Losh     count = (FICL_COUNT)SI_COUNT(si);
858ca987d46SWarner Losh 
859ca987d46SWarner Losh     /* Loop through the string's characters. */
860ca987d46SWarner Losh     while ((count--) && ((ch = *cp++) != 0))
861ca987d46SWarner Losh     {
862ca987d46SWarner Losh         switch (estate)
863ca987d46SWarner Losh         {
864ca987d46SWarner Losh             /* At start of the number so look for a sign. */
865ca987d46SWarner Losh             case FPS_START:
866ca987d46SWarner Losh             {
867ca987d46SWarner Losh                 estate = FPS_ININT;
868ca987d46SWarner Losh                 if (ch == '-')
869ca987d46SWarner Losh                 {
870ca987d46SWarner Losh                     flag |= NUMISNEG;
871ca987d46SWarner Losh                     break;
872ca987d46SWarner Losh                 }
873ca987d46SWarner Losh                 if (ch == '+')
874ca987d46SWarner Losh                 {
875ca987d46SWarner Losh                     break;
876ca987d46SWarner Losh                 }
877ca987d46SWarner Losh             } /* Note!  Drop through to FPS_ININT */
878ca987d46SWarner Losh             /*
879ca987d46SWarner Losh             **Converting integer part of number.
880ca987d46SWarner Losh             ** Only allow digits, decimal and 'E'.
881ca987d46SWarner Losh             */
882ca987d46SWarner Losh             case FPS_ININT:
883ca987d46SWarner Losh             {
884ca987d46SWarner Losh                 if (ch == '.')
885ca987d46SWarner Losh                 {
886ca987d46SWarner Losh                     estate = FPS_INMANT;
887ca987d46SWarner Losh                 }
888ca987d46SWarner Losh                 else if ((ch == 'e') || (ch == 'E'))
889ca987d46SWarner Losh                 {
890ca987d46SWarner Losh                     estate = FPS_STARTEXP;
891ca987d46SWarner Losh                 }
892ca987d46SWarner Losh                 else
893ca987d46SWarner Losh                 {
894ca987d46SWarner Losh                     digit = (unsigned char)(ch - '0');
895ca987d46SWarner Losh                     if (digit > 9)
896ca987d46SWarner Losh                         return(0);
897ca987d46SWarner Losh 
898ca987d46SWarner Losh                     accum = accum * 10 + digit;
899ca987d46SWarner Losh 
900ca987d46SWarner Losh                 }
901ca987d46SWarner Losh                 break;
902ca987d46SWarner Losh             }
903ca987d46SWarner Losh             /*
904ca987d46SWarner Losh             ** Processing the fraction part of number.
905ca987d46SWarner Losh             ** Only allow digits and 'E'
906ca987d46SWarner Losh             */
907ca987d46SWarner Losh             case FPS_INMANT:
908ca987d46SWarner Losh             {
909ca987d46SWarner Losh                 if ((ch == 'e') || (ch == 'E'))
910ca987d46SWarner Losh                 {
911ca987d46SWarner Losh                     estate = FPS_STARTEXP;
912ca987d46SWarner Losh                 }
913ca987d46SWarner Losh                 else
914ca987d46SWarner Losh                 {
915ca987d46SWarner Losh                     digit = (unsigned char)(ch - '0');
916ca987d46SWarner Losh                     if (digit > 9)
917ca987d46SWarner Losh                         return(0);
918ca987d46SWarner Losh 
919ca987d46SWarner Losh                     accum += digit * mant;
920ca987d46SWarner Losh                     mant *= 0.1f;
921ca987d46SWarner Losh                 }
922ca987d46SWarner Losh                 break;
923ca987d46SWarner Losh             }
924ca987d46SWarner Losh             /* Start processing the exponent part of number. */
925ca987d46SWarner Losh             /* Look for sign. */
926ca987d46SWarner Losh             case FPS_STARTEXP:
927ca987d46SWarner Losh             {
928ca987d46SWarner Losh                 estate = FPS_INEXP;
929ca987d46SWarner Losh 
930ca987d46SWarner Losh                 if (ch == '-')
931ca987d46SWarner Losh                 {
932ca987d46SWarner Losh                     flag |= EXPISNEG;
933ca987d46SWarner Losh                     break;
934ca987d46SWarner Losh                 }
935ca987d46SWarner Losh                 else if (ch == '+')
936ca987d46SWarner Losh                 {
937ca987d46SWarner Losh                     break;
938ca987d46SWarner Losh                 }
939ca987d46SWarner Losh             }       /* Note!  Drop through to FPS_INEXP */
940ca987d46SWarner Losh             /*
941ca987d46SWarner Losh             ** Processing the exponent part of number.
942ca987d46SWarner Losh             ** Only allow digits.
943ca987d46SWarner Losh             */
944ca987d46SWarner Losh             case FPS_INEXP:
945ca987d46SWarner Losh             {
946ca987d46SWarner Losh                 digit = (unsigned char)(ch - '0');
947ca987d46SWarner Losh                 if (digit > 9)
948ca987d46SWarner Losh                     return(0);
949ca987d46SWarner Losh 
950ca987d46SWarner Losh                 exponent = exponent * 10 + digit;
951ca987d46SWarner Losh 
952ca987d46SWarner Losh                 break;
953ca987d46SWarner Losh             }
954ca987d46SWarner Losh         }
955ca987d46SWarner Losh     }
956ca987d46SWarner Losh 
957ca987d46SWarner Losh     /* If parser never made it to the exponent this is not a float. */
958ca987d46SWarner Losh     if (estate < FPS_STARTEXP)
959ca987d46SWarner Losh         return(0);
960ca987d46SWarner Losh 
961ca987d46SWarner Losh     /* Set the sign of the number. */
962ca987d46SWarner Losh     if (flag & NUMISNEG)
963ca987d46SWarner Losh         accum = -accum;
964ca987d46SWarner Losh 
965ca987d46SWarner Losh     /* If exponent is not 0 then adjust number by it. */
966ca987d46SWarner Losh     if (exponent != 0)
967ca987d46SWarner Losh     {
968ca987d46SWarner Losh         /* Determine if exponent is negative. */
969ca987d46SWarner Losh         if (flag & EXPISNEG)
970ca987d46SWarner Losh         {
971ca987d46SWarner Losh             exponent = -exponent;
972ca987d46SWarner Losh         }
973ca987d46SWarner Losh         /* power = 10^x */
974ca987d46SWarner Losh         power = (float)pow(10.0, exponent);
975ca987d46SWarner Losh         accum *= power;
976ca987d46SWarner Losh     }
977ca987d46SWarner Losh 
978ca987d46SWarner Losh     PUSHFLOAT(accum);
979ca987d46SWarner Losh     if (pVM->state == COMPILE)
980ca987d46SWarner Losh         fliteralIm(pVM);
981ca987d46SWarner Losh 
982ca987d46SWarner Losh     return(1);
983ca987d46SWarner Losh }
984ca987d46SWarner Losh 
985ca987d46SWarner Losh #endif  /* FICL_WANT_FLOAT */
986ca987d46SWarner Losh 
987ca987d46SWarner Losh /**************************************************************************
988ca987d46SWarner Losh ** Add float words to a system's dictionary.
989ca987d46SWarner Losh ** pSys -- Pointer to the FICL sytem to add float words to.
990ca987d46SWarner Losh **************************************************************************/
ficlCompileFloat(FICL_SYSTEM * pSys)991ca987d46SWarner Losh void ficlCompileFloat(FICL_SYSTEM *pSys)
992ca987d46SWarner Losh {
993ca987d46SWarner Losh     FICL_DICT *dp = pSys->dp;
994ca987d46SWarner Losh     assert(dp);
995ca987d46SWarner Losh 
996ca987d46SWarner Losh #if FICL_WANT_FLOAT
997ca987d46SWarner Losh     dictAppendWord(dp, ">float",    ToF,            FW_DEFAULT);
998ca987d46SWarner Losh     /* d>f */
999ca987d46SWarner Losh     dictAppendWord(dp, "f!",        Fstore,         FW_DEFAULT);
1000ca987d46SWarner Losh     dictAppendWord(dp, "f*",        Fmul,           FW_DEFAULT);
1001ca987d46SWarner Losh     dictAppendWord(dp, "f+",        Fadd,           FW_DEFAULT);
1002ca987d46SWarner Losh     dictAppendWord(dp, "f-",        Fsub,           FW_DEFAULT);
1003ca987d46SWarner Losh     dictAppendWord(dp, "f/",        Fdiv,           FW_DEFAULT);
1004ca987d46SWarner Losh     dictAppendWord(dp, "f0<",       FzeroLess,      FW_DEFAULT);
1005ca987d46SWarner Losh     dictAppendWord(dp, "f0=",       FzeroEquals,    FW_DEFAULT);
1006ca987d46SWarner Losh     dictAppendWord(dp, "f<",        FisLess,        FW_DEFAULT);
1007ca987d46SWarner Losh  /*
1008ca987d46SWarner Losh     f>d
1009ca987d46SWarner Losh  */
1010ca987d46SWarner Losh     dictAppendWord(dp, "f@",        Ffetch,         FW_DEFAULT);
1011ca987d46SWarner Losh  /*
1012ca987d46SWarner Losh     falign
1013ca987d46SWarner Losh     faligned
1014ca987d46SWarner Losh  */
1015ca987d46SWarner Losh     dictAppendWord(dp, "fconstant", Fconstant,      FW_DEFAULT);
1016ca987d46SWarner Losh     dictAppendWord(dp, "fdepth",    Fdepth,         FW_DEFAULT);
1017ca987d46SWarner Losh     dictAppendWord(dp, "fdrop",     Fdrop,          FW_DEFAULT);
1018ca987d46SWarner Losh     dictAppendWord(dp, "fdup",      Fdup,           FW_DEFAULT);
1019ca987d46SWarner Losh     dictAppendWord(dp, "fliteral",  fliteralIm,     FW_IMMEDIATE);
1020ca987d46SWarner Losh /*
1021ca987d46SWarner Losh     float+
1022ca987d46SWarner Losh     floats
1023ca987d46SWarner Losh     floor
1024ca987d46SWarner Losh     fmax
1025ca987d46SWarner Losh     fmin
1026ca987d46SWarner Losh */
1027ca987d46SWarner Losh     dictAppendWord(dp, "f?dup",     FquestionDup,   FW_DEFAULT);
1028ca987d46SWarner Losh     dictAppendWord(dp, "f=",        FisEqual,       FW_DEFAULT);
1029ca987d46SWarner Losh     dictAppendWord(dp, "f>",        FisGreater,     FW_DEFAULT);
1030ca987d46SWarner Losh     dictAppendWord(dp, "f0>",       FzeroGreater,   FW_DEFAULT);
1031ca987d46SWarner Losh     dictAppendWord(dp, "f2drop",    FtwoDrop,       FW_DEFAULT);
1032ca987d46SWarner Losh     dictAppendWord(dp, "f2dup",     FtwoDup,        FW_DEFAULT);
1033ca987d46SWarner Losh     dictAppendWord(dp, "f2over",    FtwoOver,       FW_DEFAULT);
1034ca987d46SWarner Losh     dictAppendWord(dp, "f2swap",    FtwoSwap,       FW_DEFAULT);
1035ca987d46SWarner Losh     dictAppendWord(dp, "f+!",       FplusStore,     FW_DEFAULT);
1036ca987d46SWarner Losh     dictAppendWord(dp, "f+i",       Faddi,          FW_DEFAULT);
1037ca987d46SWarner Losh     dictAppendWord(dp, "f-i",       Fsubi,          FW_DEFAULT);
1038ca987d46SWarner Losh     dictAppendWord(dp, "f*i",       Fmuli,          FW_DEFAULT);
1039ca987d46SWarner Losh     dictAppendWord(dp, "f/i",       Fdivi,          FW_DEFAULT);
1040ca987d46SWarner Losh     dictAppendWord(dp, "int>float", itof,           FW_DEFAULT);
1041ca987d46SWarner Losh     dictAppendWord(dp, "float>int", Ftoi,           FW_DEFAULT);
1042ca987d46SWarner Losh     dictAppendWord(dp, "f.",        FDot,           FW_DEFAULT);
1043ca987d46SWarner Losh     dictAppendWord(dp, "f.s",       displayFStack,  FW_DEFAULT);
1044ca987d46SWarner Losh     dictAppendWord(dp, "fe.",       EDot,           FW_DEFAULT);
1045ca987d46SWarner Losh     dictAppendWord(dp, "fover",     Fover,          FW_DEFAULT);
1046ca987d46SWarner Losh     dictAppendWord(dp, "fnegate",   Fnegate,        FW_DEFAULT);
1047ca987d46SWarner Losh     dictAppendWord(dp, "fpick",     Fpick,          FW_DEFAULT);
1048ca987d46SWarner Losh     dictAppendWord(dp, "froll",     Froll,          FW_DEFAULT);
1049ca987d46SWarner Losh     dictAppendWord(dp, "frot",      Frot,           FW_DEFAULT);
1050ca987d46SWarner Losh     dictAppendWord(dp, "fswap",     Fswap,          FW_DEFAULT);
1051ca987d46SWarner Losh     dictAppendWord(dp, "i-f",       isubf,          FW_DEFAULT);
1052ca987d46SWarner Losh     dictAppendWord(dp, "i/f",       idivf,          FW_DEFAULT);
1053ca987d46SWarner Losh 
1054ca987d46SWarner Losh     dictAppendWord(dp, "float>",    FFrom,          FW_DEFAULT);
1055ca987d46SWarner Losh 
1056ca987d46SWarner Losh     dictAppendWord(dp, "f-roll",    FminusRoll,     FW_DEFAULT);
1057ca987d46SWarner Losh     dictAppendWord(dp, "f-rot",     Fminusrot,      FW_DEFAULT);
1058ca987d46SWarner Losh     dictAppendWord(dp, "(fliteral)", fliteralParen, FW_COMPILE);
1059ca987d46SWarner Losh 
1060ca987d46SWarner Losh     ficlSetEnv(pSys, "floating",       FICL_FALSE);  /* not all required words are present */
1061ca987d46SWarner Losh     ficlSetEnv(pSys, "floating-ext",   FICL_FALSE);
1062ca987d46SWarner Losh     ficlSetEnv(pSys, "floating-stack", FICL_DEFAULT_STACK);
1063ca987d46SWarner Losh #endif
1064ca987d46SWarner Losh     return;
1065ca987d46SWarner Losh }
1066ca987d46SWarner Losh 
1067