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;