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