klisp

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

commit a17b92ab13765fbab1277fd5978f28bbf7717d22
parent c2befd746ede5e81fd8764a5f335ec1b9d2be1c7
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 23 Apr 2011 14:48:20 -0300

Added bigint support to write (uses imrat directly).

Diffstat:
Msrc/krational.c | 17+++++++++++++++++
Msrc/krational.h | 4++++
Msrc/kwrite.c | 21+++++++++++++++++++++
3 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/src/krational.c b/src/krational.c @@ -79,6 +79,23 @@ TValue kbigrat_copy(klisp_State *K, TValue src) return copy; } +/* 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) +{ + return mp_rat_string_len(tv2bigrat(tv_bigint), base); +} + +/* this is used by write */ +void kbigrat_print_string(klisp_State *K, TValue tv_bigrat, int32_t base, + char *buf, int32_t limit) +{ + mp_result res = mp_rat_to_string(K, tv2bigrat(tv_bigrat), base, buf, + limit); + /* only possible error is truncation */ + klisp_assert(res == MP_OK); +} + /* Interface for kgnumbers */ /* The compare predicates take a klisp_State because in general diff --git a/src/krational.h b/src/krational.h @@ -97,6 +97,10 @@ KUNIQUE_NAME(bigrat_bigint_lbl): \ (n) = gc2bigrat(KUNIQUE_NAME(brat)); \ KUNIQUE_NAME(bigrat_exit_lbl): +/* read/write interface */ +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 */ diff --git a/src/kwrite.c b/src/kwrite.c @@ -72,6 +72,24 @@ void kw_print_bigint(klisp_State *K, TValue bigint) krooted_tvs_pop(K); } +void kw_print_bigrat(klisp_State *K, TValue bigrat) +{ + int32_t radix = KDEFAULT_NUMBER_RADIX; + int32_t size = kbigrat_print_size(bigrat, radix); + krooted_tvs_push(K, bigrat); + /* here we are using 1 byte extra, because size already includes + 1 for the terminator, but better be safe than sorry */ + TValue buf_str = kstring_new_s(K, size); + krooted_tvs_push(K, buf_str); + + char *buf = kstring_buf(buf_str); + kbigrat_print_string(K, bigrat, radix, buf, size); + kw_printf(K, "%s", buf); + + krooted_tvs_pop(K); + krooted_tvs_pop(K); +} + /* ** Helper for printing strings (correcly escapes backslashes and ** double quotes & prints embedded '\0's). It includes the surrounding @@ -248,6 +266,9 @@ void kwrite_simple(klisp_State *K, TValue obj) case K_TBIGINT: kw_print_bigint(K, obj); break; + case K_TBIGRAT: + kw_print_bigrat(K, obj); + break; case K_TNIL: kw_printf(K, "()"); break;