1
0
forked from GitHub/gf-core

pattern matching in def rules is now supported

This commit is contained in:
kr.angelov
2014-08-11 15:53:41 +00:00
parent d3b9652b81
commit c30e2df228
6 changed files with 76 additions and 60 deletions

View File

@@ -50,7 +50,7 @@ mkCanon2pgf opts gr am = do
funs = Map.fromList [(i2i f, (mkType [] ty, arity, mkDef arity mdef, 0)) |
((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs,
let arity = mkArrity ma]
let arity = mkArrity ma ty]
cats = Map.fromList [(i2i c, (snd (mkContext [] cont),catfuns c, 0)) |
((m,c),AbsCat (Just (L _ cont))) <- adefs]
@@ -150,9 +150,9 @@ mkDef arity (Just eqs) = Just ([C.Equ ps' (mkExp scope' e) | L _ (ps,e) <- eqs,
)
mkDef arity Nothing = Nothing
mkArrity (Just a) = a
mkArrity Nothing = 0
mkArrity (Just a) ty = a
mkArrity Nothing ty = let (ctxt, _, _) = GM.typeForm ty
in length ctxt
genCncCats gr am cm cdefs =
let (index,cats) = mkCncCats 0 cdefs

View File

@@ -136,6 +136,12 @@ 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)
{

View File

@@ -65,6 +65,9 @@ gu_buf_avail(GuBuf* buf);
void*
gu_buf_data(GuBuf* buf);
void*
gu_buf_last(GuBuf* buf);
GuSeq*
gu_buf_data_seq(GuBuf* buf);

View File

@@ -9,12 +9,6 @@ struct PgfEnv {
PgfClosure* closure;
};
typedef PgfClosure* (*PgfFunction)(PgfEvalState* state, PgfClosure* val);
struct PgfClosure {
PgfFunction code;
};
typedef struct {
PgfClosure header;
PgfEnv* env;
@@ -26,12 +20,6 @@ typedef struct {
PgfClosure* val;
} PgfIndirection;
typedef struct {
PgfClosure header;
PgfAbsFun* absfun;
PgfClosure* args[];
} PgfValue;
typedef struct {
PgfClosure header;
int level;
@@ -62,26 +50,7 @@ pgf_evaluate_indirection(PgfEvalState* state, PgfClosure* closure)
PgfClosure*
pgf_evaluate_value(PgfEvalState* state, PgfClosure* closure)
{
PgfValue* val = (PgfValue*) closure;
size_t n_args = gu_seq_length(val->absfun->type->hypos) +
gu_buf_length(state->stack);
PgfValue* new_val =
gu_new_flex(state->pool, PgfValue, args, n_args);
new_val->header.code = pgf_evaluate_value;
new_val->absfun = val->absfun;
size_t i = 0;
while (i < gu_seq_length(val->absfun->type->hypos)) {
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;
return closure;
}
static PgfClosure*
@@ -233,7 +202,7 @@ pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure)
if (absfun->function != NULL) {
val = (PgfValue*) ((PgfFunction) absfun->function)(state, closure);
} else {
size_t n_args = gu_buf_length(state->stack);
size_t n_args = absfun->arity;
val = gu_new_flex(state->pool, PgfValue, args, n_args);
val->header.code = pgf_evaluate_value;
@@ -290,6 +259,15 @@ pgf_evaluate_expr_thunk(PgfEvalState* state, PgfClosure* closure)
}
}
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]);
}
}
static PgfExpr
pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool)
{

View File

@@ -13,7 +13,8 @@ struct PgfJitState {
jit_state jit;
jit_insn *buf;
char *save_ip_ptr;
GuBuf* patches;
GuBuf* call_patches;
GuBuf* label_patches;
};
#define _jit (rdr->jit_state->jit)
@@ -23,6 +24,11 @@ typedef struct {
jit_insn *ref;
} PgfCallPatch;
typedef struct {
size_t label;
jit_insn *ref;
} PgfLabelPatch;
// Between two calls to pgf_jit_make_space we are not allowed
// to emit more that JIT_CODE_WINDOW bytes. This is not quite
// safe but this is how GNU lightning is designed.
@@ -71,7 +77,8 @@ PgfJitState*
pgf_new_jit(PgfReader* rdr)
{
PgfJitState* state = gu_new(PgfJitState, rdr->tmp_pool);
state->patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool);
state->call_patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool);
state->label_patches = gu_new_buf(PgfLabelPatch, rdr->tmp_pool);
state->buf = NULL;
state->save_ip_ptr = NULL;
return state;
@@ -233,7 +240,7 @@ pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr,
PgfCallPatch patch;
patch.cid = hypo->type->cid;
patch.ref = jit_finish(jit_forward());
gu_buf_push(rdr->jit_state->patches, PgfCallPatch, patch);
gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch);
#ifdef PGF_JIT_DEBUG
gu_puts(" RET\n", out, err);
@@ -336,8 +343,20 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
size_t curr_offset = 0;
size_t curr_label = 0;
gu_buf_flush(rdr->jit_state->label_patches);
for (size_t i = 0; i < n_instrs; i++) {
size_t labels_count = gu_buf_length(rdr->jit_state->label_patches);
if (labels_count > 0) {
PgfLabelPatch* patch =
gu_buf_index(rdr->jit_state->label_patches, PgfLabelPatch, labels_count-1);
if (patch->label == curr_label) {
jit_patch(patch->ref);
gu_buf_trim_n(rdr->jit_state->label_patches, 1);
}
}
#ifdef PGF_JIT_DEBUG
gu_printf(out, err, "%04d ", curr_label++);
#endif
@@ -354,19 +373,16 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
jit_prepare(1);
jit_pusharg_p(JIT_V0);
jit_finish(gu_buf_length);
jit_subi_i(JIT_V2, JIT_RET, index+1);
jit_lshi_i(JIT_V2, JIT_V2, 2);
jit_prepare(1);
jit_pusharg_p(JIT_V0);
jit_finish(gu_buf_data);
jit_ldxr_p(JIT_V0, JIT_RET, JIT_V2);
jit_finish(gu_buf_last);
jit_ldxr_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*));
jit_prepare(2);
jit_pusharg_p(JIT_V0);
jit_getarg_p(JIT_V2, es_arg);
jit_pusharg_p(JIT_V2);
jit_ldr_p(JIT_V0, JIT_V0);
jit_callr(JIT_V0);
jit_finishr(JIT_V0);
jit_retval_p(JIT_V1);
jit_ldxi_p(JIT_V0, JIT_V1, offsetof(PgfValue, absfun));
break;
}
case PGF_INSTR_CASE: {
@@ -375,6 +391,24 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
#ifdef PGF_JIT_DEBUG
gu_printf(out, err, "CASE %s %04d\n", id, curr_label+offset);
#endif
jit_insn *jump=
jit_bnei_i(jit_forward(), JIT_V0, (int) jit_forward());
PgfLabelPatch label_patch;
label_patch.label = curr_label+offset;
label_patch.ref = jump;
gu_buf_push(rdr->jit_state->label_patches, PgfLabelPatch, label_patch);
PgfCallPatch call_patch;
call_patch.cid = id;
call_patch.ref = jump-6;
gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, call_patch);
jit_prepare(2);
jit_pusharg_p(JIT_V1);
jit_getarg_p(JIT_V2, es_arg);
jit_pusharg_p(JIT_V2);
jit_finish(pgf_evaluate_save_variables);
break;
}
case PGF_INSTR_CASE_INT: {
@@ -434,7 +468,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0);
curr_offset++;
gu_buf_push(rdr->jit_state->patches, PgfCallPatch, patch);
gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch);
break;
}
case PGF_INSTR_PUT_CLOSURE: {
@@ -486,13 +520,8 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
jit_prepare(1);
jit_pusharg_p(JIT_V0);
jit_finish(gu_buf_length);
jit_subi_i(JIT_V2, JIT_RET, index+1);
jit_lshi_i(JIT_V2, JIT_V2, 2);
jit_prepare(1);
jit_pusharg_p(JIT_V0);
jit_finish(gu_buf_data);
jit_ldxr_p(JIT_V0, JIT_RET, JIT_V2);
jit_finish(gu_buf_last);
jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*));
jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0);
break;
}
@@ -536,10 +565,10 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
void
pgf_jit_done(PgfReader* rdr, PgfAbstr* abstr)
{
size_t n_patches = gu_buf_length(rdr->jit_state->patches);
size_t n_patches = gu_buf_length(rdr->jit_state->call_patches);
for (size_t i = 0; i < n_patches; i++) {
PgfCallPatch* patch =
gu_buf_index(rdr->jit_state->patches, PgfCallPatch, i);
gu_buf_index(rdr->jit_state->call_patches, PgfCallPatch, i);
PgfAbsCat* arg =
gu_map_get(abstr->cats, patch->cid, PgfAbsCat*);

View File

@@ -106,7 +106,7 @@ struct jit_local_state {
#define jit_pusharg_i(rs) PUSHLr(rs)
#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)), )
#define jit_finishr(reg) (jit_callr((reg)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
#define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))