commit 77b8aa5594386c25f2c3c0df60a081c79b04aee7
parent 9e0abd962529037edaedd2540776801fcdc9a40a
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sun, 20 Mar 2011 02:55:32 -0300
Added =?, <?, <=?, >? & >=? to the ground environment.
Diffstat:
4 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/src/kgnumbers.c b/src/kgnumbers.c
@@ -23,6 +23,7 @@
 /* 15.5.1? number?, finite?, integer? */
 /* use ftypep & ftypep_predp */
 
+/* Helpers for typed predicates */
 bool knumberp(TValue obj) { return ttype(obj) <= K_LAST_NUMBER_TYPE; }
 /* obj is known to be a number */
 bool kfinitep(TValue obj) { return (!ttiseinf(obj) && !ttisiinf(obj)); }
@@ -30,4 +31,87 @@ bool kfinitep(TValue obj) { return (!ttiseinf(obj) && !ttisiinf(obj)); }
    inexact integers */
 bool kintegerp(TValue obj) { return ttisfixint(obj); }
 
+/* 12.5.2 =? */
+/* uses typed_bpredp */
+
+/* 12.5.3 <?, <=?, >?, >=? */
+/* use typed_bpredp */
+
+/* Helpers for typed binary predicates */
+/* XXX: this should probably be in a file knumber.h but there is no real need for 
+   that file yet */
+
+/* this will come handy when there are more numeric types,
+   it is intended to be used in switch */
+inline int32_t max_ttype(TValue obj1, TValue obj2)
+{
+    int32_t t1 = ttype(obj1);
+    int32_t t2 = ttype(obj2);
+
+    return (t1 > t2? t1 : t2);
+}
+
+/* TEMP: for now only fixints and exact infinities */
+bool knum_eqp(TValue n1, TValue n2) { return tv_equal(n1, n2); }
+bool knum_ltp(TValue n1, TValue n2) 
+{ 
+    switch(max_ttype(n1, n2)) {
+    case K_TFIXINT:
+	return ivalue(n1) < ivalue(n2);
+    case K_TEINF:
+	return !tv_equal(n1, n2) && (tv_equal(n1, KEMINF) ||
+				     tv_equal(n2, KEPINF));
+    default:
+	/* shouldn't happen */
+	assert(0);
+	return false;
+    }
+}
+
+bool knum_lep(TValue n1, TValue n2)
+{ 
+    switch(max_ttype(n1, n2)) {
+    case K_TFIXINT:
+	return ivalue(n1) <= ivalue(n2);
+    case K_TEINF:
+	return tv_equal(n1, n2) || tv_equal(n1, KEMINF) || 
+	    tv_equal(n2, KEPINF);
+    default:
+	/* shouldn't happen */
+	assert(0);
+	return false;
+    }
+}
+
+bool knum_gtp(TValue n1, TValue n2)
+{ 
+    switch(max_ttype(n1, n2)) {
+    case K_TFIXINT:
+	return ivalue(n1) > ivalue(n2);
+    case K_TEINF:
+	return !tv_equal(n1, n2) && (tv_equal(n1, KEPINF) ||
+				     tv_equal(n2, KEMINF));
+    default:
+	/* shouldn't happen */
+	assert(0);
+	return false;
+    }
+}
+
+bool knum_gep(TValue n1, TValue n2)
+{ 
+    switch(max_ttype(n1, n2)) {
+    case K_TFIXINT:
+	return ivalue(n1) >= ivalue(n2);
+    case K_TEINF:
+	return tv_equal(n1, n2) || tv_equal(n1, KEPINF) ||
+	    tv_equal(n2, KEMINF);
+    default:
+	/* shouldn't happen */
+	assert(0);
+	return false;
+    }
+}
+
+
 
diff --git a/src/kgnumbers.h b/src/kgnumbers.h
@@ -28,4 +28,21 @@ bool knumberp(TValue obj);
 bool kfinitep(TValue obj);
 bool kintegerp(TValue obj);
 
+
+/* 12.5.2 =? */
+/* uses typed_bpredp */
+
+/* 12.5.3 <?, <=?, >?, >=? */
+/* use typed_bpredp */
+
+/* Helpers for typed binary predicates */
+/* XXX: this should probably be in a file knumber.h but there is no real need for 
+   that file yet */
+bool knum_eqp(TValue n1, TValue n2);
+bool knum_ltp(TValue n1, TValue n2);
+bool knum_lep(TValue n1, TValue n2);
+bool knum_gtp(TValue n1, TValue n2);
+bool knum_gep(TValue n1, TValue n2);
+
+
 #endif
diff --git a/src/kground.c b/src/kground.c
@@ -483,7 +483,7 @@ void kinit_ground_env(klisp_State *K)
     ** 12.5 Number features
     */
 
-    /* 12.5.1? number?, finite?, integer? */
+    /* 12.5.1 number?, finite?, integer? */
     add_applicative(K, ground_env, "number?", ftypep, 2, symbol, 
 		    p2tv(knumberp));
     add_applicative(K, ground_env, "finite?", ftyped_predp, 3, symbol, 
@@ -491,6 +491,19 @@ void kinit_ground_env(klisp_State *K)
     add_applicative(K, ground_env, "integer?", ftypep, 2, symbol, 
 		    p2tv(kintegerp));
 
+    /* 12.5.2 =? */
+    add_applicative(K, ground_env, "=?", ftyped_bpredp, 3,
+		    symbol, p2tv(knumberp), p2tv(knum_eqp));
+    
+    /* 12.5.3 <?, <=?, >?, >=? */
+    add_applicative(K, ground_env, "<?", ftyped_bpredp, 3,
+		    symbol, p2tv(knumberp), p2tv(knum_ltp));
+    add_applicative(K, ground_env, "<=?", ftyped_bpredp, 3,
+		    symbol, p2tv(knumberp),  p2tv(knum_lep));
+    add_applicative(K, ground_env, ">?", ftyped_bpredp, 3,
+		    symbol, p2tv(knumberp), p2tv(knum_gtp));
+    add_applicative(K, ground_env, ">=?", ftyped_bpredp, 3,
+		    symbol, p2tv(knumberp), p2tv(knum_gep));
 
     /* ... TODO */
 
diff --git a/src/kobject.h b/src/kobject.h
@@ -127,7 +127,7 @@ typedef struct __attribute__ ((__packed__)) GCheader {
 #define K_TPORT         39
 
 /* this is used to test for numbers, as returned by ttype */
-#define K_LAST_NUMBER_TYPE K_TIINF
+#define K_LAST_NUMBER_TYPE K_TCOMPLEX
 
 #define K_MAKE_VTAG(t) (K_TAG_TAGGED | (t))