ref: a805e16b52d1fe06d6ce7ca865be3153473fdb28
parent: 4c0aa8a8b86164bbe9ff9c5876fbf158e8481b45
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Feb 2 15:58:09 EST 2025
more tests and minor fixes; separate math funcs into math.c
--- a/meson.build
+++ b/meson.build
@@ -55,6 +55,7 @@
'src/htable.c',
'src/ios.c',
'src/iostream.c',
+ 'src/math.c',
'src/opcodes.c',
'src/operators.c',
'src/print.c',
--- a/mkfile
+++ b/mkfile
@@ -35,6 +35,7 @@
src/htable.$O\
src/ios.$O\
src/iostream.$O\
+ src/math.$O\
src/nan.$O\
src/opcodes.$O\
src/operators.$O\
@@ -63,8 +64,10 @@
{attr=""}' \
`{ls `{echo $OFILES | sed 's/\.'$O'/.c/g'} >[2]/dev/null} | sort >$target
-cvalues.$O: src/fl_arith_any.inc
-flisp.$O: src/maxstack.inc src/vm.inc
+src/cvalues.$O: src/fl_arith_any.inc
+src/flisp.$O: src/maxstack.inc src/vm.inc
+src/equalhash.$O: src/htable.inc
+src/ptrhash.$O: src/htable.inc
src/plan9/flisp.boot.s:D: boot/flisp.boot.builtin
aux/data2s boot <$prereq >$target
--- a/src/builtins.c
+++ b/src/builtins.c
@@ -7,7 +7,6 @@
#include "cvalues.h"
#include "timefuncs.h"
#include "table.h"
-#include "random.h"
#include "nan.h"
#define DBL_MAXINT (1LL<<53)
@@ -225,7 +224,7 @@
{
argcount(nargs, 1);
value_t v = args[0];
- if(isfixnum(v))
+ if(isfixnum(v) || ismpint(v))
return FL_t;
if(iscprim(v)){
numerictype_t nt = cp_numtype(ptr(v));
@@ -255,7 +254,7 @@
{
argcount(nargs, 1);
value_t v = args[0];
- return (isfixnum(v) ||
+ return (isfixnum(v) || ismpint(v) ||
(iscprim(v) && cp_numtype(ptr(v)) < T_FLOAT)) ?
FL_t : FL_f;
}
@@ -289,10 +288,11 @@
BUILTIN("truncate", truncate)
{
argcount(nargs, 1);
- if(isfixnum(args[0]))
- return args[0];
- if(iscprim(args[0])){
- cprim_t *cp = ptr(args[0]);
+ value_t v = args[0];
+ if(isfixnum(v) || ismpint(v))
+ return v;
+ if(iscprim(v)){
+ cprim_t *cp = ptr(v);
void *data = cp_data(cp);
numerictype_t nt = cp_numtype(cp);
double d;
@@ -301,11 +301,11 @@
else if(nt == T_DOUBLE)
d = *(double*)data;
else
- return args[0];
+ return v;
if(d > 0){
if(d > (double)INT64_MAX)
- return args[0];
+ return v;
return return_from_uint64((uint64_t)d);
}
if(d > (double)INT64_MAX || d < (double)INT64_MIN)
@@ -312,7 +312,7 @@
return args[0];
return return_from_int64((int64_t)d);
}
- type_error("number", args[0]);
+ type_error("number", v);
}
BUILTIN("vector-alloc", vector_alloc)
@@ -357,6 +357,8 @@
numerictype_t nt = cp_numtype(cp);
return conv_to_double(cp_data(cp), nt);
}
+ if(ismpint(a))
+ return conv_to_double(cv_data(ptr(a)), T_MPINT);
type_error("number", a);
}
@@ -437,71 +439,3 @@
lerrorf(FL_ArgError, "invalid environment variable");
return FL_t;
}
-
-BUILTIN("rand", rand)
-{
- USED(args); USED(nargs);
-#ifdef BITS64
- uint64_t x = genrand_uint64();
-#else
- uint32_t x = genrand_uint32();
-#endif
- return fixnum(x >> 3);
-}
-
-BUILTIN("rand-uint32", rand_uint32)
-{
- USED(args); USED(nargs);
- return mk_uint32(genrand_uint32());
-}
-
-BUILTIN("rand-uint64", rand_uint64)
-{
- USED(args); USED(nargs);
- return mk_uint64(genrand_uint64());
-}
-
-BUILTIN("rand-double", rand_double)
-{
- USED(args); USED(nargs);
- return mk_double(genrand_double());
-}
-
-BUILTIN("rand-float", rand_float)
-{
- USED(args); USED(nargs);
- return mk_float(genrand_double());
-}
-
-#define BUILTIN_(lname, cname) \
- BUILTIN(lname, cname) \
- { \
- argcount(nargs, 1); \
- return mk_double(cname(todouble(args[0]))); \
- }
-
-BUILTIN_("sqrt", sqrt)
-BUILTIN_("exp", exp)
-BUILTIN_("log", log)
-BUILTIN_("log10", log10)
-BUILTIN_("sin", sin)
-BUILTIN_("cos", cos)
-BUILTIN_("tan", tan)
-BUILTIN_("asin", asin)
-BUILTIN_("acos", acos)
-BUILTIN_("atan", atan)
-BUILTIN_("floor", floor)
-BUILTIN_("ceiling", ceil)
-BUILTIN_("sinh", sinh)
-BUILTIN_("cosh", cosh)
-BUILTIN_("tanh", tanh)
-
-#undef BUILTIN_
-#define BUILTIN_(lname, cname) \
- BUILTIN(lname, cname) \
- { \
- argcount(nargs, 2); \
- return mk_double(cname(todouble(args[0]), todouble(args[1]))); \
- }
-
-BUILTIN_("expt", pow)
--- a/src/htable.inc
+++ b/src/htable.inc
@@ -71,14 +71,14 @@
void
HTNAME(_put)(htable_t *h, void *key, void *val)
{
- void **bp = HTNAME(_lookup_bp)(h, key);
- *bp = val;
+ void **bp = HTNAME(_lookup_bp)(h, key);
+ *bp = val;
}
void **
HTNAME(_bp)(htable_t *h, void *key)
{
- return HTNAME(_lookup_bp)(h, key);
+ return HTNAME(_lookup_bp)(h, key);
}
/* returns bp if key is in hash, otherwise nil */
@@ -86,51 +86,51 @@
static void **
HTNAME(_peek_bp)(htable_t *h, void *key)
{
- size_t sz = hash_size(h);
- size_t maxprobe = max_probe(sz);
- void **tab = h->table;
- size_t index = (HFUNC(key) & (sz-1)) * 2;
- sz *= 2;
- size_t orig = index;
- size_t iter = 0;
+ size_t sz = hash_size(h);
+ size_t maxprobe = max_probe(sz);
+ void **tab = h->table;
+ size_t index = (HFUNC(key) & (sz-1)) * 2;
+ sz *= 2;
+ size_t orig = index;
+ size_t iter = 0;
- do {
- if(tab[index] == HT_NOTFOUND)
- return nil;
- if(EQFUNC(key, tab[index]))
- return &tab[index+1];
+ do {
+ if(tab[index] == HT_NOTFOUND)
+ return nil;
+ if(EQFUNC(key, tab[index]))
+ return &tab[index+1];
- index = (index+2) & (sz-1);
- iter++;
- if(iter > maxprobe)
- break;
- }while(index != orig);
+ index = (index+2) & (sz-1);
+ iter++;
+ if(iter > maxprobe)
+ break;
+ }while(index != orig);
- return nil;
+ return nil;
}
void *
HTNAME(_get)(htable_t *h, void *key)
{
- void **bp = HTNAME(_peek_bp)(h, key);
- if(bp == nil)
- return HT_NOTFOUND;
- return *bp;
+ void **bp = HTNAME(_peek_bp)(h, key);
+ if(bp == nil)
+ return HT_NOTFOUND;
+ return *bp;
}
-int
+bool
HTNAME(_has)(htable_t *h, void *key)
{
- return HTNAME(_get)(h, key) != HT_NOTFOUND;
+ return HTNAME(_get)(h, key) != HT_NOTFOUND;
}
-int
+bool
HTNAME(_remove)(htable_t *h, void *key)
{
- void **bp = HTNAME(_peek_bp)(h, key);
- if(bp != nil){
- *bp = HT_NOTFOUND;
- return 1;
- }
- return 0;
+ void **bp = HTNAME(_peek_bp)(h, key);
+ if(bp != nil && *bp != HT_NOTFOUND){
+ *bp = HT_NOTFOUND;
+ return true;
+ }
+ return false;
}
--- a/src/htableh.inc
+++ b/src/htableh.inc
@@ -5,8 +5,8 @@
#define HTPROT(HTNAME) \
void *HTNAME##_get(htable_t *h, void *key) fl_purefn; \
void HTNAME##_put(htable_t *h, void *key, void *val); \
-int HTNAME##_has(htable_t *h, void *key) fl_purefn; \
-int HTNAME##_remove(htable_t *h, void *key); \
+bool HTNAME##_has(htable_t *h, void *key) fl_purefn; \
+bool HTNAME##_remove(htable_t *h, void *key); \
void **HTNAME##_bp(htable_t *h, void *key);
// return value, or HT_NOTFOUND if key not found
--- /dev/null
+++ b/src/math.c
@@ -1,0 +1,35 @@
+#include "flisp.h"
+#include "cvalues.h"
+
+#define BUILTIN_(lname, cname) \
+ BUILTIN(lname, cname) \
+ { \
+ argcount(nargs, 1); \
+ return mk_double(cname(todouble(args[0]))); \
+ }
+
+BUILTIN_("sqrt", sqrt)
+BUILTIN_("exp", exp)
+BUILTIN_("log", log)
+BUILTIN_("log10", log10)
+BUILTIN_("sin", sin)
+BUILTIN_("cos", cos)
+BUILTIN_("tan", tan)
+BUILTIN_("asin", asin)
+BUILTIN_("acos", acos)
+BUILTIN_("atan", atan)
+BUILTIN_("floor", floor)
+BUILTIN_("ceiling", ceil)
+BUILTIN_("sinh", sinh)
+BUILTIN_("cosh", cosh)
+BUILTIN_("tanh", tanh)
+
+#undef BUILTIN_
+#define BUILTIN_(lname, cname) \
+ BUILTIN(lname, cname) \
+ { \
+ argcount(nargs, 2); \
+ return mk_double(cname(todouble(args[0]), todouble(args[1]))); \
+ }
+
+BUILTIN_("expt", pow)
--- a/src/random.c
+++ b/src/random.c
@@ -1,4 +1,5 @@
#include "flisp.h"
+#include "cvalues.h"
#include "mt19937-64.h"
#include "timefuncs.h"
#include "random.h"
@@ -5,27 +6,43 @@
static mt19937_64 ctx;
-uint64_t
-genrand_uint64(void)
+void
+randomize(void)
{
- return genrand64_int64(&ctx);
+ unsigned long long tm = sec_realtime() * 1000.0;
+ init_by_array64(&ctx, &tm, 1);
}
-uint32_t
-genrand_uint32(void)
+BUILTIN("rand", rand)
{
- return genrand64_int64(&ctx) >> 32;
+ USED(args); USED(nargs);
+#ifdef BITS64
+ return fixnum(genrand64_int64(&ctx) >> 3);
+#else
+ return fixnum(genrand64_int64(&ctx) >> (32+3));
+#endif
}
-double
-genrand_double(void)
+BUILTIN("rand-uint32", rand_uint32)
{
- return genrand64_real1(&ctx);
+ USED(args); USED(nargs);
+ return mk_uint32(genrand64_int64(&ctx) >> 32);
}
-void
-randomize(void)
+BUILTIN("rand-uint64", rand_uint64)
{
- unsigned long long tm = sec_realtime() * 1000.0;
- init_by_array64(&ctx, &tm, 1);
+ USED(args); USED(nargs);
+ return mk_uint64(genrand64_int64(&ctx));
+}
+
+BUILTIN("rand-double", rand_double)
+{
+ USED(args); USED(nargs);
+ return mk_double(genrand64_real1(&ctx));
+}
+
+BUILTIN("rand-float", rand_float)
+{
+ USED(args); USED(nargs);
+ return mk_float(genrand64_real1(&ctx));
}
--- a/src/random.h
+++ b/src/random.h
@@ -1,6 +1,4 @@
#pragma once
void randomize(void);
-double genrand_double(void);
-uint64_t genrand_uint64(void);
-uint32_t genrand_uint32(void);
+
--- a/test/number-boundaries.lsp
+++ b/test/number-boundaries.lsp
@@ -63,6 +63,12 @@
`(let* ((h (high-border ,smaller))
(L (low-border ,bigger))
(l (if (= L 0) 0 (low-border ,smaller))))
+ (assert (and (integer? h) (integer? l)))
+ (assert (and (integer? (,smaller h)) (integer? (,smaller l))))
+ (assert (and (integer? (,bigger h)) (integer? (,bigger l))))
+ (assert (and (integer-valued? h) (integer-valued? l)))
+ (assert (and (integer-valued? (,smaller h)) (integer-valued? (,smaller l))))
+ (assert (and (integer-valued? (,bigger h)) (integer-valued? (,bigger l))))
(assert (= h
(,smaller h) (,bigger h)
(,smaller (,bigger h)) (,bigger (,smaller h))))
--- a/test/unittest.lsp
+++ b/test/unittest.lsp
@@ -570,5 +570,75 @@
(assert (equal? "111111111111111111111111111111111" (number->string 111111111111111111111111111111111)))
(assert (equal? "fffffffffffffffffffffffffffffffff" (number->string 0xfffffffffffffffffffffffffffffffff 16)))
+(assert (= (length (byte #\f)) 1))
+(assert (= (length #\я) 2))
+(assert (= (length #\⁹) 3))
+(assert-fail (= (length (uint8 0)) 1))
+(assert-fail (= (length (uint16 0)) 2))
+(assert-fail (= (length (uint32 0)) 4))
+(assert-fail (= (length (uint64 0)) 4))
+(assert-fail (= (length (bignum 0)) 0))
+
+(assert-fail (symbol 1))
+(assert-fail (symbol 'blah))
+(assert-fail (exit 1 2))
+
+(assert (integer-valued? 1.0))
+(assert (integer-valued? -1.0))
+(assert (integer-valued? 1.0f))
+(assert (integer-valued? -1.0f))
+(assert (integer-valued? (bignum 0)))
+
+(assert (integer? 0))
+(assert (integer? (bignum 0)))
+
+(assert (= 12345 (fixnum (bignum 12345))))
+(assert (= -12345 (fixnum (bignum -12345))))
+
+(assert (= 1.0 (truncate 1.3)))
+(assert (= -1.0 (truncate -1.3)))
+(assert (= 1.0 (truncate 1.3)))
+(assert (= -1.0 (truncate -1.3)))
+(assert (= 1.0 (truncate 1.3f)))
+(assert (= -1.0 (truncate -1.3f)))
+(assert (= 1.0 (truncate 1.3f)))
+(assert (= -1.0 (truncate -1.3f)))
+(assert (= 1 (truncate (bignum 1))))
+(assert (= -1 (truncate (bignum -1))))
+(assert (= 123 (truncate (int64 123))))
+(assert (= -123 (truncate (int8 -123))))
+(assert-fail (truncate "blah"))
+(assert-fail (truncate 'blah))
+(assert-fail (truncate truncate))
+
+(assert (= 0 (sin 0)))
+(assert (= 0 (sin 0.0)))
+(assert (= 0 (sin 0.0f)))
+(assert (= 0 (sin (int64 0))))
+(assert (= 0 (sin (bignum 0))))
+(assert-fail (sin "blah"))
+(assert-fail (sin 'blah))
+(assert-fail (sin sin))
+
+(assert (= (length (table "hello" "goodbye" 123 456)) 2))
+(assert-fail (table 1))
+(assert-fail (table 1 2 3))
+(define t (table 1 2 "3" 4 'foo 'bar))
+(assert (table? t))
+(assert (not (table? "nope")))
+(assert-fail (get t 3))
+(assert-fail (get t "foo"))
+(assert-fail (get t 1+))
+(assert (= 2 (get t 1)))
+(assert (= 4 (get t "3")))
+
+(assert (has? t 'foo))
+(assert (equal? 'bar (get t 'foo)))
+(assert (equal? t (del! t 'foo)))
+(assert (not (has? t 'foo)))
+(assert-fail (get t 'foo))
+(assert-fail (del! t 'foo))
+
+
(princ "all tests pass")
(newline)