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