ref: 25812731cc2b3aa707b4c50d7e094f03490ded1c
parent: 5ab7a7c1e10e681ec792ffb7467f7250f374e88c
author: JeffBezanson <jeff.bezanson@gmail.com>
date: Mon Apr 20 20:56:05 EDT 2009
eliminating interpreter. the bytecode VM is now fully bootstrapped. making the empty vector a singleton removing syntax environment stuff from core reimplementing eval using the compiler fixing a couple bugs in long argument lists
--- a/femtolisp/builtins.c
+++ b/femtolisp/builtins.c
@@ -147,46 +147,10 @@
return args[1];
}
-extern value_t LAMBDA;
-
-static value_t fl_setsyntax(value_t *args, u_int32_t nargs)
-{
- argcount("set-syntax!", nargs, 2);
- symbol_t *sym = tosymbol(args[0], "set-syntax!");
- if (sym->syntax && (sym->syntax == TAG_CONST || isspecial(sym->syntax)))
- lerrorf(ArgError, "set-syntax!: cannot define syntax for %s",
- symbol_name(args[0]));
- if (args[1] == FL_F) {
- sym->syntax = 0;
- }
- else {
- if (!iscvalue(args[1]) &&
- (!iscons(args[1]) || car_(args[1])!=LAMBDA))
- type_error("set-syntax!", "function", args[1]);
- sym->syntax = args[1];
- }
- return args[1];
-}
-
-static value_t fl_symbolsyntax(value_t *args, u_int32_t nargs)
-{
- argcount("symbol-syntax", nargs, 1);
- symbol_t *sym = tosymbol(args[0], "symbol-syntax");
- // must avoid returning built-in syntax expanders, because they
- // don't behave like functions (they take their arguments directly
- // from the form rather than from the stack of evaluated arguments)
- if (sym->syntax == TAG_CONST || isspecial(sym->syntax))
- return FL_F;
- return sym->syntax;
-}
-
static void global_env_list(symbol_t *root, value_t *pv)
{
while (root != NULL) {
- if (root->name[0] != ':' &&
- (root->binding != UNBOUND ||
- (root->syntax && root->syntax != TAG_CONST &&
- !isspecial(root->syntax)))) {
+ if (root->name[0] != ':' && (root->binding != UNBOUND)) {
*pv = fl_cons(tagptr(root,TAG_SYM), *pv);
}
global_env_list(root->left, pv);
@@ -429,8 +393,6 @@
extern void iostream_init();
static builtinspec_t builtin_info[] = {
- { "set-syntax!", fl_setsyntax },
- { "symbol-syntax", fl_symbolsyntax },
{ "environment", fl_global_env },
{ "constant?", fl_constantp },
{ "top-level-value", fl_top_level_value },
--- a/femtolisp/compiler.lsp
+++ b/femtolisp/compiler.lsp
@@ -1,13 +1,13 @@
; -*- scheme -*-
-(define (make-enum-table keys)
+(define (make-enum-table offset keys)
(let ((e (table)))
(for 0 (1- (length keys))
(lambda (i)
- (put! e (aref keys i) i)))))
+ (put! e (aref keys i) (+ offset i))))))
(define Instructions
- (make-enum-table
+ (make-enum-table 0
[:nop :dup :pop :call :tcall :jmp :brf :brt :jmp.l :brf.l :brt.l :ret
:tapply
@@ -15,7 +15,7 @@
:number? :bound? :pair? :builtin? :vector? :fixnum?
:cons :list :car :cdr :set-car! :set-cdr!
- :eval :apply
+ :apply
:+ :- :* :/ := :< :compare
@@ -37,10 +37,10 @@
:vector? 1 :fixnum? 1
:cons 2 :car 1
:cdr 1 :set-car! 2
- :set-cdr! 2 :eval 1
- :apply 2 :< 2
- :compare 2 :aref 2
- :aset! 3 := 2))
+ :set-cdr! 2 :apply 2
+ :< 2 :compare 2
+ :aref 2 :aset! 3
+ := 2))
(define 1/Instructions (table.invert Instructions))
@@ -372,7 +372,9 @@
(:/ (if (= nargs 0)
(argc-error head 1)
(emit g b nargs)))
- (:vector (emit g b nargs))
+ (:vector (if (= nargs 0)
+ (emit g :loadv [])
+ (emit g b nargs)))
(else
(emit g (if (and tail? (eq? b :apply)) :tapply b)))))
(emit g (if tail? :tcall :call) nargs)))))))
--- a/femtolisp/cvalues.c
+++ b/femtolisp/cvalues.c
@@ -465,7 +465,7 @@
cnt = nargs - 1;
if (nargs > MAX_ARGS)
- cnt += llength(args[MAX_ARGS]);
+ cnt += (llength(args[MAX_ARGS])-1);
fltype_t *type = get_array_type(args[0]);
elsize = type->elsz;
sz = elsize * cnt;
--- /dev/null
+++ b/femtolisp/flisp.boot
@@ -1,0 +1,478 @@
+zero?
+#function(">\x015\x00/&\x0b" [])
+vector.map
+#function(">\x022\x004\x015\x01\x03\x01@\x04\x02\x0b" [#function("A\x022\x004\x015\x00\x03\x01@\x04\x02\x0b" [#function("A\x02/6\x00\x000#\x022\x00<B\x025\x00\x0b" [#function(">\x016\x00\x005\x006\x02\x006\x02\x015\x00*\x03\x01+\x0b" [])])
+ vector.alloc]) length])
+vector->list
+#function(">\x012\x004\x015\x00\x03\x01.@\x04\x03\x0b" [#function("A\x0305\x002\x00<B\x025\x01\x0b" [#function(">\x016\x01\x006\x00\x005\x00#\x02*6\x00\x01\x1b:\x00\x01\x0b" [])]) length])
+untrace
+#function(">\x012\x004\x015\x00\x03\x01@\x04\x02\x0b" [#function("A\x025\x00\x1d2\x00\x0d\x06%\x004\x016\x00\x004\x024\x034\x044\x055\x00\x03\x01\x03\x01\x03\x01\x03\x01\x04\x02\x0b-\x0b" [trace-lambda set-top-level-value!
+ cadr caar last-pair caddr])
+ top-level-value])
+trace
+#function(">\x012\x004\x015\x00\x03\x01@\x03\x02\x022\x02\x0b" [#function("A\x022\x004\x015\x00\x03\x01@\x04\x02\x0b" [#function("A\x022\x004\x015\x00\x03\x01@\x04\x02\x0b" [#function("A\x026\x01\x00\x1d2\x00\x0d\x11\x06c\x004\x016\x02\x002\x006\x00\x004\x022\x03\x1c\x012\x042\x05\x1c\x02\x1c\x012\x062\x076\x02\x00\x1c\x02\x1c\x02\x1c\x014\x084\x092\x0a<5\x00\x03\x02\x03\x012\x042\x0b\x1c\x02\x1c\x014\x022\x076\x01\x00\x1c\x02\x1c\x014\x085\x00\x03\x01\x03\x02\x1c\x01\x03\x06\x1c\x03\x04\x02\x0b-\x0b" [trace-lambda
+ set-top-level-value! nconc begin princ "(" print quote copy-list map #function(">\x012\x002\x012\x02\x1c\x022\x035\x00\x1c\x02\x1c\x03\x0b" [begin
+ princ " " print]) ")\n"]) to-proper]) cadr]) top-level-value ok])
+transpose
+#function(">\x014\x004\x015\x00\x1b\x0c\x0b" [mapcar list])
+to-proper
+#function(">\x015\x00\x12\x06\x0b\x005\x00\x0b5\x00\x10\x06\x16\x005\x00\x1c\x01\x0b5\x00\x1d4\x005\x00\x1e\x03\x01\x1b\x0b" [to-proper])
+table.values
+#function(">\x014\x002\x01<.5\x00\x04\x03\x0b" [table.foldl #function(">\x035\x015\x02\x1b\x0b" [])])
+table.foreach
+#function(">\x024\x002\x01<.5\x01\x04\x03\x0b" [table.foldl #function(">\x036\x00\x005\x005\x01\x03\x02\x02,\x0b" [])])
+table.invert
+#function(">\x012\x004\x01\x03\x00@\x04\x02\x0b" [#function("A\x024\x002\x01<.6\x00\x00\x03\x03\x025\x00\x0b" [table.foldl #function(">\x034\x006\x00\x005\x015\x00\x04\x03\x0b" [put!])])
+ table])
+table.keys
+#function(">\x014\x002\x01<.5\x00\x04\x03\x0b" [table.foldl #function(">\x035\x005\x02\x1b\x0b" [])])
+table.pairs
+#function(">\x014\x002\x01<.5\x00\x04\x03\x0b" [table.foldl #function(">\x035\x005\x01\x1b5\x02\x1b\x0b" [])])
+table.clone
+#function(">\x012\x004\x01\x03\x00@\x04\x02\x0b" [#function("A\x024\x002\x01<.6\x00\x00\x03\x03\x025\x00\x0b" [table.foldl #function(">\x034\x006\x00\x005\x005\x01\x04\x03\x0b" [put!])])
+ table])
+symbol-syntax
+#function(">\x014\x004\x015\x00-\x04\x03\x0b" [get *syntax-environment*])
+string.trim
+#function(">\x032\x00--@\x04\x03\x0b" [#function("A\x032\x00<9\x00\x022\x01<9\x01\x022\x024\x036\x00\x00\x03\x01@\x04\x02\x0b" [#function(">\x045\x025\x03'\x01\x06\x1a\x00\x024\x005\x014\x015\x005\x02\x03\x02\x03\x02\x061\x006\x00\x005\x005\x014\x025\x005\x02\x03\x025\x03\x04\x04\x0b5\x02\x0b" [string.find
+ string.char string.inc]) #function(">\x034\x005\x02/\x03\x02\x01\x06\"\x00\x024\x015\x014\x025\x004\x035\x005\x02\x03\x02\x03\x02\x03\x02\x067\x006\x00\x015\x005\x014\x035\x005\x02\x03\x02\x04\x03\x0b5\x02\x0b" [> string.find
+ string.char
+ string.dec])
+ #function("A\x024\x006\x01\x006\x00\x006\x01\x006\x01\x01/5\x00\x03\x046\x00\x016\x01\x006\x01\x025\x00\x03\x03\x04\x03\x0b" [string.sub])
+ length])])
+string.tail
+#function(">\x024\x005\x004\x015\x00/5\x01\x03\x034\x025\x00\x03\x01\x04\x03\x0b" [string.sub string.inc sizeof])
+string.rep
+#function(">\x025\x011\x04'\x06A\x004\x005\x01/\x03\x02\x06\x17\x002\x01\x0b5\x010&\x06%\x004\x025\x00\x04\x01\x0b5\x011\x02&\x066\x004\x025\x005\x00\x04\x02\x0b4\x025\x005\x005\x00\x04\x03\x0b4\x035\x01\x03\x01\x06\\\x004\x025\x004\x045\x005\x010#\x02\x03\x02\x04\x02\x0b4\x044\x025\x005\x00\x03\x025\x011\x02%\x02\x04\x02\x0b" [<= "" string odd?
+ string.rep])
+string.join
+#function(">\x025\x00\x12\x06\x0b\x002\x00\x0b2\x014\x02\x03\x00@\x04\x02\x0b" ["" #function("A\x024\x005\x006\x00\x00\x1d\x03\x02\x024\x012\x02<6\x00\x00\x1e\x03\x02\x024\x035\x00\x04\x01\x0b" [io.write for-each #function(">\x014\x006\x00\x006\x01\x01\x03\x02\x024\x006\x00\x005\x00\x04\x02\x0b" [io.write])
+ io.tostring!]) buffer])
+string.map
+#function(">\x022\x004\x01\x03\x004\x025\x01\x03\x01@\x04\x03\x0b" [#function("A\x032\x00/@\x03\x02\x024\x015\x00\x04\x01\x0b" [#function("A\x02-5\x006\x00\x01'\x061\x00\x024\x006\x00\x006\x01\x004\x016\x01\x015\x00\x03\x02\x03\x01\x03\x02\x024\x026\x01\x015\x00\x03\x029\x00\x05\x03\x00\x0b" [io.putc
+ string.char string.inc]) io.tostring!]) buffer length])
+splice-form?
+#function(">\x015\x00\x17\x01\x06\x1b\x00\x025\x00\x1d2\x00\x0d\x01\x07\x1b\x00\x025\x00\x1d2\x01\x0d\x01\x07%\x00\x025\x002\x02\x0d\x0b" [*comma-at* *comma-dot* *comma*])
+set-syntax!
+#function(">\x024\x004\x015\x005\x01\x04\x03\x0b" [put! *syntax-environment*])
+self-evaluating?
+#function(">\x015\x00\x10\x01\x06\x0e\x00\x025\x00\x14\x11\x01\x07/\x00\x024\x005\x00\x03\x01\x01\x06/\x00\x025\x00\x14\x01\x06/\x00\x025\x004\x015\x00\x03\x01\x0d\x0b" [constant? top-level-value])
+repl
+#function(">\x002\x00--@\x04\x03\x0b" [#function("A\x032\x00<9\x00\x022\x01<9\x01\x025\x01\x03\x00\x024\x02\x04\x00\x0b" [#function(">\x004\x002\x01\x03\x01\x024\x024\x03\x03\x01\x022\x042\x05<2\x06<=@\x04\x02\x0b" [princ "> "
+ io.flush
+ *output-stream*
+ #function("A\x024\x004\x01\x03\x01\x11\x01\x06\x19\x00\x022\x024\x035\x00\x03\x01@\x04\x02\x0b" [io.eof?
+ *input-stream* #function("A\x024\x005\x00\x03\x01\x025\x008\x01\x02,\x0b" [print that]) load-process])
+ #function(">\x004\x00\x04\x00\x0b" [read])
+ #function(">\x014\x004\x01\x03\x01\x024\x025\x00\x04\x01\x0b" [io.discardbuffer
+ *input-stream* raise])]) #function(">\x002\x00<2\x01<=\x06\x17\x004\x02\x03\x00\x026\x00\x01\x04\x00\x0b-\x0b" [#function(">\x006\x00\x00\x03\x00\x01\x06\x10\x00\x024\x00\x04\x00\x0b" [newline])
+ #function(">\x014\x005\x00\x04\x01\x0b" [print-exception])
+ newline]) newline])])
+revappend
+#function(">\x024\x004\x015\x00\x03\x015\x01\x04\x02\x0b" [nconc reverse])
+reverse
+#function(">\x014\x004\x01.5\x00\x04\x03\x0b" [foldl cons])
+separate
+#function(">\x026\x00\x005\x005\x01..\x04\x04\x0b" [] #0=[#function(">\x045\x01\x12\x06\x0e\x005\x025\x03\x1b\x0b5\x005\x01\x1d\x03\x01\x06+\x006\x00\x005\x005\x01\x1e5\x01\x1d5\x02\x1b5\x03\x04\x04\x0b,\x06B\x006\x00\x005\x005\x01\x1e5\x025\x01\x1d5\x03\x1b\x04\x04\x0b-\x0b" [] #0#) ()])
+ref-uint16-LE
+#function(">\x024\x005\x005\x01/\"\x02*/\x03\x024\x005\x005\x010\"\x02*1\x08\x03\x02\"\x02\x0b" [ash])
+ref-uint32-LE
+#function(">\x024\x005\x005\x01/\"\x02*/\x03\x024\x005\x005\x010\"\x02*1\x08\x03\x024\x005\x005\x011\x02\"\x02*1\x10\x03\x024\x005\x005\x011\x03\"\x02*1\x18\x03\x02\"\x04\x0b" [ash])
+remainder
+#function(">\x025\x005\x005\x01%\x025\x01$\x02#\x02\x0b" [])
+quote-value
+#function(">\x014\x005\x00\x03\x01\x06\x0e\x005\x00\x0b2\x015\x00\x1c\x02\x0b" [self-evaluating? quote])
+print-exception
+#function(">\x015\x00\x17\x01\x06\x1d\x00\x025\x00\x1d2\x00\x0d\x01\x06\x1d\x00\x024\x015\x001\x04\x03\x02\x06H\x004\x024\x032\x044\x055\x00\x03\x012\x064\x075\x00\x03\x012\x08\x03\x06\x024\x094\x034\x0a5\x00\x03\x01\x03\x02\x05\x09\x015\x00\x17\x01\x06_\x00\x025\x00\x1d2\x0b\x0d\x01\x06_\x00\x025\x00\x1e\x17\x06u\x004\x024\x032\x0c4\x055\x00\x03\x012\x0d\x03\x04\x05\x09\x015\x00\x17\x01\x06\x83\x00\x025\x00\x1d2\x0e\x0d\x06\x9b\x004\x024\x032\x0f\x03\x02\x024\x024\x035\x00\x1e\x1b!\x05\x09\x015\x00\x17\x01\x06\xa9\x00\x025\x00\x1d2\x10\x0d\x06\xc8\x004\x114\x075\x00\x03\x01\x03\x01\x024\x024\x032\x124\x055\x00\x03\x01\x03\x03\x05\x09\x014\x135\x00\x03\x01\x01\x06\xdb\x00\x024\x015\x001\x02\x03\x02\x06\xf8\x004\x024\x035\x00\x1d2\x14\x03\x03\x022\x154\x055\x00\x03\x01@\x03\x02\x05\x09\x014\x024\x032\x16\x03\x02\x024\x094\x035\x00\x03\x02\x024\x024\x034\x17\x03\x02\x02,\x0b" [type-error
+ length= io.princ *stderr* "type-error: " cadr ": expected " caddr ", got "
+ io.print cadddr unbound-error "unbound-error: eval: variable " " has no value"
+ error "error: " load-error print-exception "in file " list? ": " #function("A\x024\x005\x00\x03\x01\x01\x07\x10\x00\x025\x00\x14\x06\x18\x004\x01\x05\x1a\x004\x024\x035\x00\x04\x02\x0b" [string?
+ io.princ io.print *stderr*]) "*** Unhandled exception: " *linefeed*])
+print-to-string
+#function(">\x012\x004\x01\x03\x00@\x04\x02\x0b" [#function("A\x024\x005\x006\x00\x00\x03\x02\x024\x015\x00\x04\x01\x0b" [io.print io.tostring!]) buffer])
+println
+#function("?\x004\x005\x00!4\x01\x03\x00\x02\x0b" [print newline])
+#function("?\x004\x004\x015\x00\x1b\x0c\x0b" [io.print *output-stream*])
+princ
+#function("?\x004\x004\x015\x00\x1b\x0c\x0b" [io.princ *output-stream*])
+procedure?
+#function(">\x015\x00\x18\x01\x07&\x00\x024\x005\x00\x03\x012\x01\x0d\x01\x07&\x00\x025\x00\x17\x01\x06&\x00\x025\x00\x1d2\x02\x0d\x0b" [typeof function lambda])
+positive?
+#function(">\x014\x005\x00/\x04\x02\x0b" [>])
+peephole
+#function(">\x015\x00\x0b" [])
+pad-r
+#function(">\x034\x005\x004\x015\x025\x014\x025\x00\x03\x01#\x02\x03\x02\x04\x02\x0b" [string string.rep length])
+pad-l
+#function(">\x034\x004\x015\x025\x014\x025\x00\x03\x01#\x02\x03\x025\x00\x04\x02\x0b" [string string.rep length])
+odd?
+#function(">\x014\x005\x00\x03\x01\x11\x0b" [even?])
+nreconc
+#function(">\x024\x004\x015\x00\x03\x015\x01\x04\x02\x0b" [nconc nreverse])
+nreverse
+#function(">\x012\x00.@\x04\x02\x0b" [#function("A\x02-6\x00\x00\x17\x06\"\x00\x026\x00\x00\x1e6\x00\x005\x006\x00\x009\x00\x02 \x02:\x00\x00\x05\x03\x00\x025\x00\x0b" [])])
+newline
+#function(">\x004\x004\x01\x03\x01\x02,\x0b" [princ *linefeed*])
+nestlist
+#function(">\x034\x005\x02/\x03\x02\x06\x0e\x00.\x0b5\x014\x015\x005\x005\x01\x03\x015\x020#\x02\x03\x03\x1b\x0b" [<= nestlist])
+nlist*
+#function("?\x005\x00\x1e\x10\x06\x0d\x005\x00\x1d\x0b5\x004\x005\x00\x1e! \x0b" [nlist*])
+negative?
+#function(">\x015\x00/'\x0b" [])
+mod
+#function(">\x025\x005\x005\x01%\x025\x01$\x02#\x02\x0b" [])
+memv
+#function(">\x025\x01\x10\x06\x0a\x00-\x0b5\x01\x1d5\x00\x0e\x06\x16\x005\x01\x0b,\x06$\x004\x005\x005\x01\x1e\x04\x02\x0b-\x0b" [memv])
+mark-label
+#function(">\x024\x005\x004\x015\x01\x04\x03\x0b" [emit :label])
+map-int
+#function(">\x024\x005\x01/\x03\x02\x06\x0e\x00.\x0b2\x015\x00/\x03\x01.\x1b.@\x04\x03\x0b" [<= #function("A\x035\x009\x01\x0206\x00\x010#\x022\x00<B\x025\x00\x0b" [#function(">\x016\x00\x016\x01\x005\x00\x03\x01.\x1b \x026\x00\x01\x1e:\x00\x01\x0b" [])])])
+mapcar
+#function("?\x016\x00\x005\x005\x01\x04\x02\x0b" [] #0=[#function(">\x025\x01\x12\x06\x0d\x005\x00\x04\x00\x0b5\x01\x1d\x10\x06\x18\x005\x01\x1d\x0b,\x068\x005\x004\x004\x015\x01\x03\x02!6\x00\x005\x004\x004\x025\x01\x03\x02\x03\x02\x1b\x0b-\x0b" [map car cdr] #0#) ()])
+map!
+#function(">\x025\x01-5\x01\x17\x06\x1f\x00\x025\x015\x005\x01\x1d\x03\x01\x1f\x025\x01\x1e9\x01\x05\x05\x00\x02\x0b" [])
+member
+#function(">\x025\x01\x10\x06\x0a\x00-\x0b5\x01\x1d5\x00\x0f\x06\x16\x005\x01\x0b,\x06$\x004\x005\x005\x01\x1e\x04\x02\x0b-\x0b" [member])
+make-label
+#function(">\x014\x00\x04\x00\x0b" [gensym])
+make-code-emitter
+#function(">\x00.4\x00\x03\x00/)\x03\x0b" [table])
+make-enum-table
+#function(">\x022\x004\x01\x03\x00@\x04\x02\x0b" [#function("A\x02/4\x004\x016\x00\x01\x03\x01\x03\x012\x02<B\x0b" [1- length #function(">\x014\x006\x00\x006\x01\x015\x00*6\x01\x005\x00\"\x02\x04\x03\x0b" [put!])])
+ table])
+make-system-image
+#function(">\x012\x004\x015\x004\x024\x034\x04\x03\x04@\x04\x02\x0b" [#function("A\x024\x002\x01<4\x02\x03\x00\x03\x02\x024\x035\x00\x04\x01\x0b" [for-each #function(">\x015\x00\x16\x01\x06.\x00\x024\x005\x00\x03\x01\x11\x01\x06.\x00\x024\x015\x00\x03\x01\x18\x11\x01\x06.\x00\x024\x024\x015\x00\x03\x01\x03\x01\x11\x06]\x004\x036\x00\x005\x00\x03\x02\x024\x046\x00\x002\x05\x03\x02\x024\x036\x00\x004\x015\x00\x03\x01\x03\x02\x024\x046\x00\x002\x05\x04\x02\x0b-\x0b" [constant?
+ top-level-value iostream? io.print io.write "\n"]) environment io.close])
+ file :write :create :truncate])
+macroexpand-in
+#function(">\x025\x00\x10\x06\x0b\x005\x00\x0b2\x004\x015\x00\x1d5\x01\x03\x02@\x04\x02\x0b" [#function("A\x025\x00\x06\x1d\x004\x004\x015\x00\x03\x016\x00\x00\x1e!4\x025\x00\x03\x01\x04\x02\x0b2\x034\x046\x00\x00\x03\x01@\x04\x02\x0b" [macroexpand-in cadr caddr #function("A\x025\x00\x06\x16\x004\x005\x006\x01\x00\x1e!6\x01\x01\x04\x02\x0b6\x01\x00\x1d2\x01\x0d\x06$\x006\x01\x00\x0b6\x01\x00\x1d2\x02\x0d\x06Q\x004\x032\x024\x046\x01\x00\x03\x014\x004\x056\x01\x00\x03\x016\x01\x01\x03\x024\x066\x01\x00\x03\x01\x04\x04\x0b6\x01\x00\x1d2\x07\x0d\x06s\x002\x084\x046\x01\x00\x03\x014\x094\x0a6\x01\x00\x03\x01\x03\x01@\x04\x03\x0b4\x0b2\x0c<6\x01\x00\x04\x02\x0b" [macroexpand-in
+ quote lambda nlist* cadr caddr cdddr let-syntax #function("A\x034\x005\x014\x014\x022\x03<5\x00\x03\x026\x02\x01\x03\x02\x04\x02\x0b" [macroexpand-in
+ nconc map #function(">\x015\x00\x1d4\x004\x015\x00\x03\x016\x03\x01\x03\x026\x03\x01\x1c\x03\x0b" [macroexpand-in cadr])]) f-body cddr map #function(">\x014\x005\x006\x02\x01\x04\x02\x0b" [macroexpand-in])])
+ macrocall?]) assq])
+macroexpand
+#function(">\x014\x005\x00.\x04\x02\x0b" [macroexpand-in])
+macroexpand-1
+#function(">\x015\x00\x10\x06\x0b\x005\x00\x0b2\x004\x015\x00\x03\x01@\x04\x02\x0b" [#function("A\x025\x00\x06\x0f\x005\x006\x00\x00\x1e\x0c\x0b6\x00\x00\x0b" []) macrocall?])
+lookup-sym
+#function(">\x045\x01\x12\x06\x0b\x002\x00\x0b2\x015\x01\x1d@\x04\x02\x0b" [(global) #function("A\x022\x004\x016\x00\x005\x00/\x03\x03@\x04\x02\x0b" [#function("A\x025\x00\x06\x1e\x006\x01\x03\x06\x14\x002\x005\x00\x1c\x02\x0b2\x016\x01\x025\x00\x1c\x03\x0b4\x026\x01\x006\x01\x01\x1e6\x01\x03\x01\x073\x00\x026\x00\x00\x12\x06<\x006\x01\x02\x05B\x006\x01\x020\"\x02-\x04\x04\x0b" [arg
+ closed lookup-sym]) index-of])])
+macrocall?
+#function(">\x015\x00\x1d\x14\x01\x06\x15\x00\x024\x004\x015\x00\x1d-\x04\x03\x0b" [get *syntax-environment*])
+map
+#function(">\x025\x01\x10\x06\x0b\x005\x01\x0b5\x005\x01\x1d\x03\x014\x005\x005\x01\x1e\x03\x02\x1b\x0b" [map])
+load
+#function(">\x012\x004\x015\x004\x02\x03\x02@\x04\x02\x0b" [#function("A\x022\x00<2\x01<=\x0b" [#function(">\x002\x00-@\x03\x02---\x04\x03\x0b" [#function("A\x022\x00<9\x00\x0b" [#function(">\x034\x006\x01\x00\x03\x01\x11\x06\"\x006\x00\x004\x016\x01\x00\x03\x015\x004\x025\x01\x03\x01\x04\x03\x0b4\x036\x01\x00\x03\x01\x024\x025\x01\x04\x01\x0b" [io.eof?
+ read load-process io.close])])]) #function(">\x014\x006\x00\x00\x03\x01\x024\x012\x026\x01\x005\x00\x1c\x03\x04\x01\x0b" [io.close raise
+ load-error])]) file
+ :read])
+load-process
+#function(">\x014\x005\x00\x04\x01\x0b" [eval])
+list-partition
+#function(">\x024\x005\x01/\x03\x02\x06\x13\x004\x012\x02\x04\x01\x0b4\x034\x045\x005\x01/..\x03\x05\x04\x01\x0b" [<= error "list-partition: invalid count" nreverse
+ list-part-])
+list-part-
+#function(">\x055\x00\x10\x06\x1f\x004\x005\x02/\x03\x02\x06\x1c\x004\x015\x03\x03\x015\x04\x1b\x0b5\x04\x0b4\x025\x025\x01\x03\x02\x06>\x004\x035\x005\x01/.4\x015\x03\x03\x015\x04\x1b\x04\x05\x0b4\x035\x00\x1e5\x0105\x02\"\x025\x00\x1d5\x03\x1b5\x04\x04\x05\x0b" [> nreverse >= list-part-])
+list-ref
+#function(">\x024\x005\x005\x01\x03\x02\x1d\x0b" [list-tail])
+list->vector
+#function(">\x014\x005\x00\x0c\x0b" [vector])
+list*
+#function("?\x005\x00\x1e\x10\x06\x0d\x005\x00\x1d\x0b5\x00\x1d4\x005\x00\x1e!\x1b\x0b" [list*])
+list-head
+#function(">\x024\x005\x01/\x03\x02\x06\x0e\x00.\x0b5\x00\x1d4\x015\x00\x1e5\x010#\x02\x03\x02\x1b\x0b" [<= list-head])
+list-tail
+#function(">\x024\x005\x01/\x03\x02\x06\x0f\x005\x00\x0b4\x015\x00\x1e5\x010#\x02\x04\x02\x0b" [<= list-tail])
+list?
+#function(">\x015\x00\x12\x01\x07\x19\x00\x025\x00\x17\x01\x06\x19\x00\x024\x005\x00\x1e\x04\x01\x0b" [list?])
+listp
+#function(">\x015\x00\x12\x01\x07\x0d\x00\x025\x00\x17\x0b" [])
+length>
+#function(">\x025\x01/'\x06\x0c\x005\x00\x0b5\x01/&\x06\x1e\x005\x00\x17\x01\x06\x1d\x00\x025\x00\x0b5\x00\x12\x06)\x005\x01/'\x0b4\x005\x00\x1e5\x010#\x02\x04\x02\x0b" [length>])
+length=
+#function(">\x025\x01/'\x06\x0b\x00-\x0b5\x01/&\x06\x16\x005\x00\x12\x0b5\x00\x12\x06!\x005\x01/&\x0b4\x005\x00\x1e5\x010#\x02\x04\x02\x0b" [length=])
+last-pair
+#function(">\x015\x00\x10\x06\x0b\x005\x00\x0b5\x00\x1e\x10\x06\x15\x005\x00\x0b,\x06!\x004\x005\x00\x1e\x04\x01\x0b-\x0b" [last-pair])
+lastcdr
+#function(">\x015\x00\x10\x06\x0b\x005\x00\x0b4\x005\x00\x1e\x04\x01\x0b" [lastcdr])
+just-compile-args
+#function(">\x034\x002\x01<5\x01\x04\x02\x0b" [for-each #function(">\x014\x006\x00\x006\x00\x02-5\x00\x04\x04\x0b" [compile-in])])
+iota
+#function(">\x014\x004\x015\x00\x04\x02\x0b" [map-int identity])
+io.readline
+#function(">\x014\x005\x002\x01\x04\x02\x0b" [io.readuntil #\x000a])
+in-env?
+#function(">\x025\x01\x17\x01\x06!\x00\x024\x005\x005\x01\x1d\x03\x02\x01\x07!\x00\x024\x015\x005\x01\x1e\x04\x02\x0b" [memq in-env?])
+index-of
+#function(">\x035\x01\x12\x06\x0a\x00-\x0b5\x005\x01\x1d\x0d\x06\x16\x005\x02\x0b,\x06)\x004\x005\x005\x01\x1e5\x020\"\x02\x04\x03\x0b-\x0b" [index-of])
+hex5
+#function(">\x014\x004\x015\x001\x10\x03\x021\x052\x02\x04\x03\x0b" [pad-l number->string #\0])
+identity
+#function(">\x015\x00\x0b" [])
+get-defined-vars
+#function(">\x014\x006\x00\x005\x00\x03\x01\x04\x01\x0b" [delete-duplicates] #0=[#function(">\x015\x00\x10\x06\x0a\x00.\x0b5\x00\x1d2\x00\x0d\x01\x06\x19\x00\x025\x00\x1e\x17\x06\\\x004\x015\x00\x03\x01\x14\x01\x060\x00\x024\x015\x00\x03\x01\x1c\x01\x01\x07[\x00\x024\x015\x00\x03\x01\x17\x01\x06U\x00\x024\x025\x00\x03\x01\x14\x01\x06U\x00\x024\x025\x00\x03\x01\x1c\x01\x01\x07[\x00\x02.\x0b5\x00\x1d2\x03\x0d\x06s\x004\x044\x056\x00\x005\x00\x1e\x03\x02\x0c\x0b.\x0b" [define
+ cadr caadr begin append map] #0#) ()])
+function?
+#function(">\x015\x00\x18\x01\x07&\x00\x024\x005\x00\x03\x012\x01\x0d\x01\x07&\x00\x025\x00\x17\x01\x06&\x00\x025\x00\x1d2\x02\x0d\x0b" [typeof function lambda])
+for-each
+#function(">\x025\x01\x17\x06\x1a\x005\x005\x01\x1d\x03\x01\x024\x005\x005\x01\x1e\x04\x02\x0b,\x0b" [for-each])
+foldl
+#function(">\x035\x02\x12\x06\x0b\x005\x01\x0b4\x005\x005\x005\x02\x1d5\x01\x03\x025\x02\x1e\x04\x03\x0b" [foldl])
+foldr
+#function(">\x035\x02\x12\x06\x0b\x005\x01\x0b5\x005\x02\x1d4\x005\x005\x015\x02\x1e\x03\x03\x04\x02\x0b" [foldr])
+filter
+#function(">\x026\x00\x005\x005\x01.\x04\x03\x0b" [] #0=[#function(">\x035\x01\x12\x06\x0b\x005\x02\x0b5\x005\x01\x1d\x03\x01\x06&\x006\x00\x005\x005\x01\x1e5\x01\x1d5\x02\x1b\x04\x03\x0b,\x067\x006\x00\x005\x005\x01\x1e5\x02\x04\x03\x0b-\x0b" [] #0#) ()])
+f-body
+#function(">\x012\x006\x00\x005\x00\x03\x01@\x04\x02\x0b" [#function("A\x022\x004\x015\x00\x03\x01@\x04\x02\x0b" [#function("A\x025\x00\x12\x06\x0c\x006\x00\x00\x0b2\x005\x006\x00\x00\x1c\x034\x012\x02<5\x00\x03\x02\x1b\x0b" [lambda map #function(">\x01-\x0b" [])])
+ get-defined-vars])] [#function(">\x015\x00\x10\x06\x0a\x00-\x0b5\x00\x1e.\x0d\x06\x16\x005\x00\x1d\x0b,\x06 \x002\x005\x00\x1b\x0b-\x0b" [begin])
+ ()])
+expand
+#function(">\x014\x005\x00\x04\x01\x0b" [macroexpand])
+every
+#function(">\x025\x01\x10\x01\x07\x1f\x00\x025\x005\x01\x1d\x03\x01\x01\x06\x1f\x00\x024\x005\x005\x01\x1e\x04\x02\x0b" [every])
+even?
+#function(">\x014\x005\x000\x03\x02/&\x0b" [logand])
+eval
+#function(">\x014\x004\x015\x00\x03\x01\x03\x01\x04\x00\x0b" [compile-thunk expand])
+error
+#function("?\x004\x002\x015\x00\x1b\x04\x01\x0b" [raise error])
+emit-nothing
+#function(">\x015\x00\x0b" [])
+encode-byte-code
+#function(">\x012\x004\x014\x025\x00\x03\x01\x03\x01@\x04\x02\x0b" [#function("A\x022\x004\x014\x025\x00\x03\x011\x034\x032\x04<5\x00\x03\x02$\x02\"\x022\x05\x03\x02@\x04\x02\x0b" [#function("A\x022\x004\x016\x00\x00\x03\x01@\x04\x02\x0b" [#function("A\x022\x004\x015\x00\x03\x01/4\x02\x03\x004\x02\x03\x004\x03\x03\x00-@\x04\x07\x0b" [#function("A\x07-5\x015\x00'\x06\x90\x00\x026\x00\x005\x01*9\x05\x025\x054\x00\x0d\x06>\x004\x015\x026\x00\x005\x010\"\x02*4\x025\x04\x03\x01\x03\x03\x025\x011\x02\"\x029\x01\x05\x8d\x004\x035\x044\x044\x054\x066\x01\x00\x01\x06X\x00\x024\x075\x052\x08\x03\x02\x06e\x002\x095\x05@\x03\x02\x05g\x005\x05\x03\x02\x03\x01\x03\x02\x025\x010\"\x029\x01\x025\x015\x00'\x06\x8c\x002\x0a6\x00\x005\x01*@\x03\x02\x05\x8d\x00-\x05\x03\x00\x024\x0b2\x0c<5\x03\x03\x02\x024\x0d5\x04\x04\x01\x0b" [:label
+ put! sizeof io.write byte get Instructions memq (:jmp :brt :brf)
+ #function("A\x025\x004\x00\x0e\x06\x0d\x004\x01\x0b5\x004\x02\x0e\x06\x18\x004\x03\x0b5\x004\x04\x0e\x06#\x004\x05\x0b-\x0b" [:jmp :jmp.l :brt :brt.l :brf :brf.l])
+ #function("A\x022\x006\x00\x05@\x04\x02\x0b" [#function("A\x024\x005\x002\x01\x03\x02\x06&\x004\x026\x01\x044\x036\x00\x00\x03\x01\x03\x02\x026\x01\x010\"\x02:\x01\x01\x0b4\x005\x002\x04\x03\x02\x06J\x004\x026\x01\x044\x056\x00\x00\x03\x01\x03\x02\x026\x01\x010\"\x02:\x01\x01\x0b4\x005\x002\x06\x03\x02\x06\x8b\x004\x026\x01\x044\x056\x00\x00\x03\x01\x03\x02\x026\x01\x010\"\x02:\x01\x01\x024\x026\x01\x044\x056\x02\x006\x01\x01*\x03\x01\x03\x02\x026\x01\x010\"\x02:\x01\x01\x0b4\x005\x002\x07\x03\x02\x06\xca\x004\x086\x01\x034\x096\x01\x04\x03\x016\x00\x00\x03\x03\x024\x026\x01\x046\x03\x00\x06\xb8\x004\x03\x05\xba\x004\x0a/\x03\x01\x03\x02\x026\x01\x010\"\x02:\x01\x01\x0b-\x0b" [memv
+ (:loadv.l :loadg.l :setg.l) io.write uint32 (:loada :seta :call :tcall :loadv
+ :loadg :setg :list :+ :- :* :/
+ :vector :argc :vargc :loadi8
+ :let) uint8 (:loadc :setc)
+ (:jmp :brf :brt) put! sizeof uint16])]) table.foreach #function(">\x024\x006\x00\x045\x00\x03\x02\x024\x016\x00\x046\x02\x00\x06\x1c\x004\x02\x05\x1e\x004\x034\x046\x00\x025\x01\x03\x02\x03\x01\x04\x02\x0b" [io.seek
+ io.write uint32 uint16 get]) io.tostring!]) length table buffer])
+ list->vector])
+ >= length count #function(">\x014\x005\x002\x01\x04\x02\x0b" [memq
+ (:loadv :loadg :setg :jmp :brt :brf)]) 65536]) peephole nreverse])
+emit
+#function("?\x024\x005\x012\x01\x03\x02\x06\x19\x002\x025\x000*@\x03\x02\x05\x1a\x00-\x025\x00/4\x035\x015\x02\x1b5\x00/*\x03\x02+\x025\x00\x0b" [memq (:loadv :loadg :setg)
+ #function("A\x022\x006\x00\x001\x02*@\x04\x02\x0b" [#function("A\x022\x006\x01\x02\x1d@\x04\x02\x0b" [#function("A\x022\x004\x016\x01\x005\x00\x03\x02\x06\x1c\x004\x026\x01\x005\x00\x03\x02\x059\x004\x036\x01\x005\x006\x00\x00\x03\x03\x026\x00\x000\"\x02:\x00\x00\x026\x00\x000#\x02@\x04\x02\x0b" [#function("A\x026\x03\x001\x026\x01\x00+\x025\x00\x1c\x01:\x03\x02\x024\x005\x002\x01\x03\x02\x06+\x002\x026\x03\x01@\x03\x02:\x03\x01\x0b-\x0b" [>=
+ 256 #function("A\x025\x004\x00\x0e\x06\x0d\x004\x01\x0b5\x004\x02\x0e\x06\x18\x004\x03\x0b5\x004\x04\x0e\x06#\x004\x05\x0b-\x0b" [:loadv :loadv.l :loadg :loadg.l :setg :setg.l])])
+ has? get put!])])]) nreconc])
+disassemble
+#function(">\x014\x005\x00/\x03\x02\x024\x01\x04\x00\x0b" [disassemble- newline])
+disassemble-
+#function(">\x022\x004\x015\x00\x03\x01@\x04\x02\x0b" [#function("A\x022\x005\x00/*5\x000*@\x04\x03\x0b" [#function("A\x032\x00-@\x04\x02\x0b" [#function("A\x022\x00<9\x00\x022\x01/4\x026\x00\x00\x03\x01@\x04\x03\x0b" [#function(">\x015\x00\x17\x01\x06\x10\x00\x025\x00\x1d2\x00\x0d\x06'\x004\x012\x02\x03\x01\x024\x035\x006\x03\x010\"\x02\x04\x02\x0b4\x045\x00\x04\x01\x0b" [compiled-lambda
+ princ "\n" disassemble- print]) #function("A\x03-5\x005\x01'\x06 \x00\x022\x004\x014\x026\x01\x005\x00*\x03\x02@\x03\x02\x05\x03\x00\x0b" [#function("A\x024\x006\x00\x00/\x03\x02\x06\x14\x004\x01\x03\x00\x05\x15\x00-\x02/6\x04\x010#\x022\x02<B\x024\x034\x046\x00\x00\x03\x012\x054\x064\x075\x00\x03\x010\x03\x022\x08\x03\x04\x026\x00\x000\"\x02:\x00\x00\x022\x095\x00@\x04\x02\x0b" [>
+ newline #function(">\x014\x002\x01\x04\x01\x0b" [princ "\t"]) princ hex5 ": " string.tail string "\t"
+ #function("A\x024\x005\x002\x01\x03\x02\x06,\x006\x02\x006\x03\x014\x026\x03\x006\x01\x00\x03\x02*\x03\x01\x026\x01\x001\x04\"\x02:\x01\x00\x0b4\x005\x002\x03\x03\x02\x06R\x006\x02\x006\x03\x016\x03\x006\x01\x00**\x03\x01\x026\x01\x000\"\x02:\x01\x00\x0b4\x005\x002\x04\x03\x02\x06w\x004\x054\x066\x03\x006\x01\x00*\x03\x01\x03\x01\x026\x01\x000\"\x02:\x01\x00\x0b4\x005\x002\x07\x03\x02\x06\xb8\x004\x054\x066\x03\x006\x01\x00*\x03\x012\x08\x03\x02\x026\x01\x000\"\x02:\x01\x00\x024\x054\x066\x03\x006\x01\x00*\x03\x01\x03\x01\x026\x01\x000\"\x02:\x01\x00\x0b4\x005\x002\x09\x03\x02\x06\xe3\x004\x052\x0a4\x0b4\x0c6\x03\x006\x01\x00\x03\x02\x03\x01\x03\x02\x026\x01\x001\x02\"\x02:\x01\x00\x0b4\x005\x002\x0d\x03\x02\x06\x0e\x014\x052\x0a4\x0b4\x026\x03\x006\x01\x00\x03\x02\x03\x01\x03\x02\x026\x01\x001\x04\"\x02:\x01\x00\x0b-\x0b" [memv
+ (:loadv.l :loadg.l :setg.l) ref-uint32-LE (:loadv :loadg :setg)
+ (:loada :seta :call :tcall :list :+ :- :* :/ :vector :argc :vargc :loadi8
+ :let) princ number->string (:loadc :setc) " " (:jmp :brf :brt) "@" hex5
+ ref-uint16-LE (:jmp.l :brf.l :brt.l)])]) get 1/Instructions]) length])])])
+ function->vector])
+display
+#function(">\x014\x005\x00\x03\x01\x02,\x0b" [princ])
+delete-duplicates
+#function(">\x015\x00\x10\x06\x0b\x005\x00\x0b2\x005\x00\x1d5\x00\x1e@\x04\x03\x0b" [#function("A\x034\x005\x005\x01\x03\x02\x06\x14\x004\x015\x01\x04\x01\x0b5\x004\x015\x01\x03\x01\x1b\x0b" [member delete-duplicates])])
+count
+#function(">\x024\x005\x005\x01/\x04\x03\x0b" [count-])
+count-
+#function(">\x035\x01\x12\x06\x0b\x005\x02\x0b4\x005\x005\x01\x1e5\x005\x01\x1d\x03\x01\x06$\x005\x020\"\x02\x05&\x005\x02\x04\x03\x0b" [count-])
+copy-tree
+#function(">\x015\x00\x10\x06\x0b\x005\x00\x0b4\x005\x00\x1d\x03\x014\x005\x00\x1e\x03\x01\x1b\x0b" [copy-tree])
+copy-list
+#function(">\x015\x00\x10\x06\x0b\x005\x00\x0b5\x00\x1d4\x005\x00\x1e\x03\x01\x1b\x0b" [copy-list])
+const-to-idx-vec
+#function(">\x012\x005\x000*5\x001\x02*@\x04\x03\x0b" [#function("A\x032\x004\x015\x01\x03\x01@\x04\x02\x0b" [#function("A\x024\x002\x01<6\x00\x00\x03\x02\x025\x00\x0b" [table.foreach #function(">\x026\x00\x005\x015\x00+\x0b" [])])
+ vector.alloc])])
+cond->if
+#function(">\x014\x005\x00\x1e\x04\x01\x0b" [cond-clauses->if])
+cond-clauses->if
+#function(">\x015\x00\x10\x06\x0a\x00-\x0b2\x005\x00\x1d@\x04\x02\x0b" [#function("A\x025\x00\x1d2\x00\x0d\x06\x12\x002\x015\x00\x1e\x1b\x0b2\x025\x00\x1d2\x015\x00\x1e\x1b4\x036\x00\x00\x1e\x03\x01\x1c\x04\x0b" [else begin if cond-clauses->if])])
+compile-while
+#function(">\x042\x004\x015\x00\x03\x014\x015\x00\x03\x01@\x04\x03\x0b" [#function("A\x034\x006\x00\x006\x00\x01--\x03\x04\x024\x016\x00\x005\x00\x03\x02\x024\x006\x00\x006\x00\x01-6\x00\x02\x03\x04\x024\x026\x00\x004\x035\x01\x03\x03\x024\x026\x00\x004\x04\x03\x02\x024\x006\x00\x006\x00\x01-6\x00\x03\x03\x04\x024\x026\x00\x004\x055\x00\x03\x03\x024\x016\x00\x005\x01\x04\x02\x0b" [compile-in
+ mark-label
+ emit :brf
+ :pop :jmp])
+ make-label])
+compile-short-circuit
+#function(">\x065\x03\x10\x06\x15\x004\x005\x005\x015\x025\x04\x04\x04\x0b5\x03\x1e\x10\x06*\x004\x005\x005\x015\x025\x03\x1d\x04\x04\x0b2\x014\x025\x00\x03\x01@\x04\x02\x0b" [compile-in #function("A\x024\x006\x00\x006\x00\x01-6\x00\x03\x1d\x03\x04\x024\x016\x00\x004\x02\x03\x02\x024\x016\x00\x006\x00\x055\x00\x03\x03\x024\x016\x00\x004\x03\x03\x02\x024\x046\x00\x006\x00\x016\x00\x026\x00\x03\x1e6\x00\x046\x00\x05\x03\x06\x024\x056\x00\x005\x00\x04\x02\x0b" [compile-in
+ emit :dup :pop compile-short-circuit mark-label]) make-label])
+compile-let
+#function(">\x042\x005\x03\x1d5\x03\x1e@\x04\x03\x0b" [#function("A\x034\x005\x014\x014\x025\x00\x03\x01\x03\x01\x03\x02\x06\x19\x00-\x05%\x004\x034\x042\x055\x00\x03\x02\x03\x01\x024\x066\x00\x004\x074\x086\x00\x015\x00,\x03\x03\x03\x03\x022\x094\x0a6\x00\x006\x00\x015\x01\x03\x03@\x04\x02\x0b" [length= length cadr
+ error string "apply: incorrect number of arguments to "
+ emit :loadv compile-f
+ #function("A\x024\x006\x01\x004\x01\x03\x02\x024\x006\x01\x006\x01\x02\x06\x1c\x004\x02\x05\x1e\x004\x0305\x00\"\x02\x04\x03\x0b" [emit
+ :close :tcall :call]) compile-arglist])])
+compile-or
+#function(">\x044\x005\x005\x015\x025\x03-4\x01\x04\x06\x0b" [compile-short-circuit :brt])
+compile-prog1
+#function(">\x034\x005\x005\x01-4\x015\x02\x03\x01\x03\x04\x024\x025\x02\x03\x01\x17\x065\x004\x035\x005\x01-4\x025\x02\x03\x01\x03\x04\x024\x045\x004\x05\x04\x02\x0b-\x0b" [compile-in cadr cddr compile-begin emit :pop])
+compile-f
+#function("?\x022\x004\x01\x03\x004\x025\x01\x03\x01@\x04\x03\x0b" [#function("A\x036\x00\x02\x12\x11\x06\x1f\x004\x005\x004\x014\x024\x035\x01\x03\x01\x03\x01\x03\x03\x05R\x004\x045\x01\x03\x01\x12\x06:\x004\x005\x004\x054\x035\x01\x03\x01\x03\x03\x05R\x004\x005\x004\x065\x01\x10\x06J\x00/\x05P\x004\x035\x01\x03\x01\x03\x03\x024\x075\x004\x085\x01\x03\x016\x00\x00\x1b,4\x096\x00\x01\x03\x01\x03\x04\x024\x005\x004\x0a\x03\x02\x024\x0b4\x0c5\x00/*\x03\x014\x0d5\x00\x03\x01\x04\x02\x0b" [emit
+ :let 1+ length lastcdr :argc :vargc compile-in to-proper caddr :ret function
+ encode-byte-code const-to-idx-vec]) make-code-emitter cadr])
+compile-call
+#function(">\x042\x005\x03\x1d@\x04\x02\x0b" [#function("A\x022\x005\x00\x14\x01\x065\x00\x024\x015\x006\x00\x01\x03\x02\x11\x01\x065\x00\x025\x00\x16\x01\x065\x00\x024\x025\x00\x03\x01\x01\x065\x00\x024\x035\x00\x03\x01\x18\x06A\x004\x035\x00\x03\x01\x05C\x005\x00@\x04\x02\x0b" [#function("A\x022\x005\x00\x18\x01\x06\x12\x00\x024\x015\x00\x03\x01@\x04\x02\x0b" [#function("A\x025\x00\x11\x06\x19\x004\x006\x02\x006\x02\x01-6\x00\x00\x03\x04\x05\x1a\x00-\x022\x014\x026\x02\x006\x02\x016\x02\x03\x1e\x03\x03@\x04\x02\x0b" [compile-in
+ #function("A\x026\x00\x00\x06\x18\x002\x004\x014\x026\x00\x00-\x03\x03@\x04\x02\x0b4\x036\x03\x006\x03\x02\x06(\x004\x04\x05*\x004\x055\x00\x04\x03\x0b" [#function("A\x025\x00\x01\x06\x14\x00\x024\x006\x04\x03\x1e5\x00\x03\x02\x11\x06#\x004\x016\x02\x005\x00\x03\x02\x05$\x00-\x022\x026\x01\x00@\x04\x02\x0b" [length= argc-error
+ #function("A\x025\x004\x00\x0e\x06*\x006\x01\x00/&\x06\x1c\x004\x016\x05\x004\x02\x04\x02\x0b4\x016\x05\x006\x02\x006\x01\x00\x04\x03\x0b5\x004\x03\x0e\x06b\x006\x01\x00/&\x06D\x004\x016\x05\x004\x04\x04\x02\x0b6\x01\x000&\x06T\x004\x056\x05\x00\x04\x01\x0b4\x016\x05\x006\x02\x006\x01\x00\x04\x03\x0b5\x004\x06\x0e\x06\x89\x006\x01\x00/&\x06{\x004\x076\x03\x000\x04\x02\x0b4\x016\x05\x006\x02\x006\x01\x00\x04\x03\x0b5\x004\x08\x0e\x06\xc1\x006\x01\x00/&\x06\xa3\x004\x016\x05\x004\x09\x04\x02\x0b6\x01\x000&\x06\xb3\x004\x056\x05\x00\x04\x01\x0b4\x016\x05\x006\x02\x006\x01\x00\x04\x03\x0b5\x004\x0a\x0e\x06\xe8\x006\x01\x00/&\x06\xda\x004\x076\x03\x000\x04\x02\x0b4\x016\x05\x006\x02\x006\x01\x00\x04\x03\x0b5\x004\x0b\x0e\x06\x12\x016\x01\x00/&\x06\x04\x014\x016\x05\x004\x0c2\x0d\x04\x03\x0b4\x016\x05\x006\x02\x006\x01\x00\x04\x03\x0b4\x016\x05\x006\x05\x02\x01\x06%\x01\x026\x02\x004\x0e\x0d\x06-\x014\x0f\x050\x016\x02\x00\x04\x02\x0b" [:list
+ emit :loadnil :+ :load0 emit-nothing :- argc-error :* :load1 :/ :vector
+ :loadv [] :apply :tapply])]) get arg-counts emit :tcall :call])
+ compile-arglist]) builtin->instruction]) in-env? constant? top-level-value])])
+compile-for
+#function(">\x054\x005\x04\x03\x01\x068\x004\x015\x005\x01-5\x02\x03\x04\x024\x015\x005\x01-5\x03\x03\x04\x024\x015\x005\x01-5\x04\x03\x04\x024\x025\x004\x03\x04\x02\x0b4\x042\x05\x04\x01\x0b" [1arg-lambda? compile-in emit :for error
+ "for: third form must be a 1-argument lambda"])
+compile-app
+#function(">\x042\x005\x03\x1d@\x04\x02\x0b" [#function("A\x025\x00\x17\x01\x06\x1f\x00\x025\x00\x1d2\x00\x0d\x01\x06\x1f\x00\x024\x014\x025\x00\x03\x01\x03\x01\x063\x004\x036\x00\x006\x00\x016\x00\x026\x00\x03\x04\x04\x0b4\x046\x00\x006\x00\x016\x00\x026\x00\x03\x04\x04\x0b" [lambda list? cadr compile-let
+ compile-call])])
+compile-arglist
+#function(">\x032\x004\x015\x024\x02\x03\x02@\x04\x02\x0b" [#function("A\x025\x00\x069\x004\x006\x00\x004\x016\x00\x024\x02\x03\x026\x00\x01\x03\x03\x022\x034\x044\x052\x06<4\x075\x004\x02\x03\x02\x03\x02\x1b@\x03\x02\x024\x020\"\x02\x0b4\x006\x00\x006\x00\x026\x00\x01\x03\x03\x024\x086\x00\x02\x04\x01\x0b" [just-compile-args
+ list-head
+ MAX_ARGS #function("A\x024\x006\x01\x006\x01\x01-5\x00\x04\x04\x0b" [compile-in])
+ nconc map #function(">\x014\x005\x00\x1b\x0b" [list])
+ list-partition
+ length]) length>
+ MAX_ARGS])
+compile
+#function(">\x014\x00.5\x00\x04\x02\x0b" [compile-f])
+compile-and
+#function(">\x044\x005\x005\x015\x025\x03,4\x01\x04\x06\x0b" [compile-short-circuit :brf])
+compile-begin
+#function(">\x045\x03\x10\x06\x14\x004\x005\x005\x015\x02-\x04\x04\x0b5\x03\x1e\x10\x06)\x004\x005\x005\x015\x025\x03\x1d\x04\x04\x0b4\x005\x005\x01-5\x03\x1d\x03\x04\x024\x015\x004\x02\x03\x02\x024\x035\x005\x015\x025\x03\x1e\x04\x04\x0b" [compile-in emit :pop compile-begin])
+compile-if
+#function(">\x042\x004\x015\x00\x03\x014\x015\x00\x03\x01@\x04\x03\x0b" [#function("A\x034\x006\x00\x006\x00\x01-4\x016\x00\x03\x03\x01\x03\x04\x024\x026\x00\x004\x035\x00\x03\x03\x024\x006\x00\x006\x00\x016\x00\x024\x046\x00\x03\x03\x01\x03\x04\x026\x00\x02\x06H\x004\x026\x00\x004\x05\x03\x02\x05S\x004\x026\x00\x004\x065\x01\x03\x03\x024\x076\x00\x005\x00\x03\x02\x024\x006\x00\x006\x00\x016\x00\x024\x086\x00\x03\x03\x01\x17\x06~\x004\x096\x00\x03\x03\x01\x05\x7f\x00-\x03\x04\x024\x076\x00\x005\x01\x04\x02\x0b" [compile-in
+ cadr emit :brf caddr :ret :jmp mark-label cdddr cadddr]) make-label])
+compile-in
+#function(">\x045\x03\x14\x06\x15\x004\x005\x005\x015\x032\x01\x04\x04\x0b5\x03\x10\x06\xa1\x005\x03/\x0d\x06+\x004\x025\x004\x03\x04\x02\x0b5\x030\x0d\x06;\x004\x025\x004\x04\x04\x02\x0b5\x03,\x0d\x06K\x004\x025\x004\x05\x04\x02\x0b5\x03-\x0d\x06[\x004\x025\x004\x06\x04\x02\x0b5\x03.\x0d\x06k\x004\x025\x004\x07\x04\x02\x0b5\x03\x1a\x01\x06\x88\x00\x024\x085\x031\x80\x03\x02\x01\x06\x88\x00\x024\x095\x031\x7f\x03\x02\x06\x96\x004\x025\x004\x0a5\x03\x04\x03\x0b4\x025\x004\x0b5\x03\x04\x03\x0b2\x0c5\x03\x1d@\x04\x02\x0b" [compile-sym
+ [:loada :loadc :loadg] emit :load0 :load1 :loadt :loadf :loadnil >= <=
+ :loadi8 :loadv #function("A\x025\x002\x00\x0e\x06\x1b\x004\x016\x00\x004\x024\x036\x00\x03\x03\x01\x04\x03\x0b5\x002\x04\x0e\x068\x004\x056\x00\x006\x00\x016\x00\x024\x066\x00\x03\x03\x01\x04\x04\x0b5\x002\x07\x0e\x06Q\x004\x086\x00\x006\x00\x016\x00\x026\x00\x03\x04\x04\x0b5\x002\x09\x0e\x06k\x004\x0a6\x00\x006\x00\x016\x00\x026\x00\x03\x1e\x04\x04\x0b5\x002\x0b\x0e\x06\x81\x004\x0c6\x00\x006\x00\x016\x00\x03\x04\x03\x0b5\x002\x0d\x0e\x06\xa7\x004\x016\x00\x004\x024\x0e6\x00\x016\x00\x03\x03\x02\x03\x03\x024\x016\x00\x004\x0f\x04\x02\x0b5\x002\x10\x0e\x06\xc1\x004\x116\x00\x006\x00\x016\x00\x026\x00\x03\x1e\x04\x04\x0b5\x002\x12\x0e\x06\xdb\x004\x136\x00\x006\x00\x016\x00\x026\x00\x03\x1e\x04\x04\x0b5\x002\x14\x0e\x06\xff\x004\x156\x00\x006\x00\x014\x036\x00\x03\x03\x012\x094\x166\x00\x03\x03\x01\x1b\x04\x04\x0b5\x002\x17\x0e\x06'\x014\x186\x00\x006\x00\x014\x036\x00\x03\x03\x014\x196\x00\x03\x03\x014\x1a6\x00\x03\x03\x01\x04\x05\x0b5\x002\x1b\x0e\x06V\x014\x056\x00\x006\x00\x01-4\x196\x00\x03\x03\x01\x03\x04\x024\x1c6\x00\x006\x00\x014\x036\x00\x03\x03\x012\x1d\x04\x04\x0b5\x002\x1e\x0e\x06\xac\x014\x056\x00\x006\x00\x01-2\x0d.4\x036\x00\x03\x03\x01\x1c\x03\x03\x04\x024\x1f4\x196\x00\x03\x03\x01\x03\x01\x06\x88\x01-\x05\x8e\x014 2!\x03\x01\x024\x056\x00\x006\x00\x01-4\x196\x00\x03\x03\x01\x03\x04\x024\x016\x00\x004\"\x04\x02\x0b4#6\x00\x006\x00\x016\x00\x026\x00\x03\x04\x04\x0b" [quote
+ emit :loadv cadr cond compile-in cond->if if compile-if begin compile-begin
+ prog1 compile-prog1 lambda compile-f :closure and compile-and or compile-or
+ while compile-while cddr for compile-for caddr cadddr set! compile-sym [:seta
+ :setc :setg] trycatch 1arg-lambda? error "trycatch: second form must be a 1-argument lambda"
+ :trycatch compile-app])])
+compile-sym
+#function(">\x042\x004\x015\x025\x01/,\x03\x04@\x04\x02\x0b" [#function("A\x022\x005\x00\x1d@\x04\x02\x0b" [#function("A\x025\x002\x00\x0e\x06\x1e\x004\x016\x01\x006\x01\x03/*4\x026\x00\x00\x03\x01\x04\x03\x0b5\x002\x03\x0e\x06A\x004\x016\x01\x006\x01\x030*4\x026\x00\x00\x03\x014\x046\x00\x00\x03\x01\x04\x04\x0b4\x016\x01\x006\x01\x031\x02*6\x01\x02\x04\x03\x0b" [arg
+ emit cadr closed caddr])]) lookup-sym])
+compile-thunk
+#function(">\x014\x002\x01.5\x00\x1c\x03\x04\x01\x0b" [compile lambda])
+char?
+#function(">\x014\x005\x00\x03\x012\x01\x0d\x0b" [typeof wchar])
+cdddr
+#function(">\x015\x00\x1e\x1e\x1e\x0b" [])
+cddar
+#function(">\x015\x00\x1d\x1e\x1e\x0b" [])
+cddr
+#function(">\x015\x00\x1e\x1e\x0b" [])
+cdadr
+#function(">\x015\x00\x1e\x1d\x1e\x0b" [])
+cdaar
+#function(">\x015\x00\x1d\x1d\x1e\x0b" [])
+cdar
+#function(">\x015\x00\x1d\x1e\x0b" [])
+cadddr
+#function(">\x015\x00\x1e\x1e\x1e\x1d\x0b" [])
+caddr
+#function(">\x015\x00\x1e\x1e\x1d\x0b" [])
+cadar
+#function(">\x015\x00\x1d\x1e\x1d\x0b" [])
+caadr
+#function(">\x015\x00\x1e\x1d\x1d\x0b" [])
+caaar
+#function(">\x015\x00\x1d\x1d\x1d\x0b" [])
+caar
+#function(">\x015\x00\x1d\x1d\x0b" [])
+cadr
+#function(">\x015\x00\x1e\x1d\x0b" [])
+builtin->instruction
+#function(">\x012\x004\x014\x022\x035\x00\x03\x02\x03\x01@\x04\x02\x0b" [#function("A\x024\x004\x015\x00\x03\x02\x01\x06\x11\x00\x025\x00\x0b" [has? Instructions]) intern string #\:])
+bq-bracket
+#function(">\x015\x00\x10\x06\x13\x004\x004\x015\x00\x03\x01\x1c\x02\x0b5\x00\x1d2\x02\x0d\x06'\x004\x004\x035\x00\x03\x01\x1c\x02\x0b5\x00\x1d2\x04\x0d\x06;\x002\x054\x035\x00\x03\x01\x1c\x02\x0b5\x00\x1d2\x06\x0d\x06K\x004\x035\x00\x04\x01\x0b,\x06Z\x004\x004\x015\x00\x03\x01\x1c\x02\x0b-\x0b" [list bq-process *comma* cadr
+ *comma-at* copy-list *comma-dot*])
+bq-bracket1
+#function(">\x015\x00\x17\x01\x06\x10\x00\x025\x00\x1d2\x00\x0d\x06\x1a\x004\x015\x00\x04\x01\x0b4\x025\x00\x04\x01\x0b" [*comma* cadr bq-process])
+bq-process
+#function(">\x014\x005\x00\x03\x01\x06$\x005\x00\x19\x06!\x002\x014\x024\x035\x00\x03\x01\x03\x01@\x04\x02\x0b5\x00\x0b5\x00\x10\x061\x002\x045\x00\x1c\x02\x0b5\x00\x1d2\x05\x0d\x06I\x004\x024\x024\x065\x00\x03\x01\x03\x01\x04\x01\x0b5\x00\x1d2\x07\x0d\x06Y\x004\x065\x00\x04\x01\x0b4\x084\x095\x00\x03\x02\x11\x06y\x002\x0a4\x0b5\x00\x03\x014\x0c4\x0d5\x00\x03\x02@\x04\x03\x0b,\x06\x86\x002\x0e5\x00.@\x04\x03\x0b-\x0b" [self-evaluating? #function("A\x025\x00\x1d2\x00\x0d\x06\x12\x004\x015\x00\x1e\x1b\x0b4\x024\x015\x00\x1c\x03\x0b" [list
+ vector apply]) bq-process vector->list quote backquote cadr *comma* any
+ splice-form? #function("A\x035\x00\x12\x06\x0e\x002\x005\x01\x1b\x0b4\x012\x025\x01\x1b4\x035\x00\x03\x01\x1c\x01\x04\x02\x0b" [list
+ nconc nlist* bq-process]) lastcdr map bq-bracket1 #function("A\x03-5\x00\x17\x01\x06\x12\x00\x025\x00\x1d2\x00\x0d\x11\x06+\x00\x024\x015\x00\x1d\x03\x015\x01\x1b9\x01\x025\x00\x1e9\x00\x05\x03\x00\x022\x025\x00\x17\x06E\x004\x035\x014\x045\x00\x03\x01\x1c\x01\x03\x02\x05j\x005\x00\x12\x06T\x004\x055\x01\x03\x01\x05j\x00,\x06i\x004\x035\x014\x065\x00\x03\x01\x1c\x01\x03\x02\x05j\x00-@\x04\x02\x0b" [*comma*
+ bq-bracket #function("A\x025\x00\x1e\x12\x06\x0d\x005\x00\x1d\x0b2\x005\x00\x1b\x0b" [nconc]) nreconc cadr nreverse bq-process])])
+assv
+#function(">\x025\x01\x10\x06\x0a\x00-\x0b4\x005\x01\x03\x015\x00\x0e\x06\x1a\x005\x01\x1d\x0b,\x06(\x004\x015\x005\x01\x1e\x04\x02\x0b-\x0b" [caar assv])
+assoc
+#function(">\x025\x01\x10\x06\x0a\x00-\x0b4\x005\x01\x03\x015\x00\x0f\x06\x1a\x005\x01\x1d\x0b,\x06(\x004\x015\x005\x01\x1e\x04\x02\x0b-\x0b" [caar assoc])
+argc-error
+#function(">\x024\x004\x012\x025\x002\x035\x015\x010&\x06\x1a\x002\x04\x05\x1c\x002\x05\x03\x05\x04\x01\x0b" [error string "compile error: " " expects " " argument."
+ " arguments."])
+arg-counts
+#table(:not 1 :set-cdr! 2 :cons 2 :number? 1 :equal? 2 :cdr 1 :vector? 1 :eqv? 2 :apply 2 := 2 :atom? 1 :aref 2 :compare 2 :< 2 :null? 1 :eq? 2 :car 1 :set-car! 2 :builtin? 1 :aset! 3 :bound? 1 :boolean? 1 :pair? 1 :symbol? 1 :fixnum? 1)
+any
+#function(">\x025\x01\x17\x01\x06\x1f\x00\x025\x005\x01\x1d\x03\x01\x01\x07\x1f\x00\x024\x005\x005\x01\x1e\x04\x02\x0b" [any])
+__start
+#function(">\x014\x00\x03\x00\x025\x00\x1e\x17\x06!\x005\x00\x1e8\x01\x024\x024\x035\x00\x03\x01\x03\x01\x051\x005\x008\x01\x024\x044\x05\x03\x01\x024\x06\x03\x00\x024\x07/\x04\x01\x0b" [__init_globals *argv* __script cadr princ
+ *banner* repl exit])
+__script
+#function(">\x012\x00<2\x01<=\x0b" [#function(">\x004\x006\x00\x00\x04\x01\x0b" [load])
+ #function(">\x014\x005\x00\x03\x01\x024\x010\x04\x01\x0b" [print-exception exit])])
+__init_globals
+#function(">\x004\x002\x01\x0d\x01\x07\x1b\x00\x024\x002\x02\x0d\x01\x07\x1b\x00\x024\x002\x03\x0d\x06*\x002\x048\x05\x022\x068\x07\x053\x002\x088\x05\x022\x098\x07\x024\x0a8\x0b\x024\x0c8\x0d\x0b" [*os-name* win32 win64 windows "\\"
+ *directory-separator* "\r\n" *linefeed* "/"
+ "\n" *stdout* *output-stream* *stdin*
+ *input-stream*])
+abs
+#function(">\x015\x00/'\x06\x0e\x005\x00#\x01\x0b5\x00\x0b" [])
+append
+#function("?\x005\x00\x12\x06\x0a\x00.\x0b5\x00\x1e\x12\x06\x15\x005\x00\x1d\x0b,\x06'\x004\x005\x00\x1d4\x015\x00\x1e!\x04\x02\x0b-\x0b" [append2 append])
+append2
+#function(">\x025\x00\x12\x06\x0b\x005\x01\x0b5\x00\x1d4\x005\x00\x1e5\x01\x03\x02\x1b\x0b" [append2])
+MAX_ARGS
+127
+Instructions
+#table(:nop 0 :tapply 12 :set-cdr! 32 :/ 37 :setc 58 :cons 27 :equal? 15 :cdr 30 :call 3 :eqv? 14 := 38 :setg.l 59 :list 28 :atom? 16 :aref 42 :load0 47 :let 65 :argc 62 :< 39 :null? 18 :loadg 52 :load1 48 :car 29 :brt.l 10 :vargc 63 :loada 53 :set-car! 31 :setg 56 :aset! 43 :bound? 22 :pair? 23 :symbol? 20 :fixnum? 26 :loadi8 49 :not 17 :* 36 :pop 2 :loadnil 46 :brf 6 :vector 41 :- 35 :loadv 50 :closure 60 :number? 21 :trycatch 61 :loadv.l 51 :vector? 25 :brf.l 9 :seta 57 :apply 33 :dup 1 :for 66 :loadc 54 :compare 40 :eq? 13 :+ 34 :jmp 5 :loadt 44 :brt 7 :builtin? 24 :loadg.l 55 :close 64 :tcall 4 :ret 11 :boolean? 19 :loadf 45 :jmp.l 8)
+>=
+#function(">\x025\x015\x00'\x01\x07\x11\x00\x025\x005\x01&\x0b" [])
+>
+#function(">\x025\x015\x00'\x0b" [])
+<=
+#function(">\x025\x005\x01'\x01\x07\x11\x00\x025\x005\x01&\x0b" [])
+1arg-lambda?
+#function(">\x015\x00\x17\x01\x065\x00\x025\x00\x1d2\x00\x0d\x01\x065\x00\x025\x00\x1e\x17\x01\x065\x00\x024\x015\x00\x03\x01\x17\x01\x065\x00\x024\x024\x015\x00\x03\x010\x04\x02\x0b" [lambda cadr length=])
+1/Instructions
+#table(2 :pop 45 :loadf 59 :setg.l 15 :equal? 38 := 50 :loadv 61 :trycatch 14 :eqv? 30 :cdr 40 :compare 11 :ret 28 :list 48 :load1 22 :bound? 36 :* 60 :closure 41 :vector 0 :nop 29 :car 56 :setg 23 :pair? 17 :not 4 :tcall 43 :aset! 3 :call 58 :setc 21 :number? 8 :jmp.l 39 :< 63 :vargc 51 :loadv.l 53 :loada 66 :for 44 :loadt 65 :let 55 :loadg.l 5 :jmp 27 :cons 46 :loadnil 34 :+ 6 :brf 16 :atom? 42 :aref 10 :brt.l 31 :set-car! 25 :vector? 54 :loadc 13 :eq? 19 :boolean? 47 :load0 12 :tapply 32 :set-cdr! 62 :argc 20 :symbol? 26 :fixnum? 35 :- 9 :brf.l 7 :brt 37 :/ 18 :null? 52 :loadg 49 :loadi8 1 :dup 24 :builtin? 64 :close 33 :apply 57 :seta)
+1-
+#function(">\x015\x000#\x02\x0b" [])
+1+
+#function(">\x015\x000\"\x02\x0b" [])
+/=
+#function(">\x025\x005\x01&\x11\x0b" [])
+*whitespace*
+"\t\n\v\f\r \u0085 \u2028\u2029 "
+*syntax-environment*
+#table(define #function("?\x015\x00\x14\x06\x12\x002\x005\x005\x01\x1d\x1c\x03\x0b2\x005\x00\x1d2\x015\x00\x1e4\x025\x01\x03\x01\x1c\x03\x1c\x03\x0b" [set! lambda f-body]) letrec #function("?\x012\x004\x014\x025\x00\x03\x024\x034\x044\x012\x05<5\x00\x03\x025\x01\x03\x02\x03\x01\x1c\x034\x012\x06<5\x00\x03\x02\x1b\x0b" [lambda
+ map car f-body nconc #function(">\x012\x005\x00\x1b\x0b" [set!])
+ #function(">\x01-\x0b" [])]) backquote #function(">\x014\x005\x00\x04\x01\x0b" [bq-process]) assert #function(">\x012\x005\x00,2\x012\x022\x035\x00\x1c\x02\x1c\x02\x1c\x02\x1c\x04\x0b" [if
+ raise quote assert-failed]) label #function(">\x022\x005\x00\x1c\x012\x015\x005\x01\x1c\x03\x1c\x03-\x1c\x02\x0b" [lambda set!]) do #function("?\x022\x004\x01\x03\x005\x01\x1d4\x024\x035\x00\x03\x024\x024\x045\x00\x03\x024\x022\x05<5\x00\x03\x02@\x04\x06\x0b" [#function("A\x062\x005\x002\x015\x022\x025\x014\x032\x04\x1c\x014\x056\x00\x01\x1e\x03\x01\x03\x024\x032\x04\x1c\x014\x056\x00\x02\x03\x014\x035\x00\x1c\x014\x055\x04\x03\x01\x03\x02\x1c\x01\x03\x03\x1c\x04\x1c\x03\x1c\x02\x1c\x014\x035\x00\x1c\x014\x055\x03\x03\x01\x03\x02\x1c\x03\x0b" [letrec
+ lambda if nconc begin copy-list]) gensym map car cadr #function(">\x014\x005\x00\x03\x01\x17\x06\x13\x004\x015\x00\x04\x01\x0b5\x00\x1d\x0b" [cddr
+ caddr])]) when #function("?\x012\x005\x004\x015\x01\x03\x01-\x1c\x04\x0b" [if f-body]) dotimes #function("?\x012\x005\x00\x1d4\x015\x00\x03\x01@\x04\x03\x0b" [#function("A\x032\x00/2\x015\x010\x1c\x032\x025\x00\x1c\x014\x036\x00\x01\x03\x01\x1c\x03\x1c\x04\x0b" [for
+ - lambda f-body]) cadr]) unwind-protect #function(">\x022\x004\x01\x03\x00@\x04\x02\x0b" [#function("A\x022\x002\x016\x00\x002\x025\x00\x1c\x012\x036\x00\x012\x045\x00\x1c\x02\x1c\x03\x1c\x03\x1c\x036\x00\x01\x1c\x03\x0b" [prog1
+ trycatch lambda begin raise]) gensym]) define-macro #function("?\x012\x002\x015\x00\x1d\x1c\x022\x025\x00\x1e4\x035\x01\x03\x01\x1c\x03\x1c\x03\x0b" [set-syntax!
+ quote lambda f-body]) unless #function("?\x012\x005\x00-4\x015\x01\x03\x01\x1c\x04\x0b" [if f-body]) let #function("?\x012\x00-@\x04\x02\x0b" [#function("A\x026\x00\x00\x14\x06!\x006\x00\x009\x00\x026\x00\x01\x1d:\x00\x00\x026\x00\x01\x1e:\x00\x01\x05\"\x00-\x022\x002\x014\x022\x03<6\x00\x00\x03\x024\x046\x00\x01\x03\x01\x1c\x034\x022\x05<6\x00\x00\x03\x02@\x04\x03\x0b" [#function("A\x036\x00\x00\x06\x14\x002\x006\x00\x005\x00\x1c\x03\x05\x16\x005\x005\x01\x1b\x0b" [label])
+ lambda map #function(">\x015\x00\x17\x06\x0c\x005\x00\x1d\x0b5\x00\x0b" []) f-body #function(">\x015\x00\x17\x06\x0f\x004\x005\x00\x04\x01\x0b-\x0b" [cadr])])]) throw #function(">\x022\x002\x012\x022\x03\x1c\x025\x005\x01\x1c\x04\x1c\x02\x0b" [raise
+ list quote thrown-value]) time #function(">\x012\x004\x01\x03\x00@\x04\x02\x0b" [#function("A\x022\x005\x002\x01\x1c\x01\x1c\x02\x1c\x012\x026\x00\x002\x032\x042\x052\x01\x1c\x015\x00\x1c\x032\x06\x1c\x04\x1c\x03\x1c\x03\x0b" [let
+ time.now prog1 princ "Elapsed time: " - " seconds\n"]) gensym]) let* #function("?\x015\x00\x10\x06\x0f\x004\x005\x01\x04\x01\x0b2\x014\x025\x00\x03\x01\x1c\x014\x032\x04\x1c\x015\x00\x1e\x1c\x014\x055\x01\x03\x01\x03\x03\x1c\x034\x065\x00\x03\x01\x1c\x02\x0b" [f-body
+ lambda caar nconc let* copy-list cadar]) case #function("?\x012\x00-@\x04\x02\x0b" [#function("A\x022\x00<9\x00\x022\x014\x02\x03\x00@\x04\x02\x0b" [#function(">\x025\x012\x00\x0d\x06\x0d\x002\x00\x0b5\x01\x12\x06\x15\x00-\x0b5\x01\x10\x06(\x002\x015\x004\x025\x01\x03\x01\x1c\x03\x0b5\x01\x1e\x12\x06=\x002\x015\x004\x025\x01\x1d\x03\x01\x1c\x03\x0b2\x035\x002\x045\x01\x1c\x02\x1c\x03\x0b" [else
+ eqv? quote-value memv quote]) #function("A\x022\x005\x006\x01\x00\x1c\x02\x1c\x014\x012\x02\x1c\x014\x034\x042\x05<6\x01\x01\x03\x02\x03\x01\x03\x02\x1c\x03\x0b" [let nconc cond
+ copy-list map #function(">\x016\x01\x006\x00\x005\x00\x1d\x03\x025\x00\x1e\x1b\x0b" [])])
+ gensym])]) catch #function(">\x022\x004\x01\x03\x00@\x04\x02\x0b" [#function("A\x022\x006\x00\x012\x015\x00\x1c\x012\x022\x032\x045\x00\x1c\x022\x052\x065\x00\x1c\x022\x072\x08\x1c\x02\x1c\x032\x052\x095\x00\x1c\x026\x00\x00\x1c\x03\x1c\x042\x0a5\x00\x1c\x022\x0b5\x00\x1c\x02\x1c\x04\x1c\x03\x1c\x03\x0b" [trycatch
+ lambda if and pair? eq car quote thrown-value cadr caddr raise]) gensym]))
+*print-width*
+80
+*linefeed*
+"\n"
+*directory-separator*
+"/"
+*print-pretty*
+#t
+*argv*
+("./flisp")
+*banner*
+"; _\n; |_ _ _ |_ _ | . _ _\n; | (-||||_(_)|__|_)|_)\n;-------------------|----------------------------------------------------------\n\n"
--- a/femtolisp/flisp.c
+++ b/femtolisp/flisp.c
@@ -53,10 +53,8 @@
#include "opcodes.h"
static char *builtin_names[] =
- { // special forms
- "quote", "cond", "if", "and", "or", "while", "lambda",
- "trycatch", "%apply", "set!", "prog1", "for", "begin",
-
+ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
// predicates
"eq?", "eqv?", "equal?", "atom?", "not", "null?", "boolean?", "symbol?",
"number?", "bound?", "pair?", "builtin?", "vector?", "fixnum?",
@@ -65,7 +63,7 @@
"cons", "list", "car", "cdr", "set-car!", "set-cdr!",
// execution
- "eval", "apply",
+ "apply",
// arithmetic
"+", "-", "*", "/", "=", "<", "compare",
@@ -80,7 +78,7 @@
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, ANYARGS, 1, 1, 2, 2,
- 1, 2,
+ 2,
ANYARGS, -1, ANYARGS, -1, 2, 2, 2,
ANYARGS, 2, 3 };
@@ -89,15 +87,6 @@
value_t *Stack = StaticStack;
uint32_t SP = 0;
-typedef struct _stackseg_t {
- value_t *Stack;
- uint32_t SP;
- struct _stackseg_t *prev;
-} stackseg_t;
-
-stackseg_t stackseg0 = { StaticStack, 0, NULL };
-stackseg_t *current_stack_seg = &stackseg0;
-
value_t NIL, FL_T, FL_F, LAMBDA, QUOTE, IF, TRYCATCH;
value_t BACKQUOTE, COMMA, COMMAAT, COMMADOT, FUNCTION;
value_t IOError, ParseError, TypeError, ArgError, UnboundError, MemoryError;
@@ -104,10 +93,9 @@
value_t DivideError, BoundsError, Error, KeyError, EnumerationError;
value_t conssym, symbolsym, fixnumsym, vectorsym, builtinsym;
value_t definesym, defmacrosym, forsym, labelsym, printprettysym, setqsym;
-value_t printwidthsym, tsym, Tsym, fsym, Fsym, booleansym, nullsym, elsesym;
+value_t printwidthsym, tsym, Tsym, fsym, Fsym, booleansym, nullsym, evalsym;
static fltype_t *functiontype;
-static value_t eval_sexpr(value_t e, value_t *penv, int tail, uint32_t envsz);
static value_t apply_cl(uint32_t nargs);
static value_t *alloc_words(int n);
static value_t relocate(value_t v);
@@ -357,8 +345,11 @@
#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)
{
+ if (n == 0) return the_empty_vector;
value_t *c = alloc_words(n+1);
value_t v = tagptr(c, TAG_VECTOR);
vector_setsize(v, n);
@@ -418,7 +409,8 @@
newsz = sz;
if (vector_elt(v,-1) & 0x1)
newsz += vector_grow_amt(sz);
- nc = alloc_vector(newsz, 0);
+ nc = tagptr(alloc_words(newsz+1), TAG_VECTOR);
+ vector_setsize(nc, newsz);
a = vector_elt(v,0);
forward(v, nc);
i = 0;
@@ -478,8 +470,6 @@
}
}
-static value_t special_apply_form;
-static value_t apply1_args;
static value_t memory_exception_value;
void gc(int mustgrow)
@@ -488,18 +478,12 @@
void *temp;
uint32_t i;
readstate_t *rs;
- stackseg_t *ss;
curheap = tospace;
lim = curheap+heapsize-sizeof(cons_t);
- ss = current_stack_seg;
- ss->SP = SP;
- while (ss) {
- for (i=0; i < ss->SP; i++)
- ss->Stack[i] = relocate(ss->Stack[i]);
- ss = ss->prev;
- }
+ for (i=0; i < SP; i++)
+ Stack[i] = relocate(Stack[i]);
trace_globals(symtab);
relocate_typetable();
rs = readstate;
@@ -512,9 +496,8 @@
rs = rs->prev;
}
lasterror = relocate(lasterror);
- special_apply_form = relocate(special_apply_form);
- apply1_args = relocate(apply1_args);
memory_exception_value = relocate(memory_exception_value);
+ the_empty_vector = relocate(the_empty_vector);
sweep_finalizers();
@@ -551,13 +534,25 @@
// utils ----------------------------------------------------------------------
-#define topeval(e, env) (selfevaluating(e) ? (e) : eval_sexpr((e),env,1,2))
-
// apply function with n args on the stack
static value_t _applyn(uint32_t n)
{
- PUSH(fixnum(n));
- return topeval(special_apply_form, NULL);
+ value_t f = Stack[SP-n-1];
+ uint32_t saveSP = SP;
+ value_t v;
+ if (isbuiltinish(f)) {
+ if (uintval(f) > N_BUILTINS) {
+ v = ((builtin_t)ptr(f))(&Stack[SP-n], n);
+ SP = saveSP;
+ return v;
+ }
+ }
+ else if (isfunction(f)) {
+ v = apply_cl(n);
+ SP = saveSP;
+ return v;
+ }
+ type_error("apply", "function", f);
}
value_t apply(value_t f, value_t l)
@@ -567,7 +562,7 @@
PUSH(f);
while (iscons(v)) {
- if (n == MAX_ARGS) {
+ if ((SP-n-1) == MAX_ARGS) {
PUSH(v);
break;
}
@@ -575,6 +570,7 @@
v = cdr_(v);
}
n = SP - n - 1;
+ assert(n <= MAX_ARGS+1);
v = _applyn(n);
POPN(n+1);
return v;
@@ -700,95 +696,8 @@
return v;
}
-#define eval(e) (selfevaluating(e) ? (e) : eval_sexpr((e),penv,0,envsz))
-#define tail_eval(xpr) do { \
- if (selfevaluating(xpr)) { SP=saveSP; return (xpr); } \
- else { e=(xpr); goto eval_top; } } while (0)
-
-/* eval a list of expressions, giving a list of the results */
-static value_t evlis(value_t *pv, value_t *penv, uint32_t envsz)
+static value_t do_trycatch()
{
- PUSH(NIL);
- PUSH(NIL);
- value_t *rest = &Stack[SP-1];
- value_t a, v = *pv;
- while (iscons(v)) {
- a = car_(v);
- v = eval(a);
- PUSH(v);
- v = mk_cons();
- car_(v) = Stack[SP-1];
- cdr_(v) = NIL;
- POPN(1);
- if (*rest == NIL)
- Stack[SP-2] = v;
- else
- cdr_(*rest) = v;
- *rest = v;
- v = *pv = cdr_(*pv);
- }
- POPN(1);
- return POP();
-}
-
-/*
- If we start to run out of space on the lisp value stack, we allocate
- a new stack array and put it on the top of the chain. The new stack
- is active until this function returns. Any return past this function
- must free the new segment.
-*/
-static value_t new_stackseg(value_t e, value_t *penv, int tail, uint32_t envsz)
-{
- stackseg_t s;
-
- s.prev = current_stack_seg;
- s.Stack = (value_t*)malloc(N_STACK * sizeof(value_t));
- if (s.Stack == NULL)
- lerror(MemoryError, "eval: stack overflow");
- current_stack_seg->SP = SP;
- current_stack_seg = &s;
- SP = 0;
- Stack = s.Stack;
- value_t v = NIL;
- int err = 0;
- FL_TRY {
- v = eval_sexpr(e, penv, tail, envsz);
- }
- FL_CATCH {
- err = 1;
- v = lasterror;
- }
- free(s.Stack);
- current_stack_seg = s.prev;
- SP = current_stack_seg->SP;
- Stack = current_stack_seg->Stack;
- if (err) raise(v);
- return v;
-}
-
-static value_t do_trycatch(value_t expr, value_t *penv, uint32_t envsz)
-{
- value_t v;
-
- FL_TRY {
- v = eval(expr);
- }
- FL_CATCH {
- v = cdr_(Stack[SP-1]);
- if (!iscons(v)) {
- v = FL_F; // 1-argument form
- }
- else {
- v = car_(v);
- Stack[SP-1] = eval(v);
- v = applyn(1, Stack[SP-1], lasterror);
- }
- }
- return v;
-}
-
-static value_t do_trycatch2()
-{
uint32_t saveSP = SP;
value_t v;
value_t thunk = Stack[SP-2];
@@ -806,725 +715,6 @@
return v;
}
-/* stack setup on entry:
- n n+1 ...
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | LL | VAL | VAL | CLO | | | | |
- +-----+-----+-----+-----+-----+-----+-----+-----+
- ^ ^
- | |
- penv SP (who knows where)
-
- where LL is the lambda list, CLO is a closed-up environment vector
- (which can be empty, i.e. NIL). An environment vector is just a copy
- of the stack from LL through CLO.
- There might be zero values, in which case LL is NIL.
-
- penv[-1] tells you the environment size, from LL through CLO, as a fixnum.
-*/
-static value_t eval_sexpr(value_t e, value_t *penv, int tail, uint32_t envsz)
-{
- value_t f, v, *pv, *lenv;
- cons_t *c;
- symbol_t *sym;
- uint32_t saveSP, bp, nargs;
- int i, noeval=0;
- fixnum_t s, lo, hi;
- int64_t accum;
-
- /*
- ios_printf(ios_stdout, "eval "); print(ios_stdout, e, 0);
- ios_printf(ios_stdout, " in "); print(ios_stdout, penv[0], 0);
- ios_printf(ios_stdout, "\n");
- */
- saveSP = SP;
- eval_top:
- if (issymbol(e)) {
- sym = (symbol_t*)ptr(e);
- while (1) {
- v = *penv++;
- while (iscons(v)) {
- if (car_(v)==e) { SP=saveSP; return *penv; }
- v = cdr_(v); penv++;
- }
- if (v != NIL) {
- if (v == e) { SP=saveSP; return *penv; } // dotted list
- penv++;
- }
- if (*penv == NIL) break;
- assert(isvector(*penv));
- penv = &vector_elt(*penv, 0);
- }
- if (__unlikely((v = sym->binding) == UNBOUND))
- raise(list2(UnboundError, e));
- SP = saveSP;
- return v;
- }
- if (__unlikely(SP >= (N_STACK-MAX_ARGS-4))) {
- v = new_stackseg(e, penv, tail, envsz);
- SP = saveSP;
- return v;
- }
- bp = SP;
- v = car_(e);
- PUSH(cdr_(e));
- if (selfevaluating(v)) f=v;
- else if (issymbol(v) && (f=((symbol_t*)ptr(v))->syntax) && f!=TAG_CONST) {
- // handle special syntax forms
- if (isspecial(f))
- goto apply_special;
- else {
- PUSH(f);
- noeval = 2;
- v = Stack[bp];
- goto move_args;
- }
- }
- else f = eval(v);
- PUSH(f);
- v = Stack[bp];
- // evaluate argument list, placing arguments on stack
- while (iscons(v)) {
- if (SP-bp-2 == MAX_ARGS) {
- v = evlis(&Stack[bp], penv, envsz);
- PUSH(v);
- break;
- }
- v = car_(v);
- v = eval(v);
- PUSH(v);
- v = Stack[bp] = cdr_(Stack[bp]);
- }
- do_apply:
- nargs = SP - bp - 2;
- if (isbuiltinish(f)) {
- // handle builtin function
- apply_special:
- switch (uintval(f)) {
- // special forms
- case F_QUOTE:
- if (__unlikely(!iscons(Stack[bp])))
- lerror(ArgError, "quote: expected argument");
- v = car_(Stack[bp]);
- break;
- case F_SETQ:
- e = car(Stack[bp]);
- v = car(cdr_(Stack[bp]));
- v = eval(v);
- while (1) {
- f = *penv++;
- while (iscons(f)) {
- if (car_(f)==e) {
- *penv = v;
- SP = saveSP;
- return v;
- }
- f = cdr_(f); penv++;
- }
- if (f != NIL) {
- if (f == e) {
- *penv = v;
- SP = saveSP;
- return v;
- }
- penv++;
- }
- if (*penv == NIL) break;
- penv = &vector_elt(*penv, 0);
- }
- sym = tosymbol(e, "set!");
- if (sym->syntax != TAG_CONST)
- sym->binding = v;
- break;
- case F_LAMBDA:
- // build a closure (lambda args body . env)
- if (*penv != NIL) {
- // save temporary environment to the heap
- lenv = penv;
- assert(penv[envsz-1]==NIL || isvector(penv[envsz-1]));
- pv = alloc_words(envsz + 1);
- PUSH(tagptr(pv, TAG_VECTOR));
- pv[0] = fixnum(envsz);
- pv++;
- while (envsz--)
- *pv++ = *penv++;
- assert(pv[-1]==NIL || isvector(pv[-1]));
- // environment representation changed; install
- // the new representation so everybody can see it
- lenv[0] = NIL;
- lenv[1] = Stack[SP-1];
- }
- else {
- PUSH(penv[1]); // env has already been captured; share
- }
- c = (cons_t*)ptr(v=cons_reserve(3));
- e = Stack[bp];
- if (!iscons(e)) goto notpair;
- c->car = LAMBDA;
- c->cdr = tagptr(c+1, TAG_CONS); c++;
- c->car = car_(e); //argsyms
- c->cdr = tagptr(c+1, TAG_CONS); c++;
- if (!iscons(e=cdr_(e))) goto notpair;
- c->car = car_(e); //body
- c->cdr = Stack[SP-1]; //env
- break;
- case F_IF:
- if (!iscons(Stack[bp])) goto notpair;
- v = car_(Stack[bp]);
- if (eval(v) != FL_F) {
- v = cdr_(Stack[bp]);
- if (!iscons(v)) goto notpair;
- v = car_(v);
- }
- else {
- v = cdr_(Stack[bp]);
- if (!iscons(v)) goto notpair;
- if (!iscons(v=cdr_(v))) v = FL_F; // allow 2-arg form
- else v = car_(v);
- }
- tail_eval(v);
- break;
- case F_COND:
- pv = &Stack[bp]; v = FL_F;
- while (iscons(*pv)) {
- c = tocons(car_(*pv), "cond");
- v = c->car;
- // allow last condition to be 'else'
- if (iscons(cdr_(*pv)) || v != elsesym)
- v = eval(v);
- if (v != FL_F) {
- *pv = cdr_(car_(*pv));
- // evaluate body forms
- if (iscons(*pv)) {
- while (iscons(cdr_(*pv))) {
- v = car_(*pv);
- v = eval(v);
- *pv = cdr_(*pv);
- }
- tail_eval(car_(*pv));
- }
- break;
- }
- *pv = cdr_(*pv);
- }
- break;
- case F_AND:
- pv = &Stack[bp]; v = FL_T;
- if (iscons(*pv)) {
- while (iscons(cdr_(*pv))) {
- if ((v=eval(car_(*pv))) == FL_F) {
- SP = saveSP; return FL_F;
- }
- *pv = cdr_(*pv);
- }
- tail_eval(car_(*pv));
- }
- break;
- case F_OR:
- pv = &Stack[bp]; v = FL_F;
- if (iscons(*pv)) {
- while (iscons(cdr_(*pv))) {
- if ((v=eval(car_(*pv))) != FL_F) {
- SP = saveSP; return v;
- }
- *pv = cdr_(*pv);
- }
- tail_eval(car_(*pv));
- }
- break;
- case F_WHILE:
- PUSH(cdr(Stack[bp]));
- lenv = &Stack[SP-1];
- PUSH(*lenv);
- Stack[bp] = car_(Stack[bp]);
- value_t *cond = &Stack[bp];
- PUSH(FL_F);
- pv = &Stack[SP-1];
- while (eval(*cond) != FL_F) {
- *lenv = Stack[SP-2];
- while (iscons(*lenv)) {
- *pv = eval(car_(*lenv));
- *lenv = cdr_(*lenv);
- }
- }
- v = *pv;
- break;
- case F_BEGIN:
- // return last arg
- pv = &Stack[bp];
- if (iscons(*pv)) {
- while (iscons(cdr_(*pv))) {
- v = car_(*pv);
- (void)eval(v);
- *pv = cdr_(*pv);
- }
- tail_eval(car_(*pv));
- }
- v = FL_F;
- break;
- case F_PROG1:
- // return first arg
- pv = &Stack[bp];
- if (__unlikely(!iscons(*pv)))
- lerror(ArgError, "prog1: too few arguments");
- PUSH(eval(car_(*pv)));
- *pv = cdr_(*pv);
- while (iscons(*pv)) {
- (void)eval(car_(*pv));
- *pv = cdr_(*pv);
- }
- v = POP();
- break;
- case F_FOR:
- if (!iscons(Stack[bp])) goto notpair;
- v = car_(Stack[bp]);
- lo = tofixnum(eval(v), "for");
- Stack[bp] = cdr_(Stack[bp]);
- if (!iscons(Stack[bp])) goto notpair;
- v = car_(Stack[bp]);
- hi = tofixnum(eval(v), "for");
- Stack[bp] = cdr_(Stack[bp]);
- if (!iscons(Stack[bp])) goto notpair;
- v = car_(Stack[bp]);
- f = eval(v);
- v = car(cdr(f));
- if (!iscons(v) || !iscons(cdr_(cdr_(f))) || cdr_(v) != NIL ||
- car_(f) != LAMBDA)
- lerror(ArgError, "for: expected 1 argument lambda");
- f = cdr_(f);
- PUSH(f); // save function cdr
- SP += 3; // make space
- Stack[SP-1] = cdr_(cdr_(f)); // cloenv
- v = FL_F;
- for(s=lo; s <= hi; s++) {
- f = Stack[SP-4];
- Stack[SP-3] = car_(f); // lambda list
- Stack[SP-2] = fixnum(s); // argument value
- v = car_(cdr_(f));
- if (!selfevaluating(v)) v = eval_sexpr(v, &Stack[SP-3], 0, 3);
- }
- break;
- case F_TRYCATCH:
- v = do_trycatch(car(Stack[bp]), penv, envsz);
- break;
-
- // ordinary functions
- case F_BOUNDP:
- argcount("bound?", nargs, 1);
- sym = tosymbol(Stack[SP-1], "bound?");
- v = (sym->binding == UNBOUND) ? FL_F : FL_T;
- break;
- case F_EQ:
- argcount("eq?", nargs, 2);
- v = ((Stack[SP-2] == Stack[SP-1]) ? FL_T : FL_F);
- break;
- case F_CONS:
- argcount("cons", nargs, 2);
- if (curheap > lim)
- gc(0);
- c = (cons_t*)curheap;
- curheap += sizeof(cons_t);
- c->car = Stack[SP-2];
- c->cdr = Stack[SP-1];
- v = tagptr(c, TAG_CONS);
- break;
- case F_LIST:
- if (nargs)
- v = list(&Stack[SP-nargs], nargs);
- else
- v = NIL;
- break;
- case F_CAR:
- argcount("car", nargs, 1);
- v = Stack[SP-1];
- if (!iscons(v)) goto notpair;
- v = car_(v);
- break;
- case F_CDR:
- argcount("cdr", nargs, 1);
- v = Stack[SP-1];
- if (!iscons(v)) goto notpair;
- v = cdr_(v);
- break;
- case F_SETCAR:
- argcount("set-car!", nargs, 2);
- car(v=Stack[SP-2]) = Stack[SP-1];
- break;
- case F_SETCDR:
- argcount("set-cdr!", nargs, 2);
- cdr(v=Stack[SP-2]) = Stack[SP-1];
- break;
- case F_VECTOR:
- if (nargs > MAX_ARGS) {
- i = llength(Stack[SP-1]);
- nargs--;
- }
- else i = 0;
- v = alloc_vector(nargs+i, 0);
- memcpy(&vector_elt(v,0), &Stack[bp+2], nargs*sizeof(value_t));
- if (i > 0) {
- e = Stack[SP-1];
- while (iscons(e)) {
- vector_elt(v,nargs) = car_(e);
- nargs++;
- e = cdr_(e);
- }
- }
- break;
- case F_AREF:
- argcount("aref", nargs, 2);
- v = Stack[SP-2];
- if (isvector(v)) {
- i = tofixnum(Stack[SP-1], "aref");
- if (__unlikely((unsigned)i >= vector_size(v)))
- bounds_error("aref", v, Stack[SP-1]);
- v = vector_elt(v, i);
- }
- else if (isarray(v)) {
- v = cvalue_array_aref(&Stack[SP-2]);
- }
- else {
- // TODO other sequence types?
- type_error("aref", "sequence", v);
- }
- break;
- case F_ASET:
- argcount("aset!", nargs, 3);
- e = Stack[SP-3];
- if (isvector(e)) {
- i = tofixnum(Stack[SP-2], "aset!");
- if (__unlikely((unsigned)i >= vector_size(e)))
- bounds_error("aset!", v, Stack[SP-1]);
- vector_elt(e, i) = (v=Stack[SP-1]);
- }
- else if (isarray(e)) {
- v = cvalue_array_aset(&Stack[SP-3]);
- }
- else {
- type_error("aset!", "sequence", e);
- }
- break;
- case F_ATOM:
- argcount("atom?", nargs, 1);
- v = (iscons(Stack[SP-1]) ? FL_F : FL_T);
- break;
- case F_CONSP:
- argcount("pair?", nargs, 1);
- v = (iscons(Stack[SP-1]) ? FL_T : FL_F);
- break;
- case F_SYMBOLP:
- argcount("symbol?", nargs, 1);
- v = ((issymbol(Stack[SP-1])) ? FL_T : FL_F);
- break;
- case F_NUMBERP:
- argcount("number?", nargs, 1);
- v = (isfixnum(Stack[SP-1]) || iscprim(Stack[SP-1]) ? FL_T : FL_F);
- break;
- case F_FIXNUMP:
- argcount("fixnum?", nargs, 1);
- v = (isfixnum(Stack[SP-1]) ? FL_T : FL_F);
- break;
- case F_BUILTINP:
- argcount("builtin?", nargs, 1);
- v = Stack[SP-1];
- v = ((isbuiltinish(v) && v!=FL_F && v!=FL_T && v!=NIL)
- ? FL_T : FL_F);
- break;
- case F_VECTORP:
- argcount("vector?", nargs, 1);
- v = ((isvector(Stack[SP-1])) ? FL_T : FL_F);
- break;
- case F_NOT:
- argcount("not", nargs, 1);
- v = ((Stack[SP-1] == FL_F) ? FL_T : FL_F);
- break;
- case F_NULL:
- argcount("null?", nargs, 1);
- v = ((Stack[SP-1] == NIL) ? FL_T : FL_F);
- break;
- case F_BOOLEANP:
- argcount("boolean?", nargs, 1);
- v = Stack[SP-1];
- v = ((v == FL_T || v == FL_F) ? FL_T : FL_F);
- break;
- case F_ADD:
- s = 0;
- i = bp+2;
- if (nargs > MAX_ARGS) goto add_ovf;
- for (; i < (int)SP; i++) {
- if (__likely(isfixnum(Stack[i]))) {
- s += numval(Stack[i]);
- if (__unlikely(!fits_fixnum(s))) {
- i++;
- goto add_ovf;
- }
- }
- else {
- add_ovf:
- v = fl_add_any(&Stack[i], SP-i, s);
- SP = saveSP;
- return v;
- }
- }
- v = fixnum(s);
- break;
- case F_SUB:
- if (__unlikely(nargs < 1)) lerror(ArgError, "-: too few arguments");
- i = bp+2;
- if (nargs == 1) {
- if (__likely(isfixnum(Stack[i])))
- v = fixnum(-numval(Stack[i]));
- else
- v = fl_neg(Stack[i]);
- break;
- }
- if (nargs == 2) {
- if (__likely(bothfixnums(Stack[i], Stack[i+1]))) {
- s = numval(Stack[i]) - numval(Stack[i+1]);
- if (__likely(fits_fixnum(s))) {
- v = fixnum(s);
- break;
- }
- Stack[i+1] = fixnum(-numval(Stack[i+1]));
- }
- else {
- Stack[i+1] = fl_neg(Stack[i+1]);
- }
- }
- else {
- // we need to pass the full arglist on to fl_add_any
- // so it can handle rest args properly
- PUSH(Stack[i]);
- Stack[i] = fixnum(0);
- Stack[i+1] = fl_neg(fl_add_any(&Stack[i], nargs, 0));
- Stack[i] = POP();
- }
- v = fl_add_any(&Stack[i], 2, 0);
- break;
- case F_MUL:
- accum = 1;
- i = bp+2;
- if (nargs > MAX_ARGS) goto mul_ovf;
- for (; i < (int)SP; i++) {
- if (__likely(isfixnum(Stack[i]))) {
- accum *= numval(Stack[i]);
- }
- else {
- mul_ovf:
- v = fl_mul_any(&Stack[i], SP-i, accum);
- SP = saveSP;
- return v;
- }
- }
- if (__likely(fits_fixnum(accum)))
- v = fixnum(accum);
- else
- v = return_from_int64(accum);
- break;
- case F_DIV:
- if (__unlikely(nargs < 1)) lerror(ArgError, "/: too few arguments");
- i = bp+2;
- if (nargs == 1) {
- v = fl_div2(fixnum(1), Stack[i]);
- }
- else {
- if (nargs > 2) {
- PUSH(Stack[i]);
- Stack[i] = fixnum(1);
- Stack[i+1] = fl_mul_any(&Stack[i], nargs, 1);
- Stack[i] = POP();
- }
- v = fl_div2(Stack[i], Stack[i+1]);
- }
- break;
- case F_COMPARE:
- argcount("compare", nargs, 2);
- v = compare(Stack[SP-2], Stack[SP-1]);
- break;
- case F_NUMEQ:
- argcount("=", nargs, 2);
- v = Stack[SP-2]; e = Stack[SP-1];
- if (bothfixnums(v, e)) {
- v = (v == e) ? FL_T : FL_F;
- }
- else {
- v = (!numeric_compare(v,e,1,0,"=")) ? FL_T : FL_F;
- }
- break;
- case F_LT:
- argcount("<", nargs, 2);
- if (bothfixnums(Stack[SP-2], Stack[SP-1])) {
- v = (numval(Stack[SP-2]) < numval(Stack[SP-1])) ? FL_T : FL_F;
- }
- else {
- v = (numval(compare(Stack[SP-2], Stack[SP-1])) < 0) ?
- FL_T : FL_F;
- }
- break;
- case F_EQUAL:
- argcount("equal?", nargs, 2);
- if (Stack[SP-2] == Stack[SP-1]) {
- v = FL_T;
- }
- else if (eq_comparable(Stack[SP-2],Stack[SP-1])) {
- v = FL_F;
- }
- else {
- v = (numval(compare(Stack[SP-2], Stack[SP-1]))==0) ?
- FL_T : FL_F;
- }
- break;
- case F_EQV:
- argcount("eqv?", nargs, 2);
- if (Stack[SP-2] == Stack[SP-1]) {
- v = FL_T;
- }
- else if (!leafp(Stack[SP-2]) || !leafp(Stack[SP-1])) {
- v = FL_F;
- }
- else {
- v = (numval(compare(Stack[SP-2], Stack[SP-1]))==0) ?
- FL_T : FL_F;
- }
- break;
- case F_EVAL:
- argcount("eval", nargs, 1);
- e = Stack[SP-1];
- if (selfevaluating(e)) { SP=saveSP; return e; }
- envsz = 2;
- if (tail) {
- assert((ulong_t)(penv-Stack)<N_STACK);
- penv[0] = NIL;
- penv[1] = NIL;
- SP = (penv-Stack) + 2;
- }
- else {
- PUSH(NIL);
- PUSH(NIL);
- tail = 1;
- penv = &Stack[SP-2];
- }
- goto eval_top;
- case F_SPECIAL_APPLY:
- POPN(2);
- v = POP();
- saveSP = SP;
- nargs = numval(v);
- bp = SP-nargs-2;
- f = Stack[bp+1];
- penv = &Stack[bp+1];
- goto do_apply;
- case F_APPLY:
- argcount("apply", nargs, 2);
- v = Stack[SP-1]; // second arg is new arglist
- f = Stack[bp+1] = Stack[SP-2]; // first arg is new function
- POPN(2); // pop apply's args
- move_args:
- while (iscons(v)) {
- if (SP-bp-2 == MAX_ARGS) {
- PUSH(v);
- break;
- }
- PUSH(car_(v));
- v = cdr_(v);
- }
- goto do_apply;
- case F_TRUE:
- case F_FALSE:
- case F_NIL:
- goto apply_type_error;
- default:
- // function pointer tagged as a builtin
- v = ((builtin_t)ptr(f))(&Stack[bp+2], nargs);
- }
- SP = saveSP;
- return v;
- }
- f = Stack[bp+1];
- assert((signed)SP > (signed)bp+1);
- if (isfunction(f)) {
- i = SP;
- e = apply_cl(nargs);
- SP = i;
- if (noeval == 2) {
- if (selfevaluating(e)) { SP=saveSP; return(e); }
- noeval = 0;
- goto eval_top;
- }
- else {
- SP = saveSP;
- return e;
- }
- }
- else if (__likely(iscons(f))) {
- // apply lambda expression
- f = Stack[bp+1] = cdr_(f);
- if (!iscons(f)) goto notpair;
- v = car_(f); // arglist
- i = nargs;
- while (iscons(v)) {
- if (i == 0)
- lerror(ArgError, "apply: too few arguments");
- i--;
- v = cdr_(v);
- }
- if (v == NIL) {
- if (i > 0)
- lerror(ArgError, "apply: too many arguments");
- }
- else {
- v = NIL;
- if (i > 0) {
- v = list(&Stack[SP-i], i);
- if (nargs > MAX_ARGS) {
- c = (cons_t*)curheap;
- (c-2)->cdr = (c-1)->car;
- }
- }
- Stack[SP-i] = v;
- SP -= (i-1);
- }
- f = cdr_(Stack[bp+1]);
- if (!iscons(f)) goto notpair;
- e = car_(f);
- if (selfevaluating(e)) { SP=saveSP; return(e); }
- PUSH(cdr_(f)); // add closed environment
- assert(Stack[SP-1]==NIL || isvector(Stack[SP-1]));
- Stack[bp+1] = car_(Stack[bp+1]); // put lambda list
-
- if (noeval == 2) {
- // macro: evaluate body in lambda environment
- e = eval_sexpr(e, &Stack[bp+1], 1, SP - bp - 1);
- if (selfevaluating(e)) { SP=saveSP; return(e); }
- noeval = 0;
- // macro: evaluate expansion in calling environment
- goto eval_top;
- }
- else {
- envsz = SP - bp - 1;
- if (tail) {
- // ok to overwrite environment
- for(i=0; i < (int)envsz; i++)
- penv[i] = Stack[bp+1+i];
- SP = (penv-Stack)+envsz;
- assert(penv[envsz-1]==NIL || isvector(penv[envsz-1]));
- goto eval_top;
- }
- else {
- penv = &Stack[bp+1];
- tail = 1;
- goto eval_top;
- }
- }
- // not reached
- }
- apply_type_error:
- type_error("apply", "function", f);
- notpair:
- lerror(TypeError, "expected cons");
- return NIL;
-}
-
/*
stack on entry: <func> <args...>
caller's responsibility:
@@ -1664,9 +854,6 @@
v = apply_cl(i);
}
}
- else if (iscons(func)) {
- v = _applyn(i);
- }
else {
type_error("apply", "function", func);
}
@@ -1789,10 +976,6 @@
POPN(i);
PUSH(v);
break;
- case OP_EVAL:
- v = toplevel_eval(POP());
- PUSH(v);
- break;
case OP_TAPPLY:
case OP_APPLY:
@@ -1918,7 +1101,7 @@
PUSH(v);
}
break;
- case F_NUMEQ:
+ case OP_NUMEQ:
v = Stack[SP-2]; e = Stack[SP-1];
if (bothfixnums(v, e)) {
v = (v == e) ? FL_T : FL_F;
@@ -1953,9 +1136,11 @@
}
else i = 0;
v = alloc_vector(n+i, 0);
- memcpy(&vector_elt(v,0), &Stack[SP-n], n*sizeof(value_t));
- e = POP();
- POPN(n-1);
+ if (n) {
+ memcpy(&vector_elt(v,0), &Stack[SP-n], n*sizeof(value_t));
+ e = POP();
+ POPN(n-1);
+ }
if (n > MAX_ARGS) {
i = n-1;
while (iscons(e)) {
@@ -2155,7 +1340,7 @@
break;
case OP_TRYCATCH:
- v = do_trycatch2();
+ v = do_trycatch();
POPN(1);
Stack[SP-1] = v;
break;
@@ -2183,10 +1368,27 @@
(void)princ;
function_t *fn = value2c(function_t*,v);
outs("#function(", f);
- int newindent = HPOS;
- fl_print_child(f, fn->bcode, 0); outindent(newindent, f);
- fl_print_child(f, fn->vals, 0); outindent(newindent, f);
- fl_print_child(f, fn->env, 0);
+ char *data = cvalue_data(fn->bcode);
+ size_t sz = cvalue_len(fn->bcode);
+ outc('"', f);
+ size_t i; uint8_t c;
+ for(i=0; i < sz; i++) {
+ c = data[i];
+ if (c == '\\')
+ outsn("\\\\", f, 2);
+ else if (c == '"')
+ outsn("\\\"", f, 2);
+ else if (c >= 32 && c < 0x7f)
+ outc(c, f);
+ else
+ ios_printf(f, "\\x%02x", c);
+ }
+ outsn("\" ", f, 2);
+ fl_print_child(f, fn->vals, 0);
+ if (fn->env != NIL) {
+ outc(' ', f);
+ fl_print_child(f, fn->env, 0);
+ }
outc(')', f);
}
@@ -2300,21 +1502,14 @@
forsym = symbol("for");
labelsym = symbol("label");
setqsym = symbol("set!");
- elsesym = symbol("else");
+ evalsym = symbol("eval");
tsym = symbol("t"); Tsym = symbol("T");
fsym = symbol("f"); Fsym = symbol("F");
set(printprettysym=symbol("*print-pretty*"), FL_T);
set(printwidthsym=symbol("*print-width*"), fixnum(SCR_WIDTH));
lasterror = NIL;
- special_apply_form = fl_cons(builtin(F_SPECIAL_APPLY), NIL);
- apply1_args = fl_cons(NIL, NIL);
i = 0;
- while (isspecial(builtin(i))) {
- if (i != F_SPECIAL_APPLY)
- ((symbol_t*)ptr(symbol(builtin_names[i])))->syntax = builtin(i);
- i++;
- }
- for (; i < F_TRUE; i++) {
+ for (i=F_EQ; i < F_TRUE; i++) {
setc(symbol(builtin_names[i]), builtin(i));
}
setc(symbol("eq"), builtin(F_EQ));
@@ -2321,13 +1516,13 @@
setc(symbol("equal"), builtin(F_EQUAL));
#ifdef LINUX
- set(symbol("*os-name*"), symbol("linux"));
+ setc(symbol("*os-name*"), symbol("linux"));
#elif defined(WIN32) || defined(WIN64)
- set(symbol("*os-name*"), symbol("win32"));
+ setc(symbol("*os-name*"), symbol("win32"));
#elif defined(MACOSX)
- set(symbol("*os-name*"), symbol("macos"));
+ setc(symbol("*os-name*"), symbol("macos"));
#else
- set(symbol("*os-name*"), symbol("unknown"));
+ setc(symbol("*os-name*"), symbol("unknown"));
#endif
cvalues_init();
@@ -2343,6 +1538,9 @@
memory_exception_value = list2(MemoryError,
cvalue_static_cstring("out of memory"));
+ the_empty_vector = tagptr(alloc_words(1), TAG_VECTOR);
+ vector_setsize(the_empty_vector, 0);
+
functiontype = define_opaque_type(FUNCTION, sizeof(function_t),
&function_vtable, NULL);
@@ -2357,9 +1555,9 @@
{
value_t v;
uint32_t saveSP = SP;
- PUSH(NIL);
- PUSH(NIL);
- v = topeval(expr, &Stack[SP-2]);
+ PUSH(symbol_value(evalsym));
+ PUSH(expr);
+ v = apply_cl(1);
SP = saveSP;
return v;
}
@@ -2383,6 +1581,8 @@
int main(int argc, char *argv[])
{
value_t e, v;
+ int saveSP;
+ symbol_t *sym;
char fname_buf[1024];
locale_is_utf8 = u8_is_locale_utf8(setlocale(LC_ALL, ""));
@@ -2394,7 +1594,7 @@
strcat(fname_buf, EXEDIR);
strcat(fname_buf, PATHSEPSTRING);
}
- strcat(fname_buf, "system.lsp");
+ strcat(fname_buf, "flisp.boot");
FL_TRY {
// install toplevel exception handler
@@ -2402,11 +1602,22 @@
PUSH(symbol(":read"));
value_t f = fl_file(&Stack[SP-2], 2);
POPN(2);
- PUSH(f);
+ PUSH(f); saveSP = SP;
while (1) {
e = read_sexpr(Stack[SP-1]);
if (ios_eof(value2c(ios_t*,Stack[SP-1]))) break;
- v = toplevel_eval(e);
+ if (isfunction(e)) {
+ // stage 0 format: series of thunks
+ PUSH(e);
+ (void)_applyn(0);
+ SP = saveSP;
+ }
+ else {
+ // stage 1 format: symbol/value pairs
+ sym = tosymbol(e, "bootstrap");
+ v = read_sexpr(Stack[SP-1]);
+ sym->binding = v;
+ }
}
ios_close(value2c(ios_t*,Stack[SP-1]));
POPN(1);
--- a/femtolisp/flisp.h
+++ b/femtolisp/flisp.h
@@ -117,16 +117,12 @@
(arg = args[i])) || 1)); i++)
enum {
- // special forms
- F_QUOTE=0, F_COND, F_IF, F_AND, F_OR, F_WHILE, F_LAMBDA,
- F_TRYCATCH, F_SPECIAL_APPLY, F_SETQ, F_PROG1, F_FOR, F_BEGIN,
-
// functions
- F_EQ, F_EQV, F_EQUAL, F_ATOM, F_NOT, F_NULL, F_BOOLEANP, F_SYMBOLP,
+ F_EQ=13, F_EQV, F_EQUAL, F_ATOM, F_NOT, F_NULL, F_BOOLEANP, F_SYMBOLP,
F_NUMBERP, F_BOUNDP, F_CONSP, F_BUILTINP, F_VECTORP, F_FIXNUMP,
F_CONS, F_LIST, F_CAR, F_CDR, F_SETCAR, F_SETCDR,
- F_EVAL, F_APPLY,
+ F_APPLY,
F_ADD, F_SUB, F_MUL, F_DIV, F_NUMEQ, F_LT, F_COMPARE,
F_VECTOR, F_AREF, F_ASET,
@@ -133,7 +129,6 @@
F_TRUE, F_FALSE, F_NIL,
N_BUILTINS
};
-#define isspecial(v) (uintval(v) <= (unsigned int)F_BEGIN)
extern value_t NIL, FL_T, FL_F;
@@ -247,6 +242,7 @@
#define cv_isPOD(cv) (cv_class(cv)->init != NULL)
#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 valid_numtype(v) ((v) < N_NUMTYPES)
--- a/femtolisp/opcodes.h
+++ b/femtolisp/opcodes.h
@@ -10,7 +10,7 @@
OP_FIXNUMP,
OP_CONS, OP_LIST, OP_CAR, OP_CDR, OP_SETCAR, OP_SETCDR,
- OP_EVAL, OP_APPLY,
+ OP_APPLY,
OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_NUMEQ, OP_LT, OP_COMPARE,
--- a/femtolisp/print.c
+++ b/femtolisp/print.c
@@ -72,7 +72,8 @@
return;
}
if (isvector(v)) {
- mark_cons(v);
+ if (vector_size(v) > 0)
+ mark_cons(v);
unsigned int i;
for(i=0; i < vector_size(v); i++)
print_traverse(vector_elt(v,i));
@@ -225,8 +226,7 @@
value_t c = car_(v);
if (c == LAMBDA || c == labelsym || c == setqsym)
return 0;
- value_t f;
- if (issymbol(c) && (f=((symbol_t*)ptr(c))->syntax) && isspecial(f))
+ if (c == IF) // TODO: others
return !allsmallp(cdr_(v));
return 0;
}
--- a/femtolisp/read.c
+++ b/femtolisp/read.c
@@ -346,7 +346,7 @@
static value_t read_vector(value_t label, u_int32_t closer)
{
- value_t v=alloc_vector(4, 1), elt;
+ value_t v=the_empty_vector, elt;
u_int32_t i=0;
PUSH(v);
if (label != UNBOUND)
@@ -354,7 +354,12 @@
while (peek() != closer) {
if (ios_eof(F))
lerror(ParseError, "read: unexpected end of input");
- if (i >= vector_size(v))
+ if (i == 0) {
+ v = Stack[SP-1] = alloc_vector(4, 1);
+ if (label != UNBOUND)
+ ptrhash_put(&readstate->backrefs, (void*)label, (void*)v);
+ }
+ else if (i >= vector_size(v))
Stack[SP-1] = vector_grow(v);
elt = do_read_sexpr(UNBOUND);
v = Stack[SP-1];
@@ -362,7 +367,8 @@
i++;
}
take();
- vector_setsize(v, i);
+ if (i > 0)
+ vector_setsize(v, i);
return POP();
}
--- a/femtolisp/system.lsp
+++ b/femtolisp/system.lsp
@@ -11,6 +11,11 @@
((eq (cdr e) ()) (car e))
(#t (cons 'begin e)))))
+(set! *syntax-environment* (table))
+
+(set! set-syntax!
+ (lambda (s v) (put! *syntax-environment* s v)))
+
(set-syntax! 'define-macro
(lambda (form . body)
(list 'set-syntax! (list 'quote (car form))
@@ -21,6 +26,8 @@
(list 'set! form (car body))
(list 'set! (car form) (list 'lambda (cdr form) (f-body body)))))
+(define (symbol-syntax s) (get *syntax-environment* s #f))
+
(define (map f lst)
(if (atom? lst) lst
(cons (f (car lst)) (map f (cdr lst)))))
@@ -417,7 +424,6 @@
first)))
(define (iota n) (map-int identity n))
-(define ι iota)
(define (for-each f l)
(if (pair? l)
@@ -482,16 +488,6 @@
; text I/O --------------------------------------------------------------------
-(if (or (eq? *os-name* 'win32)
- (eq? *os-name* 'win64)
- (eq? *os-name* 'windows))
- (begin (define *directory-separator* "\\")
- (define *linefeed* "\r\n"))
- (begin (define *directory-separator* "/")
- (define *linefeed* "\n")))
-
-(define *output-stream* *stdout*)
-(define *input-stream* *stdin*)
(define (print . args) (apply io.print (cons *output-stream* args)))
(define (princ . args) (apply io.princ (cons *output-stream* args)))
@@ -512,8 +508,6 @@
(set! l (cons (aref v (- n i)) l))))
l))
-(define (vu8 . elts) (apply array (cons 'uint8 elts)))
-
(define (vector.map f v)
(let* ((n (length v))
(nv (vector.alloc n)))
@@ -610,7 +604,7 @@
; toplevel --------------------------------------------------------------------
(define (macrocall? e) (and (symbol? (car e))
- (symbol-syntax (car e))))
+ (get *syntax-environment* (car e) #f)))
(define (macroexpand-1 e)
(if (atom? e) e
@@ -650,9 +644,10 @@
(define (expand x) (macroexpand x))
-(if (not (bound? 'load-process))
- (define (load-process x) (eval (expand x))))
+(define (eval x) ((compile-thunk (expand x))))
+(define (load-process x) (eval x))
+
(define (load filename)
(let ((F (file filename :read)))
(trycatch
@@ -669,9 +664,6 @@
(io.close F)
(raise `(load-error ,filename ,e)))))))
-(load (string *install-dir* *directory-separator* "compiler.lsp"))
-(define (load-process x) ((compile-thunk (expand x))))
-
(define *banner* (string.tail "
; _
; |_ _ _ |_ _ | . _ _
@@ -738,6 +730,31 @@
(io.princ *stderr* *linefeed*)
#t)
+(define (make-system-image fname)
+ (let ((f (file fname :write :create :truncate)))
+ (for-each (lambda (s)
+ (if (and (bound? s)
+ (not (constant? s))
+ (not (builtin? (top-level-value s)))
+ (not (iostream? (top-level-value s))))
+ (begin
+ (io.print f s) (io.write f "\n")
+ (io.print f (top-level-value s)) (io.write f "\n"))))
+ (environment))
+ (io.close f)))
+
+; initialize globals that need to be set at load time
+(define (__init_globals)
+ (if (or (eq? *os-name* 'win32)
+ (eq? *os-name* 'win64)
+ (eq? *os-name* 'windows))
+ (begin (set! *directory-separator* "\\")
+ (set! *linefeed* "\r\n"))
+ (begin (set! *directory-separator* "/")
+ (set! *linefeed* "\n")))
+ (set! *output-stream* *stdout*)
+ (set! *input-stream* *stdin*))
+
(define (__script fname)
(trycatch (load fname)
(lambda (e) (begin (print-exception e)
@@ -744,8 +761,7 @@
(exit 1)))))
(define (__start argv)
- ; reload this file with our new definition of load
- (load (string *install-dir* *directory-separator* "system.lsp"))
+ (__init_globals)
(if (pair? (cdr argv))
(begin (set! *argv* (cdr argv))
(__script (cadr argv)))
--- a/femtolisp/table.c
+++ b/femtolisp/table.c
@@ -85,7 +85,7 @@
{
size_t cnt = (size_t)nargs;
if (nargs > MAX_ARGS)
- cnt += llength(args[MAX_ARGS]);
+ cnt += (llength(args[MAX_ARGS])-1);
if (cnt & 1)
lerror(ArgError, "table: arguments must come in pairs");
value_t nt;