diff --git a/eval.c b/eval.c index 1787465..2668ca3 100644 --- a/eval.c +++ b/eval.c @@ -164,27 +164,26 @@ fnprogn(Object *env, Object *list) Object* fnblock(Object *env, Object *list) { - if(list->type != OCELL) + if(list->type != OCELL|| (list->car->type != OSYMBOL&&list->car->type != OIDENT)) error("Malformed block"); Object *tag = car(list); Object *body = cdr(list); - Object *frame = curframe(env); jmp_buf jmp; - Object *b = frame->block = newblock(gc, tag, curblock(env), body, &jmp); - Object *res = 0; + Object *b = newblock(gc, tag, curblock(env), body, &jmp); + Object *sp = env->sp; + sp->car->block = b; + Object *res = &Nil; if(setjmp(jmp) == 1){ + env->sp->block = b->up; + env->sp = sp; res = env->retval; - env->retval = 0; - Object *p = curblock(env); - for(;p!=b; p=p->up) - assert(p->tag != &Top); - curframe(env)->block = p->up; + env->retval = &Nil; return res; } res = progn(env, body); - frame->block = frame->block->up; + sp->car->block = b->up; return res; } diff --git a/gc.c b/gc.c index 834260b..accc214 100644 --- a/gc.c +++ b/gc.c @@ -42,7 +42,6 @@ findobj(GC *gc, uintptr_t *stk) static Object* cloneobj(GC *dst, GC *src, Object *obj) { - if(obj==0)return 0; if(obj->type==OBLTIN||obj->type==OSYMBOL) return obj; if(obj->flag&FORWARD) return obj->forward; @@ -133,7 +132,7 @@ gcraise(GC *src) static void mark(GC *gc, Object *obj) { - if(obj==0||obj->flag&USING||obj->type==ONONE||obj->type==OSYMBOL||obj->type==OBLTIN) + if(obj->flag&USING||obj->type==ONONE||obj->type==OSYMBOL||obj->type==OBLTIN) return; obj->flag = USING; diff --git a/lib/lib.lisp b/lib/lib.lisp index c958ee1..96d16d8 100644 --- a/lib/lib.lisp +++ b/lib/lib.lisp @@ -1,5 +1,5 @@ (defmacro defun (name args body) - `(define ,name (block ,name (lambda ,args ,body)))) + `(define ,name (lambda ,args (block ,name ,body)))) (defmacro cond (expr . rest) (if (not expr) @@ -28,5 +28,9 @@ `(if (not ,test) (progn ,@rest))) +(defmacro return (res) + (return-from nil `,res)) + (defun list (x . y) (cons x y)) + diff --git a/obj.c b/obj.c index 38a7dd0..9e4c12e 100644 --- a/obj.c +++ b/obj.c @@ -57,6 +57,7 @@ newenv(GC *gc, Object *frames, Object *bp, Object *sp) env->frames = frames; env->bp = bp; env->sp = sp; + env->retval = &Nil; return env; } diff --git a/repl.c b/repl.c index 1640ec9..38ca3f3 100644 --- a/repl.c +++ b/repl.c @@ -31,6 +31,16 @@ error(char *fmt, ...) exit(1); } +/* remove all frames except Top */ +static void +clearenv(Object *env) +{ + env->bp->cdr = &Nil; + env->bp->car->block = &Top; + env->sp = env->bp; + env->retval = &Nil; +} + static void repl(Object *env, FILE *f, char *pre) { @@ -39,6 +49,7 @@ repl(Object *env, FILE *f, char *pre) if(setjmp(err) == 1){ if(feof(f)) exit(1); + clearenv(env); skipline(f); } while(1){