support internal definitions

This commit is contained in:
Yuichi Nishiwaki 2013-11-13 18:08:22 +09:00
parent 2fb4720e22
commit b9fce69c61
2 changed files with 49 additions and 10 deletions

View File

@ -166,6 +166,22 @@ scope_global_define(pic_state *pic, const char *name)
return e->val; return e->val;
} }
static int
scope_local_define(pic_state *pic, const char *name, codegen_scope *scope)
{
struct xh_entry *e;
e = xh_put(scope->local_tbl, name, scope->argc + scope->localc++);
scope->dirty_flags = (int *)pic_realloc(pic, scope->dirty_flags, (e->val) * sizeof(int));
return e->val;
}
static bool
scope_is_global(codegen_scope *scope)
{
return scope->up == NULL;
}
static void codegen_call(codegen_state *, pic_value, bool); static void codegen_call(codegen_state *, pic_value, bool);
static struct pic_irep *codegen_lambda(codegen_state *, pic_value); static struct pic_irep *codegen_lambda(codegen_state *, pic_value);
@ -220,6 +236,7 @@ codegen(codegen_state *state, pic_value obj, bool tailpos)
if (sym == pic->sDEFINE) { if (sym == pic->sDEFINE) {
int idx; int idx;
pic_value var, val; pic_value var, val;
codegen_scope *s;
if (pic_length(pic, obj) < 2) { if (pic_length(pic, obj) < 2) {
pic_error(pic, "syntax error"); pic_error(pic, "syntax error");
@ -242,15 +259,27 @@ codegen(codegen_state *state, pic_value obj, bool tailpos)
pic_error(pic, "syntax error"); pic_error(pic, "syntax error");
} }
idx = scope_global_define(pic, pic_symbol_name(pic, pic_sym(var))); s = state->scope;
if (scope_is_global(s)) {
codegen(state, val, false); idx = scope_global_define(pic, pic_symbol_name(pic, pic_sym(var)));
irep->code[irep->clen].insn = OP_GSET; codegen(state, val, false);
irep->code[irep->clen].u.i = idx; irep->code[irep->clen].insn = OP_GSET;
irep->clen++; irep->code[irep->clen].u.i = idx;
irep->code[irep->clen].insn = OP_PUSHFALSE; irep->clen++;
irep->clen++; irep->code[irep->clen].insn = OP_PUSHFALSE;
break; irep->clen++;
break;
}
else {
idx = scope_local_define(pic, pic_symbol_name(pic, pic_sym(var)), s);
codegen(state, val, false);
irep->code[irep->clen].insn = OP_LSET;
irep->code[irep->clen].u.i = idx;
irep->clen++;
irep->code[irep->clen].insn = OP_PUSHFALSE;
irep->clen++;
break;
}
} }
else if (sym == pic->sLAMBDA) { else if (sym == pic->sLAMBDA) {
int k = pic->ilen++; int k = pic->ilen++;
@ -738,7 +767,6 @@ codegen_lambda(codegen_state *state, pic_value obj)
state->scope = new_local_scope(pic, args, state->scope); state->scope = new_local_scope(pic, args, state->scope);
state->irep = irep = new_irep(pic); state->irep = irep = new_irep(pic);
irep->argc = state->scope->argc; irep->argc = state->scope->argc;
irep->localc = state->scope->localc;
irep->varg = state->scope->varg; irep->varg = state->scope->varg;
{ {
/* body */ /* body */
@ -756,6 +784,8 @@ codegen_lambda(codegen_state *state, pic_value obj)
irep->code[irep->clen].insn = OP_RET; irep->code[irep->clen].insn = OP_RET;
irep->clen++; irep->clen++;
irep->localc = state->scope->localc;
/* fixup local references */ /* fixup local references */
for (i = 0; i < irep->clen; ++i) { for (i = 0; i < irep->clen; ++i) {
struct pic_code c = irep->code[i]; struct pic_code c = irep->code[i];

View File

@ -484,6 +484,15 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
} }
} }
/* prepare local variable area */
if (proc->u.irep->localc > 0) {
int l = proc->u.irep->localc;
if (proc->u.irep->varg) {
--l;
}
pic->sp += l;
}
pc = proc->u.irep->code; pc = proc->u.irep->code;
pic_gc_arena_restore(pic, ai); pic_gc_arena_restore(pic, ai);
JUMP; JUMP;