1
0
forked from GitHub/gf-core

finally proper stack unwind in the evaluator

This commit is contained in:
kr.angelov
2014-10-16 10:00:32 +00:00
parent b70dba87ba
commit 26ad164cec
8 changed files with 176 additions and 211 deletions

View File

@@ -5,6 +5,23 @@
#define PGF_ARGS_DELTA 5
static inline PgfClosure*
pgf_mk_pap(PgfEvalState* state, PgfClosure* fun,
size_t n_args, PgfClosure** args)
{
if (n_args > 0) {
PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args);
val->header.code = state->eval_gates->evaluate_value_pap;
val->fun = fun;
val->n_args = n_args*sizeof(PgfClosure*);
for (size_t i = 0; i < n_args; i++) {
val->args[i] = args[i];
}
return &val->header;
}
return fun;
}
PgfClosure*
pgf_evaluate_expr_thunk(PgfEvalState* state, PgfExprThunk* thunk)
{
@@ -64,15 +81,11 @@ repeat:;
PgfExprMeta* emeta = ei.data;
PgfValueMeta* val =
gu_new_flex(state->pool, PgfValueMeta, args, n_args);
val->header.code = state->eval_gates->evaluate_value_meta;
val->id = emeta->id;
val->n_args = n_args*sizeof(PgfClosure*);
for (size_t i = 0; i < n_args; i++) {
val->args[i] = args[n_args-i-1];
}
res = &val->header;
gu_new(PgfValueMeta, state->pool);
val->header.code = state->eval_gates->evaluate_meta;
val->env = env;
val->id = emeta->id;
res = pgf_mk_pap(state, &val->header, n_args, args);
break;
}
case PGF_EXPR_FUN: {
@@ -83,18 +96,7 @@ repeat:;
gu_assert(absfun != NULL);
if (absfun->closure.code != NULL) {
res = (PgfClosure*) &absfun->closure;
if (n_args > 0) {
PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args);
val->header.code = state->eval_gates->evaluate_value_pap;
val->fun = res;
val->n_args = n_args*sizeof(PgfClosure*);
for (size_t i = 0; i < n_args; i++) {
val->args[i] = args[i];
}
res = &val->header;
}
res = pgf_mk_pap(state, (PgfClosure*) &absfun->closure, n_args, args);
} else {
size_t arity = absfun->arity;
@@ -113,18 +115,7 @@ repeat:;
PgfExprThunk* lambda = gu_new(PgfExprThunk, state->pool);
lambda->header.code = state->eval_gates->evaluate_value_lambda;
lambda->env = NULL;
res = &lambda->header;
if (n_args > 0) {
PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args);
val->header.code = state->eval_gates->evaluate_value_pap;
val->fun = &lambda->header;
val->n_args = n_args*sizeof(PgfClosure*);
for (size_t i = 0; i < n_args; i++) {
val->args[i] = args[i];
}
res = &val->header;
}
res = pgf_mk_pap(state, &lambda->header, n_args, args);
for (size_t i = 0; i < arity; i++) {
PgfExpr new_expr, arg;
@@ -180,18 +171,7 @@ repeat:;
i--;
}
res = tmp_env->closure;
if (n_args > 0) {
PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args);
val->header.code = state->eval_gates->evaluate_value_pap;
val->fun = res;
val->n_args = n_args*sizeof(PgfClosure*);
for (size_t i = 0; i < n_args; i++) {
val->args[i] = args[i];
}
res = &val->header;
}
res = pgf_mk_pap(state, tmp_env->closure, n_args, args);
break;
}
case PGF_EXPR_TYPED: {
@@ -245,28 +225,6 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
expr = absfun->ep.expr;
n_args = absfun->arity;
args = val->args;
} else if (clos->code == state->eval_gates->evaluate_value_gen) {
PgfValueGen* val = (PgfValueGen*) clos;
PgfExprVar *evar =
gu_new_variant(PGF_EXPR_VAR,
PgfExprVar,
&expr, pool);
evar->var = level - val->level - 1;
n_args = val->n_args/sizeof(PgfClosure*);
args = val->args;
} else if (clos->code == state->eval_gates->evaluate_value_meta) {
PgfValueMeta* val = (PgfValueMeta*) clos;
PgfExprMeta *emeta =
gu_new_variant(PGF_EXPR_META,
PgfExprMeta,
&expr, pool);
emeta->id = val->id;
n_args = val->n_args / sizeof(PgfClosure*);
args = val->args;
} else if (clos->code == state->eval_gates->evaluate_value_lit) {
PgfValueLit* val = (PgfValueLit*) clos;
@@ -316,18 +274,18 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
PgfValueGen* gen =
gu_new(PgfValueGen, state->pool);
gen->header.code = state->eval_gates->evaluate_value_gen;
gen->header.code = state->eval_gates->evaluate_gen;
gen->level = level;
gen->n_args = 0;
PgfValuePAP* new_pap = gu_new_flex(state->pool, PgfValuePAP, args, pap->n_args+1);
size_t n_args = pap->n_args/sizeof(PgfClosure*);
PgfValuePAP* new_pap = gu_new_flex(state->pool, PgfValuePAP, args, n_args+1);
new_pap->header.code = state->eval_gates->evaluate_value_pap;
new_pap->fun = pap->fun;
new_pap->n_args = pap->n_args+sizeof(PgfClosure*);
for (size_t i = 0; i < pap->n_args/sizeof(PgfClosure*); i++) {
new_pap->args[i] = pap->args[i];
new_pap->args[0] = &gen->header;
for (size_t i = 0; i < n_args; i++) {
new_pap->args[i+1] = pap->args[i];
}
new_pap->args[pap->n_args] = &gen->header;
PgfExprAbs *eabs =
gu_new_variant(PGF_EXPR_ABS,
@@ -336,6 +294,32 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
eabs->bind_type = PGF_BIND_TYPE_EXPLICIT;
eabs->id = gu_format_string(pool, "v%d", level);
eabs->body = pgf_value2expr(state, level+1, &new_pap->header, pool);
} else if (clos->code == state->eval_gates->evaluate_value_const) {
PgfValuePAP* val = (PgfValuePAP*) clos;
if (val->fun->code == state->eval_gates->evaluate_meta) {
PgfValueMeta* fun = (PgfValueMeta*) val->fun;
PgfExprMeta *emeta =
gu_new_variant(PGF_EXPR_META,
PgfExprMeta,
&expr, pool);
emeta->id = fun->id;
} else if (val->fun->code == state->eval_gates->evaluate_gen) {
PgfValueGen* fun = (PgfValueGen*) val->fun;
PgfExprVar *evar =
gu_new_variant(PGF_EXPR_VAR,
PgfExprVar,
&expr, pool);
evar->var = level - fun->level - 1;
} else {
PgfAbsFun* absfun = gu_container(val->fun, PgfAbsFun, closure);
expr = absfun->ep.expr;
}
n_args = val->n_args/sizeof(PgfClosure*);
args = val->args;
} else {
gu_impossible();
}