From: Stephen Dolan Date: Sun, 25 Nov 2012 23:49:57 +0000 (+0000) Subject: Add some preprocessor junk to make codegen cleaner. X-Git-Tag: jq-1.2~41 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=924aeda5043d76296c651d20025881a60161b7d3;p=jq Add some preprocessor junk to make codegen cleaner. --- diff --git a/compile.c b/compile.c index e0f675f..68d3fb9 100644 --- a/compile.c +++ b/compile.c @@ -297,150 +297,115 @@ block block_bind(block binder, block body, int bindflags) { block gen_subexp(block a) { - block c = gen_noop(); - block_append(&c, gen_op_simple(DUP)); - block_append(&c, a); - block_append(&c, gen_op_simple(SWAP)); - return c; + return BLOCK(gen_op_simple(DUP), a, gen_op_simple(SWAP)); } block gen_both(block a, block b) { - block c = gen_noop(); block jump = gen_op_targetlater(JUMP); - block fork = gen_op_targetlater(FORK); - block_append(&c, fork); - block_append(&c, a); - block_append(&c, jump); - inst_set_target(fork, c); - block_append(&c, b); + block fork = gen_op_target(FORK, jump); + block c = BLOCK(fork, a, jump, b); inst_set_target(jump, c); return c; } 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"), gen_noop(), OP_HAS_VARIABLE); - block_append(&c, array_var); - - block tail = {0}; - block_append(&tail, gen_op_simple(DUP)); - block_append(&tail, gen_op_var_bound(LOADV, array_var)); - block_append(&tail, gen_op_simple(SWAP)); - block_append(&tail, gen_op_simple(APPEND)); - block_append(&tail, gen_op_var_bound(STOREV, array_var)); - block_append(&tail, gen_op_simple(BACKTRACK)); + block c = BLOCK(gen_op_simple(DUP), gen_op_const(LOADK, jv_array()), array_var); - block_append(&c, gen_op_target(FORK, tail)); - block_append(&c, expr); - block_append(&c, tail); + block tail = BLOCK(gen_op_simple(DUP), + gen_op_var_bound(LOADV, array_var), + gen_op_simple(SWAP), + gen_op_simple(APPEND), + gen_op_var_bound(STOREV, array_var), + gen_op_simple(BACKTRACK)); - block_append(&c, gen_op_var_bound(LOADV, array_var)); - - return c; + return BLOCK(c, + gen_op_target(FORK, tail), + expr, + tail, + gen_op_var_bound(LOADV, array_var)); } 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"), gen_noop(), OP_HAS_VARIABLE); - block_append(&c, result_var); - block loop = gen_noop(); - block_append(&loop, gen_op_simple(DUP)); - block_append(&loop, expr); - block_append(&loop, gen_op_var_bound(ASSIGN, result_var)); - block_append(&loop, gen_op_simple(BACKTRACK)); + block loop = BLOCK(gen_op_simple(DUP), + expr, + gen_op_var_bound(ASSIGN, result_var), + gen_op_simple(BACKTRACK)); - block_append(&c, gen_op_target(FORK, loop)); - block_append(&c, loop); - block_append(&c, gen_op_var_bound(LOADV, result_var)); - return c; + return BLOCK(gen_op_simple(DUP), + result_var, + gen_op_target(FORK, loop), + loop, + gen_op_var_bound(LOADV, result_var)); } block gen_definedor(block a, block b) { // 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"), 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 - block tail = gen_op_simple(DUP); - block_append(&tail, gen_op_var_bound(LOADV, found_var)); block backtrack = gen_op_simple(BACKTRACK); - block_append(&tail, gen_op_target(JUMP_F, backtrack)); - block_append(&tail, backtrack); - block_append(&tail, gen_op_simple(POP)); - block_append(&tail, b); + block tail = BLOCK(gen_op_simple(DUP), + gen_op_var_bound(LOADV, found_var), + gen_op_target(JUMP_F, backtrack), + backtrack, + gen_op_simple(POP), + b); // try again block if_notfound = gen_op_simple(BACKTRACK); // found := true, produce result - block if_found = gen_op_simple(DUP); - block_append(&if_found, gen_op_const(LOADK, jv_true())); - block_append(&if_found, gen_op_var_bound(STOREV, found_var)); - block_append(&if_found, gen_op_target(JUMP, tail)); - - block_append(&c, gen_op_target(FORK, if_notfound)); - block_append(&c, a); - block_append(&c, gen_op_target(JUMP_F, if_found)); - block_append(&c, if_found); - block_append(&c, if_notfound); - block_append(&c, tail); + block if_found = BLOCK(gen_op_simple(DUP), + gen_op_const(LOADK, jv_true()), + gen_op_var_bound(STOREV, found_var), + gen_op_target(JUMP, tail)); - return c; + return BLOCK(init, + gen_op_target(FORK, if_notfound), + a, + gen_op_target(JUMP_F, if_found), + if_found, + if_notfound, + tail); } block gen_condbranch(block iftrue, block iffalse) { - block b = gen_noop(); - block_append(&iftrue, gen_op_target(JUMP, iffalse)); - block_append(&b, gen_op_target(JUMP_F, iftrue)); - block_append(&b, iftrue); - block_append(&b, iffalse); - return b; + iftrue = BLOCK(iftrue, gen_op_target(JUMP, iffalse)); + return BLOCK(gen_op_target(JUMP_F, iftrue), iftrue, iffalse); } block gen_and(block a, block b) { // a and b = if a then (if b then true else false) else false - block code = gen_op_simple(DUP); - block_append(&code, a); - - block if_a_true = gen_op_simple(POP); - block_append(&if_a_true, b); - block_append(&if_a_true, gen_condbranch(gen_op_const(LOADK, jv_true()), - 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; + return BLOCK(gen_op_simple(DUP), a, + gen_condbranch(BLOCK(gen_op_simple(POP), + b, + gen_condbranch(gen_op_const(LOADK, jv_true()), + gen_op_const(LOADK, jv_false()))), + BLOCK(gen_op_simple(POP), gen_op_const(LOADK, jv_false())))); } block gen_or(block a, block b) { // a or b = if a then true else (if b then true else false) - block code = gen_op_simple(DUP); - block_append(&code, a); - - block if_a_false = gen_op_simple(POP); - block_append(&if_a_false, b); - block_append(&if_a_false, gen_condbranch(gen_op_const(LOADK, jv_true()), - 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; + return BLOCK(gen_op_simple(DUP), a, + gen_condbranch(BLOCK(gen_op_simple(POP), gen_op_const(LOADK, jv_true())), + BLOCK(gen_op_simple(POP), + b, + gen_condbranch(gen_op_const(LOADK, jv_true()), + gen_op_const(LOADK, jv_false()))))); } block gen_cond(block cond, block iftrue, block iffalse) { - block b = gen_op_simple(DUP); - block_append(&b, cond); - block_append(&b, gen_condbranch(block_join(gen_op_simple(POP), iftrue), - block_join(gen_op_simple(POP), iffalse))); - return b; + return BLOCK(gen_op_simple(DUP), cond, + gen_condbranch(BLOCK(gen_op_simple(POP), iftrue), + BLOCK(gen_op_simple(POP), iffalse))); } block gen_cbinding(struct symbol_table* t, block code) { diff --git a/compile.h b/compile.h index 5390420..9a5f92e 100644 --- a/compile.h +++ b/compile.h @@ -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 diff --git a/parser.y b/parser.y index d64a2ec..73943c3 100644 --- a/parser.y +++ b/parser.y @@ -129,14 +129,11 @@ int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors, } static block gen_dictpair(block k, block v) { - block b = gen_subexp(k); - block_append(&b, gen_subexp(v)); - block_append(&b, gen_op_simple(INSERT)); - return b; + return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT)); } 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) { @@ -155,25 +152,19 @@ static block gen_binop(block a, block b, int op) { } assert(funcname); - block c = gen_noop(); - block_append(&c, gen_subexp(a)); - block_append(&c, gen_subexp(b)); - block_append(&c, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, funcname))); - return c; + return BLOCK(gen_subexp(a), gen_subexp(b), + gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, funcname))); } 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) { - block assign = a; - block_append(&assign, gen_op_simple(DUP)); if (optype) { op = gen_binop(gen_noop(), op, optype); } - block_append(&assign, op); - return gen_assign(assign); + return gen_assign(BLOCK(a, gen_op_simple(DUP), op)); } %} @@ -201,9 +192,9 @@ FuncDef Exp %prec ';' { } | Term "as" '$' IDENT '|' Exp { - $$ = gen_op_simple(DUP); - block_append(&$$, $1); - block_append(&$$, block_bind(gen_op_var_unbound(STOREV, jv_string_value($4)), $6, OP_HAS_VARIABLE)); + $$ = BLOCK(gen_op_simple(DUP), $1, + block_bind(gen_op_var_unbound(STOREV, jv_string_value($4)), + $6, OP_HAS_VARIABLE)); jv_free($4); } | @@ -216,12 +207,7 @@ Term "as" '$' IDENT '|' Exp { } | Exp '=' Exp { - block assign = gen_op_simple(DUP); - 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); + $$ = gen_assign(BLOCK(gen_op_simple(DUP), $3, gen_op_simple(SWAP), $1, gen_op_simple(SWAP))); } | Exp "or" Exp { @@ -394,9 +380,7 @@ String { $$ = gen_op_const(LOADK, jv_array()); } | '{' MkDict '}' { - $$ = gen_subexp(gen_op_const(LOADK, jv_object())); - block_append(&$$, $2); - block_append(&$$, gen_op_simple(POP)); + $$ = BLOCK(gen_subexp(gen_op_const(LOADK, jv_object())), $2, gen_op_simple(POP)); } | '$' IDENT { $$ = gen_location(@$, gen_op_var_unbound(LOADV, jv_string_value($2))); diff --git a/testdata b/testdata index 8cd5e27..4fff716 100644 --- a/testdata +++ b/testdata @@ -97,6 +97,11 @@ null 1 1 +1,. +[] +1 +[] + [.] [2] [[2]]