klisp

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

commit 8ccb5720da8ed45968ca4eb6206497a645ad43b4
parent 64398900ac1286a80942d404cb9c9cb5e957f690
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 23 Apr 2011 13:58:13 -0300

Several bugfixes to kensure_bigrat. (Bad copy&paste, bad!!)

Diffstat:
Msrc/kinteger.h | 2+-
Msrc/krational.c | 34+++++++++++++++++++++++++++++++++-
Msrc/krational.h | 45+++++++++++++++++++++++----------------------
3 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/src/kinteger.h b/src/kinteger.h @@ -42,7 +42,7 @@ inline bool kfit_int32_t(int64_t n) { (KUNIQUE_NAME(bigint)).used = 1; \ (KUNIQUE_NAME(bigint)).sign = (KUNIQUE_NAME(i)) < 0? \ MP_NEG : MP_ZPOS; \ - Bigint *name = &(KUNIQUE_NAME(bigint)); + Bigint *name = &(KUNIQUE_NAME(bigint)) /* This can be used prior to calling a bigint functions to automatically convert fixints to bigints. diff --git a/src/krational.c b/src/krational.c @@ -75,8 +75,40 @@ TValue kbigrat_copy(klisp_State *K, TValue src) { TValue copy = kbigrat_new(K, false, 0, 1); /* arguments are in reverse order with respect to mp_rat_copy */ - UNUSED(mp_int_init_copy(K, tv2bigrat(copy), tv2bigrat(src))); + UNUSED(mp_rat_init_copy(K, tv2bigrat(copy), tv2bigrat(src))); return copy; } /* Interface for kgnumbers */ + +/* The compare predicates take a klisp_State because in general + may need to do multiplications */ +bool kbigrat_eqp(klisp_State *K, TValue tv_bigrat1, TValue tv_bigrat2) +{ + return (mp_rat_compare(K, tv2bigrat(tv_bigrat1), + tv2bigrat(tv_bigrat2)) == 0); +} + +bool kbigrat_ltp(klisp_State *K, TValue tv_bigrat1, TValue tv_bigrat2) +{ + return (mp_rat_compare(K, tv2bigrat(tv_bigrat1), + tv2bigrat(tv_bigrat2)) < 0); +} + +bool kbigrat_lep(klisp_State *K, TValue tv_bigrat1, TValue tv_bigrat2) +{ + return (mp_rat_compare(K, tv2bigrat(tv_bigrat1), + tv2bigrat(tv_bigrat2)) <= 0); +} + +bool kbigrat_gtp(klisp_State *K, TValue tv_bigrat1, TValue tv_bigrat2) +{ + return (mp_rat_compare(K, tv2bigrat(tv_bigrat1), + tv2bigrat(tv_bigrat2)) > 0); +} + +bool kbigrat_gep(klisp_State *K, TValue tv_bigrat1, TValue tv_bigrat2) +{ + return (mp_rat_compare(K, tv2bigrat(tv_bigrat1), + tv2bigrat(tv_bigrat2)) >= 0); +} diff --git a/src/krational.h b/src/krational.h @@ -39,39 +39,39 @@ TValue kbigrat_copy(klisp_State *K, TValue src); int64_t temp = (KUNIQUE_NAME(i)); \ (uint32_t) ((temp < 0)? -temp : temp); \ }); \ - (KUNIQUE_NAME(bigrat_i)).num.digits = \ - &((KUNIQUE_NAME(bigrat_i)).single); \ + (KUNIQUE_NAME(bigrat_i)).num.digits = \ + &((KUNIQUE_NAME(bigrat_i)).num.single); \ (KUNIQUE_NAME(bigrat_i)).num.alloc = 1; \ (KUNIQUE_NAME(bigrat_i)).num.used = 1; \ (KUNIQUE_NAME(bigrat_i)).num.sign = (KUNIQUE_NAME(i)) < 0? \ MP_NEG : MP_ZPOS; \ /* denom is 1 */ \ - (KUNIQUE_NAME(bigrat_i)).num.single = 1; \ - (KUNIQUE_NAME(bigrat_i)).num.digits = \ - &((KUNIQUE_NAME(bigrat_i)).num.single); \ - (KUNIQUE_NAME(bigrat_i)).num.alloc = 1; \ - (KUNIQUE_NAME(bigrat_i)).num.used = 1; \ - (KUNIQUE_NAME(bigrat_i)).num.sign = MP_ZPOS; \ + (KUNIQUE_NAME(bigrat_i)).den.single = 1; \ + (KUNIQUE_NAME(bigrat_i)).den.digits = \ + &((KUNIQUE_NAME(bigrat_i)).den.single); \ + (KUNIQUE_NAME(bigrat_i)).den.alloc = 1; \ + (KUNIQUE_NAME(bigrat_i)).den.used = 1; \ + (KUNIQUE_NAME(bigrat_i)).den.sign = MP_ZPOS; \ \ - Bigrat *name = &(KUNIQUE_NAME(bigrat_i)); + Bigrat *name = &(KUNIQUE_NAME(bigrat_i)) #define kbind_bigrat_bigint(name, bigint) \ + Bigint *KUNIQUE_NAME(bi) = tv2bigint(bigint); \ Bigrat KUNIQUE_NAME(bigrat); \ /* numer is bigint */ \ - (KUNIQUE_NAME(bigrat)).num.single = bigint.single; \ - (KUNIQUE_NAME(bigrat)).num.digits = bigint.digits; \ - (KUNIQUE_NAME(bigrat)).num.alloc = bigint.alloc; \ - (KUNIQUE_NAME(bigrat)).num.used = bigint.used; \ - (KUNIQUE_NAME(bigrat)).num.sign = bigint.sign; \ + (KUNIQUE_NAME(bigrat)).num.single = (KUNIQUE_NAME(bi))->single; \ + (KUNIQUE_NAME(bigrat)).num.digits = (KUNIQUE_NAME(bi))->digits; \ + (KUNIQUE_NAME(bigrat)).num.alloc = (KUNIQUE_NAME(bi))->alloc; \ + (KUNIQUE_NAME(bigrat)).num.used = (KUNIQUE_NAME(bi))->used; \ + (KUNIQUE_NAME(bigrat)).num.sign = (KUNIQUE_NAME(bi))->sign; \ /* denom is 1 */ \ - (KUNIQUE_NAME(bigrat)).num.single = 1; \ - (KUNIQUE_NAME(bigrat)).num.digits = \ - &((KUNIQUE_NAME(bigrat)).num.single); \ - (KUNIQUE_NAME(bigrat)).num.alloc = 1; \ - (KUNIQUE_NAME(bigrat)).num.used = 1; \ - (KUNIQUE_NAME(bigrat)).num.sign = MP_ZPOS; \ - \ - Bigrat *name = &(KUNIQUE_NAME(bigrat)); + (KUNIQUE_NAME(bigrat)).den.single = 1; \ + (KUNIQUE_NAME(bigrat)).den.digits = \ + &((KUNIQUE_NAME(bigrat)).den.single); \ + (KUNIQUE_NAME(bigrat)).den.alloc = 1; \ + (KUNIQUE_NAME(bigrat)).den.used = 1; \ + (KUNIQUE_NAME(bigrat)).den.sign = MP_ZPOS; \ + Bigrat *name = &(KUNIQUE_NAME(bigrat)) /* XXX: Now that I think about it this (and kensure_bigint) could be more cleanly implemented as a function that takes a pointer... (derp derp) */ @@ -92,6 +92,7 @@ TValue kbigrat_copy(klisp_State *K, TValue src); (n) = gc2bigrat(KUNIQUE_NAME(brat_i)); \ goto KUNIQUE_NAME(bigrat_exit_lbl); \ KUNIQUE_NAME(bigrat_bigint_lbl): \ + ; /* gcc asks for a statement (not a decl) after label */ \ kbind_bigrat_bigint(KUNIQUE_NAME(brat), (n)); \ (n) = gc2bigrat(KUNIQUE_NAME(brat)); \ KUNIQUE_NAME(bigrat_exit_lbl):