From 5f8f0ed5cd5d4b4f793c602ed09f9b4bdb98f7e8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 18 Nov 2017 20:38:15 -0800 Subject: altos/lisp: Add 'big' ints -- 24 bits wide With the default ints being only 14 bits, having a larger type with more precision seems useful. This is not exposed to the application. Signed-off-by: Keith Packard --- src/lisp/ao_lisp_int.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'src/lisp/ao_lisp_int.c') diff --git a/src/lisp/ao_lisp_int.c b/src/lisp/ao_lisp_int.c index 3b5341bd..8e467755 100644 --- a/src/lisp/ao_lisp_int.c +++ b/src/lisp/ao_lisp_int.c @@ -20,3 +20,60 @@ ao_lisp_int_write(ao_poly p) int i = ao_lisp_poly_int(p); printf("%d", i); } + +int32_t +ao_lisp_poly_integer(ao_poly p) +{ + switch (ao_lisp_poly_base_type(p)) { + case AO_LISP_INT: + return ao_lisp_poly_int(p); + case AO_LISP_OTHER: + if (ao_lisp_other_type(ao_lisp_poly_other(p)) == AO_LISP_BIGINT) + return ao_lisp_bigint_int(ao_lisp_poly_bigint(p)->value); + } + return AO_LISP_NOT_INTEGER; +} + +ao_poly +ao_lisp_integer_poly(int32_t p) +{ + struct ao_lisp_bigint *bi; + + if (AO_LISP_MIN_INT <= p && p <= AO_LISP_MAX_INT) + return ao_lisp_int_poly(p); + bi = ao_lisp_alloc(sizeof (struct ao_lisp_bigint)); + bi->value = ao_lisp_int_bigint(p); + return ao_lisp_bigint_poly(bi); +} + +static void bigint_mark(void *addr) +{ + (void) addr; +} + +static int bigint_size(void *addr) +{ + if (!addr) + return 0; + return sizeof (struct ao_lisp_bigint); +} + +static void bigint_move(void *addr) +{ + (void) addr; +} + +const struct ao_lisp_type ao_lisp_bigint_type = { + .mark = bigint_mark, + .size = bigint_size, + .move = bigint_move, + .name = "bigint", +}; + +void +ao_lisp_bigint_write(ao_poly p) +{ + struct ao_lisp_bigint *bi = ao_lisp_poly_bigint(p); + + printf("%d", ao_lisp_bigint_int(bi->value)); +} -- cgit v1.2.3