]> granicus.if.org Git - jq/commitdiff
Constant fold objects
authorNicolas Williams <nico@cryptonector.com>
Sun, 10 Aug 2014 01:47:03 +0000 (20:47 -0500)
committerNicolas Williams <nico@cryptonector.com>
Sun, 10 Aug 2014 01:47:03 +0000 (20:47 -0500)
compile.c
compile.h
parser.y

index 612920c02263b3ad26a914aa5b0696b8c061b5d3..6005f7c32ead5647276f82bce52e6afba9b6faa6 100644 (file)
--- a/compile.c
+++ b/compile.c
@@ -499,7 +499,51 @@ block gen_both(block a, block b) {
   return c;
 }
 
-block gen_const_array(block expr) {
+block gen_const_object(block expr) {
+  int is_const = 1;
+  jv o = jv_object();
+  jv k = jv_null();
+  jv v = jv_null();
+  for (inst *i = expr.first; i; i = i->next) {
+    if (i->op != SUBEXP_BEGIN ||
+        i->next == NULL ||
+        i->next->op != LOADK ||
+        i->next->next == NULL ||
+        i->next->next->op != SUBEXP_END) {
+      is_const = 0;
+      break;
+    }
+    k = jv_copy(i->next->imm.constant);
+    i = i->next->next->next;
+    if (i == NULL ||
+        i->op != SUBEXP_BEGIN ||
+        i->next == NULL ||
+        i->next->op != LOADK ||
+        i->next->next == NULL ||
+        i->next->next->op != SUBEXP_END) {
+      is_const = 0;
+      break;
+    }
+    v = jv_copy(i->next->imm.constant);
+    i = i->next->next->next;
+    if (i == NULL || i->op != INSERT) {
+      is_const = 0;
+      break;
+    }
+    o = jv_object_set(o, k, v);
+  }
+  if (!is_const) {
+    jv_free(o);
+    jv_free(k);
+    jv_free(v);
+    block b = {0,0};
+    return b;
+  }
+  block_free(expr);
+  return gen_const(o);
+}
+
+static block gen_const_array(block expr) {
   /*
    * An expr of all constant elements looks like this:
    *
index ff8b8972cb97c92d40d3c38eea595c2af8b0f84d..b0162ae21baa4775b74f664e6b8ac5587d08acc5 100644 (file)
--- a/compile.h
+++ b/compile.h
@@ -36,6 +36,7 @@ block gen_lambda(block body);
 block gen_call(const char* name, block body);
 block gen_subexp(block a);
 block gen_both(block a, block b);
+block gen_const_object(block expr);
 block gen_collect(block expr);
 block gen_reduce(const char* varname, block source, block init, block body);
 block gen_foreach(const char* varname, block source, block init, block update, block extract);
index 8fffb7cce6aa81e7631f62db66d14a2279aebd76..9f92594802fcd55b56b3dff52ac534aef5a88d68 100644 (file)
--- a/parser.y
+++ b/parser.y
@@ -631,7 +631,11 @@ FORMAT {
   $$ = gen_const(jv_array()); 
 } |
 '{' MkDict '}' { 
-  $$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP));
+  block o = gen_const_object($2);
+  if (o.first != NULL)
+    $$ = o;
+  else
+    $$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP));
 } |
 '$' IDENT {
   $$ = gen_location(@$, locations, gen_op_unbound(LOADV, jv_string_value($2)));