let OP_RET take an argument

This commit is contained in:
Yuichi Nishiwaki 2014-02-20 16:01:29 +09:00
parent 16639a1764
commit 0f75a1b7cb
2 changed files with 23 additions and 11 deletions

View File

@ -1312,8 +1312,14 @@ codegen(codegen_state *state, pic_value obj)
return;
}
else if (sym == state->sRETURN) {
codegen(state, pic_list_ref(pic, obj, 1));
int len = pic_length(pic, obj);
pic_value elt;
pic_for_each (elt, pic_cdr(pic, obj)) {
codegen(state, elt);
}
cxt->code[cxt->clen].insn = OP_RET;
cxt->code[cxt->clen].u.i = len - 1;
cxt->clen++;
return;
}
@ -1581,7 +1587,7 @@ print_code(pic_state *pic, struct pic_code c)
printf("OP_TAILCALL\t%d\n", c.u.i);
break;
case OP_RET:
puts("OP_RET");
printf("OP_RET\t%d\n", c.u.i);
break;
case OP_LAMBDA:
printf("OP_LAMBDA\t%d\n", c.u.i);

View File

@ -624,20 +624,23 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
CASE(OP_TAILCALL) {
int i, argc;
pic_value *argv;
pic_callinfo *ci;
argc = c.u.i;
argv = pic->sp - argc;
for (i = 0; i < argc; ++i) {
pic->ci->fp[i] = argv[i];
}
pic->sp = pic->ci->fp + argc;
pic->ip = POPCI()->ip;
ci = POPCI();
pic->sp = ci->fp + argc;
pic->ip = ci->ip;
/* c is not changed */
goto L_CALL;
}
CASE(OP_RET) {
pic_value v;
int i, retc;
pic_value *retv;
pic_callinfo *ci;
if (pic->err) {
@ -645,13 +648,16 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
L_RAISE:
goto L_STOP;
}
else {
v = POP();
ci = POPCI();
pic->ip = ci->ip;
pic->sp = ci->fp;
PUSH(v);
retc = c.u.i;
retv = pic->sp - retc;
for (i = 0; i < retc; ++i) {
pic->ci->fp[i] = retv[i];
}
ci = POPCI();
pic->sp = ci->fp + retc;
pic->ip = ci->ip;
NEXT;
}
CASE(OP_LAMBDA) {