From 96ca2263af6d12d875d1ac729c6c268d00fad8dc Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Tue, 14 Jun 2022 22:32:05 -0400 Subject: [PATCH] Working version of str2bignum --- include/cyclone/types.h | 2 +- runtime.c | 25 +++++++++++++++---------- test-bn.scm | 6 ++++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/include/cyclone/types.h b/include/cyclone/types.h index f1c3e9fc..99a7f981 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -1608,7 +1608,7 @@ void Cyc_int2bignum(int n, mp_int *bn); object Cyc_int2bignum2(gc_thread_data *data, int n); // TODO: debug only, remove this function from here! string_type *bignum2string(void *data, bignum2_type *bn, int base); -void _str_to_bignum(void *data, char *str, *char *str_end, int radix); +object _str_to_bignum(void *data, char *str, char *str_end, int radix); object bignum2_plus_unsigned(void *data, bignum2_type *x, bignum2_type *y, int negp); /* Remaining GC prototypes that require objects to be defined */ diff --git a/runtime.c b/runtime.c index 28e16625..7daaa815 100644 --- a/runtime.c +++ b/runtime.c @@ -2948,16 +2948,6 @@ inline static int hex_char_to_digit(int ch) else return ch - (int)'0'; /* decimal (OR INVALID; handled elsewhere) */ } -void _str_to_bignum(void *data, char *str, *char *str_end, int radix) -{ - TODO: - need to figure out sign, size (using nlz), what else?? - bignum2_type *bn = gc_alloc_bignum2(data, 2); - bn->num_digits = 2; - bn->sign = 0; - str_to_bignum(data, bn, str, str_end, radix); -} - /* Write from digit character stream to bignum. Bignum does not need * to be initialised. Returns the bignum, or a fixnum. Assumes the * string contains only digits that fit within radix (checked by @@ -3022,6 +3012,21 @@ static object str_to_bignum(void *data, object bignum, char *str, char *str_end, return C_bignum_simplify(bignum); } +object _str_to_bignum(void *data, char *str, char *str_end, int radix) +{ + int negp = 0; + size_t nbits; + uint32_t size; + if (*str == '+' || *str == '-') { + negp = ((*str++) == '-') ? 1 : 0; + } + nbits = (str_end - str) * nlz(radix - 1); + size = C_BIGNUM_BITS_TO_DIGITS(nbits); + bignum2_type *bn = gc_alloc_bignum2(data, size); + bn->sign = negp; + return str_to_bignum(data, bn, str, str_end, radix); +} + // TODO: static //object bignum_plus_unsigned(C_word **ptr, C_word x, C_word y, C_word negp) object bignum2_plus_unsigned(void *data, bignum2_type *x, bignum2_type *y, int negp) diff --git a/test-bn.scm b/test-bn.scm index 53828522..9ad45cc1 100644 --- a/test-bn.scm +++ b/test-bn.scm @@ -17,8 +17,7 @@ "(void *data, int argc, closure _, object k, object str, object radix)" " int len = string_len(str); char *s = string_str(str); - bignum2_type *bn = gc_alloc_bignum2(data, len); - bn = str_to_bignum(data, bn, s, s + len, obj_obj2int(radix)); + object bn = _str_to_bignum(data, s, s + len, obj_obj2int(radix)); return_closcall1(data, k, bn); ") (define-c test-plus @@ -55,6 +54,9 @@ if(is_value_type(result)) { (write (test-str2bn "123454354534523454243999" 10)) (newline) +(write (test-str2bn "-123454354534523454243999" 10)) +(newline) + (write (test-str2bn "123454354534523454243999" 16)) (newline)