forked from GitHub/gf-core
now a complete JIT compiler and ByteCode compiler for the def rules in the abstract syntax. there might be some bugs yet to be found, meta variables and computation under lambda is only partially supported
This commit is contained in:
@@ -311,9 +311,8 @@ gu_pool_free(GuPool* pool)
|
||||
{
|
||||
GuFinalizerNode* node = pool->finalizers;
|
||||
while (node) {
|
||||
GuFinalizerNode* next = node->next;
|
||||
node->fin->fn(node->fin);
|
||||
node = next;
|
||||
node = node->next;
|
||||
}
|
||||
GuMemChunk* chunk = pool->chunks;
|
||||
while (chunk) {
|
||||
|
||||
@@ -136,12 +136,6 @@ gu_buf_data(GuBuf* buf)
|
||||
return &buf->seq->data;
|
||||
}
|
||||
|
||||
void*
|
||||
gu_buf_last(GuBuf* buf)
|
||||
{
|
||||
return buf->seq->data + buf->elem_size*(buf->seq->len-1);
|
||||
}
|
||||
|
||||
GuSeq*
|
||||
gu_buf_data_seq(GuBuf* buf)
|
||||
{
|
||||
|
||||
@@ -65,9 +65,6 @@ gu_buf_avail(GuBuf* buf);
|
||||
void*
|
||||
gu_buf_data(GuBuf* buf);
|
||||
|
||||
void*
|
||||
gu_buf_last(GuBuf* buf);
|
||||
|
||||
GuSeq*
|
||||
gu_buf_data_seq(GuBuf* buf);
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ typedef struct {
|
||||
PgfEquations* defns; // maybe null
|
||||
PgfExprProb ep;
|
||||
void* predicate;
|
||||
void* function;
|
||||
size_t closure_id;
|
||||
} PgfAbsFun;
|
||||
|
||||
extern GU_DECLARE_TYPE(PgfAbsFun, abstract);
|
||||
@@ -95,31 +95,31 @@ typedef struct {
|
||||
|
||||
extern GU_DECLARE_TYPE(PgfAbsCat, abstract);
|
||||
|
||||
typedef struct PgfEvalGates PgfEvalGates;
|
||||
|
||||
typedef struct {
|
||||
PgfCId name;
|
||||
PgfFlags* aflags;
|
||||
PgfCIdMap* funs; // |-> PgfAbsFun*
|
||||
PgfCIdMap* cats; // |-> PgfAbsCat*
|
||||
PgfAbsFun* abs_lin_fun;
|
||||
PgfEvalGates* eval_gates;
|
||||
} PgfAbstr;
|
||||
|
||||
typedef enum {
|
||||
PGF_INSTR_ENTER,
|
||||
PGF_INSTR_CASE,
|
||||
PGF_INSTR_CASE_LIT,
|
||||
PGF_INSTR_ALLOC,
|
||||
PGF_INSTR_PUT_CONSTR,
|
||||
PGF_INSTR_PUT_FUN,
|
||||
PGF_INSTR_PUT_CLOSURE,
|
||||
PGF_INSTR_PUT_LIT,
|
||||
PGF_INSTR_SET,
|
||||
PGF_INSTR_SET_PAD,
|
||||
PGF_INSTR_PUSH,
|
||||
PGF_INSTR_EVAL,
|
||||
PGF_INSTR_CALL,
|
||||
PGF_INSTR_FAIL,
|
||||
PGF_INSTR_UPDATE,
|
||||
PGF_INSTR_RET
|
||||
PGF_INSTR_CHECK_ARGS = 0,
|
||||
PGF_INSTR_CASE = 1,
|
||||
PGF_INSTR_CASE_LIT = 2,
|
||||
PGF_INSTR_ALLOC = 3,
|
||||
PGF_INSTR_PUT_CONSTR = 4,
|
||||
PGF_INSTR_PUT_CLOSURE = 5,
|
||||
PGF_INSTR_PUT_LIT = 6,
|
||||
PGF_INSTR_SET = 7,
|
||||
PGF_INSTR_SET_PAD = 8,
|
||||
PGF_INSTR_PUSH = 9,
|
||||
PGF_INSTR_EVAL = 10,
|
||||
PGF_INSTR_RET = 13,
|
||||
PGF_INSTR_FAIL = 15
|
||||
} PgfInstruction;
|
||||
|
||||
struct PgfPGF {
|
||||
|
||||
@@ -1,288 +1,187 @@
|
||||
#include "pgf/pgf.h"
|
||||
#include "pgf/data.h"
|
||||
#include "pgf/evaluator.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct PgfEnv PgfEnv;
|
||||
|
||||
struct PgfEnv {
|
||||
PgfEnv* next;
|
||||
PgfClosure* closure;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfEnv* env;
|
||||
PgfExpr expr;
|
||||
} PgfExprThunk;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfClosure* val;
|
||||
} PgfIndirection;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
int level;
|
||||
size_t n_args;
|
||||
PgfClosure* args[];
|
||||
} PgfValueGen;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfEnv* env;
|
||||
PgfMetaId id;
|
||||
size_t n_args;
|
||||
PgfClosure* args[];
|
||||
} PgfValueMeta;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfLiteral lit;
|
||||
} PgfValueLit;
|
||||
#define PGF_ARGS_DELTA 5
|
||||
|
||||
PgfClosure*
|
||||
pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure)
|
||||
{
|
||||
PgfIndirection* indir = (PgfIndirection*) closure;
|
||||
return indir->val;
|
||||
}
|
||||
|
||||
PgfClosure*
|
||||
pgf_evaluate_value(PgfEvalState* state, PgfClosure* closure)
|
||||
{
|
||||
return closure;
|
||||
}
|
||||
|
||||
static PgfClosure*
|
||||
pgf_evaluate_value_gen(PgfEvalState* state, PgfClosure* closure)
|
||||
{
|
||||
PgfValueGen* val = (PgfValueGen*) closure;
|
||||
|
||||
size_t n_args = val->n_args + gu_buf_length(state->stack);
|
||||
PgfValueGen* new_val =
|
||||
gu_new_flex(state->pool, PgfValueGen, args, n_args);
|
||||
new_val->header.code = pgf_evaluate_value_gen;
|
||||
new_val->level = val->level;
|
||||
new_val->n_args = n_args;
|
||||
|
||||
size_t i = 0;
|
||||
while (i < val->n_args) {
|
||||
new_val->args[i] = val->args[i];
|
||||
i++;
|
||||
}
|
||||
while (i < n_args) {
|
||||
new_val->args[i] = gu_buf_pop(state->stack, PgfClosure*);
|
||||
i++;
|
||||
}
|
||||
|
||||
return &new_val->header;
|
||||
}
|
||||
|
||||
static PgfClosure*
|
||||
pgf_evaluate_value_meta(PgfEvalState* state, PgfClosure* closure)
|
||||
{
|
||||
PgfValueMeta* val = (PgfValueMeta*) closure;
|
||||
|
||||
size_t n_args = val->n_args + gu_buf_length(state->stack);
|
||||
PgfValueMeta* new_val =
|
||||
gu_new_flex(state->pool, PgfValueMeta, args, n_args);
|
||||
new_val->header.code = pgf_evaluate_value_meta;
|
||||
new_val->id = val->id;
|
||||
new_val->n_args = n_args;
|
||||
|
||||
size_t i = 0;
|
||||
while (i < val->n_args) {
|
||||
new_val->args[i] = val->args[i];
|
||||
i++;
|
||||
}
|
||||
while (i < n_args) {
|
||||
val->args[i] = gu_buf_pop(state->stack, PgfClosure*);
|
||||
i++;
|
||||
}
|
||||
|
||||
return &new_val->header;
|
||||
}
|
||||
|
||||
static PgfClosure*
|
||||
pgf_evaluate_value_lit(PgfEvalState* state, PgfClosure* closure)
|
||||
{
|
||||
return closure;
|
||||
}
|
||||
|
||||
static PgfClosure*
|
||||
pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure)
|
||||
{
|
||||
PgfExprThunk* thunk = (PgfExprThunk*) closure;
|
||||
PgfEnv* env = thunk->env;
|
||||
PgfExpr expr = thunk->expr;
|
||||
|
||||
for (;;) {
|
||||
GuVariantInfo ei = gu_variant_open(expr);
|
||||
switch (ei.tag) {
|
||||
case PGF_EXPR_ABS: {
|
||||
PgfExprAbs* eabs = ei.data;
|
||||
size_t n_args = 0;
|
||||
PgfClosure** args = NULL;
|
||||
PgfClosure* res = NULL;
|
||||
|
||||
if (gu_buf_length(state->stack) > 0) {
|
||||
PgfEnv* new_env = gu_new(PgfEnv, state->pool);
|
||||
new_env->next = env;
|
||||
new_env->closure = gu_buf_pop(state->stack, PgfClosure*);
|
||||
repeat:;
|
||||
GuVariantInfo ei = gu_variant_open(expr);
|
||||
switch (ei.tag) {
|
||||
case PGF_EXPR_ABS: {
|
||||
PgfExprAbs* eabs = ei.data;
|
||||
|
||||
env = new_env;
|
||||
expr = eabs->body;
|
||||
} else {
|
||||
thunk->expr = expr;
|
||||
return closure;
|
||||
}
|
||||
break;
|
||||
if (n_args > 0) {
|
||||
PgfEnv* new_env = gu_new(PgfEnv, state->pool);
|
||||
new_env->next = env;
|
||||
new_env->closure = args[--n_args];
|
||||
|
||||
env = new_env;
|
||||
expr = eabs->body;
|
||||
goto repeat;
|
||||
} else {
|
||||
thunk->header.code = state->eval_gates->evaluate_value_lambda;
|
||||
thunk->expr = eabs->body;
|
||||
res = closure;
|
||||
}
|
||||
case PGF_EXPR_APP: {
|
||||
PgfExprApp* eapp = ei.data;
|
||||
PgfExprThunk* thunk =
|
||||
gu_new(PgfExprThunk, state->pool);
|
||||
thunk->header.code = pgf_evaluate_expr_thunk;
|
||||
thunk->env = env;
|
||||
thunk->expr = eapp->arg;
|
||||
gu_buf_push(state->stack, PgfClosure*, &thunk->header);
|
||||
expr = eapp->fun;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case PGF_EXPR_APP: {
|
||||
PgfExprApp* eapp = ei.data;
|
||||
PgfExprThunk* thunk =
|
||||
gu_new(PgfExprThunk, state->pool);
|
||||
thunk->header.code = state->eval_gates->evaluate_expr_thunk;
|
||||
thunk->env = env;
|
||||
thunk->expr = eapp->arg;
|
||||
|
||||
if (n_args % PGF_ARGS_DELTA == 0) {
|
||||
args = realloc(args, n_args + PGF_ARGS_DELTA);
|
||||
}
|
||||
case PGF_EXPR_LIT: {
|
||||
PgfExprLit* elit = ei.data;
|
||||
args[n_args++] = &thunk->header;
|
||||
|
||||
if (gu_buf_length(state->stack) > 0) {
|
||||
GuExnData* err_data = gu_raise(state->err, PgfExn);
|
||||
if (err_data) {
|
||||
err_data->data = "found literal of function type";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
expr = eapp->fun;
|
||||
goto repeat;
|
||||
}
|
||||
case PGF_EXPR_LIT: {
|
||||
PgfExprLit* elit = ei.data;
|
||||
PgfValueLit* val = (PgfValueLit*) closure;
|
||||
val->header.code = state->eval_gates->evaluate_value_lit;
|
||||
val->lit = elit->lit;
|
||||
res = &val->header;
|
||||
break;
|
||||
}
|
||||
case PGF_EXPR_META: {
|
||||
PgfExprMeta* emeta = ei.data;
|
||||
|
||||
PgfValueLit* val = (PgfValueLit*) closure;
|
||||
val->header.code = pgf_evaluate_value_lit;
|
||||
val->lit = elit->lit;
|
||||
return &val->header;
|
||||
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];
|
||||
}
|
||||
case PGF_EXPR_META: {
|
||||
PgfExprMeta* emeta = ei.data;
|
||||
|
||||
size_t n_args = gu_buf_length(state->stack);
|
||||
PgfIndirection* indir = (PgfIndirection*) closure;
|
||||
indir->header.code = state->eval_gates->evaluate_indirection;
|
||||
indir->val = &val->header;
|
||||
|
||||
PgfValueMeta* val =
|
||||
gu_new_flex(state->pool, PgfValueMeta, args, n_args);
|
||||
val->header.code = pgf_evaluate_value_meta;
|
||||
val->id = emeta->id;
|
||||
val->n_args = n_args;
|
||||
for (size_t i = 0; i < n_args; i++) {
|
||||
val->args[i] = gu_buf_pop(state->stack, PgfClosure*);
|
||||
res = &val->header;
|
||||
break;
|
||||
}
|
||||
case PGF_EXPR_FUN: {
|
||||
PgfExprFun* efun = ei.data;
|
||||
|
||||
PgfAbsFun* absfun =
|
||||
gu_map_get(state->pgf->abstract.funs, efun->fun, PgfAbsFun*);
|
||||
if (absfun == NULL) {
|
||||
GuExnData* err_data = gu_raise(state->err, PgfExn);
|
||||
if (err_data) {
|
||||
err_data->data = (char* const)
|
||||
gu_format_string(err_data->pool,
|
||||
"Unknown function: %s",
|
||||
efun->fun);
|
||||
}
|
||||
} else {
|
||||
if (absfun->closure_id > 0) {
|
||||
res = &state->globals[absfun->closure_id-1].header;
|
||||
|
||||
PgfIndirection* indir = (PgfIndirection*) closure;
|
||||
indir->header.code = pgf_evaluate_indirection;
|
||||
indir->val = &val->header;
|
||||
|
||||
return &val->header;
|
||||
}
|
||||
case PGF_EXPR_FUN: {
|
||||
PgfExprFun* efun = ei.data;
|
||||
|
||||
PgfAbsFun* absfun =
|
||||
gu_map_get(state->pgf->abstract.funs, efun->fun, PgfAbsFun*);
|
||||
if (absfun == NULL) {
|
||||
GuExnData* err_data = gu_raise(state->err, PgfExn);
|
||||
if (err_data) {
|
||||
err_data->data = (char* const)
|
||||
gu_format_string(err_data->pool,
|
||||
"Unknown function: %s",
|
||||
efun->fun);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PgfValue* val;
|
||||
if (absfun->function != NULL) {
|
||||
val = (PgfValue*) ((PgfFunction) absfun->function)(state, closure);
|
||||
} else {
|
||||
size_t n_args = absfun->arity;
|
||||
|
||||
val = gu_new_flex(state->pool, PgfValue, args, n_args);
|
||||
val->header.code = pgf_evaluate_value;
|
||||
val->absfun = absfun;
|
||||
for (size_t i = 0; i < n_args; i++) {
|
||||
val->args[i] = gu_buf_pop(state->stack, PgfClosure*);
|
||||
}
|
||||
}
|
||||
|
||||
PgfIndirection* indir = (PgfIndirection*) closure;
|
||||
indir->header.code = pgf_evaluate_indirection;
|
||||
indir->val = &val->header;
|
||||
|
||||
return &val->header;
|
||||
}
|
||||
case PGF_EXPR_VAR: {
|
||||
PgfExprVar* evar = ei.data;
|
||||
PgfEnv* tmp_env = env;
|
||||
size_t i = evar->var;
|
||||
while (i > 0) {
|
||||
tmp_env = tmp_env->next;
|
||||
if (tmp_env == NULL) {
|
||||
GuExnData* err_data = gu_raise(state->err, PgfExn);
|
||||
if (err_data) {
|
||||
err_data->data = "invalid de Bruijn index";
|
||||
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];
|
||||
}
|
||||
return NULL;
|
||||
res = &val->header;
|
||||
}
|
||||
i--;
|
||||
} else {
|
||||
size_t arity = absfun->arity;
|
||||
|
||||
PgfValue* val = gu_new_flex(state->pool, PgfValue, args, arity);
|
||||
val->header.code = state->eval_gates->evaluate_value;
|
||||
val->absfun = absfun;
|
||||
for (size_t i = 0; i < arity; i++) {
|
||||
val->args[i] = args[--n_args];
|
||||
}
|
||||
|
||||
res = &val->header;
|
||||
}
|
||||
|
||||
PgfClosure* val =
|
||||
tmp_env->closure->code(state, tmp_env->closure);
|
||||
|
||||
PgfIndirection* indir = (PgfIndirection*) closure;
|
||||
indir->header.code = pgf_evaluate_indirection;
|
||||
indir->val = val;
|
||||
|
||||
return val;
|
||||
}
|
||||
case PGF_EXPR_TYPED: {
|
||||
PgfExprTyped* etyped = ei.data;
|
||||
expr = etyped->expr;
|
||||
break;
|
||||
}
|
||||
case PGF_EXPR_IMPL_ARG: {
|
||||
PgfExprImplArg* eimpl = ei.data;
|
||||
expr = eimpl->expr;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
gu_impossible();
|
||||
indir->header.code = state->eval_gates->evaluate_indirection;
|
||||
indir->val = res;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
case PGF_EXPR_VAR: {
|
||||
PgfExprVar* evar = ei.data;
|
||||
PgfEnv* tmp_env = env;
|
||||
size_t i = evar->var;
|
||||
while (i > 0) {
|
||||
tmp_env = tmp_env->next;
|
||||
if (tmp_env == NULL) {
|
||||
GuExnData* err_data = gu_raise(state->err, PgfExn);
|
||||
if (err_data) {
|
||||
err_data->data = "invalid de Bruijn index";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
void
|
||||
pgf_evaluate_save_variables(PgfEvalState* state, PgfValue* val)
|
||||
{
|
||||
size_t n_args = val->absfun->arity;
|
||||
for (size_t i = 0; i < n_args; i++) {
|
||||
gu_buf_push(state->stack, PgfClosure*, val->args[i]);
|
||||
}
|
||||
}
|
||||
res = tmp_env->closure;
|
||||
|
||||
void
|
||||
pgf_evaluate_slide(PgfEvalState* state, size_t a, size_t b)
|
||||
{
|
||||
size_t len = gu_buf_length(state->stack);
|
||||
for (size_t i = 0; i < b-a; i++) {
|
||||
PgfClosure* c = gu_buf_get(state->stack, PgfClosure*, len-(b-a)+i);
|
||||
gu_buf_set(state->stack, PgfClosure*, len-b+i, c);
|
||||
PgfIndirection* indir = (PgfIndirection*) closure;
|
||||
indir->header.code = state->eval_gates->evaluate_indirection;
|
||||
indir->val = res;
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
gu_buf_trim_n(state->stack, a);
|
||||
case PGF_EXPR_TYPED: {
|
||||
PgfExprTyped* etyped = ei.data;
|
||||
expr = etyped->expr;
|
||||
goto repeat;
|
||||
}
|
||||
case PGF_EXPR_IMPL_ARG: {
|
||||
PgfExprImplArg* eimpl = ei.data;
|
||||
expr = eimpl->expr;
|
||||
goto repeat;
|
||||
}
|
||||
default:
|
||||
gu_impossible();
|
||||
}
|
||||
|
||||
free(args);
|
||||
return res;
|
||||
}
|
||||
|
||||
static PgfExpr
|
||||
pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
||||
{
|
||||
clos = clos->code(state, clos);
|
||||
clos = state->eval_gates->enter(state, clos);
|
||||
if (clos == NULL)
|
||||
return gu_null_variant;
|
||||
|
||||
@@ -290,13 +189,13 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
||||
size_t n_args = 0;
|
||||
PgfClosure** args;
|
||||
|
||||
if (clos->code == pgf_evaluate_value) {
|
||||
if (clos->code == state->eval_gates->evaluate_value) {
|
||||
PgfValue* val = (PgfValue*) clos;
|
||||
|
||||
expr = val->absfun->ep.expr;
|
||||
n_args = gu_seq_length(val->absfun->type->hypos);
|
||||
args = val->args;
|
||||
} else if (clos->code == pgf_evaluate_value_gen) {
|
||||
} else if (clos->code == state->eval_gates->evaluate_value_gen) {
|
||||
PgfValueGen* val = (PgfValueGen*) clos;
|
||||
|
||||
PgfExprVar *evar =
|
||||
@@ -305,9 +204,9 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
||||
&expr, pool);
|
||||
evar->var = level - val->level - 1;
|
||||
|
||||
n_args = val->n_args;
|
||||
n_args = val->n_args/sizeof(PgfClosure*);
|
||||
args = val->args;
|
||||
} else if (clos->code == pgf_evaluate_value_meta) {
|
||||
} else if (clos->code == state->eval_gates->evaluate_value_meta) {
|
||||
PgfValueMeta* val = (PgfValueMeta*) clos;
|
||||
|
||||
PgfExprMeta *emeta =
|
||||
@@ -316,16 +215,16 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
||||
&expr, pool);
|
||||
emeta->id = val->id;
|
||||
|
||||
n_args = val->n_args;
|
||||
n_args = val->n_args / sizeof(PgfClosure*);
|
||||
args = val->args;
|
||||
} else if (clos->code == pgf_evaluate_value_lit) {
|
||||
} else if (clos->code == state->eval_gates->evaluate_value_lit) {
|
||||
PgfValueLit* val = (PgfValueLit*) clos;
|
||||
|
||||
PgfExprLit *elit =
|
||||
gu_new_variant(PGF_EXPR_LIT,
|
||||
PgfExprLit,
|
||||
&expr, pool);
|
||||
|
||||
|
||||
GuVariantInfo i = gu_variant_open(val->lit);
|
||||
switch (i.tag) {
|
||||
case PGF_LITERAL_STR: {
|
||||
@@ -362,13 +261,18 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
||||
default:
|
||||
gu_impossible();
|
||||
}
|
||||
} else {
|
||||
} else if (clos->code == state->eval_gates->evaluate_value_pap) {
|
||||
PgfValuePAP *pap = (PgfValuePAP*) clos;
|
||||
|
||||
n_args = pap->n_args / sizeof(PgfClosure*);
|
||||
args = pap->args;
|
||||
} else if (clos->code == state->eval_gates->evaluate_value_lambda) {
|
||||
PgfExprThunk *old_thunk = (PgfExprThunk*) clos;
|
||||
PgfExprAbs *old_eabs = gu_variant_open(old_thunk->expr).data;
|
||||
|
||||
PgfValueGen* gen =
|
||||
gu_new(PgfValueGen, state->pool);
|
||||
gen->header.code = pgf_evaluate_value_gen;
|
||||
gen->header.code = state->eval_gates->evaluate_value_gen;
|
||||
gen->level = level;
|
||||
gen->n_args = 0;
|
||||
|
||||
@@ -378,7 +282,7 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
||||
|
||||
PgfExprThunk* new_thunk =
|
||||
gu_new(PgfExprThunk, state->pool);
|
||||
new_thunk->header.code = pgf_evaluate_expr_thunk;
|
||||
new_thunk->header.code = state->eval_gates->evaluate_expr_thunk;
|
||||
new_thunk->env = new_env;
|
||||
new_thunk->expr = old_eabs->body;
|
||||
|
||||
@@ -389,6 +293,8 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
||||
eabs->bind_type = old_eabs->bind_type;
|
||||
eabs->id = gu_format_string(pool, "v%d", level);
|
||||
eabs->body = pgf_value2expr(state, level+1, &new_thunk->header, pool);
|
||||
} else {
|
||||
gu_impossible();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < n_args; i++) {
|
||||
@@ -412,15 +318,24 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
|
||||
PgfExpr
|
||||
pgf_compute(PgfPGF* pgf, PgfExpr expr, GuExn* err, GuPool* pool, GuPool* out_pool)
|
||||
{
|
||||
PgfEvalState* state = gu_new(PgfEvalState, pool);
|
||||
size_t n_closures = gu_seq_length(pgf->abstract.eval_gates->defrules);
|
||||
|
||||
PgfEvalState* state =
|
||||
gu_new_flex(pool, PgfEvalState, globals, n_closures);
|
||||
state->pgf = pgf;
|
||||
state->eval_gates = pgf->abstract.eval_gates;
|
||||
state->pool = pool;
|
||||
state->err = err;
|
||||
state->stack = gu_new_buf(PgfClosure*, pool);
|
||||
|
||||
PgfFunction* defrules = gu_seq_data(state->eval_gates->defrules);
|
||||
for (size_t i = 0; i < n_closures; i++) {
|
||||
state->globals[i].header.code = defrules[i];
|
||||
state->globals[i].val = NULL;
|
||||
}
|
||||
|
||||
PgfExprThunk* thunk =
|
||||
gu_new(PgfExprThunk, pool);
|
||||
thunk->header.code = pgf_evaluate_expr_thunk;
|
||||
thunk->header.code = state->eval_gates->evaluate_expr_thunk;
|
||||
thunk->env = NULL;
|
||||
thunk->expr = expr;
|
||||
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
#ifndef PGF_EVALUATOR_H_
|
||||
#define PGF_EVALUATOR_H_
|
||||
|
||||
struct PgfEvalState {
|
||||
typedef void *PgfFunction;
|
||||
|
||||
typedef struct {
|
||||
PgfFunction code;
|
||||
} PgfClosure;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfClosure* val;
|
||||
} PgfIndirection;
|
||||
|
||||
typedef struct {
|
||||
PgfPGF* pgf;
|
||||
PgfEvalGates* eval_gates; // cached from pgf->abstr->eval_gates
|
||||
GuPool* pool;
|
||||
GuExn* err;
|
||||
GuBuf* stack;
|
||||
PgfIndirection globals[]; // derived from gu_seq_data(pgf->abstr->eval_gates->defrules)
|
||||
} PgfEvalState;
|
||||
|
||||
typedef struct PgfEnv PgfEnv;
|
||||
|
||||
struct PgfEnv {
|
||||
PgfEnv* next;
|
||||
PgfClosure* closure;
|
||||
};
|
||||
|
||||
typedef struct PgfClosure PgfClosure;
|
||||
typedef struct PgfEvalState PgfEvalState;
|
||||
|
||||
typedef PgfClosure* (*PgfFunction)(PgfEvalState* state, PgfClosure* val);
|
||||
|
||||
struct PgfClosure {
|
||||
PgfFunction code;
|
||||
};
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfEnv* env;
|
||||
PgfExpr expr;
|
||||
} PgfExprThunk;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
@@ -23,16 +39,53 @@ typedef struct {
|
||||
PgfClosure* args[];
|
||||
} PgfValue;
|
||||
|
||||
PgfClosure*
|
||||
pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure);
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
int level;
|
||||
size_t n_args;
|
||||
PgfClosure* args[];
|
||||
} PgfValueGen;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfEnv* env;
|
||||
PgfMetaId id;
|
||||
size_t n_args;
|
||||
PgfClosure* args[];
|
||||
} PgfValueMeta;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfLiteral lit;
|
||||
} PgfValueLit;
|
||||
|
||||
typedef struct {
|
||||
PgfClosure header;
|
||||
PgfClosure* fun;
|
||||
size_t n_args;
|
||||
PgfClosure* args[];
|
||||
} PgfValuePAP;
|
||||
|
||||
struct PgfEvalGates {
|
||||
PgfFunction evaluate_expr_thunk;
|
||||
PgfFunction evaluate_indirection;
|
||||
PgfFunction evaluate_value;
|
||||
PgfFunction evaluate_value_gen;
|
||||
PgfFunction evaluate_value_meta;
|
||||
PgfFunction evaluate_value_lit;
|
||||
PgfFunction evaluate_value_pap;
|
||||
PgfFunction evaluate_value_lambda;
|
||||
|
||||
PgfFunction update_closure;
|
||||
PgfFunction update_pap;
|
||||
|
||||
PgfClosure* (*enter)(PgfEvalState* state, PgfClosure* closure);
|
||||
|
||||
GuFinalizer fin;
|
||||
GuSeq* defrules;
|
||||
};
|
||||
|
||||
PgfClosure*
|
||||
pgf_evaluate_value(PgfEvalState* state, PgfClosure* closure);
|
||||
|
||||
void
|
||||
pgf_evaluate_save_variables(PgfEvalState* state, PgfValue* val);
|
||||
|
||||
void
|
||||
pgf_evaluate_slide(PgfEvalState* state, size_t a, size_t b);
|
||||
pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,12 @@ typedef struct {
|
||||
#define JIT_V0 JIT_V(0)
|
||||
#define JIT_V1 JIT_V(1)
|
||||
#define JIT_V2 JIT_V(2)
|
||||
#define JIT_FPR0 JIT_FPR(0)
|
||||
#define JIT_FPR1 JIT_FPR(1)
|
||||
#define JIT_FPR2 JIT_FPR(2)
|
||||
#define JIT_FPR3 JIT_FPR(3)
|
||||
#define JIT_FPR4 JIT_FPR(4)
|
||||
#define JIT_FPR5 JIT_FPR(5)
|
||||
|
||||
#define _jitl _jit.jitl
|
||||
|
||||
@@ -149,7 +155,7 @@ typedef union jit_code {
|
||||
#define jit_xorr_ul(d, s1, s2) jit_xorr_l((d), (s1), (s2))
|
||||
|
||||
#define jit_addr_p(d, s1, s2) jit_addr_ul((d), (s1), (s2))
|
||||
#define jit_addi_p(d, rs, is) jit_addi_ul((d), (rs), (long) (is))
|
||||
#define jit_addi_p(d, rs, is) (jit_addi_ul((d), (rs), (long) (is)), _jit.x.pc)
|
||||
#define jit_movr_p(d, rs) jit_movr_ul((d), (rs))
|
||||
#define jit_subr_p(d, s1, s2) jit_subr_ul((d), (s1), (s2))
|
||||
#define jit_subi_p(d, rs, is) jit_subi_ul((d), (rs), (long) (is))
|
||||
|
||||
@@ -101,6 +101,8 @@ struct jit_local_state {
|
||||
#define jit_ret() jit_base_ret (_jitl.alloca_offset)
|
||||
#endif
|
||||
|
||||
#define jit_bare_ret(IM) ((IM == 0) ? RET_() : RETi(IM))
|
||||
|
||||
#define jit_calli(label) (CALLm( ((unsigned long) (label))), _jit.x.pc)
|
||||
#define jit_callr(reg) CALLsr(reg)
|
||||
|
||||
@@ -108,16 +110,6 @@ struct jit_local_state {
|
||||
#define jit_finish(sub) (_jitl.finish_ref = jit_calli((sub)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0, _jitl.finish_ref)
|
||||
#define jit_finishr(reg) (jit_callr((reg)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define jit_tail_finishr(reg) jit_base_tail_finishr(-12, reg)
|
||||
#else
|
||||
#define jit_tail_finishr(reg) jit_base_tail_finishr(_jitl.alloca_offset, reg)
|
||||
#endif
|
||||
|
||||
#define jit_base_tail_finishr(ofs, reg) \
|
||||
(((ofs) < 0 ? LEAVE_() : POPLr(_EBP)), \
|
||||
POPLr(_EDI), POPLr(_ESI), POPLr(_EBX), jit_jmpr(reg))
|
||||
|
||||
#define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||
#define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||
#define jit_arg_s() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||
|
||||
@@ -190,14 +190,6 @@ struct jit_local_state {
|
||||
? (ADDQir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) \
|
||||
: 0))
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define jit_tail_finishr(reg) jit_base_tail_finishr(-12, reg)
|
||||
#else
|
||||
#define jit_tail_finishr(reg) jit_base_tail_finishr(_jitl.alloca_offset, reg)
|
||||
#endif
|
||||
|
||||
#define jit_base_tail_finishr(ofs, reg)
|
||||
|
||||
#define jit_retval_l(rd) ((void)jit_movr_l ((rd), _EAX))
|
||||
#define jit_arg_i() (_jitl.nextarg_geti < JIT_ARG_MAX \
|
||||
? _jitl.nextarg_geti++ \
|
||||
@@ -273,6 +265,7 @@ static int jit_arg_reg_order[] = { _EDI, _ESI, _EDX, _ECX, _R8D, _R9D };
|
||||
#define jit_patch_at(jump_pc,v) (_jitl.long_jumps ? jit_patch_long_at((jump_pc)-3, v) : jit_patch_short_at(jump_pc, v))
|
||||
#define jit_patch_calli(pa,pv) (*_PSL((pa) - sizeof(long)) = _jit_SL((pv)))
|
||||
#define jit_ret() (LEAVE_(), POPQr(_R14), POPQr(_R13), POPQr(_R12), POPQr(_EBX), RET_())
|
||||
#define jit_bare_ret(IM) ((IM == 0) ? RET_() : RETi(IM))
|
||||
|
||||
/* Memory */
|
||||
|
||||
|
||||
@@ -441,7 +441,7 @@ pgf_read_absfun(PgfReader* rdr, PgfAbstr* abstr)
|
||||
switch (tag) {
|
||||
case 0:
|
||||
absfun->defns = NULL;
|
||||
absfun->function = NULL;
|
||||
absfun->closure_id = 0;
|
||||
break;
|
||||
case 1: {
|
||||
GuLength length = pgf_read_len(rdr);
|
||||
@@ -557,6 +557,8 @@ pgf_read_abstract(PgfReader* rdr, PgfAbstr* abstract)
|
||||
abstract->aflags = pgf_read_flags(rdr);
|
||||
gu_return_on_exn(rdr->err, );
|
||||
|
||||
abstract->eval_gates = pgf_jit_gates(rdr);
|
||||
|
||||
abstract->funs = pgf_read_absfuns(rdr, abstract);
|
||||
gu_return_on_exn(rdr->err, );
|
||||
|
||||
|
||||
@@ -53,6 +53,9 @@ typedef struct PgfJitState PgfJitState;
|
||||
PgfJitState*
|
||||
pgf_new_jit(PgfReader* rdr);
|
||||
|
||||
PgfEvalGates*
|
||||
pgf_jit_gates(PgfReader* rdr);
|
||||
|
||||
void
|
||||
pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr,
|
||||
PgfAbsCat* abscat);
|
||||
|
||||
Reference in New Issue
Block a user