klisp

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

commit 6ef22cc59aadd05ccb75df7d5dc097b26608fc76
parent f4a846b7af7d9d9e1bb8875b5ca1a3127125da4f
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Tue, 12 Apr 2011 01:55:25 -0300

Changed all of kinteger to use the IMath library.

Diffstat:
Msrc/Makefile | 2+-
Msrc/kinteger.c | 82+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/kinteger.h | 2+-
Msrc/ktoken.c | 2+-
Msrc/kwrite.c | 2+-
5 files changed, 49 insertions(+), 41 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -54,7 +54,7 @@ ksymbol.o: ksymbol.c ksymbol.h kobject.h kpair.h kstring.h kstate.h kmem.h \ kread.o: kread.c kread.h kobject.h ktoken.h kpair.h kstate.h kerror.h klisp.h \ kport.h kwrite.o: kwrite.c kwrite.h kobject.h kpair.h kstring.h kstate.h kerror.h \ - klisp.h kport.h + klisp.h kport.h kinteger.h kstate.o: kstate.c kstate.h klisp.h kobject.h kmem.h kstring.h klisp.h \ kground.h kenvironment.h kpair.h keval.h koperative.h kground.h \ krepl.h kcontinuation.h kapplicative.h kport.h ksymbol.h kport.h \ diff --git a/src/kinteger.c b/src/kinteger.c @@ -46,7 +46,6 @@ TValue kbigint_copy(klisp_State *K, TValue src) TValue copy = kbigint_new(K, false, 0); Bigint *src_bigint = tv2bigint(src); Bigint *copy_bigint = tv2bigint(copy); - /* TODO: when the klisp allocator is used mem errors throw exceptions */ UNUSED(mp_int_init_copy(copy_bigint, src_bigint)); return copy; } @@ -57,104 +56,113 @@ TValue kbigint_copy(klisp_State *K, TValue src) void kbigint_add_digit(klisp_State *K, TValue tv_bigint, int32_t base, int32_t digit) { - /* XXX / TODO */ - return; + UNUSED(K); + Bigint *bigint = tv2bigint(tv_bigint); + UNUSED(mp_int_mul_value(bigint, base, bigint)); + UNUSED(mp_int_add_value(bigint, digit, bigint)); } /* This is used by the writer to get the digits of a number tv_bigint must be positive */ int32_t kbigint_remove_digit(klisp_State *K, TValue tv_bigint, int32_t base) { - /* XXX / TODO */ - return 0; + UNUSED(K); + Bigint *bigint = tv2bigint(tv_bigint); + int32_t r; + UNUSED(mp_int_div_value(bigint, base, bigint, &r)); + return r; } /* This is used by write to test if there is any digit left to print */ bool kbigint_has_digits(klisp_State *K, TValue tv_bigint) { UNUSED(K); - /* XXX / TODO */ - return false; + Bigint *bigint = tv2bigint(tv_bigint); + return (mp_int_compare_zero(bigint) != 0); } /* Mutate the bigint to have the opposite sign, used in read, write and abs */ -void kbigint_invert_sign(TValue tv_bigint) +void kbigint_invert_sign(klisp_State *K, TValue tv_bigint) { - /* XXX / TODO */ - return; + UNUSED(K); + Bigint *bigint = tv2bigint(tv_bigint); + UNUSED(mp_int_neg(bigint, bigint)); } /* this is used by write to estimate the number of chars necessary to print the number */ int32_t kbigint_print_size(TValue tv_bigint, int32_t base) { - /* XXX / TODO */ - return 0; + Bigint *bigint = tv2bigint(tv_bigint); + return mp_int_string_len(bigint, base); } bool kbigint_eqp(TValue tv_bigint1, TValue tv_bigint2) { - /* XXX / TODO */ - return false; + Bigint *bigint1 = tv2bigint(tv_bigint1); + Bigint *bigint2 = tv2bigint(tv_bigint2); + return (mp_int_compare(bigint1, bigint2) == 0); } bool kbigint_ltp(TValue tv_bigint1, TValue tv_bigint2) { - /* XXX / TODO */ - return false; + Bigint *bigint1 = tv2bigint(tv_bigint1); + Bigint *bigint2 = tv2bigint(tv_bigint2); + return (mp_int_compare(bigint1, bigint2) < 0); } bool kbigint_lep(TValue tv_bigint1, TValue tv_bigint2) { - /* a <= b == !(a > b) == !(b < a) */ - return !kbigint_ltp(tv_bigint2, tv_bigint1); + Bigint *bigint1 = tv2bigint(tv_bigint1); + Bigint *bigint2 = tv2bigint(tv_bigint2); + return (mp_int_compare(bigint1, bigint2) <= 0); } bool kbigint_gtp(TValue tv_bigint1, TValue tv_bigint2) { - /* a > b == (b < a) */ - return kbigint_ltp(tv_bigint2, tv_bigint1); + Bigint *bigint1 = tv2bigint(tv_bigint1); + Bigint *bigint2 = tv2bigint(tv_bigint2); + return (mp_int_compare(bigint1, bigint2) > 0); } bool kbigint_gep(TValue tv_bigint1, TValue tv_bigint2) { - /* a >= b == !(a < b) */ - return !kbigint_ltp(tv_bigint1, tv_bigint2); + Bigint *bigint1 = tv2bigint(tv_bigint1); + Bigint *bigint2 = tv2bigint(tv_bigint2); + return (mp_int_compare(bigint1, bigint2) >= 0); } bool kbigint_negativep(TValue tv_bigint) { - /* XXX / TODO */ - return false; + Bigint *bigint = tv2bigint(tv_bigint); + return (mp_int_compare_zero(bigint) < 0); } -/* unlike the positive? applicative this would return true on zero, - but zero is never represented as a bigint so there is no problem */ -/* Bigints constructed from fixints could be, but we don't care about - zero returning positive in other place than in positive? */ bool kbigint_positivep(TValue tv_bigint) { - /* XXX / TODO */ - return false; + Bigint *bigint = tv2bigint(tv_bigint); + return (mp_int_compare_zero(bigint) > 0); } bool kbigint_oddp(TValue tv_bigint) { - /* XXX / TODO */ - return false; + Bigint *bigint = tv2bigint(tv_bigint); + return mp_int_is_odd(bigint); } bool kbigint_evenp(TValue tv_bigint) { - /* XXX / TODO */ - return false; + Bigint *bigint = tv2bigint(tv_bigint); + return mp_int_is_even(bigint); } TValue kbigint_abs(klisp_State *K, TValue tv_bigint) { - /* XXX / TODO */ UNUSED(K); - return tv_bigint; + Bigint *src_bigint = tv2bigint(tv_bigint); + TValue copy = kbigint_new(K, false, 0); + Bigint *copy_bigint = tv2bigint(copy); + UNUSED(mp_int_abs(copy_bigint, src_bigint)); + return copy; } - diff --git a/src/kinteger.h b/src/kinteger.h @@ -79,7 +79,7 @@ bool kbigint_evenp(TValue tv_bigint); TValue kbigint_abs(klisp_State *K, TValue tv_bigint); /* Mutate the bigint to have the opposite sign, used in read & write */ -void kbigint_invert_sign(TValue tv_bigint); +void kbigint_invert_sign(klisp_State *K, TValue tv_bigint); /* this is used by write to estimate the number of chars necessary to print the number */ diff --git a/src/ktoken.c b/src/ktoken.c @@ -399,7 +399,7 @@ TValue ktok_read_number(klisp_State *K, bool is_pos) return i2tv(fixint); } else { if (!is_pos) - kbigint_invert_sign(bigint_res); + kbigint_invert_sign(K, bigint_res); return bigint_res; } } diff --git a/src/kwrite.c b/src/kwrite.c @@ -50,7 +50,7 @@ void kw_print_bigint(klisp_State *K, TValue bigint) TValue copy = kbigint_copy(K, bigint); /* must work with positive bigint to get the digits */ if (kbigint_negativep(bigint)) - kbigint_invert_sign(copy); + kbigint_invert_sign(K, copy); while(kbigint_has_digits(K, copy)) { int32_t digit = kbigint_remove_digit(K, copy, 10);