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