handle grefs at analyzing stage
This commit is contained in:
parent
14eba8f92d
commit
0bcb970842
|
@ -16,6 +16,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct analyze_scope {
|
typedef struct analyze_scope {
|
||||||
|
int depth;
|
||||||
bool varg;
|
bool varg;
|
||||||
xvect args, locals, captures; /* rest args variable is counted as a local */
|
xvect args, locals, captures; /* rest args variable is counted as a local */
|
||||||
struct analyze_scope *up;
|
struct analyze_scope *up;
|
||||||
|
@ -29,7 +30,7 @@ typedef struct analyze_state {
|
||||||
pic_sym rEQ, rLT, rLE, rGT, rGE, rNOT;
|
pic_sym rEQ, rLT, rLE, rGT, rGE, rNOT;
|
||||||
pic_sym rVALUES, rCALL_WITH_VALUES;
|
pic_sym rVALUES, rCALL_WITH_VALUES;
|
||||||
pic_sym sCALL, sTAILCALL, sCALL_WITH_VALUES, sTAILCALL_WITH_VALUES;
|
pic_sym sCALL, sTAILCALL, sCALL_WITH_VALUES, sTAILCALL_WITH_VALUES;
|
||||||
pic_sym sREF, sRETURN;
|
pic_sym sREF, sGREF, sRETURN;
|
||||||
} analyze_state;
|
} analyze_state;
|
||||||
|
|
||||||
static bool push_scope(analyze_state *, pic_value);
|
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, sCALL_WITH_VALUES, "call-with-values");
|
||||||
register_symbol(pic, state, sTAILCALL_WITH_VALUES, "tailcall-with-values");
|
register_symbol(pic, state, sTAILCALL_WITH_VALUES, "tailcall-with-values");
|
||||||
register_symbol(pic, state, sREF, "ref");
|
register_symbol(pic, state, sREF, "ref");
|
||||||
|
register_symbol(pic, state, sGREF, "gref");
|
||||||
register_symbol(pic, state, sRETURN, "return");
|
register_symbol(pic, state, sRETURN, "return");
|
||||||
|
|
||||||
/* push initial scope */
|
/* push initial scope */
|
||||||
|
@ -144,6 +146,7 @@ push_scope(analyze_state *state, pic_value formals)
|
||||||
if (analyze_args(pic, formals, &varg, &args, &locals)) {
|
if (analyze_args(pic, formals, &varg, &args, &locals)) {
|
||||||
scope = (analyze_scope *)pic_alloc(pic, sizeof(analyze_scope));
|
scope = (analyze_scope *)pic_alloc(pic, sizeof(analyze_scope));
|
||||||
scope->up = state->scope;
|
scope->up = state->scope;
|
||||||
|
scope->depth = scope->up ? scope->up->depth + 1 : 0;
|
||||||
scope->varg = varg;
|
scope->varg = varg;
|
||||||
scope->args = args;
|
scope->args = args;
|
||||||
scope->locals = locals;
|
scope->locals = locals;
|
||||||
|
@ -282,6 +285,26 @@ analyze(analyze_state *state, pic_value obj, bool tailpos)
|
||||||
return res;
|
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
|
static pic_value
|
||||||
analyze_var(analyze_state *state, pic_value obj)
|
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) {
|
if ((depth = find_var(state, sym)) == -1) {
|
||||||
pic_errorf(pic, "unbound variable %s", pic_symbol_name(pic, sym));
|
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);
|
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;
|
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
|
static pic_value
|
||||||
resolve_lref(resolver_state *state, pic_sym sym)
|
resolve_lref(resolver_state *state, pic_sym sym)
|
||||||
{
|
{
|
||||||
|
@ -940,7 +947,6 @@ static pic_value
|
||||||
resolve_reference_node(resolver_state *state, pic_value obj)
|
resolve_reference_node(resolver_state *state, pic_value obj)
|
||||||
{
|
{
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
resolver_scope *scope = state->scope;
|
|
||||||
pic_sym tag;
|
pic_sym tag;
|
||||||
|
|
||||||
if (! pic_pair_p(obj))
|
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));
|
depth = pic_int(pic_list_ref(pic, obj, 1));
|
||||||
sym = pic_sym(pic_list_ref(pic, obj, 2));
|
sym = pic_sym(pic_list_ref(pic, obj, 2));
|
||||||
if (depth == scope->depth) {
|
if (depth == 0 && ! is_closed(state, sym)) {
|
||||||
return resolve_gref(state, sym);
|
|
||||||
}
|
|
||||||
else if (depth == 0 && ! is_closed(state, sym)) {
|
|
||||||
return resolve_lref(state, sym);
|
return resolve_lref(state, sym);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in New Issue