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