xref: /titanic_53/usr/src/common/ficl/float.c (revision a1bf3f785ae05c419b339c3a2061f2b18c024f61)
1*a1bf3f78SToomas Soome /*
2*a1bf3f78SToomas Soome  * f l o a t . c
3*a1bf3f78SToomas Soome  * Forth Inspired Command Language
4*a1bf3f78SToomas Soome  * ANS Forth FLOAT word-set written in C
5*a1bf3f78SToomas Soome  * Author: Guy Carver & John Sadler (john_sadler@alum.mit.edu)
6*a1bf3f78SToomas Soome  * Created: Apr 2001
7*a1bf3f78SToomas Soome  * $Id: float.c,v 1.10 2010/09/13 18:43:04 asau Exp $
8*a1bf3f78SToomas Soome  */
9*a1bf3f78SToomas Soome /*
10*a1bf3f78SToomas Soome  * Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
11*a1bf3f78SToomas Soome  * All rights reserved.
12*a1bf3f78SToomas Soome  *
13*a1bf3f78SToomas Soome  * Get the latest Ficl release at http://ficl.sourceforge.net
14*a1bf3f78SToomas Soome  *
15*a1bf3f78SToomas Soome  * I am interested in hearing from anyone who uses Ficl. If you have
16*a1bf3f78SToomas Soome  * a problem, a success story, a defect, an enhancement request, or
17*a1bf3f78SToomas Soome  * if you would like to contribute to the Ficl release, please
18*a1bf3f78SToomas Soome  * contact me by email at the address above.
19*a1bf3f78SToomas Soome  *
20*a1bf3f78SToomas Soome  * L I C E N S E  and  D I S C L A I M E R
21*a1bf3f78SToomas Soome  *
22*a1bf3f78SToomas Soome  * Redistribution and use in source and binary forms, with or without
23*a1bf3f78SToomas Soome  * modification, are permitted provided that the following conditions
24*a1bf3f78SToomas Soome  * are met:
25*a1bf3f78SToomas Soome  * 1. Redistributions of source code must retain the above copyright
26*a1bf3f78SToomas Soome  *    notice, this list of conditions and the following disclaimer.
27*a1bf3f78SToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
28*a1bf3f78SToomas Soome  *    notice, this list of conditions and the following disclaimer in the
29*a1bf3f78SToomas Soome  *    documentation and/or other materials provided with the distribution.
30*a1bf3f78SToomas Soome  *
31*a1bf3f78SToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
32*a1bf3f78SToomas Soome  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33*a1bf3f78SToomas Soome  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34*a1bf3f78SToomas Soome  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
35*a1bf3f78SToomas Soome  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*a1bf3f78SToomas Soome  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*a1bf3f78SToomas Soome  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*a1bf3f78SToomas Soome  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39*a1bf3f78SToomas Soome  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40*a1bf3f78SToomas Soome  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41*a1bf3f78SToomas Soome  * SUCH DAMAGE.
42*a1bf3f78SToomas Soome  */
43*a1bf3f78SToomas Soome 
44*a1bf3f78SToomas Soome #include "ficl.h"
45*a1bf3f78SToomas Soome 
46*a1bf3f78SToomas Soome #if FICL_WANT_FLOAT
47*a1bf3f78SToomas Soome #include <math.h>
48*a1bf3f78SToomas Soome #include <values.h>
49*a1bf3f78SToomas Soome 
50*a1bf3f78SToomas Soome 
51*a1bf3f78SToomas Soome /*
52*a1bf3f78SToomas Soome  * Create a floating point constant.
53*a1bf3f78SToomas Soome  * fconstant ( r -"name"- )
54*a1bf3f78SToomas Soome  */
55*a1bf3f78SToomas Soome static void
56*a1bf3f78SToomas Soome ficlPrimitiveFConstant(ficlVm *vm)
57*a1bf3f78SToomas Soome {
58*a1bf3f78SToomas Soome 	ficlDictionary *dictionary = ficlVmGetDictionary(vm);
59*a1bf3f78SToomas Soome 	ficlString name = ficlVmGetWord(vm);
60*a1bf3f78SToomas Soome 
61*a1bf3f78SToomas Soome 	FICL_STACK_CHECK(vm->floatStack, 1, 0);
62*a1bf3f78SToomas Soome 
63*a1bf3f78SToomas Soome 	ficlDictionaryAppendWord(dictionary, name,
64*a1bf3f78SToomas Soome 	    (ficlPrimitive)ficlInstructionFConstantParen, FICL_WORD_DEFAULT);
65*a1bf3f78SToomas Soome 	ficlDictionaryAppendCell(dictionary, ficlStackPop(vm->floatStack));
66*a1bf3f78SToomas Soome }
67*a1bf3f78SToomas Soome 
68*a1bf3f78SToomas Soome 
69*a1bf3f78SToomas Soome ficlWord *
70*a1bf3f78SToomas Soome ficlDictionaryAppendFConstant(ficlDictionary *dictionary, char *name,
71*a1bf3f78SToomas Soome     ficlFloat value)
72*a1bf3f78SToomas Soome {
73*a1bf3f78SToomas Soome 	ficlString s;
74*a1bf3f78SToomas Soome 	FICL_STRING_SET_FROM_CSTRING(s, name);
75*a1bf3f78SToomas Soome 	return (ficlDictionaryAppendConstantInstruction(dictionary, s,
76*a1bf3f78SToomas Soome 	    ficlInstructionFConstantParen, *(ficlInteger *)(&value)));
77*a1bf3f78SToomas Soome }
78*a1bf3f78SToomas Soome 
79*a1bf3f78SToomas Soome 
80*a1bf3f78SToomas Soome ficlWord *
81*a1bf3f78SToomas Soome ficlDictionarySetFConstant(ficlDictionary *dictionary, char *name,
82*a1bf3f78SToomas Soome     ficlFloat value)
83*a1bf3f78SToomas Soome {
84*a1bf3f78SToomas Soome 	ficlString s;
85*a1bf3f78SToomas Soome 	FICL_STRING_SET_FROM_CSTRING(s, name);
86*a1bf3f78SToomas Soome 	return (ficlDictionarySetConstantInstruction(dictionary, s,
87*a1bf3f78SToomas Soome 	    ficlInstructionFConstantParen, *(ficlInteger *)(&value)));
88*a1bf3f78SToomas Soome }
89*a1bf3f78SToomas Soome 
90*a1bf3f78SToomas Soome 
91*a1bf3f78SToomas Soome 
92*a1bf3f78SToomas Soome 
93*a1bf3f78SToomas Soome static void
94*a1bf3f78SToomas Soome ficlPrimitiveF2Constant(ficlVm *vm)
95*a1bf3f78SToomas Soome {
96*a1bf3f78SToomas Soome 	ficlDictionary *dictionary = ficlVmGetDictionary(vm);
97*a1bf3f78SToomas Soome 	ficlString name = ficlVmGetWord(vm);
98*a1bf3f78SToomas Soome 
99*a1bf3f78SToomas Soome 	FICL_STACK_CHECK(vm->floatStack, 2, 0);
100*a1bf3f78SToomas Soome 
101*a1bf3f78SToomas Soome 	ficlDictionaryAppendWord(dictionary, name,
102*a1bf3f78SToomas Soome 	    (ficlPrimitive)ficlInstructionF2ConstantParen, FICL_WORD_DEFAULT);
103*a1bf3f78SToomas Soome 	ficlDictionaryAppendCell(dictionary, ficlStackPop(vm->floatStack));
104*a1bf3f78SToomas Soome 	ficlDictionaryAppendCell(dictionary, ficlStackPop(vm->floatStack));
105*a1bf3f78SToomas Soome }
106*a1bf3f78SToomas Soome 
107*a1bf3f78SToomas Soome ficlWord *
108*a1bf3f78SToomas Soome ficlDictionaryAppendF2Constant(ficlDictionary *dictionary, char *name,
109*a1bf3f78SToomas Soome     ficlFloat value)
110*a1bf3f78SToomas Soome {
111*a1bf3f78SToomas Soome 	ficlString s;
112*a1bf3f78SToomas Soome 	FICL_STRING_SET_FROM_CSTRING(s, name);
113*a1bf3f78SToomas Soome 	return (ficlDictionaryAppend2ConstantInstruction(dictionary, s,
114*a1bf3f78SToomas Soome 	    ficlInstructionF2ConstantParen, *(ficl2Integer *)(&value)));
115*a1bf3f78SToomas Soome }
116*a1bf3f78SToomas Soome 
117*a1bf3f78SToomas Soome ficlWord *
118*a1bf3f78SToomas Soome ficlDictionarySetF2Constant(ficlDictionary *dictionary, char *name,
119*a1bf3f78SToomas Soome     ficlFloat value)
120*a1bf3f78SToomas Soome {
121*a1bf3f78SToomas Soome 	ficlString s;
122*a1bf3f78SToomas Soome 	FICL_STRING_SET_FROM_CSTRING(s, name);
123*a1bf3f78SToomas Soome 	return (ficlDictionarySet2ConstantInstruction(dictionary, s,
124*a1bf3f78SToomas Soome 	    ficlInstructionF2ConstantParen, *(ficl2Integer *)(&value)));
125*a1bf3f78SToomas Soome }
126*a1bf3f78SToomas Soome 
127*a1bf3f78SToomas Soome /*
128*a1bf3f78SToomas Soome  * Display a float in decimal format.
129*a1bf3f78SToomas Soome  * f. ( r -- )
130*a1bf3f78SToomas Soome  */
131*a1bf3f78SToomas Soome static void
132*a1bf3f78SToomas Soome ficlPrimitiveFDot(ficlVm *vm)
133*a1bf3f78SToomas Soome {
134*a1bf3f78SToomas Soome 	ficlFloat f;
135*a1bf3f78SToomas Soome 
136*a1bf3f78SToomas Soome 	FICL_STACK_CHECK(vm->floatStack, 1, 0);
137*a1bf3f78SToomas Soome 
138*a1bf3f78SToomas Soome 	f = ficlStackPopFloat(vm->floatStack);
139*a1bf3f78SToomas Soome 	sprintf(vm->pad, "%#f ", f);
140*a1bf3f78SToomas Soome 	ficlVmTextOut(vm, vm->pad);
141*a1bf3f78SToomas Soome }
142*a1bf3f78SToomas Soome 
143*a1bf3f78SToomas Soome /*
144*a1bf3f78SToomas Soome  * Display a float in engineering format.
145*a1bf3f78SToomas Soome  * fe. ( r -- )
146*a1bf3f78SToomas Soome  */
147*a1bf3f78SToomas Soome static void
148*a1bf3f78SToomas Soome ficlPrimitiveEDot(ficlVm *vm)
149*a1bf3f78SToomas Soome {
150*a1bf3f78SToomas Soome 	ficlFloat f;
151*a1bf3f78SToomas Soome 
152*a1bf3f78SToomas Soome 	FICL_STACK_CHECK(vm->floatStack, 1, 0);
153*a1bf3f78SToomas Soome 
154*a1bf3f78SToomas Soome 	f = ficlStackPopFloat(vm->floatStack);
155*a1bf3f78SToomas Soome 	sprintf(vm->pad, "%#e ", f);
156*a1bf3f78SToomas Soome 	ficlVmTextOut(vm, vm->pad);
157*a1bf3f78SToomas Soome }
158*a1bf3f78SToomas Soome 
159*a1bf3f78SToomas Soome /*
160*a1bf3f78SToomas Soome  * d i s p l a y FS t a c k
161*a1bf3f78SToomas Soome  * Display the parameter stack (code for "f.s")
162*a1bf3f78SToomas Soome  * f.s ( -- )
163*a1bf3f78SToomas Soome  */
164*a1bf3f78SToomas Soome struct stackContext
165*a1bf3f78SToomas Soome {
166*a1bf3f78SToomas Soome 	ficlVm *vm;
167*a1bf3f78SToomas Soome 	int count;
168*a1bf3f78SToomas Soome };
169*a1bf3f78SToomas Soome 
170*a1bf3f78SToomas Soome static ficlInteger
171*a1bf3f78SToomas Soome ficlFloatStackDisplayCallback(void *c, ficlCell *cell)
172*a1bf3f78SToomas Soome {
173*a1bf3f78SToomas Soome 	struct stackContext *context = (struct stackContext *)c;
174*a1bf3f78SToomas Soome 	char buffer[80];
175*a1bf3f78SToomas Soome #ifdef	_LP64
176*a1bf3f78SToomas Soome 	snprintf(buffer, sizeof (buffer), "[0x%016lx %3d] %20e (0x%016lx)\n",
177*a1bf3f78SToomas Soome 	    (unsigned long) cell, context->count++, cell->f, cell->u);
178*a1bf3f78SToomas Soome #else
179*a1bf3f78SToomas Soome 	snprintf(buffer, sizeof (buffer), "[0x%08x %3d] %12e (0x%08x)\n",
180*a1bf3f78SToomas Soome 	    (unsigned)cell, context->count++, cell->f, cell->u);
181*a1bf3f78SToomas Soome #endif
182*a1bf3f78SToomas Soome 	ficlVmTextOut(context->vm, buffer);
183*a1bf3f78SToomas Soome 	return (FICL_TRUE);
184*a1bf3f78SToomas Soome }
185*a1bf3f78SToomas Soome 
186*a1bf3f78SToomas Soome void
187*a1bf3f78SToomas Soome ficlVmDisplayFloatStack(ficlVm *vm)
188*a1bf3f78SToomas Soome {
189*a1bf3f78SToomas Soome 	struct stackContext context;
190*a1bf3f78SToomas Soome 	context.vm = vm;
191*a1bf3f78SToomas Soome 	context.count = 0;
192*a1bf3f78SToomas Soome 	ficlStackDisplay(vm->floatStack, ficlFloatStackDisplayCallback,
193*a1bf3f78SToomas Soome 	    &context);
194*a1bf3f78SToomas Soome }
195*a1bf3f78SToomas Soome 
196*a1bf3f78SToomas Soome /*
197*a1bf3f78SToomas Soome  * Do float stack depth.
198*a1bf3f78SToomas Soome  * fdepth ( -- n )
199*a1bf3f78SToomas Soome  */
200*a1bf3f78SToomas Soome static void
201*a1bf3f78SToomas Soome ficlPrimitiveFDepth(ficlVm *vm)
202*a1bf3f78SToomas Soome {
203*a1bf3f78SToomas Soome 	int i;
204*a1bf3f78SToomas Soome 
205*a1bf3f78SToomas Soome 	FICL_STACK_CHECK(vm->dataStack, 0, 1);
206*a1bf3f78SToomas Soome 
207*a1bf3f78SToomas Soome 	i = ficlStackDepth(vm->floatStack);
208*a1bf3f78SToomas Soome 	ficlStackPushInteger(vm->dataStack, i);
209*a1bf3f78SToomas Soome }
210*a1bf3f78SToomas Soome 
211*a1bf3f78SToomas Soome /*
212*a1bf3f78SToomas Soome  * Compile a floating point literal.
213*a1bf3f78SToomas Soome  */
214*a1bf3f78SToomas Soome static void
215*a1bf3f78SToomas Soome ficlPrimitiveFLiteralImmediate(ficlVm *vm)
216*a1bf3f78SToomas Soome {
217*a1bf3f78SToomas Soome 	ficlDictionary *dictionary = ficlVmGetDictionary(vm);
218*a1bf3f78SToomas Soome 	ficlCell cell;
219*a1bf3f78SToomas Soome 
220*a1bf3f78SToomas Soome 	FICL_STACK_CHECK(vm->floatStack, 1, 0);
221*a1bf3f78SToomas Soome 
222*a1bf3f78SToomas Soome 	cell = ficlStackPop(vm->floatStack);
223*a1bf3f78SToomas Soome 	if (cell.f == 1.0f) {
224*a1bf3f78SToomas Soome 		ficlDictionaryAppendUnsigned(dictionary, ficlInstructionF1);
225*a1bf3f78SToomas Soome 	} else if (cell.f == 0.0f) {
226*a1bf3f78SToomas Soome 		ficlDictionaryAppendUnsigned(dictionary, ficlInstructionF0);
227*a1bf3f78SToomas Soome 	} else if (cell.f == -1.0f) {
228*a1bf3f78SToomas Soome 		ficlDictionaryAppendUnsigned(dictionary, ficlInstructionFNeg1);
229*a1bf3f78SToomas Soome 	} else {
230*a1bf3f78SToomas Soome 		ficlDictionaryAppendUnsigned(dictionary,
231*a1bf3f78SToomas Soome 		    ficlInstructionFLiteralParen);
232*a1bf3f78SToomas Soome 		ficlDictionaryAppendCell(dictionary, cell);
233*a1bf3f78SToomas Soome 	}
234*a1bf3f78SToomas Soome }
235*a1bf3f78SToomas Soome 
236*a1bf3f78SToomas Soome /*
237*a1bf3f78SToomas Soome  * F l o a t P a r s e S t a t e
238*a1bf3f78SToomas Soome  * Enum to determine the current segement of a floating point number
239*a1bf3f78SToomas Soome  * being parsed.
240*a1bf3f78SToomas Soome  */
241*a1bf3f78SToomas Soome #define	NUMISNEG	1
242*a1bf3f78SToomas Soome #define	EXPISNEG	2
243*a1bf3f78SToomas Soome 
244*a1bf3f78SToomas Soome typedef enum _floatParseState
245*a1bf3f78SToomas Soome {
246*a1bf3f78SToomas Soome 	FPS_START,
247*a1bf3f78SToomas Soome 	FPS_ININT,
248*a1bf3f78SToomas Soome 	FPS_INMANT,
249*a1bf3f78SToomas Soome 	FPS_STARTEXP,
250*a1bf3f78SToomas Soome 	FPS_INEXP
251*a1bf3f78SToomas Soome } FloatParseState;
252*a1bf3f78SToomas Soome 
253*a1bf3f78SToomas Soome /*
254*a1bf3f78SToomas Soome  * f i c l P a r s e F l o a t N u m b e r
255*a1bf3f78SToomas Soome  * vm -- Virtual Machine pointer.
256*a1bf3f78SToomas Soome  * s -- String to parse.
257*a1bf3f78SToomas Soome  * Returns 1 if successful, 0 if not.
258*a1bf3f78SToomas Soome  */
259*a1bf3f78SToomas Soome int
260*a1bf3f78SToomas Soome ficlVmParseFloatNumber(ficlVm *vm, ficlString s)
261*a1bf3f78SToomas Soome {
262*a1bf3f78SToomas Soome 	unsigned char c;
263*a1bf3f78SToomas Soome 	unsigned char digit;
264*a1bf3f78SToomas Soome 	char *trace;
265*a1bf3f78SToomas Soome 	ficlUnsigned length;
266*a1bf3f78SToomas Soome 	ficlFloat power;
267*a1bf3f78SToomas Soome 	ficlFloat accum = 0.0f;
268*a1bf3f78SToomas Soome 	ficlFloat mant = 0.1f;
269*a1bf3f78SToomas Soome 	ficlInteger exponent = 0;
270*a1bf3f78SToomas Soome 	char flag = 0;
271*a1bf3f78SToomas Soome 	FloatParseState estate = FPS_START;
272*a1bf3f78SToomas Soome 
273*a1bf3f78SToomas Soome 	FICL_STACK_CHECK(vm->floatStack, 0, 1);
274*a1bf3f78SToomas Soome 
275*a1bf3f78SToomas Soome 	/*
276*a1bf3f78SToomas Soome 	 * floating point numbers only allowed in base 10
277*a1bf3f78SToomas Soome 	 */
278*a1bf3f78SToomas Soome 	if (vm->base != 10)
279*a1bf3f78SToomas Soome 		return (0);
280*a1bf3f78SToomas Soome 
281*a1bf3f78SToomas Soome 	trace = FICL_STRING_GET_POINTER(s);
282*a1bf3f78SToomas Soome 	length = FICL_STRING_GET_LENGTH(s);
283*a1bf3f78SToomas Soome 
284*a1bf3f78SToomas Soome 	/* Loop through the string's characters. */
285*a1bf3f78SToomas Soome 	while ((length--) && ((c = *trace++) != 0)) {
286*a1bf3f78SToomas Soome 		switch (estate) {
287*a1bf3f78SToomas Soome 			/* At start of the number so look for a sign. */
288*a1bf3f78SToomas Soome 		case FPS_START:
289*a1bf3f78SToomas Soome 			estate = FPS_ININT;
290*a1bf3f78SToomas Soome 			if (c == '-') {
291*a1bf3f78SToomas Soome 				flag |= NUMISNEG;
292*a1bf3f78SToomas Soome 				break;
293*a1bf3f78SToomas Soome 			}
294*a1bf3f78SToomas Soome 			if (c == '+') {
295*a1bf3f78SToomas Soome 				break;
296*a1bf3f78SToomas Soome 			}
297*a1bf3f78SToomas Soome 		/* Note!  Drop through to FPS_ININT */
298*a1bf3f78SToomas Soome 		/*
299*a1bf3f78SToomas Soome 		 * Converting integer part of number.
300*a1bf3f78SToomas Soome 		 * Only allow digits, decimal and 'E'.
301*a1bf3f78SToomas Soome 		 */
302*a1bf3f78SToomas Soome 		case FPS_ININT:
303*a1bf3f78SToomas Soome 			if (c == '.') {
304*a1bf3f78SToomas Soome 				estate = FPS_INMANT;
305*a1bf3f78SToomas Soome 			} else if ((c == 'e') || (c == 'E')) {
306*a1bf3f78SToomas Soome 				estate = FPS_STARTEXP;
307*a1bf3f78SToomas Soome 			} else {
308*a1bf3f78SToomas Soome 				digit = (unsigned char)(c - '0');
309*a1bf3f78SToomas Soome 				if (digit > 9)
310*a1bf3f78SToomas Soome 					return (0);
311*a1bf3f78SToomas Soome 
312*a1bf3f78SToomas Soome 				accum = accum * 10 + digit;
313*a1bf3f78SToomas Soome 			}
314*a1bf3f78SToomas Soome 		break;
315*a1bf3f78SToomas Soome 		/*
316*a1bf3f78SToomas Soome 		 * Processing the fraction part of number.
317*a1bf3f78SToomas Soome 		 * Only allow digits and 'E'
318*a1bf3f78SToomas Soome 		 */
319*a1bf3f78SToomas Soome 		case FPS_INMANT:
320*a1bf3f78SToomas Soome 			if ((c == 'e') || (c == 'E')) {
321*a1bf3f78SToomas Soome 				estate = FPS_STARTEXP;
322*a1bf3f78SToomas Soome 			} else {
323*a1bf3f78SToomas Soome 				digit = (unsigned char)(c - '0');
324*a1bf3f78SToomas Soome 				if (digit > 9)
325*a1bf3f78SToomas Soome 					return (0);
326*a1bf3f78SToomas Soome 
327*a1bf3f78SToomas Soome 				accum += digit * mant;
328*a1bf3f78SToomas Soome 				mant *= 0.1f;
329*a1bf3f78SToomas Soome 			}
330*a1bf3f78SToomas Soome 		break;
331*a1bf3f78SToomas Soome 		/* Start processing the exponent part of number. */
332*a1bf3f78SToomas Soome 		/* Look for sign. */
333*a1bf3f78SToomas Soome 		case FPS_STARTEXP:
334*a1bf3f78SToomas Soome 			estate = FPS_INEXP;
335*a1bf3f78SToomas Soome 
336*a1bf3f78SToomas Soome 			if (c == '-') {
337*a1bf3f78SToomas Soome 				flag |= EXPISNEG;
338*a1bf3f78SToomas Soome 				break;
339*a1bf3f78SToomas Soome 			} else if (c == '+') {
340*a1bf3f78SToomas Soome 				break;
341*a1bf3f78SToomas Soome 			}
342*a1bf3f78SToomas Soome 		/* Note!  Drop through to FPS_INEXP */
343*a1bf3f78SToomas Soome 		/*
344*a1bf3f78SToomas Soome 		 * Processing the exponent part of number.
345*a1bf3f78SToomas Soome 		 * Only allow digits.
346*a1bf3f78SToomas Soome 		 */
347*a1bf3f78SToomas Soome 		case FPS_INEXP:
348*a1bf3f78SToomas Soome 			digit = (unsigned char)(c - '0');
349*a1bf3f78SToomas Soome 			if (digit > 9)
350*a1bf3f78SToomas Soome 				return (0);
351*a1bf3f78SToomas Soome 
352*a1bf3f78SToomas Soome 			exponent = exponent * 10 + digit;
353*a1bf3f78SToomas Soome 
354*a1bf3f78SToomas Soome 		break;
355*a1bf3f78SToomas Soome 		}
356*a1bf3f78SToomas Soome 	}
357*a1bf3f78SToomas Soome 
358*a1bf3f78SToomas Soome 	/* If parser never made it to the exponent this is not a float. */
359*a1bf3f78SToomas Soome 	if (estate < FPS_STARTEXP)
360*a1bf3f78SToomas Soome 		return (0);
361*a1bf3f78SToomas Soome 
362*a1bf3f78SToomas Soome 	/* Set the sign of the number. */
363*a1bf3f78SToomas Soome 	if (flag & NUMISNEG)
364*a1bf3f78SToomas Soome 		accum = -accum;
365*a1bf3f78SToomas Soome 
366*a1bf3f78SToomas Soome 	/* If exponent is not 0 then adjust number by it. */
367*a1bf3f78SToomas Soome 	if (exponent != 0) {
368*a1bf3f78SToomas Soome 		/* Determine if exponent is negative. */
369*a1bf3f78SToomas Soome 		if (flag & EXPISNEG) {
370*a1bf3f78SToomas Soome 			exponent = -exponent;
371*a1bf3f78SToomas Soome 		}
372*a1bf3f78SToomas Soome 		/* power = 10^x */
373*a1bf3f78SToomas Soome #if defined(_LP64)
374*a1bf3f78SToomas Soome 		power = (ficlFloat)pow(10.0, exponent);
375*a1bf3f78SToomas Soome #else
376*a1bf3f78SToomas Soome 		power = (ficlFloat)powf(10.0, exponent);
377*a1bf3f78SToomas Soome #endif
378*a1bf3f78SToomas Soome 		accum *= power;
379*a1bf3f78SToomas Soome 	}
380*a1bf3f78SToomas Soome 
381*a1bf3f78SToomas Soome 	ficlStackPushFloat(vm->floatStack, accum);
382*a1bf3f78SToomas Soome 	if (vm->state == FICL_VM_STATE_COMPILE)
383*a1bf3f78SToomas Soome 		ficlPrimitiveFLiteralImmediate(vm);
384*a1bf3f78SToomas Soome 
385*a1bf3f78SToomas Soome 	return (1);
386*a1bf3f78SToomas Soome }
387*a1bf3f78SToomas Soome #endif  /* FICL_WANT_FLOAT */
388*a1bf3f78SToomas Soome 
389*a1bf3f78SToomas Soome #if FICL_WANT_LOCALS
390*a1bf3f78SToomas Soome static void
391*a1bf3f78SToomas Soome ficlPrimitiveFLocalParen(ficlVm *vm)
392*a1bf3f78SToomas Soome {
393*a1bf3f78SToomas Soome 	ficlLocalParen(vm, 0, 1);
394*a1bf3f78SToomas Soome }
395*a1bf3f78SToomas Soome 
396*a1bf3f78SToomas Soome static void
397*a1bf3f78SToomas Soome ficlPrimitiveF2LocalParen(ficlVm *vm)
398*a1bf3f78SToomas Soome {
399*a1bf3f78SToomas Soome 	ficlLocalParen(vm, 1, 1);
400*a1bf3f78SToomas Soome }
401*a1bf3f78SToomas Soome #endif /* FICL_WANT_LOCALS */
402*a1bf3f78SToomas Soome 
403*a1bf3f78SToomas Soome /*
404*a1bf3f78SToomas Soome  * Add float words to a system's dictionary.
405*a1bf3f78SToomas Soome  * system -- Pointer to the Ficl sytem to add float words to.
406*a1bf3f78SToomas Soome  */
407*a1bf3f78SToomas Soome void
408*a1bf3f78SToomas Soome ficlSystemCompileFloat(ficlSystem *system)
409*a1bf3f78SToomas Soome {
410*a1bf3f78SToomas Soome 	ficlDictionary *dictionary = ficlSystemGetDictionary(system);
411*a1bf3f78SToomas Soome 	ficlDictionary *environment = ficlSystemGetEnvironment(system);
412*a1bf3f78SToomas Soome #if FICL_WANT_FLOAT
413*a1bf3f78SToomas Soome 	ficlCell data;
414*a1bf3f78SToomas Soome #endif
415*a1bf3f78SToomas Soome 
416*a1bf3f78SToomas Soome 	FICL_SYSTEM_ASSERT(system, dictionary);
417*a1bf3f78SToomas Soome 	FICL_SYSTEM_ASSERT(system, environment);
418*a1bf3f78SToomas Soome 
419*a1bf3f78SToomas Soome #if FICL_WANT_LOCALS
420*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "(flocal)",
421*a1bf3f78SToomas Soome 	    ficlPrimitiveFLocalParen, FICL_WORD_COMPILE_ONLY);
422*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "(f2local)",
423*a1bf3f78SToomas Soome 	    ficlPrimitiveF2LocalParen, FICL_WORD_COMPILE_ONLY);
424*a1bf3f78SToomas Soome #endif /* FICL_WANT_LOCALS */
425*a1bf3f78SToomas Soome 
426*a1bf3f78SToomas Soome #if FICL_WANT_FLOAT
427*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "fconstant",
428*a1bf3f78SToomas Soome 	    ficlPrimitiveFConstant, FICL_WORD_DEFAULT);
429*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "fvalue",
430*a1bf3f78SToomas Soome 	    ficlPrimitiveFConstant, FICL_WORD_DEFAULT);
431*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "f2constant",
432*a1bf3f78SToomas Soome 	    ficlPrimitiveF2Constant, FICL_WORD_DEFAULT);
433*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "f2value",
434*a1bf3f78SToomas Soome 	    ficlPrimitiveF2Constant, FICL_WORD_DEFAULT);
435*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "fdepth", ficlPrimitiveFDepth,
436*a1bf3f78SToomas Soome 	    FICL_WORD_DEFAULT);
437*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "fliteral",
438*a1bf3f78SToomas Soome 	    ficlPrimitiveFLiteralImmediate, FICL_WORD_IMMEDIATE);
439*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "f.", ficlPrimitiveFDot,
440*a1bf3f78SToomas Soome 	    FICL_WORD_DEFAULT);
441*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "f.s", ficlVmDisplayFloatStack,
442*a1bf3f78SToomas Soome 	    FICL_WORD_DEFAULT);
443*a1bf3f78SToomas Soome 	ficlDictionarySetPrimitive(dictionary, "fe.", ficlPrimitiveEDot,
444*a1bf3f78SToomas Soome 	    FICL_WORD_DEFAULT);
445*a1bf3f78SToomas Soome 
446*a1bf3f78SToomas Soome 	/*
447*a1bf3f78SToomas Soome 	 * Missing words:
448*a1bf3f78SToomas Soome 	 *
449*a1bf3f78SToomas Soome 	 * d>f
450*a1bf3f78SToomas Soome 	 * f>d
451*a1bf3f78SToomas Soome 	 * falign
452*a1bf3f78SToomas Soome 	 * faligned
453*a1bf3f78SToomas Soome 	 * float+
454*a1bf3f78SToomas Soome 	 * floats
455*a1bf3f78SToomas Soome 	 * floor
456*a1bf3f78SToomas Soome 	 * fmax
457*a1bf3f78SToomas Soome 	 * fmin
458*a1bf3f78SToomas Soome 	 */
459*a1bf3f78SToomas Soome 
460*a1bf3f78SToomas Soome #if defined(_LP64)
461*a1bf3f78SToomas Soome 	data.f = MAXDOUBLE;
462*a1bf3f78SToomas Soome #else
463*a1bf3f78SToomas Soome 	data.f = MAXFLOAT;
464*a1bf3f78SToomas Soome #endif
465*a1bf3f78SToomas Soome 	ficlDictionarySetConstant(environment, "max-float",	data.i);
466*a1bf3f78SToomas Soome 	/* not all required words are present */
467*a1bf3f78SToomas Soome 	ficlDictionarySetConstant(environment, "floating", FICL_FALSE);
468*a1bf3f78SToomas Soome 	ficlDictionarySetConstant(environment, "floating-ext", FICL_FALSE);
469*a1bf3f78SToomas Soome 	ficlDictionarySetConstant(environment, "floating-stack",
470*a1bf3f78SToomas Soome 	    system->stackSize);
471*a1bf3f78SToomas Soome #else
472*a1bf3f78SToomas Soome 	ficlDictionarySetConstant(environment, "floating", FICL_FALSE);
473*a1bf3f78SToomas Soome #endif
474*a1bf3f78SToomas Soome }
475