klisp

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

commit 7ac6a08241675b63e9f413917c89eba5e701f0f5
parent 57390ed864b9d860353ecf100974f211f2343b89
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 23 Apr 2011 12:57:53 -0300

Added a krational.h header file. TODO: add krational.c.

Diffstat:
Msrc/Makefile | 18+++++++++++-------
Msrc/kobject.h | 2++
Asrc/krational.h | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 174 insertions(+), 7 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -10,12 +10,13 @@ MYLIBS= CORE_O= kobject.o ktoken.o kpair.o kstring.o ksymbol.o kread.o \ kwrite.o kstate.o kmem.o kerror.o kauxlib.o kenvironment.o \ kcontinuation.o koperative.o kapplicative.o keval.o krepl.o \ - kencapsulation.o kpromise.o kport.o kinteger.o ktable.o \ + kencapsulation.o kpromise.o kport.o kinteger.o krational.o \ + ktable.o kgc.o imath.o imrat.o \ kground.o kghelpers.o kgbooleans.o kgeqp.o kgequalp.o \ kgsymbols.o kgcontrol.o kgpairs_lists.o kgpair_mut.o kgenvironments.o \ kgenv_mut.o kgcombiners.o kgcontinuations.o kgencapsulations.o \ kgpromises.o kgkd_vars.o kgks_vars.o kgports.o kgchars.o kgnumbers.o \ - kgstrings.o imath.o imrat.o kgc.o + kgstrings.o KRN_T= klisp KRN_O= klisp.o @@ -44,9 +45,11 @@ klisp.o: klisp.c klisp.h kobject.h kread.h kwrite.h klimits.h kstate.h kmem.h \ kapplicative.h koperative.h keval.h krepl.h kground.h kobject.o: kobject.c kobject.h klimits.h klispconf.h ktoken.o: ktoken.c ktoken.h kobject.h kstate.h kpair.h kstring.h ksymbol.h \ - kerror.h klisp.h kinteger.h kport.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 + 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 # XXX: kpair.h because of use of list as symbol table @@ -55,11 +58,12 @@ 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 ktable.h klispconf.h kwrite.o: kwrite.c kwrite.h kobject.h kpair.h kstring.h kstate.h kerror.h \ - klisp.h kport.h kinteger.h ktable.h klispconf.h + klisp.h kport.h kinteger.h krational.h ktable.h klispconf.h +# XXX: now that all dealloc code is in gc, many of these are unnecessary kstate.o: kstate.c kstate.h klisp.h kobject.h kmem.h kstring.h klisp.h \ kenvironment.h kpair.h keval.h koperative.h kground.h \ krepl.h kcontinuation.h kapplicative.h kport.h ksymbol.h kport.h \ - kstring.h kinteger.h kgc.h klimits.h ktable.h klispconf.h + kstring.h kinteger.h krational.h kgc.h klimits.h ktable.h klispconf.h kmem.o: kmem.c kmem.h klisp.h kerror.h klisp.h kstate.h kgc.h klispconf.h kerror.o: kerror.c kerror.h klisp.h kstate.h klisp.h kmem.h kstring.h kpair.h kauxlib.o: kauxlib.c kauxlib.h klisp.h kstate.h klisp.h @@ -97,7 +101,7 @@ kgbooleans.o: kgbooleans.c kgbooleans.c kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kpair.h kcontinuation.h ksymbol.h kgeqp.o: kgeqp.c kgeqp.c kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kpair.h kcontinuation.h kapplicative.h \ - kinteger.h + kinteger.h krational.h kgequalp.o: kgequalp.c kgequalp.c kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kpair.h kcontinuation.h kgeqp.h kstring.h kgsymbols.o: kgsymbols.c kgsymbols.c kghelpers.h kstate.h klisp.h \ @@ -141,7 +145,7 @@ kgchars.o: kgchars.c kgchars.h kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kapplicative.h koperative.h kcontinuation.h kgnumbers.o: kgnumbers.c kgnumbers.h kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kapplicative.h koperative.h kcontinuation.h \ - ksymbol.h kinteger.h imrat.h + ksymbol.h kinteger.h krational.h kgstrings.o: kgstrings.c kgstrings.h kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kapplicative.h koperative.h kcontinuation.h \ kstring.h ksymbol.h kgnumbers.h diff --git a/src/kobject.h b/src/kobject.h @@ -566,6 +566,7 @@ const TValue kfree; #define gc2tv(t_, o_) ((TValue) {.tv = {.t = (t_), \ .v = { .gc = obj2gco(o_)}}}) #define gc2bigint(o_) (gc2tv(K_TAG_BIGINT, o_)) +#define gc2bigrat(o_) (gc2tv(K_TAG_BIGRAT, o_)) #define gc2pair(o_) (gc2tv(K_TAG_PAIR, o_)) #define gc2str(o_) (gc2tv(K_TAG_STRING, o_)) #define gc2sym(o_) (gc2tv(K_TAG_SYMBOL, o_)) @@ -581,6 +582,7 @@ const TValue kfree; /* Macro to convert a TValue into a specific heap allocated object */ #define tv2bigint(v_) ((Bigint *) gcvalue(v_)) +#define tv2bigrat(v_) ((Bigrat *) gcvalue(v_)) #define tv2pair(v_) ((Pair *) gcvalue(v_)) #define tv2str(v_) ((String *) gcvalue(v_)) #define tv2sym(v_) ((Symbol *) gcvalue(v_)) diff --git a/src/krational.h b/src/krational.h @@ -0,0 +1,161 @@ +/* +** krational.h +** Kernel Rationals (fixrats and bigrats) +** See Copyright Notice in klisp.h +*/ + +#ifndef krational_h +#define krational_h + +#include <stdbool.h> +#include <stdint.h> +#include <inttypes.h> + +#include "kobject.h" +#include "kstate.h" +#include "kinteger.h" +#include "imrat.h" + +/* TEMP: for now we only implement bigrats (memory allocated) */ + +/* TODO: how to alloc?? */ +/* TEMP: we'll see about these */ +/* for now used only for reading */ +TValue kbigrat_new(klisp_State *K, bool sign, uint32_t num, + uint32_t den); + +/* used in write to destructively get the digits */ +TValue kbigrat_copy(klisp_State *K, TValue src); + +/* Create a stack allocated bigrat from a bigint, + useful for mixed operations, relatively light weight compared + to creating it in the heap and burdening the gc */ +#define kbind_bigrat_fixint(name, fixint) \ + int32_t (KUNIQUE_NAME(i)) = ivalue(fixint); \ + Bigrat KUNIQUE_NAME(bigrat_i); \ + /* can't use unique_name bigrat because it conflicts */ \ + /* numer is 1 */ \ + (KUNIQUE_NAME(bigrat_i)).num.single = ({ \ + 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.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; \ + \ + Bigrat *name = &(KUNIQUE_NAME(bigrat_i)); + +#define kbind_bigrat_bigint(name, 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; \ + /* 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)); + +/* 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) */ + +/* This can be used prior to calling a bigrat functions + to automatically convert fixints & bigints to bigrats. + NOTE: calls to this macro should go in different lines! + and on different lines to calls to kensure_bigint */ +#define kensure_bigrat(n) \ + /* must use goto, no block should be entered before calling \ + kbind_bigrat */ \ + if (ttisbigrat(n)) \ + goto KUNIQUE_NAME(bigrat_exit_lbl); \ + if (ttisbigint(n)) \ + goto KUNIQUE_NAME(bigrat_bigint_lbl); \ + /* else ttisfixint(n) */ \ + kbind_bigrat_fixint(KUNIQUE_NAME(brat_i), (n)); \ + (n) = gc2bigrat(KUNIQUE_NAME(brat_i)); \ + goto KUNIQUE_NAME(bigrat_exit_lbl); \ +KUNIQUE_NAME(bigrat_bigint_lbl): \ + kbind_bigrat_bigint(KUNIQUE_NAME(brat), (n)); \ + (n) = gc2bigrat(KUNIQUE_NAME(brat)); \ +KUNIQUE_NAME(bigrat_exit_lbl): + +#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); + +bool kbigrat_ltp(klisp_State *K, TValue bigrat1, TValue bigrat2); +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); + +/* TODO: Kernel allows arbitrary reals for these... will have to define */ +#if 0 +TValue kbigrat_div_mod(klisp_State *K, TValue n1, TValue n2, TValue *res_r); +TValue kbigrat_div0_mod0(klisp_State *K, TValue n1, TValue n2, TValue *res_r); +#endif + +bool kbigrat_negativep(TValue tv_bigrat); +bool kbigrat_positivep(TValue tv_bigrat); + +/* needs the state to create a copy if negative */ +TValue kbigrat_abs(klisp_State *K, TValue tv_bigrat); + +bool kbigrat_numerator(TValue tv_bigrat); +bool kbigrat_denominator(TValue tv_bigrat); + +/* TODO implement these */ +#if 0 +TValue kbigrat_floor(klisp_State *K, TValue n1, TValue n2); +TValue kbigrat_ceiling(klisp_State *K, TValue n1, TValue n2); +TValue kbigrat_truncate(klisp_State *K, TValue n1, TValue n2); +TValue kbigrat_round(klisp_State *K, TValue n1, TValue n2); + +TValue kbigrat_simplest_rational(klisp_State *K, TValue n1, TValue n2); +TValue kbigrat_rationalize(klisp_State *K, TValue n1, TValue n2); +#endif + +#endif