alignas (16) evaltype type;
pool_ptr rest;
uint32_t _pad;
- uint32_t val;
+ int32_t val;
} fix32_object;
typedef struct
{
alignas (16) evaltype type;
pool_ptr rest;
- uint64_t val;
+ int64_t val;
} fix64_object;
typedef struct
Initialization helpers.
*/
+static inline fix32_object
+new_fix32 (int32_t n)
+{
+ return (fix32_object)
+ {
+ .type = EVALTYPE_FIX32,.rest = 0,.val = n};
+}
+
static inline fix64_object
-new_fix64 (uint64_t n)
+new_fix64 (int64_t n)
{
return (fix64_object)
{
- .type = EVALTYPE_FIX64,.rest = 0,.val = n,};
+ .type = EVALTYPE_FIX64,.rest = 0,.val = n};
}
static inline list_object
}
*/
+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])
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;
}