handle error of return-from, block
fix fnblock
This commit is contained in:
parent
a196cec636
commit
001eafc790
19
eval.c
19
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;
|
||||
}
|
||||
|
||||
|
||||
3
gc.c
3
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;
|
||||
|
||||
@ -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))
|
||||
|
||||
|
||||
|
||||
1
obj.c
1
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;
|
||||
}
|
||||
|
||||
|
||||
11
repl.c
11
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){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user