--- old/CHANGELOG Sat Aug 13 20:44:19 2005 +++ CHANGELOG Fri Aug 26 07:14:19 2005 @@ -48,3 +48,10 @@ Changed dprint to allow for multiple arguments. Removed many uses of real_eqv as eqv? words are now eq?. Implemented eqv? in preload.lisp and removed it from the .h and .c's. + +2005-08-26: 1.6: Modified eqv? to not need the short-circuit macro. +Added #let function and let macro. +Added const to char* in the store_builtin_* #defines. +Removed define-local. +Changed define_local into real_define and made it not decref its arguments. +Removed subscope. --- old/Makefile Fri Aug 12 13:49:53 2005 +++ Makefile Fri Aug 26 07:12:28 2005 @@ -3,7 +3,7 @@ CFLAGS=-O2 -Wall -Werror SRCS=builtin.c cons.c func.c integer.c main.c nil.c quote.c rawfunc.c reader.c scope.c stream.c string.c throw.c util.c word.c BUILDDIR=obj/ -VERSION=1.5 +VERSION=1.6 -include .local.Makefile $(BUILDDIR)mikelisp : $(SRCS:%.c=$(BUILDDIR)%.o) lisp.h --- old/lisp.h Sat Aug 13 20:41:37 2005 +++ lisp.h Fri Aug 26 00:54:43 2005 @@ -1,4 +1,4 @@ -/* lisp.h by Michael Thorpe 2005-08-13 */ +/* lisp.h by Michael Thorpe 2005-08-26 */ #ifndef OBJ_H #define OBJ_H @@ -116,19 +116,19 @@ void drop_scope(scope *scope); #define decscoperef(s) do{if(!--(s)->refcount)drop_scope(s);}while(0) obj *define(scope *scope,obj *name,obj *value); -obj *define_local(scope *scope,obj *name,obj *value); #define incscoperef(s) ((s)->refcount++,(s)) obj *lookup(scope *scope,obj *name); scope *newscope(scope *parent); +int real_define(scope *scope,obj *name,obj *value); int store_builtin(unsigned int numargs,unsigned int wantscope,const char *name,obj *(*rawfunc)()); -#define store_builtin_ns0(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)()))store_builtin)(0,0,name,func) -#define store_builtin_ns1(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(obj *)))store_builtin)(1,0,name,func) -#define store_builtin_ns2(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(obj *,obj *)))store_builtin)(2,0,name,func) -#define store_builtin_ns3(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(obj *,obj *,obj *)))store_builtin)(3,0,name,func) -#define store_builtin_s0(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(scope *)))store_builtin)(0,1,name,func) -#define store_builtin_s1(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(scope *,obj *)))store_builtin)(1,1,name,func) -#define store_builtin_s2(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(scope *,obj *,obj *)))store_builtin)(2,1,name,func) -#define store_builtin_s3(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,char *,obj *(*)(scope *,obj *,obj *,obj *)))store_builtin)(3,1,name,func) +#define store_builtin_ns0(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)()))store_builtin)(0,0,name,func) +#define store_builtin_ns1(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(obj *)))store_builtin)(1,0,name,func) +#define store_builtin_ns2(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(obj *,obj *)))store_builtin)(2,0,name,func) +#define store_builtin_ns3(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(obj *,obj *,obj *)))store_builtin)(3,0,name,func) +#define store_builtin_s0(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(scope *)))store_builtin)(0,1,name,func) +#define store_builtin_s1(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(scope *,obj *)))store_builtin)(1,1,name,func) +#define store_builtin_s2(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(scope *,obj *,obj *)))store_builtin)(2,1,name,func) +#define store_builtin_s3(name,func) ((int (*)(unsigned int numargs,unsigned int wantscope,const char *,obj *(*)(scope *,obj *,obj *,obj *)))store_builtin)(3,1,name,func) int store_object(const char *name,obj *o); extern scope *globalscope; #ifdef DEBUG --- old/builtin.c Sat Aug 13 20:41:51 2005 +++ builtin.c Fri Aug 26 07:13:33 2005 @@ -1,4 +1,4 @@ -/* builtin.c by Michael Thorpe 2005-08-13 */ +/* builtin.c by Michael Thorpe 2005-08-26 */ #include #include @@ -245,10 +245,8 @@ for(new=list;&cons_objtype==new->type;new=new->value.c.d) length++; if(!length) { - tmp=define_local(incscoperef(s),incref(mapvar),incref(list)); - if(!tmp) + if(real_define(s,mapvar,list)) goto fail_nostart; - decref(tmp); decref(list); return(evaluate(s,expr)); } @@ -258,10 +256,8 @@ new=start; old=list; while(1) { - tmp=define_local(incscoperef(s),incref(mapvar),incref(CAR(old))); - if(!tmp) + if(real_define(s,mapvar,CAR(old))) goto fail; - decref(tmp); tmp=evaluate(incscoperef(s),incref(expr)); if(!tmp) goto fail; @@ -273,10 +269,8 @@ new=CDR(new); } if(&nilobj != old) { - tmp=define_local(incscoperef(s),incref(mapvar),incref(old)); - if(!tmp) + if(real_define(s,mapvar,old)) goto fail; - decref(tmp); tmp=evaluate(incscoperef(s),incref(expr)); if(!tmp) goto fail; @@ -403,14 +397,6 @@ return((o)->type->tostring(o)); } -static obj *subscope(scope *s,obj *o) { - s=newscope(s); - if(s) - return(evaluate(s,o)); - decref(o); - return(0); -} - int builtin_init() { if(!(divideby0error=newword("divide-by-zero",14)) || !(exitloop=newword("exit-loop",9)) @@ -440,8 +426,7 @@ || store_builtin_s1("#loop",loop) || store_builtin_s2("#map",map) || store_builtin_s2("#prog2of2",prog2of2) - || store_builtin_ns1("->string",tostring) - || store_builtin_s1("#subscope",subscope)) + || store_builtin_ns1("->string",tostring)) return(1); INC_KNOWN_OBJECTS(5); return(0); --- old/func.c Sat Aug 13 20:42:09 2005 +++ func.c Fri Aug 26 00:54:44 2005 @@ -1,12 +1,10 @@ -/* func.c by Michael Thorpe 2005-08-13 */ +/* func.c by Michael Thorpe 2005-08-26 */ #include #include "lisp.h" /* This function does not incref/decref anything; returns 0 on success */ static int bindlist(scope *s,obj *names,obj *values) { - obj *tmp; - if(names==&nilobj) { if(values==&nilobj) return(0); @@ -19,12 +17,7 @@ return(-1); return(bindlist(s,CDR(names),CDR(values))); } - tmp=define_local(incscoperef(s),incref(names),incref(values)); - if(tmp) { - decref(tmp); - return(0); - } - return(-1); + return(real_define(s,names,values)); } static obj *applyfunc(scope *s,obj *func,obj *args) { --- old/scope.c Sat Aug 13 19:57:11 2005 +++ scope.c Fri Aug 26 00:54:43 2005 @@ -1,4 +1,4 @@ -/* scope.c by Michael Thorpe 2005-08-13 */ +/* scope.c by Michael Thorpe 2005-08-26 */ #include #include @@ -40,32 +40,18 @@ entry *e; e=real_lookup(s,name); + decscoperef(s); if(e) { decref(e->value); e->value=value; - decscoperef(s); return(name); } - incscoperef(globalscope); - decscoperef(s); - return(define_local(globalscope,name,value)); -} - -obj *define_local(scope *s,obj *name,obj *value) { - entry *e; - - e=(entry *)malloc(sizeof(entry)); - if(!e) { - decscoperef(s); - decref(name); + if(real_define(globalscope,name,value)) { decref(value); - return(throwoom()); + decref(name); + return(0); } - e->next=s->firstentry; - e->name=incref(name); - e->value=value; - s->firstentry=e; - decscoperef(s); + decref(value); return(name); } @@ -93,6 +79,29 @@ decscoperef(t); } +static obj *let(scope *scope,obj *var,obj *val,obj *block) { + /* We can short-circuit the scope creation if its refcount is 1: */ + if(1 != scope->refcount) { + scope=newscope(scope); + if(!scope) { + decref(var); + decref(val); + decref(block); + return(0); + } + } + if(real_define(scope,var,val)) { + decref(var); + decref(val); + decscoperef(scope); + decref(block); + return(0); + } + decref(var); + decref(val); + return(evaluate(scope,block)); +} + obj *lookup(scope *scope,obj *name) { entry *e; obj *val; @@ -128,8 +137,24 @@ return(new); } +int real_define(scope *s,obj *name,obj *value) { + entry *e; + + e=(entry *)malloc(sizeof(entry)); + if(!e) { + throwoom(); + return(-1); + } + e->next=s->firstentry; + e->name=incref(name); + e->value=incref(value); + s->firstentry=e; + return(0); +} + int store_builtin(unsigned int numargs,unsigned int wantscope,const char *name,obj *(*rawfunc)()) { obj *key,*func; + int i; key=newword(name,strlen(name)); if(!key) @@ -142,31 +167,30 @@ func->value.rawfunc.numargs=numargs; func->value.rawfunc.wantscope=wantscope; func->value.rawfunc.rawfuncptr.ns0=rawfunc; - key=define_local(incscoperef(globalscope),key,func); - if(!key) - return(-1); + i=real_define(globalscope,key,func); decref(key); - return(0); + decref(func); + return(i); } int store_object(const char *name,obj *o) { obj *key; + int i; key=newword(name,strlen(name)); if(!key) return(-1); - key=define_local(incscoperef(globalscope),key,o); - if(!key) - return(-1); + i=real_define(globalscope,key,o); decref(key); - return(0); + decref(o); + return(i); } int scope_init() { if(!(globalscope=newscope(incscoperef(&topscope))) || !(undefined_error=newword("undefined",9)) || store_builtin_s2("#define",define) - || store_builtin_s2("#define-local",define_local)) + || store_builtin_s3("#let",let)) return(1); INC_KNOWN_OBJECTS(1); return(0); --- old/throw.c Sat Aug 13 19:58:15 2005 +++ throw.c Fri Aug 26 00:54:44 2005 @@ -1,4 +1,4 @@ -/* throw.c by Michael Thorpe 2005-08-13 */ +/* throw.c by Michael Thorpe 2005-08-26 */ #include "lisp.h" @@ -12,7 +12,7 @@ obj *exceptionvar,*exceptionvaluevar; static obj *catch(scope *s,obj *type,obj *func,obj *handler) { - obj *e,*o,*tmp; + obj *e,*o; o=evaluate(incscoperef(s),func); if(!o && (type==exception || type==&nilobj)) { @@ -24,22 +24,22 @@ } e=exception; exception=incref(&nilobj); - tmp=define_local(incscoperef(s),incref(exceptionvar),e); - if(!tmp) { + if(real_define(s,exceptionvar,e)) { + decref(e); decscoperef(s); decref(handler); return(0); } - decref(tmp); + decref(e); e=exceptionvalue; exceptionvalue=incref(&nilobj); - tmp=define_local(incscoperef(s),incref(exceptionvaluevar),e); - if(!tmp) { + if(real_define(s,exceptionvaluevar,e)) { + decref(e); decscoperef(s); decref(handler); return(0); } - decref(tmp); + decref(e); return(evaluate(s,handler)); } decref(type); --- old/preload.lisp Sat Aug 13 20:40:44 2005 +++ preload.lisp Fri Aug 26 07:13:07 2005 @@ -1,4 +1,4 @@ -; preload.lisp by Michael Thorpe 2005-08-13 +; preload.lisp by Michael Thorpe 2005-08-26 (#define '#f (= 1 2)) (#define '#t (= 1 1)) @@ -20,16 +20,13 @@ (#lambda '(o) '(#ifelse (pair? o) '(#prog2of2 - (#prog2of2 - (#define-local 'macro (get macroexpansions (car o))) + (#let 'macro (get macroexpansions (car o)) '(#ifelse macro - '(#prog2of2 - (#prog2of2 - (#define-local 'cdr-o (cdr o)) - '(#define-local 'expansion (macro . cdr-o))) - '(#ifelse (eq? expansion dont-macro-expand) - '#f - '(#define-local 'o (macro-expand expansion)))) + '(#let 'cdr-o (cdr o) + '(#let 'expansion (macro . cdr-o) + '(#ifelse (eq? expansion dont-macro-expand) + '#f + '(#define 'o (macro-expand expansion))))) '#f)) '(#map '(macro-expand #object) o)) 'o))) @@ -44,14 +41,18 @@ '(#ifelse (pair? name) '(list '#define (quote (car name)) (list 'lambda (cdr name) (cons 'progn value))) '(list '#define (quote name) . value)))) -(#macro-define 'define-local - (#lambda '(name . value) - '(#ifelse (pair? name) - '(list '#define-local (quote (car name)) (list 'lambda (cdr name) (cons 'progn value))) - '(list '#define-local (quote name) . value)))) (#macro-define 'lambda (#lambda '(args . prog) '(list '#lambda (quote args) (quote (macro-expand (cons 'progn prog)))))) +(#macro-define 'let + (#lambda '(vars . prog) + '(#ifelse (pair? vars) + '(list + '#let + (quote (car (car vars))) + (cons 'progn (cdr (car vars))) + (quote (macro-expand (cons 'let (cons (cdr vars) prog))))) + '(cons 'progn prog)))) (#macro-define 'macro-define (#lambda '(name . value) '(#ifelse (pair? name) @@ -81,9 +82,6 @@ (#macro-define 'map (#lambda '(mapper . args) '(list '#map (quote (macro-expand mapper)) . args))) -(#macro-define 'subscope - (#lambda 'body - '(list '#subscope (quote (macro-expand (cons 'progn body)))))) (#define 'evaluate-file (#lambda '(file) @@ -131,19 +129,14 @@ (list 'ifelse bool (cons 'progn progs) #f)) -(macro-define (let* bindings . body) - (ifelse bindings - (list 'progn - (list 'define-local (car (car bindings)) (cons 'progn (cdr (car bindings)))) - (cons 'let* (cons (cdr bindings) body))) - (cons 'progn body))) (macro-define (next-loop) (list 'throw ''next-loop #f)) (macro-define (not a) (list 'ifelse a #f #t)) (macro-define (or a . b) (ifelse b - (list 'subscope - (list 'define-local 'a a) - (list 'ifelse 'a 'a (cons 'or b))) + (let ((var (unique-word))) + (list 'let + (list (list var a)) + (list 'ifelse var var (cons 'or b)))) a)) (macro-define (unless bool . body) (list 'ifelse bool @@ -157,8 +150,8 @@ (define (reverse/append straight newtail) (while straight - (define-local newtail (cons (car straight) newtail)) - (define-local straight (cdr straight))) + (define newtail (cons (car straight) newtail)) + (define straight (cdr straight))) newtail) (define (reverse straight) (reverse/append straight '())) @@ -172,7 +165,7 @@ (define (dprint . o) (while o (write-object #standard-out (car o)) - (define-local o (cdr o)) + (define o (cdr o)) (if o (write-char #standard-out 32))) (write-newline #standard-out) @@ -210,10 +203,10 @@ (define hash (cdr hash)))) (define (expand-string oldstring) - (define-local newstring (new-string (+ 512 (string-length oldstring)))) - (define-local i 0) - (while (< i (string-length oldstring)) - (put-char newstring i (get-char oldstring i))) + (let ((i 0) + (newstring (new-string (+ 512 (string-length oldstring))))) + (while (< i (string-length oldstring)) + (put-char newstring i (get-char oldstring i)))) newstring) (define (macro-singlequote stream) @@ -226,30 +219,29 @@ ; token if it's not a close parenthesis (define (submacro-dot stream) (catch 'end-of-file - (progn - (define-local o (read-object stream)) + (let ((o (read-object stream))) (ifelse (not (eq? ') (read-object stream))) (throw 'reader-error stream) o)) (throw 'reader-error stream))) (define (macro-openparen stream) - (define-local reverse-list '()) - (define-local new-list '()) - (catch 'end-of-file - (loop - (define-local o (read-object stream)) - (ifelse (eq? o ')) - (exit-loop) - (ifelse (eq? o '.) - (ifelse reverse-list - (progn - (define-local new-list (submacro-dot stream)) - (exit-loop)) - (throw 'reader-error stream)) - (define-local reverse-list (cons o reverse-list))))) - (throw 'reader-error stream)) - (reverse/append reverse-list new-list)) + (let ((reverse-list '()) + (new-list '())) + (catch 'end-of-file + (loop + (let ((o (read-object stream))) + (ifelse (eq? o ')) + (exit-loop) + (ifelse (eq? o '.) + (ifelse reverse-list + (progn + (define new-list (submacro-dot stream)) + (exit-loop)) + (throw 'reader-error stream)) + (define reverse-list (cons o reverse-list)))))) + (throw 'reader-error stream)) + (reverse/append reverse-list new-list))) (define-character-macro 40 macro-openparen) (define (macro-closeparen stream) @@ -263,9 +255,9 @@ (define-character-macro 44 macro-comma) (define (macro-semicolon stream) - (define-local c 0) - (while (and (<> c 10) (<> c 13)) - (define-local c (read-char stream))) + (let ((c 0)) + (while (and (<> c 10) (<> c 13)) + (define c (read-char stream)))) (read-object stream)) (define-character-macro 59 macro-semicolon) @@ -282,15 +274,14 @@ ; (ifelse (pair? obj) ; (ifelse (eq? unquote-identifier (car obj)) ; (cdr obj) -; (progn -; (define-local stack '(list)) -; (define-local newtail '()) +; (let ((stack '(list)) +; (newtail '())) ; (while obj ; (if (eq? unquote-identifier (car obj)) -; (define-local newtail (cdr obj)) +; (define newtail (cdr obj)) ; (exit-loop)) -; (define-local stack (cons (quasiquote (car obj)) stack)) -; (define-local obj (cdr obj))) +; (define stack (cons (quasiquote (car obj)) stack)) +; (define obj (cdr obj))) ; (reverse/append stack newtail))) ; (quote obj)) ; obj)) @@ -312,61 +303,61 @@ (define-character-macro 96 macro-backtick) (define (macro-doublequote stream) - (define-local string (new-string 512)) - (define-local i 0) - (define-local c 0) - (loop - (if (= i (string-length string)) - (define-local string (expand-string string))) - (define-local c - (catch 'end-of-file - (read-char stream) - (throw 'reader-error stream))) - (if (= c 34) ; 34 = ASCII double quote - (exit-loop)) - (if (= c 92) ; 92 = ASCII backslash - (define-local c + (let ((c 0) + (i 0) + (string (new-string 512))) + (loop + (if (= i (string-length string)) + (define string (expand-string string))) + (define c (catch 'end-of-file (read-char stream) - (throw 'reader-error stream)))) - (put-char string i c) - (define-local i (+ i 1))) - (substring string 0 i)) + (throw 'reader-error stream))) + (if (= c 34) ; 34 = ASCII double quote + (exit-loop)) + (if (= c 92) ; 92 = ASCII backslash + (define c + (catch 'end-of-file + (read-char stream) + (throw 'reader-error stream)))) + (put-char string i c) + (define i (+ i 1))) + (substring string 0 i))) (define-character-macro 34 macro-doublequote) (define (read-token stream c) - (define-local buffer (new-string 512)) - (define-local i 0) - (loop - (if (= i (string-length buffer)) - (define-local buffer (expand-string buffer))) - (put-char buffer i c) - (define-local i (+ i 1)) - (catch 'end-of-file - (define-local c (peek-char stream)) - (exit-loop)) - (if (isspace c) - (exit-loop)) - (unless (isascii c) - (exit-loop)) - (if (get-using-= character-macros c) - (exit-loop)) - (define-local c (read-char stream))) - (define buffer (substring buffer 0 i)) - (catch 'type-error - (string->integer buffer) - (string->symbol buffer))) + (let ((buffer (new-string 512)) + (i 0)) + (loop + (if (= i (string-length buffer)) + (define buffer (expand-string buffer))) + (put-char buffer i c) + (define i (+ i 1)) + (catch 'end-of-file + (define c (peek-char stream)) + (exit-loop)) + (if (isspace c) + (exit-loop)) + (unless (isascii c) + (exit-loop)) + (if (get-using-= character-macros c) + (exit-loop)) + (define c (read-char stream))) + (define buffer (substring buffer 0 i)) + (catch 'type-error + (string->integer buffer) + (string->symbol buffer)))) (define (read-object stream) - (define-local c 32) ; 32 = ASCII space - (while (isspace c) - (define-local c (read-char stream))) - (unless (isascii c) - (throw 'reader-error stream)) - (define macro (get-using-= character-macros c)) - (ifelse macro - (macro stream) - (read-token stream c))) + (let ((c 32)) ; 32 = ASCII space + (while (isspace c) + (define c (read-char stream))) + (unless (isascii c) + (throw 'reader-error stream)) + (define macro (get-using-= character-macros c)) + (ifelse macro + (macro stream) + (read-token stream c)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Some more utility routines ;;; @@ -385,6 +376,53 @@ (macro-define (cddar o) `(cdr (cdr (car ,o)))) (macro-define (cdddr o) `(cdr (cdr (cdr ,o)))) +(define (cars arg) ; ((1 2) (3 4)) => (1 3) + (let ((stack '())) + (while arg + (define stack (cons (caar arg) stack)) + (define arg (cdr arg))) + (reverse stack))) +(define (cdrs arg) ; ((1 2) (3 4)) => ((2) (4)) + (let ((stack '())) + (while arg + (define stack (cons (cdar arg) stack)) + (define arg (cdr arg))) + (reverse stack))) +(define (cadrs arg) ; ((1 2) (3 4)) => (2 4) + (let ((stack '())) + (while arg + (define stack (cons (cadar arg) stack)) + (define arg (cdr arg))) + (reverse stack))) + +(define (string-eqv? a b) + (let ((c (string-length a))) + (ifelse (= c (string-length b)) + (loop + (if (= c 0) + (exit-loop #t)) + (define c (- c 1)) + (if (<> (get-char a c) (get-char b c)) + (exit-loop #f))) + #f))) +(define (eqv? a b) + (let ((ot-a (object-type a))) + (ifelse (eq? a b) + #t + (ifelse (not (eq? ot-a (object-type b))) + #f + (ifelse (eq? ot-a 'integer) + (= a b) + (ifelse (eq? ot-a 'quote) + (eqv? (evaluate a) (evaluate b)) + (ifelse (eq? ot-a 'string) + (string-eqv? a b) + (ifelse (eq? ot-a 'cons) + (and + (eqv? (car a) (car b)) + (eqv? (cdr a) (cdr b))) + #f)))))))) + ; ; switch (takes the place of case) ; @@ -409,67 +447,10 @@ (switch-handle var (cdr cases)))) #f)) (macro-define (switch key . cases) - (define-local var (unique-word)) - `(progn - (define-local ,var ,key) - ,(switch-handle var cases))) - -(define (string-equivalent a b) - (define-local c (string-length a)) - (ifelse (= c (string-length b)) - (loop - (if (= c 0) - (exit-loop #t)) - (define-local c (- c 1)) - (if (<> (get-char a c) (get-char b c)) - (exit-loop #f))) - #f)) -; This short-circuit macro is necessary to prevent switch/eqv? from getting -; into an endless mutual recursion loop: -(macro-define (eqv? a b) - (ifelse - (or - (and (eq? 'quote (object-type a)) (eq? 'word (object-type (evaluate a)))) - (and (eq? 'quote (object-type b)) (eq? 'word (object-type (evaluate b))))) - (list 'eq? a b) - dont-macro-expand)) -(define (eqv? a b) - (ifelse (eq? a b) - #t - (ifelse (eq? (object-type a) (object-type b)) - (switch (object-type a) - (('integer) - (= a b)) - (('cons) - (and - (eqv? (car a) (car b)) - (eqv? (cdr a) (cdr b)))) - (('quote) - (eqv? (evaluate a) (evaluate b))) - (('string) - (string-equivalent a b)) - (else - #f)) - #f))) - -(define (cars arg) ; ((1 2) (3 4)) => (1 3) - (define-local stack '()) - (while arg - (define-local stack (cons (caar arg) stack)) - (define-local arg (cdr arg))) - (reverse stack)) -(define (cdrs arg) ; ((1 2) (3 4)) => ((2) (4)) - (define-local stack '()) - (while arg - (define-local stack (cons (cdar arg) stack)) - (define-local arg (cdr arg))) - (reverse stack)) -(define (cadrs arg) ; ((1 2) (3 4)) => (2 4) - (define-local stack '()) - (while arg - (define-local stack (cons (cadar arg) stack)) - (define-local arg (cdr arg))) - (reverse stack)) + (let ((var (unique-word))) + `(progn + (define ,var ,key) + ,(switch-handle var cases)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; And here's our repl ;;; @@ -487,17 +468,18 @@ (write-object #standard-out errorvalue) (write-newline #standard-out)) (define (read-eval-print in out prompt) - (loop - (if prompt (write-string out prompt)) - (define-local scratchspace - (catch 'end-of-file - (read-object in) - (progn (if prompt (write-newline out)) (exit-loop)))) - (define-local scratchspace - (catch #f - (evaluate (macro-expand scratchspace)) - (progn (show-error #exception #exceptionvalue) (ifelse prompt (next-loop) (exit-loop))))) - (if (and prompt scratchspace) - (write-object out scratchspace) - (write-newline out)))) + (let ((scratchspace #f)) + (loop + (if prompt (write-string out prompt)) + (define scratchspace + (catch 'end-of-file + (read-object in) + (progn (if prompt (write-newline out)) (exit-loop)))) + (define scratchspace + (catch #f + (evaluate (macro-expand scratchspace)) + (progn (show-error #exception #exceptionvalue) (ifelse prompt (next-loop) (exit-loop))))) + (if (and prompt scratchspace) + (write-object out scratchspace) + (write-newline out))))) (read-eval-print #standard-in #standard-out (ifelse (isatty #standard-in) "mikelisp> " #f))