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
ficlPrimitiveFConstant(ficlVm * vm)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 *
ficlDictionaryAppendFConstant(ficlDictionary * dictionary,char * name,ficlFloat value)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 *
ficlDictionarySetFConstant(ficlDictionary * dictionary,char * name,ficlFloat value)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
ficlPrimitiveF2Constant(ficlVm * vm)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 *
ficlDictionaryAppendF2Constant(ficlDictionary * dictionary,char * name,ficlFloat value)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 *
ficlDictionarySetF2Constant(ficlDictionary * dictionary,char * name,ficlFloat value)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
ficlPrimitiveFDot(ficlVm * vm)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
ficlPrimitiveEDot(ficlVm * vm)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
ficlFloatStackDisplayCallback(void * c,ficlCell * cell)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
ficlVmDisplayFloatStack(ficlVm * vm)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
ficlPrimitiveFDepth(ficlVm * vm)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
ficlPrimitiveFLiteralImmediate(ficlVm * vm)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
ficlVmParseFloatNumber(ficlVm * vm,ficlString s)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
ficlPrimitiveFLocalParen(ficlVm * vm)391a1bf3f78SToomas Soome ficlPrimitiveFLocalParen(ficlVm *vm)
392a1bf3f78SToomas Soome {
393a1bf3f78SToomas Soome ficlLocalParen(vm, 0, 1);
394a1bf3f78SToomas Soome }
395a1bf3f78SToomas Soome
396a1bf3f78SToomas Soome static void
ficlPrimitiveF2LocalParen(ficlVm * vm)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
ficlSystemCompileFloat(ficlSystem * system)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