From: Nicolas Williams Date: Sun, 10 Aug 2014 01:47:03 +0000 (-0500) Subject: Constant fold objects X-Git-Tag: jq-1.5rc1~81 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c321c3b86bb319156502985ee5174e3476a5ca8c;p=jq Constant fold objects --- diff --git a/compile.c b/compile.c index 612920c..6005f7c 100644 --- 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: * diff --git a/compile.h b/compile.h index ff8b897..b0162ae 100644 --- 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); diff --git a/parser.y b/parser.y index 8fffb7c..9f92594 100644 --- 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)));