klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 7b98068825e88e638af5ac324ce08ec415279bdc
parent 5d736f60adf21e3eb6e778e8b5a855a5c6fc6fcb
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 23 Apr 2011 16:05:29 -0300

Refactored shared token reader to use kinteger_read.

Diffstat:
Msrc/kinteger.c | 44+++-----------------------------------------
Msrc/ktoken.c | 41++++++++++++++++++++---------------------
2 files changed, 23 insertions(+), 62 deletions(-)

diff --git a/src/kinteger.c b/src/kinteger.c @@ -66,47 +66,9 @@ TValue kbigint_copy(klisp_State *K, TValue src) return copy; } -/* This algorithm is like a fused multiply add on bignums, - unlike any other function here it modifies bigint. It is used in read - and it assumes that bigint is positive */ -/* GC: Assumes tv_bigint is rooted */ -void kbigint_add_digit(klisp_State *K, TValue tv_bigint, int32_t base, - int32_t digit) -{ - Bigint *bigint = tv2bigint(tv_bigint); - UNUSED(mp_int_mul_value(K, bigint, base, bigint)); - UNUSED(mp_int_add_value(K, bigint, digit, bigint)); -} - -/* This is used by the writer to get the digits of a number - tv_bigint must be positive */ -/* GC: Assumes tv_bigint is rooted */ -int32_t kbigint_remove_digit(klisp_State *K, TValue tv_bigint, int32_t base) -{ - UNUSED(K); - Bigint *bigint = tv2bigint(tv_bigint); - int32_t r; - UNUSED(mp_int_div_value(K, bigint, base, bigint, &r)); - return r; -} - -/* This is used by write to test if there is any digit left to print */ -bool kbigint_has_digits(klisp_State *K, TValue tv_bigint) -{ - UNUSED(K); - return (mp_int_compare_zero(tv2bigint(tv_bigint)) != 0); -} - -/* Mutate the bigint to have the opposite sign, used in read - and write*/ -/* GC: Assumes tv_bigint is rooted */ -void kbigint_invert_sign(klisp_State *K, TValue tv_bigint) -{ - Bigint *bigint = tv2bigint(tv_bigint); - UNUSED(mp_int_neg(K, bigint, bigint)); -} - -/* read/write interface */ +/* +** read/write interface +*/ /* this works for bigints & fixints, returns true if ok */ bool kinteger_read(klisp_State *K, char *buf, int32_t base, TValue *out, diff --git a/src/ktoken.c b/src/ktoken.c @@ -599,34 +599,33 @@ TValue ktok_read_special(klisp_State *K) token, or a char constant or a number. srfi-38 tokens are a '#' a decimal number and end with a '=' or a '#' */ if (buf_len > 2 && ktok_is_numeric(buf[1])) { + /* NOTE: it's important to check is_numeric to avoid problems with + sign in kinteger_read */ /* srfi-38 type token (can be either a def or ref) */ + /* TODO: lift this implementation restriction */ /* IMPLEMENTATION RESTRICTION: only allow fixints in shared tokens */ - int32_t res = 0; - int32_t i = 1; - char ch = buf[i]; - while(i < buf_len && ch != '#' && ch != '=') { - if (!ktok_is_numeric(ch)) { - ktok_error(K, "Invalid char found in srfi-38 token"); - /* avoid warning */ - return KINERT; - } + char ch = buf[buf_len-1]; /* remember last char */ + buf[buf_len-1] = '\0'; /* replace last char with 0 to read number */ - int new_digit = ktok_digit_value(ch); - if (can_add_digit(res, false, new_digit, 10)) { - res = res * 10 + new_digit; - } else { - ktok_error(K, "IMP. RESTRICTION: shared token too big"); - /* avoid warning */ - return KINERT; - } - ch = buf[++i]; - } - if (i == buf_len) { + if (ch != '#' && ch != '=') { ktok_error(K, "Missing last char in srfi-38 token"); return KINERT; } /* else buf[i] == '#' or '=' */ + TValue n; + char *end; + /* 10 is the radix for srfi-38 tokens, buf+1 to jump over the '#', + end+1 to count the last char */ + if (!kinteger_read(K, buf+1, 10, &n, &end) || end+1 - buf != buf_len) { + ktok_error(K, "Bad char in srfi-38 token"); + return KINERT; + } else if (!ttisfixint(n)) { + ktok_error(K, "IMP. RESTRICTION: shared token too big"); + /* avoid warning */ + return KINERT; + } ks_tbclear(K); - return kcons(K, ch2tv(ch), i2tv(res)); + /* GC: no need to root n, for now it's a fixint */ + return kcons(K, ch2tv(ch), n); } /* REFACTOR: move to new function */