test implementation for closed variable reference

This commit is contained in:
Yuichi Nishiwaki 2013-10-24 00:33:37 +09:00
parent ec0f0d3572
commit f854e225c8
1 changed files with 25 additions and 8 deletions

View File

@ -12,6 +12,7 @@ typedef struct codegen_scope {
/* local variables are 1-indexed */ /* local variables are 1-indexed */
struct xhash *local_tbl; struct xhash *local_tbl;
size_t argc; size_t argc;
int *cv_tbl;
} codegen_scope; } codegen_scope;
static codegen_scope * static codegen_scope *
@ -23,6 +24,7 @@ new_global_scope(pic_state *pic)
scope->up = NULL; scope->up = NULL;
scope->local_tbl = pic->global_tbl; scope->local_tbl = pic->global_tbl;
scope->argc = -1; scope->argc = -1;
scope->cv_tbl = NULL;
return scope; return scope;
} }
@ -46,6 +48,7 @@ new_local_scope(pic_state *pic, pic_value args, codegen_scope *scope)
xh_put(x, pic_symbol_ptr(sym)->name, i++); xh_put(x, pic_symbol_ptr(sym)->name, i++);
} }
new_scope->argc = i; new_scope->argc = i;
new_scope->cv_tbl = (int *)pic_calloc(pic, i, sizeof(int));
return new_scope; return new_scope;
} }
@ -55,6 +58,7 @@ destroy_scope(pic_state *pic, codegen_scope *scope)
{ {
if (scope->up) { if (scope->up) {
xh_destory(scope->local_tbl); xh_destory(scope->local_tbl);
pic_free(pic, scope->cv_tbl);
} }
pic_free(pic, scope); pic_free(pic, scope);
} }
@ -99,7 +103,7 @@ destroy_codegen_state(pic_state *pic, codegen_state *state)
pic_free(pic, state); pic_free(pic, state);
} }
static bool static codegen_scope *
scope_lookup(codegen_state *state, const char *key, int *depth, int *idx) scope_lookup(codegen_state *state, const char *key, int *depth, int *idx)
{ {
codegen_scope *scope = state->scope; codegen_scope *scope = state->scope;
@ -117,14 +121,14 @@ scope_lookup(codegen_state *state, const char *key, int *depth, int *idx)
*depth = d; *depth = d;
} }
*idx = e->val; *idx = e->val;
return true; return scope;
} }
if (scope->up) { if (scope->up) {
scope = scope->up; scope = scope->up;
++d; ++d;
goto enter; goto enter;
} }
return false; return NULL;
} }
static int static int
@ -153,13 +157,13 @@ codegen(codegen_state *state, pic_value obj)
switch (pic_type(obj)) { switch (pic_type(obj)) {
case PIC_TT_SYMBOL: { case PIC_TT_SYMBOL: {
bool b; codegen_scope *s;
int depth, idx; int depth, idx;
const char *name; const char *name;
name = pic_symbol_ptr(obj)->name; name = pic_symbol_ptr(obj)->name;
b = scope_lookup(state, name, &depth, &idx); s = scope_lookup(state, name, &depth, &idx);
if (! b) { if (! s) {
pic_error(pic, "unbound variable"); pic_error(pic, "unbound variable");
} }
@ -174,7 +178,11 @@ codegen(codegen_state *state, pic_value obj)
irep->clen++; irep->clen++;
} }
else { /* nonlocal */ else { /* nonlocal */
pic_error(pic, "reference to closed variable not supported"); /* dirty flag */
s->cv_tbl[idx] = 1;
/* dummy code */
irep->code[irep->clen].insn = OP_PUSHNIL;
irep->clen++;
} }
break; break;
} }
@ -371,6 +379,7 @@ codegen_lambda(codegen_state *state, pic_value obj)
codegen_scope *prev_scope; codegen_scope *prev_scope;
struct pic_irep *prev_irep, *irep; struct pic_irep *prev_irep, *irep;
pic_value body, v; pic_value body, v;
int i;
/* inner environment */ /* inner environment */
prev_irep = state->irep; prev_irep = state->irep;
@ -390,6 +399,13 @@ codegen_lambda(codegen_state *state, pic_value obj)
irep->clen--; irep->clen--;
irep->code[irep->clen].insn = OP_RET; irep->code[irep->clen].insn = OP_RET;
irep->clen++; irep->clen++;
printf("** dirty **\n");
for (i = 1; i < state->scope->argc; ++i) {
if (state->scope->cv_tbl[i])
printf("%d ", i);
}
puts("");
} }
destroy_scope(pic, state->scope); destroy_scope(pic, state->scope);
@ -456,7 +472,8 @@ print_irep(pic_state *pic, struct pic_irep *irep)
{ {
int i; int i;
printf("## irep %p [clen = %zd, ccapa = %zd]\n", irep, irep->clen, irep->ccapa); printf("## irep %p\n", irep);
printf("[clen = %zd, ccapa = %zd, argc = %d]\n", irep->clen, irep->ccapa, irep->argc);
for (i = 0; i < irep->clen; ++i) { for (i = 0; i < irep->clen; ++i) {
switch (irep->code[i].insn) { switch (irep->code[i].insn) {
case OP_POP: case OP_POP: