klisp

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

commit 20a2e94b95f262300a08b55f5eb7f389baaaaa9c
parent 7ac6a08241675b63e9f413917c89eba5e701f0f5
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 23 Apr 2011 13:16:59 -0300

Added krational.c. Still missing most functionality.

Diffstat:
Msrc/Makefile | 2+-
Msrc/kinteger.h | 2+-
Asrc/krational.c | 44++++++++++++++++++++++++++++++++++++++++++++
Msrc/krational.h | 8++++----
4 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -48,7 +48,7 @@ ktoken.o: ktoken.c ktoken.h kobject.h kstate.h kpair.h kstring.h ksymbol.h \ kerror.h klisp.h kinteger.h krational.h kport.h kinteger.o: kinteger.c kinteger.h kobject.h kstate.h kmem.h klisp.h imath.h \ kgc.h -krational.o: krational.c krational.h kinteger.h kobject.h kstate.h kmem.h klisp.h +krational.o: krational.c krational.h kinteger.h kobject.h kstate.h kmem.h klisp.h \ imrat.h kgc.h kpair.o: kpair.c kpair.h kobject.h kstate.h kmem.h klisp.h kgc.h kstring.o: kstring.c kstring.h kobject.h kstate.h kmem.h klisp.h kgc.h diff --git a/src/kinteger.h b/src/kinteger.h @@ -19,7 +19,7 @@ /* NOTE: is uint and has flag to allow INT32_MIN as positive argument */ TValue kbigint_new(klisp_State *K, bool sign, uint32_t digit); -/* used in write to destructively get the digits */ +/* used in write to destructively get the digits & in bigrat */ TValue kbigint_copy(klisp_State *K, TValue src); /* Check to see if an int64_t fits in a int32_t */ diff --git a/src/krational.c b/src/krational.c @@ -0,0 +1,44 @@ +/* +** krational.c +** Kernel Rationals (fixrats and bigrats) +** See Copyright Notice in klisp.h +*/ + +#include <stdbool.h> +#include <stdint.h> +#include <inttypes.h> +#include <math.h> + +#include "krational.h" +#include "kinteger.h" +#include "kobject.h" +#include "kstate.h" +#include "kmem.h" +#include "kgc.h" + +/* This tries to convert a bigrat to a fixint or a bigint */ +inline TValue kbigrat_try_integer(klisp_State *K, TValue n) +{ + Bigrat *b = tv2bigrat(n); + + if (mp_int_compare_zero(MP_DENOM_P(b)) == 0) + return n; + + /* sadly we have to repeat the code from try_fixint here... */ + Bigint *i = MP_NUMER_P(b); + if (MP_USED(i) == 1) { + int64_t digit = (int64_t) *(MP_DIGITS(i)); + if (MP_SIGN(i) == MP_NEG) digit = -digit; + if (kfit_int32_t(digit)) + return i2tv((int32_t) digit); + /* else fall through */ + } + /* should alloc a bigint */ + /* GC: n may not be rooted */ + krooted_tvs_push(K, n); + TValue copy = kbigint_copy(K, gc2bigint(i)); + krooted_tvs_pop(K); + return copy; +} + + diff --git a/src/krational.h b/src/krational.h @@ -127,10 +127,10 @@ bool kbigrat_lep(klisp_State *K, TValue bigrat1, TValue bigrat2); bool kbigrat_gtp(klisp_State *K, TValue bigrat1, TValue bigrat2); bool kbigrat_gep(klisp_State *K, TValue bigrat1, TValue bigrat2); -TValue kbigrat_plus(klisp_State *K, klisp_State *K, TValue n1, TValue n2); -TValue kbigrat_times(klisp_State *K, klisp_State *K, TValue n1, TValue n2); -TValue kbigrat_minus(klisp_State *K, klisp_State *K, TValue n1, TValue n2); -TValue kbigrat_divide(klisp_State *K, klisp_State *K, TValue n1, TValue n2); +TValue kbigrat_plus(klisp_State *K, TValue n1, TValue n2); +TValue kbigrat_times(klisp_State *K, TValue n1, TValue n2); +TValue kbigrat_minus(klisp_State *K, TValue n1, TValue n2); +TValue kbigrat_divide(klisp_State *K, TValue n1, TValue n2); /* TODO: Kernel allows arbitrary reals for these... will have to define */ #if 0