diff options
author | Nicolas Williams <nico@cryptonector.com> | 2014-08-09 20:47:03 -0500 |
---|---|---|
committer | Nicolas Williams <nico@cryptonector.com> | 2014-08-09 20:47:03 -0500 |
commit | c321c3b86bb319156502985ee5174e3476a5ca8c (patch) | |
tree | 4ca3ff4f2bad85ee6f03de4ddd806866ed0f4e17 | |
parent | f87521183f5c499b3c58e016c5936ade14819fd3 (diff) |
Constant fold objects
-rw-r--r-- | compile.c | 46 | ||||
-rw-r--r-- | compile.h | 1 | ||||
-rw-r--r-- | parser.y | 6 |
3 files changed, 51 insertions, 2 deletions
@@ -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: * @@ -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); @@ -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))); |