Add some preprocessor junk to make codegen cleaner.
This commit is contained in:
1 parent
f19ba32fdd
commit
924aeda504
4 files changed
+91
-121
No files matched your search
@@ -297,150 +297,115 @@ block block_bind(block binder, block body, int bindflags) {
|
|||||||
|
|
||||||
|
|
||||||
block gen_subexp(block a) {
|
block gen_subexp(block a) {
|
||||||
block c = gen_noop();
|
return BLOCK(gen_op_simple(DUP), a, gen_op_simple(SWAP));
|
||||||
block_append(&c, gen_op_simple(DUP));
|
|
||||||
block_append(&c, a);
|
|
||||||
block_append(&c, gen_op_simple(SWAP));
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_both(block a, block b) {
|
block gen_both(block a, block b) {
|
||||||
block c = gen_noop();
|
|
||||||
block jump = gen_op_targetlater(JUMP);
|
block jump = gen_op_targetlater(JUMP);
|
||||||
block fork = gen_op_targetlater(FORK);
|
block fork = gen_op_target(FORK, jump);
|
||||||
block_append(&c, fork);
|
block c = BLOCK(fork, a, jump, b);
|
||||||
block_append(&c, a);
|
|
||||||
block_append(&c, jump);
|
|
||||||
inst_set_target(fork, c);
|
|
||||||
block_append(&c, b);
|
|
||||||
inst_set_target(jump, c);
|
inst_set_target(jump, c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
block gen_collect(block expr) {
|
block gen_collect(block expr) {
|
||||||
block c = gen_noop();
|
|
||||||
block_append(&c, gen_op_simple(DUP));
|
|
||||||
block_append(&c, gen_op_const(LOADK, jv_array()));
|
|
||||||
block array_var = block_bind(gen_op_var_unbound(STOREV, "collect"),
|
block array_var = block_bind(gen_op_var_unbound(STOREV, "collect"),
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
gen_noop(), OP_HAS_VARIABLE);
|
||||||
block_append(&c, array_var);
|
block c = BLOCK(gen_op_simple(DUP), gen_op_const(LOADK, jv_array()), array_var);
|
||||||
|
|
||||||
block tail = {0};
|
block tail = BLOCK(gen_op_simple(DUP),
|
||||||
block_append(&tail, gen_op_simple(DUP));
|
gen_op_var_bound(LOADV, array_var),
|
||||||
block_append(&tail, gen_op_var_bound(LOADV, array_var));
|
gen_op_simple(SWAP),
|
||||||
block_append(&tail, gen_op_simple(SWAP));
|
gen_op_simple(APPEND),
|
||||||
block_append(&tail, gen_op_simple(APPEND));
|
gen_op_var_bound(STOREV, array_var),
|
||||||
block_append(&tail, gen_op_var_bound(STOREV, array_var));
|
gen_op_simple(BACKTRACK));
|
||||||
block_append(&tail, gen_op_simple(BACKTRACK));
|
|
||||||
|
|
||||||
block_append(&c, gen_op_target(FORK, tail));
|
return BLOCK(c,
|
||||||
block_append(&c, expr);
|
gen_op_target(FORK, tail),
|
||||||
block_append(&c, tail);
|
expr,
|
||||||
|
tail,
|
||||||
block_append(&c, gen_op_var_bound(LOADV, array_var));
|
gen_op_var_bound(LOADV, array_var));
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_assign(block expr) {
|
block gen_assign(block expr) {
|
||||||
block c = gen_noop();
|
|
||||||
block_append(&c, gen_op_simple(DUP));
|
|
||||||
block result_var = block_bind(gen_op_var_unbound(STOREV, "result"),
|
block result_var = block_bind(gen_op_var_unbound(STOREV, "result"),
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
gen_noop(), OP_HAS_VARIABLE);
|
||||||
block_append(&c, result_var);
|
|
||||||
|
|
||||||
block loop = gen_noop();
|
block loop = BLOCK(gen_op_simple(DUP),
|
||||||
block_append(&loop, gen_op_simple(DUP));
|
expr,
|
||||||
block_append(&loop, expr);
|
gen_op_var_bound(ASSIGN, result_var),
|
||||||
block_append(&loop, gen_op_var_bound(ASSIGN, result_var));
|
gen_op_simple(BACKTRACK));
|
||||||
block_append(&loop, gen_op_simple(BACKTRACK));
|
|
||||||
|
|
||||||
block_append(&c, gen_op_target(FORK, loop));
|
return BLOCK(gen_op_simple(DUP),
|
||||||
block_append(&c, loop);
|
result_var,
|
||||||
block_append(&c, gen_op_var_bound(LOADV, result_var));
|
gen_op_target(FORK, loop),
|
||||||
return c;
|
loop,
|
||||||
|
gen_op_var_bound(LOADV, result_var));
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_definedor(block a, block b) {
|
block gen_definedor(block a, block b) {
|
||||||
// var found := false
|
// var found := false
|
||||||
block c = gen_op_simple(DUP);
|
|
||||||
block_append(&c, gen_op_const(LOADK, jv_false()));
|
|
||||||
block found_var = block_bind(gen_op_var_unbound(STOREV, "found"),
|
block found_var = block_bind(gen_op_var_unbound(STOREV, "found"),
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
gen_noop(), OP_HAS_VARIABLE);
|
||||||
block_append(&c, found_var);
|
block init = BLOCK(gen_op_simple(DUP), gen_op_const(LOADK, jv_false()), found_var);
|
||||||
|
|
||||||
// if found, backtrack. Otherwise execute b
|
// if found, backtrack. Otherwise execute b
|
||||||
block tail = gen_op_simple(DUP);
|
|
||||||
block_append(&tail, gen_op_var_bound(LOADV, found_var));
|
|
||||||
block backtrack = gen_op_simple(BACKTRACK);
|
block backtrack = gen_op_simple(BACKTRACK);
|
||||||
block_append(&tail, gen_op_target(JUMP_F, backtrack));
|
block tail = BLOCK(gen_op_simple(DUP),
|
||||||
block_append(&tail, backtrack);
|
gen_op_var_bound(LOADV, found_var),
|
||||||
block_append(&tail, gen_op_simple(POP));
|
gen_op_target(JUMP_F, backtrack),
|
||||||
block_append(&tail, b);
|
backtrack,
|
||||||
|
gen_op_simple(POP),
|
||||||
|
b);
|
||||||
|
|
||||||
// try again
|
// try again
|
||||||
block if_notfound = gen_op_simple(BACKTRACK);
|
block if_notfound = gen_op_simple(BACKTRACK);
|
||||||
|
|
||||||
// found := true, produce result
|
// found := true, produce result
|
||||||
block if_found = gen_op_simple(DUP);
|
block if_found = BLOCK(gen_op_simple(DUP),
|
||||||
block_append(&if_found, gen_op_const(LOADK, jv_true()));
|
gen_op_const(LOADK, jv_true()),
|
||||||
block_append(&if_found, gen_op_var_bound(STOREV, found_var));
|
gen_op_var_bound(STOREV, found_var),
|
||||||
block_append(&if_found, gen_op_target(JUMP, tail));
|
gen_op_target(JUMP, tail));
|
||||||
|
|
||||||
block_append(&c, gen_op_target(FORK, if_notfound));
|
return BLOCK(init,
|
||||||
block_append(&c, a);
|
gen_op_target(FORK, if_notfound),
|
||||||
block_append(&c, gen_op_target(JUMP_F, if_found));
|
a,
|
||||||
block_append(&c, if_found);
|
gen_op_target(JUMP_F, if_found),
|
||||||
block_append(&c, if_notfound);
|
if_found,
|
||||||
block_append(&c, tail);
|
if_notfound,
|
||||||
|
tail);
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_condbranch(block iftrue, block iffalse) {
|
block gen_condbranch(block iftrue, block iffalse) {
|
||||||
block b = gen_noop();
|
iftrue = BLOCK(iftrue, gen_op_target(JUMP, iffalse));
|
||||||
block_append(&iftrue, gen_op_target(JUMP, iffalse));
|
return BLOCK(gen_op_target(JUMP_F, iftrue), iftrue, iffalse);
|
||||||
block_append(&b, gen_op_target(JUMP_F, iftrue));
|
|
||||||
block_append(&b, iftrue);
|
|
||||||
block_append(&b, iffalse);
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_and(block a, block b) {
|
block gen_and(block a, block b) {
|
||||||
// a and b = if a then (if b then true else false) else false
|
// a and b = if a then (if b then true else false) else false
|
||||||
block code = gen_op_simple(DUP);
|
return BLOCK(gen_op_simple(DUP), a,
|
||||||
block_append(&code, a);
|
gen_condbranch(BLOCK(gen_op_simple(POP),
|
||||||
|
b,
|
||||||
block if_a_true = gen_op_simple(POP);
|
gen_condbranch(gen_op_const(LOADK, jv_true()),
|
||||||
block_append(&if_a_true, b);
|
gen_op_const(LOADK, jv_false()))),
|
||||||
block_append(&if_a_true, gen_condbranch(gen_op_const(LOADK, jv_true()),
|
BLOCK(gen_op_simple(POP), gen_op_const(LOADK, jv_false()))));
|
||||||
gen_op_const(LOADK, jv_false())));
|
|
||||||
block_append(&code, gen_condbranch(if_a_true,
|
|
||||||
block_join(gen_op_simple(POP), gen_op_const(LOADK, jv_false()))));
|
|
||||||
return code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_or(block a, block b) {
|
block gen_or(block a, block b) {
|
||||||
// a or b = if a then true else (if b then true else false)
|
// a or b = if a then true else (if b then true else false)
|
||||||
block code = gen_op_simple(DUP);
|
return BLOCK(gen_op_simple(DUP), a,
|
||||||
block_append(&code, a);
|
gen_condbranch(BLOCK(gen_op_simple(POP), gen_op_const(LOADK, jv_true())),
|
||||||
|
BLOCK(gen_op_simple(POP),
|
||||||
block if_a_false = gen_op_simple(POP);
|
b,
|
||||||
block_append(&if_a_false, b);
|
gen_condbranch(gen_op_const(LOADK, jv_true()),
|
||||||
block_append(&if_a_false, gen_condbranch(gen_op_const(LOADK, jv_true()),
|
gen_op_const(LOADK, jv_false())))));
|
||||||
gen_op_const(LOADK, jv_false())));
|
|
||||||
block_append(&code, gen_condbranch(block_join(gen_op_simple(POP), gen_op_const(LOADK, jv_true())),
|
|
||||||
if_a_false));
|
|
||||||
return code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_cond(block cond, block iftrue, block iffalse) {
|
block gen_cond(block cond, block iftrue, block iffalse) {
|
||||||
block b = gen_op_simple(DUP);
|
return BLOCK(gen_op_simple(DUP), cond,
|
||||||
block_append(&b, cond);
|
gen_condbranch(BLOCK(gen_op_simple(POP), iftrue),
|
||||||
block_append(&b, gen_condbranch(block_join(gen_op_simple(POP), iftrue),
|
BLOCK(gen_op_simple(POP), iffalse)));
|
||||||
block_join(gen_op_simple(POP), iffalse)));
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_cbinding(struct symbol_table* t, block code) {
|
block gen_cbinding(struct symbol_table* t, block code) {
|
||||||
|
|||||||
@@ -52,4 +52,20 @@ void block_free(block);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Here's some horrible preprocessor gunk so that code
|
||||||
|
// sequences can be contructed as BLOCK(block1, block2, block3)
|
||||||
|
|
||||||
|
#define BLOCK_1(b1) (b1)
|
||||||
|
#define BLOCK_2(b1,b2) (block_join((b1),(b2)))
|
||||||
|
#define BLOCK_3(b1,b2,b3) (block_join(BLOCK_2(b1,b2),(b3)))
|
||||||
|
#define BLOCK_4(b1,b2,b3,b4) (block_join(BLOCK_3(b1,b2,b3),(b4)))
|
||||||
|
#define BLOCK_5(b1,b2,b3,b4,b5) (block_join(BLOCK_4(b1,b2,b3,b4),(b5)))
|
||||||
|
#define BLOCK_6(b1,b2,b3,b4,b5,b6) (block_join(BLOCK_5(b1,b2,b3,b4,b5),(b6)))
|
||||||
|
#define BLOCK_7(b1,b2,b3,b4,b5,b6,b7) (block_join(BLOCK_6(b1,b2,b3,b4,b5,b6),(b7)))
|
||||||
|
|
||||||
|
#define BLOCK_IDX(_1,_2,_3,_4,_5,_6,_7,NAME,...) NAME
|
||||||
|
#define BLOCK(...) \
|
||||||
|
BLOCK_IDX(__VA_ARGS__, BLOCK_7, BLOCK_6, BLOCK_5, BLOCK_4, BLOCK_3, BLOCK_2, BLOCK_1)(__VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -129,14 +129,11 @@ int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static block gen_dictpair(block k, block v) {
|
static block gen_dictpair(block k, block v) {
|
||||||
block b = gen_subexp(k);
|
return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT));
|
||||||
block_append(&b, gen_subexp(v));
|
|
||||||
block_append(&b, gen_op_simple(INSERT));
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static block gen_index(block obj, block key) {
|
static block gen_index(block obj, block key) {
|
||||||
return block_join(obj, block_join(gen_subexp(key), gen_op_simple(INDEX)));
|
return BLOCK(obj, gen_subexp(key), gen_op_simple(INDEX));
|
||||||
}
|
}
|
||||||
|
|
||||||
static block gen_binop(block a, block b, int op) {
|
static block gen_binop(block a, block b, int op) {
|
||||||
@@ -155,25 +152,19 @@ static block gen_binop(block a, block b, int op) {
|
|||||||
}
|
}
|
||||||
assert(funcname);
|
assert(funcname);
|
||||||
|
|
||||||
block c = gen_noop();
|
return BLOCK(gen_subexp(a), gen_subexp(b),
|
||||||
block_append(&c, gen_subexp(a));
|
gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, funcname)));
|
||||||
block_append(&c, gen_subexp(b));
|
|
||||||
block_append(&c, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, funcname)));
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static block gen_format(block a) {
|
static block gen_format(block a) {
|
||||||
return block_join(a, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, "tostring")));
|
return BLOCK(a, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, "tostring")));
|
||||||
}
|
}
|
||||||
|
|
||||||
static block gen_update(block a, block op, int optype) {
|
static block gen_update(block a, block op, int optype) {
|
||||||
block assign = a;
|
|
||||||
block_append(&assign, gen_op_simple(DUP));
|
|
||||||
if (optype) {
|
if (optype) {
|
||||||
op = gen_binop(gen_noop(), op, optype);
|
op = gen_binop(gen_noop(), op, optype);
|
||||||
}
|
}
|
||||||
block_append(&assign, op);
|
return gen_assign(BLOCK(a, gen_op_simple(DUP), op));
|
||||||
return gen_assign(assign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
@@ -201,9 +192,9 @@ FuncDef Exp %prec ';' {
|
|||||||
} |
|
} |
|
||||||
|
|
||||||
Term "as" '$' IDENT '|' Exp {
|
Term "as" '$' IDENT '|' Exp {
|
||||||
$$ = gen_op_simple(DUP);
|
$$ = BLOCK(gen_op_simple(DUP), $1,
|
||||||
block_append(&$$, $1);
|
block_bind(gen_op_var_unbound(STOREV, jv_string_value($4)),
|
||||||
block_append(&$$, block_bind(gen_op_var_unbound(STOREV, jv_string_value($4)), $6, OP_HAS_VARIABLE));
|
$6, OP_HAS_VARIABLE));
|
||||||
jv_free($4);
|
jv_free($4);
|
||||||
} |
|
} |
|
||||||
|
|
||||||
@@ -216,12 +207,7 @@ Term "as" '$' IDENT '|' Exp {
|
|||||||
} |
|
} |
|
||||||
|
|
||||||
Exp '=' Exp {
|
Exp '=' Exp {
|
||||||
block assign = gen_op_simple(DUP);
|
$$ = gen_assign(BLOCK(gen_op_simple(DUP), $3, gen_op_simple(SWAP), $1, gen_op_simple(SWAP)));
|
||||||
block_append(&assign, $3);
|
|
||||||
block_append(&assign, gen_op_simple(SWAP));
|
|
||||||
block_append(&assign, $1);
|
|
||||||
block_append(&assign, gen_op_simple(SWAP));
|
|
||||||
$$ = gen_assign(assign);
|
|
||||||
} |
|
} |
|
||||||
|
|
||||||
Exp "or" Exp {
|
Exp "or" Exp {
|
||||||
@@ -394,9 +380,7 @@ String {
|
|||||||
$$ = gen_op_const(LOADK, jv_array());
|
$$ = gen_op_const(LOADK, jv_array());
|
||||||
} |
|
} |
|
||||||
'{' MkDict '}' {
|
'{' MkDict '}' {
|
||||||
$$ = gen_subexp(gen_op_const(LOADK, jv_object()));
|
$$ = BLOCK(gen_subexp(gen_op_const(LOADK, jv_object())), $2, gen_op_simple(POP));
|
||||||
block_append(&$$, $2);
|
|
||||||
block_append(&$$, gen_op_simple(POP));
|
|
||||||
} |
|
} |
|
||||||
'$' IDENT {
|
'$' IDENT {
|
||||||
$$ = gen_location(@$, gen_op_var_unbound(LOADV, jv_string_value($2)));
|
$$ = gen_location(@$, gen_op_var_unbound(LOADV, jv_string_value($2)));
|
||||||
|
|||||||
Reference in new issue
Block a user