X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Fread.c;h=68efbf3eef5c2c5434c4550a23f692f464508976;hb=c25d7ca5386582feba3d02f69a7425ea5b868bc7;hp=57dd81f511d8f3538e73ee7efed7bd1bd7945029;hpb=6c1eef40f411ff4eec7a3f7599a81be7fae07e2a;p=muddle-interpreter.git diff --git a/src/read.c b/src/read.c index 57dd81f..68efbf3 100644 --- a/src/read.c +++ b/src/read.c @@ -113,10 +113,70 @@ static uint32_t obj_get_fix32(const object *o) { } */ +static int +read_num (const char *p, reader_stack *st) +{ + int i = 0; + // Use an unsigned intermediate to simplify overflow checks. + uint64_t x = 0; + // Disallow "number" composed of ancillary number components only. + bool gotdigits = false; + // Skip for now, later we'll check again to potentially negate. + if (p[0] == '-') + i++; + // TODO: asterisk-deliminated *octal* + // TODO: other bases? + for (; p[i]; i++) + { + if (p[i] >= '0' && p[i] <= '9') + { + if (x * 10 + (p[i] - '0') < x) + goto read_float; + x = x * 10 + (p[i] - '0'); + gotdigits = true; + continue; + } + + // TODO: decimal points, exponent notation + // NB. a terminal decimal denotes a FIX + // NB. exponent notation doesn't necessarily indicate a float + + // TODO: distinguish 'delimiter' characters that terminate + // number from 'identifier' chars that cause parsing to fail + // (and potentially be parsed as an atom) + break; + } + if (!gotdigits) + return 0; + if (p[0] != '-') + { + if (x <= INT32_MAX) + (--(st->pos))->fix32 = new_fix32 ((int32_t)x); + else if (x <= INT64_MAX) + (--(st->pos))->fix64 = new_fix64 (x); + else + goto read_float; + } + else + { + if (-x >= (uint64_t)INT32_MIN) + (--(st->pos))->fix32 = new_fix32 (0 - (int32_t)x); + else if (-x >= (uint64_t)INT64_MIN) + (--(st->pos))->fix64 = new_fix64 (0 - (int64_t)x); + else + goto read_float; + } + st->framelen++; + return i; + read_float: + assert(0 && "unimplemented: promote num to float"); + return i; +} + // stack[0..len]: objs in current list // stack[len]: parent len const char * -read_token (const char *p, reader_stack * st) +read_token (const char *p, reader_stack *st) { p += count_whitespace (p); switch (p[0]) @@ -191,17 +251,17 @@ read_token (const char *p, reader_stack * st) st->pos->vector = new_vector (h, len); break; } - case '4': + default: { - p++; - // push fix obj, extending frame - (--(st->pos))->fix64 = new_fix64 (4); - st->framelen++; - break; + int n = read_num (p, st); + if (n) + return p + n; + + // TODO: try read pname + + fprintf (stderr, "read unimplemented for char: '%c'\n", *p); + assert (0 && "read unimplemented for char"); } - default: - fprintf (stderr, "read unimplemented for char: '%c'\n", *p); - assert (0 && "read unimplemented for char"); } return p; }