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:
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