ref: f4e2fb078b67553b832ae8a18b53deb451be4f99
parent: 497eb997f7c9d494b7ecd26c52dcac3361ef93e1
author: mag <mag-one@autistici.org>
date: Mon May 15 15:42:44 EDT 2023
first failing attempt
--- /dev/null
+++ b/MAG.notes
@@ -1,0 +1,35 @@
+
+cvalues.c: #include "operators.c"
+flisp.c: #include "cvalues.c"
+flisp.c: #include "types.c"
+flisp.c: #include "print.c"
+flisp.c: #include "read.c"
+flisp.c: #include "equal.c"
+llt/hashing.c: #include "lookup3.c"
+================================================================================
+
+$ make
+
+cc -o flmain.o -c flmain.c -O2 -g -Wall -Wextra -Wno-parentheses -std=c99 -I3rd -Illt -Iposix
+sed -nE 's/^BUILTIN[_]?(\(".*)/BUILTIN_FN\1/gp' *.c >builtin_fns.h
+cc -o flisp.o -c flisp.c -O2 -g -Wall -Wextra -Wno-parentheses -std=c99 -I3rd -Illt -Iposix
+flisp.c: In function 'fn_builtin_function':
+flisp.c:1855:24: warning: implicit declaration of function 'fn_builtin_builtin'; did you mean 'fn_builtin_function'? [-Wimplicit-function-declaration]
+ 1855 | return fn_builtin_builtin(args, nargs);
+ | ^~~~~~~~~~~~~~~~~~
+ | fn_builtin_function
+In file included from flisp.c:9:
+builtin_fns.h: At top level:
+flisp.h:308:17: error: conflicting types for 'fn_builtin_builtin'; have 'value_t(value_t *, int)' {aka 'long unsigned int(long unsigned int *, int)'}
+ 308 | value_t fn_builtin_##cname(value_t *args, int nargs)
+ | ^~~~~~~~~~~
+flisp.c:2060:33: note: in expansion of macro 'BUILTIN'
+ 2060 | #define BUILTIN_FN(l, c) extern BUILTIN(l, c);
+ | ^~~~~~~
+builtin_fns.h:46:1: note: in expansion of macro 'BUILTIN_FN'
+ 46 | BUILTIN_FN("builtin", builtin)
+ | ^~~~~~~~~~
+flisp.c:1855:24: note: previous implicit declaration of 'fn_builtin_builtin' with type 'int()'
+ 1855 | return fn_builtin_builtin(args, nargs);
+ | ^~~~~~~~~~~~~~~~~~
+make: *** [Makefile:79: flisp.o] Error 1
--- a/Makefile
+++ b/Makefile
@@ -56,6 +56,13 @@
3rd/mp/u64.o\
3rd/mt19937-64.o\
+# cvalues.o\
+# read.o\
+# print.o\
+# equal.o\
+# types.o\
+
+
.PHONY: all default test bootstrap clean
all: default
--- a/cvalues.c
+++ b/cvalues.c
@@ -1,11 +1,8 @@
+//#include "llt.h"
+//#include "flisp.h"
+
#include "operators.c"
-#ifdef BITS64
-#define NWORDS(sz) (((sz)+7)>>3)
-#else
-#define NWORDS(sz) (((sz)+3)>>2)
-#endif
-
value_t int8sym, uint8sym, int16sym, uint16sym, int32sym, uint32sym;
value_t int64sym, uint64sym, mpintsym;
value_t longsym, ulongsym, bytesym, wcharsym;
@@ -16,14 +13,14 @@
value_t structsym, arraysym, enumsym, cfunctionsym, voidsym, pointersym;
value_t unionsym;
-static htable_t TypeTable;
-static htable_t reverse_dlsym_lookup_table;
+htable_t TypeTable;
+htable_t reverse_dlsym_lookup_table;
+fltype_t *mpinttype;
static fltype_t *int8type, *uint8type;
static fltype_t *int16type, *uint16type;
static fltype_t *int32type, *uint32type;
static fltype_t *int64type, *uint64type;
static fltype_t *longtype, *ulongtype;
-static fltype_t *mpinttype;
static fltype_t *floattype, *doubletype;
fltype_t *bytetype, *wchartype;
fltype_t *stringtype, *wcstringtype;
@@ -55,7 +52,7 @@
}
// remove dead objects from finalization list in-place
-static void
+void
sweep_finalizers(void)
{
cvalue_t **lst = Finalizers;
@@ -401,7 +398,7 @@
type_error("number", n);
}
-static int
+int
cvalue_enum_init(fltype_t *ft, value_t arg, void *dest)
{
int n;
@@ -443,7 +440,7 @@
return cv;
}
-static int
+int
isarray(value_t v)
{
return iscvalue(v) && cv_class((cvalue_t*)ptr(v))->eltype != nil;
@@ -463,7 +460,7 @@
return 1;
}
-static int
+int
cvalue_array_init(fltype_t *ft, value_t arg, void *dest)
{
value_t type = ft->type;
@@ -700,7 +697,7 @@
return cv_type(ptr(args[0]));
}
-static value_t
+value_t
cvalue_relocate(value_t v)
{
size_t nw;
@@ -845,7 +842,7 @@
bounds_error(arr, ind);
}
-static value_t
+value_t
cvalue_array_aref(value_t *args)
{
char *data; int index;
@@ -879,7 +876,7 @@
return el;
}
-static value_t
+value_t
cvalue_array_aset(value_t *args)
{
char *data; int index;
@@ -969,7 +966,7 @@
RETURN_NUM_AS(Saccum, int32);
}
-static value_t
+value_t
fl_add_any(value_t *args, uint32_t nargs, fixnum_t carryIn)
{
uint64_t Uaccum = 0;
@@ -1061,7 +1058,7 @@
return return_from_uint64(Uaccum);
}
-static value_t
+value_t
fl_neg(value_t n)
{
uint32_t ui32;
@@ -1113,7 +1110,7 @@
type_error("number", n);
}
-static value_t
+value_t
fl_mul_any(value_t *args, uint32_t nargs, int64_t Saccum)
{
uint64_t Uaccum = 1;
@@ -1264,13 +1261,13 @@
return 1;
}
-static _Noreturn void
+_Noreturn void
DivideByZeroError(void)
{
lerrorf(DivideError, "/: division by zero");
}
-static value_t
+value_t
fl_div2(value_t a, value_t b)
{
double da, db;
@@ -1296,7 +1293,7 @@
return mk_double(da);
}
-static value_t
+value_t
fl_idiv2(value_t a, value_t b)
{
lltint_t ai, bi;
@@ -1567,7 +1564,7 @@
type_error("integer", a);
}
-static void
+void
cvalues_init(void)
{
htable_new(&TypeTable, 256);
--- a/equal.c
+++ b/equal.c
@@ -1,3 +1,7 @@
+//#include "llt.h"
+//#include "flisp.h"
+//#include "opcodes.h"
+
#define BOUNDED_COMPARE_BOUND 128
#define BOUNDED_HASH_BOUND 16384
@@ -286,7 +290,7 @@
}
// 'eq' means unordered comparison is sufficient
-static value_t
+value_t
compare_(value_t a, value_t b, int eq)
{
value_t guess = bounded_compare(a, b, BOUNDED_COMPARE_BOUND, eq);
--- a/flisp.c
+++ b/flisp.c
@@ -7,16 +7,6 @@
#include "llt.h"
#include "flisp.h"
-
-typedef struct Builtin Builtin;
-
-struct Builtin {
- char *name;
- int nargs;
-};
-
-#define ANYARGS -10000
-
#include "opcodes.h"
int
@@ -26,20 +16,11 @@
return tag(x) == TAG_FUNCTION && i < nelem(builtins) && builtins[i].name != nil;
}
-static uint32_t N_STACK;
-static value_t *Stack;
-static uint32_t SP = 0;
-static uint32_t curr_frame = 0;
-static char *curr_fname = nil;
-#define PUSH(v) \
- do{ \
- Stack[SP++] = (v); \
- }while(0)
-#define POP() (Stack[--SP])
-#define POPN(n) \
- do{ \
- SP -= (n); \
- }while(0)
+uint32_t N_STACK;
+value_t *Stack;
+uint32_t SP = 0;
+uint32_t curr_frame = 0;
+char *curr_fname = nil;
#define N_GC_HANDLES 1024
static value_t *GCHandleStack[N_GC_HANDLES];
@@ -52,23 +33,28 @@
value_t printwidthsym, printreadablysym, printprettysym, printlengthsym;
value_t printlevelsym, builtins_table_sym;
-static value_t NIL, LAMBDA, IF, TRYCATCH;
-static value_t BACKQUOTE, COMMA, COMMAAT, COMMADOT, FUNCTION;
+value_t NIL, LAMBDA, IF, TRYCATCH;
+value_t BACKQUOTE, COMMA, COMMAAT, COMMADOT, FUNCTION;
-static value_t pairsym, symbolsym, fixnumsym, vectorsym, builtinsym, vu8sym;
-static value_t definesym, defmacrosym, forsym, setqsym;
-static value_t tsym, Tsym, fsym, Fsym, booleansym, nullsym, evalsym, fnsym;
+value_t pairsym, symbolsym, fixnumsym, vectorsym, builtinsym, vu8sym;
+value_t definesym, defmacrosym, forsym, setqsym;
+value_t tsym, Tsym, fsym, Fsym, booleansym, nullsym, evalsym, fnsym;
// for reading characters
-static value_t nulsym, alarmsym, backspacesym, tabsym, linefeedsym, newlinesym;
-static value_t vtabsym, pagesym, returnsym, escsym, spacesym, deletesym;
+value_t nulsym, alarmsym, backspacesym, tabsym, linefeedsym, newlinesym;
+value_t vtabsym, pagesym, returnsym, escsym, spacesym, deletesym;
static value_t apply_cl(uint32_t nargs);
-static void *alloc_words(int n);
-static value_t relocate(value_t v);
-static fl_readstate_t *readstate = nil;
+fl_readstate_t *readstate = nil;
-static void
+uint8_t *fromspace;
+uint8_t *tospace;
+uint8_t *curheap;
+uint8_t *lim;
+uint32_t heapsize;//bytes
+uint32_t *consflags;
+
+void
free_readstate(fl_readstate_t *rs)
{
htable_free(&rs->backrefs);
@@ -75,13 +61,6 @@
htable_free(&rs->gensyms);
}
-static uint8_t *fromspace;
-static uint8_t *tospace;
-static uint8_t *curheap;
-static uint8_t *lim;
-static uint32_t heapsize;//bytes
-static uint32_t *consflags;
-
// error utilities ------------------------------------------------------------
// saved execution state for an unwind target
@@ -304,9 +283,7 @@
// conses ---------------------------------------------------------------------
-void gc(int mustgrow);
-
-static value_t
+value_t
mk_cons(void)
{
cons_t *c;
@@ -318,7 +295,7 @@
return tagptr(c, TAG_CONS);
}
-static void *
+void *
alloc_words(int n)
{
value_t *first;
@@ -336,16 +313,8 @@
return first;
}
-// allocate n consecutive conses
-#define cons_reserve(n) tagptr(alloc_words((n)*2), TAG_CONS)
+value_t the_empty_vector;
-#define cons_index(c) (((cons_t*)ptr(c))-((cons_t*)fromspace))
-#define ismarked(c) bitvector_get(consflags, cons_index(c))
-#define mark_cons(c) bitvector_set(consflags, cons_index(c), 1)
-#define unmark_cons(c) bitvector_set(consflags, cons_index(c), 0)
-
-static value_t the_empty_vector;
-
value_t
alloc_vector(size_t n, int init)
{
@@ -369,8 +338,9 @@
// print ----------------------------------------------------------------------
-static int isnumtok(char *tok, value_t *pval);
-static inline int symchar(char c);
+//static int isnumtok(char *tok, value_t *pval);
+//static inline int symchar(char c);
+extern inline int symchar(char c);
#include "print.c"
@@ -391,7 +361,7 @@
N_GCHND -= n;
}
-static value_t
+value_t
relocate(value_t v)
{
value_t a, d, nc, first, *pcdr;
--- a/flisp.h
+++ b/flisp.h
@@ -99,8 +99,6 @@
// doesn't lead to other values
#define leafp(a) (((a)&3) != 3)
-int num_to_ptr(value_t a, fixnum_t *pi, numerictype_t *pt, void **pp);
-
#define isforwarded(v) (((value_t*)ptr(v))[0] == TAG_FWD)
#define forwardloc(v) (((value_t*)ptr(v))[1])
#define forward(v, to) \
@@ -141,8 +139,6 @@
#define isclosure(x) isfunction(x)
#define iscbuiltin(x) (iscvalue(x) && cv_class(ptr(x)) == builtintype)
-void fl_gc_handle(value_t *pv);
-void fl_free_gc_handles(uint32_t n);
// utility for iterating over all arguments in a builtin
// i=index, i0=start index, arg = var for each arg, args = arg array
@@ -152,19 +148,24 @@
#define N_BUILTINS ((int)N_OPCODES)
+extern value_t printprettysym, printreadablysym, printwidthsym, printlengthsym;
+extern value_t printlevelsym, builtins_table_sym;
+extern value_t QUOTE;
extern value_t FL_NIL, FL_T, FL_F, FL_EOF;
-
#define FL_UNSPECIFIED FL_T
+int num_to_ptr(value_t a, fixnum_t *pi, numerictype_t *pt, void **pp);
+void fl_gc_handle(value_t *pv);
+void fl_free_gc_handles(uint32_t n);
+int fl_isnumber(value_t v);
+void fl_init(size_t initial_heapsize);
+int fl_load_system_image(value_t ios);
+
/* read, eval, print main entry points */
-value_t fl_read_sexpr(value_t f);
-void fl_print(ios_t *f, value_t v);
value_t fl_toplevel_eval(value_t expr);
value_t fl_apply(value_t f, value_t l);
value_t fl_applyn(uint32_t n, value_t f, ...);
-extern value_t printprettysym, printreadablysym, printwidthsym;
-
/* object model manipulation */
value_t fl_cons(value_t a, value_t b);
value_t fl_list2(value_t a, value_t b);
@@ -173,12 +174,6 @@
char *symbol_name(value_t v);
int fl_is_keyword_name(char *str, size_t len);
value_t alloc_vector(size_t n, int init);
-size_t llength(value_t v);
-value_t fl_compare(value_t a, value_t b); // -1, 0, or 1
-value_t fl_equal(value_t a, value_t b); // T or nil
-int equal_lispvalue(value_t a, value_t b);
-uintptr_t hash_lispvalue(value_t a);
-int isnumtok_base(char *tok, value_t *pval, int base);
/* safe casts */
cons_t *tocons(value_t v);
@@ -243,10 +238,6 @@
} cvtable_t;
value_t relocate_lispvalue(value_t v);
-void print_traverse(value_t v);
-void fl_print_chr(char c, ios_t *f);
-void fl_print_str(char *s, ios_t *f);
-void fl_print_child(ios_t *f, value_t v);
typedef int (*cvinitfunc_t)(struct _fltype_t*, value_t, void*);
@@ -318,9 +309,42 @@
typedef value_t (*builtin_t)(value_t*, int);
-extern value_t QUOTE;
+typedef struct {
+ char *name;
+ builtin_t fptr;
+}builtinspec_t;
+
+//--------------------------------------------------
+// Nothing changed here...just grouping by file.
+//--------------------------------------------------
+
+//--------------------------------------------------read.c
+value_t fl_read_sexpr(value_t f);
+int isnumtok_base(char *tok, value_t *pval, int base);
+//--------------------------------------------------read.c
+
+//--------------------------------------------------builtins.c
+size_t llength(value_t v);
+//--------------------------------------------------builtins.c
+
+//--------------------------------------------------equal.c
+value_t fl_compare(value_t a, value_t b); // -1, 0, or 1
+value_t fl_equal(value_t a, value_t b); // T or nil
+int equal_lispvalue(value_t a, value_t b);
+uintptr_t hash_lispvalue(value_t a);
+//--------------------------------------------------equal.c
+
+//--------------------------------------------------print.c
+void fl_print(ios_t *f, value_t v);
+void print_traverse(value_t v);
+void fl_print_chr(char c, ios_t *f);
+void fl_print_str(char *s, ios_t *f);
+void fl_print_child(ios_t *f, value_t v);
+//--------------------------------------------------print.c
+
+//--------------------------------------------------cvalues.c
extern value_t int8sym, uint8sym, int16sym, uint16sym, int32sym, uint32sym;
-extern value_t int64sym, uint64sym;
+extern value_t int64sym, uint64sym, mpintsym;
extern value_t longsym, ulongsym, bytesym, wcharsym;
extern value_t structsym, arraysym, enumsym, cfunctionsym, voidsym, pointersym;
extern value_t stringtypesym, wcstringtypesym, emptystringsym;
@@ -328,7 +352,6 @@
extern fltype_t *bytetype, *wchartype;
extern fltype_t *stringtype, *wcstringtype;
extern fltype_t *builtintype;
-
value_t cvalue(fltype_t *type, size_t sz);
void add_finalizer(cvalue_t *cv);
void cv_autorelease(cvalue_t *cv);
@@ -347,18 +370,9 @@
value_t string_from_cstr(char *str);
value_t string_from_cstrn(char *str, size_t n);
int fl_isstring(value_t v);
-int fl_isnumber(value_t v);
-int fl_isiostream(value_t v);
-ios_t *fl_toiostream(value_t v);
value_t cvalue_compare(value_t a, value_t b);
int numeric_compare(value_t a, value_t b, int eq, int eqnans, int typeerr);
-
void to_sized_ptr(value_t v, char **pdata, size_t *psz);
-
-fltype_t *get_type(value_t t);
-fltype_t *get_array_type(value_t eltype);
-fltype_t *define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab, cvinitfunc_t init);
-
value_t mk_double(double n);
value_t mk_float(float n);
value_t mk_int32(int32_t n);
@@ -368,7 +382,21 @@
value_t mk_wchar(int32_t n);
value_t return_from_uint64(uint64_t Uaccum);
value_t return_from_int64(int64_t Saccum);
+//--------------------------------------------------cvalues.c
+//--------------------------------------------------iostream.c
+int fl_isiostream(value_t v);
+ios_t *fl_toiostream(value_t v);
+//--------------------------------------------------iostream.c
+
+
+//--------------------------------------------------types.c
+fltype_t *get_type(value_t t);
+fltype_t *get_array_type(value_t eltype);
+fltype_t *define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab, cvinitfunc_t init);
+//--------------------------------------------------types.c
+
+//--------------------------------------------------operators.c
double conv_to_double(void *data, numerictype_t tag);
void conv_from_double(void *data, double d, numerictype_t tag);
mpint *conv_to_mpint(void *data, numerictype_t tag);
@@ -376,6 +404,7 @@
uint64_t conv_to_uint64(void *data, numerictype_t tag);
int32_t conv_to_int32(void *data, numerictype_t tag);
uint32_t conv_to_uint32(void *data, numerictype_t tag);
+
#if defined(ULONG64)
#define conv_to_long conv_to_int64
#define conv_to_ulong conv_to_uint64
@@ -383,13 +412,135 @@
#define conv_to_long conv_to_int32
#define conv_to_ulong conv_to_uint32
#endif
+//--------------------------------------------------operators.c
-typedef struct {
- char *name;
- builtin_t fptr;
-}builtinspec_t;
-void fl_init(size_t initial_heapsize);
-int fl_load_system_image(value_t ios);
+//--------------------------------------------------------------------------------
+// New declarations here.. needed to permit files splitting
+// (and grouped by files).
+//--------------------------------------------------------------------------------
+extern value_t *Stack;
+extern uint32_t SP;
+extern uint32_t N_STACK;
+extern uint32_t curr_frame;
+extern char *curr_fname;
+#define PUSH(v) \
+ do{ \
+ Stack[SP++] = (v); \
+ }while(0)
+#define POP() (Stack[--SP])
+#define POPN(n) \
+ do{ \
+ SP -= (n); \
+ }while(0)
+
+extern value_t NIL, LAMBDA, IF, TRYCATCH;
+extern value_t BACKQUOTE, COMMA, COMMAAT, COMMADOT, FUNCTION;
+extern value_t pairsym, symbolsym, fixnumsym, vectorsym, builtinsym, vu8sym;
+extern value_t definesym, defmacrosym, forsym, setqsym;
+extern value_t tsym, Tsym, fsym, Fsym, booleansym, nullsym, evalsym, fnsym;
+extern value_t nulsym, alarmsym, backspacesym, tabsym, linefeedsym, newlinesym;
+extern value_t vtabsym, pagesym, returnsym, escsym, spacesym, deletesym;
+
+void *alloc_words(int n);
+value_t relocate(value_t v);
+
+extern fl_readstate_t *readstate;
+void free_readstate(fl_readstate_t *rs);
+
+extern uint8_t *fromspace;
+extern uint32_t heapsize;//bytes
+extern uint8_t *tospace;
+extern uint8_t *curheap;
+extern uint8_t *lim;
+extern uint32_t *consflags;
+
+void gc(int mustgrow);
+
+extern value_t IOError, ParseError, TypeError, ArgError, MemoryError;
+extern value_t DivideError, BoundsError, Error, KeyError, EnumerationError;
+
+// allocate n consecutive conses
+#define cons_reserve(n) tagptr(alloc_words((n)*2), TAG_CONS)
+#define cons_index(c) (((cons_t*)ptr(c))-((cons_t*)fromspace))
+#define ismarked(c) bitvector_get(consflags, cons_index(c))
+#define mark_cons(c) bitvector_set(consflags, cons_index(c), 1)
+#define unmark_cons(c) bitvector_set(consflags, cons_index(c), 0)
+
+typedef struct Builtin Builtin;
+
+struct Builtin {
+ char *name;
+ int nargs;
+};
+
+#define ANYARGS -10000
+
+extern value_t the_empty_vector;
+value_t mk_cons(void);
+
+//--------------------------------------------------cvalues.c
+void cvalues_init(void);
+value_t fl_idiv2(value_t a, value_t b);
+value_t fl_div2(value_t a, value_t b);
+value_t fl_mul_any(value_t *args, uint32_t nargs, int64_t Saccum);
+value_t fl_neg(value_t n);
+value_t fl_add_any(value_t *args, uint32_t nargs, fixnum_t carryIn);
+value_t cvalue_array_aset(value_t *args);
+value_t cvalue_array_aref(value_t *args);
+value_t cvalue_relocate(value_t v);
+void sweep_finalizers(void);
+
+extern htable_t TypeTable;
+extern htable_t reverse_dlsym_lookup_table;
+extern fltype_t *mpinttype;
+
+int cvalue_array_init(fltype_t *ft, value_t arg, void *dest);
+int cvalue_enum_init(fltype_t *ft, value_t arg, void *dest);
+
+value_t mk_mpint(mpint *n);
+
+#ifdef BITS64
+#define NWORDS(sz) (((sz)+7)>>3)
+#else
+#define NWORDS(sz) (((sz)+3)>>2)
#endif
+
+int isarray(value_t v);
+_Noreturn void DivideByZeroError(void);
+
+//--------------------------------------------------cvalues.c
+
+
+//--------------------------------------------------read.c
+int isnumtok(char *tok, value_t *pval);
+
+// defines which characters are ordinary symbol characters.
+// exceptions are '.', which is an ordinary symbol character
+// unless it's the only character in the symbol, and '#', which is
+// an ordinary symbol character unless it's the first character.
+inline int
+symchar(char c)
+{
+ //static char *special = "()[]'\";`,\\| \a\b\f\n\r\t\v";
+ char *special = "()[]'\";`,\\| \a\b\f\n\r\t\v";
+ return !strchr(special, c);
+}
+//--------------------------------------------------read.c
+
+//--------------------------------------------------types.c
+void relocate_typetable(void);
+//--------------------------------------------------types.c
+
+//--------------------------------------------------equal.c
+value_t compare_(value_t a, value_t b, int eq);
+//--------------------------------------------------equal.c
+
+//--------------------------------------------------print.c
+extern htable_t printconses;
+extern int SCR_WIDTH;
+//--------------------------------------------------print.c
+
+#endif
+
--- /dev/null
+++ b/flisp.h-first_attempt
@@ -1,0 +1,467 @@
+#ifndef FLISP_H
+#define FLISP_H
+
+/* functions needed to implement the value interface (cvtable_t) */
+typedef enum {
+ T_INT8, T_UINT8,
+ T_INT16, T_UINT16,
+ T_INT32, T_UINT32,
+ T_INT64, T_UINT64,
+ T_MPINT,
+ T_FLOAT,
+ T_DOUBLE,
+}numerictype_t;
+
+#define NONNUMERIC (0xff)
+#define valid_numtype(v) ((v) <= T_DOUBLE)
+
+typedef uintptr_t value_t;
+typedef lltint_t fixnum_t;
+
+#ifdef BITS64
+#define T_FIXNUM T_INT64
+#define fits_fixnum(x) (((x)>>61) == 0 || (~((x)>>61)) == 0)
+#define mk_xlong mk_int64
+#else
+#define T_FIXNUM T_INT32
+#define fits_fixnum(x) (((x)>>29) == 0 || (~((x)>>29)) == 0)
+#define mk_xlong mk_long
+#endif
+
+typedef struct {
+ value_t car;
+ value_t cdr;
+}cons_t;
+
+typedef struct _symbol_t {
+ value_t binding; // global value binding
+ uint32_t hash;
+ uint8_t numtype;
+ uint8_t size;
+ uint8_t align;
+ uint8_t flags;
+ struct _fltype_t *type;
+ void *dlcache; // dlsym address
+ // below fields are private
+ struct _symbol_t *left;
+ struct _symbol_t *right;
+ union {
+ char name[1];
+ void *_pad; // ensure field aligned to pointer size
+ };
+}symbol_t;
+
+typedef struct {
+ value_t isconst;
+ value_t binding; // global value binding
+ struct _fltype_t *type;
+ uint32_t id;
+}gensym_t;
+
+enum {
+ TAG_NUM,
+ TAG_CPRIM,
+ TAG_FUNCTION,
+ TAG_VECTOR,
+ TAG_NUM1,
+ TAG_CVALUE,
+ TAG_SYM,
+ TAG_CONS,
+};
+
+enum {
+ FLAG_CONST = 1<<0,
+ FLAG_KEYWORD = 1<<1,
+};
+
+#define UNBOUND ((value_t)0x1) // an invalid value
+#define TAG_FWD UNBOUND
+#define tag(x) ((x) & 0x7)
+#define ptr(x) ((void*)((x) & (~(value_t)0x7)))
+#define tagptr(p, t) (((value_t)(p)) | (t))
+#define fixnum(x) ((value_t)((fixnum_t)(x))<<2)
+#define numval(x) (((fixnum_t)(x))>>2)
+#define fits_bits(x, b) (((x)>>(b-1)) == 0 || (~((x)>>(b-1))) == 0)
+#define uintval(x) (((unsigned int)(x))>>3)
+#define builtin(n) tagptr((((int)n)<<3), TAG_FUNCTION)
+#define iscons(x) (tag(x) == TAG_CONS)
+#define issymbol(x) (tag(x) == TAG_SYM)
+#define isfixnum(x) (((x)&3) == TAG_NUM)
+#define bothfixnums(x, y) ((((x)|(y)) & 3) == TAG_NUM)
+int isbuiltin(value_t x);
+#define isvector(x) (tag(x) == TAG_VECTOR)
+#define iscvalue(x) (tag(x) == TAG_CVALUE)
+#define iscprim(x) (tag(x) == TAG_CPRIM)
+#define selfevaluating(x) (tag(x) < 6)
+// comparable with ==
+#define eq_comparable(a, b) (!(((a)|(b))&1))
+#define eq_comparablep(a) (!((a)&1))
+// doesn't lead to other values
+#define leafp(a) (((a)&3) != 3)
+
+#define isforwarded(v) (((value_t*)ptr(v))[0] == TAG_FWD)
+#define forwardloc(v) (((value_t*)ptr(v))[1])
+#define forward(v, to) \
+ do{ \
+ (((value_t*)ptr(v))[0] = TAG_FWD); \
+ (((value_t*)ptr(v))[1] = to); \
+ }while (0)
+
+#define vector_size(v) (((size_t*)ptr(v))[0]>>2)
+#define vector_setsize(v, n) (((size_t*)ptr(v))[0] = ((n)<<2))
+#define vector_elt(v, i) (((value_t*)ptr(v))[1+(i)])
+#define vector_grow_amt(x) ((x)<8 ? 5 : 6*((x)>>3))
+// functions ending in _ are unsafe, faster versions
+#define car_(v) (((cons_t*)ptr(v))->car)
+#define cdr_(v) (((cons_t*)ptr(v))->cdr)
+#define car(v) (tocons((v))->car)
+#define cdr(v) (tocons((v))->cdr)
+#define fn_bcode(f) (((value_t*)ptr(f))[0])
+#define fn_vals(f) (((value_t*)ptr(f))[1])
+#define fn_env(f) (((value_t*)ptr(f))[2])
+#define fn_name(f) (((value_t*)ptr(f))[3])
+
+#define set(s, v) (((symbol_t*)ptr(s))->binding = (v))
+#define setc(s, v) \
+ do{ \
+ ((symbol_t*)ptr(s))->flags |= FLAG_CONST; \
+ ((symbol_t*)ptr(s))->binding = (v); \
+ }while (0)
+#define isconstant(s) ((s)->flags & FLAG_CONST)
+#define iskeyword(s) ((s)->flags & FLAG_KEYWORD)
+#define symbol_value(s) (((symbol_t*)ptr(s))->binding)
+#define sym_to_numtype(s) (((symbol_t*)ptr(s))->numtype)
+#define ismanaged(v) ((((uint8_t*)ptr(v)) >= fromspace) && (((uint8_t*)ptr(v)) < fromspace+heapsize))
+#define isgensym(x) (issymbol(x) && ismanaged(x))
+value_t gensym(void);
+
+#define isfunction(x) (tag(x) == TAG_FUNCTION && (x) > (N_BUILTINS<<3))
+#define isclosure(x) isfunction(x)
+#define iscbuiltin(x) (iscvalue(x) && cv_class(ptr(x)) == builtintype)
+
+
+// utility for iterating over all arguments in a builtin
+// i=index, i0=start index, arg = var for each arg, args = arg array
+// assumes "nargs" is the argument count
+#define FOR_ARGS(i, i0, arg, args) \
+ for(i=i0; i<nargs && ((arg=args[i]) || 1); i++)
+
+#define N_BUILTINS ((int)N_OPCODES)
+
+extern value_t printprettysym, printreadablysym, printwidthsym;
+extern value_t QUOTE;
+extern value_t FL_NIL, FL_T, FL_F, FL_EOF;
+#define FL_UNSPECIFIED FL_T
+
+int num_to_ptr(value_t a, fixnum_t *pi, numerictype_t *pt, void **pp);
+void fl_gc_handle(value_t *pv);
+void fl_free_gc_handles(uint32_t n);
+int fl_isnumber(value_t v);
+void fl_init(size_t initial_heapsize);
+int fl_load_system_image(value_t ios);
+
+/* read, eval, print main entry points */
+value_t fl_toplevel_eval(value_t expr);
+value_t fl_apply(value_t f, value_t l);
+value_t fl_applyn(uint32_t n, value_t f, ...);
+
+/* object model manipulation */
+value_t fl_cons(value_t a, value_t b);
+value_t fl_list2(value_t a, value_t b);
+value_t fl_listn(size_t n, ...);
+value_t symbol(char *str);
+char *symbol_name(value_t v);
+int fl_is_keyword_name(char *str, size_t len);
+value_t alloc_vector(size_t n, int init);
+
+/* safe casts */
+cons_t *tocons(value_t v);
+symbol_t *tosymbol(value_t v);
+fixnum_t tofixnum(value_t v);
+char *tostring(value_t v);
+
+/* error handling */
+typedef struct _fl_readstate_t {
+ htable_t backrefs;
+ htable_t gensyms;
+ value_t source;
+ struct _fl_readstate_t *prev;
+}fl_readstate_t;
+
+typedef struct _ectx_t {
+ jmp_buf buf;
+ uint32_t sp;
+ uint32_t frame;
+ uint32_t ngchnd;
+ fl_readstate_t *rdst;
+ struct _ectx_t *prev;
+}fl_exception_context_t;
+
+extern fl_exception_context_t *fl_ctx;
+extern uint32_t fl_throwing_frame;
+extern value_t fl_lasterror;
+
+#define FL_TRY_EXTERN \
+ fl_exception_context_t _ctx; int l__tr, l__ca; \
+ fl_savestate(&_ctx); fl_ctx = &_ctx; \
+ if(!setjmp(_ctx.buf)) \
+ for(l__tr=1; l__tr; l__tr=0, (void)(fl_ctx = fl_ctx->prev))
+
+#define FL_CATCH_EXTERN_NO_RESTORE \
+ else \
+ for(l__ca=1; l__ca;)
+
+#define FL_CATCH_EXTERN \
+ else \
+ for(l__ca=1; l__ca; l__ca=0, fl_restorestate(&_ctx))
+
+_Noreturn void lerrorf(value_t e, char *format, ...);
+void fl_savestate(fl_exception_context_t *_ctx);
+void fl_restorestate(fl_exception_context_t *_ctx);
+_Noreturn void fl_raise(value_t e);
+_Noreturn void type_error(char *expected, value_t got);
+_Noreturn void bounds_error(value_t arr, value_t ind);
+_Noreturn void unbound_error(value_t sym);
+extern value_t ArgError, IOError, KeyError, MemoryError, EnumerationError;
+#define argcount(nargs, c) \
+ do{ \
+ if(__unlikely(nargs != c)) \
+ lerrorf(ArgError, "arity mismatch: wanted %d, got %d", c, nargs); \
+ }while(0)
+
+typedef struct {
+ void (*print)(value_t self, ios_t *f);
+ void (*relocate)(value_t oldv, value_t newv);
+ void (*finalize)(value_t self);
+ void (*print_traverse)(value_t self);
+} cvtable_t;
+
+value_t relocate_lispvalue(value_t v);
+
+typedef int (*cvinitfunc_t)(struct _fltype_t*, value_t, void*);
+
+typedef struct _fltype_t {
+ value_t type;
+ cvtable_t *vtable;
+ struct _fltype_t *eltype; // for arrays
+ struct _fltype_t *artype; // (array this)
+ cvinitfunc_t init;
+ size_t size;
+ size_t elsz;
+ int marked;
+ numerictype_t numtype;
+}fltype_t;
+
+typedef struct {
+ fltype_t *type;
+ void *data;
+ size_t len; // length of *data in bytes
+ union {
+ value_t parent; // optional
+ char _space[1]; // variable size
+ };
+}cvalue_t;
+
+#define CVALUE_NWORDS 4
+
+typedef struct {
+ fltype_t *type;
+ char _space[1];
+}cprim_t;
+
+typedef struct {
+ value_t bcode;
+ value_t vals;
+ value_t env;
+ value_t name;
+}function_t;
+
+#define CPRIM_NWORDS 2
+#define MAX_INL_SIZE 384
+
+#define CV_OWNED_BIT 0x1
+#define CV_PARENT_BIT 0x2
+#define owned(cv) ((uintptr_t)(cv)->type & CV_OWNED_BIT)
+#define hasparent(cv) ((uintptr_t)(cv)->type & CV_PARENT_BIT)
+#define isinlined(cv) ((cv)->data == &(cv)->_space[0])
+#define cv_class(cv) ((fltype_t*)(((uintptr_t)((cvalue_t*)cv)->type)&~3))
+#define cv_len(cv) (((cvalue_t*)(cv))->len)
+#define cv_type(cv) (cv_class(cv)->type)
+#define cv_data(cv) (((cvalue_t*)(cv))->data)
+#define cv_isstr(cv) (cv_class(cv)->eltype == bytetype)
+#define cv_isPOD(cv) (cv_class(cv)->init != nil)
+
+#define cvalue_data(v) cv_data((cvalue_t*)ptr(v))
+#define cvalue_len(v) cv_len((cvalue_t*)ptr(v))
+#define value2c(type, v) ((type)cv_data((cvalue_t*)ptr(v)))
+
+#define cp_class(cp) (((cprim_t*)(cp))->type)
+#define cp_type(cp) (cp_class(cp)->type)
+#define cp_numtype(cp) (cp_class(cp)->numtype)
+#define cp_data(cp) (&((cprim_t*)(cp))->_space[0])
+
+// WARNING: multiple evaluation!
+#define cptr(v) (iscprim(v) ? cp_data(ptr(v)) : cv_data(ptr(v)))
+
+#define BUILTIN(lname, cname) \
+ value_t fn_builtin_##cname(value_t *args, int nargs)
+
+typedef value_t (*builtin_t)(value_t*, int);
+
+typedef struct {
+ char *name;
+ builtin_t fptr;
+}builtinspec_t;
+
+//--------------------------------------------------
+// THESE WERE STATIC BEFORE FILES SPLITTING
+//--------------------------------------------------
+extern value_t *Stack;
+extern uint32_t SP;
+extern uint32_t N_STACK;
+extern uint32_t curr_frame;
+extern char *curr_fname;
+
+#define PUSH(v) \
+ do{ \
+ Stack[SP++] = (v); \
+ }while(0)
+#define POP() (Stack[--SP])
+#define POPN(n) \
+ do{ \
+ SP -= (n); \
+ }while(0)
+
+extern value_t NIL, LAMBDA, IF, TRYCATCH;
+extern value_t BACKQUOTE, COMMA, COMMAAT, COMMADOT, FUNCTION;
+extern value_t pairsym, symbolsym, fixnumsym, vectorsym, builtinsym, vu8sym;
+extern value_t definesym, defmacrosym, forsym, setqsym;
+extern value_t tsym, Tsym, fsym, Fsym, booleansym, nullsym, evalsym, fnsym;
+// for reading characters
+extern value_t nulsym, alarmsym, backspacesym, tabsym, linefeedsym, newlinesym;
+extern value_t vtabsym, pagesym, returnsym, escsym, spacesym, deletesym;
+extern void *alloc_words(int n);
+extern value_t relocate(value_t v);
+extern fl_readstate_t *readstate = nil;
+extern void
+free_readstate(fl_readstate_t *rs)
+{
+ htable_free(&rs->backrefs);
+ htable_free(&rs->gensyms);
+}
+
+extern uint8_t *fromspace;
+extern uint32_t heapsize;//bytes
+extern uint8_t *tospace;
+extern uint8_t *curheap;
+extern uint8_t *lim;
+extern uint32_t *consflags;
+
+value_t mk_cons(void);
+void *alloc_words(int n);
+
+int isnumtok(char *tok, value_t *pval);
+inline int symchar(char c);
+value_t relocate(value_t v);
+
+extern value_t the_empty_vector;
+
+
+
+//--------------------------------------------------read.c
+value_t fl_read_sexpr(value_t f);
+int isnumtok_base(char *tok, value_t *pval, int base);
+//--------------------------------------------------read.c
+
+//--------------------------------------------------builtins.c
+size_t llength(value_t v);
+//--------------------------------------------------builtins.c
+
+//--------------------------------------------------equal.c
+value_t fl_compare(value_t a, value_t b); // -1, 0, or 1
+value_t fl_equal(value_t a, value_t b); // T or nil
+int equal_lispvalue(value_t a, value_t b);
+uintptr_t hash_lispvalue(value_t a);
+//--------------------------------------------------equal.c
+
+//--------------------------------------------------print.c
+void fl_print(ios_t *f, value_t v);
+void print_traverse(value_t v);
+void fl_print_chr(char c, ios_t *f);
+void fl_print_str(char *s, ios_t *f);
+void fl_print_child(ios_t *f, value_t v);
+//--------------------------------------------------print.c
+
+//--------------------------------------------------cvalues.c
+extern value_t int8sym, uint8sym, int16sym, uint16sym, int32sym, uint32sym;
+extern value_t int64sym, uint64sym;
+extern value_t longsym, ulongsym, bytesym, wcharsym;
+extern value_t structsym, arraysym, enumsym, cfunctionsym, voidsym, pointersym;
+extern value_t stringtypesym, wcstringtypesym, emptystringsym;
+extern value_t unionsym, floatsym, doublesym;
+extern fltype_t *bytetype, *wchartype;
+extern fltype_t *stringtype, *wcstringtype;
+extern fltype_t *builtintype;
+value_t cvalue(fltype_t *type, size_t sz);
+void add_finalizer(cvalue_t *cv);
+void cv_autorelease(cvalue_t *cv);
+void cv_pin(cvalue_t *cv);
+size_t ctype_sizeof(value_t type, int *palign);
+value_t cvalue_copy(value_t v);
+value_t cvalue_from_data(fltype_t *type, void *data, size_t sz);
+value_t cvalue_from_ref(fltype_t *type, void *ptr, size_t sz, value_t parent);
+value_t cbuiltin(char *name, builtin_t f);
+size_t cvalue_arraylen(value_t v);
+value_t size_wrap(size_t sz);
+size_t toulong(value_t n);
+off_t tooffset(value_t n);
+value_t cvalue_string(size_t sz);
+value_t cvalue_static_cstring(const char *str);
+value_t string_from_cstr(char *str);
+value_t string_from_cstrn(char *str, size_t n);
+int fl_isstring(value_t v);
+value_t cvalue_compare(value_t a, value_t b);
+int numeric_compare(value_t a, value_t b, int eq, int eqnans, int typeerr);
+void to_sized_ptr(value_t v, char **pdata, size_t *psz);
+value_t mk_double(double n);
+value_t mk_float(float n);
+value_t mk_int32(int32_t n);
+value_t mk_uint32(uint32_t n);
+value_t mk_int64(int64_t n);
+value_t mk_uint64(uint64_t n);
+value_t mk_wchar(int32_t n);
+value_t return_from_uint64(uint64_t Uaccum);
+value_t return_from_int64(int64_t Saccum);
+//--------------------------------------------------cvalues.c
+
+//--------------------------------------------------iostream.c
+int fl_isiostream(value_t v);
+ios_t *fl_toiostream(value_t v);
+//--------------------------------------------------iostream.c
+
+
+//--------------------------------------------------types.c
+fltype_t *get_type(value_t t);
+fltype_t *get_array_type(value_t eltype);
+fltype_t *define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab, cvinitfunc_t init);
+//--------------------------------------------------types.c
+
+//--------------------------------------------------operators.c
+double conv_to_double(void *data, numerictype_t tag);
+void conv_from_double(void *data, double d, numerictype_t tag);
+mpint *conv_to_mpint(void *data, numerictype_t tag);
+int64_t conv_to_int64(void *data, numerictype_t tag);
+uint64_t conv_to_uint64(void *data, numerictype_t tag);
+int32_t conv_to_int32(void *data, numerictype_t tag);
+uint32_t conv_to_uint32(void *data, numerictype_t tag);
+//--------------------------------------------------???
+#if defined(ULONG64)
+#define conv_to_long conv_to_int64
+#define conv_to_ulong conv_to_uint64
+#else
+#define conv_to_long conv_to_int32
+#define conv_to_ulong conv_to_uint32
+#endif
+//--------------------------------------------------operators.c
+
+#endif
--- /dev/null
+++ b/flisp.h-orig
@@ -1,0 +1,395 @@
+#ifndef FLISP_H
+#define FLISP_H
+
+/* functions needed to implement the value interface (cvtable_t) */
+typedef enum {
+ T_INT8, T_UINT8,
+ T_INT16, T_UINT16,
+ T_INT32, T_UINT32,
+ T_INT64, T_UINT64,
+ T_MPINT,
+ T_FLOAT,
+ T_DOUBLE,
+}numerictype_t;
+
+#define NONNUMERIC (0xff)
+#define valid_numtype(v) ((v) <= T_DOUBLE)
+
+typedef uintptr_t value_t;
+typedef lltint_t fixnum_t;
+
+#ifdef BITS64
+#define T_FIXNUM T_INT64
+#define fits_fixnum(x) (((x)>>61) == 0 || (~((x)>>61)) == 0)
+#define mk_xlong mk_int64
+#else
+#define T_FIXNUM T_INT32
+#define fits_fixnum(x) (((x)>>29) == 0 || (~((x)>>29)) == 0)
+#define mk_xlong mk_long
+#endif
+
+typedef struct {
+ value_t car;
+ value_t cdr;
+}cons_t;
+
+typedef struct _symbol_t {
+ value_t binding; // global value binding
+ uint32_t hash;
+ uint8_t numtype;
+ uint8_t size;
+ uint8_t align;
+ uint8_t flags;
+ struct _fltype_t *type;
+ void *dlcache; // dlsym address
+ // below fields are private
+ struct _symbol_t *left;
+ struct _symbol_t *right;
+ union {
+ char name[1];
+ void *_pad; // ensure field aligned to pointer size
+ };
+}symbol_t;
+
+typedef struct {
+ value_t isconst;
+ value_t binding; // global value binding
+ struct _fltype_t *type;
+ uint32_t id;
+}gensym_t;
+
+enum {
+ TAG_NUM,
+ TAG_CPRIM,
+ TAG_FUNCTION,
+ TAG_VECTOR,
+ TAG_NUM1,
+ TAG_CVALUE,
+ TAG_SYM,
+ TAG_CONS,
+};
+
+enum {
+ FLAG_CONST = 1<<0,
+ FLAG_KEYWORD = 1<<1,
+};
+
+#define UNBOUND ((value_t)0x1) // an invalid value
+#define TAG_FWD UNBOUND
+#define tag(x) ((x) & 0x7)
+#define ptr(x) ((void*)((x) & (~(value_t)0x7)))
+#define tagptr(p, t) (((value_t)(p)) | (t))
+#define fixnum(x) ((value_t)((fixnum_t)(x))<<2)
+#define numval(x) (((fixnum_t)(x))>>2)
+#define fits_bits(x, b) (((x)>>(b-1)) == 0 || (~((x)>>(b-1))) == 0)
+#define uintval(x) (((unsigned int)(x))>>3)
+#define builtin(n) tagptr((((int)n)<<3), TAG_FUNCTION)
+#define iscons(x) (tag(x) == TAG_CONS)
+#define issymbol(x) (tag(x) == TAG_SYM)
+#define isfixnum(x) (((x)&3) == TAG_NUM)
+#define bothfixnums(x, y) ((((x)|(y)) & 3) == TAG_NUM)
+int isbuiltin(value_t x);
+#define isvector(x) (tag(x) == TAG_VECTOR)
+#define iscvalue(x) (tag(x) == TAG_CVALUE)
+#define iscprim(x) (tag(x) == TAG_CPRIM)
+#define selfevaluating(x) (tag(x) < 6)
+// comparable with ==
+#define eq_comparable(a, b) (!(((a)|(b))&1))
+#define eq_comparablep(a) (!((a)&1))
+// doesn't lead to other values
+#define leafp(a) (((a)&3) != 3)
+
+int num_to_ptr(value_t a, fixnum_t *pi, numerictype_t *pt, void **pp);
+
+#define isforwarded(v) (((value_t*)ptr(v))[0] == TAG_FWD)
+#define forwardloc(v) (((value_t*)ptr(v))[1])
+#define forward(v, to) \
+ do{ \
+ (((value_t*)ptr(v))[0] = TAG_FWD); \
+ (((value_t*)ptr(v))[1] = to); \
+ }while (0)
+
+#define vector_size(v) (((size_t*)ptr(v))[0]>>2)
+#define vector_setsize(v, n) (((size_t*)ptr(v))[0] = ((n)<<2))
+#define vector_elt(v, i) (((value_t*)ptr(v))[1+(i)])
+#define vector_grow_amt(x) ((x)<8 ? 5 : 6*((x)>>3))
+// functions ending in _ are unsafe, faster versions
+#define car_(v) (((cons_t*)ptr(v))->car)
+#define cdr_(v) (((cons_t*)ptr(v))->cdr)
+#define car(v) (tocons((v))->car)
+#define cdr(v) (tocons((v))->cdr)
+#define fn_bcode(f) (((value_t*)ptr(f))[0])
+#define fn_vals(f) (((value_t*)ptr(f))[1])
+#define fn_env(f) (((value_t*)ptr(f))[2])
+#define fn_name(f) (((value_t*)ptr(f))[3])
+
+#define set(s, v) (((symbol_t*)ptr(s))->binding = (v))
+#define setc(s, v) \
+ do{ \
+ ((symbol_t*)ptr(s))->flags |= FLAG_CONST; \
+ ((symbol_t*)ptr(s))->binding = (v); \
+ }while (0)
+#define isconstant(s) ((s)->flags & FLAG_CONST)
+#define iskeyword(s) ((s)->flags & FLAG_KEYWORD)
+#define symbol_value(s) (((symbol_t*)ptr(s))->binding)
+#define sym_to_numtype(s) (((symbol_t*)ptr(s))->numtype)
+#define ismanaged(v) ((((uint8_t*)ptr(v)) >= fromspace) && (((uint8_t*)ptr(v)) < fromspace+heapsize))
+#define isgensym(x) (issymbol(x) && ismanaged(x))
+value_t gensym(void);
+
+#define isfunction(x) (tag(x) == TAG_FUNCTION && (x) > (N_BUILTINS<<3))
+#define isclosure(x) isfunction(x)
+#define iscbuiltin(x) (iscvalue(x) && cv_class(ptr(x)) == builtintype)
+
+void fl_gc_handle(value_t *pv);
+void fl_free_gc_handles(uint32_t n);
+
+// utility for iterating over all arguments in a builtin
+// i=index, i0=start index, arg = var for each arg, args = arg array
+// assumes "nargs" is the argument count
+#define FOR_ARGS(i, i0, arg, args) \
+ for(i=i0; i<nargs && ((arg=args[i]) || 1); i++)
+
+#define N_BUILTINS ((int)N_OPCODES)
+
+extern value_t FL_NIL, FL_T, FL_F, FL_EOF;
+
+#define FL_UNSPECIFIED FL_T
+
+/* read, eval, print main entry points */
+value_t fl_read_sexpr(value_t f);
+void fl_print(ios_t *f, value_t v);
+value_t fl_toplevel_eval(value_t expr);
+value_t fl_apply(value_t f, value_t l);
+value_t fl_applyn(uint32_t n, value_t f, ...);
+
+extern value_t printprettysym, printreadablysym, printwidthsym;
+
+/* object model manipulation */
+value_t fl_cons(value_t a, value_t b);
+value_t fl_list2(value_t a, value_t b);
+value_t fl_listn(size_t n, ...);
+value_t symbol(char *str);
+char *symbol_name(value_t v);
+int fl_is_keyword_name(char *str, size_t len);
+value_t alloc_vector(size_t n, int init);
+size_t llength(value_t v);
+value_t fl_compare(value_t a, value_t b); // -1, 0, or 1
+value_t fl_equal(value_t a, value_t b); // T or nil
+int equal_lispvalue(value_t a, value_t b);
+uintptr_t hash_lispvalue(value_t a);
+int isnumtok_base(char *tok, value_t *pval, int base);
+
+/* safe casts */
+cons_t *tocons(value_t v);
+symbol_t *tosymbol(value_t v);
+fixnum_t tofixnum(value_t v);
+char *tostring(value_t v);
+
+/* error handling */
+typedef struct _fl_readstate_t {
+ htable_t backrefs;
+ htable_t gensyms;
+ value_t source;
+ struct _fl_readstate_t *prev;
+}fl_readstate_t;
+
+typedef struct _ectx_t {
+ jmp_buf buf;
+ uint32_t sp;
+ uint32_t frame;
+ uint32_t ngchnd;
+ fl_readstate_t *rdst;
+ struct _ectx_t *prev;
+}fl_exception_context_t;
+
+extern fl_exception_context_t *fl_ctx;
+extern uint32_t fl_throwing_frame;
+extern value_t fl_lasterror;
+
+#define FL_TRY_EXTERN \
+ fl_exception_context_t _ctx; int l__tr, l__ca; \
+ fl_savestate(&_ctx); fl_ctx = &_ctx; \
+ if(!setjmp(_ctx.buf)) \
+ for(l__tr=1; l__tr; l__tr=0, (void)(fl_ctx = fl_ctx->prev))
+
+#define FL_CATCH_EXTERN_NO_RESTORE \
+ else \
+ for(l__ca=1; l__ca;)
+
+#define FL_CATCH_EXTERN \
+ else \
+ for(l__ca=1; l__ca; l__ca=0, fl_restorestate(&_ctx))
+
+_Noreturn void lerrorf(value_t e, char *format, ...);
+void fl_savestate(fl_exception_context_t *_ctx);
+void fl_restorestate(fl_exception_context_t *_ctx);
+_Noreturn void fl_raise(value_t e);
+_Noreturn void type_error(char *expected, value_t got);
+_Noreturn void bounds_error(value_t arr, value_t ind);
+_Noreturn void unbound_error(value_t sym);
+extern value_t ArgError, IOError, KeyError, MemoryError, EnumerationError;
+#define argcount(nargs, c) \
+ do{ \
+ if(__unlikely(nargs != c)) \
+ lerrorf(ArgError, "arity mismatch: wanted %d, got %d", c, nargs); \
+ }while(0)
+
+typedef struct {
+ void (*print)(value_t self, ios_t *f);
+ void (*relocate)(value_t oldv, value_t newv);
+ void (*finalize)(value_t self);
+ void (*print_traverse)(value_t self);
+} cvtable_t;
+
+value_t relocate_lispvalue(value_t v);
+void print_traverse(value_t v);
+void fl_print_chr(char c, ios_t *f);
+void fl_print_str(char *s, ios_t *f);
+void fl_print_child(ios_t *f, value_t v);
+
+typedef int (*cvinitfunc_t)(struct _fltype_t*, value_t, void*);
+
+typedef struct _fltype_t {
+ value_t type;
+ cvtable_t *vtable;
+ struct _fltype_t *eltype; // for arrays
+ struct _fltype_t *artype; // (array this)
+ cvinitfunc_t init;
+ size_t size;
+ size_t elsz;
+ int marked;
+ numerictype_t numtype;
+}fltype_t;
+
+typedef struct {
+ fltype_t *type;
+ void *data;
+ size_t len; // length of *data in bytes
+ union {
+ value_t parent; // optional
+ char _space[1]; // variable size
+ };
+}cvalue_t;
+
+#define CVALUE_NWORDS 4
+
+typedef struct {
+ fltype_t *type;
+ char _space[1];
+}cprim_t;
+
+typedef struct {
+ value_t bcode;
+ value_t vals;
+ value_t env;
+ value_t name;
+}function_t;
+
+#define CPRIM_NWORDS 2
+#define MAX_INL_SIZE 384
+
+#define CV_OWNED_BIT 0x1
+#define CV_PARENT_BIT 0x2
+#define owned(cv) ((uintptr_t)(cv)->type & CV_OWNED_BIT)
+#define hasparent(cv) ((uintptr_t)(cv)->type & CV_PARENT_BIT)
+#define isinlined(cv) ((cv)->data == &(cv)->_space[0])
+#define cv_class(cv) ((fltype_t*)(((uintptr_t)((cvalue_t*)cv)->type)&~3))
+#define cv_len(cv) (((cvalue_t*)(cv))->len)
+#define cv_type(cv) (cv_class(cv)->type)
+#define cv_data(cv) (((cvalue_t*)(cv))->data)
+#define cv_isstr(cv) (cv_class(cv)->eltype == bytetype)
+#define cv_isPOD(cv) (cv_class(cv)->init != nil)
+
+#define cvalue_data(v) cv_data((cvalue_t*)ptr(v))
+#define cvalue_len(v) cv_len((cvalue_t*)ptr(v))
+#define value2c(type, v) ((type)cv_data((cvalue_t*)ptr(v)))
+
+#define cp_class(cp) (((cprim_t*)(cp))->type)
+#define cp_type(cp) (cp_class(cp)->type)
+#define cp_numtype(cp) (cp_class(cp)->numtype)
+#define cp_data(cp) (&((cprim_t*)(cp))->_space[0])
+
+// WARNING: multiple evaluation!
+#define cptr(v) (iscprim(v) ? cp_data(ptr(v)) : cv_data(ptr(v)))
+
+#define BUILTIN(lname, cname) \
+ value_t fn_builtin_##cname(value_t *args, int nargs)
+
+typedef value_t (*builtin_t)(value_t*, int);
+
+extern value_t QUOTE;
+extern value_t int8sym, uint8sym, int16sym, uint16sym, int32sym, uint32sym;
+extern value_t int64sym, uint64sym;
+extern value_t longsym, ulongsym, bytesym, wcharsym;
+extern value_t structsym, arraysym, enumsym, cfunctionsym, voidsym, pointersym;
+extern value_t stringtypesym, wcstringtypesym, emptystringsym;
+extern value_t unionsym, floatsym, doublesym;
+extern fltype_t *bytetype, *wchartype;
+extern fltype_t *stringtype, *wcstringtype;
+extern fltype_t *builtintype;
+
+value_t cvalue(fltype_t *type, size_t sz);
+void add_finalizer(cvalue_t *cv);
+void cv_autorelease(cvalue_t *cv);
+void cv_pin(cvalue_t *cv);
+size_t ctype_sizeof(value_t type, int *palign);
+value_t cvalue_copy(value_t v);
+value_t cvalue_from_data(fltype_t *type, void *data, size_t sz);
+value_t cvalue_from_ref(fltype_t *type, void *ptr, size_t sz, value_t parent);
+value_t cbuiltin(char *name, builtin_t f);
+size_t cvalue_arraylen(value_t v);
+value_t size_wrap(size_t sz);
+size_t toulong(value_t n);
+off_t tooffset(value_t n);
+value_t cvalue_string(size_t sz);
+value_t cvalue_static_cstring(const char *str);
+value_t string_from_cstr(char *str);
+value_t string_from_cstrn(char *str, size_t n);
+int fl_isstring(value_t v);
+int fl_isnumber(value_t v);
+int fl_isiostream(value_t v);
+ios_t *fl_toiostream(value_t v);
+value_t cvalue_compare(value_t a, value_t b);
+int numeric_compare(value_t a, value_t b, int eq, int eqnans, int typeerr);
+
+void to_sized_ptr(value_t v, char **pdata, size_t *psz);
+
+fltype_t *get_type(value_t t);
+fltype_t *get_array_type(value_t eltype);
+fltype_t *define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab, cvinitfunc_t init);
+
+value_t mk_double(double n);
+value_t mk_float(float n);
+value_t mk_int32(int32_t n);
+value_t mk_uint32(uint32_t n);
+value_t mk_int64(int64_t n);
+value_t mk_uint64(uint64_t n);
+value_t mk_wchar(int32_t n);
+value_t return_from_uint64(uint64_t Uaccum);
+value_t return_from_int64(int64_t Saccum);
+
+double conv_to_double(void *data, numerictype_t tag);
+void conv_from_double(void *data, double d, numerictype_t tag);
+mpint *conv_to_mpint(void *data, numerictype_t tag);
+int64_t conv_to_int64(void *data, numerictype_t tag);
+uint64_t conv_to_uint64(void *data, numerictype_t tag);
+int32_t conv_to_int32(void *data, numerictype_t tag);
+uint32_t conv_to_uint32(void *data, numerictype_t tag);
+#if defined(ULONG64)
+#define conv_to_long conv_to_int64
+#define conv_to_ulong conv_to_uint64
+#else
+#define conv_to_long conv_to_int32
+#define conv_to_ulong conv_to_uint32
+#endif
+
+typedef struct {
+ char *name;
+ builtin_t fptr;
+}builtinspec_t;
+
+void fl_init(size_t initial_heapsize);
+int fl_load_system_image(value_t ios);
+
+#endif
--- a/print.c
+++ b/print.c
@@ -1,6 +1,10 @@
+//#include "llt.h"
+//#include "flisp.h"
+//#include "opcodes.h"
+
#include "ieee754.h"
-static htable_t printconses;
+htable_t printconses;
static uint32_t printlabel;
static int print_pretty;
static int print_princ;
@@ -7,7 +11,7 @@
static fixnum_t print_length;
static fixnum_t print_level;
static fixnum_t P_LEVEL;
-static int SCR_WIDTH = 80;
+int SCR_WIDTH = 80;
static int HPOS = 0, VPOS;
static void
--- a/read.c
+++ b/read.c
@@ -1,3 +1,6 @@
+//#include "llt.h"
+//#include "flisp.h"
+
enum {
TOK_NONE, TOK_OPEN, TOK_CLOSE, TOK_DOT, TOK_QUOTE, TOK_SYM, TOK_NUM,
TOK_BQ, TOK_COMMA, TOK_COMMAAT, TOK_COMMADOT,
@@ -83,12 +86,13 @@
// exceptions are '.', which is an ordinary symbol character
// unless it's the only character in the symbol, and '#', which is
// an ordinary symbol character unless it's the first character.
-static inline int
-symchar(char c)
-{
- static char *special = "()[]'\";`,\\| \a\b\f\n\r\t\v";
- return !strchr(special, c);
-}
+//inline int
+//symchar(char c)
+//{
+// //static char *special = "()[]'\";`,\\| \a\b\f\n\r\t\v";
+// char *special = "()[]'\";`,\\| \a\b\f\n\r\t\v";
+// return !strchr(special, c);
+//}
int
isnumtok_base(char *tok, value_t *pval, int base)
@@ -150,7 +154,7 @@
return *end == '\0';
}
-static int
+int
isnumtok(char *tok, value_t *pval)
{
return isnumtok_base(tok, pval, 0);
--- a/types.c
+++ b/types.c
@@ -1,3 +1,6 @@
+//#include "llt.h"
+//#include "flisp.h"
+
#include "equalhash.h"
fltype_t *