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