handle grefs at analyzing stage
This commit is contained in:
parent
14eba8f92d
commit
0bcb970842
|
@ -16,6 +16,7 @@
|
|||
#endif
|
||||
|
||||
typedef struct analyze_scope {
|
||||
int depth;
|
||||
bool varg;
|
||||
xvect args, locals, captures; /* rest args variable is counted as a local */
|
||||
struct analyze_scope *up;
|
||||
|
@ -29,7 +30,7 @@ typedef struct analyze_state {
|
|||
pic_sym rEQ, rLT, rLE, rGT, rGE, rNOT;
|
||||
pic_sym rVALUES, rCALL_WITH_VALUES;
|
||||
pic_sym sCALL, sTAILCALL, sCALL_WITH_VALUES, sTAILCALL_WITH_VALUES;
|
||||
pic_sym sREF, sRETURN;
|
||||
pic_sym sREF, sGREF, sRETURN;
|
||||
} analyze_state;
|
||||
|
||||
static bool push_scope(analyze_state *, pic_value);
|
||||
|
@ -83,6 +84,7 @@ new_analyze_state(pic_state *pic)
|
|||
register_symbol(pic, state, sCALL_WITH_VALUES, "call-with-values");
|
||||
register_symbol(pic, state, sTAILCALL_WITH_VALUES, "tailcall-with-values");
|
||||
register_symbol(pic, state, sREF, "ref");
|
||||
register_symbol(pic, state, sGREF, "gref");
|
||||
register_symbol(pic, state, sRETURN, "return");
|
||||
|
||||
/* push initial scope */
|
||||
|
@ -144,6 +146,7 @@ push_scope(analyze_state *state, pic_value formals)
|
|||
if (analyze_args(pic, formals, &varg, &args, &locals)) {
|
||||
scope = (analyze_scope *)pic_alloc(pic, sizeof(analyze_scope));
|
||||
scope->up = state->scope;
|
||||
scope->depth = scope->up ? scope->up->depth + 1 : 0;
|
||||
scope->varg = varg;
|
||||
scope->args = args;
|
||||
scope->locals = locals;
|
||||
|
@ -282,6 +285,26 @@ analyze(analyze_state *state, pic_value obj, bool tailpos)
|
|||
return res;
|
||||
}
|
||||
|
||||
static pic_value
|
||||
analyze_global_var(analyze_state *state, pic_sym sym)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
xh_entry *e;
|
||||
size_t i;
|
||||
|
||||
if ((e = xh_get_int(pic->global_tbl, sym))) {
|
||||
i = e->val;
|
||||
}
|
||||
else {
|
||||
i = pic->glen++;
|
||||
if (i >= pic->gcapa) {
|
||||
pic_error(pic, "global table overflow");
|
||||
}
|
||||
xh_put_int(pic->global_tbl, sym, i);
|
||||
}
|
||||
return pic_list2(pic, pic_symbol_value(state->sGREF), pic_int_value(i));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
analyze_var(analyze_state *state, pic_value obj)
|
||||
{
|
||||
|
@ -293,6 +316,10 @@ analyze_var(analyze_state *state, pic_value obj)
|
|||
if ((depth = find_var(state, sym)) == -1) {
|
||||
pic_errorf(pic, "unbound variable %s", pic_symbol_name(pic, sym));
|
||||
}
|
||||
|
||||
if (depth == state->scope->depth) {
|
||||
return analyze_global_var(state, sym);
|
||||
}
|
||||
return new_ref(state, depth, sym);
|
||||
}
|
||||
|
||||
|
@ -871,26 +898,6 @@ is_closed(resolver_state *state, pic_sym sym)
|
|||
return xh_get_int(state->scope->cvs, sym) != NULL;
|
||||
}
|
||||
|
||||
static pic_value
|
||||
resolve_gref(resolver_state *state, pic_sym sym)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
xh_entry *e;
|
||||
size_t i;
|
||||
|
||||
if ((e = xh_get_int(pic->global_tbl, sym))) {
|
||||
i = e->val;
|
||||
}
|
||||
else {
|
||||
i = pic->glen++;
|
||||
if (i >= pic->gcapa) {
|
||||
pic_error(pic, "global table overflow");
|
||||
}
|
||||
xh_put_int(pic->global_tbl, sym, i);
|
||||
}
|
||||
return pic_list2(pic, pic_symbol_value(state->sGREF), pic_int_value(i));
|
||||
}
|
||||
|
||||
static pic_value
|
||||
resolve_lref(resolver_state *state, pic_sym sym)
|
||||
{
|
||||
|
@ -940,7 +947,6 @@ static pic_value
|
|||
resolve_reference_node(resolver_state *state, pic_value obj)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
resolver_scope *scope = state->scope;
|
||||
pic_sym tag;
|
||||
|
||||
if (! pic_pair_p(obj))
|
||||
|
@ -953,10 +959,7 @@ resolve_reference_node(resolver_state *state, pic_value obj)
|
|||
|
||||
depth = pic_int(pic_list_ref(pic, obj, 1));
|
||||
sym = pic_sym(pic_list_ref(pic, obj, 2));
|
||||
if (depth == scope->depth) {
|
||||
return resolve_gref(state, sym);
|
||||
}
|
||||
else if (depth == 0 && ! is_closed(state, sym)) {
|
||||
if (depth == 0 && ! is_closed(state, sym)) {
|
||||
return resolve_lref(state, sym);
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Reference in New Issue