Adjust number-reader to allow 'negative zero' FP values.

Also add builtins for NaN and +/- infinity, and bytecodes for classification.
This commit is contained in:
Jesse D. McDonald 2009-11-17 01:07:42 -06:00
parent aa461c8574
commit b74f0cddda
5 changed files with 39 additions and 8 deletions

View File

@ -2,6 +2,7 @@
#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
#include <math.h>
#include "gc.h"
#include "builtin.h"
@ -19,12 +20,22 @@ void builtin_init(void)
{
gc_root_t ms_root;
register_gc_root(&builtin_list, UNDEFINED);
register_gc_root(&builtin_list, NIL);
register_gc_root(&ms_root, UNDEFINED);
register_builtin(BI_UNDEFINED, UNDEFINED);
register_builtin(BI_STRING_TO_NUMBER, make_builtin_fn(bi_string_to_number));
#ifdef NAN
register_builtin(BI_POS_NAN, make_float(NAN));
register_builtin(BI_NEG_NAN, make_float(-NAN));
#endif
#ifdef INFINITY
register_builtin(BI_POS_INFINITY, make_float(INFINITY));
register_builtin(BI_NEG_INFINITY, make_float(-INFINITY));
#endif
register_structure(&ms_root);
register_template(&ms_root);
register_lambda(&ms_root);

View File

@ -8,10 +8,14 @@
#include "gc.h"
/* Names of fundamental builtin values */
#define BI_UNDEFINED "undefined"
#define BI_STRUCTURE "structure"
#define BI_TEMPLATE "template"
#define BI_LAMBDA "lambda"
#define BI_UNDEFINED "undefined"
#define BI_STRUCTURE "structure"
#define BI_TEMPLATE "template"
#define BI_LAMBDA "lambda"
#define BI_POS_NAN "+NaN"
#define BI_NEG_NAN "-NaN"
#define BI_POS_INFINITY "+infinity"
#define BI_NEG_INFINITY "-infinity"
/* Name of builtin function */
#define BI_STRING_TO_NUMBER "string->number"

View File

@ -75,6 +75,14 @@ unary-expr: up to 255, 1 out, 1 in
5d (set! out (ilogb in))
5e (set! out (log1p in))
; (set! out (rint in)) ; implies changing rounding mode; use floor or ceil
; C99
70 (set! out (normal? in))
71 (set! out (finite? in))
72 (set! out (subnormal? in))
73 (set! out (infinite? in))
74 (set! out (nan? in))
binary-expr: up to 63 (01..3f), 1 out, 2 in
00 unary-expr

View File

@ -451,6 +451,11 @@ static value_t eval_unary_expression(interp_state_t *state, uint8_t subcode, uin
case 0x5c: return make_float(expm1(get_float(ST1)));
case 0x5d: return make_float(ilogb(get_float(ST1)));
case 0x5e: return make_float(log1p(get_float(ST1)));
case 0x70: return boolean_value(isnormal(get_float(ST1)));
case 0x71: return boolean_value(isfinite(get_float(ST1)));
case 0x72: return boolean_value(fpclassify(get_float(ST1)) == FP_SUBNORMAL);
case 0x73: return boolean_value(isinf(get_float(ST1)));
case 0x74: return boolean_value(isnan(get_float(ST1)));
default: release_assert(NOTREACHED("Invalid unary sub-bytecode."));
}

View File

@ -382,11 +382,10 @@ static value_t read_number(reader_state_t *state)
next_char(state);
}
if (negative)
num = -num;
if ((radix != 10) || ((state->ch != '.') && (state->ch != 'E') && (state->ch != 'e')))
{
if (negative)
num = -num;
release_assert(!issymbol(state->ch));
release_assert((FIXNUM_MIN <= num) && (num <= FIXNUM_MAX));
return fixnum_value(num);
@ -416,6 +415,9 @@ static value_t read_number(reader_state_t *state)
flt *= pow(10, _get_fixnum(num));
}
if (negative)
flt = -flt;
release_assert(!issymbol(state->ch));
return make_float(flt);
}
@ -653,6 +655,7 @@ static value_t read_placeholder(reader_state_t *state)
char *name = value_to_string(read_string(state));
value_t bi = lookup_builtin(name);
free(name);
release_assert(bi != FALSE_VALUE);
return bi;
}
else