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:
parent
aa461c8574
commit
b74f0cddda
13
builtin.c
13
builtin.c
|
|
@ -2,6 +2,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
|
@ -19,12 +20,22 @@ void builtin_init(void)
|
||||||
{
|
{
|
||||||
gc_root_t ms_root;
|
gc_root_t ms_root;
|
||||||
|
|
||||||
register_gc_root(&builtin_list, UNDEFINED);
|
register_gc_root(&builtin_list, NIL);
|
||||||
register_gc_root(&ms_root, UNDEFINED);
|
register_gc_root(&ms_root, UNDEFINED);
|
||||||
|
|
||||||
register_builtin(BI_UNDEFINED, UNDEFINED);
|
register_builtin(BI_UNDEFINED, UNDEFINED);
|
||||||
register_builtin(BI_STRING_TO_NUMBER, make_builtin_fn(bi_string_to_number));
|
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_structure(&ms_root);
|
||||||
register_template(&ms_root);
|
register_template(&ms_root);
|
||||||
register_lambda(&ms_root);
|
register_lambda(&ms_root);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@
|
||||||
#define BI_STRUCTURE "structure"
|
#define BI_STRUCTURE "structure"
|
||||||
#define BI_TEMPLATE "template"
|
#define BI_TEMPLATE "template"
|
||||||
#define BI_LAMBDA "lambda"
|
#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 */
|
/* Name of builtin function */
|
||||||
#define BI_STRING_TO_NUMBER "string->number"
|
#define BI_STRING_TO_NUMBER "string->number"
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,14 @@ unary-expr: up to 255, 1 out, 1 in
|
||||||
5d (set! out (ilogb in))
|
5d (set! out (ilogb in))
|
||||||
5e (set! out (log1p in))
|
5e (set! out (log1p in))
|
||||||
; (set! out (rint in)) ; implies changing rounding mode; use floor or ceil
|
; (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
|
binary-expr: up to 63 (01..3f), 1 out, 2 in
|
||||||
00 unary-expr
|
00 unary-expr
|
||||||
|
|
||||||
|
|
|
||||||
5
interp.c
5
interp.c
|
|
@ -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 0x5c: return make_float(expm1(get_float(ST1)));
|
||||||
case 0x5d: return make_float(ilogb(get_float(ST1)));
|
case 0x5d: return make_float(ilogb(get_float(ST1)));
|
||||||
case 0x5e: return make_float(log1p(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."));
|
default: release_assert(NOTREACHED("Invalid unary sub-bytecode."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
9
reader.c
9
reader.c
|
|
@ -382,11 +382,10 @@ static value_t read_number(reader_state_t *state)
|
||||||
next_char(state);
|
next_char(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negative)
|
|
||||||
num = -num;
|
|
||||||
|
|
||||||
if ((radix != 10) || ((state->ch != '.') && (state->ch != 'E') && (state->ch != 'e')))
|
if ((radix != 10) || ((state->ch != '.') && (state->ch != 'E') && (state->ch != 'e')))
|
||||||
{
|
{
|
||||||
|
if (negative)
|
||||||
|
num = -num;
|
||||||
release_assert(!issymbol(state->ch));
|
release_assert(!issymbol(state->ch));
|
||||||
release_assert((FIXNUM_MIN <= num) && (num <= FIXNUM_MAX));
|
release_assert((FIXNUM_MIN <= num) && (num <= FIXNUM_MAX));
|
||||||
return fixnum_value(num);
|
return fixnum_value(num);
|
||||||
|
|
@ -416,6 +415,9 @@ static value_t read_number(reader_state_t *state)
|
||||||
flt *= pow(10, _get_fixnum(num));
|
flt *= pow(10, _get_fixnum(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (negative)
|
||||||
|
flt = -flt;
|
||||||
|
|
||||||
release_assert(!issymbol(state->ch));
|
release_assert(!issymbol(state->ch));
|
||||||
return make_float(flt);
|
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));
|
char *name = value_to_string(read_string(state));
|
||||||
value_t bi = lookup_builtin(name);
|
value_t bi = lookup_builtin(name);
|
||||||
free(name);
|
free(name);
|
||||||
|
release_assert(bi != FALSE_VALUE);
|
||||||
return bi;
|
return bi;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue