klisp

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

commit 8a5173acbe9ddc2908d23ccc89de694d2b01848c
parent 7b98068825e88e638af5ac324ce08ec415279bdc
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 23 Apr 2011 16:17:02 -0300

Added read support for bigrat read. BUT there is a bug somewhere, it reads as a rare integer...

Diffstat:
Msrc/krational.c | 29+++++++++++++++++++++++++++++
Msrc/krational.h | 34+++++++++++-----------------------
Msrc/ktoken.c | 13+++++++++++--
3 files changed, 51 insertions(+), 25 deletions(-)

diff --git a/src/krational.c b/src/krational.c @@ -79,6 +79,35 @@ TValue kbigrat_copy(klisp_State *K, TValue src) return copy; } +/* +** read/write interface +*/ +/* this works for bigrats, bigints & fixints, returns true if ok */ +bool krational_read(klisp_State *K, char *buf, int32_t base, TValue *out, + char **end) +{ + TValue res = kbigrat_new(K, false, 0, 1); + krooted_tvs_push(K, res); + bool ret_val = (mp_rat_read_cstring(K, tv2bigrat(res), base, + buf, end) == MP_OK); + krooted_tvs_pop(K); + *out = kbigrat_try_integer(K, res); + return ret_val; +} + +/* NOTE: allow decimal for use after #e */ +bool krational_read_decimal(klisp_State *K, char *buf, int32_t base, TValue *out, + char **end) +{ + TValue res = kbigrat_new(K, false, 0, 1); + krooted_tvs_push(K, res); + bool ret_val = (mp_rat_read_ustring(K, tv2bigrat(res), base, + buf, end) == MP_OK); + krooted_tvs_pop(K); + *out = kbigrat_try_integer(K, res); + return ret_val; +} + /* this is used by write to estimate the number of chars necessary to print the number */ int32_t kbigrat_print_size(TValue tv_bigint, int32_t base) diff --git a/src/krational.h b/src/krational.h @@ -97,32 +97,20 @@ KUNIQUE_NAME(bigrat_bigint_lbl): \ (n) = gc2bigrat(KUNIQUE_NAME(brat)); \ KUNIQUE_NAME(bigrat_exit_lbl): -/* read/write interface */ +/* +** read/write interface +*/ +/* this works for bigrats, bigints & fixints, returns true if ok */ +/* NOTE: doesn't allow decimal */ +bool krational_read(klisp_State *K, char *buf, int32_t base, TValue *out, + char **end); +/* NOTE: allow decimal for use after #e */ +bool krational_read_decimal(klisp_State *K, char *buf, int32_t base, TValue *out, + char **end); + int32_t kbigrat_print_size(TValue tv_bigrat, int32_t base); void kbigrat_print_string(klisp_State *K, TValue tv_bigrat, int32_t base, char *buf, int32_t limit); -#if 0 -/* This is used by the reader to destructively add digits to a number - tv_bigrat must be positive */ -void kbigrat_add_digit(klisp_State *K, TValue tv_bigrat, int32_t base, - int32_t digit); - -/* This is used by the writer to get the digits of a number - tv_bigrat must be positive */ -int32_t kbigrat_remove_digit(klisp_State *K, TValue tv_bigrat, int32_t base); - -/* This is used by write to test if there is any digit left to print */ -bool kbigrat_has_digits(klisp_State *K, TValue tv_bigrat); - -/* Mutate the bigrat to have the opposite sign, used in read & write */ -void kbigrat_invert_sign(klisp_State *K, TValue tv_bigrat); - -/* this is used by write to estimate the number of chars necessary to - print the number */ -int32_t kbigrat_print_size(TValue tv_bigrat, int32_t base); - -#endif /* #if 0 */ - /* Interface for kgnumbers */ bool kbigrat_eqp(klisp_State *K, TValue bigrat1, TValue bigrat2); diff --git a/src/ktoken.c b/src/ktoken.c @@ -401,12 +401,21 @@ TValue ktok_read_number(klisp_State *K, char *buf, int32_t len, { UNUSED(len); /* not needed really, buf ends with '\0' */ TValue n; - if (!kinteger_read(K, buf, radix, &n, NULL)) { + if (has_exactp) { + /* TEMP: while there are no inexacts */ + /* allow decimals if has #e prefix */ + if (!krational_read_decimal(K, buf, radix, &n, NULL)) { /* TODO throw meaningful error msgs, use last param */ ktok_error(K, "Bad format in number"); return KINERT; + } + } else { + if (!krational_read(K, buf, radix, &n, NULL)) { + /* TODO throw meaningful error msgs, use last param */ + ktok_error(K, "Bad format in number"); + return KINERT; + } } - ks_tbclear(K); return n; }