]> granicus.if.org Git - jq/commitdiff
Add some preprocessor junk to make codegen cleaner.
authorStephen Dolan <mu@netsoc.tcd.ie>
Sun, 25 Nov 2012 23:49:57 +0000 (23:49 +0000)
committerStephen Dolan <mu@netsoc.tcd.ie>
Sun, 25 Nov 2012 23:49:57 +0000 (23:49 +0000)
compile.c
compile.h
parser.y
testdata

index e0f675f85cf407d92c6f7204c2cf64b16af91d55..68d3fb926ece886499915ca901252858ac67d791 100644 (file)
--- 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) {
index 5390420b64414f49b39e7f5e56a853632e39bb43..9a5f92e5082a9401dd785af03a00af2a186fcd96 100644 (file)
--- 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
index d64a2ec5d90598bc66adf5da73fbc2781f9b637c..73943c3811045ab11c2d10ddc9f87397aaaad8ff 100644 (file)
--- 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)));
index 8cd5e27caedc03d327201f3fdfcadf0e3db9ecf1..4fff7167f103b0e7889209d34941b5348b1f0e4d 100644 (file)
--- a/testdata
+++ b/testdata
@@ -97,6 +97,11 @@ null
 1
 1
 
+1,.
+[]
+1
+[]
+
 [.]
 [2]
 [[2]]