memorize only list of captured symbols
This commit is contained in:
parent
77d74fd592
commit
a9a530c9bd
|
@ -15,15 +15,9 @@
|
||||||
# error enable PIC_NONE_IS_FALSE
|
# error enable PIC_NONE_IS_FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {
|
|
||||||
LOCAL,
|
|
||||||
CAPTURED,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct analyze_scope {
|
typedef struct analyze_scope {
|
||||||
bool varg;
|
bool varg;
|
||||||
xvect args, locals; /* rest args variable is counted as a local */
|
xvect args, locals, captures; /* rest args variable is counted as a local */
|
||||||
xhash *captures;
|
|
||||||
struct analyze_scope *up;
|
struct analyze_scope *up;
|
||||||
} analyze_scope;
|
} analyze_scope;
|
||||||
|
|
||||||
|
@ -97,7 +91,6 @@ new_analyze_state(pic_state *pic)
|
||||||
global_tbl = pic->global_tbl;
|
global_tbl = pic->global_tbl;
|
||||||
for (xh_begin(global_tbl, &it); ! xh_isend(&it); xh_next(&it)) {
|
for (xh_begin(global_tbl, &it); ! xh_isend(&it); xh_next(&it)) {
|
||||||
xv_push(&state->scope->locals, &it.e->key);
|
xv_push(&state->scope->locals, &it.e->key);
|
||||||
xh_put_int(state->scope->captures, (long)&it.e->key, LOCAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
@ -142,12 +135,11 @@ push_scope(analyze_state *state, pic_value formals)
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
analyze_scope *scope;
|
analyze_scope *scope;
|
||||||
bool varg;
|
bool varg;
|
||||||
xvect args, locals;
|
xvect args, locals, captures;
|
||||||
size_t i;
|
|
||||||
pic_sym *var;
|
|
||||||
|
|
||||||
xv_init(&args, sizeof(pic_sym));
|
xv_init(&args, sizeof(pic_sym));
|
||||||
xv_init(&locals, sizeof(pic_sym));
|
xv_init(&locals, sizeof(pic_sym));
|
||||||
|
xv_init(&captures, sizeof(pic_sym));
|
||||||
|
|
||||||
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));
|
||||||
|
@ -155,17 +147,7 @@ push_scope(analyze_state *state, pic_value formals)
|
||||||
scope->varg = varg;
|
scope->varg = varg;
|
||||||
scope->args = args;
|
scope->args = args;
|
||||||
scope->locals = locals;
|
scope->locals = locals;
|
||||||
scope->captures = xh_new_int();
|
scope->captures = captures;
|
||||||
|
|
||||||
for (i = 0; i < scope->args.size; ++i) {
|
|
||||||
var = xv_get(&scope->args, i);
|
|
||||||
xh_put_int(scope->captures, *var, LOCAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < scope->locals.size; ++i) {
|
|
||||||
var = xv_get(&scope->locals, i);
|
|
||||||
xh_put_int(scope->captures, *var, LOCAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
state->scope = scope;
|
state->scope = scope;
|
||||||
|
|
||||||
|
@ -186,7 +168,7 @@ pop_scope(analyze_state *state)
|
||||||
scope = state->scope;
|
scope = state->scope;
|
||||||
xv_destroy(&scope->args);
|
xv_destroy(&scope->args);
|
||||||
xv_destroy(&scope->locals);
|
xv_destroy(&scope->locals);
|
||||||
xh_destroy(scope->captures);
|
xv_destroy(&scope->captures);
|
||||||
|
|
||||||
scope = scope->up;
|
scope = scope->up;
|
||||||
pic_free(state->pic, state->scope);
|
pic_free(state->pic, state->scope);
|
||||||
|
@ -223,7 +205,7 @@ find_var(analyze_state *state, pic_sym sym)
|
||||||
while (scope) {
|
while (scope) {
|
||||||
if (lookup_scope(scope, sym)) {
|
if (lookup_scope(scope, sym)) {
|
||||||
if (depth > 0) {
|
if (depth > 0) {
|
||||||
xh_put_int(scope->captures, sym, CAPTURED); /* mark dirty */
|
xv_push(&scope->captures, &sym);
|
||||||
}
|
}
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +227,6 @@ define_var(analyze_state *state, pic_sym sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
xv_push(&scope->locals, &sym);
|
xv_push(&scope->locals, &sym);
|
||||||
xh_put_int(scope->captures, sym, LOCAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
|
@ -437,7 +418,6 @@ analyze_lambda(analyze_state *state, pic_value obj)
|
||||||
analyze_scope *scope = state->scope;
|
analyze_scope *scope = state->scope;
|
||||||
pic_sym *var;
|
pic_sym *var;
|
||||||
size_t i;
|
size_t i;
|
||||||
xh_iter it;
|
|
||||||
|
|
||||||
args = pic_nil_value();
|
args = pic_nil_value();
|
||||||
for (i = scope->args.size; i > 0; --i) {
|
for (i = scope->args.size; i > 0; --i) {
|
||||||
|
@ -459,10 +439,9 @@ analyze_lambda(analyze_state *state, pic_value obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
captures = pic_nil_value();
|
captures = pic_nil_value();
|
||||||
for (xh_begin(scope->captures, &it); ! xh_isend(&it); xh_next(&it)) {
|
for (i = scope->captures.size; i > 0; --i) {
|
||||||
if (it.e->val == CAPTURED) {
|
var = xv_get(&scope->captures, i - 1);
|
||||||
pic_push(pic, pic_sym_value((long)it.e->key), captures);
|
pic_push(pic, pic_sym_value(*var), captures);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_scope(state);
|
pop_scope(state);
|
||||||
|
|
Loading…
Reference in New Issue