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:
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;