From f19ba32fdde2bfea89e6c10a9183d130b6de99aa Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 25 Nov 2012 23:07:43 +0000 Subject: [PATCH 01/62] Minor refactor of function call setup to allow for multiple arguments. --- compile.c | 122 +++++++++++++++++++++++++++++++++++++++++--------- opcode.c | 1 + opcode_list.h | 1 + 3 files changed, 102 insertions(+), 22 deletions(-) diff --git a/compile.c b/compile.c index fe50c70a..e0f675f8 100644 --- a/compile.c +++ b/compile.c @@ -30,7 +30,9 @@ struct inst { // are bound, and even then only for instructions which bind. struct inst* bound_by; char* symbol; + block subfn; + block arglist; // This instruction is compiled as part of which function? // (only used during block_compile) @@ -47,6 +49,7 @@ static inst* inst_new(opcode op) { i->bound_by = 0; i->symbol = 0; i->subfn = gen_noop(); + i->arglist = gen_noop(); i->source = UNKNOWN_LOCATION; return i; } @@ -56,6 +59,9 @@ static void inst_free(struct inst* i) { if (opcode_describe(i->op)->flags & OP_HAS_BLOCK) { block_free(i->subfn); } + if (opcode_describe(i->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { + block_free(i->arglist); + } if (opcode_describe(i->op)->flags & OP_HAS_CONSTANT) { jv_free(i->imm.constant); } @@ -186,30 +192,11 @@ block gen_op_block_bound(opcode op, block binder) { } block gen_op_call(opcode op, block arglist) { + assert(op == CALL_1_1); assert(opcode_describe(op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST); inst* i = inst_new(op); - block prelude = gen_noop(); - block call = inst_block(i); - int nargs = 0; - inst* curr = 0; - while ((curr = block_take(&arglist))) { - assert(opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); - block bcurr = inst_block(curr); - switch (curr->op) { - default: assert(0 && "Unknown type of parameter"); break; - case CLOSURE_REF: - block_append(&call, bcurr); - break; - case CLOSURE_CREATE: - block_append(&prelude, bcurr); - block_append(&call, gen_op_block_bound(CLOSURE_REF, bcurr)); - break; - } - nargs++; - } - assert(nargs < 100); //FIXME - i->imm.intval = nargs; - return block_join(prelude, call); + i->arglist = arglist; + return block_join(inst_block(i), inst_block(inst_new(CALLSEQ_END))); } static void inst_join(inst* a, inst* b) { @@ -220,6 +207,32 @@ static void inst_join(inst* a, inst* b) { b->prev = a; } +static void block_insert_after(inst* i, block b) { + if (b.first) { + assert(b.last); + if (i->next) { + inst* j = i->next; + i->next = 0; + j->prev = 0; + inst_join(b.last, j); + } + inst_join(i, b.first); + } +} + +static void block_insert_before(inst* i, block b) { + if (b.first) { + assert(b.last); + if (i->prev) { + inst* j = i->prev; + i->prev = 0; + j->next = 0; + inst_join(j, b.first); + } + inst_join(b.last, i); + } +} + void block_append(block* b, block b2) { if (b2.first) { if (b->last) { @@ -266,6 +279,10 @@ static void block_bind_subblock(block binder, block body, int bindflags) { // binding recurses into closures block_bind_subblock(binder, i->subfn, bindflags); } + if (flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { + // binding recurses into argument list + block_bind_subblock(binder, i->arglist, bindflags); + } } } @@ -457,12 +474,70 @@ static int count_cfunctions(block b) { return n; } + +// Expands call instructions into a calling sequence +// Checking for argument count compatibility happens later +static void expand_call_arglist(struct bytecode* bc, block b) { + for (inst* curr = b.first; curr; curr = curr->next) { + if (opcode_describe(curr->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { + assert(curr->op == CALL_1_1); + assert(curr->next && curr->next->op == CALLSEQ_END); + // We expand the argument list as a series of instructions + block arglist = curr->arglist; + curr->arglist = gen_noop(); + assert(arglist.first && "zeroth argument (function to call) must be present"); + inst* function = arglist.first->bound_by; + assert(function); + + switch (function->op) { + default: assert(0 && "Unknown parameter type"); break; + case CLOSURE_CREATE: + case CLOSURE_PARAM: { + block prelude = gen_noop(); + block callargs = gen_noop(); + int nargs = 0; + for (inst* i; (i = block_take(&arglist));) { + assert(opcode_describe(i->op)->flags & OP_IS_CALL_PSEUDO); + block b = inst_block(i); + switch (i->op) { + default: assert(0 && "Unknown type of parameter"); break; + case CLOSURE_REF: + block_append(&callargs, b); + break; + case CLOSURE_CREATE: + block_append(&prelude, b); + block_append(&callargs, gen_op_block_bound(CLOSURE_REF, b)); + break; + } + nargs++; + } + + assert(!arglist.first); + block_insert_before(curr, prelude); + block_insert_after(curr, callargs); + curr->imm.intval = nargs; + break; + } + + case CLOSURE_CREATE_C: + // Arguments to C functions not yet supported + assert(block_is_single(arglist)); + assert(arglist.first->op == CLOSURE_REF); + block_insert_after(curr, arglist); + curr->imm.intval = 1; + break; + } + } + } +} + static int compile(struct locfile* locations, struct bytecode* bc, block b) { int errors = 0; int pos = 0; int var_frame_idx = 0; bc->nsubfunctions = 0; bc->nclosures = 0; + expand_call_arglist(bc, b); for (inst* curr = b.first; curr; curr = curr->next) { if (!curr->next) assert(curr == b.last); pos += opcode_length(curr->op); @@ -484,6 +559,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { assert(curr->bound_by == curr); curr->imm.intval = bc->nsubfunctions++; } + if (curr->op == CLOSURE_PARAM) { assert(curr->bound_by == curr); curr->imm.intval = bc->nclosures++; @@ -524,9 +600,11 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { int opflags = op->flags; assert(!(op->flags & OP_IS_CALL_PSEUDO)); if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { + assert(curr->op == CALL_1_1); int nargs = curr->imm.intval; assert(nargs > 0); code[pos++] = (uint16_t)nargs; + int desired_params = 0; for (int i=0; inext; diff --git a/opcode.c b/opcode.c index bc259c22..6e85e709 100644 --- a/opcode.c +++ b/opcode.c @@ -7,6 +7,7 @@ #define BRANCH OP_HAS_BRANCH, 2 #define CFUNC (OP_HAS_SYMBOL | OP_HAS_CFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST), 2 #define UFUNC (OP_HAS_UFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST), 2 +#define CALLSEQ_END_IMM (OP_IS_CALL_PSEUDO), 0 #define CLOSURE_PARAM_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 #define CLOSURE_CREATE_IMM (OP_HAS_BLOCK | OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 #define CLOSURE_CREATE_C_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 diff --git a/opcode_list.h b/opcode_list.h index 306373fb..00817a13 100644 --- a/opcode_list.h +++ b/opcode_list.h @@ -24,6 +24,7 @@ OP(CALL_BUILTIN_3_1, CFUNC, 3, 1) OP(CALL_1_1, UFUNC, 1, 1) OP(RET, NONE, 1, 1) +OP(CALLSEQ_END, CALLSEQ_END_IMM, 0, 0) OP(CLOSURE_PARAM, CLOSURE_PARAM_IMM, 0, 0) OP(CLOSURE_REF, CLOSURE_REF_IMM, 0, 0) OP(CLOSURE_CREATE, CLOSURE_CREATE_IMM, 0, 0) From 924aeda5043d76296c651d20025881a60161b7d3 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 25 Nov 2012 23:49:57 +0000 Subject: [PATCH 02/62] Add some preprocessor junk to make codegen cleaner. --- compile.c | 153 +++++++++++++++++++++--------------------------------- compile.h | 16 ++++++ parser.y | 38 ++++---------- testdata | 5 ++ 4 files changed, 91 insertions(+), 121 deletions(-) diff --git a/compile.c b/compile.c index e0f675f8..68d3fb92 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 c = BLOCK(gen_op_simple(DUP), gen_op_const(LOADK, jv_array()), 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 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_target(FORK, tail)); - block_append(&c, expr); - block_append(&c, tail); - - 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 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)); - 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); - - 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 5390420b..9a5f92e5 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 d64a2ec5..73943c38 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 8cd5e27c..4fff7167 100644 --- a/testdata +++ b/testdata @@ -97,6 +97,11 @@ null 1 1 +1,. +[] +1 +[] + [.] [2] [[2]] From 3e3fe5195947a0af711959e2dedc9c84a697c5fb Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 26 Nov 2012 00:39:01 +0000 Subject: [PATCH 03/62] Clean up function creation API and epilogue generation. --- builtin.c | 20 ++++++-------------- compile.c | 50 +++++++++++++++++++++++++++----------------------- compile.h | 3 +-- execute.c | 1 - parser.y | 11 ++++------- 5 files changed, 38 insertions(+), 47 deletions(-) diff --git a/builtin.c b/builtin.c index 3d726854..e1144e3d 100644 --- a/builtin.c +++ b/builtin.c @@ -252,32 +252,24 @@ static void f_type(jv input[], jv output[]) { } static block j_empty() { - return gen_op_block_defn(CLOSURE_CREATE, "empty", gen_op_simple(BACKTRACK)); + return gen_function("empty", gen_op_simple(BACKTRACK)); } static block j_false() { - return gen_op_block_defn(CLOSURE_CREATE, "false", - block_join(gen_op_const(LOADK, jv_false()), - gen_op_simple(RET))); + return gen_function("false", gen_op_const(LOADK, jv_false())); } static block j_true() { - return gen_op_block_defn(CLOSURE_CREATE, "true", - block_join(gen_op_const(LOADK, jv_true()), - gen_op_simple(RET))); + return gen_function("true", gen_op_const(LOADK, jv_true())); } static block j_null() { - return gen_op_block_defn(CLOSURE_CREATE, "null", - block_join(gen_op_const(LOADK, jv_null()), - gen_op_simple(RET))); + return gen_function("null", gen_op_const(LOADK, jv_null())); } static block j_not() { - return gen_op_block_defn(CLOSURE_CREATE, "not", - block_join(gen_condbranch(gen_op_const(LOADK, jv_false()), - gen_op_const(LOADK, jv_true())), - gen_op_simple(RET))); + return gen_function("not", gen_condbranch(gen_op_const(LOADK, jv_false()), + gen_op_const(LOADK, jv_true()))); } static struct cfunction function_list[] = { diff --git a/compile.c b/compile.c index 68d3fb92..b2878b1a 100644 --- a/compile.c +++ b/compile.c @@ -161,22 +161,6 @@ block gen_op_symbol(opcode op, const char* sym) { return inst_block(i); } -block gen_op_block_defn(opcode op, const char* name, block block) { - assert(opcode_describe(op)->flags & OP_IS_CALL_PSEUDO); - assert(opcode_describe(op)->flags & OP_HAS_BLOCK); - inst* i = inst_new(op); - i->subfn = block; - i->symbol = strdup(name); - return inst_block(i); -} - -static void block_bind_subblock(block binder, block body, int bindflags); -block gen_op_block_defn_rec(opcode op, const char* name, block blk) { - block b = gen_op_block_defn(op, name, blk); - block_bind_subblock(b, b, OP_IS_CALL_PSEUDO | OP_HAS_BINDING); - return b; -} - block gen_op_block_unbound(opcode op, const char* name) { assert(opcode_describe(op)->flags & OP_IS_CALL_PSEUDO); inst* i = inst_new(op); @@ -296,6 +280,16 @@ block block_bind(block binder, block body, int bindflags) { } +block gen_function(const char* name, block body) { + inst* i = inst_new(CLOSURE_CREATE); + i->subfn = body; + i->symbol = strdup(name); + block b = inst_block(i); + block_bind_subblock(b, b, OP_IS_CALL_PSEUDO | OP_HAS_BINDING); + return b; +} + + block gen_subexp(block a) { return BLOCK(gen_op_simple(DUP), a, gen_op_simple(SWAP)); } @@ -442,11 +436,13 @@ static int count_cfunctions(block b) { // Expands call instructions into a calling sequence // Checking for argument count compatibility happens later -static void expand_call_arglist(struct bytecode* bc, block b) { - for (inst* curr = b.first; curr; curr = curr->next) { +static block expand_call_arglist(struct bytecode* bc, block b) { + block ret = gen_noop(); + for (inst* curr; (curr = block_take(&b));) { if (opcode_describe(curr->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { assert(curr->op == CALL_1_1); - assert(curr->next && curr->next->op == CALLSEQ_END); + inst* seq_end = block_take(&b); + assert(seq_end && seq_end->op == CALLSEQ_END); // We expand the argument list as a series of instructions block arglist = curr->arglist; curr->arglist = gen_noop(); @@ -478,9 +474,8 @@ static void expand_call_arglist(struct bytecode* bc, block b) { } assert(!arglist.first); - block_insert_before(curr, prelude); - block_insert_after(curr, callargs); curr->imm.intval = nargs; + ret = BLOCK(ret, prelude, inst_block(curr), callargs, inst_block(seq_end)); break; } @@ -488,12 +483,21 @@ static void expand_call_arglist(struct bytecode* bc, block b) { // Arguments to C functions not yet supported assert(block_is_single(arglist)); assert(arglist.first->op == CLOSURE_REF); - block_insert_after(curr, arglist); curr->imm.intval = 1; + ret = BLOCK(ret, inst_block(curr), arglist, inst_block(seq_end)); break; } + } else { + ret = BLOCK(ret, inst_block(curr)); } } + if (bc->parent) { + // functions should end in a return + return BLOCK(ret, gen_op_simple(RET)); + } else { + // the toplevel should YIELD;BACKTRACK; when it finds an answer + return BLOCK(ret, gen_op_simple(YIELD), gen_op_simple(BACKTRACK)); + } } static int compile(struct locfile* locations, struct bytecode* bc, block b) { @@ -502,7 +506,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { int var_frame_idx = 0; bc->nsubfunctions = 0; bc->nclosures = 0; - expand_call_arglist(bc, b); + b = expand_call_arglist(bc, b); for (inst* curr = b.first; curr; curr = curr->next) { if (!curr->next) assert(curr == b.last); pos += opcode_length(curr->op); diff --git a/compile.h b/compile.h index 9a5f92e5..d9ed654e 100644 --- a/compile.h +++ b/compile.h @@ -22,12 +22,11 @@ block gen_op_const(opcode op, jv constant); block gen_op_target(opcode op, block target); block gen_op_var_unbound(opcode op, const char* name); block gen_op_var_bound(opcode op, block binder); -block gen_op_block_defn(opcode op, const char* name, block block); -block gen_op_block_defn_rec(opcode op, const char* name, block block); block gen_op_block_unbound(opcode op, const char* name); block gen_op_call(opcode op, block arglist); block gen_op_symbol(opcode op, const char* name); +block gen_function(const char* name, block body); block gen_subexp(block a); block gen_both(block a, block b); block gen_collect(block expr); diff --git a/execute.c b/execute.c index 93aefc0e..605db552 100644 --- a/execute.c +++ b/execute.c @@ -512,7 +512,6 @@ struct bytecode* jq_compile(const char* str) { struct bytecode* bc = 0; int nerrors = jq_parse(&locations, &program); if (nerrors == 0) { - block_append(&program, block_join(gen_op_simple(YIELD), gen_op_simple(BACKTRACK))); program = builtins_bind(program); nerrors = block_compile(program, &locations, &bc); block_free(program); diff --git a/parser.y b/parser.y index 73943c38..e8cbf6d8 100644 --- a/parser.y +++ b/parser.y @@ -305,14 +305,13 @@ QQSTRING_START QQString QQSTRING_END { FuncDef: "def" IDENT ':' Exp ';' { - block body = block_join($4, gen_op_simple(RET)); - $$ = gen_op_block_defn_rec(CLOSURE_CREATE, jv_string_value($2), body); + $$ = gen_function(jv_string_value($2), $4); jv_free($2); } | "def" IDENT '(' IDENT ')' ':' Exp ';' { - block body = block_bind(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)), block_join($7, gen_op_simple(RET)), OP_IS_CALL_PSEUDO); - $$ = gen_op_block_defn_rec(CLOSURE_CREATE, jv_string_value($2), body); + block body = block_bind(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)), $7, OP_IS_CALL_PSEUDO); + $$ = gen_function(jv_string_value($2), body); jv_free($2); jv_free($4); } @@ -393,9 +392,7 @@ IDENT { IDENT '(' Exp ')' { $$ = gen_op_call(CALL_1_1, block_join(gen_op_block_unbound(CLOSURE_REF, jv_string_value($1)), - block_bind(gen_op_block_defn(CLOSURE_CREATE, - "lambda", - block_join($3, gen_op_simple(RET))), + block_bind(gen_function("@lambda", $3), gen_noop(), OP_IS_CALL_PSEUDO))); $$ = gen_location(@1, $$); jv_free($1); From 4747f8681b3442af8b7916ac5bdfec712662c49b Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 26 Nov 2012 01:36:55 +0000 Subject: [PATCH 04/62] Transparent handling for CBV arguments to C functions. C function arguments closures are inlined before the call. --- compile.c | 63 +++++++++++++++++++++++++++++++++++-------------------- compile.h | 3 ++- execute.c | 1 - parser.y | 12 ++++------- 4 files changed, 46 insertions(+), 33 deletions(-) diff --git a/compile.c b/compile.c index b2878b1a..46e5dd88 100644 --- a/compile.c +++ b/compile.c @@ -175,14 +175,6 @@ block gen_op_block_bound(opcode op, block binder) { return b; } -block gen_op_call(opcode op, block arglist) { - assert(op == CALL_1_1); - assert(opcode_describe(op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST); - inst* i = inst_new(op); - i->arglist = arglist; - return block_join(inst_block(i), inst_block(inst_new(CALLSEQ_END))); -} - static void inst_join(inst* a, inst* b) { assert(a && b); assert(!a->next); @@ -289,6 +281,17 @@ block gen_function(const char* name, block body) { return b; } +block gen_lambda(block body) { + return gen_function("@lambda", body); +} + +block gen_call(const char* name, block args) { + inst* i = inst_new(CALL_1_1); + i->arglist = BLOCK(gen_op_block_unbound(CLOSURE_REF, name), args); + return BLOCK(inst_block(i), inst_block(inst_new(CALLSEQ_END))); +} + + block gen_subexp(block a) { return BLOCK(gen_op_simple(DUP), a, gen_op_simple(SWAP)); @@ -436,7 +439,7 @@ static int count_cfunctions(block b) { // Expands call instructions into a calling sequence // Checking for argument count compatibility happens later -static block expand_call_arglist(struct bytecode* bc, block b) { +static block expand_call_arglist(block b) { block ret = gen_noop(); for (inst* curr; (curr = block_take(&b));) { if (opcode_describe(curr->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { @@ -448,7 +451,7 @@ static block expand_call_arglist(struct bytecode* bc, block b) { curr->arglist = gen_noop(); assert(arglist.first && "zeroth argument (function to call) must be present"); inst* function = arglist.first->bound_by; - assert(function); + assert(function); // FIXME better errors switch (function->op) { default: assert(0 && "Unknown parameter type"); break; @@ -479,25 +482,30 @@ static block expand_call_arglist(struct bytecode* bc, block b) { break; } - case CLOSURE_CREATE_C: + case CLOSURE_CREATE_C: { // Arguments to C functions not yet supported - assert(block_is_single(arglist)); - assert(arglist.first->op == CLOSURE_REF); + inst* cfunction_ref = block_take(&arglist); + block prelude = gen_noop(); + int nargs = 0; + for (inst* i; (i = block_take(&arglist)); ) { + assert(i->op == CLOSURE_CREATE); // FIXME + block body = i->subfn; + i->subfn = gen_noop(); + inst_free(i); + prelude = BLOCK(prelude, gen_subexp(expand_call_arglist(body))); + nargs++; + } + assert(curr->op == CALL_1_1); curr->imm.intval = 1; - ret = BLOCK(ret, inst_block(curr), arglist, inst_block(seq_end)); + ret = BLOCK(ret, prelude, inst_block(curr), inst_block(cfunction_ref), inst_block(seq_end)); break; } + } } else { ret = BLOCK(ret, inst_block(curr)); } } - if (bc->parent) { - // functions should end in a return - return BLOCK(ret, gen_op_simple(RET)); - } else { - // the toplevel should YIELD;BACKTRACK; when it finds an answer - return BLOCK(ret, gen_op_simple(YIELD), gen_op_simple(BACKTRACK)); - } + return ret; } static int compile(struct locfile* locations, struct bytecode* bc, block b) { @@ -506,7 +514,14 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { int var_frame_idx = 0; bc->nsubfunctions = 0; bc->nclosures = 0; - b = expand_call_arglist(bc, b); + b = expand_call_arglist(b); + if (bc->parent) { + // functions should end in a return + b = BLOCK(b, gen_op_simple(RET)); + } else { + // the toplevel should YIELD;BACKTRACK; when it finds an answer + b = BLOCK(b, gen_op_simple(YIELD), gen_op_simple(BACKTRACK)); + } for (inst* curr = b.first; curr; curr = curr->next) { if (!curr->next) assert(curr == b.last); pos += opcode_length(curr->op); @@ -550,6 +565,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { subfn->globals = bc->globals; subfn->parent = bc; errors += compile(locations, subfn, curr->subfn); + curr->subfn = gen_noop(); } } else { bc->subfunctions = 0; @@ -571,7 +587,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { assert(curr->op == CALL_1_1); int nargs = curr->imm.intval; - assert(nargs > 0); + assert(nargs > 0 && nargs < 100); //FIXME code[pos++] = (uint16_t)nargs; int desired_params = 0; @@ -630,6 +646,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { } bc->constants = constant_pool; bc->nlocals = maxvar + 2; // FIXME: frames of size zero? + block_free(b); return errors; } diff --git a/compile.h b/compile.h index d9ed654e..c8a326da 100644 --- a/compile.h +++ b/compile.h @@ -23,10 +23,11 @@ block gen_op_target(opcode op, block target); block gen_op_var_unbound(opcode op, const char* name); block gen_op_var_bound(opcode op, block binder); block gen_op_block_unbound(opcode op, const char* name); -block gen_op_call(opcode op, block arglist); block gen_op_symbol(opcode op, const char* name); block gen_function(const char* name, block body); +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_collect(block expr); diff --git a/execute.c b/execute.c index 605db552..e1e9b511 100644 --- a/execute.c +++ b/execute.c @@ -514,7 +514,6 @@ struct bytecode* jq_compile(const char* str) { if (nerrors == 0) { program = builtins_bind(program); nerrors = block_compile(program, &locations, &bc); - block_free(program); } if (nerrors) { fprintf(stderr, "%d compile %s\n", nerrors, nerrors > 1 ? "errors" : "error"); diff --git a/parser.y b/parser.y index e8cbf6d8..92d6f7cd 100644 --- a/parser.y +++ b/parser.y @@ -152,12 +152,11 @@ static block gen_binop(block a, block b, int op) { } assert(funcname); - return BLOCK(gen_subexp(a), gen_subexp(b), - gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, funcname))); + return gen_call(funcname, BLOCK(gen_lambda(a), gen_lambda(b))); } static block gen_format(block a) { - return BLOCK(a, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, "tostring"))); + return BLOCK(a, gen_call("tostring", gen_noop())); } static block gen_update(block a, block op, int optype) { @@ -386,14 +385,11 @@ String { jv_free($2); } | IDENT { - $$ = gen_location(@$, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, jv_string_value($1)))); + $$ = gen_location(@$, gen_call(jv_string_value($1), gen_noop())); jv_free($1); } | IDENT '(' Exp ')' { - $$ = gen_op_call(CALL_1_1, - block_join(gen_op_block_unbound(CLOSURE_REF, jv_string_value($1)), - block_bind(gen_function("@lambda", $3), - gen_noop(), OP_IS_CALL_PSEUDO))); + $$ = gen_call(jv_string_value($1), gen_lambda($3)); $$ = gen_location(@1, $$); jv_free($1); } | From 4c658475681fdd2a12c9239976776684ff3d6375 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 26 Nov 2012 01:40:35 +0000 Subject: [PATCH 05/62] Raise a proper error from the lexer on unmatched },),] --- lexer.l | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lexer.l b/lexer.l index e0bb2b7b..b09ccce4 100644 --- a/lexer.l +++ b/lexer.l @@ -126,6 +126,10 @@ static int try_exit(int c, int state, yyscan_t yyscanner) { match = ')'; ret = QQSTRING_INTERP_END; break; + + default: + // may not be the best error to give + return INVALID_CHARACTER; } assert(match); if (match == c) { From 334a79b7040df4b5942da9688fbee0e5d3af9fd7 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 26 Nov 2012 18:53:47 +0000 Subject: [PATCH 06/62] Define bytecoded builtins more concisely. --- builtin.c | 50 +++++++++++++++++--------------------------------- 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/builtin.c b/builtin.c index e1144e3d..657a7a1f 100644 --- a/builtin.c +++ b/builtin.c @@ -251,27 +251,6 @@ static void f_type(jv input[], jv output[]) { jv_free(input[0]); } -static block j_empty() { - return gen_function("empty", gen_op_simple(BACKTRACK)); -} - -static block j_false() { - return gen_function("false", gen_op_const(LOADK, jv_false())); -} - -static block j_true() { - return gen_function("true", gen_op_const(LOADK, jv_true())); -} - -static block j_null() { - return gen_function("null", gen_op_const(LOADK, jv_null())); -} - -static block j_not() { - return gen_function("not", gen_condbranch(gen_op_const(LOADK, jv_false()), - gen_op_const(LOADK, jv_true()))); -} - static struct cfunction function_list[] = { {f_plus, "_plus", CALL_BUILTIN_3_1}, {f_minus, "_minus", CALL_BUILTIN_3_1}, @@ -294,13 +273,22 @@ static struct cfunction function_list[] = { static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])}; typedef block (*bytecoded_builtin)(); -static bytecoded_builtin bytecoded_builtins[] = { - j_empty, - j_false, - j_true, - j_null, - j_not, -}; +struct bytecoded_builtin { const char* name; block code; }; +static block bind_bytecoded_builtins(block b) { + struct bytecoded_builtin builtin_defs[] = { + {"empty", gen_op_simple(BACKTRACK)}, + {"false", gen_op_const(LOADK, jv_false())}, + {"true", gen_op_const(LOADK, jv_true())}, + {"null", gen_op_const(LOADK, jv_null())}, + {"not", gen_condbranch(gen_op_const(LOADK, jv_false()), + gen_op_const(LOADK, jv_true()))} + }; + block builtins = gen_noop(); + for (unsigned i=0; i Date: Mon, 26 Nov 2012 22:22:45 +0000 Subject: [PATCH 07/62] Move some higher-level JSON manipulation functions into jv_aux.{c,h} --- Makefile | 2 +- execute.c | 1 + jv.h | 61 ------------------------------------------------------ jv_aux.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ jv_aux.h | 11 ++++++++++ 5 files changed, 75 insertions(+), 62 deletions(-) create mode 100644 jv_aux.c create mode 100644 jv_aux.h diff --git a/Makefile b/Makefile index 9c5e1635..0c2d3177 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ version.gen.h: VERSION sed 's/.*/#define JQ_VERSION "&"/' $^ > $@ main.c: version.gen.h -JQ_SRC=parser.gen.c lexer.gen.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c +JQ_SRC=parser.gen.c lexer.gen.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c jq_test: $(JQ_SRC) jq_test.c diff --git a/execute.c b/execute.c index e1e9b511..fa6b1b79 100644 --- a/execute.c +++ b/execute.c @@ -14,6 +14,7 @@ #include "locfile.h" #include "jv.h" +#include "jv_aux.h" #include "parser.h" #include "builtin.h" diff --git a/jv.h b/jv.h index e67d614a..c81b2e24 100644 --- a/jv.h +++ b/jv.h @@ -112,67 +112,6 @@ jv jv_parse(const char* string); jv jv_parse_sized(const char* string, int length); -static jv jv_lookup(jv t, jv k) { - jv v; - if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) { - v = jv_object_get(t, k); - if (!jv_is_valid(v)) { - jv_free(v); - v = jv_null(); - } - } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) { - // FIXME: don't do lookup for noninteger index - v = jv_array_get(t, (int)jv_number_value(k)); - if (!jv_is_valid(v)) { - jv_free(v); - v = jv_null(); - } - } else if (jv_get_kind(t) == JV_KIND_NULL && - (jv_get_kind(k) == JV_KIND_STRING || jv_get_kind(k) == JV_KIND_NUMBER)) { - jv_free(t); - jv_free(k); - v = jv_null(); - } else { - v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with %s", - jv_kind_name(jv_get_kind(t)), - jv_kind_name(jv_get_kind(k)))); - jv_free(t); - jv_free(k); - } - return v; -} - -static jv jv_modify(jv t, jv k, jv v) { - int isnull = jv_get_kind(t) == JV_KIND_NULL; - if (jv_get_kind(k) == JV_KIND_STRING && - (jv_get_kind(t) == JV_KIND_OBJECT || isnull)) { - if (isnull) t = jv_object(); - t = jv_object_set(t, k, v); - } else if (jv_get_kind(k) == JV_KIND_NUMBER && - (jv_get_kind(t) == JV_KIND_ARRAY || isnull)) { - if (isnull) t = jv_array(); - t = jv_array_set(t, (int)jv_number_value(k), v); - } else { - jv err = jv_invalid_with_msg(jv_string_fmt("Cannot update field at %s index of %s", - jv_kind_name(jv_get_kind(t)), - jv_kind_name(jv_get_kind(v)))); - jv_free(t); - jv_free(k); - jv_free(v); - t = err; - } - return t; -} - -static jv jv_insert(jv root, jv value, jv* path, int pathlen) { - if (pathlen == 0) { - jv_free(root); - return value; - } - return jv_modify(root, jv_copy(*path), - jv_insert(jv_lookup(jv_copy(root), jv_copy(*path)), value, path+1, pathlen-1)); -} - diff --git a/jv_aux.c b/jv_aux.c new file mode 100644 index 00000000..483a75ef --- /dev/null +++ b/jv_aux.c @@ -0,0 +1,62 @@ +#include "jv_aux.h" + +jv jv_lookup(jv t, jv k) { + jv v; + if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) { + v = jv_object_get(t, k); + if (!jv_is_valid(v)) { + jv_free(v); + v = jv_null(); + } + } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) { + // FIXME: don't do lookup for noninteger index + v = jv_array_get(t, (int)jv_number_value(k)); + if (!jv_is_valid(v)) { + jv_free(v); + v = jv_null(); + } + } else if (jv_get_kind(t) == JV_KIND_NULL && + (jv_get_kind(k) == JV_KIND_STRING || jv_get_kind(k) == JV_KIND_NUMBER)) { + jv_free(t); + jv_free(k); + v = jv_null(); + } else { + v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with %s", + jv_kind_name(jv_get_kind(t)), + jv_kind_name(jv_get_kind(k)))); + jv_free(t); + jv_free(k); + } + return v; +} + +jv jv_modify(jv t, jv k, jv v) { + int isnull = jv_get_kind(t) == JV_KIND_NULL; + if (jv_get_kind(k) == JV_KIND_STRING && + (jv_get_kind(t) == JV_KIND_OBJECT || isnull)) { + if (isnull) t = jv_object(); + t = jv_object_set(t, k, v); + } else if (jv_get_kind(k) == JV_KIND_NUMBER && + (jv_get_kind(t) == JV_KIND_ARRAY || isnull)) { + if (isnull) t = jv_array(); + t = jv_array_set(t, (int)jv_number_value(k), v); + } else { + jv err = jv_invalid_with_msg(jv_string_fmt("Cannot update field at %s index of %s", + jv_kind_name(jv_get_kind(t)), + jv_kind_name(jv_get_kind(v)))); + jv_free(t); + jv_free(k); + jv_free(v); + t = err; + } + return t; +} + +jv jv_insert(jv root, jv value, jv* path, int pathlen) { + if (pathlen == 0) { + jv_free(root); + return value; + } + return jv_modify(root, jv_copy(*path), + jv_insert(jv_lookup(jv_copy(root), jv_copy(*path)), value, path+1, pathlen-1)); +} diff --git a/jv_aux.h b/jv_aux.h new file mode 100644 index 00000000..9b91b664 --- /dev/null +++ b/jv_aux.h @@ -0,0 +1,11 @@ +#ifndef JV_AUX_H +#define JV_AUX_H + +#include "jv.h" + +jv jv_lookup(jv t, jv k); +jv jv_modify(jv t, jv k, jv v); +jv jv_insert(jv root, jv value, jv* path, int pathlen); + + +#endif From 9e743d517a047566996181549f05383948c0d0c0 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Fri, 30 Nov 2012 20:27:16 +0000 Subject: [PATCH 08/62] Sort function and more general comparison operators. --- builtin.c | 66 ++++++------------- jv_aux.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ jv_aux.h | 6 ++ testdata | 4 ++ 4 files changed, 219 insertions(+), 47 deletions(-) diff --git a/builtin.c b/builtin.c index 756b069d..eea85ed6 100644 --- a/builtin.c +++ b/builtin.c @@ -3,6 +3,7 @@ #include "compile.h" #include "parser.h" #include "locfile.h" +#include "jv_aux.h" enum { CMP_OP_LESS, @@ -127,22 +128,11 @@ static void f_notequal(jv input[], jv output[]) { static void order_cmp(jv input[], jv output[], int op) { jv_free(input[0]); - jv a = input[2]; - jv b = input[1]; - if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { - double da = jv_number_value(a); - double db = jv_number_value(b); - output[0] = jv_bool((op == CMP_OP_LESS && da < db) || - (op == CMP_OP_LESSEQ && da <= db) || - (op == CMP_OP_GREATEREQ && da >= db) || - (op == CMP_OP_GREATER && da > db)); - } else { - output[0] = jv_invalid_with_msg(jv_string_fmt("Attempted to compare order of %s wrt %s", - jv_kind_name(jv_get_kind(a)), - jv_kind_name(jv_get_kind(b)))); - jv_free(a); - jv_free(b); - } + int r = jv_cmp(input[2], input[1]); + output[0] = jv_bool((op == CMP_OP_LESS && r < 0) || + (op == CMP_OP_LESSEQ && r <= 0) || + (op == CMP_OP_GREATEREQ && r >= 0) || + (op == CMP_OP_GREATER && r > 0)); } static void f_less(jv input[], jv output[]) { @@ -222,38 +212,9 @@ static void f_tostring(jv input[], jv output[]) { } } -static int string_cmp(const void* pa, const void* pb){ - const jv* a = pa; - const jv* b = pb; - int lena = jv_string_length(jv_copy(*a)); - int lenb = jv_string_length(jv_copy(*b)); - int minlen = lena < lenb ? lena : lenb; - int r = memcmp(jv_string_value(*a), jv_string_value(*b), minlen); - if (r == 0) r = lena - lenb; - return r; -} - static void f_keys(jv input[], jv output[]) { - if (jv_get_kind(input[0]) == JV_KIND_OBJECT) { - int nkeys = jv_object_length(jv_copy(input[0])); - jv* keys = malloc(sizeof(jv) * nkeys); - int kidx = 0; - jv_object_foreach(i, input[0]) { - keys[kidx++] = jv_object_iter_key(input[0], i); - } - qsort(keys, nkeys, sizeof(jv), string_cmp); - output[0] = jv_array_sized(nkeys); - for (int i = 0; i +#include jv jv_lookup(jv t, jv k) { jv v; @@ -60,3 +62,191 @@ jv jv_insert(jv root, jv value, jv* path, int pathlen) { return jv_modify(root, jv_copy(*path), jv_insert(jv_lookup(jv_copy(root), jv_copy(*path)), value, path+1, pathlen-1)); } + + +static int string_cmp(const void* pa, const void* pb){ + const jv* a = pa; + const jv* b = pb; + int lena = jv_string_length(jv_copy(*a)); + int lenb = jv_string_length(jv_copy(*b)); + int minlen = lena < lenb ? lena : lenb; + int r = memcmp(jv_string_value(*a), jv_string_value(*b), minlen); + if (r == 0) r = lena - lenb; + return r; +} + +jv jv_keys(jv x) { + if (jv_get_kind(x) == JV_KIND_OBJECT) { + int nkeys = jv_object_length(jv_copy(x)); + jv* keys = malloc(sizeof(jv) * nkeys); + int kidx = 0; + jv_object_foreach(i, x) { + keys[kidx++] = jv_object_iter_key(x, i); + } + qsort(keys, nkeys, sizeof(jv), string_cmp); + jv answer = jv_array_sized(nkeys); + for (int i = 0; i= jv_array_length(jv_copy(a)); + int b_done = i >= jv_array_length(jv_copy(b)); + if (a_done || b_done) { + r = b_done - a_done; //suddenly, logic + break; + } + jv xa = jv_array_get(jv_copy(a), i); + jv xb = jv_array_get(jv_copy(b), i); + r = jv_cmp(xa, xb); + i++; + } + break; + } + + case JV_KIND_OBJECT: { + jv keys_a = jv_keys(jv_copy(a)); + jv keys_b = jv_keys(jv_copy(b)); + r = jv_cmp(jv_copy(keys_a), keys_b); + if (r == 0) { + for (int i=0; ikey), jv_copy(b->key)); + // comparing by address if r == 0 makes the sort stable + return r ? r : (int)(a - b); +} + +static struct sort_entry* sort_items(jv objects, jv keys) { + assert(jv_get_kind(objects) == JV_KIND_ARRAY); + assert(jv_get_kind(keys) == JV_KIND_ARRAY); + assert(jv_array_length(jv_copy(objects)) == jv_array_length(jv_copy(keys))); + int n = jv_array_length(jv_copy(objects)); + struct sort_entry* entries = malloc(sizeof(struct sort_entry) * n); + for (int i=0; i Date: Sat, 1 Dec 2012 19:41:36 +0000 Subject: [PATCH 09/62] Refactor of function call codegen. Separate codegen for C and jq calls. --- compile.c | 84 ++++++++++++++++++++++++--------------------------- execute.c | 6 ++-- opcode.c | 2 +- opcode_list.h | 2 +- 4 files changed, 44 insertions(+), 50 deletions(-) diff --git a/compile.c b/compile.c index 46e5dd88..c85ef938 100644 --- a/compile.c +++ b/compile.c @@ -56,12 +56,8 @@ static inst* inst_new(opcode op) { static void inst_free(struct inst* i) { free(i->symbol); - if (opcode_describe(i->op)->flags & OP_HAS_BLOCK) { - block_free(i->subfn); - } - if (opcode_describe(i->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - block_free(i->arglist); - } + block_free(i->subfn); + block_free(i->arglist); if (opcode_describe(i->op)->flags & OP_HAS_CONSTANT) { jv_free(i->imm.constant); } @@ -486,7 +482,7 @@ static block expand_call_arglist(block b) { // Arguments to C functions not yet supported inst* cfunction_ref = block_take(&arglist); block prelude = gen_noop(); - int nargs = 0; + int nargs = 2; for (inst* i; (i = block_take(&arglist)); ) { assert(i->op == CLOSURE_CREATE); // FIXME block body = i->subfn; @@ -496,8 +492,11 @@ static block expand_call_arglist(block b) { nargs++; } assert(curr->op == CALL_1_1); - curr->imm.intval = 1; - ret = BLOCK(ret, prelude, inst_block(curr), inst_block(cfunction_ref), inst_block(seq_end)); + curr->op = CALL_BUILTIN_1_1; + curr->imm.intval = nargs; + assert(!curr->arglist.first); + curr->arglist = inst_block(cfunction_ref); + ret = BLOCK(ret, prelude, inst_block(curr), inst_block(seq_end)); break; } } @@ -584,38 +583,46 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { code[pos++] = curr->op; int opflags = op->flags; assert(!(op->flags & OP_IS_CALL_PSEUDO)); - if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { + if (curr->op == CALL_BUILTIN_1_1) { + int nargs = curr->imm.intval; + code[pos++] = (uint16_t)nargs; + assert(block_is_single(curr->arglist)); + inst* cfunc = curr->arglist.first; + assert(cfunc && cfunc->bound_by->op == CLOSURE_CREATE_C); + assert(opcode_length(*opcode_rewrite) == + opcode_length(bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop)); + *opcode_rewrite = bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop; + code[pos++] = cfunc->bound_by->imm.intval; + // FIXME arg errors + assert(nargs > 0); + } else if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { assert(curr->op == CALL_1_1); int nargs = curr->imm.intval; assert(nargs > 0 && nargs < 100); //FIXME code[pos++] = (uint16_t)nargs; - - int desired_params = 0; - for (int i=0; inext; + assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); + assert(curr->bound_by->op == CLOSURE_CREATE || + curr->bound_by->op == CLOSURE_PARAM); + code[pos++] = nesting_level(bc, curr->bound_by); + if (curr->bound_by->op == CLOSURE_CREATE) { + code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE; + inst* i = curr->bound_by; + // FIXME arg errors + assert(nargs - 1 == i->compiled->subfunctions[i->imm.intval]->nclosures); + } else { + code[pos++] = curr->bound_by->imm.intval; + // FIXME arg errors + assert(nargs == 1); + } + for (int i=1; inext; assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); + assert(curr->op == CLOSURE_REF); code[pos++] = nesting_level(bc, curr->bound_by); - switch (curr->bound_by->op) { - default: assert(0 && "Unknown type of argument"); - case CLOSURE_CREATE: - code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE; - if (i == 0) { - inst* i = curr->bound_by; - desired_params = i->compiled->subfunctions[i->imm.intval]->nclosures; - } - break; - case CLOSURE_PARAM: - code[pos++] = curr->bound_by->imm.intval; - if (i == 0) desired_params = 0; - break; - case CLOSURE_CREATE_C: - code[pos++] = curr->bound_by->imm.intval; - *opcode_rewrite = bc->globals->cfunctions[curr->bound_by->imm.intval].callop; - if (i == 0) desired_params = 0; - break; - } + assert(curr->bound_by->op == CLOSURE_CREATE); + code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE; } - assert(nargs - 1 == desired_params); } else if (opflags & OP_HAS_CONSTANT) { code[pos++] = jv_array_length(jv_copy(constant_pool)); constant_pool = jv_array_append(constant_pool, jv_copy(curr->imm.constant)); @@ -629,17 +636,6 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { assert(curr->imm.target->bytecode_pos > pos); // only forward branches code[pos] = curr->imm.target->bytecode_pos - (pos + 1); pos++; - } else if (opflags & OP_HAS_CFUNC) { - assert(curr->symbol); - int found = 0; - for (int i=0; iglobals->ncfunctions; i++) { - if (!strcmp(curr->symbol, bc->globals->cfunctions[i].name)) { - code[pos++] = i; - found = 1; - break; - } - } - assert(found); } else if (op->length > 1) { assert(0 && "codegen not implemented for this operation"); } diff --git a/execute.c b/execute.c index fa6b1b79..74221a55 100644 --- a/execute.c +++ b/execute.c @@ -411,9 +411,8 @@ jv jq_next() { } case CALL_BUILTIN_1_1: { - assert(*pc == 1); // no closure args allowed + assert(*pc == 2); pc++; // skip nclosures - pc++; // skip level stackval top = stack_pop(); cfunc_input[0] = top.value; struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++]; @@ -429,9 +428,8 @@ jv jq_next() { } case CALL_BUILTIN_3_1: { - assert(*pc == 1); // no closure args allowed + assert(*pc == 4); // no closure args allowed pc++; // skip nclosures - pc++; // skip level stackval top = stack_pop(); jv a = stack_pop().value; jv b = stack_pop().value; diff --git a/opcode.c b/opcode.c index 6e85e709..c4c6356d 100644 --- a/opcode.c +++ b/opcode.c @@ -5,7 +5,7 @@ #define CONSTANT OP_HAS_CONSTANT, 2 #define VARIABLE (OP_HAS_VARIABLE | OP_HAS_BINDING), 3 #define BRANCH OP_HAS_BRANCH, 2 -#define CFUNC (OP_HAS_SYMBOL | OP_HAS_CFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST), 2 +#define CFUNC (OP_HAS_SYMBOL | OP_HAS_CFUNC), 3 #define UFUNC (OP_HAS_UFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST), 2 #define CALLSEQ_END_IMM (OP_IS_CALL_PSEUDO), 0 #define CLOSURE_PARAM_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 diff --git a/opcode_list.h b/opcode_list.h index 00817a13..34a68e1c 100644 --- a/opcode_list.h +++ b/opcode_list.h @@ -18,7 +18,7 @@ OP(INSERT, NONE, 4, 2) OP(ASSIGN, VARIABLE, 3, 0) OP(CALL_BUILTIN_1_1, CFUNC, 1, 1) -OP(CALL_BUILTIN_2_1, CFUNC, 2, 1) +OP(WTFBROKEN, CFUNC, 2, 1) OP(CALL_BUILTIN_3_1, CFUNC, 3, 1) OP(CALL_1_1, UFUNC, 1, 1) From 125e2785025ed1a4363800d712bdf4e782a94cd4 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 2 Dec 2012 20:45:55 +0000 Subject: [PATCH 10/62] Clean up calls to C functions, unify opcodes --- builtin.c | 36 ++++++++++++++++++------------------ bytecode.c | 4 ++-- bytecode.h | 2 +- compile.c | 32 +++++++++++++++----------------- execute.c | 42 +++++++++++++----------------------------- opcode_list.h | 6 ++---- 6 files changed, 51 insertions(+), 71 deletions(-) diff --git a/builtin.c b/builtin.c index eea85ed6..ae4df33b 100644 --- a/builtin.c +++ b/builtin.c @@ -238,24 +238,24 @@ static void f_type(jv input[], jv output[]) { } static struct cfunction function_list[] = { - {f_plus, "_plus", CALL_BUILTIN_3_1}, - {f_minus, "_minus", CALL_BUILTIN_3_1}, - {f_multiply, "_multiply", CALL_BUILTIN_3_1}, - {f_divide, "_divide", CALL_BUILTIN_3_1}, - {f_tonumber, "tonumber", CALL_BUILTIN_1_1}, - {f_tostring, "tostring", CALL_BUILTIN_1_1}, - {f_keys, "keys", CALL_BUILTIN_1_1}, - {f_equal, "_equal", CALL_BUILTIN_3_1}, - {f_notequal, "_notequal", CALL_BUILTIN_3_1}, - {f_less, "_less", CALL_BUILTIN_3_1}, - {f_greater, "_greater", CALL_BUILTIN_3_1}, - {f_lesseq, "_lesseq", CALL_BUILTIN_3_1}, - {f_greatereq, "_greatereq", CALL_BUILTIN_3_1}, - {f_contains, "_contains", CALL_BUILTIN_3_1}, - {f_length, "length", CALL_BUILTIN_1_1}, - {f_type, "type", CALL_BUILTIN_1_1}, - {f_add, "add", CALL_BUILTIN_1_1}, - {f_sort, "sort", CALL_BUILTIN_1_1}, + {f_plus, "_plus", 3}, + {f_minus, "_minus", 3}, + {f_multiply, "_multiply", 3}, + {f_divide, "_divide", 3}, + {f_tonumber, "tonumber", 1}, + {f_tostring, "tostring", 1}, + {f_keys, "keys", 1}, + {f_equal, "_equal", 3}, + {f_notequal, "_notequal", 3}, + {f_less, "_less", 3}, + {f_greater, "_greater", 3}, + {f_lesseq, "_lesseq", 3}, + {f_greatereq, "_greatereq", 3}, + {f_contains, "_contains", 3}, + {f_length, "length", 1}, + {f_type, "type", 1}, + {f_add, "add", 1}, + {f_sort, "sort", 1}, }; static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])}; diff --git a/bytecode.c b/bytecode.c index bafd0474..a18f0d90 100644 --- a/bytecode.c +++ b/bytecode.c @@ -7,7 +7,7 @@ static int bytecode_operation_length(uint16_t* codeptr) { if (opcode_describe(*codeptr)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - return 2 + codeptr[1] * 2; + return 4 + codeptr[1] * 2; } else { return opcode_length(*codeptr); } @@ -42,7 +42,7 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) { if (op->length > 1) { uint16_t imm = bc->code[pc++]; if (op->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - for (int i=0; icode[pc++]; uint16_t idx = bc->code[pc++]; if (idx & ARG_NEWCLOSURE) { diff --git a/bytecode.h b/bytecode.h index 5ffe80a6..011745c0 100644 --- a/bytecode.h +++ b/bytecode.h @@ -10,7 +10,7 @@ typedef void (*cfunction_ptr)(jv input[], jv output[]); struct cfunction { cfunction_ptr fptr; const char* name; - opcode callop; + int nargs; }; #define MAX_CFUNCTION_ARGS 10 diff --git a/compile.c b/compile.c index c85ef938..d31e0c34 100644 --- a/compile.c +++ b/compile.c @@ -282,7 +282,7 @@ block gen_lambda(block body) { } block gen_call(const char* name, block args) { - inst* i = inst_new(CALL_1_1); + inst* i = inst_new(CALL_JQ); i->arglist = BLOCK(gen_op_block_unbound(CLOSURE_REF, name), args); return BLOCK(inst_block(i), inst_block(inst_new(CALLSEQ_END))); } @@ -439,7 +439,7 @@ static block expand_call_arglist(block b) { block ret = gen_noop(); for (inst* curr; (curr = block_take(&b));) { if (opcode_describe(curr->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - assert(curr->op == CALL_1_1); + assert(curr->op == CALL_JQ); inst* seq_end = block_take(&b); assert(seq_end && seq_end->op == CALLSEQ_END); // We expand the argument list as a series of instructions @@ -473,7 +473,8 @@ static block expand_call_arglist(block b) { } assert(!arglist.first); - curr->imm.intval = nargs; + assert(nargs > 0); + curr->imm.intval = nargs - 1; ret = BLOCK(ret, prelude, inst_block(curr), callargs, inst_block(seq_end)); break; } @@ -482,7 +483,7 @@ static block expand_call_arglist(block b) { // Arguments to C functions not yet supported inst* cfunction_ref = block_take(&arglist); block prelude = gen_noop(); - int nargs = 2; + int nargs = 1; for (inst* i; (i = block_take(&arglist)); ) { assert(i->op == CLOSURE_CREATE); // FIXME block body = i->subfn; @@ -491,8 +492,8 @@ static block expand_call_arglist(block b) { prelude = BLOCK(prelude, gen_subexp(expand_call_arglist(body))); nargs++; } - assert(curr->op == CALL_1_1); - curr->op = CALL_BUILTIN_1_1; + assert(curr->op == CALL_JQ); + curr->op = CALL_BUILTIN; curr->imm.intval = nargs; assert(!curr->arglist.first); curr->arglist = inst_block(cfunction_ref); @@ -579,26 +580,23 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { const struct opcode_description* op = opcode_describe(curr->op); if (op->length == 0) continue; - uint16_t* opcode_rewrite = &code[pos]; code[pos++] = curr->op; int opflags = op->flags; assert(!(op->flags & OP_IS_CALL_PSEUDO)); - if (curr->op == CALL_BUILTIN_1_1) { + if (curr->op == CALL_BUILTIN) { int nargs = curr->imm.intval; code[pos++] = (uint16_t)nargs; assert(block_is_single(curr->arglist)); inst* cfunc = curr->arglist.first; assert(cfunc && cfunc->bound_by->op == CLOSURE_CREATE_C); - assert(opcode_length(*opcode_rewrite) == - opcode_length(bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop)); - *opcode_rewrite = bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop; + //*opcode_rewrite = bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop; code[pos++] = cfunc->bound_by->imm.intval; // FIXME arg errors - assert(nargs > 0); + assert(nargs == bc->globals->cfunctions[cfunc->bound_by->imm.intval].nargs); } else if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - assert(curr->op == CALL_1_1); + assert(curr->op == CALL_JQ); int nargs = curr->imm.intval; - assert(nargs > 0 && nargs < 100); //FIXME + assert(nargs >= 0 && nargs < 100); //FIXME code[pos++] = (uint16_t)nargs; curr = curr->next; assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); @@ -609,13 +607,13 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE; inst* i = curr->bound_by; // FIXME arg errors - assert(nargs - 1 == i->compiled->subfunctions[i->imm.intval]->nclosures); + assert(nargs == i->compiled->subfunctions[i->imm.intval]->nclosures); } else { code[pos++] = curr->bound_by->imm.intval; // FIXME arg errors - assert(nargs == 1); + assert(nargs == 0); } - for (int i=1; inext; assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); assert(curr->op == CLOSURE_REF); diff --git a/execute.c b/execute.c index 74221a55..8aeee779 100644 --- a/execute.c +++ b/execute.c @@ -167,7 +167,9 @@ jv jq_next() { printf("\t"); const struct opcode_description* opdesc = opcode_describe(opcode); data_stk_elem* param; - for (int i=0; istack_in; i++) { + int stack_in = opdesc->stack_in; + if (stack_in == -1) stack_in = pc[1]; + for (int i=0; iglobals->cfunctions[*pc++]; func->fptr(cfunc_input, cfunc_output); top.value = cfunc_output[0]; @@ -427,36 +431,16 @@ jv jq_next() { break; } - case CALL_BUILTIN_3_1: { - assert(*pc == 4); // no closure args allowed - pc++; // skip nclosures - stackval top = stack_pop(); - jv a = stack_pop().value; - jv b = stack_pop().value; - cfunc_input[0] = top.value; - cfunc_input[1] = a; - cfunc_input[2] = b; - struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++]; - func->fptr(cfunc_input, cfunc_output); - top.value = cfunc_output[0]; - if (jv_is_valid(top.value)) { - stack_push(top); - } else { - print_error(top.value); - goto do_backtrack; - } - break; - } - - case CALL_1_1: { + case CALL_JQ: { uint16_t nclosures = *pc++; + uint16_t* retaddr = pc + 2 + nclosures*2; frame_ptr new_frame = frame_push(&frame_stk, make_closure(&frame_stk, frame_current(&frame_stk), pc), - pc + nclosures * 2); + retaddr); pc += 2; frame_ptr old_frame = forkable_stack_peek_next(&frame_stk, new_frame); - assert(nclosures - 1 == frame_self(new_frame)->bc->nclosures); - for (int i=0; ibc->nclosures); + for (int i=0; i Date: Sun, 2 Dec 2012 21:25:54 +0000 Subject: [PATCH 11/62] Move all the includes one place to the left --- builtin.c | 1 + builtin.h | 11 ++++++++++- bytecode.h | 9 +-------- compile.c | 1 + compile.h | 5 ++++- execute.c | 1 - 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/builtin.c b/builtin.c index ae4df33b..4fca4a63 100644 --- a/builtin.c +++ b/builtin.c @@ -1,5 +1,6 @@ #include #include "builtin.h" +#include "bytecode.h" #include "compile.h" #include "parser.h" #include "locfile.h" diff --git a/builtin.h b/builtin.h index fe2ac6ac..b6c26cda 100644 --- a/builtin.h +++ b/builtin.h @@ -1,9 +1,18 @@ #ifndef BUILTIN_H #define BUILTIN_H -#include "bytecode.h" #include "compile.h" block builtins_bind(block); + +typedef void (*cfunction_ptr)(jv input[], jv output[]); + +struct cfunction { + cfunction_ptr fptr; + const char* name; + int nargs; +}; + + #endif diff --git a/bytecode.h b/bytecode.h index 011745c0..e84f1387 100644 --- a/bytecode.h +++ b/bytecode.h @@ -4,14 +4,7 @@ #include "jv.h" #include "opcode.h" - -typedef void (*cfunction_ptr)(jv input[], jv output[]); - -struct cfunction { - cfunction_ptr fptr; - const char* name; - int nargs; -}; +#include "builtin.h" #define MAX_CFUNCTION_ARGS 10 struct symbol_table { diff --git a/compile.c b/compile.c index d31e0c34..b7c202ac 100644 --- a/compile.c +++ b/compile.c @@ -3,6 +3,7 @@ #include #include "opcode.h" #include "compile.h" +#include "bytecode.h" #include "locfile.h" struct inst { diff --git a/compile.h b/compile.h index c8a326da..9a885159 100644 --- a/compile.h +++ b/compile.h @@ -1,10 +1,13 @@ #ifndef COMPILE_H #define COMPILE_H #include -#include "bytecode.h" +#include "jv.h" #include "opcode.h" #include "locfile.h" +struct bytecode; +struct symbol_table; + struct inst; typedef struct inst inst; diff --git a/execute.c b/execute.c index 8aeee779..8c56b67c 100644 --- a/execute.c +++ b/execute.c @@ -7,7 +7,6 @@ #include "opcode.h" #include "bytecode.h" -#include "compile.h" #include "forkable_stack.h" #include "frame_layout.h" From ea9db414edd078d8cb5e95a7694df7ae81d6daac Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 2 Dec 2012 22:12:08 +0000 Subject: [PATCH 12/62] Clean up implementation of builtin functions. --- builtin.c | 322 ++++++++++++++++++++++++++---------------------------- builtin.h | 5 +- compile.c | 3 +- execute.c | 4 +- 4 files changed, 163 insertions(+), 171 deletions(-) diff --git a/builtin.c b/builtin.c index 4fca4a63..f432bea5 100644 --- a/builtin.c +++ b/builtin.c @@ -6,41 +6,62 @@ #include "locfile.h" #include "jv_aux.h" -enum { - CMP_OP_LESS, - CMP_OP_GREATER, - CMP_OP_LESSEQ, - CMP_OP_GREATEREQ -} _cmp_op; -static void f_plus(jv input[], jv output[]) { - jv_free(input[0]); - jv a = input[2]; - jv b = input[1]; - if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { - output[0] = jv_number(jv_number_value(a) + - jv_number_value(b)); - } else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) { - output[0] = jv_string_concat(a, b); - } else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) { - output[0] = jv_array_concat(a, b); - } else if (jv_get_kind(a) == JV_KIND_OBJECT && jv_get_kind(b) == JV_KIND_OBJECT) { - output[0] = jv_object_merge(a, b); - } else { - output[0] = jv_invalid_with_msg(jv_string_fmt("Attempted to add %s and %s", - jv_kind_name(jv_get_kind(a)), - jv_kind_name(jv_get_kind(b)))); - jv_free(a); - jv_free(b); +typedef jv (*func_1)(jv); +typedef jv (*func_2)(jv,jv); +typedef jv (*func_3)(jv,jv,jv); +typedef jv (*func_4)(jv,jv,jv,jv); +typedef jv (*func_5)(jv,jv,jv,jv,jv); +jv cfunction_invoke(struct cfunction* function, jv input[]) { + switch (function->nargs) { + case 1: return ((func_1)function->fptr)(input[0]); + case 2: return ((func_2)function->fptr)(input[0], input[1]); + case 3: return ((func_3)function->fptr)(input[0], input[1], input[2]); + case 4: return ((func_4)function->fptr)(input[0], input[1], input[2], input[3]); + case 5: return ((func_5)function->fptr)(input[0], input[1], input[2], input[3], input[4]); + default: return jv_invalid_with_msg(jv_string("Function takes too many arguments")); } } -static void f_minus(jv input[], jv output[]) { - jv_free(input[0]); - jv a = input[2]; - jv b = input[1]; +static jv type_error(jv bad, const char* msg) { + jv err = jv_invalid_with_msg(jv_string_fmt("%s %s", + jv_kind_name(jv_get_kind(bad)), + msg)); + jv_free(bad); + return err; +} + +static jv type_error2(jv bad1, jv bad2, const char* msg) { + jv err = jv_invalid_with_msg(jv_string_fmt("%s and %s %s", + jv_kind_name(jv_get_kind(bad1)), + jv_kind_name(jv_get_kind(bad2)), + msg)); + jv_free(bad1); + jv_free(bad2); + return err; +} + + +static jv f_plus(jv input, jv a, jv b) { + jv_free(input); if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { - output[0] = jv_number(jv_number_value(a) - jv_number_value(b)); + return jv_number(jv_number_value(a) + + jv_number_value(b)); + } else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) { + return jv_string_concat(a, b); + } else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) { + return jv_array_concat(a, b); + } else if (jv_get_kind(a) == JV_KIND_OBJECT && jv_get_kind(b) == JV_KIND_OBJECT) { + return jv_object_merge(a, b); + } else { + return type_error2(a, b, "cannot be added"); + } +} + +static jv f_minus(jv input, jv a, jv b) { + jv_free(input); + if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { + return jv_number(jv_number_value(a) - jv_number_value(b)); } else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) { jv out = jv_array(); for (int i=0; i= 0) || - (op == CMP_OP_GREATER && r > 0)); +enum cmp_op { + CMP_OP_LESS, + CMP_OP_GREATER, + CMP_OP_LESSEQ, + CMP_OP_GREATEREQ +}; + +static jv order_cmp(jv input, jv a, jv b, enum cmp_op op) { + jv_free(input); + int r = jv_cmp(a, b); + return jv_bool((op == CMP_OP_LESS && r < 0) || + (op == CMP_OP_LESSEQ && r <= 0) || + (op == CMP_OP_GREATEREQ && r >= 0) || + (op == CMP_OP_GREATER && r > 0)); } -static void f_less(jv input[], jv output[]) { - order_cmp(input, output, CMP_OP_LESS); +static jv f_less(jv input, jv a, jv b) { + return order_cmp(input, a, b, CMP_OP_LESS); } -static void f_greater(jv input[], jv output[]) { - order_cmp(input, output, CMP_OP_GREATER); +static jv f_greater(jv input, jv a, jv b) { + return order_cmp(input, a, b, CMP_OP_GREATER); } -static void f_lesseq(jv input[], jv output[]) { - order_cmp(input, output, CMP_OP_LESSEQ); +static jv f_lesseq(jv input, jv a, jv b) { + return order_cmp(input, a, b, CMP_OP_LESSEQ); } -static void f_greatereq(jv input[], jv output[]) { - order_cmp(input, output, CMP_OP_GREATEREQ); +static jv f_greatereq(jv input, jv a, jv b) { + return order_cmp(input, a, b, CMP_OP_GREATEREQ); } -static void f_contains(jv input[], jv output[]) { - jv_free(input[0]); - jv a = input[2]; - jv b = input[1]; +static jv f_contains(jv input, jv a, jv b) { + jv_free(input); jv_kind akind = jv_get_kind(a); if (akind == jv_get_kind(b)) { - output[0] = jv_bool(jv_contains(a, b)); - } else { - output[0] = jv_invalid_with_msg(jv_string_fmt("Can only check containment of values of the same type.")); - jv_free(a); - jv_free(b); + return jv_bool(jv_contains(a, b)); + } else { + return type_error2(a, b, "cannot have their containment checked"); } } -static void f_tonumber(jv input[], jv output[]) { - if (jv_get_kind(input[0]) == JV_KIND_NUMBER) { - output[0] = input[0]; - } else if (jv_get_kind(input[0]) == JV_KIND_STRING) { - jv parsed = jv_parse(jv_string_value(input[0])); - if (!jv_is_valid(parsed)) { - jv_free(input[0]); - output[0] = parsed; - } else if (jv_get_kind(parsed) != JV_KIND_NUMBER) { - output[0] = jv_invalid_with_msg(jv_string_fmt("'%s' is not a number", - jv_string_value(input[0]))); - jv_free(input[0]); - } else { - jv_free(input[0]); - output[0] = parsed; +static jv f_tonumber(jv input) { + if (jv_get_kind(input) == JV_KIND_NUMBER) { + return input; + } + if (jv_get_kind(input) == JV_KIND_STRING) { + jv parsed = jv_parse(jv_string_value(input)); + if (!jv_is_valid(parsed) || jv_get_kind(parsed) == JV_KIND_NUMBER) { + jv_free(input); + return parsed; } + } + return type_error(input, "cannot be parsed as a number"); +} + +static jv f_length(jv input) { + if (jv_get_kind(input) == JV_KIND_ARRAY) { + return jv_number(jv_array_length(input)); + } else if (jv_get_kind(input) == JV_KIND_OBJECT) { + return jv_number(jv_object_length(input)); + } else if (jv_get_kind(input) == JV_KIND_STRING) { + return jv_number(jv_string_length(input)); } else { - output[0] = jv_invalid_with_msg(jv_string_fmt("Cannot parse %s as a number", - jv_kind_name(jv_get_kind(input[0])))); - jv_free(input[0]); - return; + return type_error(input, "has no length"); } } -static void f_length(jv input[], jv output[]) { - if (jv_get_kind(input[0]) == JV_KIND_ARRAY) { - output[0] = jv_number(jv_array_length(input[0])); - } else if (jv_get_kind(input[0]) == JV_KIND_OBJECT) { - output[0] = jv_number(jv_object_length(input[0])); - } else if (jv_get_kind(input[0]) == JV_KIND_STRING) { - output[0] = jv_number(jv_string_length(input[0])); +static jv f_tostring(jv input) { + if (jv_get_kind(input) == JV_KIND_STRING) { + return input; } else { - output[0] = jv_invalid_with_msg(jv_string_fmt("Cannot get the length of %s", - jv_kind_name(jv_get_kind(input[0])))); - jv_free(input[0]); + return jv_dump_string(input, 0); } } -static void f_tostring(jv input[], jv output[]) { - if (jv_get_kind(input[0]) == JV_KIND_STRING) { - output[0] = input[0]; +static jv f_keys(jv input) { + if (jv_get_kind(input) == JV_KIND_OBJECT || jv_get_kind(input) == JV_KIND_ARRAY) { + return jv_keys(input); } else { - output[0] = jv_dump_string(input[0], 0); + return type_error(input, "has no keys"); } } -static void f_keys(jv input[], jv output[]) { - if (jv_get_kind(input[0]) == JV_KIND_OBJECT || jv_get_kind(input[0]) == JV_KIND_ARRAY) { - output[0] = jv_keys(input[0]); +static jv f_sort(jv input){ + if (jv_get_kind(input) == JV_KIND_ARRAY) { + return jv_sort(input, jv_copy(input)); } else { - output[0] = jv_invalid_with_msg(jv_string_fmt("'keys' only supports object, not %s", - jv_kind_name(jv_get_kind(input[0])))); - jv_free(input[0]); + return type_error(input, "cannot be sorted, as it is not an array"); } } -static void f_sort(jv input[], jv output[]){ - if (jv_get_kind(input[0]) == JV_KIND_ARRAY) { - output[0] = jv_sort(input[0], jv_copy(input[0])); - } else { - output[0] = jv_invalid_with_msg(jv_string_fmt("only arrays may be sorted, not %s", - jv_kind_name(jv_get_kind(input[0])))); - jv_free(input[0]); - } -} - -static void f_type(jv input[], jv output[]) { - output[0] = jv_string(jv_kind_name(jv_get_kind(input[0]))); - jv_free(input[0]); +static jv f_type(jv input) { + jv out = jv_string(jv_kind_name(jv_get_kind(input))); + jv_free(input); + return out; } static struct cfunction function_list[] = { - {f_plus, "_plus", 3}, - {f_minus, "_minus", 3}, - {f_multiply, "_multiply", 3}, - {f_divide, "_divide", 3}, - {f_tonumber, "tonumber", 1}, - {f_tostring, "tostring", 1}, - {f_keys, "keys", 1}, - {f_equal, "_equal", 3}, - {f_notequal, "_notequal", 3}, - {f_less, "_less", 3}, - {f_greater, "_greater", 3}, - {f_lesseq, "_lesseq", 3}, - {f_greatereq, "_greatereq", 3}, - {f_contains, "_contains", 3}, - {f_length, "length", 1}, - {f_type, "type", 1}, - {f_add, "add", 1}, - {f_sort, "sort", 1}, + {(cfunction_ptr)f_plus, "_plus", 3}, + {(cfunction_ptr)f_minus, "_minus", 3}, + {(cfunction_ptr)f_multiply, "_multiply", 3}, + {(cfunction_ptr)f_divide, "_divide", 3}, + {(cfunction_ptr)f_tonumber, "tonumber", 1}, + {(cfunction_ptr)f_tostring, "tostring", 1}, + {(cfunction_ptr)f_keys, "keys", 1}, + {(cfunction_ptr)f_equal, "_equal", 3}, + {(cfunction_ptr)f_notequal, "_notequal", 3}, + {(cfunction_ptr)f_less, "_less", 3}, + {(cfunction_ptr)f_greater, "_greater", 3}, + {(cfunction_ptr)f_lesseq, "_lesseq", 3}, + {(cfunction_ptr)f_greatereq, "_greatereq", 3}, + {(cfunction_ptr)f_contains, "_contains", 3}, + {(cfunction_ptr)f_length, "length", 1}, + {(cfunction_ptr)f_type, "type", 1}, + {(cfunction_ptr)f_add, "add", 1}, + {(cfunction_ptr)f_sort, "sort", 1}, }; static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])}; diff --git a/builtin.h b/builtin.h index b6c26cda..538a1391 100644 --- a/builtin.h +++ b/builtin.h @@ -6,7 +6,7 @@ block builtins_bind(block); -typedef void (*cfunction_ptr)(jv input[], jv output[]); +typedef void (*cfunction_ptr)(void); struct cfunction { cfunction_ptr fptr; @@ -15,4 +15,7 @@ struct cfunction { }; +jv cfunction_invoke(struct cfunction* function, jv input[]); + + #endif diff --git a/compile.c b/compile.c index b7c202ac..acc89749 100644 --- a/compile.c +++ b/compile.c @@ -490,7 +490,8 @@ static block expand_call_arglist(block b) { block body = i->subfn; i->subfn = gen_noop(); inst_free(i); - prelude = BLOCK(prelude, gen_subexp(expand_call_arglist(body))); + // arguments should be pushed in reverse order, prepend them to prelude + prelude = BLOCK(gen_subexp(expand_call_arglist(body)), prelude); nargs++; } assert(curr->op == CALL_JQ); diff --git a/execute.c b/execute.c index 8c56b67c..8fadc7e7 100644 --- a/execute.c +++ b/execute.c @@ -149,7 +149,6 @@ void print_error(jv value) { jv jq_next() { jv cfunc_input[MAX_CFUNCTION_ARGS]; - jv cfunc_output[MAX_CFUNCTION_ARGS]; assert(!forkable_stack_empty(&frame_stk)); uint16_t* pc = *frame_current_retaddr(&frame_stk); @@ -419,8 +418,7 @@ jv jq_next() { cfunc_input[i] = stack_pop().value; } struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++]; - func->fptr(cfunc_input, cfunc_output); - top.value = cfunc_output[0]; + top.value = cfunction_invoke(func, cfunc_input); if (jv_is_valid(top.value)) { stack_push(top); } else { From 63d10433c9e92028d5b6acda47119bde998eae1f Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 2 Dec 2012 22:22:08 +0000 Subject: [PATCH 13/62] Fix a horrible scoping/associativity bug. `1 as $x | . | $x` didn't compile, as it was parsed as (1 as $x | .) | $x where `$x` is undefined, rather than as 1 as $x | (. | $x) --- parser.y | 2 +- testdata | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/parser.y b/parser.y index 59d535e6..9c234506 100644 --- a/parser.y +++ b/parser.y @@ -75,7 +75,7 @@ struct lexer_param; /* revolting hack */ %left ';' -%left '|' +%right '|' %left ',' %right "//" %nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETDEFINEDOR diff --git a/testdata b/testdata index 1bab84f2..e6fcaaf7 100644 --- a/testdata +++ b/testdata @@ -146,6 +146,10 @@ null [6] [7] +42 as $x | . | . | . + 432 | $x + 1 +34324 +43 + 1 as $x | [$x,$x,$x as $x | $x] null [1,1,1] From ed7f95a492b647c7da3fc4bc2c9194b4bbbf7622 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 2 Dec 2012 22:24:02 +0000 Subject: [PATCH 14/62] Demote "contains" to a built-in function rather than an operator. --- builtin.c | 5 ++- docs/content/3.manual/manual.yml | 56 +++++++++++++++++--------------- lexer.l | 1 - parser.y | 8 +---- testdata | 20 ++++++------ 5 files changed, 42 insertions(+), 48 deletions(-) diff --git a/builtin.c b/builtin.c index f432bea5..ab13a2bb 100644 --- a/builtin.c +++ b/builtin.c @@ -161,8 +161,7 @@ static jv f_greatereq(jv input, jv a, jv b) { return order_cmp(input, a, b, CMP_OP_GREATEREQ); } -static jv f_contains(jv input, jv a, jv b) { - jv_free(input); +static jv f_contains(jv a, jv b) { jv_kind akind = jv_get_kind(a); if (akind == jv_get_kind(b)) { @@ -242,7 +241,7 @@ static struct cfunction function_list[] = { {(cfunction_ptr)f_greater, "_greater", 3}, {(cfunction_ptr)f_lesseq, "_lesseq", 3}, {(cfunction_ptr)f_greatereq, "_greatereq", 3}, - {(cfunction_ptr)f_contains, "_contains", 3}, + {(cfunction_ptr)f_contains, "contains", 2}, {(cfunction_ptr)f_length, "length", 1}, {(cfunction_ptr)f_type, "type", 1}, {(cfunction_ptr)f_add, "add", 1}, diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 437afdff..60679ba2 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -487,6 +487,35 @@ sections: input: '[1, "1", [1]]' output: ['"1"', '"1"', '"[1]"'] + - title: `contains` + body: | + + The filter `contains(b)` will produce true if b is + completely contained within the input. A string B is + contained in a string A if B is a substring of A. An array B + is contained in an array A is all elements in B are + contained in any element in A. An object B is contained in + object A if all of the values in B are contained in the + value in A with the same key. All other types are assumed to + be contained in each other if they are equal. + + examples: + - program: 'contains("bar")' + input: '"foobar"' + output: ['true'] + - program: 'contains(["baz", "bar"])' + input: '["foobar", "foobaz", "blarp"]' + output: ['true'] + - program: 'contains(["bazzzzz", "bar"])' + input: '["foobar", "foobaz", "blarp"]' + output: ['false'] + - program: 'contains({foo: 12, bar: [{barp: 12}]})' + input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}' + output: ['true'] + - program: 'contains({foo: 12, bar: [{barp: 15}]})' + input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}' + output: ['false'] + - title: "String interpolation - `\(foo)`" body: | @@ -522,33 +551,6 @@ sections: - program: '.[] == 1' input: '[1, 1.0, "1", "banana"]' output: ['[true, true, false, false]'] - - title: `contains` - body: | - - The expression 'a contains b' will produce true if b is completely - contained within a. A string B is contained in a string A if B is a - substring of A. An array B is contained in an array A is all elements - in B are contained in any element in A. An object B is contained in - object A if all of the values in B are contained in the value in A with - the same key. All other types are assumed to be contained in each other - if they are equal. - - examples: - - program: '. == contains "bar"' - input: '"foobar"' - output: ['true'] - - program: '. contains ["baz", "bar"]' - input: '["foobar", "foobaz", "blarp"]' - output: ['true'] - - program: '. contains ["bazzzzz", "bar"]' - input: '["foobar", "foobaz", "blarp"]' - output: ['false'] - - program: '. contains {foo: 12, bar: [{barp: 12}]}' - input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}' - output: ['true'] - - program: '. contains {foo: 12, bar: [{barp: 15}]}' - input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}' - output: ['false'] - title: if-then-else body: | diff --git a/lexer.l b/lexer.l index 4f283011..b09ccce4 100644 --- a/lexer.l +++ b/lexer.l @@ -56,7 +56,6 @@ struct lexer_param; "//=" { return SETDEFINEDOR; } "<=" { return LESSEQ; } ">=" { return GREATEREQ; } -"contains" { return CONTAINS; } "."|"="|";"|","|":"|"|"|"+"|"-"|"*"|"/"|"\$"|"<"|">" { return yytext[0];} "["|"{"|"(" { diff --git a/parser.y b/parser.y index 9c234506..bdee008b 100644 --- a/parser.y +++ b/parser.y @@ -65,7 +65,6 @@ struct lexer_param; %token SETDEFINEDOR "//=" %token LESSEQ "<=" %token GREATEREQ ">=" -%token CONTAINS "contains" %token QQSTRING_START %token QQSTRING_TEXT @@ -81,7 +80,7 @@ struct lexer_param; %nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETDEFINEDOR %left OR %left AND -%nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ CONTAINS +%nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ %left '+' '-' %left '*' '/' @@ -150,7 +149,6 @@ static block gen_binop(block a, block b, int op) { case '>': funcname = "_greater"; break; case LESSEQ: funcname = "_lesseq"; break; case GREATEREQ: funcname = "_greatereq"; break; - case CONTAINS: funcname = "_contains"; break; } assert(funcname); @@ -295,10 +293,6 @@ Exp ">=" Exp { $$ = gen_binop($1, $3, GREATEREQ); } | -Exp "contains" Exp { - $$ = gen_binop($1, $3, CONTAINS); -} | - Term { $$ = $1; } diff --git a/testdata b/testdata index e6fcaaf7..30df927b 100644 --- a/testdata +++ b/testdata @@ -406,27 +406,27 @@ def inc(x): x |= .+1; inc(.[].a) [true,false] # containment operator -["foo" contains "foo", "foobar" contains "foo", "foo" contains "foobar"] +[("foo" | contains("foo")), ("foobar" | contains("foo")), ("foo" | contains("foobar"))] {} [true, true, false] -[[] contains [], [1,2,3] contains [1,2], [1,2,3] contains [3,1], [1,2,3] contains [4], [1,2,3] contains [1,4]] -{} +map(.[1] as $needle | .[0] | contains($needle)) +[[[],[]], [[1,2,3], [1,2]], [[1,2,3], [3,1]], [[1,2,3], [4]], [[1,2,3], [1,4]]] [true, true, true, false, false] -[["foobar", "foobaz"] contains ["baz", "bar"], ["foobar", "foobaz"] contains ["foo"], ["foobar", "foobaz"] contains ["blap"]] +map(.[1] as $needle | .[0] | contains($needle)) +[[["foobar", "foobaz"], ["baz", "bar"]], [["foobar", "foobaz"], ["foo"]], [["foobar", "foobaz"], ["blap"]]] +[true, true, false] + +[({foo: 12, bar:13} | contains({foo: 12})), ({foo: 12} | contains({})), ({foo: 12, bar:13} | contains({baz:14}))] {} [true, true, false] -[{foo: 12, bar:13} contains {foo: 12}, {foo: 12} contains {}, {foo: 12, bar:13} contains {baz:14}] -{} -[true, true, false] - -{foo: {baz: 12, blap: {bar: 13}}, bar: 14} contains {bar: 14, foo: {blap: {}}} +{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {}}}) {} true -{foo: {baz: 12, blap: {bar: 13}}, bar: 14} contains {bar: 14, foo: {blap: {bar: 14}}} +{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {bar: 14}}}) {} false From 11965aaa2e9cf2b09c431e682cdc459b99de60fb Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 2 Dec 2012 23:22:15 +0000 Subject: [PATCH 15/62] sort_by and group_by functions, tests and docs. --- builtin.c | 24 ++++++++++++ docs/content/3.manual/manual.yml | 64 ++++++++++++++++++++++++++++++++ testdata | 8 ++++ 3 files changed, 96 insertions(+) diff --git a/builtin.c b/builtin.c index ab13a2bb..43cfe267 100644 --- a/builtin.c +++ b/builtin.c @@ -221,6 +221,26 @@ static jv f_sort(jv input){ } } +static jv f_sort_by_impl(jv input, jv keys) { + if (jv_get_kind(input) == JV_KIND_ARRAY && + jv_get_kind(keys) == JV_KIND_ARRAY && + jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) { + return jv_sort(input, keys); + } else { + return type_error2(input, keys, "cannot be sorted, as they are not both arrays"); + } +} + +static jv f_group_by_impl(jv input, jv keys) { + if (jv_get_kind(input) == JV_KIND_ARRAY && + jv_get_kind(keys) == JV_KIND_ARRAY && + jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) { + return jv_group(input, keys); + } else { + return type_error2(input, keys, "cannot be sorted, as they are not both arrays"); + } +} + static jv f_type(jv input) { jv out = jv_string(jv_kind_name(jv_get_kind(input))); jv_free(input); @@ -246,6 +266,8 @@ static struct cfunction function_list[] = { {(cfunction_ptr)f_type, "type", 1}, {(cfunction_ptr)f_add, "add", 1}, {(cfunction_ptr)f_sort, "sort", 1}, + {(cfunction_ptr)f_sort_by_impl, "_sort_by_impl", 2}, + {(cfunction_ptr)f_group_by_impl, "_group_by_impl", 2}, }; static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])}; @@ -271,6 +293,8 @@ static block bind_bytecoded_builtins(block b) { static const char* jq_builtins[] = { "def map(f): [.[] | f];", "def select(f): if f then . else empty end;", + "def sort_by(f): _sort_by_impl(map([f]));", + "def group_by(f): _group_by_impl(map([f]));", }; diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 60679ba2..4d228691 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -487,6 +487,55 @@ sections: input: '[1, "1", [1]]' output: ['"1"', '"1"', '"[1]"'] + - title: `sort, sort_by` + body: | + + The `sort` functions sorts its input, which must be an + array. Values are sorted in the following order: + + * `null` + * `false` + * `true` + * numbers + * strings, in alphabetical order (by unicode codepoint value) + * arrays, in lexical order + * objects + + The ordering for objects is a little complex: first they're + compared by comparing their sets of keys (as arrays in + sorted order), and if their keys are equal then the values + are compared key by key. + + `sort_by` may be used to sort by a particular field of an + object, or by applying any jq filter. `sort_by(foo)` + compares two elements by comparing the result of `foo` on + each element. + + examples: + - program: 'sort' + input: '[8,3,null,6]' + output: ['[null,3,6,8]'] + - program: 'sort_by(.foo)' + input: '[{"foo":4, "bar":10}, {"foo":3, "bar":100}, {"foo":2, "bar":1}]' + output: ['[{"foo":2, "bar":1}, {"foo":3, "bar":100}, {"foo":4, "bar":10}]'] + + - title: `group_by` + body: | + + `group_by(.foo)` takes as input an array, groups the + elements having the same `.foo` field into separate arrays, + and produces all of these arrays as elements of a larger + array, sorted by the value of the `.foo` field. + + Any jq expression, not just a field access, may be used in + place of `.foo`. The sorting order is the same as described + in the `sort` function above. + + examples: + - program: 'group_by(.foo)' + input: '[{"foo":1, "bar":10}, {"foo":3, "bar":100}, {"foo":1, "bar":1}]' + output: ['[[{"foo":1, "bar":10}, {"foo":1, "bar":1}], [{"foo":3, "bar":100}]]'] + - title: `contains` body: | @@ -583,6 +632,21 @@ sections: end input: 2 output: ['"many"'] + + - title: `>, >=, <=, <` + body: | + + The comparison operators `>`, `>=`, `<=`, `<` return whether + their left argument is greater than, greater than or equal + to, less than or equal to or less than their right argument + (respectively). + + The ordering is the same as that described for `sort`, above. + + examples: + - program: '. < 5' + input: 2 + output: ['true'] - title: and/or/not body: | diff --git a/testdata b/testdata index 30df927b..29bbe7a8 100644 --- a/testdata +++ b/testdata @@ -433,3 +433,11 @@ false sort [42,[2,5,3,11],10,{"a":42,"b":2},{"a":42},true,2,[2,6],"hello",null,[2,5,6],{"a":[],"b":1},"abc","ab",[3,10],{},false,"abcd",null] [null,null,false,true,2,10,42,"ab","abc","abcd","hello",[2,5,3,11],[2,5,6],[2,6],[3,10],{},{"a":42},{"a":42,"b":2},{"a":[],"b":1}] + +(sort_by(.b) | sort_by(.a)), sort_by(.a, .b), sort_by(.b, .c), group_by(.b), group_by(.a + .b - .c == 2) +[{"a": 1, "b": 4, "c": 14}, {"a": 4, "b": 1, "c": 3}, {"a": 1, "b": 4, "c": 3}, {"a": 0, "b": 2, "c": 43}] +[{"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}, {"a": 4, "b": 1, "c": 3}] +[{"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}, {"a": 4, "b": 1, "c": 3}] +[{"a": 4, "b": 1, "c": 3}, {"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 3}, {"a": 1, "b": 4, "c": 14}] +[[{"a": 4, "b": 1, "c": 3}], [{"a": 0, "b": 2, "c": 43}], [{"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}]] +[[{"a": 1, "b": 4, "c": 14}, {"a": 0, "b": 2, "c": 43}], [{"a": 4, "b": 1, "c": 3}, {"a": 1, "b": 4, "c": 3}]] From 5b45184a1a79372630df76c0e840f4fffcce9494 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 2 Dec 2012 23:24:07 +0000 Subject: [PATCH 16/62] Make the -c output more compact. Closes #44. --- jv_print.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jv_print.c b/jv_print.c index 9e0a8812..2530b23b 100644 --- a/jv_print.c +++ b/jv_print.c @@ -144,7 +144,7 @@ static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FI put_str(",\n", F, S); put_space(indent+INDENT, F, S); } else { - put_str(", ", F, S); + put_str(",", F, S); } } jv_dump_term(C, jv_array_get(jv_copy(x), i), flags, indent + INDENT, F, S); @@ -173,12 +173,12 @@ static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FI put_str(",\n", F, S); put_space(indent+INDENT, F, S); } else { - put_str(", ", F, S); + put_str(",", F, S); } } first = 0; jv_dump_term(C, jv_object_iter_key(x, i), flags, indent + INDENT, F, S); - put_str(": ", F, S); + put_str(":", F, S); jv_dump_term(C, jv_object_iter_value(x, i), flags, indent + INDENT, F, S); } if (flags & JV_PRINT_PRETTY) { From 67f8ad943538e00826966c069d917b5bc99a4e47 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 2 Dec 2012 23:53:55 +0000 Subject: [PATCH 17/62] Ignore a UTF-8 BOM if one appears at the start of a JSON document. Closes #45. --- jv_parse.c | 20 ++++++++++++++++++++ jv_parse.h | 1 + testdata | 7 +++++++ 3 files changed, 28 insertions(+) diff --git a/jv_parse.c b/jv_parse.c index 63cdf935..738beb94 100644 --- a/jv_parse.c +++ b/jv_parse.c @@ -24,6 +24,7 @@ void jv_parser_init(struct jv_parser* p) { p->st = JV_PARSER_NORMAL; p->curr_buf = 0; p->curr_buf_length = p->curr_buf_pos = p->curr_buf_is_partial = 0; + p->bom_strip_position = 0; jvp_dtoa_context_init(&p->dtoa); } @@ -332,9 +333,27 @@ static pfunc scan(struct jv_parser* p, char ch, jv* out) { return answer; } +static unsigned char UTF8_BOM[] = {0xEF,0xBB,0xBF}; + void jv_parser_set_buf(struct jv_parser* p, const char* buf, int length, int is_partial) { assert((p->curr_buf == 0 || p->curr_buf_pos == p->curr_buf_length) && "previous buffer not exhausted"); + while (p->bom_strip_position < sizeof(UTF8_BOM)) { + if ((unsigned char)*buf == UTF8_BOM[p->bom_strip_position]) { + // matched a BOM character + buf++; + length--; + p->bom_strip_position++; + } else { + if (p->bom_strip_position == 0) { + // no BOM in this document + p->bom_strip_position = sizeof(UTF8_BOM); + } else { + // malformed BOM (prefix present, rest missing) + p->bom_strip_position = 0xff; + } + } + } p->curr_buf = buf; p->curr_buf_length = length; p->curr_buf_pos = 0; @@ -343,6 +362,7 @@ void jv_parser_set_buf(struct jv_parser* p, const char* buf, int length, int is_ jv jv_parser_next(struct jv_parser* p) { assert(p->curr_buf && "a buffer must be provided"); + if (p->bom_strip_position == 0xff) return jv_invalid_with_msg(jv_string("Malformed BOM")); jv value; presult msg = 0; while (!msg && p->curr_buf_pos < p->curr_buf_length) { diff --git a/jv_parse.h b/jv_parse.h index 5b8e7cdf..5958316a 100644 --- a/jv_parse.h +++ b/jv_parse.h @@ -6,6 +6,7 @@ struct jv_parser { int curr_buf_length; int curr_buf_pos; int curr_buf_is_partial; + unsigned bom_strip_position; jv* stack; int stackpos; diff --git a/testdata b/testdata index 29bbe7a8..e08e6aa5 100644 --- a/testdata +++ b/testdata @@ -31,6 +31,13 @@ null null [] +# The input line starts with a 0xFEFF (byte order mark) codepoint +# No, there is no reason to have a byte order mark in UTF8 text. +# But apparently people do, so jq shouldn't break on it. +. +"byte order mark" +"byte order mark" + # We test escapes by matching them against Unicode codepoints # FIXME: more tests needed for weird unicode stuff (e.g. utf16 pairs) "Aa\r\n\t\b\f\u03bc" From e9c7548b825a4fb56b53111a76cb90e0f6aef4cc Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 3 Dec 2012 01:21:07 +0000 Subject: [PATCH 18/62] Oh alright then, if you insist. Colo(u)red output for jq. Enabled by default if isatty(stdout). Closes #11. --- docs/content/3.manual/manual.yml | 6 ++++ jv.h | 2 +- jv_print.c | 49 +++++++++++++++++++++++++++++--- main.c | 13 +++++++-- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 4d228691..0e16a495 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -65,6 +65,12 @@ sections: will result in more compact output by instead putting each JSON object on a single line. + * `--colour-output` / `-C` and `--monochrome-output` / `-M` + + By default, jq outputs colored JSON if writing to a + terminal. You can force it to produce color even if writing to + a pipe or a file using `-C`, and disable color with `-M`. + * `--ascii-output` / `-a` jq usually outputs non-ASCII Unicode codepoints as UTF-8, even diff --git a/jv.h b/jv.h index 02817681..12e7c790 100644 --- a/jv.h +++ b/jv.h @@ -105,7 +105,7 @@ jv jv_object_iter_value(jv, int); int jv_get_refcnt(jv); -enum { JV_PRINT_PRETTY = 1, JV_PRINT_ASCII = 2 }; +enum { JV_PRINT_PRETTY = 1, JV_PRINT_ASCII = 2, JV_PRINT_COLOUR = 4 }; void jv_dump(jv, int flags); jv jv_dump_string(jv, int flags); diff --git a/jv_print.c b/jv_print.c index 2530b23b..acade6cd 100644 --- a/jv_print.c +++ b/jv_print.c @@ -6,6 +6,20 @@ #include "jv_dtoa.h" #include "jv_unicode.h" +#define ESC "\033" +#define COL(c) (ESC "[" c "m") +#define COLRESET (ESC "[0m") + +// Colour table. See http://en.wikipedia.org/wiki/ANSI_escape_code#Colors +// for how to choose these. +static jv_kind colour_kinds[] = + {JV_KIND_NULL, JV_KIND_FALSE, JV_KIND_TRUE, JV_KIND_NUMBER, + JV_KIND_STRING, JV_KIND_ARRAY, JV_KIND_OBJECT}; +static const char* colours[] = + {COL("30;1"), COL("0"), COL("0"), COL("0"), + COL("32"), COL("37"), COL("37")}; +#define FIELD_COLOUR COL("34;1") + static void put_buf(const char* s, int len, FILE* fout, jv* strout) { if (strout) { *strout = jv_string_append_buf(*strout, s, len); @@ -35,6 +49,7 @@ static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S) { const char* cstart; int c = 0; char buf[32]; + put_char('"', F, S); while ((i = jvp_utf8_next((cstart = i), end, &c))) { assert(c != -1); int unicode_escape = 0; @@ -91,12 +106,23 @@ static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S) { } } assert(c != -1); + put_char('"', F, S); } enum { INDENT = 2 }; static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FILE* F, jv* S) { char buf[JVP_DTOA_FMT_MAX_LEN]; + const char* colour = 0; + if (flags & JV_PRINT_COLOUR) { + for (unsigned i=0; i #include #include +#include #include "compile.h" #include "builtin.h" #include "jv.h" @@ -50,8 +51,10 @@ enum { RAW_OUTPUT = 8, COMPACT_OUTPUT = 16, ASCII_OUTPUT = 32, + COLOUR_OUTPUT = 64, + NO_COLOUR_OUTPUT = 128, - FROM_FILE = 64, + FROM_FILE = 256, }; static int options = 0; static struct bytecode* bc; @@ -63,9 +66,11 @@ static void process(jv value) { if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) { fwrite(jv_string_value(result), 1, jv_string_length(jv_copy(result)), stdout); } else { - int dumpopts = 0; + int dumpopts = isatty(fileno(stdout)) ? JV_PRINT_COLOUR : 0; if (!(options & COMPACT_OUTPUT)) dumpopts |= JV_PRINT_PRETTY; if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII; + if (options & COLOUR_OUTPUT) dumpopts |= JV_PRINT_COLOUR; + if (options & NO_COLOUR_OUTPUT) dumpopts &= ~JV_PRINT_COLOUR; jv_dump(result, dumpopts); } printf("\n"); @@ -111,6 +116,10 @@ int main(int argc, char* argv[]) { options |= RAW_OUTPUT; } else if (isoption(argv[i], 'c', "compact-output")) { options |= COMPACT_OUTPUT; + } else if (isoption(argv[i], 'C', "color-output")) { + options |= COLOUR_OUTPUT; + } else if (isoption(argv[i], 'M', "monochrome-output")) { + options |= NO_COLOUR_OUTPUT; } else if (isoption(argv[i], 'a', "ascii-output")) { options |= ASCII_OUTPUT; } else if (isoption(argv[i], 'R', "raw-input")) { From c8bbfed0410b7181a81952fb9314d5995b0d5e2e Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 3 Dec 2012 02:00:29 +0000 Subject: [PATCH 19/62] See, I told you colour was a bad idea! #11 Last commit broke the build, minor fix needed to testsuite. --- jq_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jq_test.c b/jq_test.c index b4674c81..2960162e 100644 --- a/jq_test.c +++ b/jq_test.c @@ -61,7 +61,7 @@ static void run_jq_tests() { printf("\n"); pass = 0; } - jv as_string = jv_dump_string(jv_copy(expected), rand()); + jv as_string = jv_dump_string(jv_copy(expected), rand() & ~JV_PRINT_COLOUR); jv reparsed = jv_parse_sized(jv_string_value(as_string), jv_string_length(jv_copy(as_string))); assert(jv_equal(jv_copy(expected), jv_copy(reparsed))); jv_free(as_string); From fadeb66365cb8da2cddf3993ad139736922852ae Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 3 Dec 2012 02:02:12 +0000 Subject: [PATCH 20/62] Add a `unique` function. --- builtin.c | 1 + docs/content/3.manual/manual.yml | 12 ++++++++++++ testdata | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/builtin.c b/builtin.c index 43cfe267..a3c1f78b 100644 --- a/builtin.c +++ b/builtin.c @@ -295,6 +295,7 @@ static const char* jq_builtins[] = { "def select(f): if f then . else empty end;", "def sort_by(f): _sort_by_impl(map([f]));", "def group_by(f): _group_by_impl(map([f]));", + "def unique: group_by(.) | map(.[0]);", }; diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 0e16a495..2e616e14 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -542,6 +542,18 @@ sections: input: '[{"foo":1, "bar":10}, {"foo":3, "bar":100}, {"foo":1, "bar":1}]' output: ['[[{"foo":1, "bar":10}, {"foo":1, "bar":1}], [{"foo":3, "bar":100}]]'] + - title: `unique` + body: | + + The `unique` function takes as input an array and produces + an array of the same elements, in sorted order, with + duplicates removed. + + examples: + - program: 'unique' + input: '[1,2,5,3,5,3,1,3]' + output: ['[1,2,3,5]'] + - title: `contains` body: | diff --git a/testdata b/testdata index e08e6aa5..cc8263b0 100644 --- a/testdata +++ b/testdata @@ -448,3 +448,7 @@ sort [{"a": 4, "b": 1, "c": 3}, {"a": 0, "b": 2, "c": 43}, {"a": 1, "b": 4, "c": 3}, {"a": 1, "b": 4, "c": 14}] [[{"a": 4, "b": 1, "c": 3}], [{"a": 0, "b": 2, "c": 43}], [{"a": 1, "b": 4, "c": 14}, {"a": 1, "b": 4, "c": 3}]] [[{"a": 1, "b": 4, "c": 14}, {"a": 0, "b": 2, "c": 43}], [{"a": 4, "b": 1, "c": 3}, {"a": 1, "b": 4, "c": 3}]] + +unique +[1,2,5,3,5,3,1,3] +[1,2,3,5] From 5f6a95c7b574c6d0f52e62e2405c550606a5ce75 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 3 Dec 2012 20:00:36 +0000 Subject: [PATCH 21/62] General cleanup - rename a few things, delete dead code. --- builtin.c | 10 ++--- bytecode.c | 4 +- compile.c | 106 ++++++++++++++--------------------------------- compile.h | 3 +- forkable_stack.h | 2 - opcode.c | 8 ++-- opcode.h | 3 -- opcode_list.h | 7 ++-- parser.y | 31 +++++++------- 9 files changed, 62 insertions(+), 112 deletions(-) diff --git a/builtin.c b/builtin.c index a3c1f78b..ef447935 100644 --- a/builtin.c +++ b/builtin.c @@ -277,11 +277,11 @@ struct bytecoded_builtin { const char* name; block code; }; static block bind_bytecoded_builtins(block b) { struct bytecoded_builtin builtin_defs[] = { {"empty", gen_op_simple(BACKTRACK)}, - {"false", gen_op_const(LOADK, jv_false())}, - {"true", gen_op_const(LOADK, jv_true())}, - {"null", gen_op_const(LOADK, jv_null())}, - {"not", gen_condbranch(gen_op_const(LOADK, jv_false()), - gen_op_const(LOADK, jv_true()))} + {"false", gen_const(jv_false())}, + {"true", gen_const(jv_true())}, + {"null", gen_const(jv_null())}, + {"not", gen_condbranch(gen_const(jv_false()), + gen_const(jv_true()))} }; block builtins = gen_noop(); for (unsigned i=0; iflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { + if (*codeptr == CALL_JQ) { return 4 + codeptr[1] * 2; } else { return opcode_length(*codeptr); @@ -41,7 +41,7 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) { printf("%s", op->name); if (op->length > 1) { uint16_t imm = bc->code[pc++]; - if (op->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { + if (op->op == CALL_JQ) { for (int i=0; icode[pc++]; uint16_t idx = bc->code[pc++]; diff --git a/compile.c b/compile.c index acc89749..8a493b45 100644 --- a/compile.c +++ b/compile.c @@ -109,9 +109,9 @@ block gen_op_simple(opcode op) { } -block gen_op_const(opcode op, jv constant) { - assert(opcode_describe(op)->flags & OP_HAS_CONSTANT); - inst* i = inst_new(op); +block gen_const(jv constant) { + assert(opcode_describe(LOADK)->flags & OP_HAS_CONSTANT); + inst* i = inst_new(LOADK); i->imm.constant = constant; return inst_block(i); } @@ -151,13 +151,6 @@ block gen_op_var_bound(opcode op, block binder) { return b; } -block gen_op_symbol(opcode op, const char* sym) { - assert(opcode_describe(op)->flags & OP_HAS_SYMBOL); - inst* i = inst_new(op); - i->symbol = strdup(sym); - return inst_block(i); -} - block gen_op_block_unbound(opcode op, const char* name) { assert(opcode_describe(op)->flags & OP_IS_CALL_PSEUDO); inst* i = inst_new(op); @@ -180,32 +173,6 @@ static void inst_join(inst* a, inst* b) { b->prev = a; } -static void block_insert_after(inst* i, block b) { - if (b.first) { - assert(b.last); - if (i->next) { - inst* j = i->next; - i->next = 0; - j->prev = 0; - inst_join(b.last, j); - } - inst_join(i, b.first); - } -} - -static void block_insert_before(inst* i, block b) { - if (b.first) { - assert(b.last); - if (i->prev) { - inst* j = i->prev; - i->prev = 0; - j->next = 0; - inst_join(j, b.first); - } - inst_join(b.last, i); - } -} - void block_append(block* b, block b2) { if (b2.first) { if (b->last) { @@ -248,14 +215,10 @@ static void block_bind_subblock(block binder, block body, int bindflags) { // bind this instruction i->bound_by = binder.first; } - if (flags & OP_HAS_BLOCK) { - // binding recurses into closures - block_bind_subblock(binder, i->subfn, bindflags); - } - if (flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - // binding recurses into argument list - block_bind_subblock(binder, i->arglist, bindflags); - } + // binding recurses into closures + block_bind_subblock(binder, i->subfn, bindflags); + // binding recurses into argument list + block_bind_subblock(binder, i->arglist, bindflags); } } @@ -306,7 +269,7 @@ block gen_both(block a, block b) { block gen_collect(block expr) { block array_var = block_bind(gen_op_var_unbound(STOREV, "collect"), gen_noop(), OP_HAS_VARIABLE); - block c = BLOCK(gen_op_simple(DUP), gen_op_const(LOADK, jv_array()), array_var); + block c = BLOCK(gen_op_simple(DUP), gen_const(jv_array()), array_var); block tail = BLOCK(gen_op_simple(DUP), gen_op_var_bound(LOADV, array_var), @@ -342,7 +305,7 @@ block gen_definedor(block a, block b) { // var found := false block found_var = block_bind(gen_op_var_unbound(STOREV, "found"), gen_noop(), OP_HAS_VARIABLE); - block init = BLOCK(gen_op_simple(DUP), gen_op_const(LOADK, jv_false()), found_var); + block init = BLOCK(gen_op_simple(DUP), gen_const(jv_false()), found_var); // if found, backtrack. Otherwise execute b block backtrack = gen_op_simple(BACKTRACK); @@ -358,7 +321,7 @@ block gen_definedor(block a, block b) { // found := true, produce result block if_found = BLOCK(gen_op_simple(DUP), - gen_op_const(LOADK, jv_true()), + gen_const(jv_true()), gen_op_var_bound(STOREV, found_var), gen_op_target(JUMP, tail)); @@ -381,19 +344,19 @@ block gen_and(block a, block b) { 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())))); + gen_condbranch(gen_const(jv_true()), + gen_const(jv_false()))), + BLOCK(gen_op_simple(POP), gen_const(jv_false())))); } block gen_or(block a, block b) { // a or b = if a then true else (if b then true else false) return BLOCK(gen_op_simple(DUP), a, - gen_condbranch(BLOCK(gen_op_simple(POP), gen_op_const(LOADK, jv_true())), + gen_condbranch(BLOCK(gen_op_simple(POP), gen_const(jv_true())), BLOCK(gen_op_simple(POP), b, - gen_condbranch(gen_op_const(LOADK, jv_true()), - gen_op_const(LOADK, jv_false()))))); + gen_condbranch(gen_const(jv_true()), + gen_const(jv_false()))))); } block gen_cond(block cond, block iftrue, block iffalse) { @@ -427,8 +390,7 @@ static int count_cfunctions(block b) { int n = 0; for (inst* i = b.first; i; i = i->next) { if (i->op == CLOSURE_CREATE_C) n++; - if (opcode_describe(i->op)->flags & OP_HAS_BLOCK) - n += count_cfunctions(i->subfn); + n += count_cfunctions(i->subfn); } return n; } @@ -439,8 +401,7 @@ static int count_cfunctions(block b) { static block expand_call_arglist(block b) { block ret = gen_noop(); for (inst* curr; (curr = block_take(&b));) { - if (opcode_describe(curr->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - assert(curr->op == CALL_JQ); + if (curr->op == CALL_JQ) { inst* seq_end = block_take(&b); assert(seq_end && seq_end->op == CALLSEQ_END); // We expand the argument list as a series of instructions @@ -541,11 +502,11 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { curr->bound_by == curr) { curr->imm.intval = var_frame_idx++; } - if (opflags & OP_HAS_BLOCK) { + + if (curr->op == CLOSURE_CREATE) { assert(curr->bound_by == curr); curr->imm.intval = bc->nsubfunctions++; } - if (curr->op == CLOSURE_PARAM) { assert(curr->bound_by == curr); curr->imm.intval = bc->nclosures++; @@ -560,14 +521,14 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { if (bc->nsubfunctions) { bc->subfunctions = malloc(sizeof(struct bytecode*) * bc->nsubfunctions); for (inst* curr = b.first; curr; curr = curr->next) { - if (!(opcode_describe(curr->op)->flags & OP_HAS_BLOCK)) - continue; - struct bytecode* subfn = malloc(sizeof(struct bytecode)); - bc->subfunctions[curr->imm.intval] = subfn; - subfn->globals = bc->globals; - subfn->parent = bc; - errors += compile(locations, subfn, curr->subfn); - curr->subfn = gen_noop(); + if (curr->op == CLOSURE_CREATE) { + struct bytecode* subfn = malloc(sizeof(struct bytecode)); + bc->subfunctions[curr->imm.intval] = subfn; + subfn->globals = bc->globals; + subfn->parent = bc; + errors += compile(locations, subfn, curr->subfn); + curr->subfn = gen_noop(); + } } } else { bc->subfunctions = 0; @@ -583,7 +544,6 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { if (op->length == 0) continue; code[pos++] = curr->op; - int opflags = op->flags; assert(!(op->flags & OP_IS_CALL_PSEUDO)); if (curr->op == CALL_BUILTIN) { int nargs = curr->imm.intval; @@ -591,12 +551,10 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { assert(block_is_single(curr->arglist)); inst* cfunc = curr->arglist.first; assert(cfunc && cfunc->bound_by->op == CLOSURE_CREATE_C); - //*opcode_rewrite = bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop; code[pos++] = cfunc->bound_by->imm.intval; // FIXME arg errors assert(nargs == bc->globals->cfunctions[cfunc->bound_by->imm.intval].nargs); - } else if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) { - assert(curr->op == CALL_JQ); + } else if (curr->op == CALL_JQ) { int nargs = curr->imm.intval; assert(nargs >= 0 && nargs < 100); //FIXME code[pos++] = (uint16_t)nargs; @@ -623,15 +581,15 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { assert(curr->bound_by->op == CLOSURE_CREATE); code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE; } - } else if (opflags & OP_HAS_CONSTANT) { + } else if (op->flags & OP_HAS_CONSTANT) { code[pos++] = jv_array_length(jv_copy(constant_pool)); constant_pool = jv_array_append(constant_pool, jv_copy(curr->imm.constant)); - } else if (opflags & OP_HAS_VARIABLE) { + } else if (op->flags & OP_HAS_VARIABLE) { code[pos++] = nesting_level(bc, curr->bound_by); uint16_t var = (uint16_t)curr->bound_by->imm.intval; code[pos++] = var; if (var > maxvar) maxvar = var; - } else if (opflags & OP_HAS_BRANCH) { + } else if (op->flags & OP_HAS_BRANCH) { assert(curr->imm.target->bytecode_pos != -1); assert(curr->imm.target->bytecode_pos > pos); // only forward branches code[pos] = curr->imm.target->bytecode_pos - (pos + 1); diff --git a/compile.h b/compile.h index 9a885159..7ac634ba 100644 --- a/compile.h +++ b/compile.h @@ -21,12 +21,11 @@ block gen_location(location, block); block gen_noop(); block gen_op_simple(opcode op); -block gen_op_const(opcode op, jv constant); +block gen_const(jv constant); block gen_op_target(opcode op, block target); block gen_op_var_unbound(opcode op, const char* name); block gen_op_var_bound(opcode op, block binder); block gen_op_block_unbound(opcode op, const char* name); -block gen_op_symbol(opcode op, const char* name); block gen_function(const char* name, block body); block gen_lambda(block body); diff --git a/forkable_stack.h b/forkable_stack.h index 5bfad8a9..a94a1ec3 100644 --- a/forkable_stack.h +++ b/forkable_stack.h @@ -15,7 +15,6 @@ struct forkable_stack_header { struct forkable_stack { // Stack grows down from stk+length - char* stk; // stk+length is just past end of allocated area @@ -61,7 +60,6 @@ static void* forkable_stack_push(struct forkable_stack* s, size_t sz_size) { forkable_stack_check(s); int curr = s->pos < s->savedlimit ? s->pos : s->savedlimit; if (curr - size < 0) { - //assert(0); int oldlen = s->length; s->length = (size + oldlen + 1024) * 2; s->stk = realloc(s->stk, s->length); diff --git a/opcode.c b/opcode.c index c4c6356d..9b3e5ca3 100644 --- a/opcode.c +++ b/opcode.c @@ -5,12 +5,10 @@ #define CONSTANT OP_HAS_CONSTANT, 2 #define VARIABLE (OP_HAS_VARIABLE | OP_HAS_BINDING), 3 #define BRANCH OP_HAS_BRANCH, 2 -#define CFUNC (OP_HAS_SYMBOL | OP_HAS_CFUNC), 3 -#define UFUNC (OP_HAS_UFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST), 2 +#define CFUNC OP_HAS_CFUNC, 3 +#define UFUNC OP_HAS_UFUNC, 2 #define CALLSEQ_END_IMM (OP_IS_CALL_PSEUDO), 0 -#define CLOSURE_PARAM_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 -#define CLOSURE_CREATE_IMM (OP_HAS_BLOCK | OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 -#define CLOSURE_CREATE_C_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 +#define DEFINITION (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 #define CLOSURE_REF_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 2 #define OP(name, imm, in, out) \ diff --git a/opcode.h b/opcode.h index 73948cd5..91624788 100644 --- a/opcode.h +++ b/opcode.h @@ -19,12 +19,9 @@ enum { OP_HAS_CONSTANT = 2, OP_HAS_VARIABLE = 4, OP_HAS_BRANCH = 8, - OP_HAS_SYMBOL = 16, OP_HAS_CFUNC = 32, OP_HAS_UFUNC = 64, OP_IS_CALL_PSEUDO = 128, - OP_HAS_VARIABLE_LENGTH_ARGLIST = 256, - OP_HAS_BLOCK = 512, OP_HAS_BINDING = 1024, }; struct opcode_description { diff --git a/opcode_list.h b/opcode_list.h index 27211a2d..a39d30e0 100644 --- a/opcode_list.h +++ b/opcode_list.h @@ -5,7 +5,6 @@ OP(POP, NONE, 1, 0) OP(LOADV, VARIABLE, 1, 1) OP(STOREV, VARIABLE, 1, 0) OP(INDEX, NONE, 2, 1) -//OP(DISPLAY, NONE, 1, 0) OP(YIELD, NONE, 1, 0) OP(EACH, NONE, 1, 1) OP(FORK, BRANCH, 0, 0) @@ -23,7 +22,7 @@ OP(CALL_JQ, UFUNC, 1, 1) OP(RET, NONE, 1, 1) OP(CALLSEQ_END, CALLSEQ_END_IMM, 0, 0) -OP(CLOSURE_PARAM, CLOSURE_PARAM_IMM, 0, 0) +OP(CLOSURE_PARAM, DEFINITION, 0, 0) OP(CLOSURE_REF, CLOSURE_REF_IMM, 0, 0) -OP(CLOSURE_CREATE, CLOSURE_CREATE_IMM, 0, 0) -OP(CLOSURE_CREATE_C, CLOSURE_CREATE_C_IMM, 0, 0) +OP(CLOSURE_CREATE, DEFINITION, 0, 0) +OP(CLOSURE_CREATE_C, DEFINITION, 0, 0) diff --git a/parser.y b/parser.y index bdee008b..cee3c9d6 100644 --- a/parser.y +++ b/parser.y @@ -297,11 +297,6 @@ Term { $$ = $1; } -String: -QQSTRING_START QQString QQSTRING_END { - $$ = $2; -} - FuncDef: "def" IDENT ':' Exp ';' { $$ = gen_function(jv_string_value($2), $4); @@ -315,12 +310,18 @@ FuncDef: jv_free($4); } + +String: +QQSTRING_START QQString QQSTRING_END { + $$ = $2; +} + QQString: /* empty */ { - $$ = gen_op_const(LOADK, jv_string("")); + $$ = gen_const(jv_string("")); } | QQString QQSTRING_TEXT { - $$ = gen_binop($1, gen_op_const(LOADK, $2), '+'); + $$ = gen_binop($1, gen_const($2), '+'); } | QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END { $$ = gen_binop($1, gen_format($3), '+'); @@ -350,10 +351,10 @@ Term: $$ = gen_noop(); } | Term '.' IDENT { - $$ = gen_index($1, gen_op_const(LOADK, $3)); + $$ = gen_index($1, gen_const($3)); } | '.' IDENT { - $$ = gen_index(gen_noop(), gen_op_const(LOADK, $2)); + $$ = gen_index(gen_noop(), gen_const($2)); } | /* FIXME: string literals */ Term '[' Exp ']' { @@ -363,7 +364,7 @@ Term '[' ']' { $$ = block_join($1, gen_op_simple(EACH)); } | LITERAL { - $$ = gen_op_const(LOADK, $1); + $$ = gen_const($1); } | String { $$ = $1; @@ -375,10 +376,10 @@ String { $$ = gen_collect($2); } | '[' ']' { - $$ = gen_op_const(LOADK, jv_array()); + $$ = gen_const(jv_array()); } | '{' MkDict '}' { - $$ = BLOCK(gen_subexp(gen_op_const(LOADK, jv_object())), $2, gen_op_simple(POP)); + $$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP)); } | '$' IDENT { $$ = gen_location(@$, gen_op_var_unbound(LOADV, jv_string_value($2))); @@ -408,14 +409,14 @@ MkDict: MkDictPair : IDENT ':' ExpD { - $$ = gen_dictpair(gen_op_const(LOADK, $1), $3); + $$ = gen_dictpair(gen_const($1), $3); } | String ':' ExpD { $$ = gen_dictpair($1, $3); } | IDENT { - $$ = gen_dictpair(gen_op_const(LOADK, jv_copy($1)), - gen_index(gen_noop(), gen_op_const(LOADK, $1))); + $$ = gen_dictpair(gen_const(jv_copy($1)), + gen_index(gen_noop(), gen_const($1))); } | '(' Exp ')' ':' ExpD { $$ = gen_dictpair($2, $5); From a88d53d2fda9a755c9c972a09a1206d54ca0d8b2 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 3 Dec 2012 20:31:40 +0000 Subject: [PATCH 22/62] Extend `{foo}` syntax to allow `{"foo"}` as well. Useful when "foo" contains unusual characters. Should help with the issues #7, #38, #40, #42. --- execute.c | 11 +++++++++++ opcode_list.h | 1 + parser.y | 4 ++++ testdata | 4 ++++ 4 files changed, 20 insertions(+) diff --git a/execute.c b/execute.c index 8fadc7e7..8b8036a1 100644 --- a/execute.c +++ b/execute.c @@ -208,6 +208,17 @@ jv jq_next() { break; } + case DUP2: { + stackval keep = stack_pop(); + stackval v = stack_pop(); + stackval v2 = v; + v2.value = jv_copy(v.value); + stack_push(v); + stack_push(keep); + stack_push(v2); + break; + } + case SWAP: { stackval a = stack_pop(); stackval b = stack_pop(); diff --git a/opcode_list.h b/opcode_list.h index a39d30e0..03cdbc8b 100644 --- a/opcode_list.h +++ b/opcode_list.h @@ -1,5 +1,6 @@ OP(LOADK, CONSTANT, 1, 1) OP(DUP, NONE, 1, 2) +OP(DUP2, NONE, 2, 3) OP(SWAP, NONE, 2, 2) OP(POP, NONE, 1, 0) OP(LOADV, VARIABLE, 1, 1) diff --git a/parser.y b/parser.y index cee3c9d6..e3d32e45 100644 --- a/parser.y +++ b/parser.y @@ -414,6 +414,10 @@ MkDictPair | String ':' ExpD { $$ = gen_dictpair($1, $3); } +| String { + $$ = gen_dictpair($1, BLOCK(gen_op_simple(POP), gen_op_simple(DUP2), + gen_op_simple(DUP2), gen_op_simple(INDEX))); + } | IDENT { $$ = gen_dictpair(gen_const(jv_copy($1)), gen_index(gen_noop(), gen_const($1))); diff --git a/testdata b/testdata index cc8263b0..088d255d 100644 --- a/testdata +++ b/testdata @@ -64,6 +64,10 @@ null {"a":1, "b":2, "c":3, "d":"c"} {"a":1, "b":2, "c":1, "e":2} +{"a",b,"a$\(1+1)"} +{"a":1, "b":2, "c":3, "a$2":4} +{"a":1, "b":2, "a$2":4} + # # Field access, piping # From 616e8f9924ad9df22acf58c79c5d49ef6030fcb8 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Tue, 4 Dec 2012 00:39:21 +0000 Subject: [PATCH 23/62] Refactor function argument passing into what it always should have been. Most visible change is that error messages when a function is called with the wrong number of arguments are much better. --- builtin.c | 3 +- bytecode.c | 6 +- compile.c | 180 +++++++++++++++++++++++++------------------------- compile.h | 2 +- opcode.c | 5 +- opcode.h | 4 -- opcode_list.h | 1 - parser.y | 7 +- 8 files changed, 103 insertions(+), 105 deletions(-) diff --git a/builtin.c b/builtin.c index ef447935..2c5787da 100644 --- a/builtin.c +++ b/builtin.c @@ -285,7 +285,8 @@ static block bind_bytecoded_builtins(block b) { }; block builtins = gen_noop(); for (unsigned i=0; ilength; if (*codeptr == CALL_JQ) { - return 4 + codeptr[1] * 2; - } else { - return opcode_length(*codeptr); + length += codeptr[1] * 2; } + return length; } void dump_disassembly(int indent, struct bytecode* bc) { diff --git a/compile.c b/compile.c index 8a493b45..eb0fe78d 100644 --- a/compile.c +++ b/compile.c @@ -12,7 +12,7 @@ struct inst { opcode op; - union { + struct { uint16_t intval; struct inst* target; jv constant; @@ -222,33 +222,38 @@ static void block_bind_subblock(block binder, block body, int bindflags) { } } -block block_bind(block binder, block body, int bindflags) { +static void block_bind_each(block binder, block body, int bindflags) { assert(block_has_only_binders(binder, bindflags)); bindflags |= OP_HAS_BINDING; for (inst* curr = binder.first; curr; curr = curr->next) { block_bind_subblock(inst_block(curr), body, bindflags); } +} + +block block_bind(block binder, block body, int bindflags) { + block_bind_each(binder, body, bindflags); return block_join(binder, body); } - -block gen_function(const char* name, block body) { +block gen_function(const char* name, block formals, block body) { + block_bind_each(formals, body, OP_IS_CALL_PSEUDO); inst* i = inst_new(CLOSURE_CREATE); i->subfn = body; i->symbol = strdup(name); + i->arglist = formals; block b = inst_block(i); block_bind_subblock(b, b, OP_IS_CALL_PSEUDO | OP_HAS_BINDING); return b; } block gen_lambda(block body) { - return gen_function("@lambda", body); + return gen_function("@lambda", gen_noop(), body); } block gen_call(const char* name, block args) { - inst* i = inst_new(CALL_JQ); - i->arglist = BLOCK(gen_op_block_unbound(CLOSURE_REF, name), args); - return BLOCK(inst_block(i), inst_block(inst_new(CALLSEQ_END))); + block b = gen_op_block_unbound(CALL_JQ, name); + b.first->arglist = args; + return b; } @@ -397,28 +402,30 @@ static int count_cfunctions(block b) { // Expands call instructions into a calling sequence -// Checking for argument count compatibility happens later -static block expand_call_arglist(block b) { +static int expand_call_arglist(struct locfile* locations, block* b) { + int errors = 0; block ret = gen_noop(); - for (inst* curr; (curr = block_take(&b));) { - if (curr->op == CALL_JQ) { - inst* seq_end = block_take(&b); - assert(seq_end && seq_end->op == CALLSEQ_END); - // We expand the argument list as a series of instructions - block arglist = curr->arglist; - curr->arglist = gen_noop(); - assert(arglist.first && "zeroth argument (function to call) must be present"); - inst* function = arglist.first->bound_by; - assert(function); // FIXME better errors + for (inst* curr; (curr = block_take(b));) { + if (opcode_describe(curr->op)->flags & OP_HAS_BINDING) { + if (!curr->bound_by) { + locfile_locate(locations, curr->source, "error: %s is not defined", curr->symbol); + errors++; + // don't process this instruction if it's not well-defined + ret = BLOCK(ret, inst_block(curr)); + continue; + } + } - switch (function->op) { - default: assert(0 && "Unknown parameter type"); break; + block prelude = gen_noop(); + if (curr->op == CALL_JQ) { + int actual_args = 0, desired_args = 0; + // We expand the argument list as a series of instructions + switch (curr->bound_by->op) { + default: assert(0 && "Unknown function type"); break; case CLOSURE_CREATE: case CLOSURE_PARAM: { - block prelude = gen_noop(); block callargs = gen_noop(); - int nargs = 0; - for (inst* i; (i = block_take(&arglist));) { + for (inst* i; (i = block_take(&curr->arglist));) { assert(opcode_describe(i->op)->flags & OP_IS_CALL_PSEUDO); block b = inst_block(i); switch (i->op) { @@ -431,44 +438,54 @@ static block expand_call_arglist(block b) { block_append(&callargs, gen_op_block_bound(CLOSURE_REF, b)); break; } - nargs++; + actual_args++; } + curr->imm.intval = actual_args; + curr->arglist = callargs; - assert(!arglist.first); - assert(nargs > 0); - curr->imm.intval = nargs - 1; - ret = BLOCK(ret, prelude, inst_block(curr), callargs, inst_block(seq_end)); + if (curr->bound_by->op == CLOSURE_CREATE) { + for (inst* i = curr->bound_by->arglist.first; i; i = i->next) { + assert(i->op == CLOSURE_PARAM); + desired_args++; + } + } break; } case CLOSURE_CREATE_C: { - // Arguments to C functions not yet supported - inst* cfunction_ref = block_take(&arglist); - block prelude = gen_noop(); - int nargs = 1; - for (inst* i; (i = block_take(&arglist)); ) { + for (inst* i; (i = block_take(&curr->arglist)); ) { assert(i->op == CLOSURE_CREATE); // FIXME block body = i->subfn; i->subfn = gen_noop(); inst_free(i); // arguments should be pushed in reverse order, prepend them to prelude - prelude = BLOCK(gen_subexp(expand_call_arglist(body)), prelude); - nargs++; + errors += expand_call_arglist(locations, &body); + prelude = BLOCK(gen_subexp(body), prelude); + actual_args++; } assert(curr->op == CALL_JQ); curr->op = CALL_BUILTIN; - curr->imm.intval = nargs; + curr->imm.intval = actual_args + 1 /* include the implicit input in arg count */; + assert(curr->bound_by->op == CLOSURE_CREATE_C); + desired_args = curr->bound_by->imm.cfunc->nargs - 1; assert(!curr->arglist.first); - curr->arglist = inst_block(cfunction_ref); - ret = BLOCK(ret, prelude, inst_block(curr), inst_block(seq_end)); break; } } - } else { - ret = BLOCK(ret, inst_block(curr)); + + if (actual_args != desired_args) { + locfile_locate(locations, curr->source, + "error: %s arguments to %s (expected %d but got %d)", + actual_args > desired_args ? "too many" : "too few", + curr->symbol, desired_args, actual_args); + errors++; + } + } + ret = BLOCK(ret, prelude, inst_block(curr)); } - return ret; + *b = ret; + return errors; } static int compile(struct locfile* locations, struct bytecode* bc, block b) { @@ -476,8 +493,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { int pos = 0; int var_frame_idx = 0; bc->nsubfunctions = 0; - bc->nclosures = 0; - b = expand_call_arglist(b); + errors += expand_call_arglist(locations, &b); if (bc->parent) { // functions should end in a return b = BLOCK(b, gen_op_simple(RET)); @@ -487,18 +503,19 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { } for (inst* curr = b.first; curr; curr = curr->next) { if (!curr->next) assert(curr == b.last); - pos += opcode_length(curr->op); + int length = opcode_describe(curr->op)->length; + if (curr->op == CALL_JQ) { + for (inst* arg = curr->arglist.first; arg; arg = arg->next) { + length += 2; + } + } + pos += length; curr->bytecode_pos = pos; curr->compiled = bc; - int opflags = opcode_describe(curr->op)->flags; - if (opflags & OP_HAS_BINDING) { - if (!curr->bound_by) { - locfile_locate(locations, curr->source, "error: %s is not defined", curr->symbol); - errors++; - } - } - if ((opflags & OP_HAS_VARIABLE) && + assert(curr->op != CLOSURE_REF && curr->op != CLOSURE_PARAM); + + if ((opcode_describe(curr->op)->flags & OP_HAS_VARIABLE) && curr->bound_by == curr) { curr->imm.intval = var_frame_idx++; } @@ -507,10 +524,6 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { assert(curr->bound_by == curr); curr->imm.intval = bc->nsubfunctions++; } - if (curr->op == CLOSURE_PARAM) { - assert(curr->bound_by == curr); - curr->imm.intval = bc->nclosures++; - } if (curr->op == CLOSURE_CREATE_C) { assert(curr->bound_by == curr); int idx = bc->globals->ncfunctions++; @@ -526,6 +539,13 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { bc->subfunctions[curr->imm.intval] = subfn; subfn->globals = bc->globals; subfn->parent = bc; + subfn->nclosures = 0; + for (inst* param = curr->arglist.first; param; param = param->next) { + assert(param->op == CLOSURE_PARAM); + assert(param->bound_by == param); + param->imm.intval = subfn->nclosures++; + param->compiled = subfn; + } errors += compile(locations, subfn, curr->subfn); curr->subfn = gen_noop(); } @@ -544,42 +564,23 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { if (op->length == 0) continue; code[pos++] = curr->op; - assert(!(op->flags & OP_IS_CALL_PSEUDO)); + assert(curr->op != CLOSURE_REF && curr->op != CLOSURE_PARAM); if (curr->op == CALL_BUILTIN) { - int nargs = curr->imm.intval; - code[pos++] = (uint16_t)nargs; - assert(block_is_single(curr->arglist)); - inst* cfunc = curr->arglist.first; - assert(cfunc && cfunc->bound_by->op == CLOSURE_CREATE_C); - code[pos++] = cfunc->bound_by->imm.intval; - // FIXME arg errors - assert(nargs == bc->globals->cfunctions[cfunc->bound_by->imm.intval].nargs); + assert(curr->bound_by->op == CLOSURE_CREATE_C); + assert(!curr->arglist.first); + code[pos++] = (uint16_t)curr->imm.intval; + code[pos++] = curr->bound_by->imm.intval; } else if (curr->op == CALL_JQ) { - int nargs = curr->imm.intval; - assert(nargs >= 0 && nargs < 100); //FIXME - code[pos++] = (uint16_t)nargs; - curr = curr->next; - assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); assert(curr->bound_by->op == CLOSURE_CREATE || curr->bound_by->op == CLOSURE_PARAM); + code[pos++] = (uint16_t)curr->imm.intval; code[pos++] = nesting_level(bc, curr->bound_by); - if (curr->bound_by->op == CLOSURE_CREATE) { - code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE; - inst* i = curr->bound_by; - // FIXME arg errors - assert(nargs == i->compiled->subfunctions[i->imm.intval]->nclosures); - } else { - code[pos++] = curr->bound_by->imm.intval; - // FIXME arg errors - assert(nargs == 0); - } - for (int i=0; inext; - assert(curr && opcode_describe(curr->op)->flags & OP_IS_CALL_PSEUDO); - assert(curr->op == CLOSURE_REF); - code[pos++] = nesting_level(bc, curr->bound_by); - assert(curr->bound_by->op == CLOSURE_CREATE); - code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE; + code[pos++] = curr->bound_by->imm.intval | + (curr->bound_by->op == CLOSURE_CREATE ? ARG_NEWCLOSURE : 0); + for (inst* arg = curr->arglist.first; arg; arg = arg->next) { + assert(arg->op == CLOSURE_REF && arg->bound_by->op == CLOSURE_CREATE); + code[pos++] = nesting_level(bc, arg->bound_by); + code[pos++] = arg->bound_by->imm.intval | ARG_NEWCLOSURE; } } else if (op->flags & OP_HAS_CONSTANT) { code[pos++] = jv_array_length(jv_copy(constant_pool)); @@ -607,6 +608,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { int block_compile(block b, struct locfile* locations, struct bytecode** out) { struct bytecode* bc = malloc(sizeof(struct bytecode)); bc->parent = 0; + bc->nclosures = 0; bc->globals = malloc(sizeof(struct symbol_table)); int ncfunc = count_cfunctions(b); bc->globals->ncfunctions = 0; diff --git a/compile.h b/compile.h index 7ac634ba..e74afce4 100644 --- a/compile.h +++ b/compile.h @@ -27,7 +27,7 @@ block gen_op_var_unbound(opcode op, const char* name); block gen_op_var_bound(opcode op, block binder); block gen_op_block_unbound(opcode op, const char* name); -block gen_function(const char* name, block body); +block gen_function(const char* name, block formals, block body); block gen_lambda(block body); block gen_call(const char* name, block body); block gen_subexp(block a); diff --git a/opcode.c b/opcode.c index 9b3e5ca3..4e785b8f 100644 --- a/opcode.c +++ b/opcode.c @@ -5,9 +5,8 @@ #define CONSTANT OP_HAS_CONSTANT, 2 #define VARIABLE (OP_HAS_VARIABLE | OP_HAS_BINDING), 3 #define BRANCH OP_HAS_BRANCH, 2 -#define CFUNC OP_HAS_CFUNC, 3 -#define UFUNC OP_HAS_UFUNC, 2 -#define CALLSEQ_END_IMM (OP_IS_CALL_PSEUDO), 0 +#define CFUNC (OP_HAS_CFUNC | OP_HAS_BINDING), 3 +#define UFUNC (OP_HAS_UFUNC | OP_HAS_BINDING | OP_IS_CALL_PSEUDO), 4 #define DEFINITION (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0 #define CLOSURE_REF_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 2 diff --git a/opcode.h b/opcode.h index 91624788..ee956e27 100644 --- a/opcode.h +++ b/opcode.h @@ -38,8 +38,4 @@ struct opcode_description { const struct opcode_description* opcode_describe(opcode op); -static inline int opcode_length(opcode op) { - return opcode_describe(op)->length; -} - #endif diff --git a/opcode_list.h b/opcode_list.h index 03cdbc8b..e6dece6e 100644 --- a/opcode_list.h +++ b/opcode_list.h @@ -22,7 +22,6 @@ OP(CALL_BUILTIN, CFUNC, -1, 1) OP(CALL_JQ, UFUNC, 1, 1) OP(RET, NONE, 1, 1) -OP(CALLSEQ_END, CALLSEQ_END_IMM, 0, 0) OP(CLOSURE_PARAM, DEFINITION, 0, 0) OP(CLOSURE_REF, CLOSURE_REF_IMM, 0, 0) OP(CLOSURE_CREATE, DEFINITION, 0, 0) diff --git a/parser.y b/parser.y index e3d32e45..f77d6d92 100644 --- a/parser.y +++ b/parser.y @@ -299,13 +299,14 @@ Term { FuncDef: "def" IDENT ':' Exp ';' { - $$ = gen_function(jv_string_value($2), $4); + $$ = gen_function(jv_string_value($2), gen_noop(), $4); jv_free($2); } | "def" IDENT '(' IDENT ')' ':' Exp ';' { - block body = block_bind(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)), $7, OP_IS_CALL_PSEUDO); - $$ = gen_function(jv_string_value($2), body); + $$ = gen_function(jv_string_value($2), + gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)), + $7); jv_free($2); jv_free($4); } From c0a2f1ab470595d85fd20a643325a16737433a2a Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Tue, 4 Dec 2012 22:45:03 +0000 Subject: [PATCH 24/62] Add min, max, min_by, max_by functions. --- builtin.c | 59 +++++++++++++++++++++++++++++++- docs/content/3.manual/manual.yml | 16 +++++++++ testdata | 8 +++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/builtin.c b/builtin.c index 2c5787da..b572dfaf 100644 --- a/builtin.c +++ b/builtin.c @@ -241,6 +241,56 @@ static jv f_group_by_impl(jv input, jv keys) { } } +static jv minmax_by(jv values, jv keys, int is_min) { + if (jv_get_kind(values) != JV_KIND_ARRAY) + return type_error2(values, keys, "cannot be iterated over"); + if (jv_get_kind(keys) != JV_KIND_ARRAY) + return type_error2(values, keys, "cannot be iterated over"); + if (jv_array_length(jv_copy(values)) != jv_array_length(jv_copy(keys))) + return type_error2(values, keys, "have wrong length"); + + if (jv_array_length(jv_copy(values)) == 0) { + jv_free(values); + jv_free(keys); + return jv_null(); + } + jv ret = jv_array_get(jv_copy(values), 0); + jv retkey = jv_array_get(jv_copy(keys), 0); + for (int i=1; i Date: Fri, 7 Dec 2012 00:26:00 +0000 Subject: [PATCH 25/62] Change order of evaluation for certain indexing operations. '.foo[.bar]' used to parse like '.foo | .bar as $b | .[$b]', now it parses like '.bar as $b | .foo | .[$b]'. --- parser.y | 2 +- testdata | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/parser.y b/parser.y index f77d6d92..a2c765cd 100644 --- a/parser.y +++ b/parser.y @@ -133,7 +133,7 @@ static block gen_dictpair(block k, block v) { } static block gen_index(block obj, block key) { - return BLOCK(obj, gen_subexp(key), gen_op_simple(INDEX)); + return BLOCK(gen_subexp(key), obj, gen_op_simple(INDEX)); } static block gen_binop(block a, block b, int op) { diff --git a/testdata b/testdata index a3e2e49b..00ecc69f 100644 --- a/testdata +++ b/testdata @@ -464,3 +464,7 @@ unique [min,max,min_by(.),max_by(.)] [] [null,null,null,null] + +.foo[.baz] +{"foo":{"bar":4},"baz":"bar"} +4 From c15e51ffb1312b3407fac1f6fd991a8f69cf96ce Mon Sep 17 00:00:00 2001 From: Stephen Shaw Date: Fri, 7 Dec 2012 14:31:59 +0000 Subject: [PATCH 26/62] Add information about installing dev environment on OS X --- docs/content/2.download/default.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/content/2.download/default.yml b/docs/content/2.download/default.yml index 7834ce72..5acf6bb4 100644 --- a/docs/content/2.download/default.yml +++ b/docs/content/2.download/default.yml @@ -58,6 +58,12 @@ body: likely already installed. I have no idea how to get these installed on OS X, you're on your own there. + On OS X, these are all included in Apple's command line tools, which + can be installed from [Xcode](developer.apple.com/technologies/tools/). + However, you may find that you need a newer version of Bison than the one provided + by Apple. This can be found in [Homebrew](http://mxcl.github.com/homebrew/) + or [MacPorts](http://macports.org/). + `flex` and `bison` are used to generate the lexer and parser for jq, and some python scripts generate the UTF8 encoding tables needed for JSON parsing. From 1db51e66bc36a7a4f4422be4549162522ec6fa82 Mon Sep 17 00:00:00 2001 From: Stephen Shaw Date: Fri, 7 Dec 2012 14:40:20 +0000 Subject: [PATCH 27/62] Remove old OS X 'instructions' --- docs/content/2.download/default.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/content/2.download/default.yml b/docs/content/2.download/default.yml index 5acf6bb4..833cac84 100644 --- a/docs/content/2.download/default.yml +++ b/docs/content/2.download/default.yml @@ -55,11 +55,10 @@ body: For Linux systems, these will all be in your system's package manager, and if you do development on the machine they're most - likely already installed. I have no idea how to get these - installed on OS X, you're on your own there. + likely already installed. On OS X, these are all included in Apple's command line tools, which - can be installed from [Xcode](developer.apple.com/technologies/tools/). + can be installed from [Xcode](http://developer.apple.com/technologies/tools/). However, you may find that you need a newer version of Bison than the one provided by Apple. This can be found in [Homebrew](http://mxcl.github.com/homebrew/) or [MacPorts](http://macports.org/). From b660bd2be669765c4070b1d8c1f9026e05abdbeb Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 10 Dec 2012 22:25:11 +0000 Subject: [PATCH 28/62] Fix Rack setup so that viewing documentation locally is less painful. --- docs/Rakefile | 6 ++++-- docs/site.yml | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/Rakefile b/docs/Rakefile index 62b0139e..51e9b484 100644 --- a/docs/Rakefile +++ b/docs/Rakefile @@ -38,11 +38,13 @@ task :serve do server = fork { app = Rack::Builder.app { - use Bonsai::StaticPassThrough, :root => Bonsai.root_dir + "/output", :urls => ["/"] + map "/jq" do + use Bonsai::StaticPassThrough, :root => Bonsai.root_dir + "/output", :urls => ["/"] + end run Bonsai::DevelopmentServer } Rack::Handler.default.run(app, :Port => 5000) do - Launchy.open("http://localhost:5000/") + Launchy.open("http://localhost:5000/jq") end } Watch.new("{content,templates,public}/**/*") { Bonsai::Exporter.process! } diff --git a/docs/site.yml b/docs/site.yml index 92a690d1..df758cef 100644 --- a/docs/site.yml +++ b/docs/site.yml @@ -2,9 +2,7 @@ jq_version: 1.1 -# Next line is needed for publishing to github pages root: '/jq' -# root: '' footer: | This website is made with [Bonsai](http://www.tinytree.info) and From 34ff993059310e362db0cc41bce43670e09e10ac Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 10 Dec 2012 22:30:09 +0000 Subject: [PATCH 29/62] error() function --- builtin.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/builtin.c b/builtin.c index b572dfaf..f046e91a 100644 --- a/builtin.c +++ b/builtin.c @@ -41,7 +41,6 @@ static jv type_error2(jv bad1, jv bad2, const char* msg) { return err; } - static jv f_plus(jv input, jv a, jv b) { jv_free(input); if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { @@ -297,6 +296,13 @@ static jv f_type(jv input) { return out; } +static jv f_error(jv input, jv msg) { + jv_free(input); + msg = f_tostring(msg); + return jv_invalid_with_msg(msg); +} + + static struct cfunction function_list[] = { {(cfunction_ptr)f_plus, "_plus", 3}, {(cfunction_ptr)f_minus, "_minus", 3}, @@ -322,6 +328,7 @@ static struct cfunction function_list[] = { {(cfunction_ptr)f_max, "max", 1}, {(cfunction_ptr)f_min_by_impl, "_min_by_impl", 2}, {(cfunction_ptr)f_max_by_impl, "_max_by_impl", 2}, + {(cfunction_ptr)f_error, "error", 2}, }; static struct symbol_table cbuiltins = From dcc93042d35135f0aa16fd6de953a1c5c76e0f1a Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 10 Dec 2012 22:35:33 +0000 Subject: [PATCH 30/62] some words explaining struct inst a little --- compile.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/compile.c b/compile.c index eb0fe78d..3a094721 100644 --- a/compile.c +++ b/compile.c @@ -6,6 +6,18 @@ #include "bytecode.h" #include "locfile.h" +/* + The intermediate representation for jq filters is as a sequence of + struct inst, which form a doubly-linked list via the next and prev + pointers. + + A "block" represents a sequence of "struct inst", which may be + empty. + + Blocks are generated by the parser bottom-up, so may have free + variables (refer to things not defined). See inst.bound_by and + inst.symbol. + */ struct inst { struct inst* next; struct inst* prev; @@ -22,18 +34,20 @@ struct inst { location source; // Binding - // An instruction requiring binding (for parameters/variables) + // An instruction requiring binding (for parameters/variables/functions) // is in one of three states: - // bound_by = NULL - Unbound free variable - // bound_by = self - This instruction binds a variable - // bound_by = other - Uses variable bound by other instruction - // The immediate field is generally not meaningful until instructions - // are bound, and even then only for instructions which bind. + // inst->bound_by = NULL - Unbound free variable + // inst->bound_by = inst - This instruction binds a variable + // inst->bound_by = other - Uses variable bound by other instruction + // Unbound instructions (references to other things that may or may not + // exist) are created by "gen_foo_unbound", and bindings are created by + // block_bind(definition, body), which binds all instructions in + // body which are unboudn and refer to "definition" by name. struct inst* bound_by; char* symbol; - block subfn; - block arglist; + block subfn; // used by CLOSURE_CREATE (body of function) + block arglist; // used by CLOSURE_CREATE (formals) and CALL_JQ (arguments) // This instruction is compiled as part of which function? // (only used during block_compile) From 8ba2cef91356257d8c8415df916480fdba4d17f6 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 10 Dec 2012 22:36:01 +0000 Subject: [PATCH 31/62] Delete autogenerated source from the repository. This was a horrible hack to fix build issues on OS X some time ago. There are better ways to fix build issues on OS X :) See #49. --- jv_utf8_tables.gen.h | 35 - lexer.gen.c | 2328 --------------------------- lexer.gen.h | 362 ----- parser.gen.c | 2855 --------------------------------- parser.gen.h | 132 -- parser.gen.info | 3565 ------------------------------------------ 6 files changed, 9277 deletions(-) delete mode 100644 jv_utf8_tables.gen.h delete mode 100644 lexer.gen.c delete mode 100644 lexer.gen.h delete mode 100644 parser.gen.c delete mode 100644 parser.gen.h delete mode 100644 parser.gen.info diff --git a/jv_utf8_tables.gen.h b/jv_utf8_tables.gen.h deleted file mode 100644 index 24d9a63a..00000000 --- a/jv_utf8_tables.gen.h +++ /dev/null @@ -1,35 +0,0 @@ -#define UTF8_CONTINUATION_BYTE ((unsigned char)255) -static const unsigned char utf8_coding_length[] = - {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static const unsigned char utf8_coding_bits[] = - {0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/lexer.gen.c b/lexer.gen.c deleted file mode 100644 index 250fc430..00000000 --- a/lexer.gen.c +++ /dev/null @@ -1,2328 +0,0 @@ -#line 2 "lexer.gen.c" - -#line 4 "lexer.gen.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE jq_yyrestart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via jq_yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void jq_yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void jq_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE jq_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void jq_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void jq_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void jq_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void jq_yypop_buffer_state (yyscan_t yyscanner ); - -static void jq_yyensure_buffer_stack (yyscan_t yyscanner ); -static void jq_yy_load_buffer_state (yyscan_t yyscanner ); -static void jq_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER jq_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE jq_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE jq_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *jq_yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *jq_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void jq_yyfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer jq_yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - jq_yyensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - jq_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - jq_yyensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - jq_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define jq_yywrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 36 -#define YY_END_OF_BUFFER 37 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[96] = - { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 37, 35, 34, 34, 35, 27, 1, 23, - 24, 25, 23, 23, 23, 23, 23, 26, 23, 23, - 23, 33, 33, 33, 33, 33, 33, 33, 33, 23, - 31, 31, 29, 32, 34, 2, 1, 17, 15, 26, - 16, 0, 13, 18, 20, 3, 21, 33, 33, 4, - 33, 33, 33, 33, 6, 11, 33, 14, 31, 30, - 28, 30, 0, 26, 19, 10, 33, 5, 33, 33, - 12, 33, 0, 30, 33, 9, 8, 7, 30, 33, - 30, 33, 33, 22, 0 - - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 6, 7, 8, 1, 1, 1, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 18, 19, 20, - 21, 22, 1, 1, 23, 23, 23, 23, 24, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 25, 26, 27, 1, 28, 1, 29, 23, 30, 31, - - 32, 33, 23, 34, 35, 23, 23, 36, 23, 37, - 38, 23, 23, 39, 40, 41, 42, 23, 23, 23, - 23, 23, 43, 44, 45, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[46] = - { 0, - 1, 1, 2, 2, 1, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, - 1, 1, 4, 4, 1, 5, 1, 6, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 1, 1, 1 - } ; - -static yyconst flex_int16_t yy_base[105] = - { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 43, 44, 152, 153, 49, 51, 130, 153, 0, 153, - 153, 153, 129, 128, 40, 41, 43, 51, 127, 126, - 125, 0, 23, 107, 112, 35, 110, 88, 91, 100, - 0, 0, 153, 39, 74, 153, 0, 153, 153, 63, - 153, 72, 94, 153, 153, 153, 153, 0, 75, 0, - 68, 71, 27, 72, 0, 0, 70, 153, 0, 75, - 153, 74, 82, 81, 153, 0, 56, 0, 63, 62, - 0, 56, 65, 66, 62, 0, 0, 0, 64, 53, - 59, 45, 39, 0, 153, 107, 113, 116, 122, 128, - - 131, 133, 135, 137 - } ; - -static yyconst flex_int16_t yy_def[105] = - { 0, - 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 96, 96, 95, 95, 95, 95, 95, 95, 97, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 98, 98, 98, 98, 98, 98, 98, 98, 95, - 99, 99, 95, 100, 95, 95, 97, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 95, 99, 95, - 95, 101, 95, 95, 95, 98, 98, 98, 98, 98, - 98, 98, 100, 102, 98, 98, 98, 98, 103, 98, - 104, 98, 98, 98, 0, 95, 95, 95, 95, 95, - - 95, 95, 95, 95 - } ; - -static yyconst flex_int16_t yy_nxt[199] = - { 0, - 14, 15, 16, 14, 17, 18, 19, 20, 21, 22, - 23, 24, 20, 25, 26, 27, 28, 20, 20, 29, - 30, 31, 32, 32, 21, 14, 22, 32, 33, 34, - 35, 36, 32, 32, 37, 32, 32, 38, 32, 32, - 39, 32, 21, 40, 22, 42, 42, 71, 43, 43, - 45, 45, 45, 45, 50, 50, 50, 50, 53, 59, - 51, 79, 60, 54, 52, 50, 80, 50, 44, 44, - 63, 64, 52, 95, 52, 45, 45, 50, 94, 50, - 72, 93, 52, 73, 83, 73, 52, 92, 74, 83, - 90, 83, 88, 87, 52, 86, 85, 74, 74, 83, - - 83, 82, 81, 78, 77, 76, 72, 41, 41, 41, - 41, 41, 41, 47, 75, 47, 47, 47, 47, 58, - 68, 58, 69, 69, 67, 69, 66, 69, 70, 70, - 70, 70, 70, 70, 84, 84, 89, 89, 91, 91, - 70, 70, 65, 62, 61, 57, 56, 55, 49, 48, - 46, 95, 13, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95 - - } ; - -static yyconst flex_int16_t yy_chk[199] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 11, 12, 44, 11, 12, - 15, 15, 16, 16, 25, 26, 25, 26, 27, 33, - 25, 63, 33, 27, 26, 28, 63, 28, 11, 12, - 36, 36, 26, 83, 28, 45, 45, 50, 93, 50, - 44, 92, 28, 52, 91, 52, 50, 90, 52, 89, - 85, 84, 82, 80, 50, 79, 77, 74, 73, 72, - - 70, 67, 64, 62, 61, 59, 83, 96, 96, 96, - 96, 96, 96, 97, 53, 97, 97, 97, 97, 98, - 40, 98, 99, 99, 39, 99, 38, 99, 100, 100, - 100, 100, 100, 100, 101, 101, 102, 102, 103, 103, - 104, 104, 37, 35, 34, 31, 30, 29, 24, 23, - 17, 13, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95 - - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "lexer.l" -#line 2 "lexer.l" -#include "compile.h" - -struct lexer_param; - -#include "parser.gen.h" /* Generated by bison. */ - -#define YY_USER_ACTION \ - do { \ - yylloc->start = jq_yyget_extra(yyscanner); \ - yylloc->end = yylloc->start + yyleng; \ - jq_yyset_extra(yylloc->end,yyscanner); \ - } while (0); - - - - - - -#line 23 "lexer.l" - static int enter(int opening, int state, yyscan_t yyscanner); - static int try_exit(int closing, int state, yyscan_t yyscanner); -#define YY_NO_INPUT 1 -#line 542 "lexer.gen.c" - -#define INITIAL 0 -#define IN_PAREN 1 -#define IN_BRACKET 2 -#define IN_BRACE 3 -#define IN_QQINTERP 4 -#define IN_QQSTRING 5 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#define YY_EXTRA_TYPE int - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int jq_yylex_init (yyscan_t* scanner); - -int jq_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int jq_yylex_destroy (yyscan_t yyscanner ); - -int jq_yyget_debug (yyscan_t yyscanner ); - -void jq_yyset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE jq_yyget_extra (yyscan_t yyscanner ); - -void jq_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *jq_yyget_in (yyscan_t yyscanner ); - -void jq_yyset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *jq_yyget_out (yyscan_t yyscanner ); - -void jq_yyset_out (FILE * out_str ,yyscan_t yyscanner ); - -int jq_yyget_leng (yyscan_t yyscanner ); - -char *jq_yyget_text (yyscan_t yyscanner ); - -int jq_yyget_lineno (yyscan_t yyscanner ); - -void jq_yyset_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * jq_yyget_lval (yyscan_t yyscanner ); - -void jq_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *jq_yyget_lloc (yyscan_t yyscanner ); - - void jq_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int jq_yywrap (yyscan_t yyscanner ); -#else -extern int jq_yywrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - - static void yy_push_state (int new_state ,yyscan_t yyscanner); - - static void yy_pop_state (yyscan_t yyscanner ); - - static int yy_top_state (yyscan_t yyscanner ); - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int jq_yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int jq_yylex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 35 "lexer.l" - - -#line 798 "lexer.gen.c" - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - jq_yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - jq_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - jq_yy_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 96 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 153 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 37 "lexer.l" -{ /* comments */ } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 39 "lexer.l" -{ return NEQ; } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 40 "lexer.l" -{ return EQ; } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 41 "lexer.l" -{ return AS; } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 42 "lexer.l" -{ return DEF; } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 43 "lexer.l" -{ return IF; } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 44 "lexer.l" -{ return THEN; } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 45 "lexer.l" -{ return ELSE; } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 46 "lexer.l" -{ return ELSE_IF; } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 47 "lexer.l" -{ return AND; } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 48 "lexer.l" -{ return OR; } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 49 "lexer.l" -{ return END; } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 50 "lexer.l" -{ return DEFINEDOR; } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 51 "lexer.l" -{ return SETPIPE; } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 52 "lexer.l" -{ return SETPLUS; } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 53 "lexer.l" -{ return SETMINUS; } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 54 "lexer.l" -{ return SETMULT; } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 55 "lexer.l" -{ return SETDIV; } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 56 "lexer.l" -{ return SETDEFINEDOR; } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 57 "lexer.l" -{ return LESSEQ; } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 58 "lexer.l" -{ return GREATEREQ; } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 59 "lexer.l" -{ return CONTAINS; } - YY_BREAK -case 23: -YY_RULE_SETUP -#line 60 "lexer.l" -{ return yytext[0];} - YY_BREAK -case 24: -YY_RULE_SETUP -#line 62 "lexer.l" -{ - return enter(yytext[0], YY_START, yyscanner); -} - YY_BREAK -case 25: -YY_RULE_SETUP -#line 66 "lexer.l" -{ - return try_exit(yytext[0], YY_START, yyscanner); -} - YY_BREAK -case 26: -YY_RULE_SETUP -#line 71 "lexer.l" -{ - yylval->literal = jv_parse_sized(yytext, yyleng); return LITERAL; -} - YY_BREAK -case 27: -YY_RULE_SETUP -#line 75 "lexer.l" -{ - yy_push_state(IN_QQSTRING, yyscanner); - return QQSTRING_START; -} - YY_BREAK - -case 28: -YY_RULE_SETUP -#line 81 "lexer.l" -{ - return enter(QQSTRING_INTERP_START, YY_START, yyscanner); - } - YY_BREAK -case 29: -YY_RULE_SETUP -#line 84 "lexer.l" -{ - yy_pop_state(yyscanner); - return QQSTRING_END; - } - YY_BREAK -case 30: -/* rule 30 can match eol */ -YY_RULE_SETUP -#line 88 "lexer.l" -{ - /* pass escapes to the json parser */ - jv escapes = jv_string_fmt("\"%.*s\"", yyleng, yytext); - yylval->literal = jv_parse_sized(jv_string_value(escapes), jv_string_length(jv_copy(escapes))); - jv_free(escapes); - return QQSTRING_TEXT; - } - YY_BREAK -case 31: -/* rule 31 can match eol */ -YY_RULE_SETUP -#line 95 "lexer.l" -{ - yylval->literal = jv_string_sized(yytext, yyleng); - return QQSTRING_TEXT; - } - YY_BREAK -case 32: -YY_RULE_SETUP -#line 99 "lexer.l" -{ - return INVALID_CHARACTER; - } - YY_BREAK - -case 33: -YY_RULE_SETUP -#line 105 "lexer.l" -{ yylval->literal = jv_string(yytext); return IDENT;} - YY_BREAK -case 34: -/* rule 34 can match eol */ -YY_RULE_SETUP -#line 107 "lexer.l" -{} - YY_BREAK -case 35: -YY_RULE_SETUP -#line 109 "lexer.l" -{ return INVALID_CHARACTER; } - YY_BREAK -case 36: -YY_RULE_SETUP -#line 111 "lexer.l" -YY_FATAL_ERROR( "flex scanner jammed" ); - YY_BREAK -#line 1095 "lexer.gen.c" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(IN_PAREN): -case YY_STATE_EOF(IN_BRACKET): -case YY_STATE_EOF(IN_BRACE): -case YY_STATE_EOF(IN_QQINTERP): -case YY_STATE_EOF(IN_QQSTRING): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * jq_yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( jq_yywrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of jq_yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - jq_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - jq_yyrestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) jq_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 96 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 96 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 95); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - jq_yyrestart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( jq_yywrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void jq_yyrestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - jq_yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - jq_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - jq_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - jq_yy_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void jq_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * jq_yypop_buffer_state(); - * jq_yypush_buffer_state(new_buffer); - */ - jq_yyensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - jq_yy_load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (jq_yywrap()) processing, but the only time this flag - * is looked at is after jq_yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void jq_yy_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE jq_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) jq_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in jq_yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) jq_yyalloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in jq_yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - jq_yy_init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with jq_yy_create_buffer() - * @param yyscanner The scanner object. - */ - void jq_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - jq_yyfree((void *) b->yy_ch_buf ,yyscanner ); - - jq_yyfree((void *) b ,yyscanner ); -} - -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a jq_yyrestart() or at EOF. - */ - static void jq_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - jq_yy_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then jq_yy_init_buffer was _probably_ - * called from jq_yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void jq_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - jq_yy_load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void jq_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - jq_yyensure_buffer_stack(yyscanner); - - /* This block is copied from jq_yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from jq_yy_switch_to_buffer. */ - jq_yy_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void jq_yypop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - jq_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - jq_yy_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void jq_yyensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)jq_yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in jq_yyensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)jq_yyrealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in jq_yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE jq_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) jq_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in jq_yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - jq_yy_switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to jq_yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * jq_yy_scan_bytes() instead. - */ -YY_BUFFER_STATE jq_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return jq_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to jq_yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) jq_yyalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in jq_yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = jq_yy_scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in jq_yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - - static void yy_push_state (int new_state , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth ) - { - yy_size_t new_size; - - yyg->yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yyg->yy_start_stack_depth * sizeof( int ); - - if ( ! yyg->yy_start_stack ) - yyg->yy_start_stack = (int *) jq_yyalloc(new_size ,yyscanner ); - - else - yyg->yy_start_stack = (int *) jq_yyrealloc((void *) yyg->yy_start_stack,new_size ,yyscanner ); - - if ( ! yyg->yy_start_stack ) - YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); - } - - yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); -} - - static void yy_pop_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( --yyg->yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]); -} - - static int yy_top_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1]; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE jq_yyget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int jq_yyget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int jq_yyget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *jq_yyget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *jq_yyget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int jq_yyget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *jq_yyget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void jq_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void jq_yyset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "jq_yyset_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void jq_yyset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "jq_yyset_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see jq_yy_switch_to_buffer - */ -void jq_yyset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void jq_yyset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int jq_yyget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void jq_yyset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * jq_yyget_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void jq_yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *jq_yyget_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void jq_yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* jq_yylex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int jq_yylex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) jq_yyalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* jq_yylex_init_extra has the same functionality as jq_yylex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to jq_yyalloc in - * the yyextra field. - */ - -int jq_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - jq_yyset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) jq_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - jq_yyset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from jq_yylex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * jq_yylex_init() - */ - return 0; -} - -/* jq_yylex_destroy is for both reentrant and non-reentrant scanners. */ -int jq_yylex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - jq_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - jq_yypop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - jq_yyfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - jq_yyfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * jq_yylex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - jq_yyfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *jq_yyalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *jq_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void jq_yyfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see jq_yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 111 "lexer.l" - - -/* perhaps these should be calls... */ -/* -"true" { return TRUE; } -"false" { return FALSE; } -"null" { return NULL; } -*/ -static int try_exit(int c, int state, yyscan_t yyscanner) { - char match = 0; - int ret; - switch (state) { - case IN_PAREN: match = ret = ')'; break; - case IN_BRACKET: match = ret = ']'; break; - case IN_BRACE: match = ret = '}'; break; - - case IN_QQINTERP: - match = ')'; - ret = QQSTRING_INTERP_END; - break; - - default: - // may not be the best error to give - return INVALID_CHARACTER; - } - assert(match); - if (match == c) { - yy_pop_state(yyscanner); - return ret; - } else { - // FIXME: should we pop? Give a better error at least - return INVALID_CHARACTER; - } -} - -static int enter(int c, int currstate, yyscan_t yyscanner) { - int state = 0; - switch (c) { - case '(': state = IN_PAREN; break; - case '[': state = IN_BRACKET; break; - case '{': state = IN_BRACE; break; - case QQSTRING_INTERP_START: state = IN_QQINTERP; break; - } - assert(state); - yy_push_state(state, yyscanner); - return c; -} - diff --git a/lexer.gen.h b/lexer.gen.h deleted file mode 100644 index 9249586d..00000000 --- a/lexer.gen.h +++ /dev/null @@ -1,362 +0,0 @@ -#ifndef jq_yyHEADER_H -#define jq_yyHEADER_H 1 -#define jq_yyIN_HEADER 1 - -#line 6 "lexer.gen.h" - -#line 8 "lexer.gen.h" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -void jq_yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void jq_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE jq_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void jq_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void jq_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void jq_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void jq_yypop_buffer_state (yyscan_t yyscanner ); - -YY_BUFFER_STATE jq_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE jq_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *jq_yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *jq_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void jq_yyfree (void * ,yyscan_t yyscanner ); - -/* Begin user sect3 */ - -#define jq_yywrap(n) 1 -#define YY_SKIP_YYWRAP - -#define yytext_ptr yytext_r - -#ifdef YY_HEADER_EXPORT_START_CONDITIONS -#define INITIAL 0 -#define IN_PAREN 1 -#define IN_BRACKET 2 -#define IN_BRACE 3 -#define IN_QQINTERP 4 -#define IN_QQSTRING 5 - -#endif - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#define YY_EXTRA_TYPE int - -int jq_yylex_init (yyscan_t* scanner); - -int jq_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int jq_yylex_destroy (yyscan_t yyscanner ); - -int jq_yyget_debug (yyscan_t yyscanner ); - -void jq_yyset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE jq_yyget_extra (yyscan_t yyscanner ); - -void jq_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *jq_yyget_in (yyscan_t yyscanner ); - -void jq_yyset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *jq_yyget_out (yyscan_t yyscanner ); - -void jq_yyset_out (FILE * out_str ,yyscan_t yyscanner ); - -int jq_yyget_leng (yyscan_t yyscanner ); - -char *jq_yyget_text (yyscan_t yyscanner ); - -int jq_yyget_lineno (yyscan_t yyscanner ); - -void jq_yyset_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * jq_yyget_lval (yyscan_t yyscanner ); - -void jq_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *jq_yyget_lloc (yyscan_t yyscanner ); - - void jq_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int jq_yywrap (yyscan_t yyscanner ); -#else -extern int jq_yywrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int jq_yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int jq_yylex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - -#line 111 "lexer.l" - - -#line 361 "lexer.gen.h" -#undef jq_yyIN_HEADER -#endif /* jq_yyHEADER_H */ diff --git a/parser.gen.c b/parser.gen.c deleted file mode 100644 index 0fb39b3c..00000000 --- a/parser.gen.c +++ /dev/null @@ -1,2855 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.5. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.5" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 1 - - - -/* Copy the first part of user declarations. */ - -/* Line 268 of yacc.c */ -#line 1 "parser.y" - -#include -#include -#include "compile.h" - -struct lexer_param; - - - -/* Line 268 of yacc.c */ -#line 81 "parser.gen.c" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -/* "%code requires" blocks. */ - -/* Line 288 of yacc.c */ -#line 9 "parser.y" - -#include "locfile.h" -#define YYLTYPE location -#define YYLLOC_DEFAULT(Loc, Rhs, N) \ - do { \ - if (N) { \ - (Loc).start = YYRHSLOC(Rhs, 1).start; \ - (Loc).end = YYRHSLOC(Rhs, N).end; \ - } else { \ - (Loc).start = YYRHSLOC(Rhs, 0).end; \ - (Loc).end = YYRHSLOC(Rhs, 0).end; \ - } \ - } while (0) - - - -/* Line 288 of yacc.c */ -#line 122 "parser.gen.c" - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - INVALID_CHARACTER = 258, - IDENT = 259, - LITERAL = 260, - EQ = 261, - NEQ = 262, - DEFINEDOR = 263, - AS = 264, - DEF = 265, - IF = 266, - THEN = 267, - ELSE = 268, - ELSE_IF = 269, - END = 270, - AND = 271, - OR = 272, - SETPIPE = 273, - SETPLUS = 274, - SETMINUS = 275, - SETMULT = 276, - SETDIV = 277, - SETDEFINEDOR = 278, - LESSEQ = 279, - GREATEREQ = 280, - CONTAINS = 281, - QQSTRING_START = 282, - QQSTRING_TEXT = 283, - QQSTRING_INTERP_START = 284, - QQSTRING_INTERP_END = 285, - QQSTRING_END = 286 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 293 of yacc.c */ -#line 27 "parser.y" - - jv literal; - block blk; - - - -/* Line 293 of yacc.c */ -#line 177 "parser.gen.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -/* Copy the second part of user declarations. */ - -/* Line 343 of yacc.c */ -#line 90 "parser.y" - -#include "lexer.gen.h" -struct lexer_param { - yyscan_t lexer; -}; -#define FAIL(loc, msg) \ - do { \ - location l = loc; \ - yyerror(&l, answer, errors, locations, lexer_param_ptr, msg); \ - /*YYERROR*/; \ - } while (0) - -void yyerror(YYLTYPE* loc, block* answer, int* errors, - struct locfile* locations, struct lexer_param* lexer_param_ptr, const char *s){ - (*errors)++; - locfile_locate(locations, *loc, "error: %s", s); -} - -int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors, - struct locfile* locations, struct lexer_param* lexer_param_ptr) { - yyscan_t lexer = lexer_param_ptr->lexer; - while (1) { - int tok = jq_yylex(yylval, yylloc, lexer); - if (tok == INVALID_CHARACTER) { - FAIL(*yylloc, "Invalid character"); - } else { - if ((tok == LITERAL || tok == QQSTRING_TEXT) && !jv_is_valid(yylval->literal)) { - jv msg = jv_invalid_get_msg(jv_copy(yylval->literal)); - if (jv_get_kind(msg) == JV_KIND_STRING) { - FAIL(*yylloc, jv_string_value(msg)); - } else { - FAIL(*yylloc, "Invalid literal"); - } - jv_free(msg); - jv_free(yylval->literal); - yylval->literal = jv_null(); - } - return tok; - } - } -} - -static block gen_dictpair(block k, block v) { - return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT)); -} - -static block gen_index(block obj, block key) { - return BLOCK(obj, gen_subexp(key), gen_op_simple(INDEX)); -} - -static block gen_binop(block a, block b, int op) { - const char* funcname = 0; - switch (op) { - case '+': funcname = "_plus"; break; - case '-': funcname = "_minus"; break; - case '*': funcname = "_multiply"; break; - case '/': funcname = "_divide"; break; - case EQ: funcname = "_equal"; break; - case NEQ: funcname = "_notequal"; break; - case '<': funcname = "_less"; break; - case '>': funcname = "_greater"; break; - case LESSEQ: funcname = "_lesseq"; break; - case GREATEREQ: funcname = "_greatereq"; break; - case CONTAINS: funcname = "_contains"; break; - } - assert(funcname); - - return gen_call(funcname, BLOCK(gen_lambda(a), gen_lambda(b))); -} - -static block gen_format(block a) { - return BLOCK(a, gen_call("tostring", gen_noop())); -} - -static block gen_update(block a, block op, int optype) { - if (optype) { - op = gen_binop(gen_noop(), op, optype); - } - return gen_assign(BLOCK(a, gen_op_simple(DUP), op)); -} - - - -/* Line 343 of yacc.c */ -#line 286 "parser.gen.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 35 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 854 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 51 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 12 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 70 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 151 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 286 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 42, 2, 2, 2, - 44, 45, 40, 38, 34, 39, 46, 41, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 43, 32, - 36, 35, 37, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 47, 2, 48, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 49, 33, 50, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 5, 7, 8, 11, 14, 21, 27, - 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, - 71, 75, 79, 83, 87, 91, 95, 99, 103, 107, - 111, 115, 119, 123, 125, 129, 135, 144, 145, 148, - 153, 159, 163, 167, 169, 171, 175, 178, 183, 187, - 189, 191, 195, 199, 202, 206, 209, 211, 216, 220, - 224, 229, 233, 234, 236, 240, 244, 248, 252, 254, - 260 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 52, 0, -1, 54, -1, 53, -1, -1, 56, 53, - -1, 56, 54, -1, 60, 9, 42, 4, 33, 54, - -1, 11, 54, 12, 54, 58, -1, 11, 54, 1, - -1, 54, 35, 54, -1, 54, 17, 54, -1, 54, - 16, 54, -1, 54, 8, 54, -1, 54, 23, 54, - -1, 54, 18, 54, -1, 54, 33, 54, -1, 54, - 34, 54, -1, 54, 38, 54, -1, 54, 19, 54, - -1, 54, 39, 54, -1, 54, 20, 54, -1, 54, - 40, 54, -1, 54, 21, 54, -1, 54, 41, 54, - -1, 54, 22, 54, -1, 54, 6, 54, -1, 54, - 7, 54, -1, 54, 36, 54, -1, 54, 37, 54, - -1, 54, 24, 54, -1, 54, 25, 54, -1, 54, - 26, 54, -1, 60, -1, 27, 57, 31, -1, 10, - 4, 43, 54, 32, -1, 10, 4, 44, 4, 45, - 43, 54, 32, -1, -1, 57, 28, -1, 57, 29, - 54, 30, -1, 14, 54, 12, 54, 58, -1, 13, - 54, 15, -1, 59, 33, 59, -1, 60, -1, 46, - -1, 60, 46, 4, -1, 46, 4, -1, 60, 47, - 54, 48, -1, 60, 47, 48, -1, 5, -1, 55, - -1, 44, 54, 45, -1, 47, 54, 48, -1, 47, - 48, -1, 49, 61, 50, -1, 42, 4, -1, 4, - -1, 4, 44, 54, 45, -1, 44, 1, 45, -1, - 47, 1, 48, -1, 60, 47, 1, 48, -1, 49, - 1, 50, -1, -1, 62, -1, 62, 34, 61, -1, - 1, 34, 61, -1, 4, 43, 59, -1, 55, 43, - 59, -1, 4, -1, 44, 54, 45, 43, 59, -1, - 44, 1, 45, 43, 59, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 175, 175, 178, 183, 186, 191, 195, 202, 205, - 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, - 250, 254, 258, 262, 266, 270, 274, 278, 282, 286, - 290, 294, 298, 302, 307, 312, 317, 325, 328, 331, - 337, 340, 345, 349, 355, 358, 361, 365, 368, 371, - 374, 377, 380, 383, 386, 389, 393, 397, 402, 403, - 404, 405, 408, 411, 412, 413, 416, 419, 422, 426, - 429 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "INVALID_CHARACTER", "IDENT", "LITERAL", - "\"==\"", "\"!=\"", "\"//\"", "\"as\"", "\"def\"", "\"if\"", "\"then\"", - "\"else\"", "\"elif\"", "\"end\"", "\"and\"", "\"or\"", "\"|=\"", - "\"+=\"", "\"-=\"", "\"*=\"", "\"/=\"", "\"//=\"", "\"<=\"", "\">=\"", - "\"contains\"", "QQSTRING_START", "QQSTRING_TEXT", - "QQSTRING_INTERP_START", "QQSTRING_INTERP_END", "QQSTRING_END", "';'", - "'|'", "','", "'='", "'<'", "'>'", "'+'", "'-'", "'*'", "'/'", "'$'", - "':'", "'('", "')'", "'.'", "'['", "']'", "'{'", "'}'", "$accept", - "TopLevel", "FuncDefs", "Exp", "String", "FuncDef", "QQString", - "ElseBody", "ExpD", "Term", "MkDict", "MkDictPair", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 59, 124, 44, 61, 60, 62, 43, 45, - 42, 47, 36, 58, 40, 41, 46, 91, 93, 123, - 125 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 51, 52, 52, 53, 53, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 55, 56, 56, 57, 57, 57, - 58, 58, 59, 59, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, - 62 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 0, 2, 2, 6, 5, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 1, 3, 5, 8, 0, 2, 4, - 5, 3, 3, 1, 1, 3, 2, 4, 3, 1, - 1, 3, 3, 2, 3, 2, 1, 4, 3, 3, - 4, 3, 0, 1, 3, 3, 3, 3, 1, 5, - 5 -}; - -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 4, 56, 49, 0, 0, 37, 0, 0, 44, 0, - 0, 0, 3, 2, 50, 4, 33, 0, 0, 0, - 0, 0, 55, 0, 0, 46, 0, 53, 0, 0, - 68, 0, 0, 0, 63, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 6, 0, 0, 0, 0, 0, 0, 9, 0, 38, - 0, 34, 58, 51, 59, 52, 0, 61, 0, 0, - 0, 0, 54, 0, 26, 27, 13, 12, 11, 15, - 19, 21, 23, 25, 14, 30, 31, 32, 16, 17, - 10, 28, 29, 18, 20, 22, 24, 0, 45, 0, - 48, 0, 57, 0, 0, 0, 0, 0, 65, 66, - 43, 0, 0, 67, 64, 0, 60, 47, 35, 0, - 0, 0, 8, 39, 0, 0, 0, 0, 0, 0, - 0, 42, 70, 69, 7, 0, 41, 0, 36, 0, - 40 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 11, 12, 60, 14, 20, 21, 132, 119, 16, - 33, 34 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -76 -static const yytype_int16 yypact[] = -{ - 179, -42, -76, 10, 179, -76, 16, 131, 18, 79, - 65, 28, -76, 662, -76, 179, 53, 179, -28, 302, - 179, -18, -76, -15, 338, -76, -19, -76, 223, -29, - -11, 155, -10, 14, 1, -76, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, -76, - 662, -8, 72, 106, 374, 179, 73, -76, 179, -76, - 179, -76, -76, -76, -76, -76, 74, -76, 165, 34, - 410, 165, -76, 74, 807, 807, 734, 813, 786, 760, - 760, 760, 760, 760, 760, 807, 807, 807, 698, 734, - 760, 807, 807, -16, -16, -76, -76, 77, -76, 37, - -76, 259, -76, 482, 41, 446, 518, 48, -76, 54, - -20, 45, 50, 54, -76, 58, -76, -76, -76, 51, - 179, 179, -76, -76, 165, 165, 165, 179, 179, 554, - 590, -76, 54, 54, 698, 626, -76, 179, -76, 446, - -76 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -76, -76, 80, 0, -9, 8, -76, -53, -63, -75, - -64, -76 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -63 -static const yytype_int16 yytable[] = -{ - 13, 32, 17, 120, 19, 76, 120, 24, 15, 28, - 69, 70, 118, 71, 18, 65, 66, 64, 123, 124, - 22, 77, 25, 15, 57, 58, 62, 63, 35, 74, - 72, 80, 78, 81, 107, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 120, - 120, 120, 61, 111, 82, 113, 29, 32, 115, 30, - 116, 141, 142, 143, 32, 117, 108, 114, 30, 121, - 26, 125, 76, 1, 2, 126, 129, 134, 135, 3, - 4, 137, 5, 136, 138, 59, 150, 0, 0, 62, - 63, 5, 0, 0, 0, 0, 5, 109, 0, 31, - 1, 2, 0, 0, 0, -62, 3, 4, 31, 0, - 0, 6, 0, 7, -62, 8, 9, 27, 10, 0, - 139, 140, 23, 5, 0, 1, 2, 144, 145, 0, - 0, 3, 4, 0, 0, 0, 0, 149, 6, 0, - 7, 0, 8, 9, 110, 10, 79, 0, 5, 1, - 2, 0, 0, 0, 0, 3, 4, 0, 0, 1, - 2, 0, 0, 6, 0, 7, 0, 8, 9, 0, - 10, 0, 5, 1, 2, 0, 0, 0, 0, 3, - 4, 0, 5, 0, 0, 0, 0, 6, 0, 7, - 0, 8, 9, 0, 10, 0, 5, 6, 0, 7, - 0, 8, 9, 0, 10, 0, 0, 0, 0, 0, - 0, 6, 0, 7, 0, 8, 9, 0, 10, 36, - 37, 38, 0, 0, 0, 0, 0, 0, 0, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 0, 0, 0, 0, 0, 0, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 36, 37, 38, 0, 0, - 0, 75, 0, 0, 0, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, - 0, 0, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 0, 0, 67, 0, 0, 0, 127, 36, 37, - 38, 0, 0, 0, 68, 0, 0, 0, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, - 0, 0, 0, 0, 0, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 36, 37, 38, 0, 0, 0, - 0, 0, 0, 0, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, - 0, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 36, 37, 38, 73, 0, 0, 0, 0, 0, 0, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 0, 0, 0, 0, 0, 0, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 36, 37, 38, 112, - 0, 0, 0, 0, 0, 0, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, - 0, 0, 0, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 36, 37, 38, 122, 0, 0, 0, 130, - 131, 0, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 0, 0, 0, 0, 0, 0, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 36, 37, - 38, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, - 0, 0, 0, 0, 128, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 36, 37, 38, 0, 0, 0, - 0, 0, 0, 0, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 0, 0, 0, 133, 0, - 0, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 36, 37, 38, 0, 0, 0, 0, 0, 0, 146, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 0, 0, 0, 0, 0, 0, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 36, 37, 38, 0, - 0, 0, 147, 0, 0, 0, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, - 0, 0, 0, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 36, 37, 38, 0, 0, 0, 0, 0, - 0, 0, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 0, 0, 0, 0, 0, 148, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 36, 37, - 38, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, - 0, 0, 0, 0, 0, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 36, 37, 38, 0, 0, 0, - 0, 0, 0, 0, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, - 0, 0, 51, 52, 53, 54, 55, 56, 57, 58, - 36, 37, 38, 0, 0, 0, 0, 0, 0, 0, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 0, 0, 0, 0, 0, 36, 37, 0, 52, - 53, 54, 55, 56, 57, 58, 39, 40, -63, -63, - -63, -63, -63, -63, 47, 48, 49, 0, 0, 0, - 0, 0, 36, 37, 0, -63, 53, 54, 55, 56, - 57, 58, 39, 0, 0, 0, 0, 0, 0, 0, - 47, 48, 49, -63, -63, 0, 0, 0, 0, 36, - 37, 0, 53, 54, 55, 56, 57, 58, 0, 0, - 0, -63, -63, -63, 0, 0, 0, 47, 48, 49, - 0, 0, 0, -63, -63, 55, 56, 57, 58, 53, - 54, 55, 56, 57, 58 -}; - -#define yypact_value_is_default(yystate) \ - ((yystate) == (-76)) - -#define yytable_value_is_error(yytable_value) \ - ((yytable_value) == (-63)) - -static const yytype_int16 yycheck[] = -{ - 0, 10, 44, 78, 4, 34, 81, 7, 0, 9, - 28, 29, 76, 31, 4, 43, 44, 17, 81, 83, - 4, 50, 4, 15, 40, 41, 46, 47, 0, 48, - 45, 31, 43, 43, 42, 34, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 134, - 135, 136, 9, 63, 50, 65, 1, 76, 68, 4, - 70, 134, 135, 136, 83, 1, 4, 4, 4, 45, - 1, 4, 34, 4, 5, 48, 45, 33, 43, 10, - 11, 33, 27, 43, 43, 15, 149, -1, -1, 46, - 47, 27, -1, -1, -1, -1, 27, 1, -1, 44, - 4, 5, -1, -1, -1, 50, 10, 11, 44, -1, - -1, 42, -1, 44, 50, 46, 47, 48, 49, -1, - 130, 131, 1, 27, -1, 4, 5, 137, 138, -1, - -1, 10, 11, -1, -1, -1, -1, 147, 42, -1, - 44, -1, 46, 47, 48, 49, 1, -1, 27, 4, - 5, -1, -1, -1, -1, 10, 11, -1, -1, 4, - 5, -1, -1, 42, -1, 44, -1, 46, 47, -1, - 49, -1, 27, 4, 5, -1, -1, -1, -1, 10, - 11, -1, 27, -1, -1, -1, -1, 42, -1, 44, - -1, 46, 47, -1, 49, -1, 27, 42, -1, 44, - -1, 46, 47, -1, 49, -1, -1, -1, -1, -1, - -1, 42, -1, 44, -1, 46, 47, -1, 49, 6, - 7, 8, -1, -1, -1, -1, -1, -1, -1, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - -1, -1, -1, -1, -1, -1, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 6, 7, 8, -1, -1, - -1, 48, -1, -1, -1, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, -1, -1, -1, -1, - -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, - 41, -1, -1, 1, -1, -1, -1, 48, 6, 7, - 8, -1, -1, -1, 12, -1, -1, -1, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, -1, - -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 6, 7, 8, -1, -1, -1, - -1, -1, -1, -1, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, -1, -1, -1, -1, -1, - -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 6, 7, 8, 45, -1, -1, -1, -1, -1, -1, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, -1, -1, -1, -1, -1, -1, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 6, 7, 8, 45, - -1, -1, -1, -1, -1, -1, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 6, 7, 8, 45, -1, -1, -1, 13, - 14, -1, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, -1, -1, -1, -1, -1, -1, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 6, 7, - 8, -1, -1, -1, -1, -1, -1, -1, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, -1, - -1, -1, -1, -1, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 6, 7, 8, -1, -1, -1, - -1, -1, -1, -1, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, -1, -1, -1, 30, -1, - -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 6, 7, 8, -1, -1, -1, -1, -1, -1, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, -1, -1, -1, -1, -1, -1, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 6, 7, 8, -1, - -1, -1, 12, -1, -1, -1, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 6, 7, 8, -1, -1, -1, -1, -1, - -1, -1, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, -1, -1, -1, -1, -1, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 6, 7, - 8, -1, -1, -1, -1, -1, -1, -1, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, -1, - -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 6, 7, 8, -1, -1, -1, - -1, -1, -1, -1, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, -1, -1, -1, -1, -1, - -1, -1, 34, 35, 36, 37, 38, 39, 40, 41, - 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, -1, -1, -1, -1, -1, 6, 7, -1, 35, - 36, 37, 38, 39, 40, 41, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, -1, -1, -1, - -1, -1, 6, 7, -1, 35, 36, 37, 38, 39, - 40, 41, 16, -1, -1, -1, -1, -1, -1, -1, - 24, 25, 26, 6, 7, -1, -1, -1, -1, 6, - 7, -1, 36, 37, 38, 39, 40, 41, -1, -1, - -1, 24, 25, 26, -1, -1, -1, 24, 25, 26, - -1, -1, -1, 36, 37, 38, 39, 40, 41, 36, - 37, 38, 39, 40, 41 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 4, 5, 10, 11, 27, 42, 44, 46, 47, - 49, 52, 53, 54, 55, 56, 60, 44, 4, 54, - 56, 57, 4, 1, 54, 4, 1, 48, 54, 1, - 4, 44, 55, 61, 62, 0, 6, 7, 8, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 53, - 54, 9, 46, 47, 54, 43, 44, 1, 12, 28, - 29, 31, 45, 45, 48, 48, 34, 50, 43, 1, - 54, 43, 50, 34, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 42, 4, 1, - 48, 54, 45, 54, 4, 54, 54, 1, 61, 59, - 60, 45, 45, 59, 61, 4, 48, 48, 32, 45, - 13, 14, 58, 30, 33, 43, 43, 33, 43, 54, - 54, 59, 59, 59, 54, 54, 15, 12, 32, 54, - 58 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, answer, errors, locations, lexer_param_ptr, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc, answer, errors, locations, lexer_param_ptr) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, answer, errors, locations, lexer_param_ptr); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, answer, errors, locations, lexer_param_ptr) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - block* answer; - int* errors; - struct locfile* locations; - struct lexer_param* lexer_param_ptr; -#endif -{ - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (answer); - YYUSE (errors); - YYUSE (locations); - YYUSE (lexer_param_ptr); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, answer, errors, locations, lexer_param_ptr) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - block* answer; - int* errors; - struct locfile* locations; - struct lexer_param* lexer_param_ptr; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, answer, errors, locations, lexer_param_ptr); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, answer, errors, locations, lexer_param_ptr) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - block* answer; - int* errors; - struct locfile* locations; - struct lexer_param* lexer_param_ptr; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , answer, errors, locations, lexer_param_ptr); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, answer, errors, locations, lexer_param_ptr); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = 0; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - - for details. YYERROR is fine as it does not invoke this - function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, answer, errors, locations, lexer_param_ptr) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - block* answer; - int* errors; - struct locfile* locations; - struct lexer_param* lexer_param_ptr; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (answer); - YYUSE (errors); - YYUSE (locations); - YYUSE (lexer_param_ptr); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - case 4: /* "IDENT" */ - -/* Line 1391 of yacc.c */ -#line 32 "parser.y" - { jv_free((yyvaluep->literal)); }; - -/* Line 1391 of yacc.c */ -#line 1531 "parser.gen.c" - break; - case 5: /* "LITERAL" */ - -/* Line 1391 of yacc.c */ -#line 32 "parser.y" - { jv_free((yyvaluep->literal)); }; - -/* Line 1391 of yacc.c */ -#line 1540 "parser.gen.c" - break; - case 28: /* "QQSTRING_TEXT" */ - -/* Line 1391 of yacc.c */ -#line 32 "parser.y" - { jv_free((yyvaluep->literal)); }; - -/* Line 1391 of yacc.c */ -#line 1549 "parser.gen.c" - break; - case 53: /* "FuncDefs" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1558 "parser.gen.c" - break; - case 54: /* "Exp" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1567 "parser.gen.c" - break; - case 55: /* "String" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1576 "parser.gen.c" - break; - case 56: /* "FuncDef" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1585 "parser.gen.c" - break; - case 57: /* "QQString" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1594 "parser.gen.c" - break; - case 58: /* "ElseBody" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1603 "parser.gen.c" - break; - case 59: /* "ExpD" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1612 "parser.gen.c" - break; - case 60: /* "Term" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1621 "parser.gen.c" - break; - case 61: /* "MkDict" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1630 "parser.gen.c" - break; - case 62: /* "MkDictPair" */ - -/* Line 1391 of yacc.c */ -#line 33 "parser.y" - { block_free((yyvaluep->blk)); }; - -/* Line 1391 of yacc.c */ -#line 1639 "parser.gen.c" - break; - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) -#else -int -yyparse (answer, errors, locations, lexer_param_ptr) - block* answer; - int* errors; - struct locfile* locations; - struct lexer_param* lexer_param_ptr; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - yylsp = yyls; - -#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 1; -#endif - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: - -/* Line 1806 of yacc.c */ -#line 175 "parser.y" - { - *answer = (yyvsp[(1) - (1)].blk); -} - break; - - case 3: - -/* Line 1806 of yacc.c */ -#line 178 "parser.y" - { - *answer = (yyvsp[(1) - (1)].blk); -} - break; - - case 4: - -/* Line 1806 of yacc.c */ -#line 183 "parser.y" - { - (yyval.blk) = gen_noop(); -} - break; - - case 5: - -/* Line 1806 of yacc.c */ -#line 186 "parser.y" - { - (yyval.blk) = block_join((yyvsp[(1) - (2)].blk), (yyvsp[(2) - (2)].blk)); -} - break; - - case 6: - -/* Line 1806 of yacc.c */ -#line 191 "parser.y" - { - (yyval.blk) = block_bind((yyvsp[(1) - (2)].blk), (yyvsp[(2) - (2)].blk), OP_IS_CALL_PSEUDO); -} - break; - - case 7: - -/* Line 1806 of yacc.c */ -#line 195 "parser.y" - { - (yyval.blk) = BLOCK(gen_op_simple(DUP), (yyvsp[(1) - (6)].blk), - block_bind(gen_op_var_unbound(STOREV, jv_string_value((yyvsp[(4) - (6)].literal))), - (yyvsp[(6) - (6)].blk), OP_HAS_VARIABLE)); - jv_free((yyvsp[(4) - (6)].literal)); -} - break; - - case 8: - -/* Line 1806 of yacc.c */ -#line 202 "parser.y" - { - (yyval.blk) = gen_cond((yyvsp[(2) - (5)].blk), (yyvsp[(4) - (5)].blk), (yyvsp[(5) - (5)].blk)); -} - break; - - case 9: - -/* Line 1806 of yacc.c */ -#line 205 "parser.y" - { - FAIL((yyloc), "Possibly unterminated 'if' statment"); - (yyval.blk) = (yyvsp[(2) - (3)].blk); -} - break; - - case 10: - -/* Line 1806 of yacc.c */ -#line 210 "parser.y" - { - (yyval.blk) = gen_assign(BLOCK(gen_op_simple(DUP), (yyvsp[(3) - (3)].blk), gen_op_simple(SWAP), (yyvsp[(1) - (3)].blk), gen_op_simple(SWAP))); -} - break; - - case 11: - -/* Line 1806 of yacc.c */ -#line 214 "parser.y" - { - (yyval.blk) = gen_or((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); -} - break; - - case 12: - -/* Line 1806 of yacc.c */ -#line 218 "parser.y" - { - (yyval.blk) = gen_and((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); -} - break; - - case 13: - -/* Line 1806 of yacc.c */ -#line 222 "parser.y" - { - (yyval.blk) = gen_definedor((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); -} - break; - - case 14: - -/* Line 1806 of yacc.c */ -#line 226 "parser.y" - { - (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), gen_definedor(gen_noop(), (yyvsp[(3) - (3)].blk)), 0); -} - break; - - case 15: - -/* Line 1806 of yacc.c */ -#line 230 "parser.y" - { - (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), 0); -} - break; - - case 16: - -/* Line 1806 of yacc.c */ -#line 234 "parser.y" - { - (yyval.blk) = block_join((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); -} - break; - - case 17: - -/* Line 1806 of yacc.c */ -#line 238 "parser.y" - { - (yyval.blk) = gen_both((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); -} - break; - - case 18: - -/* Line 1806 of yacc.c */ -#line 242 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '+'); -} - break; - - case 19: - -/* Line 1806 of yacc.c */ -#line 246 "parser.y" - { - (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '+'); -} - break; - - case 20: - -/* Line 1806 of yacc.c */ -#line 250 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '-'); -} - break; - - case 21: - -/* Line 1806 of yacc.c */ -#line 254 "parser.y" - { - (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '-'); -} - break; - - case 22: - -/* Line 1806 of yacc.c */ -#line 258 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '*'); -} - break; - - case 23: - -/* Line 1806 of yacc.c */ -#line 262 "parser.y" - { - (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '*'); -} - break; - - case 24: - -/* Line 1806 of yacc.c */ -#line 266 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '/'); -} - break; - - case 25: - -/* Line 1806 of yacc.c */ -#line 270 "parser.y" - { - (yyval.blk) = gen_update((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '/'); -} - break; - - case 26: - -/* Line 1806 of yacc.c */ -#line 274 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), EQ); -} - break; - - case 27: - -/* Line 1806 of yacc.c */ -#line 278 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), NEQ); -} - break; - - case 28: - -/* Line 1806 of yacc.c */ -#line 282 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '<'); -} - break; - - case 29: - -/* Line 1806 of yacc.c */ -#line 286 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), '>'); -} - break; - - case 30: - -/* Line 1806 of yacc.c */ -#line 290 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), LESSEQ); -} - break; - - case 31: - -/* Line 1806 of yacc.c */ -#line 294 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), GREATEREQ); -} - break; - - case 32: - -/* Line 1806 of yacc.c */ -#line 298 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk), CONTAINS); -} - break; - - case 33: - -/* Line 1806 of yacc.c */ -#line 302 "parser.y" - { - (yyval.blk) = (yyvsp[(1) - (1)].blk); -} - break; - - case 34: - -/* Line 1806 of yacc.c */ -#line 307 "parser.y" - { - (yyval.blk) = (yyvsp[(2) - (3)].blk); -} - break; - - case 35: - -/* Line 1806 of yacc.c */ -#line 312 "parser.y" - { - (yyval.blk) = gen_function(jv_string_value((yyvsp[(2) - (5)].literal)), (yyvsp[(4) - (5)].blk)); - jv_free((yyvsp[(2) - (5)].literal)); -} - break; - - case 36: - -/* Line 1806 of yacc.c */ -#line 317 "parser.y" - { - block body = block_bind(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value((yyvsp[(4) - (8)].literal))), (yyvsp[(7) - (8)].blk), OP_IS_CALL_PSEUDO); - (yyval.blk) = gen_function(jv_string_value((yyvsp[(2) - (8)].literal)), body); - jv_free((yyvsp[(2) - (8)].literal)); - jv_free((yyvsp[(4) - (8)].literal)); -} - break; - - case 37: - -/* Line 1806 of yacc.c */ -#line 325 "parser.y" - { - (yyval.blk) = gen_op_const(LOADK, jv_string("")); -} - break; - - case 38: - -/* Line 1806 of yacc.c */ -#line 328 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (2)].blk), gen_op_const(LOADK, (yyvsp[(2) - (2)].literal)), '+'); -} - break; - - case 39: - -/* Line 1806 of yacc.c */ -#line 331 "parser.y" - { - (yyval.blk) = gen_binop((yyvsp[(1) - (4)].blk), gen_format((yyvsp[(3) - (4)].blk)), '+'); -} - break; - - case 40: - -/* Line 1806 of yacc.c */ -#line 337 "parser.y" - { - (yyval.blk) = gen_cond((yyvsp[(2) - (5)].blk), (yyvsp[(4) - (5)].blk), (yyvsp[(5) - (5)].blk)); -} - break; - - case 41: - -/* Line 1806 of yacc.c */ -#line 340 "parser.y" - { - (yyval.blk) = (yyvsp[(2) - (3)].blk); -} - break; - - case 42: - -/* Line 1806 of yacc.c */ -#line 345 "parser.y" - { - (yyval.blk) = block_join((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); -} - break; - - case 43: - -/* Line 1806 of yacc.c */ -#line 349 "parser.y" - { - (yyval.blk) = (yyvsp[(1) - (1)].blk); -} - break; - - case 44: - -/* Line 1806 of yacc.c */ -#line 355 "parser.y" - { - (yyval.blk) = gen_noop(); -} - break; - - case 45: - -/* Line 1806 of yacc.c */ -#line 358 "parser.y" - { - (yyval.blk) = gen_index((yyvsp[(1) - (3)].blk), gen_op_const(LOADK, (yyvsp[(3) - (3)].literal))); -} - break; - - case 46: - -/* Line 1806 of yacc.c */ -#line 361 "parser.y" - { - (yyval.blk) = gen_index(gen_noop(), gen_op_const(LOADK, (yyvsp[(2) - (2)].literal))); -} - break; - - case 47: - -/* Line 1806 of yacc.c */ -#line 365 "parser.y" - { - (yyval.blk) = gen_index((yyvsp[(1) - (4)].blk), (yyvsp[(3) - (4)].blk)); -} - break; - - case 48: - -/* Line 1806 of yacc.c */ -#line 368 "parser.y" - { - (yyval.blk) = block_join((yyvsp[(1) - (3)].blk), gen_op_simple(EACH)); -} - break; - - case 49: - -/* Line 1806 of yacc.c */ -#line 371 "parser.y" - { - (yyval.blk) = gen_op_const(LOADK, (yyvsp[(1) - (1)].literal)); -} - break; - - case 50: - -/* Line 1806 of yacc.c */ -#line 374 "parser.y" - { - (yyval.blk) = (yyvsp[(1) - (1)].blk); -} - break; - - case 51: - -/* Line 1806 of yacc.c */ -#line 377 "parser.y" - { - (yyval.blk) = (yyvsp[(2) - (3)].blk); -} - break; - - case 52: - -/* Line 1806 of yacc.c */ -#line 380 "parser.y" - { - (yyval.blk) = gen_collect((yyvsp[(2) - (3)].blk)); -} - break; - - case 53: - -/* Line 1806 of yacc.c */ -#line 383 "parser.y" - { - (yyval.blk) = gen_op_const(LOADK, jv_array()); -} - break; - - case 54: - -/* Line 1806 of yacc.c */ -#line 386 "parser.y" - { - (yyval.blk) = BLOCK(gen_subexp(gen_op_const(LOADK, jv_object())), (yyvsp[(2) - (3)].blk), gen_op_simple(POP)); -} - break; - - case 55: - -/* Line 1806 of yacc.c */ -#line 389 "parser.y" - { - (yyval.blk) = gen_location((yyloc), gen_op_var_unbound(LOADV, jv_string_value((yyvsp[(2) - (2)].literal)))); - jv_free((yyvsp[(2) - (2)].literal)); -} - break; - - case 56: - -/* Line 1806 of yacc.c */ -#line 393 "parser.y" - { - (yyval.blk) = gen_location((yyloc), gen_call(jv_string_value((yyvsp[(1) - (1)].literal)), gen_noop())); - jv_free((yyvsp[(1) - (1)].literal)); -} - break; - - case 57: - -/* Line 1806 of yacc.c */ -#line 397 "parser.y" - { - (yyval.blk) = gen_call(jv_string_value((yyvsp[(1) - (4)].literal)), gen_lambda((yyvsp[(3) - (4)].blk))); - (yyval.blk) = gen_location((yylsp[(1) - (4)]), (yyval.blk)); - jv_free((yyvsp[(1) - (4)].literal)); -} - break; - - case 58: - -/* Line 1806 of yacc.c */ -#line 402 "parser.y" - { (yyval.blk) = gen_noop(); } - break; - - case 59: - -/* Line 1806 of yacc.c */ -#line 403 "parser.y" - { (yyval.blk) = gen_noop(); } - break; - - case 60: - -/* Line 1806 of yacc.c */ -#line 404 "parser.y" - { (yyval.blk) = (yyvsp[(1) - (4)].blk); } - break; - - case 61: - -/* Line 1806 of yacc.c */ -#line 405 "parser.y" - { (yyval.blk) = gen_noop(); } - break; - - case 62: - -/* Line 1806 of yacc.c */ -#line 408 "parser.y" - { - (yyval.blk)=gen_noop(); -} - break; - - case 63: - -/* Line 1806 of yacc.c */ -#line 411 "parser.y" - { (yyval.blk) = (yyvsp[(1) - (1)].blk); } - break; - - case 64: - -/* Line 1806 of yacc.c */ -#line 412 "parser.y" - { (yyval.blk)=block_join((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); } - break; - - case 65: - -/* Line 1806 of yacc.c */ -#line 413 "parser.y" - { (yyval.blk) = (yyvsp[(3) - (3)].blk); } - break; - - case 66: - -/* Line 1806 of yacc.c */ -#line 416 "parser.y" - { - (yyval.blk) = gen_dictpair(gen_op_const(LOADK, (yyvsp[(1) - (3)].literal)), (yyvsp[(3) - (3)].blk)); - } - break; - - case 67: - -/* Line 1806 of yacc.c */ -#line 419 "parser.y" - { - (yyval.blk) = gen_dictpair((yyvsp[(1) - (3)].blk), (yyvsp[(3) - (3)].blk)); - } - break; - - case 68: - -/* Line 1806 of yacc.c */ -#line 422 "parser.y" - { - (yyval.blk) = gen_dictpair(gen_op_const(LOADK, jv_copy((yyvsp[(1) - (1)].literal))), - gen_index(gen_noop(), gen_op_const(LOADK, (yyvsp[(1) - (1)].literal)))); - } - break; - - case 69: - -/* Line 1806 of yacc.c */ -#line 426 "parser.y" - { - (yyval.blk) = gen_dictpair((yyvsp[(2) - (5)].blk), (yyvsp[(5) - (5)].blk)); - } - break; - - case 70: - -/* Line 1806 of yacc.c */ -#line 429 "parser.y" - { (yyval.blk) = (yyvsp[(5) - (5)].blk); } - break; - - - -/* Line 1806 of yacc.c */ -#line 2589 "parser.gen.c" - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, answer, errors, locations, lexer_param_ptr, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (&yylloc, answer, errors, locations, lexer_param_ptr, yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, answer, errors, locations, lexer_param_ptr); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, answer, errors, locations, lexer_param_ptr); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, answer, errors, locations, lexer_param_ptr, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, answer, errors, locations, lexer_param_ptr); - } - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, answer, errors, locations, lexer_param_ptr); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - -/* Line 2067 of yacc.c */ -#line 430 "parser.y" - - -int jq_parse(struct locfile* locations, block* answer) { - struct lexer_param scanner; - YY_BUFFER_STATE buf; - jq_yylex_init_extra(0, &scanner.lexer); - buf = jq_yy_scan_bytes(locations->data, locations->length, scanner.lexer); - int errors = 0; - *answer = gen_noop(); - yyparse(answer, &errors, locations, &scanner); - jq_yy_delete_buffer(buf, scanner.lexer); - jq_yylex_destroy(scanner.lexer); - if (errors > 0) { - block_free(*answer); - *answer = gen_noop(); - } - return errors; -} - -int jq_parse_library(struct locfile* locations, block* answer) { - int errs = jq_parse(locations, answer); - if (errs) return errs; - if (!block_has_only_binders(*answer, OP_IS_CALL_PSEUDO)) { - locfile_locate(locations, UNKNOWN_LOCATION, "error: library should only have function definitions, not a main expression"); - return 1; - } - return 0; -} - diff --git a/parser.gen.h b/parser.gen.h deleted file mode 100644 index bf9f9f8c..00000000 --- a/parser.gen.h +++ /dev/null @@ -1,132 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.5. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* "%code requires" blocks. */ - -/* Line 2068 of yacc.c */ -#line 9 "parser.y" - -#include "locfile.h" -#define YYLTYPE location -#define YYLLOC_DEFAULT(Loc, Rhs, N) \ - do { \ - if (N) { \ - (Loc).start = YYRHSLOC(Rhs, 1).start; \ - (Loc).end = YYRHSLOC(Rhs, N).end; \ - } else { \ - (Loc).start = YYRHSLOC(Rhs, 0).end; \ - (Loc).end = YYRHSLOC(Rhs, 0).end; \ - } \ - } while (0) - - - -/* Line 2068 of yacc.c */ -#line 55 "parser.gen.h" - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - INVALID_CHARACTER = 258, - IDENT = 259, - LITERAL = 260, - EQ = 261, - NEQ = 262, - DEFINEDOR = 263, - AS = 264, - DEF = 265, - IF = 266, - THEN = 267, - ELSE = 268, - ELSE_IF = 269, - END = 270, - AND = 271, - OR = 272, - SETPIPE = 273, - SETPLUS = 274, - SETMINUS = 275, - SETMULT = 276, - SETDIV = 277, - SETDEFINEDOR = 278, - LESSEQ = 279, - GREATEREQ = 280, - CONTAINS = 281, - QQSTRING_START = 282, - QQSTRING_TEXT = 283, - QQSTRING_INTERP_START = 284, - QQSTRING_INTERP_END = 285, - QQSTRING_END = 286 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 2068 of yacc.c */ -#line 27 "parser.y" - - jv literal; - block blk; - - - -/* Line 2068 of yacc.c */ -#line 110 "parser.gen.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - diff --git a/parser.gen.info b/parser.gen.info deleted file mode 100644 index 8f1f5656..00000000 --- a/parser.gen.info +++ /dev/null @@ -1,3565 +0,0 @@ -Terminals unused in grammar - - INVALID_CHARACTER - - -Grammar - - 0 $accept: TopLevel $end - - 1 TopLevel: Exp - 2 | FuncDefs - - 3 FuncDefs: /* empty */ - 4 | FuncDef FuncDefs - - 5 Exp: FuncDef Exp - 6 | Term "as" '$' IDENT '|' Exp - 7 | "if" Exp "then" Exp ElseBody - 8 | "if" Exp error - 9 | Exp '=' Exp - 10 | Exp "or" Exp - 11 | Exp "and" Exp - 12 | Exp "//" Exp - 13 | Exp "//=" Exp - 14 | Exp "|=" Exp - 15 | Exp '|' Exp - 16 | Exp ',' Exp - 17 | Exp '+' Exp - 18 | Exp "+=" Exp - 19 | Exp '-' Exp - 20 | Exp "-=" Exp - 21 | Exp '*' Exp - 22 | Exp "*=" Exp - 23 | Exp '/' Exp - 24 | Exp "/=" Exp - 25 | Exp "==" Exp - 26 | Exp "!=" Exp - 27 | Exp '<' Exp - 28 | Exp '>' Exp - 29 | Exp "<=" Exp - 30 | Exp ">=" Exp - 31 | Exp "contains" Exp - 32 | Term - - 33 String: QQSTRING_START QQString QQSTRING_END - - 34 FuncDef: "def" IDENT ':' Exp ';' - 35 | "def" IDENT '(' IDENT ')' ':' Exp ';' - - 36 QQString: /* empty */ - 37 | QQString QQSTRING_TEXT - 38 | QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END - - 39 ElseBody: "elif" Exp "then" Exp ElseBody - 40 | "else" Exp "end" - - 41 ExpD: ExpD '|' ExpD - 42 | Term - - 43 Term: '.' - 44 | Term '.' IDENT - 45 | '.' IDENT - 46 | Term '[' Exp ']' - 47 | Term '[' ']' - 48 | LITERAL - 49 | String - 50 | '(' Exp ')' - 51 | '[' Exp ']' - 52 | '[' ']' - 53 | '{' MkDict '}' - 54 | '$' IDENT - 55 | IDENT - 56 | IDENT '(' Exp ')' - 57 | '(' error ')' - 58 | '[' error ']' - 59 | Term '[' error ']' - 60 | '{' error '}' - - 61 MkDict: /* empty */ - 62 | MkDictPair - 63 | MkDictPair ',' MkDict - 64 | error ',' MkDict - - 65 MkDictPair: IDENT ':' ExpD - 66 | String ':' ExpD - 67 | IDENT - 68 | '(' Exp ')' ':' ExpD - 69 | '(' error ')' ':' ExpD - - -Terminals, with rules where they appear - -$end (0) 0 -'$' (36) 6 54 -'(' (40) 35 50 56 57 68 69 -')' (41) 35 50 56 57 68 69 -'*' (42) 21 -'+' (43) 17 -',' (44) 16 63 64 -'-' (45) 19 -'.' (46) 43 44 45 -'/' (47) 23 -':' (58) 34 35 65 66 68 69 -';' (59) 34 35 -'<' (60) 27 -'=' (61) 9 -'>' (62) 28 -'[' (91) 46 47 51 52 58 59 -']' (93) 46 47 51 52 58 59 -'{' (123) 53 60 -'|' (124) 6 15 41 -'}' (125) 53 60 -error (256) 8 57 58 59 60 64 69 -INVALID_CHARACTER (258) -IDENT (259) 6 34 35 44 45 54 55 56 65 67 -LITERAL (260) 48 -"==" (261) 25 -"!=" (262) 26 -"//" (263) 12 -"as" (264) 6 -"def" (265) 34 35 -"if" (266) 7 8 -"then" (267) 7 39 -"else" (268) 40 -"elif" (269) 39 -"end" (270) 40 -"and" (271) 11 -"or" (272) 10 -"|=" (273) 14 -"+=" (274) 18 -"-=" (275) 20 -"*=" (276) 22 -"/=" (277) 24 -"//=" (278) 13 -"<=" (279) 29 -">=" (280) 30 -"contains" (281) 31 -QQSTRING_START (282) 33 -QQSTRING_TEXT (283) 37 -QQSTRING_INTERP_START (284) 38 -QQSTRING_INTERP_END (285) 38 -QQSTRING_END (286) 33 - - -Nonterminals, with rules where they appear - -$accept (51) - on left: 0 -TopLevel (52) - on left: 1 2, on right: 0 -FuncDefs (53) - on left: 3 4, on right: 2 4 -Exp (54) - on left: 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 - 25 26 27 28 29 30 31 32, on right: 1 5 6 7 8 9 10 11 12 13 14 15 - 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 34 35 38 39 40 - 46 50 51 56 68 -String (55) - on left: 33, on right: 49 66 -FuncDef (56) - on left: 34 35, on right: 4 5 -QQString (57) - on left: 36 37 38, on right: 33 37 38 -ElseBody (58) - on left: 39 40, on right: 7 39 -ExpD (59) - on left: 41 42, on right: 41 65 66 68 69 -Term (60) - on left: 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60, - on right: 6 32 42 44 46 47 59 -MkDict (61) - on left: 61 62 63 64, on right: 53 63 64 -MkDictPair (62) - on left: 65 66 67 68 69, on right: 62 63 - - -state 0 - - 0 $accept: . TopLevel $end - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - $default reduce using rule 3 (FuncDefs) - - TopLevel go to state 11 - FuncDefs go to state 12 - Exp go to state 13 - String go to state 14 - FuncDef go to state 15 - Term go to state 16 - - -state 1 - - 55 Term: IDENT . - 56 | IDENT . '(' Exp ')' - - '(' shift, and go to state 17 - - $default reduce using rule 55 (Term) - - -state 2 - - 48 Term: LITERAL . - - $default reduce using rule 48 (Term) - - -state 3 - - 34 FuncDef: "def" . IDENT ':' Exp ';' - 35 | "def" . IDENT '(' IDENT ')' ':' Exp ';' - - IDENT shift, and go to state 18 - - -state 4 - - 7 Exp: "if" . Exp "then" Exp ElseBody - 8 | "if" . Exp error - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 19 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 5 - - 33 String: QQSTRING_START . QQString QQSTRING_END - - $default reduce using rule 36 (QQString) - - QQString go to state 21 - - -state 6 - - 54 Term: '$' . IDENT - - IDENT shift, and go to state 22 - - -state 7 - - 50 Term: '(' . Exp ')' - 57 | '(' . error ')' - - error shift, and go to state 23 - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 24 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 8 - - 43 Term: '.' . - 45 | '.' . IDENT - - IDENT shift, and go to state 25 - - $default reduce using rule 43 (Term) - - -state 9 - - 51 Term: '[' . Exp ']' - 52 | '[' . ']' - 58 | '[' . error ']' - - error shift, and go to state 26 - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - ']' shift, and go to state 27 - '{' shift, and go to state 10 - - Exp go to state 28 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 10 - - 53 Term: '{' . MkDict '}' - 60 | '{' . error '}' - - error shift, and go to state 29 - IDENT shift, and go to state 30 - QQSTRING_START shift, and go to state 5 - '(' shift, and go to state 31 - - '}' reduce using rule 61 (MkDict) - - String go to state 32 - MkDict go to state 33 - MkDictPair go to state 34 - - -state 11 - - 0 $accept: TopLevel . $end - - $end shift, and go to state 35 - - -state 12 - - 2 TopLevel: FuncDefs . - - $default reduce using rule 2 (TopLevel) - - -state 13 - - 1 TopLevel: Exp . - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 1 (TopLevel) - - -state 14 - - 49 Term: String . - - $default reduce using rule 49 (Term) - - -state 15 - - 4 FuncDefs: FuncDef . FuncDefs - 5 Exp: FuncDef . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - $default reduce using rule 3 (FuncDefs) - - FuncDefs go to state 59 - Exp go to state 60 - String go to state 14 - FuncDef go to state 15 - Term go to state 16 - - -state 16 - - 6 Exp: Term . "as" '$' IDENT '|' Exp - 32 | Term . - 44 Term: Term . '.' IDENT - 46 | Term . '[' Exp ']' - 47 | Term . '[' ']' - 59 | Term . '[' error ']' - - "as" shift, and go to state 61 - '.' shift, and go to state 62 - '[' shift, and go to state 63 - - $default reduce using rule 32 (Exp) - - -state 17 - - 56 Term: IDENT '(' . Exp ')' - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 64 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 18 - - 34 FuncDef: "def" IDENT . ':' Exp ';' - 35 | "def" IDENT . '(' IDENT ')' ':' Exp ';' - - ':' shift, and go to state 65 - '(' shift, and go to state 66 - - -state 19 - - 7 Exp: "if" Exp . "then" Exp ElseBody - 8 | "if" Exp . error - 9 | Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - error shift, and go to state 67 - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "then" shift, and go to state 68 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - -state 20 - - 5 Exp: FuncDef . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 60 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 21 - - 33 String: QQSTRING_START QQString . QQSTRING_END - 37 QQString: QQString . QQSTRING_TEXT - 38 | QQString . QQSTRING_INTERP_START Exp QQSTRING_INTERP_END - - QQSTRING_TEXT shift, and go to state 69 - QQSTRING_INTERP_START shift, and go to state 70 - QQSTRING_END shift, and go to state 71 - - -state 22 - - 54 Term: '$' IDENT . - - $default reduce using rule 54 (Term) - - -state 23 - - 57 Term: '(' error . ')' - - ')' shift, and go to state 72 - - -state 24 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 50 Term: '(' Exp . ')' - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - ')' shift, and go to state 73 - - -state 25 - - 45 Term: '.' IDENT . - - $default reduce using rule 45 (Term) - - -state 26 - - 58 Term: '[' error . ']' - - ']' shift, and go to state 74 - - -state 27 - - 52 Term: '[' ']' . - - $default reduce using rule 52 (Term) - - -state 28 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 51 Term: '[' Exp . ']' - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - ']' shift, and go to state 75 - - -state 29 - - 60 Term: '{' error . '}' - 64 MkDict: error . ',' MkDict - - ',' shift, and go to state 76 - '}' shift, and go to state 77 - - -state 30 - - 65 MkDictPair: IDENT . ':' ExpD - 67 | IDENT . - - ':' shift, and go to state 78 - - $default reduce using rule 67 (MkDictPair) - - -state 31 - - 68 MkDictPair: '(' . Exp ')' ':' ExpD - 69 | '(' . error ')' ':' ExpD - - error shift, and go to state 79 - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 80 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 32 - - 66 MkDictPair: String . ':' ExpD - - ':' shift, and go to state 81 - - -state 33 - - 53 Term: '{' MkDict . '}' - - '}' shift, and go to state 82 - - -state 34 - - 62 MkDict: MkDictPair . - 63 | MkDictPair . ',' MkDict - - ',' shift, and go to state 83 - - $default reduce using rule 62 (MkDict) - - -state 35 - - 0 $accept: TopLevel $end . - - $default accept - - -state 36 - - 25 Exp: Exp "==" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 84 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 37 - - 26 Exp: Exp "!=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 85 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 38 - - 12 Exp: Exp "//" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 86 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 39 - - 11 Exp: Exp "and" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 87 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 40 - - 10 Exp: Exp "or" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 88 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 41 - - 14 Exp: Exp "|=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 89 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 42 - - 18 Exp: Exp "+=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 90 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 43 - - 20 Exp: Exp "-=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 91 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 44 - - 22 Exp: Exp "*=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 92 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 45 - - 24 Exp: Exp "/=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 93 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 46 - - 13 Exp: Exp "//=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 94 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 47 - - 29 Exp: Exp "<=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 95 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 48 - - 30 Exp: Exp ">=" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 96 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 49 - - 31 Exp: Exp "contains" . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 97 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 50 - - 15 Exp: Exp '|' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 98 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 51 - - 16 Exp: Exp ',' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 99 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 52 - - 9 Exp: Exp '=' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 100 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 53 - - 27 Exp: Exp '<' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 101 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 54 - - 28 Exp: Exp '>' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 102 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 55 - - 17 Exp: Exp '+' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 103 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 56 - - 19 Exp: Exp '-' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 104 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 57 - - 21 Exp: Exp '*' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 105 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 58 - - 23 Exp: Exp '/' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 106 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 59 - - 4 FuncDefs: FuncDef FuncDefs . - - $default reduce using rule 4 (FuncDefs) - - -state 60 - - 5 Exp: FuncDef Exp . - 9 | Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 5 (Exp) - - -state 61 - - 6 Exp: Term "as" . '$' IDENT '|' Exp - - '$' shift, and go to state 107 - - -state 62 - - 44 Term: Term '.' . IDENT - - IDENT shift, and go to state 108 - - -state 63 - - 46 Term: Term '[' . Exp ']' - 47 | Term '[' . ']' - 59 | Term '[' . error ']' - - error shift, and go to state 109 - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - ']' shift, and go to state 110 - '{' shift, and go to state 10 - - Exp go to state 111 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 64 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 56 Term: IDENT '(' Exp . ')' - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - ')' shift, and go to state 112 - - -state 65 - - 34 FuncDef: "def" IDENT ':' . Exp ';' - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 113 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 66 - - 35 FuncDef: "def" IDENT '(' . IDENT ')' ':' Exp ';' - - IDENT shift, and go to state 114 - - -state 67 - - 8 Exp: "if" Exp error . - - $default reduce using rule 8 (Exp) - - -state 68 - - 7 Exp: "if" Exp "then" . Exp ElseBody - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 115 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 69 - - 37 QQString: QQString QQSTRING_TEXT . - - $default reduce using rule 37 (QQString) - - -state 70 - - 38 QQString: QQString QQSTRING_INTERP_START . Exp QQSTRING_INTERP_END - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 116 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 71 - - 33 String: QQSTRING_START QQString QQSTRING_END . - - $default reduce using rule 33 (String) - - -state 72 - - 57 Term: '(' error ')' . - - $default reduce using rule 57 (Term) - - -state 73 - - 50 Term: '(' Exp ')' . - - $default reduce using rule 50 (Term) - - -state 74 - - 58 Term: '[' error ']' . - - $default reduce using rule 58 (Term) - - -state 75 - - 51 Term: '[' Exp ']' . - - $default reduce using rule 51 (Term) - - -state 76 - - 64 MkDict: error ',' . MkDict - - error shift, and go to state 117 - IDENT shift, and go to state 30 - QQSTRING_START shift, and go to state 5 - '(' shift, and go to state 31 - - '}' reduce using rule 61 (MkDict) - - String go to state 32 - MkDict go to state 118 - MkDictPair go to state 34 - - -state 77 - - 60 Term: '{' error '}' . - - $default reduce using rule 60 (Term) - - -state 78 - - 65 MkDictPair: IDENT ':' . ExpD - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - String go to state 14 - ExpD go to state 119 - Term go to state 120 - - -state 79 - - 69 MkDictPair: '(' error . ')' ':' ExpD - - ')' shift, and go to state 121 - - -state 80 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 68 MkDictPair: '(' Exp . ')' ':' ExpD - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - ')' shift, and go to state 122 - - -state 81 - - 66 MkDictPair: String ':' . ExpD - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - String go to state 14 - ExpD go to state 123 - Term go to state 120 - - -state 82 - - 53 Term: '{' MkDict '}' . - - $default reduce using rule 53 (Term) - - -state 83 - - 63 MkDict: MkDictPair ',' . MkDict - - error shift, and go to state 117 - IDENT shift, and go to state 30 - QQSTRING_START shift, and go to state 5 - '(' shift, and go to state 31 - - '}' reduce using rule 61 (MkDict) - - String go to state 32 - MkDict go to state 124 - MkDictPair go to state 34 - - -state 84 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 25 | Exp "==" Exp . - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "==" error (nonassociative) - "!=" error (nonassociative) - "<=" error (nonassociative) - ">=" error (nonassociative) - "contains" error (nonassociative) - '<' error (nonassociative) - '>' error (nonassociative) - - $default reduce using rule 25 (Exp) - - -state 85 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 26 | Exp "!=" Exp . - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "==" error (nonassociative) - "!=" error (nonassociative) - "<=" error (nonassociative) - ">=" error (nonassociative) - "contains" error (nonassociative) - '<' error (nonassociative) - '>' error (nonassociative) - - $default reduce using rule 26 (Exp) - - -state 86 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 12 | Exp "//" Exp . - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 12 (Exp) - - -state 87 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 11 | Exp "and" Exp . - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 11 (Exp) - - -state 88 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 10 | Exp "or" Exp . - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "and" shift, and go to state 39 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 10 (Exp) - - -state 89 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 14 | Exp "|=" Exp . - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "|=" error (nonassociative) - "+=" error (nonassociative) - "-=" error (nonassociative) - "*=" error (nonassociative) - "/=" error (nonassociative) - "//=" error (nonassociative) - '=' error (nonassociative) - - $default reduce using rule 14 (Exp) - - -state 90 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 18 | Exp "+=" Exp . - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "|=" error (nonassociative) - "+=" error (nonassociative) - "-=" error (nonassociative) - "*=" error (nonassociative) - "/=" error (nonassociative) - "//=" error (nonassociative) - '=' error (nonassociative) - - $default reduce using rule 18 (Exp) - - -state 91 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 20 | Exp "-=" Exp . - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "|=" error (nonassociative) - "+=" error (nonassociative) - "-=" error (nonassociative) - "*=" error (nonassociative) - "/=" error (nonassociative) - "//=" error (nonassociative) - '=' error (nonassociative) - - $default reduce using rule 20 (Exp) - - -state 92 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 22 | Exp "*=" Exp . - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "|=" error (nonassociative) - "+=" error (nonassociative) - "-=" error (nonassociative) - "*=" error (nonassociative) - "/=" error (nonassociative) - "//=" error (nonassociative) - '=' error (nonassociative) - - $default reduce using rule 22 (Exp) - - -state 93 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 24 | Exp "/=" Exp . - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "|=" error (nonassociative) - "+=" error (nonassociative) - "-=" error (nonassociative) - "*=" error (nonassociative) - "/=" error (nonassociative) - "//=" error (nonassociative) - '=' error (nonassociative) - - $default reduce using rule 24 (Exp) - - -state 94 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 13 | Exp "//=" Exp . - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "|=" error (nonassociative) - "+=" error (nonassociative) - "-=" error (nonassociative) - "*=" error (nonassociative) - "/=" error (nonassociative) - "//=" error (nonassociative) - '=' error (nonassociative) - - $default reduce using rule 13 (Exp) - - -state 95 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 29 | Exp "<=" Exp . - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "==" error (nonassociative) - "!=" error (nonassociative) - "<=" error (nonassociative) - ">=" error (nonassociative) - "contains" error (nonassociative) - '<' error (nonassociative) - '>' error (nonassociative) - - $default reduce using rule 29 (Exp) - - -state 96 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 30 | Exp ">=" Exp . - 31 | Exp . "contains" Exp - - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "==" error (nonassociative) - "!=" error (nonassociative) - "<=" error (nonassociative) - ">=" error (nonassociative) - "contains" error (nonassociative) - '<' error (nonassociative) - '>' error (nonassociative) - - $default reduce using rule 30 (Exp) - - -state 97 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 31 | Exp "contains" Exp . - - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "==" error (nonassociative) - "!=" error (nonassociative) - "<=" error (nonassociative) - ">=" error (nonassociative) - "contains" error (nonassociative) - '<' error (nonassociative) - '>' error (nonassociative) - - $default reduce using rule 31 (Exp) - - -state 98 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 15 | Exp '|' Exp . - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 15 (Exp) - - -state 99 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 16 | Exp ',' Exp . - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 16 (Exp) - - -state 100 - - 9 Exp: Exp . '=' Exp - 9 | Exp '=' Exp . - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "|=" error (nonassociative) - "+=" error (nonassociative) - "-=" error (nonassociative) - "*=" error (nonassociative) - "/=" error (nonassociative) - "//=" error (nonassociative) - '=' error (nonassociative) - - $default reduce using rule 9 (Exp) - - -state 101 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 27 | Exp '<' Exp . - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "==" error (nonassociative) - "!=" error (nonassociative) - "<=" error (nonassociative) - ">=" error (nonassociative) - "contains" error (nonassociative) - '<' error (nonassociative) - '>' error (nonassociative) - - $default reduce using rule 27 (Exp) - - -state 102 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 28 | Exp '>' Exp . - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - "==" error (nonassociative) - "!=" error (nonassociative) - "<=" error (nonassociative) - ">=" error (nonassociative) - "contains" error (nonassociative) - '<' error (nonassociative) - '>' error (nonassociative) - - $default reduce using rule 28 (Exp) - - -state 103 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 17 | Exp '+' Exp . - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 17 (Exp) - - -state 104 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 19 | Exp '-' Exp . - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 19 (Exp) - - -state 105 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 21 | Exp '*' Exp . - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - $default reduce using rule 21 (Exp) - - -state 106 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 23 | Exp '/' Exp . - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - $default reduce using rule 23 (Exp) - - -state 107 - - 6 Exp: Term "as" '$' . IDENT '|' Exp - - IDENT shift, and go to state 125 - - -state 108 - - 44 Term: Term '.' IDENT . - - $default reduce using rule 44 (Term) - - -state 109 - - 59 Term: Term '[' error . ']' - - ']' shift, and go to state 126 - - -state 110 - - 47 Term: Term '[' ']' . - - $default reduce using rule 47 (Term) - - -state 111 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 46 Term: Term '[' Exp . ']' - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - ']' shift, and go to state 127 - - -state 112 - - 56 Term: IDENT '(' Exp ')' . - - $default reduce using rule 56 (Term) - - -state 113 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 34 FuncDef: "def" IDENT ':' Exp . ';' - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - ';' shift, and go to state 128 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - -state 114 - - 35 FuncDef: "def" IDENT '(' IDENT . ')' ':' Exp ';' - - ')' shift, and go to state 129 - - -state 115 - - 7 Exp: "if" Exp "then" Exp . ElseBody - 9 | Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "else" shift, and go to state 130 - "elif" shift, and go to state 131 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - ElseBody go to state 132 - - -state 116 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 38 QQString: QQString QQSTRING_INTERP_START Exp . QQSTRING_INTERP_END - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - QQSTRING_INTERP_END shift, and go to state 133 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - -state 117 - - 64 MkDict: error . ',' MkDict - - ',' shift, and go to state 76 - - -state 118 - - 64 MkDict: error ',' MkDict . - - $default reduce using rule 64 (MkDict) - - -state 119 - - 41 ExpD: ExpD . '|' ExpD - 65 MkDictPair: IDENT ':' ExpD . - - '|' shift, and go to state 134 - - $default reduce using rule 65 (MkDictPair) - - -state 120 - - 42 ExpD: Term . - 44 Term: Term . '.' IDENT - 46 | Term . '[' Exp ']' - 47 | Term . '[' ']' - 59 | Term . '[' error ']' - - '.' shift, and go to state 62 - '[' shift, and go to state 63 - - $default reduce using rule 42 (ExpD) - - -state 121 - - 69 MkDictPair: '(' error ')' . ':' ExpD - - ':' shift, and go to state 135 - - -state 122 - - 68 MkDictPair: '(' Exp ')' . ':' ExpD - - ':' shift, and go to state 136 - - -state 123 - - 41 ExpD: ExpD . '|' ExpD - 66 MkDictPair: String ':' ExpD . - - '|' shift, and go to state 134 - - $default reduce using rule 66 (MkDictPair) - - -state 124 - - 63 MkDict: MkDictPair ',' MkDict . - - $default reduce using rule 63 (MkDict) - - -state 125 - - 6 Exp: Term "as" '$' IDENT . '|' Exp - - '|' shift, and go to state 137 - - -state 126 - - 59 Term: Term '[' error ']' . - - $default reduce using rule 59 (Term) - - -state 127 - - 46 Term: Term '[' Exp ']' . - - $default reduce using rule 46 (Term) - - -state 128 - - 34 FuncDef: "def" IDENT ':' Exp ';' . - - $default reduce using rule 34 (FuncDef) - - -state 129 - - 35 FuncDef: "def" IDENT '(' IDENT ')' . ':' Exp ';' - - ':' shift, and go to state 138 - - -state 130 - - 40 ElseBody: "else" . Exp "end" - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 139 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 131 - - 39 ElseBody: "elif" . Exp "then" Exp ElseBody - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 140 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 132 - - 7 Exp: "if" Exp "then" Exp ElseBody . - - $default reduce using rule 7 (Exp) - - -state 133 - - 38 QQString: QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END . - - $default reduce using rule 38 (QQString) - - -state 134 - - 41 ExpD: ExpD '|' . ExpD - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - String go to state 14 - ExpD go to state 141 - Term go to state 120 - - -state 135 - - 69 MkDictPair: '(' error ')' ':' . ExpD - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - String go to state 14 - ExpD go to state 142 - Term go to state 120 - - -state 136 - - 68 MkDictPair: '(' Exp ')' ':' . ExpD - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - String go to state 14 - ExpD go to state 143 - Term go to state 120 - - -state 137 - - 6 Exp: Term "as" '$' IDENT '|' . Exp - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 144 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 138 - - 35 FuncDef: "def" IDENT '(' IDENT ')' ':' . Exp ';' - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 145 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 139 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 40 ElseBody: "else" Exp . "end" - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "end" shift, and go to state 146 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - -state 140 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 39 ElseBody: "elif" Exp . "then" Exp ElseBody - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "then" shift, and go to state 147 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - -state 141 - - 41 ExpD: ExpD . '|' ExpD - 41 | ExpD '|' ExpD . - - $default reduce using rule 41 (ExpD) - - -state 142 - - 41 ExpD: ExpD . '|' ExpD - 69 MkDictPair: '(' error ')' ':' ExpD . - - '|' shift, and go to state 134 - - $default reduce using rule 69 (MkDictPair) - - -state 143 - - 41 ExpD: ExpD . '|' ExpD - 68 MkDictPair: '(' Exp ')' ':' ExpD . - - '|' shift, and go to state 134 - - $default reduce using rule 68 (MkDictPair) - - -state 144 - - 6 Exp: Term "as" '$' IDENT '|' Exp . - 9 | Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - $default reduce using rule 6 (Exp) - - -state 145 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 35 FuncDef: "def" IDENT '(' IDENT ')' ':' Exp . ';' - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - ';' shift, and go to state 148 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - -state 146 - - 40 ElseBody: "else" Exp "end" . - - $default reduce using rule 40 (ElseBody) - - -state 147 - - 39 ElseBody: "elif" Exp "then" . Exp ElseBody - - IDENT shift, and go to state 1 - LITERAL shift, and go to state 2 - "def" shift, and go to state 3 - "if" shift, and go to state 4 - QQSTRING_START shift, and go to state 5 - '$' shift, and go to state 6 - '(' shift, and go to state 7 - '.' shift, and go to state 8 - '[' shift, and go to state 9 - '{' shift, and go to state 10 - - Exp go to state 149 - String go to state 14 - FuncDef go to state 20 - Term go to state 16 - - -state 148 - - 35 FuncDef: "def" IDENT '(' IDENT ')' ':' Exp ';' . - - $default reduce using rule 35 (FuncDef) - - -state 149 - - 9 Exp: Exp . '=' Exp - 10 | Exp . "or" Exp - 11 | Exp . "and" Exp - 12 | Exp . "//" Exp - 13 | Exp . "//=" Exp - 14 | Exp . "|=" Exp - 15 | Exp . '|' Exp - 16 | Exp . ',' Exp - 17 | Exp . '+' Exp - 18 | Exp . "+=" Exp - 19 | Exp . '-' Exp - 20 | Exp . "-=" Exp - 21 | Exp . '*' Exp - 22 | Exp . "*=" Exp - 23 | Exp . '/' Exp - 24 | Exp . "/=" Exp - 25 | Exp . "==" Exp - 26 | Exp . "!=" Exp - 27 | Exp . '<' Exp - 28 | Exp . '>' Exp - 29 | Exp . "<=" Exp - 30 | Exp . ">=" Exp - 31 | Exp . "contains" Exp - 39 ElseBody: "elif" Exp "then" Exp . ElseBody - - "==" shift, and go to state 36 - "!=" shift, and go to state 37 - "//" shift, and go to state 38 - "else" shift, and go to state 130 - "elif" shift, and go to state 131 - "and" shift, and go to state 39 - "or" shift, and go to state 40 - "|=" shift, and go to state 41 - "+=" shift, and go to state 42 - "-=" shift, and go to state 43 - "*=" shift, and go to state 44 - "/=" shift, and go to state 45 - "//=" shift, and go to state 46 - "<=" shift, and go to state 47 - ">=" shift, and go to state 48 - "contains" shift, and go to state 49 - '|' shift, and go to state 50 - ',' shift, and go to state 51 - '=' shift, and go to state 52 - '<' shift, and go to state 53 - '>' shift, and go to state 54 - '+' shift, and go to state 55 - '-' shift, and go to state 56 - '*' shift, and go to state 57 - '/' shift, and go to state 58 - - ElseBody go to state 150 - - -state 150 - - 39 ElseBody: "elif" Exp "then" Exp ElseBody . - - $default reduce using rule 39 (ElseBody) From 2b48ee4a8f894d698b3f726cc58dc9e18a3b27bf Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Wed, 12 Dec 2012 23:18:43 +0000 Subject: [PATCH 32/62] Add a Gemfile to make building the documentation easier. Use "bundle install" in the docs folder to install ruby dependencies. --- docs/Gemfile | 4 ++++ docs/Gemfile.lock | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 docs/Gemfile create mode 100644 docs/Gemfile.lock diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 00000000..84f2c4e6 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,4 @@ +source :rubygems + +gem "bonsai" +gem "maruku" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100644 index 00000000..6926b4ad --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,45 @@ +GEM + remote: http://rubygems.org/ + specs: + activesupport (3.2.9) + i18n (~> 0.6) + multi_json (~> 1.0) + addressable (2.3.2) + bonsai (1.4.7) + activesupport (>= 3.0.3) + builder (>= 3.0.0) + i18n (>= 0.5.0) + launchy (>= 0.3.7) + liquid (>= 2.2.2) + maruku (>= 0.6.0) + rack + sass + sinatra (>= 1.0) + tilt (>= 1.3) + watch (>= 0.1.0) + builder (3.1.4) + i18n (0.6.1) + launchy (2.1.2) + addressable (~> 2.3) + liquid (2.4.1) + maruku (0.6.1) + syntax (>= 1.0.0) + multi_json (1.5.0) + rack (1.4.1) + rack-protection (1.3.2) + rack + sass (3.2.3) + sinatra (1.3.3) + rack (~> 1.3, >= 1.3.6) + rack-protection (~> 1.2) + tilt (~> 1.3, >= 1.3.3) + syntax (1.0.0) + tilt (1.3.3) + watch (0.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + bonsai + maruku From 73c657cdc477a9ec97548991e355b766e06634a2 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 16 Dec 2012 13:06:03 +0000 Subject: [PATCH 33/62] Lots of build system and docs improvements, including a manpage. - Build binaries for multiple platforms - Make a manpage out of the manual (see #19) - Extract more tests from the documentation - Fix a few documentation bugs uncovered by above. --- .gitignore | 2 + Makefile | 54 ++++++++++--- docs/Gemfile | 1 + docs/Gemfile.lock | 8 ++ docs/Rakefile | 42 ++++++++++ docs/content/3.manual/manual.yml | 132 +++++++++++++++++-------------- jq_test.c | 40 +++++++--- 7 files changed, 197 insertions(+), 82 deletions(-) diff --git a/.gitignore b/.gitignore index e43b388c..6caf43c4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,7 @@ jv_test jv_parse parsertest*~ +build + # Something delightfully recursive happens otherwise docs/content/2.download/source/* \ No newline at end of file diff --git a/Makefile b/Makefile index 0c2d3177..5dfbb7f9 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,13 @@ -CC=gcc -Wextra -Wall -Wno-missing-field-initializers -Wno-unused-parameter -std=gnu99 -ggdb -Wno-unused-function +CC=gcc +CFLAGS=-Wextra -Wall -Wno-missing-field-initializers -Wno-unused-parameter -std=gnu99 -ggdb -Wno-unused-function + prefix=/usr/local +mandir=$(prefix)/share/man + .PHONY: all clean releasedep tarball install uninstall test releasetag all: jq - lexer.gen.c: lexer.l flex -o lexer.gen.c --header-file=lexer.gen.h lexer.l lexer.gen.h: lexer.gen.c @@ -23,16 +26,45 @@ main.c: version.gen.h JQ_SRC=parser.gen.c lexer.gen.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c - +jq_test: CFLAGS += -DJQ_DEBUG=1 jq_test: $(JQ_SRC) jq_test.c - $(CC) -DJQ_DEBUG=1 -o $@ $^ + $(CC) $(CFLAGS) $(CFLAGS_DEBUG) -o $@ $^ +jq: CFLAGS += -O -DJQ_DEBUG=0 jq: $(JQ_SRC) main.c - $(CC) -O -DJQ_DEBUG=0 -o $@ $^ + $(CC) $(CFLAGS) $(CFLAGS_OPT) -o $@ $^ test: jq_test valgrind --error-exitcode=1 -q --leak-check=full ./jq_test >/dev/null +BINARIES=jq jq_test +PLATFORMS=linux32 linux64 osx32 osx64 win32 win64 + +build/linux32%: CC='x86_64-linux-gnu-gcc -m32' +build/linux64%: CC='x86_64-linux-gnu-gcc -m64' + +# OS X cross compilers can be gotten from +# https://launchpad.net/~flosoft/+archive/cross-apple +build/osx32%: CC='i686-apple-darwin10-gcc -m32' +build/osx64%: CC='i686-apple-darwin10-gcc -m64' + +# On Debian, you can get windows compilers in the +# gcc-mingw-w64-i686 and gcc-mingw-w64-x86-64 packages. +build/win32%: CC='i686-w64-mingw32-gcc -m32' +build/win64%: CC='x86_64-w64-mingw32-gcc -m64' + +ALL_BINARIES=$(foreach platform, $(PLATFORMS), $(foreach binary, $(BINARIES), build/$(platform)/$(binary))) + +$(ALL_BINARIES): build/%: + mkdir -p $(@D) + make -B $(BINARIES) CC=$(CC) + cp $(BINARIES) $(@D) + +binaries: $(ALL_BINARIES) + +clean: + rm -rf build + rm -f $(BINARIES) *.gen.* releasedep: lexer.gen.c parser.gen.c jv_utf8_tables.gen.h @@ -45,12 +77,16 @@ docs/content/2.download/source/jq.tgz: jq tarball: docs/content/2.download/source/jq.tgz -install: jq +jq.1: docs/content/3.manual/manual.yml + ( cd docs; rake manpage; ) > $@ + +install: jq jq.1 install -d -m 0755 $(prefix)/bin install -m 0755 jq $(prefix)/bin + install -d -m 0755 $(mandir)/man1 + install -m 0755 jq.1 $(mandir)/man1 uninstall: - test -d $(prefix)/bin && \ - cd $(prefix)/bin && \ - rm -f jq + rm -vf $(prefix)/bin/jq + rm -vf $(mandir)/man1/jq.1 diff --git a/docs/Gemfile b/docs/Gemfile index 84f2c4e6..f06950f6 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -2,3 +2,4 @@ source :rubygems gem "bonsai" gem "maruku" +gem "ronn" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 6926b4ad..ccbc84fe 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -18,6 +18,7 @@ GEM tilt (>= 1.3) watch (>= 0.1.0) builder (3.1.4) + hpricot (0.8.6) i18n (0.6.1) launchy (2.1.2) addressable (~> 2.3) @@ -25,9 +26,15 @@ GEM maruku (0.6.1) syntax (>= 1.0.0) multi_json (1.5.0) + mustache (0.99.4) rack (1.4.1) rack-protection (1.3.2) rack + rdiscount (1.6.8) + ronn (0.7.3) + hpricot (>= 0.8.2) + mustache (>= 0.7.0) + rdiscount (>= 1.5.8) sass (3.2.3) sinatra (1.3.3) rack (~> 1.3, >= 1.3.6) @@ -43,3 +50,4 @@ PLATFORMS DEPENDENCIES bonsai maruku + ronn diff --git a/docs/Rakefile b/docs/Rakefile index 51e9b484..da2d4cf4 100644 --- a/docs/Rakefile +++ b/docs/Rakefile @@ -2,6 +2,8 @@ require 'bonsai' require 'liquid' require 'maruku' require 'json' +require 'ronn' +require 'tempfile' module ExtraFilters def markdownify(input) @@ -59,3 +61,43 @@ task :build do Bonsai.root_dir = Dir.pwd Bonsai::Exporter.publish! end + +def load_manual + YAML::ENGINE.yamler = 'syck' + YAML::load(File.open("content/3.manual/manual.yml")) +end + +task :manpage do + Tempfile.open "manpage" do |f| + manual = load_manual + f.puts manual['manpage_intro'] + f.puts manual['body'] + manual['sections'].each do |section| + + f.puts "## #{section['title'].upcase}\n" + f.puts section['body'] + f.puts "" + (section['entries'] || []).each do |entry| + f.puts "### #{entry['title']}\n" + f.puts entry['body'] + f.puts "" + end + f.puts "" + end + f.close + puts Ronn::Document.new(f.path).convert('roff').gsub(/<\/?code>/,"") + end +end + +task :mantests do + load_manual['sections'].each do |section| + (section['entries'] || []).each do |entry| + (entry['examples'] || []).each do |example| + puts example['program'].gsub("\n", " ") + puts example['input'] + example['output'].each do |s| puts s end + puts + end + end + end +end diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 15dcb489..f0cedf4f 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -26,6 +26,15 @@ body: | But that's getting ahead of ourselves. :) Let's start with something simpler: + +manpage_intro: | + jq(1) -- Command-line JSON processor + ==================================== + + ## SYNOPSIS + + `jq` [...] + sections: - title: Invoking jq @@ -40,51 +49,51 @@ sections: You can affect how jq reads and writes its input and output using some command-line options: - * `--slurp`/`-s` - - Instead of running the filter for each JSON object in the - input, read the entire input stream into a large array and run - the filter just once. - - * `--raw-input`/`-R` - - Don't parse the input as JSON. Instead, each line of text is - passed to the filter as a string. If combined with `--slurp`, - then the entire input is passed to the filter as a single long - string. - - * `--null-input`/`-n` - - Don't read any input at all! Instead, the filter is run once - using `null` as the input. This is useful when using jq as a - simple calculator or to construct JSON data from scratch. - - * `--compact-output` / `-c` - - By default, jq pretty-prints JSON output. Using this option - will result in more compact output by instead putting each - JSON object on a single line. - - * `--colour-output` / `-C` and `--monochrome-output` / `-M` - - By default, jq outputs colored JSON if writing to a - terminal. You can force it to produce color even if writing to - a pipe or a file using `-C`, and disable color with `-M`. - - * `--ascii-output` / `-a` - - jq usually outputs non-ASCII Unicode codepoints as UTF-8, even - if the input specified them as escape sequences (like - "\u03bc"). Using this option, you can force jq to produce pure - ASCII output with every non-ASCII character replaced with the - equivalent escape sequence. - - * `--raw-output` / `-r` - - With this option, if the filter's result is a string then it - will be written directly to standard output rather than being - formatted as a JSON string with quotes. This can be useful for - making jq filters talk to non-JSON-based systems. + * `--slurp`/`-s`: + + Instead of running the filter for each JSON object in the + input, read the entire input stream into a large array and run + the filter just once. + + * `--raw-input`/`-R`: + + Don't parse the input as JSON. Instead, each line of text is + passed to the filter as a string. If combined with `--slurp`, + then the entire input is passed to the filter as a single long + string. + + * `--null-input`/`-n`: + + Don't read any input at all! Instead, the filter is run once + using `null` as the input. This is useful when using jq as a + simple calculator or to construct JSON data from scratch. + + * `--compact-output` / `-c`: + + By default, jq pretty-prints JSON output. Using this option + will result in more compact output by instead putting each + JSON object on a single line. + + * `--colour-output` / `-C` and `--monochrome-output` / `-M`: + + By default, jq outputs colored JSON if writing to a + terminal. You can force it to produce color even if writing to + a pipe or a file using `-C`, and disable color with `-M`. + + * `--ascii-output` / `-a`: + + jq usually outputs non-ASCII Unicode codepoints as UTF-8, even + if the input specified them as escape sequences (like + "\u03bc"). Using this option, you can force jq to produce pure + ASCII output with every non-ASCII character replaced with the + equivalent escape sequence. + + * `--raw-output` / `-r`: + + With this option, if the filter's result is a string then it + will be written directly to standard output rather than being + formatted as a JSON string with quotes. This can be useful for + making jq filters talk to non-JSON-based systems. - title: Basic filters entries: @@ -148,7 +157,7 @@ sections: examples: - program: '.[]' - input: '[{name":"JSON", "good":true}, {"name":"XML", "good":false}]' + input: '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' output: - '{"name":"JSON", "good":true}' - '{"name":"XML", "good":false}' @@ -178,7 +187,7 @@ sections: - program: '.[4,2]' input: '["a","b","c","d","e"]' - output: ['"d"', '"c"'] + output: ['"e"', '"c"'] - title: "`|`" body: | @@ -194,7 +203,7 @@ sections: examples: - program: '.[] | .name' - input: '[{name":"JSON", "good":true}, {"name":"XML", "good":false}]' + input: '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' output: ['"JSON"', '"XML"'] - title: Types and Values @@ -325,7 +334,7 @@ sections: examples: - program: '.a + 1' input: '{"a": 7}' - output: '{"a": 8}' + output: ['8'] - program: '.a + .b' input: '{"a": [1,2], "b": [3,4]}' output: ['[1,2,3,4]'] @@ -409,11 +418,11 @@ sections: `foo` returns true for that input, and produces no output otherwise. - It's useful for filtering lists: `[1,2,3] | select(. >= 2)` + It's useful for filtering lists: `[1,2,3] | map(select(. >= 2))` will give you `[3]`. examples: - - program: 'select(. >= 2)' + - program: 'map(select(. >= 2))' input: '[1,5,3,0,7]' output: ['[5,3,7]'] @@ -427,7 +436,7 @@ sections: examples: - program: '1, empty, 2' input: 'null' - output: [1,2] + output: [1, 2] - program: '[1,2,empty,3]' input: 'null' output: ['[1,2,3]'] @@ -461,7 +470,7 @@ sections: examples: - program: add input: '["a","b","c"]' - output: ["abc"] + output: ['"abc"'] - program: add input: '[1, 2, 3]' output: [6] @@ -479,7 +488,7 @@ sections: examples: - program: '.[] | tonumber' input: '[1, "1"]' - output: [1,1] + output: [1, 1] - title: `tostring` body: | @@ -593,10 +602,10 @@ sections: input: '["foobar", "foobaz", "blarp"]' output: ['false'] - program: 'contains({foo: 12, bar: [{barp: 12}]})' - input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}' + input: '{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}' output: ['true'] - program: 'contains({foo: 12, bar: [{barp: 15}]})' - input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}' + input: '{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}' output: ['false'] - title: "String interpolation - `\(foo)`" @@ -633,7 +642,7 @@ sections: examples: - program: '.[] == 1' input: '[1, 1.0, "1", "banana"]' - output: ['[true, true, false, false]'] + output: ['true', 'true', 'false', 'false'] - title: if-then-else body: | @@ -854,12 +863,12 @@ sections: input's `.foo` field to each element of the array. examples: - - program: 'def addvalue(f): map(. + [$value]); addvalue(.[0])' + - program: 'def addvalue(f): . + [f]; map(addvalue(.[0]))' input: '[[1,2],[10,20]]' output: ['[[1,2,1], [10,20,10]]'] - - program: 'def addvalue(f): f as $x | map (. + $x); addvalue(.[0])' + - program: 'def addvalue(f): f as $x | map(. + $x); addvalue(.[0])' input: '[[1,2],[10,20]]' - output: ['[[1,2,[1,2]], [10,20,[1,2]]]'] + output: ['[[1,2,1,2], [10,20,1,2]]'] - title: Assignment @@ -971,4 +980,5 @@ sections: "stedolan" wrote, and we can comment on each of them in the same way that we did before: - (.posts[] | select(.author == "stedolan") | .comments) |= . + ["terrible."] + (.posts[] | select(.author == "stedolan") | .comments) |= + . + ["terrible."] diff --git a/jq_test.c b/jq_test.c index 2960162e..c9bdaef4 100644 --- a/jq_test.c +++ b/jq_test.c @@ -8,9 +8,24 @@ static void jv_test(); static void run_jq_tests(); -int main() { +FILE* testdata; + +int main(int argc, char* argv[]) { jv_test(); + if (argc == 1) { + testdata = fopen("testdata", "r"); + } else if (argc == 2) { + if (!strcmp(argv[1], "-")) { + testdata = stdin; + } else { + testdata = fopen(argv[1], "r"); + } + } else { + printf("usage: %s OR cat testdata | %s - OR %s testdata\n", argv[0], argv[0], argv[0]); + return 127; + } run_jq_tests(); + if (testdata != stdin) fclose(testdata); } @@ -24,37 +39,40 @@ static int skipline(const char* buf) { } static void run_jq_tests() { - FILE* testdata = fopen("testdata","r"); char buf[4096]; - int tests = 0, passed = 0; + int tests = 0, passed = 0, invalid = 0; while (1) { if (!fgets(buf, sizeof(buf), testdata)) break; if (skipline(buf)) continue; + if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0; printf("Testing %s\n", buf); int pass = 1; + tests++; struct bytecode* bc = jq_compile(buf); - assert(bc); + if (!bc) {invalid++; continue;} +#if JQ_DEBUG printf("Disassembly:\n"); dump_disassembly(2, bc); printf("\n"); +#endif fgets(buf, sizeof(buf), testdata); jv input = jv_parse(buf); - assert(jv_is_valid(input)); + if (!jv_is_valid(input)){ invalid++; continue; } jq_init(bc, input); while (fgets(buf, sizeof(buf), testdata)) { if (skipline(buf)) break; jv expected = jv_parse(buf); - assert(jv_is_valid(expected)); + if (!jv_is_valid(expected)){ invalid++; continue; } jv actual = jq_next(); if (!jv_is_valid(actual)) { jv_free(actual); - printf("Insufficient results\n"); + printf("*** Insufficient results\n"); pass = 0; break; } else if (!jv_equal(jv_copy(expected), jv_copy(actual))) { - printf("Expected "); + printf("*** Expected "); jv_dump(jv_copy(expected), 0); printf(", but got "); jv_dump(jv_copy(actual), 0); @@ -72,7 +90,7 @@ static void run_jq_tests() { if (pass) { jv extra = jq_next(); if (jv_is_valid(extra)) { - printf("Superfluous result: "); + printf("*** Superfluous result: "); jv_dump(extra, 0); printf("\n"); pass = 0; @@ -82,11 +100,9 @@ static void run_jq_tests() { } jq_teardown(); bytecode_free(bc); - tests++; passed+=pass; } - fclose(testdata); - printf("%d of %d tests passed\n", passed,tests); + printf("%d of %d tests passed (%d malformed)\n", passed,tests,invalid); if (passed != tests) exit(1); } From 3ae8fb7371085f7507de6324c391c9953fc638e3 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 16 Dec 2012 13:10:48 +0000 Subject: [PATCH 34/62] Fix a bug uncovered by tests extracted from manual. `null | length` should give 0, and now does. --- builtin.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/builtin.c b/builtin.c index f046e91a..4f9fab59 100644 --- a/builtin.c +++ b/builtin.c @@ -191,6 +191,9 @@ static jv f_length(jv input) { return jv_number(jv_object_length(input)); } else if (jv_get_kind(input) == JV_KIND_STRING) { return jv_number(jv_string_length(input)); + } else if (jv_get_kind(input) == JV_KIND_NULL) { + jv_free(input); + return jv_number(0); } else { return type_error(input, "has no length"); } From b0aa62f2b77b2b97fca3e75030156455381d0df3 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 16 Dec 2012 17:11:40 +0000 Subject: [PATCH 35/62] Improve manpage introduction, add examples to manpage. Closes #19 --- docs/Rakefile | 6 ++++++ docs/content/3.manual/manual.yml | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/docs/Rakefile b/docs/Rakefile index da2d4cf4..375ce408 100644 --- a/docs/Rakefile +++ b/docs/Rakefile @@ -81,6 +81,12 @@ task :manpage do f.puts "### #{entry['title']}\n" f.puts entry['body'] f.puts "" + (entry['examples'] || []).each do |example| + f.puts " jq '#{example['program']}'" + f.puts " #{example['input']}" + f.puts " => #{example['output'].join(", ")}" + f.puts + end end f.puts "" end diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index f0cedf4f..6e8065c6 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -35,6 +35,17 @@ manpage_intro: | `jq` [...] + `jq` can transform JSON in various ways, by selecting, iterating, + reducing and otherwise mangling JSON documents. For instance, + running the command `jq 'map(.price) | add'` will take an array of + JSON objects as input and return the sum of their "price" fields. + + The are described in the [INVOKING JQ] section, they + mostly concern input and output formatting. The is written + in the jq language and specifies how to transform the input + document. + + ## FILTERS sections: - title: Invoking jq From 75421cbfe32ae6428fe08b6ba83f1f7ac0322c33 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 16 Dec 2012 19:46:41 +0000 Subject: [PATCH 36/62] Add the ability to specify input files on the commandline. See #21. --- docs/content/3.manual/manual.yml | 6 +++- main.c | 58 +++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 6e8065c6..5acb212c 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -33,12 +33,16 @@ manpage_intro: | ## SYNOPSIS - `jq` [...] + `jq` [...] [...] `jq` can transform JSON in various ways, by selecting, iterating, reducing and otherwise mangling JSON documents. For instance, running the command `jq 'map(.price) | add'` will take an array of JSON objects as input and return the sum of their "price" fields. + + By default, `jq` reads a stream of JSON objects (whitespace + separated) from `stdin`. One or more may be specified, in + which case `jq` will read input from those instead. The are described in the [INVOKING JQ] section, they mostly concern input and output formatting. The is written diff --git a/main.c b/main.c index 64cb1fd4..252ebd5a 100644 --- a/main.c +++ b/main.c @@ -16,10 +16,11 @@ static const char* progname; static void usage() { fprintf(stderr, "\njq - commandline JSON processor [version %s]\n", JQ_VERSION); - fprintf(stderr, "Usage: %s [options] \n\n", progname); + fprintf(stderr, "Usage: %s [options] [file...]\n\n", progname); fprintf(stderr, "For a description of the command line options and\n"); fprintf(stderr, "how to write jq filters (and why you might want to)\n"); - fprintf(stderr, "see the jq documentation at http://stedolan.github.com/jq\n\n"); + fprintf(stderr, "see the jq manpage, or the online documentation at\n"); + fprintf(stderr, "http://stedolan.github.com/jq\n\n"); exit(1); } @@ -102,14 +103,53 @@ static jv slurp_file(const char* filename) { return data; } +FILE* current_input; +const char** input_filenames; +int ninput_files; +int next_input_idx; +static int read_more(char* buf, size_t size) { + while (!current_input || feof(current_input)) { + if (current_input) { + fclose(current_input); + current_input = 0; + } + if (next_input_idx == ninput_files) { + return 0; + } + if (!strcmp(input_filenames[next_input_idx], "-")) { + current_input = stdin; + } else { + current_input = fopen(input_filenames[next_input_idx], "r"); + } + if (!current_input) { + fprintf(stderr, "%s: %s: %s\n", progname, input_filenames[next_input_idx], strerror(errno)); + } + next_input_idx++; + } + + if (!fgets(buf, sizeof(buf), current_input)) buf[0] = 0; + return 1; +} + int main(int argc, char* argv[]) { if (argc) progname = argv[0]; const char* program = 0; + input_filenames = malloc(sizeof(const char*) * argc); + ninput_files = 0; + int further_args_are_files = 0; for (int i=1; i 0) { @@ -216,7 +256,7 @@ int main(int argc, char* argv[]) { process(slurped); } } - + free(input_filenames); bytecode_free(bc); return 0; } From 04daafbde36ab696069a9df17ff85629574491c4 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Tue, 18 Dec 2012 16:52:47 +0000 Subject: [PATCH 37/62] Add wrappers for malloc/realloc/free. See #43. --- Makefile | 2 +- bytecode.c | 11 ++++++----- compile.c | 20 +++++++++++--------- execute.c | 5 +++-- forkable_stack.h | 10 +++++----- jv.c | 31 ++++++++++++++++--------------- jv_alloc.c | 15 +++++++++++++++ jv_alloc.h | 10 ++++++++++ jv_aux.c | 11 ++++++----- jv_dtoa.c | 7 ++++++- jv_parse.c | 9 +++++---- lexer.l | 12 ++++++++++++ locfile.h | 5 +++-- main.c | 6 ++++-- parser.y | 3 +++ 15 files changed, 106 insertions(+), 51 deletions(-) create mode 100644 jv_alloc.c create mode 100644 jv_alloc.h diff --git a/Makefile b/Makefile index 5dfbb7f9..cbaf5040 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ version.gen.h: VERSION sed 's/.*/#define JQ_VERSION "&"/' $^ > $@ main.c: version.gen.h -JQ_SRC=parser.gen.c lexer.gen.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c +JQ_SRC=parser.gen.c lexer.gen.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c jv_alloc.c jq_test: CFLAGS += -DJQ_DEBUG=1 jq_test: $(JQ_SRC) jq_test.c diff --git a/bytecode.c b/bytecode.c index e66bffbb..39381204 100644 --- a/bytecode.c +++ b/bytecode.c @@ -4,6 +4,7 @@ #include "bytecode.h" #include "opcode.h" +#include "jv_alloc.h" static int bytecode_operation_length(uint16_t* codeptr) { int length = opcode_describe(*codeptr)->length; @@ -72,17 +73,17 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) { } void symbol_table_free(struct symbol_table* syms) { - free(syms->cfunctions); - free(syms); + jv_mem_free(syms->cfunctions); + jv_mem_free(syms); } void bytecode_free(struct bytecode* bc) { - free(bc->code); + jv_mem_free(bc->code); jv_free(bc->constants); for (int i=0; insubfunctions; i++) bytecode_free(bc->subfunctions[i]); if (!bc->parent) symbol_table_free(bc->globals); - free(bc->subfunctions); - free(bc); + jv_mem_free(bc->subfunctions); + jv_mem_free(bc); } diff --git a/compile.c b/compile.c index 3a094721..139b64bc 100644 --- a/compile.c +++ b/compile.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE // for strdup #include #include #include @@ -5,6 +6,7 @@ #include "compile.h" #include "bytecode.h" #include "locfile.h" +#include "jv_alloc.h" /* The intermediate representation for jq filters is as a sequence of @@ -57,7 +59,7 @@ struct inst { }; static inst* inst_new(opcode op) { - inst* i = malloc(sizeof(inst)); + inst* i = jv_mem_alloc(sizeof(inst)); i->next = i->prev = 0; i->op = op; i->bytecode_pos = -1; @@ -70,13 +72,13 @@ static inst* inst_new(opcode op) { } static void inst_free(struct inst* i) { - free(i->symbol); + jv_mem_free(i->symbol); block_free(i->subfn); block_free(i->arglist); if (opcode_describe(i->op)->flags & OP_HAS_CONSTANT) { jv_free(i->imm.constant); } - free(i); + jv_mem_free(i); } static block inst_block(inst* i) { @@ -546,10 +548,10 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { } } if (bc->nsubfunctions) { - bc->subfunctions = malloc(sizeof(struct bytecode*) * bc->nsubfunctions); + bc->subfunctions = jv_mem_alloc(sizeof(struct bytecode*) * bc->nsubfunctions); for (inst* curr = b.first; curr; curr = curr->next) { if (curr->op == CLOSURE_CREATE) { - struct bytecode* subfn = malloc(sizeof(struct bytecode)); + struct bytecode* subfn = jv_mem_alloc(sizeof(struct bytecode)); bc->subfunctions[curr->imm.intval] = subfn; subfn->globals = bc->globals; subfn->parent = bc; @@ -568,7 +570,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { bc->subfunctions = 0; } bc->codelen = pos; - uint16_t* code = malloc(sizeof(uint16_t) * bc->codelen); + uint16_t* code = jv_mem_alloc(sizeof(uint16_t) * bc->codelen); bc->code = code; pos = 0; jv constant_pool = jv_array(); @@ -620,13 +622,13 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) { } int block_compile(block b, struct locfile* locations, struct bytecode** out) { - struct bytecode* bc = malloc(sizeof(struct bytecode)); + struct bytecode* bc = jv_mem_alloc(sizeof(struct bytecode)); bc->parent = 0; bc->nclosures = 0; - bc->globals = malloc(sizeof(struct symbol_table)); + bc->globals = jv_mem_alloc(sizeof(struct symbol_table)); int ncfunc = count_cfunctions(b); bc->globals->ncfunctions = 0; - bc->globals->cfunctions = malloc(sizeof(struct cfunction) * ncfunc); + bc->globals->cfunctions = jv_mem_alloc(sizeof(struct cfunction) * ncfunc); int nerrors = compile(locations, bc, b); assert(bc->globals->ncfunctions == ncfunc); if (nerrors > 0) { diff --git a/execute.c b/execute.c index 8b8036a1..a4719aae 100644 --- a/execute.c +++ b/execute.c @@ -11,6 +11,7 @@ #include "forkable_stack.h" #include "frame_layout.h" +#include "jv_alloc.h" #include "locfile.h" #include "jv.h" #include "jv_aux.h" @@ -33,7 +34,7 @@ int path_push(stackval sv, jv val) { if (pos == pathsize) { int oldpathsize = pathsize; pathsize = oldpathsize ? oldpathsize * 2 : 100; - pathbuf = realloc(pathbuf, sizeof(pathbuf[0]) * pathsize); + pathbuf = jv_mem_realloc(pathbuf, sizeof(pathbuf[0]) * pathsize); for (int i=oldpathsize; i #include #include #include +#include "jv_alloc.h" struct forkable_stack_header { /* distance in bytes between this header and the header @@ -18,7 +18,7 @@ struct forkable_stack { char* stk; // stk+length is just past end of allocated area - // stk = malloc(length) + // stk = jv_mem_alloc(length) int length; // stk+pos is header of top object, or stk+length if empty @@ -40,7 +40,7 @@ static int forkable_stack_empty(struct forkable_stack* s) { } static void forkable_stack_init(struct forkable_stack* s, size_t sz) { - s->stk = malloc(sz); + s->stk = jv_mem_alloc(sz); s->length = sz; s->pos = s->length; s->savedlimit = s->length; @@ -50,7 +50,7 @@ static void forkable_stack_init(struct forkable_stack* s, size_t sz) { static void forkable_stack_free(struct forkable_stack* s) { assert(forkable_stack_empty(s)); assert(s->savedlimit == s->length); - free(s->stk); + jv_mem_free(s->stk); s->stk = 0; } @@ -62,7 +62,7 @@ static void* forkable_stack_push(struct forkable_stack* s, size_t sz_size) { if (curr - size < 0) { int oldlen = s->length; s->length = (size + oldlen + 1024) * 2; - s->stk = realloc(s->stk, s->length); + s->stk = jv_mem_realloc(s->stk, s->length); int shift = s->length - oldlen; memmove(s->stk + shift, s->stk, oldlen); s->pos += shift; diff --git a/jv.c b/jv.c index 77937a8d..abbeb6d4 100644 --- a/jv.c +++ b/jv.c @@ -6,6 +6,7 @@ #include #include +#include "jv_alloc.h" #include "jv.h" /* @@ -86,7 +87,7 @@ jv jv_invalid_with_msg(jv err) { jv x; x.kind = JV_KIND_INVALID; x.val.complex.i[0] = x.val.complex.i[1] = 0; - jvp_invalid* i = malloc(sizeof(jvp_invalid)); + jvp_invalid* i = jv_mem_alloc(sizeof(jvp_invalid)); x.val.complex.ptr = &i->refcnt; i->refcnt.count = 1; i->errmsg = err; @@ -113,7 +114,7 @@ int jv_invalid_has_msg(jv inv) { static void jvp_invalid_free(jv_complex* x) { if (jvp_refcnt_dec(x)) { jv_free(((jvp_invalid*)x->ptr)->errmsg); - free(x->ptr); + jv_mem_free(x->ptr); } } @@ -157,7 +158,7 @@ static jvp_array* jvp_array_ptr(jv_complex* a) { } static jvp_array* jvp_array_alloc(unsigned size) { - jvp_array* a = malloc(sizeof(jvp_array) + sizeof(jv) * size); + jvp_array* a = jv_mem_alloc(sizeof(jvp_array) + sizeof(jv) * size); a->refcnt.count = 1; a->length = 0; a->alloc_length = size; @@ -175,7 +176,7 @@ static void jvp_array_free(jv_complex* a) { for (int i=0; ilength; i++) { jv_free(array->elements[i]); } - free(array); + jv_mem_free(array); } } @@ -371,7 +372,7 @@ static jvp_string* jvp_string_ptr(jv_complex* a) { } static jvp_string* jvp_string_alloc(uint32_t size) { - jvp_string* s = malloc(sizeof(jvp_string) + size + 1); + jvp_string* s = jv_mem_alloc(sizeof(jvp_string) + size + 1); s->refcnt.count = 1; s->alloc_length = size; return s; @@ -389,7 +390,7 @@ static jv_complex jvp_string_new(const char* data, uint32_t length) { static void jvp_string_free(jv_complex* s) { if (jvp_refcnt_dec(s)) { jvp_string* str = jvp_string_ptr(s); - free(str); + jv_mem_free(str); } } @@ -569,17 +570,17 @@ jv jv_string_append_str(jv a, const char* str) { jv jv_string_fmt(const char* fmt, ...) { int size = 1024; while (1) { - char* buf = malloc(size); + char* buf = jv_mem_alloc(size); va_list args; va_start(args, fmt); int n = vsnprintf(buf, size, fmt, args); va_end(args); if (n < size) { jv ret = jv_string_sized(buf, n); - free(buf); + jv_mem_free(buf); return ret; } else { - free(buf); + jv_mem_free(buf); size = n * 2; } } @@ -609,9 +610,9 @@ static jv_complex jvp_object_new(int size) { // size must be a power of two assert(size > 0 && (size & (size - 1)) == 0); - jvp_object* obj = malloc(sizeof(jvp_object) + - sizeof(struct object_slot) * size + - sizeof(int) * (size * 2)); + jvp_object* obj = jv_mem_alloc(sizeof(jvp_object) + + sizeof(struct object_slot) * size + + sizeof(int) * (size * 2)); obj->refcnt.count = 1; for (int i=0; ielements[i].next = i - 1; @@ -711,7 +712,7 @@ static void jvp_object_free(jv_complex* o) { jv_free(slot->value); } } - free(jvp_object_ptr(o)); + jv_mem_free(jvp_object_ptr(o)); } } @@ -730,7 +731,7 @@ static void jvp_object_rehash(jv_complex* object) { new_slot->value = slot->value; } // references are transported, just drop the old table - free(jvp_object_ptr(object)); + jv_mem_free(jvp_object_ptr(object)); *object = new_object; } @@ -1037,4 +1038,4 @@ int jv_contains(jv a, jv b) { jv_free(a); jv_free(b); return r; -} \ No newline at end of file +} diff --git a/jv_alloc.c b/jv_alloc.c new file mode 100644 index 00000000..3e1c8fe7 --- /dev/null +++ b/jv_alloc.c @@ -0,0 +1,15 @@ +#include +#include "jv_alloc.h" + + +void* jv_mem_alloc(size_t sz) { + return malloc(sz); +} + +void jv_mem_free(void* p) { + free(p); +} + +void* jv_mem_realloc(void* p, size_t sz) { + return realloc(p, sz); +} diff --git a/jv_alloc.h b/jv_alloc.h new file mode 100644 index 00000000..0613d587 --- /dev/null +++ b/jv_alloc.h @@ -0,0 +1,10 @@ +#ifndef JV_ALLOC_H +#define JV_ALLOC_H + +#include + +void* jv_mem_alloc(size_t); +void jv_mem_free(void*); +__attribute__((warn_unused_result)) void* jv_mem_realloc(void*, size_t); + +#endif diff --git a/jv_aux.c b/jv_aux.c index 15bc3de7..a4bfddd2 100644 --- a/jv_aux.c +++ b/jv_aux.c @@ -1,6 +1,7 @@ #include "jv_aux.h" #include #include +#include "jv_alloc.h" jv jv_lookup(jv t, jv k) { jv v; @@ -78,7 +79,7 @@ static int string_cmp(const void* pa, const void* pb){ jv jv_keys(jv x) { if (jv_get_kind(x) == JV_KIND_OBJECT) { int nkeys = jv_object_length(jv_copy(x)); - jv* keys = malloc(sizeof(jv) * nkeys); + jv* keys = jv_mem_alloc(sizeof(jv) * nkeys); int kidx = 0; jv_object_foreach(i, x) { keys[kidx++] = jv_object_iter_key(x, i); @@ -88,7 +89,7 @@ jv jv_keys(jv x) { for (int i = 0; ifreelist[k]) { Bigint* v = C->freelist[k]; C->freelist[k] = v->next; - free(v); + FREE(v); } } } diff --git a/jv_parse.c b/jv_parse.c index 738beb94..0d4f1549 100644 --- a/jv_parse.c +++ b/jv_parse.c @@ -5,6 +5,7 @@ #include "jv_dtoa.h" #include "jv_parse.h" #include "jv_unicode.h" +#include "jv_alloc.h" typedef const char* presult; @@ -32,8 +33,8 @@ void jv_parser_free(struct jv_parser* p) { jv_free(p->next); for (int i=0; istackpos; i++) jv_free(p->stack[i]); - free(p->stack); - free(p->tokenbuf); + jv_mem_free(p->stack); + jv_mem_free(p->tokenbuf); jvp_dtoa_context_free(&p->dtoa); } @@ -48,7 +49,7 @@ static void push(struct jv_parser* p, jv v) { assert(p->stackpos <= p->stacklen); if (p->stackpos == p->stacklen) { p->stacklen = p->stacklen * 2 + 10; - p->stack = realloc(p->stack, p->stacklen * sizeof(jv)); + p->stack = jv_mem_realloc(p->stack, p->stacklen * sizeof(jv)); } assert(p->stackpos < p->stacklen); p->stack[p->stackpos++] = v; @@ -142,7 +143,7 @@ static void tokenadd(struct jv_parser* p, char c) { assert(p->tokenpos <= p->tokenlen); if (p->tokenpos == p->tokenlen) { p->tokenlen = p->tokenlen*2 + 256; - p->tokenbuf = realloc(p->tokenbuf, p->tokenlen); + p->tokenbuf = jv_mem_realloc(p->tokenbuf, p->tokenlen); } assert(p->tokenpos < p->tokenlen); p->tokenbuf[p->tokenpos++] = c; diff --git a/lexer.l b/lexer.l index b09ccce4..7090de31 100644 --- a/lexer.l +++ b/lexer.l @@ -1,4 +1,5 @@ %{ +#include "jv_alloc.h" #include "compile.h" struct lexer_param; @@ -25,6 +26,7 @@ struct lexer_param; %} %option noyywrap nounput noinput nodefault +%option noyyalloc noyyrealloc noyyfree %option reentrant %option extra-type="int" %option bison-bridge bison-locations @@ -153,3 +155,13 @@ static int enter(int c, int currstate, yyscan_t yyscanner) { yy_push_state(state, yyscanner); return c; } + +void* yyalloc(size_t sz, void* extra) { + return jv_mem_alloc(sz); +} +void* yyrealloc(void* p, size_t sz, void* extra) { + return jv_mem_realloc(p, sz); +} +void yyfree(void* p, void* extra) { + jv_mem_free(p); +} diff --git a/locfile.h b/locfile.h index 77b1aef1..710cfbd1 100644 --- a/locfile.h +++ b/locfile.h @@ -4,6 +4,7 @@ #include #include #include +#include "jv_alloc.h" typedef struct { int start, end; } location; @@ -24,7 +25,7 @@ static void locfile_init(struct locfile* l, const char* data, int length) { for (int i=0; inlines++; } - l->linemap = malloc(sizeof(int) * (l->nlines + 1)); + l->linemap = jv_mem_alloc(sizeof(int) * (l->nlines + 1)); l->linemap[0] = 0; int line = 1; for (int i=0; ilinemap); + jv_mem_free(l->linemap); } static int locfile_get_line(struct locfile* l, int pos) { diff --git a/main.c b/main.c index 252ebd5a..711d03ad 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,4 @@ +#define _POSIX_SOURCE #include #include #include @@ -10,6 +11,7 @@ #include "locfile.h" #include "parser.h" #include "execute.h" +#include "jv_alloc.h" #include "version.gen.h" static const char* progname; @@ -135,7 +137,7 @@ int main(int argc, char* argv[]) { if (argc) progname = argv[0]; const char* program = 0; - input_filenames = malloc(sizeof(const char*) * argc); + input_filenames = jv_mem_alloc(sizeof(const char*) * argc); ninput_files = 0; int further_args_are_files = 0; for (int i=1; i #include #include "compile.h" +#include "jv_alloc.h" +#define YYMALLOC jv_mem_alloc +#define YYFREE jv_mem_free struct lexer_param; From 8dca3ef10d01fe116d34b2c4768b08e678d180b0 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Tue, 18 Dec 2012 17:01:23 +0000 Subject: [PATCH 38/62] Print an error message and abort in out-of-memory situations. Closes #43. Tested with: ulimit -v 5000 ./jq -n -c 'def f(x): x,f([x,x]); f(0)' --- jv_alloc.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/jv_alloc.c b/jv_alloc.c index 3e1c8fe7..320f16e1 100644 --- a/jv_alloc.c +++ b/jv_alloc.c @@ -1,9 +1,18 @@ #include +#include #include "jv_alloc.h" +static void memory_exhausted() { + fprintf(stderr, "error: cannot allocate memory\n"); + abort(); +} void* jv_mem_alloc(size_t sz) { - return malloc(sz); + void* p = malloc(sz); + if (!p) { + memory_exhausted(); + } + return p; } void jv_mem_free(void* p) { @@ -11,5 +20,9 @@ void jv_mem_free(void* p) { } void* jv_mem_realloc(void* p, size_t sz) { - return realloc(p, sz); + p = realloc(p, sz); + if (!p) { + memory_exhausted(); + } + return p; } From 5968f54f55a157aac934b57a9925e95a8b747221 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Tue, 18 Dec 2012 17:36:24 +0000 Subject: [PATCH 39/62] Fix a bug in stack reallocation during deep recursion. --- execute.c | 6 +++--- forkable_stack.h | 21 ++++++++++++--------- testdata | 5 +++++ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/execute.c b/execute.c index a4719aae..6d0bf727 100644 --- a/execute.c +++ b/execute.c @@ -469,9 +469,9 @@ jv jq_next() { void jq_init(struct bytecode* bc, jv input) { - forkable_stack_init(&data_stk, sizeof(stackval) * 1000); // FIXME: lower this number, see if it breaks - forkable_stack_init(&frame_stk, 10240); // FIXME: lower this number, see if it breaks - forkable_stack_init(&fork_stk, 10240); // FIXME: lower this number, see if it breaks + forkable_stack_init(&data_stk, sizeof(stackval) * 100); + forkable_stack_init(&frame_stk, 1024); + forkable_stack_init(&fork_stk, 1024); stack_push(stackval_root(input)); struct closure top = {bc, -1}; diff --git a/forkable_stack.h b/forkable_stack.h index 041bfac4..c96c132e 100644 --- a/forkable_stack.h +++ b/forkable_stack.h @@ -112,21 +112,24 @@ static void forkable_stack_pop(struct forkable_stack* s) { struct forkable_stack_state { - int prevpos, prevlimit; + // We save the previous pos, savedlimit as + // length-pos, length-savedlimit since these + // values are stable across stack reallocations. + int prev_pos_delta, prev_limit_delta; }; static void forkable_stack_save(struct forkable_stack* s, struct forkable_stack_state* state) { forkable_stack_check(s); - state->prevpos = s->pos; - state->prevlimit = s->savedlimit; + state->prev_pos_delta = s->length - s->pos; + state->prev_limit_delta = s->length - s->savedlimit; if (s->pos < s->savedlimit) s->savedlimit = s->pos; } static void forkable_stack_switch(struct forkable_stack* s, struct forkable_stack_state* state) { forkable_stack_check(s); int curr_pos = s->pos; - s->pos = state->prevpos; - state->prevpos = curr_pos; + s->pos = s->length - state->prev_pos_delta; + state->prev_pos_delta = s->length - curr_pos; int curr_limit = s->savedlimit; if (curr_pos < curr_limit) s->savedlimit = curr_pos; @@ -136,10 +139,10 @@ static void forkable_stack_switch(struct forkable_stack* s, struct forkable_stac static void forkable_stack_restore(struct forkable_stack* s, struct forkable_stack_state* state) { forkable_stack_check(s); - assert(s->savedlimit <= state->prevpos); - assert(s->savedlimit <= state->prevlimit); - s->pos = state->prevpos; - s->savedlimit = state->prevlimit; + assert(s->savedlimit <= s->length - state->prev_pos_delta); + assert(s->savedlimit <= s->length - state->prev_limit_delta); + s->pos = s->length - state->prev_pos_delta; + s->savedlimit = s->length - state->prev_limit_delta; forkable_stack_check(s); } diff --git a/testdata b/testdata index 00ecc69f..a1c72f0d 100644 --- a/testdata +++ b/testdata @@ -311,6 +311,11 @@ def fac: if . == 1 then 1 else . * (. - 1 | fac) end; [.[] | fac] [1,2,3,4] [1,2,6,24] +# test stack overflow and reallocation +# this test is disabled for now, it takes a realllllly long time. +# def f: if length > 1000 then . else .+[1]|f end; f | length +# [] +# 1001 # # Assignment From c85d8d8b4ef210c25f1c3492c7790e0ddbcb2c3b Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 20 Dec 2012 12:16:22 +0000 Subject: [PATCH 40/62] Don't enable coloured output by default on Windows. --- Makefile | 6 +++--- main.c | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index cbaf5040..cd0fb321 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-Wextra -Wall -Wno-missing-field-initializers -Wno-unused-parameter -std=gnu99 -ggdb -Wno-unused-function +CFLAGS=-Wextra -Wall -Wno-missing-field-initializers -Wno-unused-parameter -std=gnu99 -ggdb -Wno-unused-function $(EXTRA_CFLAGS) prefix=/usr/local mandir=$(prefix)/share/man @@ -50,8 +50,8 @@ build/osx64%: CC='i686-apple-darwin10-gcc -m64' # On Debian, you can get windows compilers in the # gcc-mingw-w64-i686 and gcc-mingw-w64-x86-64 packages. -build/win32%: CC='i686-w64-mingw32-gcc -m32' -build/win64%: CC='x86_64-w64-mingw32-gcc -m64' +build/win32%: CC='i686-w64-mingw32-gcc -m32' EXTRA_CFLAGS=-DJQ_DEFAULT_ENABLE_COLOR=0 +build/win64%: CC='x86_64-w64-mingw32-gcc -m64' EXTRA_CFLAGS=-DJQ_DEFAULT_ENABLE_COLOR=0 ALL_BINARIES=$(foreach platform, $(PLATFORMS), $(foreach binary, $(BINARIES), build/$(platform)/$(binary))) diff --git a/main.c b/main.c index 711d03ad..0ab0f3ca 100644 --- a/main.c +++ b/main.c @@ -69,7 +69,12 @@ static void process(jv value) { if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) { fwrite(jv_string_value(result), 1, jv_string_length(jv_copy(result)), stdout); } else { - int dumpopts = isatty(fileno(stdout)) ? JV_PRINT_COLOUR : 0; + int dumpopts; +#ifdef JQ_DEFAULT_ENABLE_COLOR + dumpopts = JQ_DEFAULT_ENABLE_COLOR ? JV_PRINT_COLOUR : 0; +#else + dumpopts = isatty(fileno(stdout)) ? JV_PRINT_COLOUR : 0; +#endif if (!(options & COMPACT_OUTPUT)) dumpopts |= JV_PRINT_PRETTY; if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII; if (options & COLOUR_OUTPUT) dumpopts |= JV_PRINT_COLOUR; From 6a597b41a671941cf5d1a298795ea2c6c545068a Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 20 Dec 2012 12:17:56 +0000 Subject: [PATCH 41/62] Update download page and build system to handle more platforms. --- Makefile | 10 ++++ docs/content/2.download/default.yml | 65 +++++++++++++----------- docs/content/2.download/linux_x86_64/jq | Bin 385542 -> 0 bytes docs/content/2.download/osx_64/jq | Bin 190556 -> 0 bytes docs/templates/index.liquid | 4 +- 5 files changed, 46 insertions(+), 33 deletions(-) delete mode 100755 docs/content/2.download/linux_x86_64/jq delete mode 100755 docs/content/2.download/osx_64/jq diff --git a/Makefile b/Makefile index cd0fb321..30e6d42d 100644 --- a/Makefile +++ b/Makefile @@ -90,3 +90,13 @@ uninstall: rm -vf $(prefix)/bin/jq rm -vf $(mandir)/man1/jq.1 + +www: docs/output www_binaries + +docs/output: + cd docs; rake build + +www_binaries: docs/output binaries + $(foreach platform, $(PLATFORMS), $(foreach binary, $(BINARIES), \ + mkdir -p docs/output/download/$(platform); \ + cp build/$(platform)/$(binary) docs/output/download/$(platform)/$(binary); )) diff --git a/docs/content/2.download/default.yml b/docs/content/2.download/default.yml index 833cac84..f364277b 100644 --- a/docs/content/2.download/default.yml +++ b/docs/content/2.download/default.yml @@ -5,39 +5,46 @@ body: jq is written in C and has no runtime dependencies, so it should be possible to build it for nearly any platform. Prebuilt binaries are - available for Linux (64-bit x86) and OS X. - - * [Download binary for 64-bit Linux](linux_x86_64/jq) - * [Download binary for OS X](osx_64/jq) - (or use [homebrew](http://mxcl.github.com/homebrew/): `brew install jq`) - * [Download source](source/jq.tgz) + available for Linux, OS X and Windows. - The binaries should just run, but you may need to make them - executable first using: + The binaries should just run, but on OS X and Linux you may need + to make them executable first using `chmod +x jq`. - chmod +x jq - jq is licensed under the MIT license. For all of the gory details, read the file `COPYING` in the source distribution. - Arch Linux - ---------- - A PKGBUILD for jq-1.1 is in the - [AUR](https://aur.archlinux.org/packages.php?ID=63849), as well as a - PKGBUILD for the HEAD of master - ([jq-git](https://aur.archlinux.org/packages.php?ID=63850)). + ### Linux + + * Binaries for [64-bit](linux64/jq) or [32-bit](linux32/jq) systems. - You can install jq using [Yaourt](https://wiki.archlinux.org/index.php/Yaourt) - or manually by following instructions on - [Arch Linux's Wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository). + * For Arch users, a PKGBUILD for jq-1.1 is in the + [AUR](https://aur.archlinux.org/packages.php?ID=63849), as + well as a PKGBUILD for the HEAD of master + ([jq-git](https://aur.archlinux.org/packages.php?ID=63850)). + You can install them using + [Yaourt](https://wiki.archlinux.org/index.php/Yaourt) or + manually by following instructions on [Arch Linux's + Wiki](https://wiki.archlinux.org/index.php/Arch_UseRepository). - Hacking on jq - ============= + * Debian/Ubuntu packages are coming Real Soon Now. - If you want to work on jq, grab the source from - [https://github.com/stedolan/jq](https://github.com/stedolan/jq). - + ### OS X + + * `brew install jq` using [homebrew](http://mxcl.github.com/homebrew/) + + * Or, grab prebuilt [64-bit binaries](osx64/jq) or [32-bit + binaries](osx32/jq) + + ### Windows + + * Executables for [64-bit](win64/jq) or [32-bit](win32/jq) + + ### From source on Linux or OS X + + git clone https://github.com/stedolan/jq.git + cd jq + make && sudo make install To build it from a git clone, you'll need to install a few packages first: @@ -48,11 +55,6 @@ body: * [GCC](http://gcc.gnu.org) * [Make](http://www.gnu.org/software/make) - Most of these aren't necessary if you're just trying to compile - jq from the released tarball - that version has the - non-platform-specific build steps already done, so you'll only - need a C compiler and `make` to finish it off. - For Linux systems, these will all be in your system's package manager, and if you do development on the machine they're most likely already installed. @@ -67,9 +69,10 @@ body: jq, and some python scripts generate the UTF8 encoding tables needed for JSON parsing. - Building the documentation - -- + #### Building the documentation jq's documentation is compiled into static HTML using [Bonsai](http://www.tinytree.info). To view the documentation locally, run `rake serve` from the docs/ subdirectory. + + diff --git a/docs/content/2.download/linux_x86_64/jq b/docs/content/2.download/linux_x86_64/jq deleted file mode 100755 index 4395acc175d74f4dcd7b93b484cb999cb70c9ed5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 385542 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

-R6k_YSkWtNO@PN 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 z z>5B4iQ4+r1CdmtII(Yj&v-8|`o`0XB{WHCuj_?u7@E94+^8BwW$)TB@>plM)3Ra)% z_591yb-qm%9I^^NQX5vE*Zt07Xga8H+j(A3M>%(sa`ebWB*%iy|G72lTw3^ra_m2^ z^JLHerGi7}b)U?Te`W23ekWzwW|g)I(sUI0GvhS>AzUkv_6xyV1elxof8{N$csq+Q zSN8wLj=LYA*VBnqQS^-Gy|p z$?;1k!P`@4x3 zuRy5R)0Hm0OU*j7fvUGq{Xo?)vyY3@>;(4<`uiHbS7`nSWVBn2Ywf?l*Gr}n`YNa% zC4G4Imj5Knxqo)zD@J&j+&SCrgj{}F(m&ifb?E#)@-))n)fZH**rrCcv{$P*IoAb@ zPF`=y>z>B-QB=-zYE!%-nh6QaCLVF>{n*{3q7@xBo1N7ICHGtnE0;VwE8XKQaWNzwPGX`Jp zD~_T33**GR_=t+j-;HrM#7U3M1bXZw``EJbbW3!*{iX3git%f}hM5EJ7K6@&=1?PJ zathJ#rXa~gzPy)c#0R|j@=~G^yZScV{1K7|`-3B(s-EbDVl2R*6iFF<@kZPkUJdGr zRvM}>rh}DRLAl;>W(Ga|!-(t7jqQ&nD8+jYcFl<+IE99d4j7F{KiMqo&X;5G$Qk@jlv;RqyH~c0X3~YMSlL{ zNW6>00wg-VhJ-9w>l=r#w%-BXi~OG6&IE)ZLiRT$j#2}UenY8Od4kQJWPjVHqNv>- z6nWn9yqBMBJ-o>N`jdS_<50{S`lLPXhJHdm*c{0!M;h_9YL5JCL54cuVues-NgVaZ zw@z|+S;~=zm!%wecv*@)ysYjbw(eZsF3?1N$&y<0>UgT6zZn5?54qfSjBZ!H4?-^9 zzfiANmqXg2HaG5aN3c3iv$+YI>m7`u9ebt`T7xc)cr{m-M(nUor5{XCsP{)R5N?D^ zM<0Lne`(`?@bJd};Q!~w|CE3)<#U+xKihTg%iadw)UdB{#NcfXcb)r=KB&l-^CKyu zzNTG3A-m3fxlHFxsb|{NUvhlrkD7(MZ2{*HH`O5$4q={g- zD>$0u$hLNTKP(wNRgBx(@%=F6_F@A-f$xW5Ld+_SZ9!AR_rnxMW8Bt`?}sUj#oh!J zz8|JA9^BP9L9p4XAk7mTUtsUPFQ#d=uZSDAe z*ivzDevI4N@%^x#fLx{%Y(e_rnx#F)?my$M?e&Z!baKVz}IaS(Nm?}srY_WNNP9nXG0OoQXTAEv?Jw(}?$ zg5hou5*h^^^h;I+Gnef{au>MVY;;2Y(0V{wjNm_Nuen2ZF@istY>j0xfk1gYHFot(xbFNQ!0 zP`V;s3{)(O5t1|hMlvN}LZ^Z>G6**eFLD|Fnn+jt^+melR^j)WeZ;I%Gaf|2@D%*b zYmGni@E_+_{lLO+jJwNp+LeG5?Dg7%=e?jP7}6O`+{1-8u%g8NbM?5CVyfp-E@@PH!) z4?HY*G6kP+oWP+^tKb7*>lStvpHIQJKkWnyd>2qo_&UEo49R>()hs+x%_66!_?#zI zZ0%F}TQUwNE#a+f02oWg!PyIm76T!Szp)Z;FwU5>tx>n2^!x^+ZlF=$AWJJzVCJ)A ze~#>Hjboc{**l2orDcBxg}*kiUq$w;=N!Ahj(}dl zRBFG{IJWhceH037a0zJ}xRUI*HLweOR@hIV_PNHfRX>w}P&~3j;k*X+xn#fed8b|A zZa}YKGuhuZj;-hO337WskQNu7YJZ#T)%zT~!0~{^)2y~-&na8!yL9HA{*Z7Z%1iH{ z^mobq24NcEdn`?P5sxl-vQP??a9Q&E%0ION?swT11McWllN2CC4|ceUnSf{ z_ypl=gx>?kvB~vy0zTpl?|_ITw%LMqwC-u+Ec(z|cET$duYyRU_%!42C9<>y2`u7x zs*iQ8UEAQ!U(@T~=>Sy>q zCI9P1{cWB^akuJqhMmhzaV zf7xqJzrbmL>`2P3vJ2QlRVY}puzXt*ie>3|3(ecOu>1h>Sn(|x;oHDp9z|gAGQ~(R z@WqpbrT4QwT9e=#5ETFO6}6|wtNL3q$un(OTK+oz@LvIs;Wp{US^nDF3CW)Ug8Lgh zNT&yBZ#WMG_5q{^QERmHv69px^vQsT4bVDsZ-t9nuKHe3GZyGqA6O`)UHA*^_(Exp>7GGo zglNP>wTwL)9q%E@2M+#5{gG_T2M+#xCfl6_s`hw-5hL9Q=6T zaG8}`LAhQ>vz_L&H{z``B>i9lW$1|B^1Sad@EQlLxxG+ei^-zST=QX~_>Y4~cJ>m= znp^2~cT2NzaajVU?FVZYR9y$T*iU*J4Rr>xYiFH{T@xJ*&En&Vnsdn8+48Pl+?CHK zu#1W2&jC}nX0Y@W8>5X7fPE5oL3H{TE)yRU#qJC(8GOuEzkt@yPEv z$#P$2fBCAv$H^$Y52ar5{Wkk$``e=)MW3?>PfKPY-Q}Z%fC2W`bT!?VAiwAx$u6E{ z^S9Vvdfmf}N8tdWkZ~wOCQT4WrZB2)`K-bp$wYP%2c;p-e99eBx>u9Ws)?E=$V&Dn zWN|BQlV>nm#fB3wEW)$7GAgWhym(1=9jVI9eBq7TT1pxU7-B10YYGk8)2r7Bol4>hYuB_9@3naec}W zJ(z$AxaXv5kBbfI28@GHtR+2{0OI_ zp?1>dITej?DjI5Uq(X7RT7*;4PzN&#vN;vSrWW8DGePij6X8@e)XUrfaojNy;Z!s< z*gPe8or!QN8amG6jV8jWXlRJVTTFyg(a`Z0Z!-~2MMEc;ON4)iiEt_!Iy@DPa4H%a zYNm;Pcfwk@@)1;J()0Mk|I!HXU`kF{!z*pjrm@K%L>4WljOuoLlo zn~G6--40~NV&)_>0VNT!WvH>jBS9K7Odi~@w^$Pg9BE-{M3kLuVKlTF(#0zIGx@rs;Q0@zK8s8dYn?wbl>a3aFj zVy1^r-)H-{)+TfLCYB$VXwyTiV=Pr zx_d0scFRi9pJp7xc-Hxa7^#B55e`0>01}2MZU9^Y zd7(%|(27>Gk#AB4M|je~1nFrJ_uLj^EWb%4ni0jAe{M3ZP>6kpCBM;|JC)fno%eBq zyxwFqh&o&prF=04BD%2UUCh$tO1a;#>;vHPDQDx%z6Z3z-a~mYU3k!3jrMQ?aQTF` zj2IodlyEHI4s#l~)88k=nHi4=>;za=Lgt-j42sVrmd*FiiLwhxJ{jCEh_KrLD{elR zfLt6naxlRkuN-5H&Kp>^;|Ec%j-agy$ZcI1~HW_#JPO>%6NJE&);>79b$ zSh`>BZ^nmsX^s3Uw2z%sa~d+L;NMQRgNdHD&x!qP$>lU>zR&RRL1)LreDPkN}hv&fp~VHN>cq)^593P zI5e>|KUI7IR590*-)4VV?dek7;UJ1Hv)MP=-!d^V!%y=kg8=_Zvf1<(sjE)=6PEr8 z&|J}A#UiP#caW#9F7i>%pOjN_Dt%w2QXF@`PZHGN#XrVvFV*?7N~BCdUMUw#fQc8> zEx;{TGN7yQ4jv5^xEu}Z3Ll$T`oC}m{6-a5%3Yu@@mrk0tQH&22lh%f#E~)0XUOk# z-*0Vr3KWxILn&lV6APlBK*ov1V3{r&`vXgrod+^hS+%P&X(7y%7Lw&CE~z-<;o=O%?7Dd2Btaks_rgO4s%~^_e&)@x&H?KgM*-@5}i6?X)8;m<}LxQc+J`xu!3~q_eIh??f?Pw zmQciPKIvqfzM+;p_BoD%ZP0t0=pBbVt(DtE@AbfCqW5;uyPsIDs7<2g2Vk%5#ndw0 z7$c3~jzd^st?2p5X|Bt5-@&dDRT^Nrq!w`R@b;d*ea=Aq2FPHS>ey(rWRQtxFc5 zE+e)s+fA>>1HlvIax``AN72huBn)O~Iqr+6`l#|2aCi8@+Sl8v;a98KF%1<3e}TlS zIK!4Lw7)DrUCKLtP1Cd+?n}={>!`sQeY@p21$2C#p~jDv3-Na3wL>(q4f*HT6o zD-B1J;crpNGP+nPDiXluFywMEWG+zI1+0%%QhFC~7dn>vxvJ=Ce{nk9G-#@xhqB~D zsDxt)YOh2|OO$lIkR<*?u8Z(0rdb&W?Qhvz4D4D_I1LX%6k>Q*CR2hnckd zUH0pTi@TY}DSV(|xy$eJrB($zeI5qT(}DdF7K}Z+n-AH@MhLy5yTsBTf?qj!U|Gn0 z2WA9C;+pFT_K{3?`yP)UapjysnzsNjzTjjuVT$9BIfgV&)IKY+_y^X;%WRGph)!4V z&S4vuQYDmJz&Wxxs}rvLg_ITPAWPiOlEVnQo97sZiwubzbJbVs=vrubj#9vSku_T? z=xt=8f}%%N5HqEMGQ13O_4)@xxLMkd@i)SJO0Ln(yheK?5L?*S;8403NtSBF4X61e zYr)4qU^y39OEF?fm0M(+AJHyhPnysV1#0s?l(n)9L+r1~FxB56{}T{Y99vlXD@wvY zK|5}-rfD4dvqhX!JI+d(37TGQIlTB&-S{20Pg?#uPY^KFRmf#W1gV$e(Jo_I_c{KMB>OPXn&wkNi0(S zgUEbU8KX{mzlj zh8^!@VL*GhhpqZ24T%fI=ho=Ue)hb_AX2AsKZ(dUk*6K&PZE{XU$lk%M?%&csLdOQ z$7NQ;OV0maO!fE3zYhe}pCa)Y5*5c%)&7N&{9oa17;01GK-&QKh@gJ@nC-lFuoRQm zhBGnin*=M*I|ocZHJJK`nEC+nz_y5Y#B`rzIr52??M;w$&q1Z5ji>9gl{H$a%tfUh zaPgLltdAK%VYv_n8=R19t+3+Xuepxy4-0X(Aee5eR~Zs3{0nA zg(}m@`j?gYAV}V^G7B4I%76zDGAn-<89aK*l&B2Hd+^%?$~^BlknD&-HP0&t5!vSa zfyt6?{3{h(9z(_;uGTLXgUfx-fHUP!yu{-7a7~4er_lJSD(icEl z`vH(Z%0@b}Sfx1b!QZPReq+4P8l)^fTFPRPG9M%ywk`2<#(M*hxJfSdxYkY9{Zh+b zr<2X&uVKG9(-=QmZ$9qJGkFj3PB1Iz)(w8+jQF=T<`c*s0b2G1H#k$;d<8|DEyc(7 z*WBu_{uTLceelpb(a^)YjFU6+2XzjQ2fQaCkB?yPqV8sX<5m1-Wt?cK^a;y796O)H z@}SKhV1GGMxwk*mT#8csYx@{$a;wicHLqL3$57r8R|zNUTV*PCQ2_F0+Txw|mve@@ z<>Gzh$l|TGSexTLGBtY-1o+qLA_nq&olqElgqq{|^Yuo8dD8`YBWe2-dx?EM;|yB- zQ-bVXR?v83^4Y`~r+s2tMUwH_SF*=?MW#SJoV4sX>UkH}Aijiw^0Eg=|DNEhfTi9k z2=%_lPOvIk{g|K*FWD-id#{Rn+rd&%V~Y>j-?F{b@tU~zHFexed9MpD!Oo&KjNlcP z_-^}a-t<)uK>jHps5rK;>q#il#VWXV`IMuN`4U;CPOn`Th2N}!t081JlQP8T3WH42o&>JA?GQJ~T8Xi0A+b^Y0So*7C6EcbSOy zlS%lW63%`-xGW}*9|hQmEqU9 ztVuGek%VGoBQJwe`k1#!Fi<-I7m3$?PJjX14dC3BXw({!fi5D&V!MMe2@uIp`<@L@ zo7WJ5tN){7F16y!asKK<$gfQ{UjKg~A;YUy*S0hnzELH6wlstlxuEUT>_Q$Q|;<&BB4`GSPh|C26vzu&xkvTJ4B*TPerC7Nk5q* z?362}pInfS$^}_hg9~YwWY_f*UAskBKZe%qQ5)pq*=rk)Ry_qv)n|Gc)Qr0b4eOy* z@2dRK-xD7HeT&F^j0UV#-{a`2cQ7_&IbsJ9IwPu#{+p1Hc5y6KExXrqK~nny5-%gs^-Uyjr?Hyad;!?* zSCzf!H~lr=`Ko_G{>oIefny76v*Os3j*_kgNU*2t8bAUgOV^2AX2qRo#nrYz`M)Xa z23wMFC7n=Gh?Dqgdm}M|i4%}miG=+py#%8pwUFjzFur}vv#hq0wH93T-~KZpOizG& zDlXn)+^9}&r~^ExbU-gYk|5+`Y!j}C{-Nv_STXE+Pm%8G%ygP#$II;z7t=;HJB`2o zrK~$a_$9<@{kLh*EtkH7s-0xeo@-;K_o;SL;jJ?;MBuAt(_SQu19pDzkAp2+N5xL- z)W22xHqa$X)bDIJvMz?-4#di50X33~@AxQ$_A&ctMo6DvJ2{7}yo*4xj`A>o2swGu zTA2&uU$s+-GI_C^EH8F{rd)Y&*T?i?s66eL#+4O5wuoMhqd_yv3cD_aGOt6nbxL% z7991jxp8s-WJzHDeJoXN6-v&9(%KG4Y+<4&5TMzNQ^*YG!k8#A%RQ78c~sL zRMi#sw{|qjuLWU6sm&SfN+zRZCrUI>e9+d%oXd-~Km+9h^sx=pcc9HL*FY5<9jF4C zj$hH(4wXoS$W*&VCtYM*BJ&hz^ol7G5x)WJQ@%dt-6F8%=sOLk^vr%2~{8CXHVWiJ##|+K^2ZY*WO+$yn_?2RqkMnJsCxG zQ4x+cE2JXkLqv-T1P47?mj)5Ih8@s0LlPLf+8R5knv-5!2tCB!#xdjCYRwo2}y+$al)e+r*|iL%y>4_k5f!{)1Ft}BoXWwlfr5(&L{SsXb>>T3h2ah z70hHJ-Ya_Ia-Py328{wW+<%1bZ`QG;6V%TN+ys)J=svE!&8{=`daY--@~xO)N-Oo^ z|5h%3L`D*Iz2W^&)PfP^Vv>KM4Zw^AeQQMX3wg%g8Vs81w~ZI`mof?H_aJThO444d zX=HD#2AUVhJ{@n}8_Q(3_4IZw*>5N#+eGdc{f=ikN76Fzh-p#>9!+I#+%H-Lnr71B z!%ED|8QATr#|6MGU;G|{XxUub!FCr2_UsPC*h@YvT0YD*UKd7fS+Z8kGb#FOp7hsO z;YmdXe5h=OQC<=f$0Jek^D&gQO;K_#O7ISW0p4dNR7I?$XZ#OQQUYbyP*Nu(4pP#w zl(mCV(k2gG%Sa^7Mgov^;6#nI3pCC1{^}*jzX2rGbC8JUL)@`cwJTAw3?;Q|k$4n| zL1V%g8s7%=J<)2Sdx1_Y0MVmJtV2Tn4c)^4*K|f0GuRl14vYhLAs+fW>#LT@VZGQ6 zZj&V#ebzPaGhElF4)r6~4A=Fk3cRgpm?*(HJPOt=wkM+Nmt!^1BwAPpXUkOmj~owT#{}&6mFSVkM*m?ogB!UEEiIGRqd#=Izaxk-5v%_exvk>kN* zjvNmjbL4pNm?Ou7#~e8xJp74XIdVLB%#q{4p_ty&o~Mi#@uL|A?E=r>E`~%Fcm{WC zbaa7d@G%XJF7OQQt(P$K$ngbW(8FToC?)zOhbAzW?L%@8y4-B!{u>~DJp>&6N%jov z*6sjXq5)iQUKC>p&qU=L;nDRW5J%@DQi13!%8c&DC6N?84}|s`;lAwOQILt<+9M(3 z|GZnfCrUE0TbnCPvv}H|FPBLyD$K&cX3Z`UpLmusMcCciXCax5-P#Z0w~_AFmZa|1 zz6`l=Lw0LtVz>4IV7ptJu28b>*1kqi*lR4iwI2maorEiUU{Vqfhe)eIIw`~?S!Q&c z> znZDLgyX!-vY1)V4;r3pTG@WoZo_t2^jX!Z z7d|tk-3GjLiinr9GA}ny^ko@J{VpW7!BtL2FQ6DQ-nW6YV0_x;vXR4k%A*m&*ka|9#o(?6LGRc(gBet-GgpqRaA7mhVml}LF z(=#8_QI0fAtI_d13?*z8Uy|fOka%SyqALGF`}-b9ia)0v-*7?m+axM?goV(RJxd7#-Stqlkw#iUo zs%cMwab&Hs)aH_M|=UT1wsFgehcrZ4}igaxh_G^LpwJ7-2U1sUPh&AWFUJe()EY!YIf1Q}Aj6w$(7m zZE0E!Eo;ZCCmUs0TMj5UOhR!oh#eS6SC62Q+f~lhR?h8|(|#g4piOK;?Zv~*l9ZOU zg~?WzfVw>_+Dct*I-JTj^BBY2;V;U3qDHcRDn|NQrUi=o|0UjIv)u~vj53B-fve_V zu~y1SsH_!uqR;9cB|*QU%2wZX$VT;@Ypbu5babbR6l{lID2L-=VK%iq1)gRz5WCI{ z%NY{9am}&It3C3bvMp;P()i$37k)-Pvjt`(Cn9k?6aA3*4T)w9f9-huscvb!QV*_w z8o_(=dB`zmc4Oms%?jg@?Wpm^DDLt!^3z+RS(gpXR+%s2joQGR11RbGBT%ycLf429-)2#W?S4D*Yhs`npQlRe zkZTgAOBM14lYKR{w*$HgsJ0sttE!P0fW((bl=7_ea}ea(laaHjEjXe?X8~2U1K|`T z9zdd5g4y$dhPQ_s=!#y-SCzR1`dfP`3ioIs3A7cm0;LtEd+Ds>jwXjKVS%;;*8(cb zRYr0L;~kIrOO-4*TOgPE%gED9eSuu+fsV%Ow3Y4dJj2@-_6uLoL)yhcX&1F9FPm(e zR+CZ{+#EtX$u5w^w(%TT=#>vG)6%9^eNTBNu+}xNMKm`|O&ir*XQrD$T>@1XH<-Io z%zX`cUh5N&^YFdBD^Zrtwwd5`Eqn(Dz{Vul{e5cKH=L4P1PaT-319uEG7IQWe03iRm_Nj}{Q=+mu$0k(Vp8)vds0)dn} z@S7xKh!JMh=_=(m?hM@P@*H#{2LaJ{f&}pvl=t zVo>M>xCJVZ^B^grfu_IWH<@GPKrWM@NS^2gn*A;5u$L01h)7rb$$;ck8fUz~Ux-v7 z?@fTTXdvDNCFvY92Z|)gF>|1p^l)3o%%NDI;B4S9&&dlE(lu)004Gp_XAVGNyfB>W z1xgb@aDVc}_)Yo-VKzx4%Rt}--b61LT-6)Afzi0_2CrZ;8cqq{LIEae0xB-h1Amg* zK8T!5xBc-#7@Nh}E4Dw<5ope`+aGTvXGu8AZhur5&9d7c6~?mYC$>K-jAz;Hj|wZZ z?Dj{6)me7?qr#djyZupNBC8J+V*8`QfmwF@qr$o@zU>Va+tN{4cKhSwu-{iQCTj_K z%gxgQCuG^}kLuBkEW7kz!>jkefS$6xQ;*BQjDwYqijBhmkq@v{9$g|;^eqIzSYT?|RMsuEedH9B5+ z3nf0L!3l@|ZUnSfgAqk5UJizoFq=h$t%ZI`TV^iXhva_eaiMHqZ>nv?4_dlHm54#4#^FW4UECv;(Nf-esPnq-nr!nY#w0x@Wnm=Kls57_HI>zrvQ8ot8=F$rrR+?aJz5G` zjg6Br(8}74!e=N8?l-3U$+b>aW6EktD6$$;Rz09sP(`~6jTwxdB&Msz=zG(B)KN%_ za6W-4B!6re667r8sEvmj8FI%lIxeERxQx7tnJnr-u_cm=D3wx9T!z7Aqrq2P6k&NK zvu#78IB6sqUSrxKt#7)^EcBZFMT6>%bN2MM8o+h%Vmf;Bygn#p;-6hHZ^5Lto^IeJ zQU0evGE!ARHw1u-q7|M4mD&eaI9N{y{|TVW^2X9!9(hnkpO-;CMs-V`Q{Ck= zFfhnPzgvOn%ekzYNO%0HWF>rCsWjU_VwOa}SjBUrhJ&E$b0p?5@c|OoBhmbIBrwNX z)ZzfhTP8#2Ze+L2LSkqSBzU~k93)z`6?0ZEZp9CL;T46oq-8$xzXCz)y;Z9Bp%(hv zvO7vLdSZ&nYptctJ<4(3*81BT?&7p@vq~yB0jk#BY*EP8TRTR>+(Cj85VZczmcLr9BFKIxOD`llFU&vC zuB2747Nn`9dX48G-QGM<3R!!NYZFgc9q)tn4G^$7>^-VENH;jN7it;J=1EHSufe%g z9ZYT+Bt36P?4-DH%yN)(1Vm}iA0_R1+F90HrM;li4lUvik{6XO;dSIdD(MdP#m01$ zdEA`}yjPpC`#Yf+y{JC-zN5kpr0f9d-c2U~(rdR~9hNNDu4=kBnIhYH)L3`441Q-cZTS&)& z`1uKqE~LZ3kPZh!I&ci>z%e}>!C85vk&z92Du7Rs@BrjxL~x8920v0B2)v7m#Bi?y ztt>NaTH>Qp81djTZD~$rY6w%z^MY^T4{zcUDBM;@u;?sgG+M;QZ~#+J#Et2e=Aby4 zGHymSo|4#5d4PC>?2sC$&HUJY?Q)P>y9)AbOdc)a^E9q zE7h&>s1b1s&d8%vpR6fp>~?Hp+K6*9HiN3kDvVWqZJE(TcWk4z zdrfr5_UDL@m*bujBT0^*8#Giutc4%g& zsv@W0@eaK}fcJYas8dh_bDC)S1UU@MX#oZ%+#l#{qTfM13`hcVMu34?p%9)cF2jYH zJCBIM6hwRm_2A9o}p#1@vjbCWzF<*Zh?E|>Y!Av zGyYFoineo?_2HTzqcsI0VzUt5Yl18=!(&+IeoYX$o;iunwATh1yepAGy^5YDLN~Wg z=zb@0B+S3@5xf*02#Ic|v$&%M@YF%Z<9(Yg>wyrJZ$b{+(gPs|@Oh#cc+ZVOsQd~r z_gp+@eMn&OV9KAz>tdJ6cXBs&Qu+Nr@vD`;TjVc2PUY_w`L`2cAfxDAAU>vlT%?x| z0jfv4*%M-QouLr5srW_WnMACv+T(#{H4v{;*g*UdaM5%IVs8jzFfV}Kx9A%hu6Q;u zYg^I31RQQr@!X*0% zP#U_la0zIaFnjtIbua@LU#;9~P5?qBUPtYlXluI9$mMRePUzeVo}(dy?oF#bU3#B? zBBv=DC=kkjp;Xus6*L@A7(`{JkHY2wdIjU!p~`Ozh!1kYeohw>X>8_& zBVaTn03kxXf!NLU7IZcdtWtC%5neX+PGcYPI*=EiN?moT%jwALqTz~+G~N=ct4?%n zMov?-rn)p*%*fQ|<;(%GM-Is7;ZD$ptZEH$2U3J_{UQ9TgnhQCS~^uh7pq@k=s zN$xzbDSSmB_!K6gz2?pXqr&clsJq|gj(4LVuqymSAzW76>@?_{4^axuDY^6O8wz`% zFn2x#YvEZ6(Mv0SjTp`154nNnpYE>XzkIa_%m`pM6Gbb5yn=~r+h1s`T#UNeSlvSk zJe*~$zLZ$~h8#8wAjC5N3|I>GuWfX^_-}05@8EcQTsuz6iCs1F=YaYrEA3smPY*j& zBmb`4r&ka`nxfx;*qgsEWg|xeLGK50-@TlOu~+y{f#6gaAA{2QDE(0G@O>2`f{M=( z3~Gg!DQqadTQC%B@qR$<8b9(ggv~ITWPlaT=h(6&pZBw3pK*>}U>&{(rR{NRWB5um ze8}M&#}Wxxbv?M_8yPZeKxfDtXTNS5vhkq!!b%t{67EM1gEUwq{F?}eH=+#Haq?Io z_^s$XAcky+l-)!mBYnkB5Tiw&AT4sxIM+~4l!h_|m|iNng{U6m;*p~CX+ST24X?4Y zw5FZ8UUxP7cTilOrjFN3O@DT_nq4oonLi!~R}#u#_T@k#ew-A3ML44)me~m`K1U$5 zD_%kjx6T&c7l86+RD*iF|3+xUGVy(CgD0Z^=Eoh^#O!_()$C+AR#I~Lc zh^km2&2^q26e_%4AX=xwhNuhiU4pMpN){1|Bc!O&?N+~GhoD2)f} z0$^~GG>Ez6Ei*mY`a1ZGZ6ids?pNw*sM7butmfthr1H#5M$HOan zI#5PLRlKVWl;Kd-EOh4sWprA_QPDsd715=^VcL)n?`^6cW6$GcG}P*P%GGrKxQ6Wf zaUgcN6S3ITQM1dk`G}BB;T~^OjBrB|=GZjHx-N-pPLr)R9v0R*%=DGvHnOqvg>dV0 zh`$ZDZcp=m47Zt1g96Do7HuEnot-T4cCGG(Q+uH%v2hwL*{%Y$6vZhK-7!RSbH?P0l4f<^!P# zDY|$z3iN`zmo#RX{~m zENzy|%f-7GrDu(U(~3)gWl*P(PwxPs+v0i8$-O8qnOFI_WQLQ9mS4gF2|k*@pCEd2io!~^8Xe2=kXTbNq_L^ zkYS43v5PMlq@dGa{WZU*^afe`3sB};gCWdJB*rr_9*L)z;OCID|A9mu5`&oNkHkJC zDvp)bVL3`Jxe9lae;{$y)kxfk#CJ?=LZb2-B(@=O91?iJ#2bLKB#Jw>IV1HBTJsU| zmx84ITS)9<;w2;+U5iH?36OR866g$|4*x-72@^c=_f{q%NW8}c&+<*IrJBy{;M)&Z zhflQ8HyLT|>yUpNNZR*9;s6u1NW|75QH{iKBr1;O>u?%M{y<3wo+|S`T4IOkNDRFm ziSv-Sk%>!?XnX?_YmgYj#EmSv5s58G6x@WwgGgM<#A8UjxgLqQl)@3}Q%y2J-Y5$)0nT=yDZqUW6anCAgGs#+g9Xo;#Mznv6q23lO31FOE2jbgBK5GJcV7ZGeIY4V2vzh`|iNMvjLLl!CtI|#d`+orz^Sd1^hHYbR1KvW3iq{cOXMXJ$C0EH*@?qdEa+|zQu6?ud6S&K<`)sN%0t z%wAm4e>UUVf1ai(9&jh{>xc0p#1|gM^>+bZdKhm7=3U@^F>LhRMCi5@cDff3Hw8s0 z+lbIoE#69eIwfoQufVxe;iSUr9w3C13Qv0wkasnOcM5DM9rzGrtz?h$ zfY@~h@fi%b;`nxOqnm$FO8)^=w3wya1;6qzN-@%UIF0>w+Z{k?9*;=#7%m7ND!k|s zuu4~}_)*~8sZ+4=Sn=GQ#1jy1#kW5SJj|g%yMcHs-XU{;xRNN0ZZ;nG; z{g}%a9*;^J^BxB=&@O4idj%o33jclrZ|Qo{qsK*Zp=`7IG5vyiZNY`BS+*u)`gn`C zGw!Q0Mml^pV^^LrX{;?@N&0rt&n79>-oHikdW#F+CjVy{uTHS^9}~ZyakImJ6E}-a zvh=vXKB9(+QF*N6E-d$s>DRr+8;ciGyuc<#If%OBNn8=Ago#l;Ci$KS6*Mu*t8Mwy zhy)@$Im&BoD-qh9qTFXRN>hYyK2VWdcTn(}Xwl z93?ftv4D9T#c8Q;OC01bu@1EI_h< z%nQmErQ<@n-jU+N!|O?ULhwN$jqkIhR{(Yy&Z;>v_=*&bIkL!m1^t=NTMl0PQqNTC zOFeIzwQ+|2Ca~^MHnaHt_nTS#t0tlvWHXCjH?xG3!dD>6o`oK&MSZ><$i&H_u#3xo z0u7s2!d(6n$T7<)p(GsU@}EG=!l*3R2sE`Y7UuGwK(2-HFqi)Xnps#G=HiGzo`uz6 zF8>MSTUZn3@}EF~g^6$<0~oh(V3^B)0!0?qh1XC~v4x|;YiMLC-a^sHG2tcTEjOD4 zP6%`PPoQD*N|?)k0u7s2!d(6nXxO|G#+}j&9NxSV=JKDw;ms>yF8>L1Fn2*Vm;Z$0 zq_44?S(ckHm;VF~Z(a#=`A=Z5xrE`y3jXlr#K&2@(S*7DCosg~EhcmlV$;}4s+W_gL%`in!WRhej zjcd>k+lGw?2-9I%lxuU7$Ztku%EAxqQ z7TRll8#IhYHO53sOS1ey8)Wfv%jJOW_Mv;_N|Wgz!%CBlFRQL>Ic2OhNhZGtkEL=* zBbAfkrBiGwgLtva{M*Y(M=b??*C7XzUQ|ixvjKAs!N_3t16uOZ5hc00PJxZam|R__ zpuoEU&lG*$x9D1JmsSh$r{KzuTlWT>r-J5p0inL@XM^(V$^*Z?*Z1ptefPx&eZBvG z{&0jYZfxk%g8!ZUc|Kk2xD9%Bs~*1fun^A3Ry{0sWX!qL!7g@OCor7C-VWb-P#8_I ziyallQrO#tj^3(=Z#`&fWeR&ceCt7Bb&6f=sIVr*E_PIyNMUamI(n;K=;*C_p`*9z z;ad-n!hTtL$0r0%NU@6@)uS0HcCn+v*(vPpLJhrL3VS;&cI*#NxY#kpE_NI) zc&SOTiyfbZ?1rs+SnT+gV7pZhiyhAw`qd`IE_S?D@H&&i-VWb-P`uHk*u{>Dx0n?6 zcKFtV;%z2{y&V=iy53H<>fu`tw4RF{Q|w~L_eDQ?JK3st_*)DNiTxIXM#q!S4u&4n z;J9xwP#jOQ4~H)XLpaQ4A$ttym#pq)F58FX^6R{k%dL7p0LWIoj6ibR;keMF{i`rZ z^hGa3vtJU3rV@pt&k#kUm+>baeT6@Jyy#c_U1Fks5`m`%zb1MQa(&T{@i!1HM-IMW za4V)#;dZQ+jDSC79o77g_5k{`M}s#r>~Fjizp@9=fAkky{W-UiBIN(dbOb$&5BZepYlH(%DVqGp^BDplKZaM+hcF>+m-x8i$0K=ldM9=9FZbEgxTv zgk#_hhq>7<$F#xUSi>J=Ga9M#@zqGm6cozGS0fSKQm7wajij>8VZ0?DUyY>Ec{bQo z`S@xi^BS@phdXy9i%A4jKE4`}dmq@Kr6clF+c)vNx=4OG9i4(E6)9knwk7L`f@vZ-Oh zVhA$BHil%fKuBU{CIMv8OmJ(f32OH;sNJq5XzixNw%+!(C1~wVu*635 zf4%*GpL5Rho;R6j?eE^+|K}HR<~h$f=Q+=L&a<8Ko|&N!JZ?dl9Wj-DklCGFG-@N& zO`oeu3r0n$G(-2hVblt2@JGyCpz3Z0Lu4yb(uAcXtdt)D-2VfwW8}!8x1&z|s^>@* zyh&LoPvFuJ$K8PMgcv!j4DIwMMn?rdMt$ho+o+)gQXjhZHcIxW(hbf<1bhzvD?1+Q zTv~<3_{1ooE*>&E@5gw5(@%_!9+JUot51xMzDO^O{>13$APey6$xxzxpBNo&xYwT; z9X*^hfIl%hy5A>8N2|2Povc4GI(n2Awf@BD=zgCV9o_E}qoezMVsvz9FXrG*R-YIh zed)iVpgu8*4~Wis5$xxzgntR-wBgmw`2b#rK5-9JC@`JE%*1baATA*PmHLh5!A9P`1T7qA8E9OJ zc}^xlK4@sTrZSK-#2tC-k$ zL+q(<^(XcY`V6g@tz^QK?l+x21B&#`{nK}$h0>lboQ1BXsazM}MkNVN@NZ~LACI|8 zeZ=TG(|qPqvWIt4iO$UP?`_eozhmBK#fjP?TB#4e6u|4%g;xQQulNbjNAoUI3zAPF zcV-8cP;IHI<$*a3{2uz#FBDw)Fp(@Jk~!bTlKn4Lq?&ms&Z6_dKpBy%N3r1B@H^kY zFoj6^S5cp@16xEB`JkED*Ufui^%1n2GZZhsK^raSXOen8KQZrt+vd=s#lC~jR_WC$ zqO~29(#;CZd!Y6;qD4*LN3(6!!u$4?S!(NoOBc8xf=)BlXS;Tj zhrxl-=KN<(@3iSXSKWW#J0259eXNLVh}(RZ`PkQv%MMd-MAe*ycnN$r;LM?~pP3H8 znfH6ste{OZ^a(UBRG)7+KwPY%M)_RHmKGy(PQwz;2aQf$2wy4^&=LJD23^ZDfrFxMW}~IG$7=9Q6Nwn3ZObT(J2iTLY_k} zMmx-n-l*TOP(X|xF#=>RqISbaX_^<6h893&MtHR&sCJ~OMNg_7#SB0a(?FkMP(aaA zt#f98*5y$6F(DuJ63~#EYoZYv=c~)L^pT=~x@m|^1+*m5!nc--(Z!Jc_#w==8tl?> z{fZOpD6nb6Cng1#?=@5tzQPQt>fTWhSUgh8bo$8BP(Bu!rhVl_K0)V?$C^$oz-TlH zYDVjELy#IyLPNu{iv^l&`%!Vqe2^&(%^&Gv-c$V)^3@ck+1{`SZhSdbbOsf8rLVF* z?Z`823!*;DSH#Fyj|i++49*7L$6&z~fjNr($cU(70nvR_De`7WNaO$vlxE3J3*~W2h&~qXD65E&fTI!n$@|o>lkHCo6Mg5h2JuB{LW(xJC95J&Ld>anyBRZokyM>0sg}8Jl@o2uv3}f`2?k2 zm)TL^FT90O#?C(B3ZsI`iN1q;!j)b_wSwF*-><6^jixJIos^|sN>|xyka}T`%4=9{ zo9fe8)J|i&oNkF(wVyEnsnqu>%LD2BOv@h?XZdvuo`W62Z0!dMe8Z!4p?}VH+#)~P zD6^W|9Djwiin)HYU-{u}JX6DL=bQNqaJ$$e`n?+N_p`U88C_>>gNh5N$X@uJeuCP! zTyKfN_t?JhIw*JniM);?L;ks+*U@Aao1SW=Z!kSoVabR9+3wO2a7D|kaW7|(T+|A7 z*f-L0l*6OIL#udo6FcUcwVx?vf4tIqHRUI`6TF0vhSG0%3+?4s8z!N|q-twy@h!ZF z-%15r=@2%hi`WBDti{LJO>&{e9ct~0tXEotrQ$G7NpNY6I*+g!%}ATkjPg{)DuGh1 z(RSTvE*Ep=lf#+M7&|*^@c)X3^o#qSlTqabrmHjur#&S1OS5faf|V_@ss1a#e(rK> zb=VP;L+qDLS!1Vc%9n$%esNH(2O{jFtme`~q8zqR07 z)NH0b#vcbM!S<3x{2&So8{v{yI!~|kSZ_e(TE>}<@KR)t<9X&vB?iljNiDpQE~6z! zu+$ixK9irLKgSWZT5a$)*z(vFK0_qCX(fwp!>* zwy8NjNXb*7qDr_qNc^3EX|%|Ud$paR9Sp(KqmBtt5H$%TeQys6G!zArB2%NXiaEAG z4r{Kj2o~pYh(IFF0w&h`rQ@^!2#4BYkc8{h9qBja^zY=*frMMPSlHh{DBy9T3kFK8 zsV(v~RJyZRTjLG=eS=-$CAPw!4=lCl{#h?lZ>w=ukjt%fb(p2(+tV(8uvE^%CgB5g z=Vr4YMt2ZI6%|ul=?#uD!^`Dn(vo{;h z&gN3>Y$ou={j&ba_CJzeYa{YBMa6xJ9~@46&H~wiT{(6YCa93B@KV4jKHG%(P=0NE z8d=jct8o6jly>JlC|b>6XXD$O^InzmYfnSfzMPHyYM&9|NJeGYG$!1GHb>fqTeP1l zcI@2Rw#A;EoQ}$y^_GLG9vA(r z7|+Snl#RbeKJ5*JzIK0(qXItG!QPxTPkSBY+QekoKZ0KX{)}6>$5pdNR>VGje@n;zWx9|h<6MqhZTgq%jIR5kJAeXRz2(f?2)&3#ROGcFI9y<+Q zYMh5tLL1*dLAlgAKI>cz4y%i7B+s0FayrVZXqVP^v`3~lF!QjsOSO~O%sJOE{)D&a zriheO+awZFItt>gx!tg+eK>E<6Z6ni_Ld8*WaX)OOp}A?NU#LNt8T zXL|B>+t_9?842%WiKi0IU>33e^Sg}xCPgm8IC34Hm--R^Ehfc*dno7m>Qo&&*=f+- z;r(@YM1S4=JCWLI_QiTn@z0Cb#5ch4@mGRsUTB1I_kxrwtGHshBe)|NV8=p1Rw9mJQkf@SNZf2A+-C;7R9Uz8vOS(~sN} z`g!I_8xAs0LlYYUKR0A=dSieo!!UIwQSA8u>&?`%lnhd#+}xr9hm!$bU7W}JSOWPQ zvf2QNEd#3#=Tc@^vitf4jHeqyz5n8?TM#fGP1_Dv+KN;ob4@E12lzlGXXXCb#^wFLsS*E?*FZ= zi2p$3zx8m7Hyh*p`M`K9ZB|8ERBTXKtH?ekK$u3!$l5Q{3eoRm!>*O@bb}i6`NjZ^ zWQS+GLcZn0Qlf(|Z&NbKE+~=p=NsTq9eok!gC2f)n$~X%1lMNFu%7~wYxCvVGp*LK z&CN2>0q@8<3}31+TW7((M*?tYq`Nr&A85IFjL1SYCmFm8>Yr!WdB0V@VYy(3#(ojP zTHwzb)Wb!+RT{*Z`CF1au{ohV3bG5oP}o_~>OuOvHGv_%g|XSgYd$o@W%|MFQ-vCdY;Zr#(Ku)>6poB_2YA#E88K-*gR$?kjF(%p)vj) zJDn!`jL`SA&2MHHMmxtVX~kHhd`Y}MPxi(`0* zj!0ApzQ*YDTWf6pwG~!rNC}4YSG_^*l~{$B9wn7C4l|UDI?)XilD8?2U?m>OYDTs( z%0BQJt#uT6Fix$s!trspBG30pKu_zcAr5Ud6je=Lf8p>`3*3&i>Nw8t{ghl)Y-jxi z9kPE87gU71;c#J!q|J&0ZwVBQ%Z-*98dun&4jTQts8zete>B1&V?bb0LBs5>zzgNZ zr0j+lUv6x*WQr#U4g`up+(#KKKA2}J$_7|*DNFYF)%M33G6wGVL>b#wzf5&wJ|f5X z8bP;G4BObe^0X050IGphNU`ksGqO3{h8~;F^;wWoj(KdC`nC#0q>jh^d&+CIpsEGL+KaalYOlMpk4T zF%i3zYT3_{4Vk*P2&pU;(lHLI*uwmGUU%amAX;yQl;8)ReQ8JZKXBcRPst!Yn)js~ zYbW#Emh7*Nx`5vzQ?pw9Jt|TuE^gSchX-pmM}uEKA59}b>;%| z?H72-)u~HwBnjSf8&+`0PSmK$d}VRCdX*hqX-DQdmqLDlz<(h53gC}C2mTeN5-o-G zja3b)>UiO<1=q%|oj<#wzA?3Hc5P#-a9e#c;ix7J_1g+-tE#e_%rCf>`|Fm57`_9t zsj8;FAzo02p`1jry1r>HU<}$^*^-F26x7BW3#zEjly?)nz13@99j^h5YpBWH&GCfp zs>lGuM;^dYeUk=(t!$~)jf=OX>Kl@?>l+slxu)i-rfS1NRnyL9kDrG4F2jOi4=&Dq zYV-}%#SwD@VaFX32u6Z3-M7)5eu)_EUKbF_!$Vy0b;q3^5Zhz~mpwPjOMsbD18}80 zQzvhg9lat~o(co|4%7uil{^FZ3Tja;Uk7;kVSqLAlIx==T&CJ=$Ey$rN636Ja^;XA z;`t#e^c;X z3chzFwf}R1+IK1V4+{REg3l@VaRvWG!ABMReFYy^@Ds_1Ou2hQq7CnW3PbM9+~3G! zZgpNt{gLciMXPL2i4hUmLk;k6Rj!;byEE?0P}sdWSC*Uw17~GT=p}c?rH@5x%V$Qn zrp0R6F6PVP5;3|!c8lrq@F6)d`pD_77eu&ITvaUAMa1>(vgG7@Wntz4(ON8WkBXiH z@{(pTtXMqnv@aEVlFM3CDUnJpkI9Y=4DofIpeuvNWbJmfxT0;P70HSygSs$XM*1mBTm#R z_;~PKciExZ`C`~%jQ-k&>+gy6iQ(;H_zCx#Jk=tCS69{qk6~KxZIKaK7L{e2Q}uxjk2WXTLlpo(i~61OgauGx12hz>nMea`Or?9GS__b7Z?ad8~U?NKSiBYS+*n>^&_;ysp;8q?zS(3S1}Em)V;Ap5l9A4r`JAIw$Lri z?O7ylKP<-7xHHC!I(P)A_>6WjHsVeViSO@f7mp8(h~4e?iP1IqSvR<-GivM}g59~7 zzETQP{QSpy56bXnajQ&b{6%M!M5If724wqoTD4Qg@LSKXhfmvAb*Qx?Vn)dI4T51zUc;CAr9*l9xh@K z+R}j;zAX5YLNt@wL4*t9D+$)USt=#-A;FB~w=R zMfoc^r8ZnL2h@-6cIV)=GM%KO!Z$7F|Ca>AV(au*Z6 z_i<`672udOz%jDd{TGT$Arx}lYeJ6!rh{nF4AGOr%?kO~J($zL1eoO!B$?vPSL_qmswuL@_GzTt_&yS+?SJt4JR>A?^x9An~uX z$>JUa@_WRy2Pma{0y^|m;JA2ds9PL>#r%9vL@w5v2y<(#eXd)ab*t)fp9kYWi*e#bN*=m1_^D95+D5BA)B@JV+l{Qu2xTdp$;uUY#8&Y+b8 z_GiMOHBChibV6$kwwa5Q2?KQUTPR3QHpA{(lJikeB z=)aS|FQw^S1&0KWw%y3+1|)*#Sp-u8XQ3`%b&g{dzkEQF1OHb?7NE35CVOsLoPpc} zePY*PF|1Rx9T&rkYrD{9K`~mCxibT`D9j_>S}u!`nbIDjkoFDbvK?SSJHU#=?ygX{ z1jVbUVMG>Fr|AT5#)br25dvfAzwX3^ILhC2NT)u3KpsWmq$6ppXAT?|b;akOgMXYz zwaNCGTgA?!=h5P{(+R|<4#>mZ$A-A1CuB220tz~I0AE4`l)U==lDKJNXiwWOiaROZcEHW+=%(C-nmPj&PR>UBSb_)^DsT z>%b=NxER$ACZ5=T)V~iFzJ0K(_Q8Vo!S29)uu%J8SM7rZ?Soyl4;Hi!cFjImsC}?2 zXdfI9cM6&BUOhII`a(Q@uj036$dI7;;a+z#dErlp_HekYrz<79l~+_dqSB3rln~(6 zWcsAuBn<$2-K#^QYUOw1VrqLz7N$>UdeULB8{5s{hdaW3Wpa`l>nOT~(nor`wag%r zJ69QztOV_cO2iiqM8r3o*W*Vh1iMsJ@4b#*j8kYu2A32sI1vg1val;G?>;Z*oJUL( z4e}B(o^p09!zF0iAt!=vEu0Y-m@jCbXrb4E#}F5l{o~D z65)Car(`BwXSOy}=Z&5Ur(1o^(&<`d^ORkfRy1R;dAL>U57B^xTMfxGD0Y_(Ugr&W zg8ImbJ?S=@;-YhJK}k$a_D037PT42VmNYIpv{9xq7sTo_;=KnTh2J{GiXp`W^1KWV zk%j~yVwvg1f|L}=5_f(c;lzLJPi|bYE}AY8?Ex}^K(Gc}ps8p&Dz26_XVa+t+da2$ z7UPq$M>U|uAr*7Up}X$9F$X1a+(Vn^5^TTD;ZUT9{_DliB^b0scDy1($ZK#Cxh3Sb z2Xas1)MS3hT@<2M1LV3(&|e;M7v{-HXioIpooL$Q77<}=$cu7mZw@dQEskK(-P=O$ zy@A{}2wWbb*XyX`{1CotY)T%Lt5n7ETvTIIj~C+Xi?UUoRdlIoiCiRe6**alE@<|v zK(70jKptArAX!*!MM0#*eF04-sRee=k|=uVMbbfw2Hn!p9~1aqwgQ-5Z@N#0x*-{@ z;D;f@aQet9dG3POT>Rh;S~j<-*XJAlz`}xE!VTgF zWQX8q3l-W|+A2%BOG--8IN&-XOQI#Ui&eKsa1pGCFtyqvw+AV6dHTQ^r6Yl$p%e&` z;hzUb`DZLgU?i^~98E_>eL;^pCUJwbjSYA)3wC(-`tX-PvOL+9K2P4l4a$|&1_X5` z48L>mNcem-EJIs+-;E)DpqwT896Qi?w}`Y4#!3$|qi2fKT;0A2@w=$m&G6+7K& z6ozu?P_`jiB(eP>W6)~tiIV(wNo^YAM9ye`tbE5^b>vEozwug?xP_#qGktAywlRToNSrgLAlP@J}WLYHTjP3&@9c3qsVzoi!#3 zcLWdM&I-v%?vX&Ag7d`q!?Gj{B#z@mjr&!6_gpuTM*A+Ap$O-d((cpnFJC}UwATNM za>Z~Qhe4!&*ncLir|N|TlI0@z^=n&K_tF4^_G+lOHZIxDB)ir1sXZC#s@WdKOGg6+-jomk_g zAvwjJpL^cj8cItFXwU=2R}E&5kVdPR#x~!*UIkGbOH{CDg&dUL%+ zKmHFt*vozdXm{@3vp@9^uHHP~<6t;=07PWxb67meZck@om20MjsDn z#GXjMmw2QH31nqR{M1PzLxbNbMPepjQ;Dcbx!iSQh0b@br zv&JA%wgbYz8-3#sQp`2f-C4Ofu{o?{(CvO0DzJ^7Y`QzBy9wHL3P#>dD0zh%1{0_m z=T0FXDIN(NPPt!o$BI;Y$~_v$6RiW@ceRIc^eGlaWTYOp`qO>xRRP#|?=M%$lriyu zc-TEbIe|`*(CYX5a4d^V;N9*i92L^gIN(%og=6YLt`}`i?>nLG{aTeT{~8uBxV^uP zXZ>u&Z~wtRJw7ofZ@$Me{^Zw7VPWHdb?yt-#HJ4~zy_{c=(7~G=>I^UtsRZnt$+Sjw&DAh~FbQbMhO}!i)+sForGSxBE|oQ#de2`jrm% zMN`pmcNre$osm(>^0bAcZxJ@BE$#T`sk7qacfc%Fo!at>ui$7^lR@uiWE+-@lKZ5B=Ib+|?m-MS34jfO0p6UsiVv zT16Y(FBl%#S|WQUdH<`qD)}PSLqSM7Y!N}sdqn=~BRJ-esf}rPB{8A%hVDrwnVYV% z!n*@U#fJ~96u*LtO>KnxEs98!HqN{xi1T^bE_*X@h|x?G=e+HGG9^A0kTv4<{qjtP zlKmI<(Nn9>yGO-?fg0@mkA;zQW*HHgIco@YzSdLGy;n#>6yj_6Pe7R989 zZ6B>IJAyBAzr8a}hhT}$G-bJJW6+U~;$R4mtUJT#)Dy*j;@i7dQZgt$9Xu@V*%Rqf z$6xx4*DV}#utWSwB)c#4c17iP6`A7Tzg`e|oo8R5c#-MuJCD3hd}3cG_Iv>9$NQLU33&Vp&~+uD&qIf37z}vY4pI!iA1{&%o?TIYEXRoz=_NS z*(OWG`wv8Vqfn_R&ZEUShc0gHDSj1)-qT(DDc?!}NG>3;G4Rs* zjL6HsUG&Guu6xQvJ4*T8YsOLhM2|Hm>?)a6)w7dzQ3ThM6a^uKzI~lty*M+%Y`R3# zVZV@Y4ub~C_H5k8_qR*E@g{D>2S|O-Ug(DYNkre7W7_)8%W(+TWhr;t7`Zr#zLg&7cFzeA-sR>nPQF&ajm$8vC)K)@povhx>3KbZCGK(04xBqKiF{lEo8& zG3$xuCU=Y41VRvx?mv-+Kroj>m?zRJq_(pk70(1E;^oxwNQXA>+IrHBgf?_U-8({Z z@~v{S7;#FZBI3zCr)2kr4n*%;|a*2+OkKo#0cw?(t&vyOHKWN|UO2n>$JzHR&_aDfo z2T6Ni3~87SPFdmcUJZ20rR!8*^8d({|3q)=!fL@bi~IMR;~RCjmy&AV1M=`ka0sWI z0uvlnb>@O$0$wtNCsSwAf5MSuug=2di{bDF(Q*`5pyZXC+^h3aUAP6dLG_3PH)1=P z63HYYq-d@YpTvnlx)0tf-Iqzpa93TI@1c}CdrU`HSC@FgO=>5sA{Th-C@D#mY}EEq zPlUgQGkURdrPy-H-7`*1tU*41L~OveUd*cbljzughSFrD-8YQoR~*>p;)ySrXd#ff z$J}c}$Q5Z+}a)F}AFF05+QT^8blImCGV{DVZ( zh1+PoROzlzXUH={;(Z6)8G+A0)<-}6^f9^dGsncpqfg727w8QY4GyN$pZd32z?ek{Nna%lq$KY?=_ zH%jMDZYw-P-Z{ii_aa#1tFQvs>3vhnd>c9KKWx0p!kUrICONaU7g#;(^kt#GM3!?@ zSm~P?Eaj}XP1ANcAsuy>=gK0eZg^{^_O(r7S0n`ws2(A`E{kw{B@dq8NdG~AJH8-S zzm~y1ZrpisARbQJp$}?))ZfmsB4)*)15eO z?_Fh^v8gW@i`$#xl9k<4A0FIjY2{B6h?q*Migm(G8t>!A$NvDBlx zY^e=7mD>W!Plu@B$!zw9z1Yn zai*kI{5nt|M#+L`xEFVghv70TX_U>>vj7R7y)NHa8l`L9sy?#lwD^n$IiHJg4 zuYi~m!EtA}^iY{Nf5*{q^zKKyR*4A_oNr7Hl$0H$Cc$F$st72)#Kp;Q6wj|=zW;iM zx`Y1wkVyBUKZ;)k*ee`)OsEo(KhIs9n-*8)A3BseKot*& z;mOqcZxC4fwD{hrq?n9raD_S##7fkC@IF~7LdV690x|9cH4~#x$nHD0U1G7`L3M#bugm|N3bs&J8@SbZE1+-thdr&X@3W;7WAudGc+D}Y-m?g>Qt+GGoEg|}ZV60%c#4iE8XDSa2SYeds2x_ku$ zj(=)4)ONkxAwQB{c(6{YW2By_Ol%Z6#Yi@~aD_IL(7YZGZj?7{|FPK8E~eIWAM8e& zg2(yz*WJAZ54%6TCH><6K6Li{7I$*qXP!)n5lMM=^Dpt_L6(Zq?Q+p(+-C@F!Np*N z&U8xlc8Q*SN5#(qr^J!{HF$?7Cg2Z4abe)x9$C|kh}+fM-P`@Yv6~J*Bjk{As!d55%)J??;%^eOK?r$ z&QYDXh$#!YvG=aM`$4(@H5@n6KO*kG2xnj7huBt;I)83EKJE|@FXrLKN(hgGCI=3_ zCknBp5+x;xoA0_Ooi2?25!*prbdTcVU8JOJk+}7gn7uMwSW-vl_l4aX!{-4&@2ME- zN}Wb(`3L7Poo1-}3T<$EI(4lHehj;~nPWS^Q>N{g=jBcJ$=2wXk9BOq1)9%Edp_-6Hz6hG$V)f6*Ieo@94BkLyJKGzy|+go|C3^jJPfZZ4~oO1u`!$^7aqf@ zEK=HTBw;^zxlcZ<+$o-L;$DB}55$$H8E=TjNI$;FvaYgA%q zP4$n<&`U6e`7*y%=6-PN##)o2;qit(+o6X_FUV=#_>;Y)8c&HYx4xbxqPZ82iQz{- zweP-<;yK~!9x>r4wyrBy(kCSP;uK%Exfb(e}EE6BFGjW01*r(iO2Y5?5K}YN|X%;Uw-Z&g&LeoItLg8$IS0 z)5|sEWKSw8C(Ff0#Jl9{J^Eg%I#&vcJ?a`vgUG3Q6zkcUR=GxyT&)Q9h@-o3w{i__ zzlt_9I6Qg+=Sia9;+&rd=G}hf|0@29o0EPVobHuz4;MmB)-S6dw+X zwsvvx>sxoqjXl4G{>;dT+p&L9JkWE7K=3Yl#a+}qS^U2|qxe!d6%JRZ`r?{kgZSy* zPTW6h7bDv7^f}x^WTwmGrCn`k;s%cg-&YHv_4O8J%2KV+)57jOQ2U7~x#Zb&>Af=d zu@V?B!6A4M097nBD@q9vcAzTzIp$6s_vDXKuP77_#TMa;Stp3$ ztwu~}-=Xj|c&t#9I{!yippOAf=|1=C*7UivzwS9EQ$5%}$!>Y|12F1JYI4b@! zBvJ+iuRo4wk6_}**Z~(Zg%`uoaCoL7R~)?eUIT~+_rqbo5$Np2y`Nt3v3+N7e%am~ z?n!sh<*a;hRlA74o_4wKfG|jP%jxA$Vi^@&u}Hlo#IlGeDL%RQZc%wy7Jg{+HuVf~zS@6%6MxDBk3q2e*rxM45 z-L-Z2d_njJUA?t*u7D3{>^Vbc{+C3G5PL{g3AyU)o9aTD%(_>;KH>TO3i*4l2J{FN2sINU0PT3VKZKDD+jM;1@`mh1*4(?lynl zp);wc576H8QIv7=it;lDa3=!C=b^(?8jjs;Eqzu@EyIZ*Z7=T&z(wFG1DrGjS48E2tN95xrIJvScKR^RAkGeh}Yh~E{O{*`0VCmxC}FOjA%F| z#_2smBzQy(ihHfW8`15hN9DwyWRMjqEbcl@{xCi9=)kT20FqLvM~eiZJ>6-wd4gNS z<%{3qudn}=<(zvdOBN%&nMzqhdd!C7OBzP zS#;hS2#U&xm?DcaxPpTdo*g|=d1BbCgWVY zF1l*znlfki?nM2bIL4^inZ)CL(jsT&t+6or#?~xdxnfxbny4dCCsw*9mZ)rv$LM#- z@bTbSePeZe7pi0R3BbvCOJ!BEzBLXE{f5r&-7WFzR8`zrx1wTs>8(!LnkCD_ibz{a zeKH=~R+)%9H?AoUQ-f8dtJkkX7aBj70WlNG4MoFu>zAD*VS>NJpzg?dxW6id;RJQD<{*5$ROTvjpG1iSY zt|*VKt5{O8Ld{@jWy_9u3tCmx#jAES)bC``+`6Q^bji}P6|u4vt8c2fIku$yrn1s? z;0+6PV`7qf;IotZbC!f?iPuzN zj>f!~(PBEWnuf|+{QNu_DfEt(Ud>i%d@NSkOwCKz#grPaUAJQW@-=D^%*rB$rxJ1e z^83;y%fc1qc=42A_4-vySCoS=RuX*Es<$R$l?_-BfV@<5u0?_P_G}@MY_4kF?ZlcI zs#&^ZTOZ2{m!;SG3q; zmC4w)rUs{U^|}>U=~{24+4_hX_^l?GF?a$WiUhHzMAt}mOH18cS&gNqx4HUlo_?FJ z->z|D32pf?e4RoA(^5`IFMU&Myrrh0sV#;(6Zk)_bUvQcm3sNWOA7|8sc(S=#dhL5 z5rAog+{tp3OD1D6vR_fQZbhv0Mo(Fnm9K!Oh%Hk@lBpI_BoMFKVZ_`*E7vlY)n;k= zlGQL3;>e}2yOX_h;qy8%PN#Fi{0ofS-W<{YI3hoS*r%*UlfPy zHY{0-N^SOV$+%9{60g+(!_1m2Fh)87dxjR#*H55_@@jbZ`wc46+_kPLm7^%K;>Oa| zE0(V**Gr`wfnKdxq7K$Y>tN`{YU4>|N+7apTfCMWxiM}nFU`oc^ObACjPx2du#i1R zp{J};R*ypYiW@yEsVHBsy)o5`M0pJV$H78>MvhtxL*EN%+mRP01!+Jq`fCBLFw2lB9#Mg;vF{wLS<% zF+iTCswst$qS18~(X}g3Zct9RA<^95wC2LJhy~KtR#d9lsIip=QXnKXYtlhhxg2A7 z5CmJbiv4R#G0sh^*XJ+G$G4Fb%(Fr;4wFQ@u3}C3id*5$z(2enX$7JZ+2Bs?!YH9x zwq`Z_HiEB~SU<-PS<>%@`#$ULNH zCLH4v7l~v{M>NP$1$-YT@m)yIbf=g~0d!)9Q3v#^BB^?;QX;E3(8^>hs^i;IwGMJG zcuI<^+cX07U~Kr5A?0I8k{viD$j77S1t<91_%5^s70gN1#}aMzN#t*kq8Ux+8kD3V z>4xiv&Hx2nY;4kksH50s@}^j_Wp@k-Dc%vH;PaAXz)k{z1-b8T`Zx-Yq+_QUl=30U zMu^Tbq)^Q*@z(mLRKf@u-Kw-gfg%Iw1kvV8og-ogg9?5i@Z6N zP&)wY`3A5?N>tl|EI>&ShD-Y9QwXh=7^O+=2evgE)@Tk{a)R-K9=w7#4}i^0%|68- z-$lV>J5*SivPnaI)1DmN)_(?RcH))Xtr| zAq+AB>Z_fRC9Yir8AMDwOf(_~qx4=GfVOmOul;-(e`Rt*%o45`)Rj`<-LeEZ?yOV> z(Wulnrj$X84$JC&msS&^k#gU(cWi-&@|KJA9^7C~l@$16)%8{#wR37}jK!O3?3~D# z8zoYml%!%+fUQ}$lY)pxdB({^10+_Eh>3DTaS)w^esxsI9Nd#3m zdeEs%eWS`#V!DyP&cV(hwr1_JHOp75qdhR>1BKN9@!hY-wzw%f2_%;Ef~;L15js_5 zAI;pJmJHV2NXZN=7hj6jL|!W4&{XIgGNyFGD>XIaK!SMXV-adYW(eoDjj}X74`@#_ zG!`khf~xBim5D@r=eCC3{g~0jtB}McD;uF_HAIOHDwHFwVtOiAG*h^w=U7}**n?65`pM5Ke91qmfm zURK=uux4FnAS>cc(B~n4#Ek2ubd%U+1yMCobEuBsJ_*q=K7CRU^9>1p%GiF(?-8hUU<2}C-S6<;j|ZHRCeC0z#-QYQ(-gWBA3wbl)&gT~VS zs0lkHowU)sRKrS|1o0Ewwp$@UwHoIvjfh1wIH`|vK2)GOXFD{2W`VOcJrRVuIm$GQ z5RHsYiL}yzDb(Y5OXmm)Ef*y^tfKlJyJ}Fxu@d>H#9T!TBUB)EI_ ze*M@Wt-)bJ74xfG`#FZAZ-^sC*VpKAla=)iY_2VFwH-HOC=NA&x=QT28ynz3mAb-` z;aMqlY>2nU8$1g^JWF`fL;-twcv+fLd{?tx>TON%2bC=?mAlnkw~%B#yi5$LRp9e&?TUlMLVvHixf3#S9 zCk~XInjNt^1U6&}4)SL5aFCEn_gi6&O>~;KBOY&#)k2Gr+mkCrz`$f zO2-kT=>!l-3K9`Y!?mPorPR(#O-@UNc0!2k zv@sK91}=u0ZA-klp|UEzlSUXYb0l}9KzcF=dNiBF9-aJ=y5KuJwHH$CK(H`0Ma=Qo zB4G@mN{NMX%X)3FV##=AOLbElR9Jodoq`gHLZ3wR`;}OQK@ro#f~=Ynj7-@kg$G(iJAT94J zns2x?G6|xW%@3_JF`^VfcOVtkkWocbQoCQ}N8sn_FhNhFKGB$h*Va8K0yHR(0V}qCw|(1DV6zk&x1Y;!y#)m?W9Co|0ZGxFfSyF`Bg_rfuJA zWEF8Bb!|0jw~MnZvPP0kGt4AQ&iW8-J2pq;|Cg;=iv$dh1=g)waf`o%#}>$TD1Mla zfI{3bH@w38;=~Q><5fTml{kBD+{OfMQU{IYo`{ui!xW6&&m93OI7W_ z5i~KOBu4}5K&pc_85OOak0Ip_)P|L^8Op>-kKy`=N;8j36g8i8lBJ&0sWH?!6*xoo zgR))<0GcyG86FL35^4YWVT)NEGlFAY6*tsbYdvM-dPi=>K>mQl0J?MNWiB-*qYzAIu^r;gvBV0 zRnLRzq{ZR~6G)qnwpl?lS5F$qaPVk~=olWzoV`^uIMz;&EsbbtN;b@!>tNTxcBSXV z%~`M%rARK`7|L=mZFVP~01z!&ym)8^r-K#aB2>gASP|2Mk*2Xk2{7jFAI?mc!n4|q zLYeeovicM-9XsmhWX*JNOItp>B8nm9Ka^Hkv8gHOqFs1zg4UaOBJ=YJ0oV8QV4fy$ z^Fdfpj)DzI4NuEN=F7t>7L`;SdZ3Rd-m6R3-MnJCYGTwG5y{sBryB{JK(-ox-ftZo zmOq=YDJ#EY%#y~|%YaoOI;M>h8(fy+$O;47Y;0QU>1+sXbw^eXQ}iUvlQM^_-X!6d z=%my?31uWoXB*Xq3V}Ahlb*O*_O!t9$mHhOx)qQJ<;j*Wmb%&tQK$Y^qMkzPw8>XV zhGR^VLyXaDBNMWHob-DWg&xze#<+M4WzVgNM)Ujwx`}7)ctVS(=IY7;PIQpyQ&OdF zE%?gca+SEy1%fxD(vRsH#)!;9f>ueAj&BlsK$XnVua{Z92H9G^JWIOUai?!&Ux_ z*{iGw9zZ?Lx@G;EiWMH?NWU2y8u3J~eEqTt+=lRa z8ehfp;WU64G9SbONQY<+J&A;j)jNr(GEr4uuQvVa(emmFCt(zTTB-*rBphf!g}JFh zgR1j5@Ujy!Q5Owk`heK0Gs{R?s@j?|))>cXkO#IniW8MUp_1_4I7`+oD=kG%ihLLw z(8d-hu8NSjSB2cmS-Pygv8KsUCy3xSUWMHwGVA81wreN}#aUZz5|2rorJRI-2cH<> zn31kGG!?0DUom!+Y^rveT5FJ~;(>z>XQ~fH&MNqa-A+TI4#!4Ls-}USwbj+@?$tO* z)43RFHg$1o$a&Y`xCNo6x&>P{wF$&_ysmx@_FD})i1y=1Sw*!TpdpUKsruSF%LLBM zV0mrWUpL~)OIZTX*!pXIQA45Cmb!e&hS-|*6>Ha5KoshV zsd`F|D}Bzovi0R_ac$l%%#B!gWofL&@)>1?*j zSzEs5R$PM9**#s@p)t?~cavHgoMmfP!Rc1;0Kn_60Q63#2DusZp{2H!IyKWlyaLFF z;P6nN%BK>Q$dyr#L!ah40xBDt>nfc@L#m}2I$xjAEp-htD}%xQ25q-BR5s!<6d$rBB*XJ9E{EZ3EKV9Q>+K4I2{`K~8IZdHmDSuJ=vQ{=FW^*U z_o~o!_LT`dVg29g%)J4uiLt+mN;o?gM9ds%b-XmoIruecc2b^05HfhB*Z~D92 zybpDnow-wPcP23+Wab%gw(6Gl^(E8iw0RFWn;EpdZnf<-^lt|77EICQc>1$cHfw}^ z&2Ew<&vAyzZ1e6qMVV3quQTrfXPu>~p?gdf4~}1MOW(0X)nx{@{X}-#``)ZAE6i0s z#bNjwd@7v&pu|NCUu$t$3dXcHd5g2Y(t!Ids>6VfTGS^D_=H7$&VbKY)K?Aob&L9r z0l#liKQ-VlEb4a#eAS}nLou!rI zN3y)$;YYH>uJ$9Xv^2yrV*$Y@3=|Jg1BC+=i{@#=F;Fa+=PioG@{&cdP=0JtERx?? z6bt0f7RBNSn)zTv7Dlc`u_z{46bqurqW-=Z%Cp5#o-Ky*Y%!E)i=jMQ4CUEkD9;u{ zdA1nJv&B%JEr#-JF_dSEq5SWQA(AbINVXUv*tg33=YZHodGU<%hzxqF|PZbuMNXBCIwc+xKL}5H0nTNTvz97!*G+u zt7~n{N3*!tD1LQC~-s0YL&?5X27X1aB$Q%RSXi>V(zNQU3uXt<~Wf=aw z!6B#k66Xnwd&Aa!p6eL*e{9{8T*o+JSOLv{;W`gz>yB{UaDy9T>)y|GjKj}(sz1dF2=WI(jW2?25<6EYa<4{-9xR{&Fw1_TI)5*+F$*~aCV*7WUcM5A#Rdmnh2*Q zkm155UcYh%FSqU73>RkGb`0{6ir&CMd3Kv@KL)Ek)LI6cJXBU>VM4Y^mJC>e2}6Yp zpW&3ni1`d3oQl-1{W}#u(%?I zQx-Ra;WmrQXLz^8jc51{i_2knuf<7*?>9Kb;K0>mi5@XCg9bCmbHN-SNw-z^M&*+XsaFn0VN^N#)G-zQYggudqyTE~PQ z^ay3`@;+%=f8Oi0mO++&z=;i%2~Yz$dJ96sz2RdFMm*HkN&_;p*kChg`HnI8itWhY zWTOd4i{A#H>kR?sAc&3rerHmK%ghegc-b`d4Nzys+Ubp%bsE5eIAnTLd|>zk28Vd^ z3da-1ec0EY;m2+J3*4S@PuM#7Ub8P}+^22b0lpXEsUw~l{*J*RP_Q6a z3P3T)0->G*SAlSErY}PHP~;1=f>*b1Q?aCq$27mOh#d z6gE&SPo6JO11F^h&7ReqtXX~4%;q&~O+1+fPmG%fk{`sre`*MD??Iw8H{r2{I>WCL z&CcZ+M!exMv4zPn6RPcAv>nKbS21wCm>A0$=XTlR-I6WdE!pDTGH}pA&H#D1c28>S zvWHujJ={7T?vu9T69#)F#MFoLPz>THuGwL3*RzGFt~u>Z(Cdu!{4>I84Q2l;_?|jWpU#f zK5cP148Lq~SxUpgJ7p#TrD2eV8N{5kdsT2Rp4cG9mEG$W?!_!3%X((N7M*>~?pMzJ zc#4B0FxkB#+>3=Z$k~5(uPFE8r5MD$pEJ^X)sx~{26<88GZ^H_2Ar(D5m)`lw`2_e z#Nu)o{;9={XZYt9m(TDoEN%wFzqGg_hJRym3mATJrd|r@@{vVc_@+UUE;Ia+#T7C9 zZHt@1@OLdPpW*LY+<1mhSzHdoeHNFc%PhRsk(y!XGK1WWviPM|vow_5uVRpX?|&Qp zZW*NCC*MZDa_+~|97LaInOSjD;SBrF3>Q8-n%Ai7#8NIe7c&wqxv*~rBhiuz4|+(n zY;97@P_G{0BA9|!b9D{;CqaC(27Bp97bgDeYO>YAMjAOFvy|? zEe8K+TTM1%o@d@cey0I>Ss)1pKk2pF@`M3DXHj1;;1?~5my}l%{;^;zO+c} z>su|^LBl(gI!{!0Sy7!{$_1aOo*zt9rw0?&^Mi@%^k6!A`t69y$Kzi; zQQi7E!|soaT#z_0_*+j@tun)fah|AdWpKHNx`jcG$AfHL78u{gj%}FpknHN*|Im8r)(cJ&0#}NE#<;9 z-s-Mp@PvoDg+X5weJV?R{%W*ho~IRS8Eo>j0?v#Jk9h5FVeq3KYAu7GG^imsG`ljx zC61{GDx*zU9qWbHwG3`BN`{#pS;~d22AKzf;`u}R7;DnQ0l8p`Trf4m)s>!tu4VA! z9=YZ@87{nN+Z{D3!}H;-z`5rU9*cH0Y+zflZADKGDyMgLJhgSnh z4fH#d+SD77vedyrpP2>osU$X#Q-yrRj6dFsyA=cZQ0)dXvcoJ-i+R7uSqse_!o{RP z4<&RfD(*0d1Lj>igr)x(!z(bHLdiozy1tE6N3Cx(A$aXAeC$l}H` z{8Nj|XSjWq7CZLc_%3r(NSk*IlFx95#f@k9Zi~xd_#TUs16PzM@dv{Q_Rb74$w5*F z?)4k5R|SL2+#s2)G<@WlcL#224C?| zSr6&5dsT3+pLo5pp2&T|RP}gG)-u@Vp|Z}C&E*njoLMO0q+aw2j~XNdH*g(?8-%al zodGV`epwb)X!_mnkU3dF<$nD z&l-!H{KRXLC8M92s=u0dS~P|qb~Vqy6*2sX#bwEeX$?1RFf|76@=#ftoZYK}d)@8z z%CfcWUbk?sy@TN`7lE;H{g(olvwy>3}ip1ZvTWxk&FH;;0gWO$mr36{g~bc@T9 zBh&I-3ck`b=Wc^27Wd+-vG}}0cCW1UXCD8tUd+ZU-z*p|x40aJ*I8WFY?;=LrVXYR zHXwH!WVYOErPr$>yI0n1na6*u*FiJJede8PgyBOLm&5Qw7MC?!ru81vW{|06H_4g@ zkMOW>B!(ZcxEzK*Y;ofmPMXY{(uV*SQU-}Bj%T>l;&K>nv$(7&GIO7_Q)H0450WZy zuaA1YDi~x&21yl|k6k`~7{124u-BHu@U<3~#W&Ns)6l}wFv#5p;eaWw_EBc|dlpy3 z@b@h)ivy+=Gi|^DgWvK{StqUBYophsg29s>D$9X#uPU#}Eew9mLuEPZT2r;lYqFNX z=RMRq26?W7K${=?i#JzE^i@aVHI}ON;46;1`$IQ#u zi@~?(#oTxLX2Ecm#pN*kh{cU(_zE*`*kwM$@36S>3}0z+ISl7poPn(3FmH#=n2;WW z+?Lg)@+&97E^=SGI-8I zWw~bVb(7bmg26jH)H(+L)u4ova5G%^zHMh^uOX(+m+J61kHO!1y|RK#+*GxCP1Z8V zV-B)zESuL&FY@vXU$D3whTpKb@eKdb;_?~(i^a`gxNVqc??nvnvbY%x^TlJ*Y=-Z! z?Zz{_&*E|z-fwY+11nvg>&2!G)|x>cdJrAuUL(C;6$~#i6^@36nJS*fAdihNHBF|N_rZ>J znXh)QO`Bx+Uo0+%;U_FEYt@+6drcdx+CZ+k$w#~<6%2mVLuKU(Jm?pFgEPF)oWhU_ zGF)tNSxhpmA9};BXK=3RHi+?YuNS>u6@3Pr?e)sqB7fC1@%3WxEqXEcCB9iOyvX8m z7+z{|;~D;n#pN^nRf`+X@V{AH4#QuwxGd>0Z!yybOUz)8hsw%yxz`%6Nd<$<$ROr? zlWEOOu?c7JEqZM-y>@tGt!**jUW*#2mptdMnemM z403nOmO-X8h+|+v!^~h1K*)fTEb7gsGQ?|g3-_94Q3HFOFwFkDCxD_1!{PO4w>Z(c;>UcZf%m`LW|2`c#g%5XLz2)>jl~r)Tx@X* z7{20iEf{R%e-_}vI}8#Euz=w!Ev|^+i5545;mH=4&+t@>8_)1`i_2knhQ&#SA2B$^ z;J`&>i9Tj#2J2+-;|7K6_?_l>()Q+l+z5(hD>cMT-tUpVg~85T-2`rPXr2ah4VOR- zWPA|k`U^wztmW}VhYL;iX<(ZH)8-v>`IYk(Q}{PO@-}k{f5E)NxW00kX6?J?9jMn0 z=z83)U1h+iMd@z#m2WUIgW%$Mk6UID2F{?5+gBYfeA#e|b`1I^@T$WFJAthX{)acG zbqs#po6}YXd76qlF8tB9W02>r+HrxE63=b3moMu?m+!(3Dv&cCx0@Mct}*1D0WN&g zV{J2o%(ZIAg}>T%3^LcM9T(XCkfreyD!et_%pfnb>dFN+u|X0%R>nKL#L5D$c-@y$v zIFPvSAgCCZCjR2C5ska3XreJjqj8C3d6l?D4KWxsuF>~Y_xYStsar$H@BcjS^Zb1t zsn7k^x#ymH?yXx(SNG^v4wNy9hq*LM@p_kDP<+j$f%*Z}>bezQdn$Iibe7^}F3nf` zjZ0rC4p^~qEQ+sDio3gXn&P=Gy`uQ0OBWAn__$iP;_GY0fh(E&Jrp}!x=!(Sm)=lZ z>=Mi1%DNni`%@Lqap@k#CtMo3N~7_zZl&T_#lu~?T=9QgdRg&Rmu}G`<)?PUR5&=6 zw1F8Kd>>3>_}eb3_t30B?%SkS||%&}P)J;VmFmQYhp zHQ_Pc*;}om{!x`u1!OqsF>d7qh*o zi`mGsE#%$xU9fti*44UAUbuqqF>SLNOlWeGnGG!GzVkfo<19;GWyjST4Yui4CU%G7 zIG4c58iMq1eos!P=LcU~xk;Pa)0_oQT^>}Ef9ke>a^CKDMxo!DH6&`wD^)M_^pmz_ zUpBqJ$hcW1I-@wNW#sU{@Nf;~Jl)ExiyPD^{M6#C+^_hIOLVzM56yZlhlu4ssR&?KOq3^bAMA=%) zN0TDyUOY|yn>%3rTGmB&f7ah2nJ8p!nIC1Hm^5Zwp!k+m5X(O|46qnt{BnPMOrHZ2^8n8x_HR_|-P6OZ3Msube>&R6W*W?0xy=yW2 zKduGOPVjZDHP?~Nb!ZaYtkS|=sg~fDwHgkS=Y?=z*Mf-fHP0ggzci^m8zi;fF_S77 zX=6FZ!~JTFsoaNyOQ=Qk{ZhSvk8v%Ak995RExra>kR2e^b7nw)wZ>GQJAg~5MI6Va z;(`C=S`2^fS`atBPFEX=0Q}UXcF;YAKdvxI&8eR9L?AgCVEpxsrQ}B#3$VTdk!Ufj zpG77bzcUo+hj58jg6XJet+1}biCr09MH`dHLerZltm^MimEodmtuQ}>nlucr>2^h! zpF9=27+%Nih>u*@wpB?|3DR`VK|r-(Rx3EZ^+Gw?%uL3Cr>i8N>NM3T++=p`;9Rpi zv8hJkF?}*70}Otll6)fARHHCRJDoETc2mD&tjP*^wMkvet5@A zglFQ%v*j5y;f77QiG80EJ%UJSe$CE8P=RMtNTM zEFYaXH68tns{dKH%cb_qWh3(2y;N7(HV-P{R^Fc9{g$2TVsJ@~%{y90Y}_vqgIvP29?Efw%E*J60MYekq}98H!em><3strfn_>z3i$U2BE! zaIFO2=~@xK%e5H3+qGcHqp#bjjVyT})pKsQsI{fls)7WZv(#*=)-;eD#Mi6FZ%XE@ zub5*ZL)Yu?4Nnf-1?$vIHMvH&%SKb8S-w&wHUtNwIck0 zYbAJ|Ypw7O{+?zT-qE#Icqi9N@Gh$z5hPjsyepX6E* zKH0SxKE<^l5oO)Co!OLY-%&nRw>h(Y^Gr3#A0CJ#Cw~OObz+hTn2Q|IV)!--Dm>ir zHPeFZn5{@P2}%{)Q0o$_RSj!Z&0GP8cWOC_8|Gpoi5p%?FD4SZ-hBNZ-627~q1a!m ziNvKIo^rZEPz%ga6-Qho$^C5TDCiwMp>}d!gFjH`eWHm?wNJFLoW@xfRkIBdubj#O z%&+?=xq^#sSAV9$ttj?4Y7F(hBeBS_$6SwIaN$Ycaf=Yr$Y{ ztwC+4+rCl9%)-n9#aB&kPh^UC?knFh7MUUq^^0cgnCO;L1u~0w`GH*UPufte^HO`>sG#P6vJH640pOV z3f@2;0wnk9%@j6NQPMFA-pI8wyoqbAaM`sIyqRl7cnjBJcuUuU0Va8GYbWHO2Wckf zVwPIBTCFO`mA3u~5{j>>Wp96i1ds2T$KVnCIeNCcLbvuONDzi;KXZOa<~6PJu5RTL z4D?!^+1dZH2D5~qhNwgL5?nopCgZXV@$Ibb)LXI~j#WO`LT=AiIW@KS6ST zCQz~M^_GAMvsG&1z+1Z(!`r%6gtv381aI$JE4+hiWq5bjM#0Z5+vvR zuwIpV^i5X8YzR4vRS?Ex4xiU?-Yf?fJTocSa5_&bvp_>xY%5yQ1!~-oo?4uqi~PgfurmokqlGVMnwq* zJSlBQ;fHPq&Qd8E#q3c~@5s{3oFSPBD{2Y@$pJ0ZEwjNMpE>^J4H%An`YKmsAV+D=&n7NVN8ji+xk!Vl zp7Vg?0X2Wjs+|~TV|+x%;UnGljZP`|8>W-ojafGM4xR)FvXbOnT<)bwKG{dhT{h^k z%s7Z+RtXX>jxW+FN7^ObFZ7UmR;`=>{;b}I*`iPxuDGR39JSxrv0dQ+E!p8z;jkO$ z5=YqME{)bmC)#mSnWV_CTS@=xj{L&KD22xA9JUi%eUCcV`r#++7$!ww5qpa6$ z^m={!>P1`F>o$6QymhgyNAY5pu2HPHL~fpU=`F<%Tq0c)EM09N8BD?tQy5&Sep`FC zxAzdFr;@FkgR_11l#{G#oN+k4NX7GdcGKCx`9g;A4wX_3gqIUb(}2u+e*PO@Im^H% znFyMr6GvqSe-q6uayS^JaMSF*=bl8J1+U#okDGO_uWYRjt6MC08? z#aOi{E7z9=_(s=C@J+61{yYwR?W#6%i3nbAQgDm% zUEOuMnN+}QO=<^eKj*M#*Uefh=?Z+iYcc$`Yi0Ny*JAiDt_5AD&AZh`x(rf1XCcMo zyD87`BG+PgM}3DnxgmgeaxI2;b}fjMHvi#~f>h6mbT#$JPnYGSokn*_H4g9US`6>$ zS`nVBTK$m}g}YLQ@ZGM(@XuTedQET#sEv#dNcEgsjs4UbQ+X0lkedyP1e3_}h>9X{ z^b>i;p5c=ye&O{tizPU7;ez++lPL^8;N6Vj&s{6SU$_>-U%D2gh&CTp8%YsJ^_+?E zwpxE|wSvyj=vS%6VSc<)IvB%E`gXr)MfiNxWMa&ZC|r;-gfDb0hA(n0==JKlZ*AS` zGf0ZK?HkpfK~lt{JZ!Aw-AsmFlV1!i;FZ9ViPJf=K+(PCPaO7NoazsJiEA-@nQKM( z|EN|^B!$;fhVbjI#W3H$NT#DN_YESrtF@j?AMi<&g6BSAttz!>H0QX);j`wr0up}C zR3-X9d(R5+8?MFhJFXSs@(PXKO8OQ?6h^9;Ojvj`*J5~c*MjsB+-KIM4v^|OiTFgV zztnAC`LoFK(1Rku=IHm+YW1{GI5K6JU6ydRsoKbF`OhZ7hkUefRH`NTXxC!+c-M;XL#ove2nr9U4B>gM z#qcAp1tUsur>c!~5xm}{U_`@ORcg^_&WPgh7IRzy2|s5qi{YQUR)m*Z zF}3niSYE~CfPhzUErw&)g7gvGE7qkBkm@;!cu}nv=vG%=iUgx8FGb?$b>+oia4KN< zOxH^AS*`^g!`E(VBlBW!#Y0^>N)bO%#q*QPS87ALm*Lp6FT;KEbsZ zKGC%Te1U3`l{xxpx95QjyrB`x1Z}|R>Of8V)$>Z{@vz#aB+o~ga zl|1%=85(&g9eN5rtj+V34I9rSOV;iInivuyQrK8~))DEsP;1MKE5H}I7Q@qBE5fh3 zR)!b2R)l}=S`7cewO}12wjZmFd|&`lJ!caBM6G{nwK_lo$vM*z#~)Miz<+Wrh8Mb4 zgwGn>$gUhwiz5nWtC*bW;B#Dy;d5OJ5 zc)u#boYe=NJ1nPT9aiRxxMOnkewy^gL(mTVE?CHt@yz&C?|L%@i(C zG0z$ME>GFOzgWW}Tiit9Nfq;)vG3WG4SaaXoXzh;;RqG;oU!l7lns28YcYJBYejg6 zAyNH5Nyqdi3OlMOjTYgZT#MnIT?+=3eS4*B;Ae+fqYIlUJf~t_Pucf!$_CzVM9LY3 zF)HRcW8e6c4Sd0R=4^fwg$q^8bH=`lQ#SA=uEp@Bt`*^#u9e{JS}l-;5ryqllt4=G z4z3m9om`9Ion0$5T>HOt;!X`j&f*}|b3P}Xqt=)vXR=mpWmDbeEI0GC+GEyO1@v0& z9$bS6e|)MN@K)latHrb+V1N{%J1>aH%YmKJXCfZoe`TqOb#zodv z1zg8!1>L<~t#9;N;QCf8xFYzYTEFhKz~NS_6C^`9SIO+!T5Baqgtu`mhPQXE2tTBn zjLHiUg@;py@I2RIn7>h%H+rMhzC*V%$HpigXs%9-;QQPxJE^{-yYMLU9!xn0k2go{ zQxxxV30y*Rq3?DA_gcYJSVyBS={89Te2Qx^%nemu>hPt9UL+j`sh)G9$K&_CwF2C) zsUb>hF}#dx1+8Kmd|j@JMDQcUdtG`+@%JvhruZ+HnzbF;6JNU1HtgaR>m(`gZXRX{ z-rcnzbbPI?HqspUZIgoGqt;L}se(J1)M)`L5C?xHBZ(V6U#p2$f-i6_h#Ozs)?5cT z&7>giuvV2?XIrfx?g_f-r(G+-zj7_;KfbP4 z8yPo{?<3|+`mk1&TE8$yLH~(^*UFP|gSXRHbdzy|c`HA$^WHZIUmsg@9pKjX>T$0T zEVNoxa0{yyj5cxb%6k$Ie3HiN)ww<0&c6@I|i0@WrkL5#Z|# zj{u~4P6Yf(lJl%qB|9WEdP%Br_)^zmm~SIWI*V{$eY-iC25>*uitsY7#c;v3pwq;5 zt%ctK;xebxVXZ2)Xf)>Qlc#hme`ijf#LQ}0v-V3>7U;I0>^UJ?vqt%^ zL5)SK&>S_g!$W%dr_uxua4m+HcdZCt=UNG_xmJYdxE8}db}bklVp~~lWEBFpFsbu+ zMP8TB$^B|-GR$gKKw^_|1_>$WB9CVIzNEY{7Qw`k(>@+=(Dsw10)Ei77=FmLASw8| z#rhJQ!Kwae$_@OIYcb5%Ad|4N^8;T`^xhoR`Icnj27Wcw9K67_BFq zVZJaUS`2S$FP(B$_z!J-WoxLiilWyFR(Wc7 zKXkaZcdZCdaxI2Wa4lE~=xn4m$=O4Z>N$_bTGV7& zt5pFBE@y79tJa(9RxVox!sE?TunvUP%C-H~+^Yq{NUtxo)+QI=BbRBUT{2vTk8&-@ z627jqC_BJ5t(J4BQ0sQ9RlQH~5tp)u&4Zx{)(2QyL6V-OH$xAHWh0Iy)4f(Nx9skxg3-(scFW7LZbVF5nQwHQ9$ zwIV#xwGw=iYprm9od|MtE{rG)P%$|=;bmPb!OOW;gjaAahGW;1dwMknC-M}ZG`ap6J4FKO8+9co7K+5u+c)*Yct#T%o^y`-Yc+dDZ zeoM9b34p@eDZ}2JZDpP50Qr7qPX7o2Q|TYL&>RJa;{@Gxm~Q*YeWpy8B4xfK8rSuS zh2+oIPmGfZ#U6g`cW}mHVllC0?`-wIT=FWn{CWDB1G|#l$j|ET71`a=J+m;fmYA^X zcWN@I{-RUj!fn|1N3~i0-)v?U&`HFy`m&TXGP8il(CC{~Mam2nuZ;y?JYrC;)YfHM zgTFPY6U1H4gNv?d4WCNvTPTPvJngtLMOJ?K;+;BkF?i!gXF2fTW$hiXz%iln?vZrE-o-k}yAi`DyHt{1ufFe6MRo_A!*xPJo1c&aI8JnC-JeqjW+)OUOkGK}YtE}7@=K69^VO15A`2ZJP3u510 z_wAjsf#7Bu>jI{rYnIjbFU{l;QA zIf7{-Sp;BjE?flIcTp-N_+i&#c%ExP=-27K+jJ|TgH+F%CU|@#O>=2{HjyJ~8jDcq-GGS2Y*t_7i+R+0tYX;OQmA^#VT z52rlCKh=Y@e*93lQ^jN3ljY~!Q0Dr6QgG3U34q+5}asK7dUivx_V+ujlu#Ir7F03sbME)uVISo4nb-M z*EgwaGsSyNY6m|usjG8n!^hRb%olj(x=3B%MJn})rZm?m%rLul@G6tKz@a1X)(*bB zAyU`Zipy-&kdn`K;8-=Wou-m4M{X@$sI|>`BD0bjflRCklS=AE@H3~18C=YH2>cktYTk$tUafHpui4nZH zn}Od>nZY}oSvz=wNnPMHlY*6M6P?80vdKJdYsDROo7{iG1&;|QK+U8;n~T_=a&My1A}%fcQWcby!9+uA`^ z;kf&r9&FMg2ifIzq;!HenpELP`PO>0*tvFV1JBm2_&QhdewPkdzhSlh23B!d9S0Jg zqylD|iZgIio3Rxp7}G_pPS#;ySQ2O1|47$5rN*9Sd1el?gh{<-n6!#E1t!1JWY&F- ztCk#BJ)x`MG2(U_;hwt9xiZ^Jca7`agn?(_P5K5i8Ir!i2iOD&`nHMgqPkRTfvGN9 z56lFU6(Y*~_g!_hpS4!WSVRPJgqwiwIEayx2s62VG_yG4-4m0C5ZMNp_nd5!%)sOI zm`E}MPgN~v)JN+sswbI&sh(s8COY}ysccje)z$Z{wIDMD@;`0@y5k@-M-Oi_b)s%% zI)VGxvE2@~tCaj~%}EqE;pSY^vWs(Va#&^mV=1{+eJ3{X+ZI9)`0sSr@6DtF{!OLa zABlZS&+VJoGSv-kqmuk$*wh*Y)-V}g(3i7rkY!EM2l@)v4L)XzUIk?F6ZfF6gWaHC zeFS-!twGP#?LfI2k-s8vO7hQ!wYRjzkGH)yYO~_M*-VnZVh}XV)yntuswK}Y`;JtbrEt5Ro+7r;ZPFun zJJU{VhObghjzy4DOYRTKaiw&j)vJKi%lY}F8EQSpYk|~~Lv7Bn+3~qm?H|%@GKMSY zY0j^}f~z5}K4zAqS3LPp+aucx z?rFw>Sx@ZSFVz}+fNL>))aDHj$sHVgv}-YZjB7#kU#Z^#W>cKDxk+f&J`J$Gjc(IW@RawL`R1q#dXyZ}*$DEM>M(?IEo?7b z;y=~!hG}f_*k#b&JJmZFtjX9APfIjoaZg}Ha+(y9)y26XCW}V1?$=L}lRs`{e;A9e zKGatn3S2WJhVU8QNDTM5797XAE7E(7e$`5fu29&Lk1==V~Zg41eKTFe3vyBMMD|h-l$2 zsg~e(U5nvGt`*^v^=DpXNn9LJI7P)|NrWf67Q?5y7Icx|R!|$6m>@25j_|Nnm0C2K zbA%Je>8W_&DXzsZzjd7S51!_BCHM!fwZcDitqh;<+9-I+a*cyb61%X8!Wk+`!=vCH z*UIoT*IMBpx>kbEa;*rT<5~=#>sl~SB=2_ZgbWl&h&cll)~ZsAPUH;KH?*;ABRO(w z)1>&^K=L)?#se0DM1N*lpcf&}lg_PfCcO{##K zX;*R{Law8`zOCE5+Ytuq{M4Yq7rGY17r9o1FLtd2&v303=BGMkmQHV?aH;;9qs-D) zc)DvPnBVkF4kLJ$+r{wZt_8D?&fcrR$?OAZCTAW|>p`nk1^3j(a^~!nYE1)6*A}&C zKweA&m(bSh+SVHuVFf(PBJ9dez4dh024+$LNoLMG&(=!bLmVW}E~iAR43^EttxeG? zE7fpB^Mj)^a;&luF?LsIL^9R|_)6Dem|ss#<^()k-``4>!id7UDkg^T2-jkGJ=cQC zLvW8;x;j8y=1haIR+U;bnlt5yqcs%|yuNEO%#X7s{ewSQku^@v2^9XRVqyq?>RJqc z=30;lf@{}6WM+f7%t=I8t4b{z%}E4te36O={?fG={>rr?+-FcD5z^-p+^z3c$Sj%G zLSZ~FT!ISs%xD)%Hm)|Z3!)1KtqrmQu%5zD*NX6}Yc-;;Uo255s+b%Y@M^Bb@anDw<4kauS_V77&DLzRxr8oZ zDoZ{{qd9|09BZWFf!A~`hKIRUgs(1HBIfp?aE*#dBH(LXi{a~B3lc$a2WX=*;TtXa zzoAJLYg)+Z^=E50JT$MP+vNGJ@{y&6mXl&)y+KW+Zw2`8LmJiUvw^~56%)h8ZvU5k zpQdc!TZfvnIZYI9Q!&pO`|eKJz=!Hb*F6L16_;Z39c34gIz1Zhq%@XAK_XV-h71her^+mEmV}= zm*Fj4YlXLRtpsoFS`psXwHW@kYX!JdH5u2rP1#JHpwXXgy%<@`+H9tum-8vV+%xQ} z(y{*OdbZY&)#F>bmCso~dMZa8LGGqOCZEPA5_isViSJ9b`GN9jZJ)wJJJn+tic0e8 zdt>&}qPuU;hQ3%s{vwr><+Z6*tjD9#_e}r!3j0Dn5&b`hd znOc3KlLyzRcYrq6Cpu$raEKnGHK$s86>t-+mvh5@s#?#sTJ7MERBDlz;noS7qas%Q zqJg{2-e8y7{aS0jIqY~`@oAGP;BzK*%3WOjzdbG3PLO`fs-yO{Aq-6VMc1{oZG7Fc zW}pz-4V<~a=A|(Cn|ezQF8J@N$$S7mPMN_?mWB?npGt{0cpWz@ zDUQ%>f4NPrcXI6-5;@LEBpqk;8>3E%@scYY@Yfo2pXkJ<8U@cuu%ce8_BZIZ@ke>5 zL_-mNsyiexcPh@;ZK^A(*k-c!mS06n)+qR0-6vWJe$TanIZ?pZWojdlfNz-;yk14E zOU$GS@{?tfw%_R9KbTdJp_=Y`%uFit6`yq}8#EpIR85iuz+?1-%OnBtSl5CC;H$sd zNCLpBNkIar)nq1BaBq`>-V(@CyIm{7<6SGk2fNk^|H!p6e6?$>@HMWL z;Okr~!gE}UVSaHd=|^^q=<88hPx1=lGH0PVOs)AqIXUiOqLV8lkN|QH?j?Dm?>RRy zXK4WZo?4D)8oj|YQh?{W7Q=VB7Gw!ux2cU}DVs=4ZZebLQzKgVO{yh$i#`p9GDc;1 zOV@&k@byP)t^@qgq+n);wW`!AYhyWQ;;>d5wT4)&;MjXz!}yzpQvpXD2H=Z7C@;-{ zKeeEOj0;DwQQOqT%PAP1^9f|V)z2ritr__mEcqQHJYkFzMwE!MH!3| ze5z|j_;lA|`1`H}eWw$%G!U7_;O<&Y1_-1TStCFik?)N*)hN)S+`tuPwG3+t?xA;8 z-~1uCWJ=O5LSAW#5ylJ^D*EUdxv?~t~v*Sq%oobr* zw2RiKn9bw@Jj=BhzTCAS^Z1&kHj;Ue>XLcTJxz?Wk+biLRBP}fuEp@9t_4xy>qd_X zq`E`}x~GZyHiyT?zJ;mQ;E(kUL7Cz&L=-+zG4K41v%h;-Aa5z=tRrEqDz#`#USNEH zXJ8h4Sg(zGf7Kv!uFm;Uvo9>h3b@#6jkiV=zE*4AL6y@M_+6_tu3PaUm%tZQlC))g zM+0;p)pNc)w2_)@s@vqZpU#lqdZxUm>V;@(JgX(ylWpa2wKzq$GLgX^m5TD@edO>$ zDfxHcH}c==`)()?n&g!XEUs3|mJGFzKT>6DI3B1`c~rx z{&r&lKH0SxKE<^lf{k_GR=QnYo+!uyJdoa_pQQU&Z0v85g&Grf(cB<4IZ=LR3mf(k z3O4fNVrG-=X0~Y=%WPBfMc6{tb#mvLbw#t2Q<;Fj?^+B$s9Jr&qQL9D$>72dd*z_f zXLR3hQZ{f=UkempWq38$0$=P~J!J#$=voZ#c*mhKv^+kVlvl36jB z@(!x6*wE9nfn7v0NKMkSfqg`Y&5~vVAuS>5Y;?;e7Y)q7Y+M6n>iFJlMDm5$)ZT1* zh9)tL+}*rC;O?%cv! zZPZ%HY6bT;cWWCYLD7%ozd%CS`T-cnTZjv#A7r0i2fA3l_miU^cHZqpr z%O(X6#m>ZwqLYm{dlMRyy`19^cMMbQI0Ei(Un1JvZUjO=7>zb zp8_sLkeDuALeA3A&(*D*MLW7mSg#n%TGRj>v( zYxRC9H}DwO%J5j%g67z_f64|v+qD=z$F*L49i}!prw^KQli*PhEu5Qb3BJ&^7=F>U zGW?QjG5oS?LFBYqQ=6Q~ss6i^8+d_hG5iPDitry@E5UzqtrdRLwKDv`a<<}6Yo@@< z*D~SC@Iz`SS}Q!ywG#ZOYejgzYcc$|YX$g4)#UUuO`q@kf=8ydS0hO#NIUW}L)KN! z`wgSi0kvDA0Z~hh68(^4H1rib=>D$yI>dsifFwyS|3gQ?$?ZgS@ZWWXTC=SAV5P<6 zzY8auZ21e^5gB3xo1>lxriaO|jKPd%Vwe4oeJ^R?$RJp({vLc8ZgMR)b}cv> z2kO4%Qa14NuEp>m*NX5Bs>uwUA5pk5WeDHoS`6RpTCc%vsWx&K2G&dp26u+;`jMFg z4>D==b~Q;d4X?UFV_cHs94@*R1j)YDQa12fuEp>VTx*4Y=voY)=~~bx`_4+)z~{LZ z!;iXFh97e+hUdH1Yn!vwCTHEI`r|1#@RP2^@F;z%R=>fcu(gVk{}|rJwID7U{cZ1Y z{Z4m%WG0o56^E;5xgY_(vG6xC*tdNuAox|+%J2f$g21oTeb?w#o{AM}6y~TXQyzRN zZI@j;Xz2H9l+0-O53a@VYpxaHT~=&(tsln}c2!Xv7UA7oi{af}3wla$Z)>B{DKOG% zIS&#)QENA;fIC>N;GB`Il{``2OwG5lYQdsG_RTW>U$n8*Awoky`DW zQS#TSmECi2iT5ov*;%&|5BQcz?b*h5*Ij#=Nd@#;K`(mL`WoFPj~n5I<|()bXAt;3 z_GI?K{CavaXz;t5B+<(7d#=Us`>q9pJ74!bsar`4NOf80KsK%?!}t=z7F$C=a)PBtlM?hf_&xcRPtJ6WxE zn!};Y5zu`HbL4sTnR1k!Mwrk*{SqTQ;P%Pn*=9 zjpzyW{Tq)6e95GCaDhtl&h-&B3h$d;1^mFIcJN;&RX`8Eoe1ByNGsrAOH2^_Q0;xJ zCb`2tPK^$=R8_!Ky^Dg+X-`*sqD(HZw$Si)urPz=_&Tk2k2eQ;t)M3lsP(VC7Ff2n zy0e4#g<7v_CY7S1*9wj&Cg|;{i3;E0S`6RgS`mJ7jYcdo^XE2EcuGZ?`9=7buEp@v zt_4TP#;Z3RZ>C$B#o$(2O;!zX2a_rw4d+~F)9$ZQ?ZeNx7Q=s8vk{B*rwqUAS`5GE zTF{@vb>B4IN`Ed@ywauYz!K?)7S+iSOsjHv5Wyb7#H_1`eeY{?$+`sp)wLM@yK6;w z|Fs%!>sR*_`0{Ep+;Eo~iWbA;Tnp0kjW*U#Z6rM))pOQlJa(r%!xLPK;n!R%!>_v* z!wX#tBE3)dJ*-=a6r{RLIS@}`l^qav{W;Yb{I+W`d=Os%mRSf-a4m)pb}a~gYu&fK zZY3;`>JmJNr<~x~b!e(F_;A-^_(<1^@X@Z7;A32Cg^zWu3{P@x6dVt+$vM4=!ip-& zL>vVVa;*#xcC8g&#kCS#bgc-l?ph45;aV^XB=0BM33;*vQccca*92#xkJNsJbs8O& zaRCV>=T_=#t#z8!Y6p8%lD}s=wMOASx64l1YjoEfGpT@cO2jliTk9^he!y#iUTfTc zs+F8}!)n0^w2wAIZ}MKSE2_=fx|L_s1$bW%G8++Nvu0{&;k8_g;UTUS;TKe^FQ62D zn=*u7bS;KoaxIus1h+3VXOSu%xr8{;+}qfAKVyiFQM6n9VO4)Rt_6v(?o`LI9_m6ih{GjWUxec)3Zzkw6?*t4R_#yhXEhCWg0kEl3@{Znow+ zK&t1Y4v)K}Jj1_otpq>gS`Y!gMyriv4xDdNkU467$4si=lO}b7wBI*6A(|8owNX=G z_ph~Pl2G`0*J60*mPW<;B^!lZRFujwysK*kxIJCDw@BWwK6HTil;Oy_${8VQHQN`b z%Qd*9n*5oJzdo>2J%k$C_P%d1`_Q_4-#hF>dr z5-r<2UzU$7O$TL7M(8fGo6|Zotg5ETbcV;c7Q=sbtqi~6S`5GGT5uH8=1FQJM=?nC zoLP#;w^E+rw_S_j_gpK&NA+!_NDjvN5rv~wl&%-yV_b{jV_gfnL~sMtM!E!2J?DwZ zvTD7Gc`ny>SN@K93f40MnPk=E4pI4b*JAh%*Mh+DHB)UQ@Y#w~6Dd2fsKpn6m^wOf9}%EY~1mt>A)#T4z~=qr+OkazOBRruq)w;fM#sq^ei=cHoTx2~@= z+9&J{fzA~)+SPTN^MXc;2Dyu7Mt<*b+8H%`(cOlc?I?BW*#ECODibT)%bdAJ7a!L& zCG!e?Q#F}a;Cm@E{z}hDHjv|HC^CA9H-Z?X!~%6D>P|2kCJA7ZaEvltYP8^!4R`c?@2wVccsIssb|Ca-N42mT7c{ zHAGg0rU4Dfr(73Pi4^5r9pK1owTHFZv$?xb=Q4|v96YqaFo={Lg`7hyyWq*|IrAe{ zKVCwYu)#mr@znO3;&J+9LarcASA1W$@}O$L6bhf4T_@OLCxi+(Q`J}+Q0=S zb-bxazw2$%^L1_Q?Z~EZi9Pqcb`b^sW$xjf*`2ep-=)dnX|mTPmQKXn?wPU5SgkV!>X0DkualaOKO6A zCqQdb9nD2=EgJ#Ot(K)!s@H<~!@fj+e` z8Fe|E3?}pGc8pd)KVZf&u3WX{te#w!?xC|VxgUl1bS;MWa;*qgTr0r`>-%QOL%Kc` z4)K@JO7Nks72(5Oi{T?&3$CB(!~_jQuAf0%=B)Q&tu|`WXwGs%Encxr9tgwqDf#FT z_P8fz2Qgybk*U7H(_M?<8LkC6z}FdSBRL4#Q$ZgmM#)&idaa&lF?@vD%NV{8Q8-e? z#1KBpwID9t6_pj_U<9`?smi)@ut^;edu% zKb2AVhlDEK4S%J3(ywZfmeR)Rlwtq6bVS`2^XS}>L*Z+BhPWh}vc`!xC>uNd-F z?k4q=^VVVLsEVTx?8A?7p`&q{J==ti+Hgci)Lle$l)*fT;!2xCC}*X@|YsmZj6)0VYPBB+^j6@0!%L^kpslJHBk{MM{I`uzDXcdEA%oDH(J z^4xHGc+Q}g`~<3ae55yz*pAYSG(1w;$@0_z;xxbMWAqWrpO$H)Dd*fYqtMv(if)s? zN&^qFN4Mj_ZEayH*I!JyPOW?0cQ6&14ga!`CKq7- zlB%rRF+5&>Q78GFpozkPDkg^TL9S`oHpwCyEvStwz97|e76d#_NO^`2b}fdFa;*q| zp_+t0w~4}+DMR=x*JAizt_58pxKq_eu4zE3=d8k{WOs!n+=wivCduIj4>E1X8oZ;q zs(^c`BtKc)RHMMdIhiK9+csw?aao!)316i9nxh?S@Lj5jEARo8>P=GMx=ZZ9`Dr_4 z+w7-wfo_|llOmXgI^z}`&8*ggeZ6Ln5H7G_PONyVUJ zPpZ+=x|Km04AaH{(Pp(wlK;#J`xVFdSI5Vk&J2f}l$f^bIuTr0AYB)P^#h=rX!2mnV zRd7vkh&FtL1<(fm#H4ZeD?a5C_>4;Zq8U5(+hWZchT!qjlF*GpSsu$RDPW7_*thq1Wp8 zq1L+A90hGn&|TC{R$%xNt2P=W4q3LQ)+o69VA*09f08FTFyY75eR53!KjB(%0OO0l zdy})4V{*Gi9!x+?+)Eos5II*S_ozdE&o9V7q5mS)1^6k~V)$v-iZHMDNlHpEulI@8 z3P0<0%kT@Xje@td+la~YBMRU0SCdA;Te((-{gtrEt?;&PSAw^5tqAYnS`6>#S}?XG z@27Tq7R*#k_=`DmB?S^)&UHJr2AShF(AydfK4bS{@?!wm1MK&jU~V{*GZswFa;^Zs z(Q4aT1l`~dOsYJhNCfg60{p_QK>n;t&eIB-!?&ENTQ-xw>ppZ?p@#Mo_xLZx0XjGX zqDf|s=B)*jeod{ufqMk$k<8l&p6_PhNShTicFkt|uR-eCNu7704d)&vSH9-&3w1W3y(tY@m{oFzT1)kdw^Rx7xk7^}N3F_VLAmMNT|yG}Ec3itz+`bCAKC*}NU01|PV z+R3p~fS2jp@SmI;;DT#G;_$W5!U*OBCU=`j75s%s?I5qa%KQfZ>Q>n-yrjF_B*^81 zYVwSEsqp$N9m~1SVb=z!zQfUHZ?>x6%C0)_ic6K=YW&Z6&ye)f%5|i$6)Uw}n#yH@8}yAW6#^fC=j0 zGjr6nj5-)$j)KQf=c+YX5y!8nG|*~QK;FS>i6-7%s8L!=4GU3EB!4DH_WY+#%7uHe zmhGneMnJKa?P%RH>+TedkiYsPL4zbnp1g*C5M^JjH&M4z4@}jYH#OVdQ)=%?YUi)= zFpH80kMIynTyVyt8U9L7GWp?Cw3=u!%-=}LJ4o<#oHZA$B$ym!Ccz1h*1N3rEouiT zA7RykD~zyOxi&ti7WDskH96TmgLG9!d`d8Z*vX%3O7a1proNKA!DqNugdcRR1V7|j z5q{XU7@p@^uvih>`D&AMD#YY$GpT~pP3i=%R!I(srW%Di+%7vk@$Lb%f%GZoL>tx$ zE*LJ*Hii?rJHX3`Gcppv}2I<-cD2_Q!bNb2O*#s_CR(?@-*WbQ|ULrrQMr+B_e z!7;Y1?iyhx`-8OK6djOlo_sO&a;}ER4Kp$4rj+mww6?3@4@_zUy%W{Tbng{rwLeIb z`$VUQ%Q!LZV)aIYxRi$lApOt12H0I)?5*48=(GsNfoM~*nWN8#S_mEASM&}BC(?;( zLN4T(%Q`07Usyns3-BLZi(x+1OqR#qd_AxAa#jJF`?Z-=L0XWh40>Y|i`mB5_nHS; zfET(J!+&DZACIC=Xp$*hqZ;yHLX|=}AQ6%1+1&PV?k(ws!8oY+SiXmDI zuj!iB@OmOt=-L}+NOB7NnPN*CUt|qGpP$C%A7-)=FYQP!6AVOVaQC)CYxX}NoHWyW@l{y z+vFo_nAV%4DTCohETT?uzDo6bAqr2LDDPEJ_^nsY#zC9JnsfHvOKW$Vm-Y#Y&$^U# ze1Ptv137uRNKGy`FBOpC%egXR`2M1`l1T}_=UNQ^)wLqL$h8vuH`iL>+5QGn8NSN3 zR`_byO7OL=72%p|F+9h$;Gm(eE2@ng>>w_4E^otHRcak(j=I1jP3i{ef}HO`qRcsH zXznXbpxpNs)F%#Q#RrepU47*{79&U0D3aZrbHf2z<4_B<0^&4hnv~Rfq;C5}XUvZ% z@Lrl+18lAP`D2dKLGUtbFnAD*$!=y+nWT88Zjou@p@&9cYICz>@^zSXrd{8QIP!I$gnX7xwf6t3|1 z)JDNqx>km-a;+7<+O-mVt!qWN=2{HTaVz~(Y~wKDALiK>Hf0%U7%YzcMODSNT&8;-OVfNd8a0NLv?Xg zfZbJf6OHj`3x8~OcFxn*mNk>$!tZ%CInqozK^zyN8S|#r|HeGZR5u2hKlPJgHjYKw z2)$1wg83xND9Dt_S?c&}q8D2L!Sw-ckYVw%rCN`&T4TVyO{#!&vMCw^PI0Sj*O)Qq zn@Mo_%|H=GGUo8ER;}8mNTWGd0%YbUHBCIhcbYb`2H$VmW;OUR(>AZczcg)&8qA;P zOn!q1e%0*0RfAtQZL1pmu4$u!6_b7Mna$(^{Jv{3%%AI&%Zwtt$H2xgh*pC4bgc;Q zrGUxm_NIkA*p2N#c+!WL%XK<-L+)RR*MC{+SmL?bAeO!y- zifcu9v}+}}-L+P@>RK5-z_n5ES?e{%Le4hRnkk&Eq72X|_#D^D@OiGa!WXz!f-iEd z2w&n_3}5P60Y0iV6=3%8C8HN>&t$~G4~934WyHbOb&)#3?M!M1C!5p>-fmJmIM1X` zkW5L7+2C`g9ihK#p;y5}^eg*vo&x#0yL|X~^Hd7|7({=%!Pb=;Qr+%4Eu6lx*?}*q zRJVIe3!klGc68t=9g&<(00jW9`5UCe7^s`tA=M0cF_ zUe0e|KkH}*_^L_4tv$h}`aa$Ieu8@kQ|XxAlN0LnrAfybeQ6p-|Pk4aU%i1pn4dQn<_B|u_Am4H!DmdWfX}JaPkzXv|Kina zl>6vvBdKPkSVo@?i^Q)fz2nk_y1ve}b-2YuIG25baRU=9;w|bPpYo-`t3HSiLq@BmIGHRqm^2gI3)(M?2TxgX~Pv2A*tY z<=Umn_nBGcGCigr(XD*LW@?SX2ew>|20vA4nP}NQU!5v%&h^*DU{&1?mhTY^lHV6O zC0b>$Y&LFfidI>v#@;P$>1g{bo`Kp zG)uQ4ap1jbXUbr3f29KGak@ z&+eh%S#ASUi{k8_?8%`%qja98u7qX>3*}{D3Qp6gKC@(wXCYk6=J0qH#A!C^#nv7jw$NuR5CKqd`4r};H^Im0$hMV^) z4f+sO!y&3NM4S(kQlOCbxE%#l&Q~Z-lj1XfW z&KL&rEfRB;bw;GH*Igtab$_v_Crm{bskqFJ(k^hGN#j876r@cswPGz=+7&DOl>>77 z6MM!{uE9SwZDb9;&$Mz4eoi%6c;D@z@Mg*oCUbSecAY%rFc~g5waC63EV7(?IQqof z%~L7(5RL;G%DNo|AJ=gp<6F0*K*;i-mf#p+k-*eoFU%S2aSZmwKC<9rCUt|1urvUs z276&J*kZ@glSDQh=QOX6%!&jnhj>9#342)xVfruRIjg~_<8 zDEzsUs!XB9u2(03+naRI0DZ)^fo`RVh7bQYr?b<0PS<$pY*RFWF5q4IKfNdGzb?A( z1})NI7-Y+H$0~{)E?uaX=X3osoxgOt`kD<#gQEJSr5v`4r>-vl#yMZR`Ajo6u+*p{ z*N+YGfB8duLoCS$%`9x7_M7XrPbA`nT9}m%-I01vWz+-~qNmBihG9tv03V~K8%Cl>W)DLm|UAdfNXb`*YWv$-2& z(X881SXoz4dDsuKsMhT$tnYRp&r0fc6js$kNBn`KRI1xi*iR>j*nuajRJWtBo}IF~ z!Hra^+fg{r?ZDJ^$MoR3BN;X>JYKP5x*O!lPQ48Z@3MX&vbq6>jxD0*|0`9QWHF1KlYPg=l4*UVV?z#zg9oD<8!>aUEUhRgdl6u zMz-%Pj`TO_RCYm;IlXj!@22luJty9Nt}~f4O`>I^$Qyy2U3cSFiZt!-KDt9PydY0>Y z&_|~mBoT51J&-s59takTX7x|cnxn02;UuvSMf|RH>l#esIhQK0=#l-FZj&Y9J>|dY zHs^^o)mQ^$E@uZ36Zbr__Djri;+m&rUbkrF->I@xq z{%1$+p`-TDQ82A1>gUBh_PKFz-+zwoy2?y~1RbWkjy03EGZm@bBJaAd)9cF486=s4 zd9Up}koVfo19`9Qggcig&v7 zGsT~~1m0>_m0jS2CRM;g>^7_mJkg{I*kNy0c7YR2s({|XU`5CdgpBm;p4T<#4?TGB zQB*lAmn|Op5yBYXZ$_(zS^N)rp?_u+@?O;W2mXcOr zUJ#bcYE{A1zKF>2C2gFUx=F>Es{L5El0)zYYjl$Q*oGE-y=nvZ z(yY~wTMB*vRzR{Wb`SJWV2UQOz~nx;cY~Rua)r(~oNGhV38rqf9|&%>lO`_LI?P7- z^3DVDCgiZD+O7Jb!&ADIPcF0Lc2$sr(fDJ+OW!{3p^$3i<3=MW!)(6TYw;(z#Iv*e zU8-qR&slVBuPDCmQa0e6iS~5QJK;n-Zz>ZlHGjhU?HqUWdp-=^U6ki8d|Ncf-2-_G zaW7X_*~1{2R#Q2xPP4fy;<;LQPPa0&U~0h*ufqPRU0cnTh3=)u@WLMIal9oH59UBk z<~ID8#+BH?seuSDqmI(c_2YD#e8(8R(6t!8$hAVY2lzTiZRD+^-b{XICRLDHedI?` zgDYi1!dQ%^)F@Ch=dOrwFG+JoUmN^-Q$oqDDgE=!9Pu2M1i0qyL6^k+r2kx2x4 z9^@sX-s%msdTrp)a>G~xTi7#I6MU|2>muoSHZ4;4+J>ZDgO{@*$+;Dx3(Ht2qrp@c zrcdpy3qAs4!Vwt52#{`hHHT!ASCRg+@3AzKifLL9(&hmFV!zwdM^Qjjf{FWR)GRype9@st3H=NB8Eb zG?423%|Y+~x<#XbFLW!t2RHpzs`nIjQc zS1aC?wxjTKw*x;-+pVR&-N<{rsE5KfDoP_{IF*Pn(>Ll=zFoJ=$dNnXn`Kt7A-rvK zz51Tw?mA^!qLbv;M=9N4<5Imzah^+$DgNH2Hx=JDsU7^#q-wv78mZh@x5-pERQX8V z%2fD);(aNz=agSHv+8D>G`#Jm+r-;g<->F<3)5waZ>G%Pew#L2Bv%8+DW9Lx+I3O- zAKfN)zgK=ErR||d*@3!E>|RuUSGO{X{Wohgx0-H6YSM$ukG~4YaVW>%oT=;UV8CX)P4SyPSE8?#1YW76zx6QunX#fi2Ww_llAjin-U z;Z9rd+L;L~Mq(8%LG9tf(w?0y5`T7P)N|{TqCrdz`XvqGij%fTOfHr$k+P1Ka>Of3 z9C5}}q6Z1AK9SAs`vk})VvoXJ}i{^)Zz6D3<9G7|vdMHd#QNjZcS1I{2n*7cU zMGhOW1n)?Dr0|S+Yy+P+kMg&qM${yrXXif@s=IdJN3SU%qJ@+Od4CF9{Egy5|d1>mIY)PloW!Vhz@X7 zTh_Y45hitjo0`-OZf{Zt$fc;X__eNwE7;=K4X$BQ2gvDCDuOJPGAn*El>%o_u>+ZF z_1Qy#MYUd;0#|l*%N9ND4zP>2?(DK#x8vfD;g^;{UqCy+AGtTsFO++x+6kUnk|av2 zFiT_rK_*PS7ugxZ%HFKkH{xm;MTRyN>kmD!vlNLrH-_M#tLZFc3MP{n_Abg$aZoHV zc+Mu5>G?kK26H7Vy*_U$g*#J*Fx{*hW(TD%W=|bSGueFC4YSGR1i!Lg0gBP09twV0 z*amWYR=1(Tx|sD_7qjlNx30-j$Gz*adZcNv*Ub?THj%{+Q5%hlI!G3jXSc{)K&e5D%RD)x6FS9 zr0KfdOx=H<+ksE0RJUV2TT|Dyx_GD-xYv_YGq-x2zeM7qodY>_0%!fJ_k#k9VZ8~K zh$ek7C6z%AmbzUwd9Uit`k!^1%o1+Z_tEt;85%gXZr+|Z4{s0V;hO3N4{{ft4dPmD z{KvYL;K2iQrpjvw-~^RqqJGvx;TS!j#SXmKqzV|@CEz%49g`~HD<+Kt|6o!Dyvi;V z$AO&6C4TUCZUw$=QUxTd5`FeuBvLkA6-~hYmYWJlI_kN})>}z07B{eq#tJyrB)h2o zwM$%7zwZ(k)jZdd+pp|XEs@9qmop+U8&~y-3Ud0*xs~IXV3A6uDQk0wF2{)mb44b3 zSlmP5Upj~)F6dcCM`4(5>mr4%eTYCV=jwJ8=wH$_OkeAU6u6E{3}LR_>V_0pa1%qA zlT6)^{E@7>m>ucE^kVxS-6q~xd{}uBjkJEC*TsnjZ|8^E;vNcn`;-G``l)nr4+S1A z$dLdtbQ1959tw3THKQ}M&T!YOFKsAXv(kl)Pv7?>ObqD@CRS^K(Z|nf40Qbr+V>O zUN1fiK6bfJm+as8(!HrJ_&e%W@|m5Vd+NMgWH*IlIotX(&9ThHt*qx`S>GnQbdusU zm*_87G4f*(980^~O~qKwpEF$IEXn{%#cb$PwO0>X?+z;InfkdPyb;$fc9C2>!s*Fdk$%6DyDmNnD^O zs}tN=*E;#V)~PiLEQI0>T-DZ+@u1JAPLOkpv@-51;35&1lLI0QQ(6d zi482-l&yfnP3ih)WsYtf!nI$I(9KsCu~KsU}q} zQoO?@@G+I-2BfJ*;VrWp3w~yHr#00mMB6mFlq|)H{dL%ZU0pK!lVkgnhui;0r)+WDh$E7CXEFd-<-dG!l*E&Ilnyd zZH;6Hj|d!NQrl6A$C^|DNs!#KouR>bM8RDgBQaDRHAmaj;Nj+cbgLo*A|C*dfy=a! zq^3{g26gJ>7;E#U0{SehhO@BBEPTpl*GWw^3cqo&x%Q$K7J3t8;BAY)$~bRf!xdzL z!()HT#EdcHlzsknfaJ6}nlUEZ?J%jE|BqHFQ+{zr~#im{irZ?{_l@qCf*G zh=?tNqJ~b>a~s5JrT`)kY{VG#bamC~?xJg=2I$5_agI{}m0S!esEH4wNzgk=JJ=3{gjA*BP()PPkABV5`>FtFMOfnVX0_V|37?`|iTDo+7^1mAoz;BgVG`QKBOo-rX>?Z(Ez#)9Ikapy zqVML=5{+tkWD6H_LEqw9v^e#)#9*3GCI%)VcJ$g@5bR$C{+7CAW^ z(SPJo&S69}*YPk0>y$@gwuBT;mh-Y>dVy z=UIiukIJ(t8b3PEsx)4iXN?*kHze0aTPJDaa6oFKMvafpvnq{OZ#E}s(WrV-;*|STs8z~Ggb(4~ei0%48S`t1ezLzb z7@-5a1i}$@+vc7;$Q`NFHTV}P8z6QoRUEFnmke;)xi?W z)h1L&YdXaA|Jkl)YqZan_&sP3MG2&x;-|d`nrjjAZbakHqEpG88noi-Tx<53l{Hrg zk^yFjDevQ3U)6@~P9N3V@MhG0+H6Y?MRaN&-GS&Y@<^kv0MU;Ymi4h-1`oAT)IPuS zYoDvd0i#>2Cope~!nA?Qx!{gL5{;tmI#E^(VNQt1lV4J=|7GBz7|VwteDDCTWl1Lv zlrV#E1H#v_oBi=Ia(xFvuN80poyh+@!v8?H9`?NX^*_pa7XCeRh$#AvlkjAO8xek9 z{!d1WB6gUB-~1oWfA$zDcQtkcpI3gzp`zc7@bmQglj>7peYK3cPCZtx9FI`{ z*2YhN@E6o;{sD;Wk5C_c^}09o>SsZ);B)eyf%$ti!gCOAMA!twGqeCt!F#du+kyG% zpBQgd7;hfA8G!lx|CN3u>~9z@C96NbIY`pO;n!Fn|1|$qu=5(iKO&Y7k_4l0aKHO_r(qC5J0y7&C z{s7^2gx=tr0ABsAULn%@fWHFsk)9$vgZaq&DBj0RWx6Mp3AUNabS5QXr^X`jjGIcD z%6KB0Do}zI zA-YI5gRw}63QUk0daJay#ZFtA)S*Ny=Emt_*lo*pIKfmf-r=$pn~cQU6B-Y;wWZuu znuNzEX<$j7qH?C@=vm<{F^ubY`XOK&pu0N`J4I$tauYZl}#C= zx3PD7yoj#z)>897+%G^WV;%-*#dzmwgX^yObz8`P(7_VTKV`oFrHq+^d1jrb!8}R( z&8E)^{NFi9^6$j@HP2eh`>*9_*hSa(734RACBHh_iu_*xfz29VR^)F*MOz{C zwx8DjLQno)hL!@CUMCkQ@ zD{;=R?H@q?0P_FaGGs(hQJgf}C|#KU1suq|u#2fN(fw_Zd-IlmH(e>rKkubxtDX0f zEgq(UHr2wJk zKi0$59S!%-;sy?`^+hza#k<`;@PK%`g5yb-7V((8(q(f`4FS)bTL1G*4;oMvhn`3a_hQUc(K13YI?C=7V}|7 z*TG^w-01pN%*&0gTg7~Y(e{WOQ99<_8;{?~C~%M(6QjKHBK~ zT+C@S>bzTUp}#rQ=zLm$X_S=yP@=!Vhcks@iudoc3l~9u;~Ct@*WZlySWx{DKD@$* zAK8cV{nL;7{T)xg^E@!Xy!V+m13y2MnZEtS>q437+h2{A_wBDa#JSw^VF8NeU*Do= z8MX7nShw{4UID%fT<48$;%sNF$Bv)>7g{?bO%?V9l(er6^j>C0nDql^f=Iw0nwFWq z{@+HN%iX)CxkrAoCM?`v4U9e&m!*B%PX%y6^ze6e#7_$Sc60sUSy#1INu-wHj~ zlVAKNTWtT?@_0Utd|xSqo-CeGzPeRZ={4uQTC z`iBn^{e$3X@GB1%&iitH@gH8XpGO`Nu<1jwSX@Dz?eB(ttuOyo7W1vB?@^TI*Jf~Y zQL{}i#RJF9;H{Sz^V`68Um*N&O7m+6c<%<`R|_`1;H_5)=kdy~2UYLkkAe?`{|AcP z@N&)mSAf&ZVqY(V2f(%5*T8peY_>Wb=YJz!YFtrc+Vg&MQ-dLpKa0-Ii{J{x;~V%Ot}upl|(Iv3;E&IiqfZyxU&jjBEJ_`1~1-=(tpVKnn z27apkO7IF#eQyDu2CjbI4;}!=$JOQq@U`Fv!yo=zDz4X7a4mNTZOfV853cLNMDU-3 z>wGvJ{1I?H*5UJgw(|_Q`WYu)>VD}a&f~fDV(Axc=PSWu9{ywSHQv>p$9xi>)H0DX!$*ULb!_vz)(KMVaB=x+dj7yNAS9k5dcJBNbr zg1+<8fF;+0zY6_9&};vG2z}XQqE|b^=)PqC$Aas;Gzq*GocD|TswK|#S`Yi`|H;s= zgMOvRjRXBI=ym*eLvJn*SmkrjUj+Rg=yT(3fRwuz{1E7GfSu=Hrw9Bl*lC3xA0L?~ zpkI7Nz$!0*{sr)-z&`?i2X=Zf-n1VF4wiO%^h&XF3-smS$?pk&7JM>sZny35N5}09 z=;y2xy{@MVz`Mcsr~31&1^m3L12(;c`jua2!TvV*IYco1MYoiDC%Dc7>%l+p=x+sI z4L@~0`3?95;FPqlKY;It`&adUBVKAg*+-nm+s=CfHvc(d#tfu|n|b|x!v9$&7lwgX z|62H5TJQNa8oawVVAIEgPXNF3H^R4qe+7K$gTi%QZ3K5cyjksg_(|ZGd-ziD8^Eu! zUKw*bc-8Nu+~KsI@hb>^;v)f@)_oD5J99gn{HSoX!+!|N{Ey&IqF(2NZ+~3$T^J9S zfgkpa@EsUG8^E7>LHLF6=ik6jeOdTYwEy+s+g=fVuaVae!9%YW^V`73|FM|=9Q;M_ zuffi}#O*wJPw~9^5O_Jb&SSg5E5N6~&ij^+F%>vZ(E0gO@BlbJNAc?bxYf1OoW2IUZcl(Ql_jrc@TNTh3kC@`OTh!+st)v0j~Wx8T0021OFs;)St(}mx3Pw{VU)r!6$?N75w|)AAs*8&i)?&f3&|w(?rewT>h4ntLy$0 z@E?I613Qi2Pk=X+$%O^P+5TR%&tcGqzzz6N@Na{cgKPh81m6m-e*P4EyGQ>J_-+s1 z4ZgOwc)WcKo&;C>BgrxLe=E3-ljDeU`@HpE0qc1j{vQv1>ifdK1HJ(KY4F?8K4-#y zuV);t0uP|v5wNok+<5pl@CtC9fB5eM+5hjtzRr^`f$s(%3H$GZZw1$K52TE2rxo_K zUnYZ(_1K>Q{-meBmV@_#tNkSSLU3}!zAgoC_4MOS;8h;|z2Frd{WIX}J^WqbrRMpM zh;#q;9w_5v3H;IhSou)lx*z)t`dQ%J&<~`6#CGll-vV9^e)=%6vl;wg;@r-cJS2P| zcqQ~7K)(^Z0s1ST*ZFw~^p_16JC~M8hO?k=gP8{5WM`1urk zJ-CkBLnud@cV1U z&J5U@3H~X#&gb*NC)A1l9N1X`zO`QXnXt1=?SOZIp8?+4Ao|&`(+YljqwwRPkAOc9 zJ_kGvKCVghgJ7o{eB$xK^||uf;M2iJL4O|j;;)H*D(qhZ{%!C_z}JD#nJ#+We{Ldf z=e@^-)AVj%H$rbt5Kbcd+6KM;7}8F`<|p74u%r9QyHxMtzb0O4Ts;Q;)_*T9_f_SO z7xTX=e?mAV?Q1Yin5FCwC(h%xA}RVM(2oI6f?o$do;ZKL^MdDdoTH&XaHZHe33{FP zmV@iOcO3MWf&aWrGStBSTORxM;Jd*GsD0vwKF^xu`8;T`)%X28@iZTOm(}3>r&xBuKuNrf^M!dq%Zq)O6 zYb*5coG$IQ1p_exUbkHA(DG+rY4CB^3;zoETJS4Q5U&0HJ@Ajfb-mjRerc!Zb-Zl@ zf2>P*3+&$wp8A&XYrr3}9EpP95757aez_b2;x+Ki@JIcB-^b2=v>~KReO_ZNA8IDg z2-s`dK9ha)jnI!iQS|r2;#}~jJ{11v{&Jy(IFE;&p8Kl<`ZMFAe-PuDzxTxBf7}_u z&lWT0Jn+#s2>%HDO4$F%V}B#`mv_l{NTJh3^1=5_}5w3Hsde68O}S;*aDq<{j`$#|qguUJU&W++8bN`~4H}A7MOq zirkE#2Rd%IOhEM7kK@5NVVs~_%vA8+(?qX7(=i=<0`*45JW1xNgFYxiR12(PW|Ciu@JYD$J_Np=e z8~lB=gWkWt2Oo&>uk+6<;0?!%9T#@~0>1Zr;WZeyAA;}stMDr5%MO-)Ip0(6Q1E|z zAo>?zXT0UeTo5!tKXR|=v7I!Fz{i1KhdgcI2Yc$31phwzcMjm1-aN zsf=D@Hi18fc|i5IgTL^p*f|pQx(9q9#)-E7?}(4+H_8M&>*>>04<`zOH(}=zPkX)( zZf1yw^N?qMI$$p~?;TbHO*#>Dm_+>C0o1jU;DiSzt(F2=LY+hf5`jEEh1r@xN}KeJoN%~)vbEw`qN-uV046-7i6 z%VFo{5z;T0LDLSNN(L;A>o4l)-6*ZJ_DSw7S} zgz>5K(*4$c{_o$^{u9ujH9-9T5z2TK{A!G!4d8zP@7^4+q!Rp}mLpLRlv4+By(&EY zHI_K{*AnbAFGZeXEiW*D=nNm;0y}3+6aRIdJOey}c}Aa)R)TNvjOR7PdHrpLpX$N6 z(Dx1vD6-+j;AJu4Ex5WF{0NNO?}PsYe9mC;b2U2PZt%lB^W<;AzdBRwYy1BJ{Ob3F zp8)%N!DlTOE_Vk#1JQ$Isrlzf%ZHk@5r1~}6GN5YAMOx4_rrcY_(8jc|D#MU%m%NX zE_@O6%fXL%NB9)*cFU0{2+oH7CETYgaqUv#rS?S|p`U>JYYFtXgP)L=dJP#Q7w)jU zpg=?)gZ`*h0ZSUt4$pxP#r{Ow|4-nL%@O^I5n^aBco6%vDX{Z*@Nb|UX!~SepMl@| zNx-HLhkp22xi9K)|LT5eyycR&@Vy55{sX1H!(nF@cp1i(-tSAn|NO3$tNX(d{J8$&&rax{1%CkZ!*$@VgU7HR-ZWe;ybnIqb3c|HCjAmdKkip1`f}nGuvr*P zg8p^PKl^a88vK^c0ZYyXKLLCc){*t#3&9^lJHSnID)^^p|H;tv@2l{OdpNIWS8~798Q!rn3fjQ0)I5`mciTcZP7$67J?yjgjvnhqJL*kCroM(QI4H+@;MY&v7)x#b`WV ziv8BIEhQODrQK9zhZ`r4>5Ihek*MqN_l%vW8}G<;lJzA^=d`qZ)0w+$(X5vFix)Xg zWlddOZC;!R1v9RXuC~tf^n_jdvT`<*F;t2ZiHF^88w*E5nPf1MvWd1xJdrGEq_)1P z$x5PSYB!alSh^>k33fY_NO00#pfDMv!g_i_oo=X$aj-3F^U=4X(^0Vz zcH2diswM^f+zsWTuWBbKq)UjUGl{fWw&w>#HjJv~l`n{kr# zCGAKeo901aU3A$6L#(>-bT;J{n6=H~B(v#GWTbDSyQz}R zUsu)8;B%qA&LondMA)UF6N#@1Mk8TI097{~N=1?x{^EUKls0WW85cQuoYSDQHqsfV zjRs+tvF}cV8Z;8`pw0^=vhj=)YR|?)Y%^`*G^XehjnY+aw4{GEP1OysLxU^qq_b^e zyX1&&tZuS*9C_knt+tUWNe;%{)uj~;Rn>kMO1EH5!?YTo9Mc+oE>ze0U1;*TP~&H+ z*3T5(+$Gznp~27HMxUBDR@M8MYV`4{v9@$QYOBZ;-FTra{TM{Zv?o$sd{^`E4Rtwg zESc%?LcT3lM`(I(Pq{8;%(NSA_v-BBk`=CRq?xw3B$-o6tLZ;b@u=X)0|MwaAK9NhjsDhiI{i#EX() z+7U!z!EP%Frc%KkCrLly!Wkrm{T2gMTCXDsK`N1n)>PY!xL|+#hVv!bR=6SBjleFF z>Bt(Yb*>!hgK+5z*VQyw9rE!Vn~qXDmK;VdQYzP=*2*tZiGb0%#kB)5vVs1W(%G zTQk?l{@Z~1nnE||`G9_&hciky=hG-Em`u8HpDNYY`Rp8O>wFg0TG}j^?5}#iEkzwI zTP1TeRQr_CR9AX-sA;OJDs8HXwu<>C$TcoTiZ_jJE^VrjOqF!Ei6-#U7yRnc=(m|_ zs`fF}SnJbPjed>TRO8o((|k-dR8K2ij|N&XN>;FrR{zo${M@Z;@~L25qt8-NU)4xG z=-9_an&-0dPPe<((9%UStKAbh;RO9SmH$FnM@vd3(dEW@elG1T&1zyQ8lhE!)_{_- z`Wl}BP+#LS^y{j5^wC2a{h}E8p3KryMz-CCA(~HYBu&qZ>^@CdcJ_4W**fWv8?lmJ zR5#J{LMivEo2sg~FnU}MQdymmsNb;FT_(?ajlC+clY3U1zT+tLiFi8tK2UkBa#W zJp!7xNQVt+@utTw0_0~l9>H^1Hq+kdP+Xp>?6ZF%vehVA<7(Rd$AWf45J@NGnJ=3T zc2IMs5*_@kPOjQS$faLDYYWj6p*+Mnv`EsEtxSw|5}f_bMa?JApG8eua79j5oUboj zJhOSBvv}^@Q|7cdEzL6*&f#N~XrwLVgwk2Z{$N`&nCY|+wp=;PuvnY8r2>JkFPuMf zmQ!6>U0KK7%>$qq@*zbi5f8V~X#w?*L zn>jibp-0tx4lXgB2`94j#~6iP4AZNXw~v`M4W20B40c8l8~NDGrKf{pU2 zP&{E)rV}Yo4aia^(^H(?W|Of?ZU@69uF^q@?Pl&O-K)@oPi++OG#mRu?(<<=Zc8SQ zb+&786vBPLH?}sK(;nj%RNFkM@TSr@uKg{(o*p?jvK`Jx1T^wlZs)jMgpOgT?rfIN zmFTcc+LCr|d|t!Pm~zs>9Y#k#mQsCX)n^H3r>#&bD9xTo($r?pMe_YF)2Iw!qFucE zvGTa@-ZcEsKpn)^W_>l z8Hr2W4kvPnQ?|x@i=~389$Rz1HS&#`&%wEKO&xamhvX4Rq9N9K;if!3DLk^8rB(x$qY)1J-BIcYo3 z3i-yh&T>Dpn(wRJ=%SY3Uy76=%)OHeXOo_cvZKr-xC}c{+1uLT>C&qtJGK>g%j(3^ z9VX_+Xt^ks;YOgjf!yJvOpHV6Tj_k$PS?`K`KY$?5VTSc0174<^1M$$1tW%^fzmpI zNE_2>W}KdLLONA-6*MkpTX>p|@F}*&-+*|?M*WiJR9JVh@d>iI(EIZ!>PD$vhg-LEDaY!?l8_P&(^kcxnB8M%8>OC(v5<(-P-+_o+B3EHt;DmL5c>0PHUE*rV% z*)?o1pB6V>(XBwuO~0&4?Zu0xj8VRg67eXVwbQtv-+;Ay6w>*5%JyiwigaKa|VAzfdGKDi8u7<6p8|NiTkC#YLFe2?49krF6dt{yB4OqDN^M*EbitaVg zGkqp;yMRyup+pkh&E2S7QsfRDLq|LtAj;U5pp8}g>J+V9#pBd*eD{yi7WU{jSLJ*g z^Km5)XAE>1)kXId>vI<4AW)T;I~9wYltnojxXzF;@2C$nT!Mw1>V z>B6h?wG-kKN2iUq*ZF3q0~ZzA-)^QUz0Yc3D`e+xHyPz;JzBB-rUG&UBUVP#{{eIN Biktud diff --git a/docs/content/2.download/osx_64/jq b/docs/content/2.download/osx_64/jq deleted file mode 100755 index c7b521ec27e91c90f110f32dc4b835b45d6cbc57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190556 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 E7nNM@YXATM diff --git a/docs/templates/index.liquid b/docs/templates/index.liquid index aaff1c9f..7785526c 100644 --- a/docs/templates/index.liquid +++ b/docs/templates/index.liquid @@ -16,8 +16,8 @@

From c181a9185ae14971ea78393a3552baadb56f1669 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 20 Dec 2012 12:25:50 +0000 Subject: [PATCH 42/62] Add a few lines to the bottom of the manpage. --- docs/Rakefile | 1 + docs/content/3.manual/manual.yml | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/docs/Rakefile b/docs/Rakefile index 375ce408..a95c97fa 100644 --- a/docs/Rakefile +++ b/docs/Rakefile @@ -90,6 +90,7 @@ task :manpage do end f.puts "" end + f.puts manual['manpage_epilogue'] f.close puts Ronn::Document.new(f.path).convert('roff').gsub(/<\/?code>/,"") end diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 5acb212c..cf5de527 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -50,6 +50,17 @@ manpage_intro: | document. ## FILTERS + +manpage_epilogue: | + ## BUGS + + Presumably. Report them or discuss them at: + + https://github.com/stedolan/jq/issues + + ## AUTHOR + + Stephen Dolan `` sections: - title: Invoking jq From a05904b2267d53f9a305d010facd6f307a9d5373 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 20 Dec 2012 12:26:15 +0000 Subject: [PATCH 43/62] Version 1.2! --- VERSION | 2 +- docs/site.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 9459d4ba..5625e59d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1 +1.2 diff --git a/docs/site.yml b/docs/site.yml index df758cef..863d578d 100644 --- a/docs/site.yml +++ b/docs/site.yml @@ -1,7 +1,7 @@ # The key value pairs found below are available within the templates. -jq_version: 1.1 +jq_version: 1.2 root: '/jq' footer: | From 5578ec0f6981e9c01d92f0cda65dfc02605a030c Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 20 Dec 2012 15:12:14 +0000 Subject: [PATCH 44/62] Give Windows builds a proper .exe suffix. --- Makefile | 15 +++++++++++---- docs/content/2.download/default.yml | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 30e6d42d..69e97c71 100644 --- a/Makefile +++ b/Makefile @@ -53,12 +53,19 @@ build/osx64%: CC='i686-apple-darwin10-gcc -m64' build/win32%: CC='i686-w64-mingw32-gcc -m32' EXTRA_CFLAGS=-DJQ_DEFAULT_ENABLE_COLOR=0 build/win64%: CC='x86_64-w64-mingw32-gcc -m64' EXTRA_CFLAGS=-DJQ_DEFAULT_ENABLE_COLOR=0 -ALL_BINARIES=$(foreach platform, $(PLATFORMS), $(foreach binary, $(BINARIES), build/$(platform)/$(binary))) +BIN_SUFFIX_win32 = .exe +BIN_SUFFIX_win64 = .exe + +ALL_BINARIES=\ + $(foreach platform, $(PLATFORMS), \ + $(foreach binary, $(BINARIES), \ + build/$(platform)/$(binary)$(BIN_SUFFIX_$(platform)))) $(ALL_BINARIES): build/%: mkdir -p $(@D) + echo $(dir $*) make -B $(BINARIES) CC=$(CC) - cp $(BINARIES) $(@D) + $(foreach binary, $(BINARIES), cp $(binary) $(@D)/$(binary)$(suffix $*);) binaries: $(ALL_BINARIES) @@ -97,6 +104,6 @@ docs/output: cd docs; rake build www_binaries: docs/output binaries - $(foreach platform, $(PLATFORMS), $(foreach binary, $(BINARIES), \ + $(foreach platform, $(PLATFORMS), \ mkdir -p docs/output/download/$(platform); \ - cp build/$(platform)/$(binary) docs/output/download/$(platform)/$(binary); )) + cp build/$(platform)/* docs/output/download/$(platform)/; ) diff --git a/docs/content/2.download/default.yml b/docs/content/2.download/default.yml index f364277b..502ef0b4 100644 --- a/docs/content/2.download/default.yml +++ b/docs/content/2.download/default.yml @@ -38,7 +38,7 @@ body: ### Windows - * Executables for [64-bit](win64/jq) or [32-bit](win32/jq) + * Executables for [64-bit](win64/jq.exe) or [32-bit](win32/jq.exe) ### From source on Linux or OS X From 0fed03f35a63c01e89c0ba91cfe92dfc226d1e86 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 23 Dec 2012 15:41:20 +0000 Subject: [PATCH 45/62] Fix a bad memory leak when using --raw-output --- main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/main.c b/main.c index 0ab0f3ca..fd482122 100644 --- a/main.c +++ b/main.c @@ -68,6 +68,7 @@ static void process(jv value) { while (jv_is_valid(result = jq_next())) { if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) { fwrite(jv_string_value(result), 1, jv_string_length(jv_copy(result)), stdout); + jv_free(result); } else { int dumpopts; #ifdef JQ_DEFAULT_ENABLE_COLOR From cedda2084d2f6b331ba0a73e05f0b77ee7995c86 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 24 Dec 2012 17:11:18 +0000 Subject: [PATCH 46/62] Sneaky valgrind trick to detect stack memory issues. After something is popped from a stack, we overwrite the memory with uninitialised data (if JQ_DEBUG is on). This means that valgrind reports use-after-pop as an uninitialised memory error. --- forkable_stack.h | 13 +++++++++++-- jv_alloc.c | 9 +++++++++ jv_alloc.h | 11 +++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/forkable_stack.h b/forkable_stack.h index c96c132e..74fcf433 100644 --- a/forkable_stack.h +++ b/forkable_stack.h @@ -100,13 +100,22 @@ static void* forkable_stack_peek_next(struct forkable_stack* s, void* top) { // Returns 1 if the next forkable_stack_pop will permanently remove an // object from the stack (i.e. the top object was not saved with a fork) static int forkable_stack_pop_will_free(struct forkable_stack* s) { - return s->pos < s->savedlimit ? 1 : 0; + return s->pos < s->savedlimit; } static void forkable_stack_pop(struct forkable_stack* s) { forkable_stack_check(s); struct forkable_stack_header* elem = forkable_stack_peek(s); - s->pos += elem->next_delta; + int reclaim_upto = s->pos + elem->next_delta < s->savedlimit ? + s->pos + elem->next_delta : s->savedlimit; + assert(reclaim_upto <= s->length); + int reclaimed = reclaim_upto > s->pos ? reclaim_upto - s->pos : 0; + assert(0 <= reclaimed && s->pos + reclaimed <= s->length); + // s->pos <= i < reclaim_upto means that position i is to be freed + assert((reclaimed > 0) == forkable_stack_pop_will_free(s)); + int new_pos = s->pos + elem->next_delta; + jv_mem_invalidate(elem, reclaimed); + s->pos = new_pos; } diff --git a/jv_alloc.c b/jv_alloc.c index 320f16e1..e127029d 100644 --- a/jv_alloc.c +++ b/jv_alloc.c @@ -26,3 +26,12 @@ void* jv_mem_realloc(void* p, size_t sz) { } return p; } + +#if JQ_DEBUG +volatile char jv_mem_uninitialised; +__attribute__((constructor)) void jv_mem_uninit_setup(){ + char* p = malloc(1); + jv_mem_uninitialised = *p; + free(p); +} +#endif diff --git a/jv_alloc.h b/jv_alloc.h index 0613d587..b4e72c0d 100644 --- a/jv_alloc.h +++ b/jv_alloc.h @@ -3,6 +3,17 @@ #include +#if JQ_DEBUG +extern volatile char jv_mem_uninitialised; +#endif + +static void jv_mem_invalidate(void* mem, size_t n) { +#if JQ_DEBUG + char* m = mem; + while (n--) *m++ ^= jv_mem_uninitialised ^ jv_mem_uninitialised; +#endif +} + void* jv_mem_alloc(size_t); void jv_mem_free(void*); __attribute__((warn_unused_result)) void* jv_mem_realloc(void*, size_t); From d327772dfc78ad49f46fbf583418e33abc0b59d2 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 27 Dec 2012 01:56:23 +0000 Subject: [PATCH 47/62] JSON parsing error messages now specify a location of the error. Should help with #53. --- jv_parse.c | 9 ++++++++- jv_parse.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/jv_parse.c b/jv_parse.c index 0d4f1549..f55c17e5 100644 --- a/jv_parse.c +++ b/jv_parse.c @@ -26,6 +26,8 @@ void jv_parser_init(struct jv_parser* p) { p->curr_buf = 0; p->curr_buf_length = p->curr_buf_pos = p->curr_buf_is_partial = 0; p->bom_strip_position = 0; + p->line = 1; + p->column = 0; jvp_dtoa_context_init(&p->dtoa); } @@ -294,6 +296,11 @@ static int check_done(struct jv_parser* p, jv* out) { } static pfunc scan(struct jv_parser* p, char ch, jv* out) { + p->column++; + if (ch == '\n') { + p->line++; + p->column = 0; + } presult answer = 0; if (p->st == JV_PARSER_NORMAL) { chclass cls = classify(ch); @@ -373,7 +380,7 @@ jv jv_parser_next(struct jv_parser* p) { if (msg == OK) { return value; } else if (msg) { - return jv_invalid_with_msg(jv_string(msg)); + return jv_invalid_with_msg(jv_string_fmt("%s at line %d, column %d", msg, p->line, p->column)); } else if (p->curr_buf_is_partial) { assert(p->curr_buf_pos == p->curr_buf_length); // need another buffer diff --git a/jv_parse.h b/jv_parse.h index 5958316a..1d538c12 100644 --- a/jv_parse.h +++ b/jv_parse.h @@ -16,6 +16,8 @@ struct jv_parser { char* tokenbuf; int tokenpos; int tokenlen; + + int line, column; struct dtoa_context dtoa; From 52db8000c6e0564e92fdba72687e338dc603e02d Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 27 Dec 2012 01:57:09 +0000 Subject: [PATCH 48/62] Fix an embarassing I/O bug. Pulling some I/O out to a function meant that buf changed from "char buf[4096]" to "char* buf", and "sizeof(buf)" got a lot less interesting. The upshot of this is that jq read input eight bytes at a time, which is not the fastest. --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index fd482122..e18f6fdd 100644 --- a/main.c +++ b/main.c @@ -135,7 +135,7 @@ static int read_more(char* buf, size_t size) { next_input_idx++; } - if (!fgets(buf, sizeof(buf), current_input)) buf[0] = 0; + if (!fgets(buf, size, current_input)) buf[0] = 0; return 1; } From 89e26969ae5bc7a259c1bd150f4d58c67800424b Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 27 Dec 2012 20:49:34 +0000 Subject: [PATCH 49/62] @foo syntax for encoding of strings into various formats. Fixes part of #47 and #48. --- builtin.c | 171 +++++++++++++++++++++++++++++++ docs/content/3.manual/manual.yml | 141 ++++++++++++++++++------- lexer.l | 3 + parser.y | 20 +++- testdata | 14 +++ 5 files changed, 307 insertions(+), 42 deletions(-) diff --git a/builtin.c b/builtin.c index 4f9fab59..c431be07 100644 --- a/builtin.c +++ b/builtin.c @@ -5,6 +5,8 @@ #include "parser.h" #include "locfile.h" #include "jv_aux.h" +#include "jv_unicode.h" + typedef jv (*func_1)(jv); @@ -207,6 +209,174 @@ static jv f_tostring(jv input) { } } +#define CHARS_ALPHANUM "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + +static jv escape_string(jv input, const char* escapings) { + + assert(jv_get_kind(input) == JV_KIND_STRING); + const char* lookup[128] = {0}; + const char* p = escapings; + while (*p) { + lookup[(int)*p] = p+1; + p++; + p += strlen(p); + p++; + } + + jv ret = jv_string(""); + const char* i = jv_string_value(input); + const char* end = i + jv_string_length(jv_copy(input)); + const char* cstart; + int c = 0; + while ((i = jvp_utf8_next((cstart = i), end, &c))) { + assert(c != -1); + if (c < 128 && lookup[c]) { + ret = jv_string_append_str(ret, lookup[c]); + } else { + ret = jv_string_append_buf(ret, cstart, i - cstart); + } + } + jv_free(input); + return ret; + +} + +static jv f_format(jv input, jv fmt) { + if (jv_get_kind(fmt) != JV_KIND_STRING) { + jv_free(input); + return type_error(fmt, "is not a valid format"); + } + const char* fmt_s = jv_string_value(fmt); + if (!strcmp(fmt_s, "json")) { + jv_free(fmt); + return jv_dump_string(input, 0); + } else if (!strcmp(fmt_s, "text")) { + jv_free(fmt); + return f_tostring(input); + } else if (!strcmp(fmt_s, "csv")) { + jv_free(fmt); + if (jv_get_kind(input) != JV_KIND_ARRAY) + return type_error(input, "cannot be csv-formatted, only array"); + jv line = jv_string(""); + for (int i=0; i>\0''\0\""\0"); + } else if (!strcmp(fmt_s, "uri")) { + jv_free(fmt); + input = f_tostring(input); + + int unreserved[128] = {0}; + const char* p = CHARS_ALPHANUM "-_.!~*'()"; + while (*p) unreserved[(int)*p++] = 1; + + jv line = jv_string(""); + const char* s = jv_string_value(input); + for (int i=0; i= 3 ? 3 : len-i; + for (int j=0; j<3; j++) { + code <<= 8; + code |= j < n ? (unsigned)data[i+j] : 0; + } + char buf[4]; + for (int j=0; j<4; j++) { + buf[j] = b64[(code >> (18 - j*6)) & 0x3f]; + } + if (n < 3) buf[3] = '='; + if (n < 2) buf[2] = '='; + line = jv_string_append_buf(line, buf, sizeof(buf)); + } + jv_free(input); + return line; + } else { + jv_free(input); + return jv_invalid_with_msg(jv_string_concat(fmt, jv_string(" is not a valid format"))); + } +} + static jv f_keys(jv input) { if (jv_get_kind(input) == JV_KIND_OBJECT || jv_get_kind(input) == JV_KIND_ARRAY) { return jv_keys(input); @@ -332,6 +502,7 @@ static struct cfunction function_list[] = { {(cfunction_ptr)f_min_by_impl, "_min_by_impl", 2}, {(cfunction_ptr)f_max_by_impl, "_max_by_impl", 2}, {(cfunction_ptr)f_error, "error", 2}, + {(cfunction_ptr)f_format, "format", 2}, }; static struct symbol_table cbuiltins = diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index cf5de527..55f43a00 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -75,51 +75,51 @@ sections: You can affect how jq reads and writes its input and output using some command-line options: - * `--slurp`/`-s`: + * `--slurp`/`-s`: - Instead of running the filter for each JSON object in the - input, read the entire input stream into a large array and run - the filter just once. - - * `--raw-input`/`-R`: - - Don't parse the input as JSON. Instead, each line of text is - passed to the filter as a string. If combined with `--slurp`, - then the entire input is passed to the filter as a single long - string. + Instead of running the filter for each JSON object in the + input, read the entire input stream into a large array and run + the filter just once. + + * `--raw-input`/`-R`: + + Don't parse the input as JSON. Instead, each line of text is + passed to the filter as a string. If combined with `--slurp`, + then the entire input is passed to the filter as a single long + string. - * `--null-input`/`-n`: + * `--null-input`/`-n`: - Don't read any input at all! Instead, the filter is run once - using `null` as the input. This is useful when using jq as a - simple calculator or to construct JSON data from scratch. + Don't read any input at all! Instead, the filter is run once + using `null` as the input. This is useful when using jq as a + simple calculator or to construct JSON data from scratch. - * `--compact-output` / `-c`: + * `--compact-output` / `-c`: - By default, jq pretty-prints JSON output. Using this option - will result in more compact output by instead putting each - JSON object on a single line. + By default, jq pretty-prints JSON output. Using this option + will result in more compact output by instead putting each + JSON object on a single line. - * `--colour-output` / `-C` and `--monochrome-output` / `-M`: - - By default, jq outputs colored JSON if writing to a - terminal. You can force it to produce color even if writing to - a pipe or a file using `-C`, and disable color with `-M`. + * `--colour-output` / `-C` and `--monochrome-output` / `-M`: + + By default, jq outputs colored JSON if writing to a + terminal. You can force it to produce color even if writing to + a pipe or a file using `-C`, and disable color with `-M`. - * `--ascii-output` / `-a`: + * `--ascii-output` / `-a`: - jq usually outputs non-ASCII Unicode codepoints as UTF-8, even - if the input specified them as escape sequences (like - "\u03bc"). Using this option, you can force jq to produce pure - ASCII output with every non-ASCII character replaced with the - equivalent escape sequence. + jq usually outputs non-ASCII Unicode codepoints as UTF-8, even + if the input specified them as escape sequences (like + "\u03bc"). Using this option, you can force jq to produce pure + ASCII output with every non-ASCII character replaced with the + equivalent escape sequence. - * `--raw-output` / `-r`: + * `--raw-output` / `-r`: - With this option, if the filter's result is a string then it - will be written directly to standard output rather than being - formatted as a JSON string with quotes. This can be useful for - making jq filters talk to non-JSON-based systems. + With this option, if the filter's result is a string then it + will be written directly to standard output rather than being + formatted as a JSON string with quotes. This can be useful for + making jq filters talk to non-JSON-based systems. - title: Basic filters entries: @@ -646,10 +646,77 @@ sections: input: '42' output: ['"The input was 42, which is one less than 43"'] - + - title: "Format strings and escaping" + body: | - + The `@foo` syntax is used to format and escape strings, + which is useful for building URLs, documents in a language + like HTML or XML, and so forth. `@foo` can be used as a + filter on its own, the possible escapings are: + * `@text`: + + Calls `tostring`, see that function for details. + + * `@json`: + + Serialises the input as JSON. + + * `@html`: + + Applies HTML/XML escaping, by mapping the characters + `<>&'"` to their entity equivalents `<`, `>`, + `&`, `'`, `"`. + + * `@uri`: + + Applies percent-encoding, by mapping all reserved URI + characters to a `%xx` sequence. + + * `@csv`: + + The input must be an array, and it is rendered as CSV + with double quotes for strings, and quotes escaped by + repetition. + + * `@sh`: + + The input is escaped suitable for use in a command-line + for a POSIX shell. If the input is an array, the output + will be a series of space-separated strings. + + * `@base64`: + + The input is converted to base64 as specified by RFC 4648. + + This syntax can be combined with string interpolation in a + useful way. You can follow a `@foo` token with a string + literal. The contents of the string literal will *not* be + escaped. However, all interpolations made inside that string + literal will be escaped. For instance, + + @uri "http://www.google.com/search?q=\(.search)" + + will produce the following output for the input + `{"search":"jq!"}`: + + http://www.google.com/search?q=jq%21 + + Note that the slashes, question mark, etc. in the URL are + not escaped, as they were part of the string literal. + + examples: + - program: '@html' + input: '"This works if x < y"' + output: ['"This works if x < y"'] + +# - program: '@html "Anonymous said: \(.)"' +# input: '""' +# output: ["Anonymous said: <script>alert("lol hax");</script>"] + + - program: '@sh "echo \(.)"' + input: "\"O'Hara's Ale\"" + output: ["\"echo 'O'\\''Hara'\\''s Ale\""] - title: Conditionals and Comparisons entries: diff --git a/lexer.l b/lexer.l index 7090de31..12851de8 100644 --- a/lexer.l +++ b/lexer.l @@ -68,6 +68,9 @@ struct lexer_param; return try_exit(yytext[0], YY_START, yyscanner); } +"@"[a-zA-Z0-9_]+ { + yylval->literal = jv_string_sized(yytext + 1, yyleng - 1); return FORMAT; +} -?[0-9.]+([eE][+-]?[0-9]+)? { yylval->literal = jv_parse_sized(yytext, yyleng); return LITERAL; diff --git a/parser.y b/parser.y index 807db704..397982d6 100644 --- a/parser.y +++ b/parser.y @@ -48,6 +48,7 @@ struct lexer_param; %token INVALID_CHARACTER %token IDENT %token LITERAL +%token FORMAT %token EQ "==" %token NEQ "!=" %token DEFINEDOR "//" @@ -158,8 +159,8 @@ static block gen_binop(block a, block b, int op) { return gen_call(funcname, BLOCK(gen_lambda(a), gen_lambda(b))); } -static block gen_format(block a) { - return BLOCK(a, gen_call("tostring", gen_noop())); +static block gen_format(block a, jv fmt) { + return BLOCK(a, gen_call("format", BLOCK(gen_lambda(gen_const(fmt))))); } static block gen_update(block a, block op, int optype) { @@ -316,10 +317,16 @@ FuncDef: String: -QQSTRING_START QQString QQSTRING_END { - $$ = $2; +QQSTRING_START { $$ = jv_string("text"); } QQString QQSTRING_END { + $$ = $3; + jv_free($2); +} | +FORMAT QQSTRING_START { $$ = $1; } QQString QQSTRING_END { + $$ = $4; + jv_free($3); } + QQString: /* empty */ { $$ = gen_const(jv_string("")); @@ -328,7 +335,7 @@ QQString QQSTRING_TEXT { $$ = gen_binop($1, gen_const($2), '+'); } | QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END { - $$ = gen_binop($1, gen_format($3), '+'); + $$ = gen_binop($1, gen_format($3, jv_copy($0)), '+'); } @@ -373,6 +380,9 @@ LITERAL { String { $$ = $1; } | +FORMAT { + $$ = gen_format(gen_noop(), $1); +} | '(' Exp ')' { $$ = $2; } | diff --git a/testdata b/testdata index a1c72f0d..c3352af4 100644 --- a/testdata +++ b/testdata @@ -52,6 +52,20 @@ null null "interpolation" +@text,@json,([1,.] | @csv),@html,@uri,@sh,@base64 +"<>&'\"" +"<>&'\"" +"\"<>&'\\\"\"" +"1,\"<>&'\"\"\"" +"<>&'"" +"%3c%3e%26'%22" +"'<>&'\\''\"'" +"PD4mJyI=" + +@html "\(.)" +"" +"<script>hax</script>" + # # Dictionary construction syntax # From 9302b16247eb124c23cc7cf091822afc503105d3 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Fri, 28 Dec 2012 14:21:28 +0000 Subject: [PATCH 50/62] Docs typos. --- docs/content/3.manual/manual.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 55f43a00..fd91ef13 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -748,8 +748,8 @@ sections: means that you'll sometimes have to be more explicit about the condition you want: you can't test whether, e.g. a string is empty using `if .name then A else B end`, you'll - need something more like 'if (.name | count) > 0 then A else - B end' instead. + need something more like `if (.name | count) > 0 then A else + B end` instead. If the condition A produces multiple results, it is considered "true" if any of those results is not false or @@ -872,8 +872,8 @@ sections: For instance, calculating the average value of an array of numbers requires a few variables in most languages - at least one to hold the array, perhaps one for each element or for a loop counter. In jq, it's - simply `add / length` - the `sum` expression is given the array and - produces its sum, and the `count` expression is given the array and + simply `add / length` - the `add` expression is given the array and + produces its sum, and the `length` expression is given the array and produces its length. So, there's generally a cleaner way to solve most problems in jq that From 417899f9a02f8957e30fc6252cf0e02b713c4c4a Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Fri, 28 Dec 2012 15:04:16 +0000 Subject: [PATCH 51/62] Fold operation (code/docs/test) --- compile.c | 11 +++++++++ compile.h | 1 + docs/content/3.manual/manual.yml | 39 +++++++++++++++++++++++++++++++- lexer.l | 1 + parser.y | 6 +++++ testdata | 4 ++++ 6 files changed, 61 insertions(+), 1 deletion(-) diff --git a/compile.c b/compile.c index 139b64bc..178b0463 100644 --- a/compile.c +++ b/compile.c @@ -306,6 +306,17 @@ block gen_collect(block expr) { gen_op_var_bound(LOADV, array_var)); } +block gen_fold(const char* varname, block init, block fold) { + block loop = BLOCK(fold, gen_op_var_unbound(STOREV, varname), gen_op_simple(BACKTRACK)); + return BLOCK(gen_op_simple(DUP), + init, + block_bind(gen_op_var_unbound(STOREV, varname), + BLOCK(gen_op_target(FORK, loop), + loop, + gen_op_var_unbound(LOADV, varname)), + OP_HAS_VARIABLE)); +} + block gen_assign(block expr) { block result_var = block_bind(gen_op_var_unbound(STOREV, "result"), gen_noop(), OP_HAS_VARIABLE); diff --git a/compile.h b/compile.h index e74afce4..ce1b3089 100644 --- a/compile.h +++ b/compile.h @@ -33,6 +33,7 @@ block gen_call(const char* name, block body); block gen_subexp(block a); block gen_both(block a, block b); block gen_collect(block expr); +block gen_fold(const char* varname, block init, block body); block gen_assign(block expr); block gen_definedor(block a, block b); block gen_condbranch(block iftrue, block iffalse); diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index fd91ef13..1de1a387 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -841,7 +841,7 @@ sections: input: '{}' output: [42] - - title: Variables and Functions + - title: Advanced features body: | Variables are an absolute necessity in most programming languages, but they're relegated to an "advanced feature" in jq. @@ -858,6 +858,10 @@ sections: (many jq functions such as `map` and `find` are in fact written in jq). + Finally, jq has a `fold` operation, which is very powerful but a + bit tricky. Again, it's mostly used internally, to define some + useful bits of jq's standard library. + entries: - title: Variables body: | @@ -962,6 +966,39 @@ sections: - program: 'def addvalue(f): f as $x | map(. + $x); addvalue(.[0])' input: '[[1,2],[10,20]]' output: ['[[1,2,1,2], [10,20,1,2]]'] + + - title: Fold + body: | + + The `fold` syntax in jq allows you to combine all of the + results of an expression by accumulating them into a single + answer. As an example, we'll pass `[3,2,1]` to this expression: + + fold 0 as $sum (.[] | $sum + .) + + The variable `$sum` is first given the value `0`. The body + of the fold (i.e. `.[] | $sum + .`) is evaluated. `.[]` + produces three results, `3`, `2`, and `1`. For the first + one, `$sum + .` gives `3`. + + Having produced this answer, jq backtracks to find the next + result as per usual. However, this time, `$sum` is set to + the previous value of the body, so `$sum + .` gives + `5`. After the final backtracking, `$sum + .` gives + `6`. This final value is used as the value of the entire + `fold` expression, so the above filter returns `6`. + + More formally, in order to evaluate `fold INIT as $VAR + (BODY)`, jq first sets `$VAR` to the value of `INIT`. It + then runs through `BODY`. Each time `BODY` produces a value, + `$VAR` is set to that value and jq backtracks to find the + next one. When `BODY` stops producing values, the final + value of `$VAR` is the result of the entire expression. + + examples: + - program: 'fold 0 as $sum (.[] | $sum + .)' + input: '[10,2,5,3]' + output: ['20'] - title: Assignment diff --git a/lexer.l b/lexer.l index 12851de8..fd0e120e 100644 --- a/lexer.l +++ b/lexer.l @@ -49,6 +49,7 @@ struct lexer_param; "and" { return AND; } "or" { return OR; } "end" { return END; } +"fold" { return FOLD; } "//" { return DEFINEDOR; } "|=" { return SETPIPE; } "+=" { return SETPLUS; } diff --git a/parser.y b/parser.y index 397982d6..5cc2640f 100644 --- a/parser.y +++ b/parser.y @@ -58,6 +58,7 @@ struct lexer_param; %token THEN "then" %token ELSE "else" %token ELSE_IF "elif" +%token FOLD "fold" %token END "end" %token AND "and" %token OR "or" @@ -201,6 +202,11 @@ Term "as" '$' IDENT '|' Exp { jv_free($4); } | +"fold" Term "as" '$' IDENT '(' Exp ')' { + $$ = gen_fold(jv_string_value($5), $2, $7); + jv_free($5); +} | + "if" Exp "then" Exp ElseBody { $$ = gen_cond($2, $4, $5); } | diff --git a/testdata b/testdata index c3352af4..bb8e677a 100644 --- a/testdata +++ b/testdata @@ -331,6 +331,10 @@ def fac: if . == 1 then 1 else . * (. - 1 | fac) end; [.[] | fac] # [] # 1001 +fold 0 as $s (.[] | $s + .) +[1,2,4] +7 + # # Assignment # From f1e23448e789983f8581f291e56a37c3c63e7dbf Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Fri, 28 Dec 2012 15:07:27 +0000 Subject: [PATCH 52/62] Support for two-argument functions. Should probably support n args instead. This is a quick hack. Also, ';' is a slightly ugly argument separator. --- parser.y | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/parser.y b/parser.y index 5cc2640f..2b9732c0 100644 --- a/parser.y +++ b/parser.y @@ -319,9 +319,20 @@ FuncDef: $7); jv_free($2); jv_free($4); +} | + +"def" IDENT '(' IDENT ';' IDENT ')' ':' Exp ';' { + $$ = gen_function(jv_string_value($2), + BLOCK(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)), + gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($6))), + $9); + jv_free($2); + jv_free($4); + jv_free($6); } + String: QQSTRING_START { $$ = jv_string("text"); } QQString QQSTRING_END { $$ = $3; @@ -414,6 +425,11 @@ IDENT '(' Exp ')' { $$ = gen_location(@1, $$); jv_free($1); } | +IDENT '(' Exp ';' Exp ')' { + $$ = gen_call(jv_string_value($1), BLOCK(gen_lambda($3), gen_lambda($5))); + $$ = gen_location(@1, $$); + jv_free($1); +} | '(' error ')' { $$ = gen_noop(); } | '[' error ']' { $$ = gen_noop(); } | Term '[' error ']' { $$ = $1; } | From 79c9c418c6c6312c550b9253b62701f3f788dfa2 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Fri, 28 Dec 2012 16:08:29 +0000 Subject: [PATCH 53/62] Path manipulation (path/getpath/setpath/delpath) and docs. del function should fix #37. --- builtin.c | 42 +++++++++++++++------ execute.c | 23 +++++++++++- jv.c | 3 +- jv_aux.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++--- jv_aux.h | 8 ++-- opcode_list.h | 1 + testdata | 44 ++++++++++++++++++++++ 7 files changed, 198 insertions(+), 25 deletions(-) diff --git a/builtin.c b/builtin.c index c431be07..de40be7e 100644 --- a/builtin.c +++ b/builtin.c @@ -484,6 +484,9 @@ static struct cfunction function_list[] = { {(cfunction_ptr)f_tonumber, "tonumber", 1}, {(cfunction_ptr)f_tostring, "tostring", 1}, {(cfunction_ptr)f_keys, "keys", 1}, + {(cfunction_ptr)jv_setpath, "setpath", 3}, // FIXME typechecking + {(cfunction_ptr)jv_getpath, "getpath", 2}, + {(cfunction_ptr)jv_delpath, "delpath", 2}, {(cfunction_ptr)f_equal, "_equal", 3}, {(cfunction_ptr)f_notequal, "_notequal", 3}, {(cfunction_ptr)f_less, "_less", 3}, @@ -508,22 +511,36 @@ static struct cfunction function_list[] = { static struct symbol_table cbuiltins = {function_list, sizeof(function_list)/sizeof(function_list[0])}; -typedef block (*bytecoded_builtin)(); struct bytecoded_builtin { const char* name; block code; }; static block bind_bytecoded_builtins(block b) { - struct bytecoded_builtin builtin_defs[] = { - {"empty", gen_op_simple(BACKTRACK)}, - {"false", gen_const(jv_false())}, - {"true", gen_const(jv_true())}, - {"null", gen_const(jv_null())}, - {"not", gen_condbranch(gen_const(jv_false()), - gen_const(jv_true()))} - }; block builtins = gen_noop(); - for (unsigned i=0; ii[1] + end < array->length); + assert(a->i[0] + end <= a->i[1]); jv_complex slice = *a; slice.i[0] += start; slice.i[1] = slice.i[0] + (end - start); diff --git a/jv_aux.c b/jv_aux.c index a4bfddd2..83695f96 100644 --- a/jv_aux.c +++ b/jv_aux.c @@ -3,7 +3,7 @@ #include #include "jv_alloc.h" -jv jv_lookup(jv t, jv k) { +jv jv_get(jv t, jv k) { jv v; if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) { v = jv_object_get(t, k); @@ -33,7 +33,12 @@ jv jv_lookup(jv t, jv k) { return v; } -jv jv_modify(jv t, jv k, jv v) { +jv jv_set(jv t, jv k, jv v) { + if (!jv_is_valid(v)) { + jv_free(t); + jv_free(k); + return v; + } int isnull = jv_get_kind(t) == JV_KIND_NULL; if (jv_get_kind(k) == JV_KIND_STRING && (jv_get_kind(t) == JV_KIND_OBJECT || isnull)) { @@ -55,15 +60,100 @@ jv jv_modify(jv t, jv k, jv v) { return t; } -jv jv_insert(jv root, jv value, jv* path, int pathlen) { - if (pathlen == 0) { +jv jv_del(jv t, jv k) { + if (jv_get_kind(t) == JV_KIND_NULL) { + jv_free(k); + } else if (jv_get_kind(t) == JV_KIND_ARRAY && + jv_get_kind(k) == JV_KIND_NUMBER) { + int idx = (int)jv_number_value(k); + jv_free(k); + int len = jv_array_length(jv_copy(t)); + if (idx >= 0 && idx < len) { + for (int i = idx+1; i < len; i++) { + t = jv_array_set(t, i-1, jv_array_get(jv_copy(t), i)); + } + t = jv_array_slice(t, 0, len-1); + } + } else if (jv_get_kind(t) == JV_KIND_OBJECT && + jv_get_kind(k) == JV_KIND_STRING) { + t = jv_object_delete(t, k); + } else { + jv err = jv_invalid_with_msg(jv_string_fmt("Cannot delete field at %s index of %s", + jv_kind_name(jv_get_kind(k)), + jv_kind_name(jv_get_kind(t)))); + jv_free(t); + jv_free(k); + t = err; + } + return t; +} + +jv jv_setpath(jv root, jv path, jv value) { + if (jv_get_kind(path) != JV_KIND_ARRAY) { + jv_free(value); + jv_free(root); + jv_free(path); + return jv_invalid_with_msg(jv_string("Path must be specified as an array")); + } + if (!jv_is_valid(root)){ + jv_free(value); + jv_free(path); + return root; + } + if (jv_array_length(jv_copy(path)) == 0) { + jv_free(path); jv_free(root); return value; } - return jv_modify(root, jv_copy(*path), - jv_insert(jv_lookup(jv_copy(root), jv_copy(*path)), value, path+1, pathlen-1)); + jv pathcurr = jv_array_get(jv_copy(path), 0); + jv pathrest = jv_array_slice(path, 1, jv_array_length(jv_copy(path))); + return jv_set(root, pathcurr, + jv_setpath(jv_get(jv_copy(root), jv_copy(pathcurr)), pathrest, value)); } +jv jv_getpath(jv root, jv path) { + if (jv_get_kind(path) != JV_KIND_ARRAY) { + jv_free(root); + jv_free(path); + return jv_invalid_with_msg(jv_string("Path must be specified as an array")); + } + if (!jv_is_valid(root)) { + jv_free(path); + return root; + } + if (jv_array_length(jv_copy(path)) == 0) { + jv_free(path); + return root; + } + jv pathcurr = jv_array_get(jv_copy(path), 0); + jv pathrest = jv_array_slice(path, 1, jv_array_length(jv_copy(path))); + return jv_getpath(jv_get(root, pathcurr), pathrest); +} + +jv jv_delpath(jv root, jv path) { + if (jv_get_kind(path) != JV_KIND_ARRAY) { + jv_free(root); + jv_free(path); + return jv_invalid_with_msg(jv_string("Path must be specified as an array")); + } + if (!jv_is_valid(root)) { + jv_free(path); + return root; + } + if (jv_array_length(jv_copy(path)) == 1) { + return jv_del(root, jv_array_get(path, 0)); + } + jv pathcurr = jv_array_get(jv_copy(path), 0); + jv pathrest = jv_array_slice(path, 1, jv_array_length(jv_copy(path))); + jv new_obj = jv_delpath(jv_get(jv_copy(root), jv_copy(pathcurr)), pathrest); + if (jv_get_kind(new_obj) == JV_KIND_NULL) { + jv_free(pathcurr); + jv_free(new_obj); + return root; + } else { + return jv_set(root, pathcurr, new_obj); + } +} static int string_cmp(const void* pa, const void* pb){ const jv* a = pa; diff --git a/jv_aux.h b/jv_aux.h index 36b0e5e4..0b827d2e 100644 --- a/jv_aux.h +++ b/jv_aux.h @@ -3,9 +3,11 @@ #include "jv.h" -jv jv_lookup(jv t, jv k); -jv jv_modify(jv t, jv k, jv v); -jv jv_insert(jv root, jv value, jv* path, int pathlen); +jv jv_get(jv t, jv k); +jv jv_set(jv t, jv k, jv v); +jv jv_setpath(jv root, jv path, jv value); +jv jv_getpath(jv root, jv path); +jv jv_delpath(jv root, jv path); jv jv_keys(jv /*object or array*/); int jv_cmp(jv, jv); diff --git a/opcode_list.h b/opcode_list.h index e6dece6e..e460ffe9 100644 --- a/opcode_list.h +++ b/opcode_list.h @@ -15,6 +15,7 @@ OP(BACKTRACK, NONE, 0, 0) OP(APPEND, NONE, 2, 1) OP(INSERT, NONE, 4, 2) +OP(GETPATH, NONE, 2, 1) OP(ASSIGN, VARIABLE, 3, 0) OP(CALL_BUILTIN, CFUNC, -1, 1) diff --git a/testdata b/testdata index bb8e677a..36429f59 100644 --- a/testdata +++ b/testdata @@ -335,6 +335,50 @@ fold 0 as $s (.[] | $s + .) [1,2,4] 7 +# +# Paths +# + +path(.foo[0,1]) +null +["foo", 0] +["foo", 1] + +path(.[] | select(.>3)) +[1,5,3] +[1] + +path(.) +42 +[] + +["foo",1] as $p | getpath($p), setpath($p; 20), delpath($p) +{"bar": 42, "foo": ["a", "b", "c", "d"]} +"b" +{"bar": 42, "foo": ["a", 20, "c", "d"]} +{"bar": 42, "foo": ["a", "c", "d"]} + +map(getpath([2])), map(setpath([2]; 42)), map(delpath([2])) +[[0], [0,1], [0,1,2]] +[null, null, 2] +[[0,null,42], [0,1,42], [0,1,42]] +[[0], [0,1], [0,1]] + +map(delpath([0,"foo"])) +[[{"foo":2, "x":1}], [{"bar":2}]] +[[{"x":1}], [{"bar":2}]] + +["foo",1] as $p | getpath($p), setpath($p; 20), delpath($p) +{"bar":false} +null +{"bar":false, "foo": [null, 20]} +{"bar":false} + +delpath([-200]) +[1,2,3] +[1,2,3] + + # # Assignment # From 3a5377e183976cc6dafa16a17f608e091dfa96b9 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sat, 29 Dec 2012 01:37:22 +0000 Subject: [PATCH 54/62] Fix a bug in URI-encoding of certain non-ASCII characters. Oh how I hate C casting rules. --- builtin.c | 2 +- testdata | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/builtin.c b/builtin.c index de40be7e..bb704bb8 100644 --- a/builtin.c +++ b/builtin.c @@ -306,7 +306,7 @@ static jv f_format(jv input, jv fmt) { jv line = jv_string(""); const char* s = jv_string_value(input); for (int i=0; i&'\\''\"'" "PD4mJyI=" +@uri +"\u03bc" +"%ce%bc" + @html "\(.)" "" "<script>hax</script>" From 465a4ec565a106e0e4cc1d64214fb2d6d791c8dc Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sat, 29 Dec 2012 16:13:06 +0000 Subject: [PATCH 55/62] Improvements to del(foo). del(foo,bar) is now very different from del(foo),del(bar). See #37. --- builtin.c | 5 +- jv_aux.c | 164 +++++++++++++++++++++++++++++++++++++++++------------- jv_aux.h | 2 +- testdata | 16 ++++-- 4 files changed, 138 insertions(+), 49 deletions(-) diff --git a/builtin.c b/builtin.c index bb704bb8..dca3d6ff 100644 --- a/builtin.c +++ b/builtin.c @@ -475,7 +475,6 @@ static jv f_error(jv input, jv msg) { return jv_invalid_with_msg(msg); } - static struct cfunction function_list[] = { {(cfunction_ptr)f_plus, "_plus", 3}, {(cfunction_ptr)f_minus, "_minus", 3}, @@ -486,7 +485,7 @@ static struct cfunction function_list[] = { {(cfunction_ptr)f_keys, "keys", 1}, {(cfunction_ptr)jv_setpath, "setpath", 3}, // FIXME typechecking {(cfunction_ptr)jv_getpath, "getpath", 2}, - {(cfunction_ptr)jv_delpath, "delpath", 2}, + {(cfunction_ptr)jv_delpaths, "delpaths", 2}, {(cfunction_ptr)f_equal, "_equal", 3}, {(cfunction_ptr)f_notequal, "_notequal", 3}, {(cfunction_ptr)f_less, "_less", 3}, @@ -552,7 +551,7 @@ static const char* jq_builtins[] = { "def unique: group_by(.) | map(.[0]);", "def max_by(f): _max_by_impl(map([f]));", "def min_by(f): _min_by_impl(map([f]));", - "def del(f): delpath(path(f));", + "def del(f): delpaths([path(f)]);", }; diff --git a/jv_aux.c b/jv_aux.c index 83695f96..f0e15b50 100644 --- a/jv_aux.c +++ b/jv_aux.c @@ -60,31 +60,63 @@ jv jv_set(jv t, jv k, jv v) { return t; } -jv jv_del(jv t, jv k) { - if (jv_get_kind(t) == JV_KIND_NULL) { - jv_free(k); - } else if (jv_get_kind(t) == JV_KIND_ARRAY && - jv_get_kind(k) == JV_KIND_NUMBER) { - int idx = (int)jv_number_value(k); - jv_free(k); - int len = jv_array_length(jv_copy(t)); - if (idx >= 0 && idx < len) { - for (int i = idx+1; i < len; i++) { - t = jv_array_set(t, i-1, jv_array_get(jv_copy(t), i)); +// assumes keys is a sorted array +jv jv_dels(jv t, jv keys) { + assert(jv_get_kind(keys) == JV_KIND_ARRAY); + assert(jv_is_valid(t)); + + if (jv_get_kind(t) == JV_KIND_NULL || jv_array_length(jv_copy(keys)) == 0) { + // no change + } else if (jv_get_kind(t) == JV_KIND_ARRAY) { + jv new_array = jv_array(); + int kidx = 0; + for (int i=0; i start); + int delkey = jv_array_length(jv_array_get(jv_copy(paths), i)) == start + 1; + jv key = jv_array_get(jv_array_get(jv_copy(paths), i), start); + while (j < jv_array_length(jv_copy(paths)) && + jv_equal(jv_copy(key), jv_array_get(jv_array_get(jv_copy(paths), j), start))) + j++; + // if i <= entry < j, then entry starts with key + if (delkey) { + // deleting this entire key, we don't care about any more specific deletions + delkeys = jv_array_append(delkeys, key); + } else { + // deleting certain sub-parts of this key + jv subobject = jv_get(jv_copy(object), jv_copy(key)); + if (!jv_is_valid(subobject)) { + jv_free(key); + jv_free(object); + object = subobject; + break; + } else if (jv_get_kind(subobject) == JV_KIND_NULL) { + jv_free(key); + jv_free(subobject); + } else { + jv newsubobject = delpaths_sorted(subobject, jv_array_slice(jv_copy(paths), i, j), start+1); + if (!jv_is_valid(newsubobject)) { + jv_free(key); + jv_free(object); + object = newsubobject; + break; + } + object = jv_set(object, key, newsubobject); + } + if (!jv_is_valid(object)) break; + } + i = j; } + jv_free(paths); + if (jv_is_valid(object)) + object = jv_dels(object, delkeys); + else + jv_free(delkeys); + return object; } +jv jv_delpaths(jv object, jv paths) { + paths = jv_sort(paths, jv_copy(paths)); + for (int i=0; i Date: Sat, 29 Dec 2012 16:43:36 +0000 Subject: [PATCH 56/62] Refactor assignment. New version is much more elegant and probably slower. Uses library functions implemented in jq rather than dedicated opcodes. --- builtin.c | 3 +++ compile.c | 16 ---------------- compile.h | 1 - execute.c | 28 ---------------------------- opcode_list.h | 1 - parser.y | 19 ++++++++++++------- testdata | 4 ++++ 7 files changed, 19 insertions(+), 53 deletions(-) diff --git a/builtin.c b/builtin.c index dca3d6ff..f5917cbe 100644 --- a/builtin.c +++ b/builtin.c @@ -552,6 +552,9 @@ static const char* jq_builtins[] = { "def max_by(f): _max_by_impl(map([f]));", "def min_by(f): _min_by_impl(map([f]));", "def del(f): delpaths([path(f)]);", + "def _assign(paths; value): value as $v | fold . as $obj (path(paths) as $p | $obj | setpath($p; $v));", + "def _modify(paths; update): fold . as $obj (path(paths) as $p | $obj | setpath($p; getpath($p) | update));", + }; diff --git a/compile.c b/compile.c index 178b0463..08187836 100644 --- a/compile.c +++ b/compile.c @@ -317,22 +317,6 @@ block gen_fold(const char* varname, block init, block fold) { OP_HAS_VARIABLE)); } -block gen_assign(block expr) { - block result_var = block_bind(gen_op_var_unbound(STOREV, "result"), - gen_noop(), OP_HAS_VARIABLE); - - block loop = BLOCK(gen_op_simple(DUP), - expr, - gen_op_var_bound(ASSIGN, result_var), - gen_op_simple(BACKTRACK)); - - 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 found_var = block_bind(gen_op_var_unbound(STOREV, "found"), diff --git a/compile.h b/compile.h index ce1b3089..150eef28 100644 --- a/compile.h +++ b/compile.h @@ -34,7 +34,6 @@ block gen_subexp(block a); block gen_both(block a, block b); block gen_collect(block expr); block gen_fold(const char* varname, block init, block body); -block gen_assign(block expr); block gen_definedor(block a, block b); block gen_condbranch(block iftrue, block iffalse); block gen_and(block a, block b); diff --git a/execute.c b/execute.c index ed251d18..94f6cd43 100644 --- a/execute.c +++ b/execute.c @@ -298,34 +298,6 @@ jv jq_next() { break; } - case ASSIGN: { - stackval replacement = stack_pop(); - stackval path_end = stack_pop(); - stackval path_start = stack_pop(); - jv_free(path_end.value); - jv_free(path_start.value); - - jv path = jv_array(); - for (int i=path_start.pathidx; i Date: Sat, 29 Dec 2012 16:50:58 +0000 Subject: [PATCH 57/62] Make null + foo return foo, rather than an error. This also allows 'add' to be implemented in jq rather than C. --- builtin.c | 26 ++++++++------------------ docs/content/3.manual/manual.yml | 9 +++++++++ testdata | 12 ++++++++++++ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/builtin.c b/builtin.c index f5917cbe..b0c6c34c 100644 --- a/builtin.c +++ b/builtin.c @@ -45,7 +45,13 @@ static jv type_error2(jv bad1, jv bad2, const char* msg) { static jv f_plus(jv input, jv a, jv b) { jv_free(input); - if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { + if (jv_get_kind(a) == JV_KIND_NULL) { + jv_free(a); + return b; + } else if (jv_get_kind(b) == JV_KIND_NULL) { + jv_free(b); + return a; + } else if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { return jv_number(jv_number_value(a) + jv_number_value(b)); } else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) { @@ -104,22 +110,6 @@ static jv f_divide(jv input, jv a, jv b) { } } -static jv f_add(jv array) { - if (jv_get_kind(array) != JV_KIND_ARRAY) { - return type_error(array, "cannot have its elements added"); - } else if (jv_array_length(jv_copy(array)) == 0) { - jv_free(array); - return jv_null(); - } else { - jv sum = jv_array_get(jv_copy(array), 0); - for (int i = 1; i < jv_array_length(jv_copy(array)); i++) { - sum = f_plus(jv_null(), sum, jv_array_get(jv_copy(array), i)); - } - jv_free(array); - return sum; - } -} - static jv f_equal(jv input, jv a, jv b) { jv_free(input); return jv_bool(jv_equal(a, b)); @@ -495,7 +485,6 @@ static struct cfunction function_list[] = { {(cfunction_ptr)f_contains, "contains", 2}, {(cfunction_ptr)f_length, "length", 1}, {(cfunction_ptr)f_type, "type", 1}, - {(cfunction_ptr)f_add, "add", 1}, {(cfunction_ptr)f_sort, "sort", 1}, {(cfunction_ptr)f_sort_by_impl, "_sort_by_impl", 2}, {(cfunction_ptr)f_group_by_impl, "_group_by_impl", 2}, @@ -551,6 +540,7 @@ static const char* jq_builtins[] = { "def unique: group_by(.) | map(.[0]);", "def max_by(f): _max_by_impl(map([f]));", "def min_by(f): _min_by_impl(map([f]));", + "def add: fold null as $sum (.[] | $sum + .);", "def del(f): delpaths([path(f)]);", "def _assign(paths; value): value as $v | fold . as $obj (path(paths) as $p | $obj | setpath($p; $v));", "def _modify(paths; update): fold . as $obj (path(paths) as $p | $obj | setpath($p; getpath($p) | update));", diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 1de1a387..fba7e4a7 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -356,6 +356,9 @@ sections: the key-value pairs from both objects into a single combined object. If both objects contain a value for the same key, the object on the right of the `+` wins. + + `null` can be added to any value, and returns the other + value unchanged. examples: - program: '.a + 1' @@ -364,6 +367,12 @@ sections: - program: '.a + .b' input: '{"a": [1,2], "b": [3,4]}' output: ['[1,2,3,4]'] + - program: '.a + null' + input: '{"a": 1}' + output: ['1'] + - program: '.a + 1' + input: '{}' + output: ['1'] - program: '{a: 1} + {b: 2} + {c: 3} + {a: 42}' input: 'null' output: ['{"a": 42, "b": 2, "c": 3}'] diff --git a/testdata b/testdata index 224f0651..4a998d8e 100644 --- a/testdata +++ b/testdata @@ -205,6 +205,18 @@ null 15 19.0 +.+null +{"a":42} +{"a":42} + +null+. +null +null + +.a+.b +{"a":42} +42 + [1,2,3] + [.] null [1,2,3,null] From b3bad59dd7d9fcea575ef2de2843b9515b0630b4 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sat, 29 Dec 2012 22:59:07 +0000 Subject: [PATCH 58/62] Add the `recurse` function. See #37. --- builtin.c | 2 +- docs/content/3.manual/manual.yml | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/builtin.c b/builtin.c index b0c6c34c..5818a6a4 100644 --- a/builtin.c +++ b/builtin.c @@ -544,7 +544,7 @@ static const char* jq_builtins[] = { "def del(f): delpaths([path(f)]);", "def _assign(paths; value): value as $v | fold . as $obj (path(paths) as $p | $obj | setpath($p; $v));", "def _modify(paths; update): fold . as $obj (path(paths) as $p | $obj | setpath($p; getpath($p) | update));", - + "def recurse(f): ., (f | select(. != null) | recurse(f));", }; diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index fba7e4a7..de608210 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -643,6 +643,38 @@ sections: input: '{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}' output: ['false'] + - title: `recurse` + body: | + + The `recurse` function allows you to search through a + recursive structure, and extract interesting data from all + levels. Suppose your input represents a filesystem: + + {"name": "/", "children": [ + {"name": "/bin", "children": [ + {"name": "/bin/ls", "children": []}, + {"name": "/bin/sh", "children": []}]}, + {"name": "/home", "children": [ + {"name": "/home/stephen", "children": [ + {"name": "/home/stephen/jq", "children": []}]}]}]} + + Now suppose you want to extract all of the filenames + present. You need to retrieve `.name`, `.children[].name`, + `.children[].children[].name`, and so on. You can do this + with: + + recurse(.children[]) | .name + + examples: + - program: 'recurse(.foo[])' + input: '{"foo":[{"foo": []}, {"foo":[{"foo":[]}]}]}' + output: + - '{"foo":[{"foo":[]},{"foo":[{"foo":[]}]}]}' + - '{"foo":[]}' + - '{"foo":[{"foo":[]}]}' + - '{"foo":[]}' + + - title: "String interpolation - `\(foo)`" body: | From 38fe6fc0cbf23c3bb97b10529cda119cb4418245 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 31 Dec 2012 23:25:12 +0000 Subject: [PATCH 59/62] Ignore some more stuff. --- .gitignore | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 6caf43c4..5e0bf5a7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,10 @@ # Autogenerated *.gen.* -# Test binaries -jv_test -jv_parse -parsertest*~ - +jq_test build +jq +jq.1 # Something delightfully recursive happens otherwise docs/content/2.download/source/* \ No newline at end of file From fb84541e1124565ee7af32cd842771cf81326dc7 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 31 Dec 2012 23:27:00 +0000 Subject: [PATCH 60/62] Clean up jv_object_foreach and add jv_array_foreach --- builtin.c | 17 ++++++----------- jv.c | 23 +++++++++-------------- jv.h | 21 ++++++++++++++++----- jv_aux.c | 21 +++++++++++---------- jv_print.c | 9 ++++----- 5 files changed, 46 insertions(+), 45 deletions(-) diff --git a/builtin.c b/builtin.c index 5818a6a4..32b67ccc 100644 --- a/builtin.c +++ b/builtin.c @@ -71,11 +71,10 @@ static jv f_minus(jv input, jv a, jv b) { return jv_number(jv_number_value(a) - jv_number_value(b)); } else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) { jv out = jv_array(); - for (int i=0; i Date: Thu, 3 Jan 2013 12:51:33 +0000 Subject: [PATCH 61/62] Change APPEND opcode to directly modify a variable. Avoids a big O(n^2) loop in constructing arrays. Fixes #61. --- compile.c | 6 +----- execute.c | 9 ++++++--- opcode_list.h | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/compile.c b/compile.c index 08187836..b06e4f75 100644 --- a/compile.c +++ b/compile.c @@ -292,11 +292,7 @@ block gen_collect(block expr) { gen_noop(), OP_HAS_VARIABLE); block c = BLOCK(gen_op_simple(DUP), gen_const(jv_array()), array_var); - 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), + block tail = BLOCK(gen_op_var_bound(APPEND, array_var), gen_op_simple(BACKTRACK)); return BLOCK(c, diff --git a/execute.c b/execute.c index 94f6cd43..fb4a3895 100644 --- a/execute.c +++ b/execute.c @@ -236,9 +236,12 @@ jv jq_next() { case APPEND: { // FIXME paths jv v = stack_pop().value; - jv array = stack_pop().value; - array = jv_array_append(array, v); - stack_push(stackval_root(array)); + uint16_t level = *pc++; + uint16_t vidx = *pc++; + frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level); + jv* var = frame_local_var(fp, vidx); + assert(jv_get_kind(*var) == JV_KIND_ARRAY); + *var = jv_array_append(*var, v); break; } diff --git a/opcode_list.h b/opcode_list.h index 0185b5a6..f384d715 100644 --- a/opcode_list.h +++ b/opcode_list.h @@ -12,7 +12,7 @@ OP(FORK, BRANCH, 0, 0) OP(JUMP, BRANCH, 0, 0) OP(JUMP_F,BRANCH, 1, 0) OP(BACKTRACK, NONE, 0, 0) -OP(APPEND, NONE, 2, 1) +OP(APPEND, VARIABLE,1, 0) OP(INSERT, NONE, 4, 2) OP(GETPATH, NONE, 2, 1) From 925ec3751f3b407c17412b0fa04a84fe39c1e0b7 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Thu, 3 Jan 2013 12:53:06 +0000 Subject: [PATCH 62/62] Fix negative number syntax. Add a unary '-' operator. Closes #63. --- builtin.c | 10 ++++++++++ lexer.l | 2 +- parser.y | 4 ++++ testdata | 13 +++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/builtin.c b/builtin.c index 32b67ccc..76e559ea 100644 --- a/builtin.c +++ b/builtin.c @@ -65,6 +65,15 @@ static jv f_plus(jv input, jv a, jv b) { } } +static jv f_negate(jv input) { + if (jv_get_kind(input) != JV_KIND_NUMBER) { + return type_error(input, "cannot be negated"); + } + jv ret = jv_number(-jv_number_value(input)); + jv_free(input); + return ret; +} + static jv f_minus(jv input, jv a, jv b) { jv_free(input); if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { @@ -462,6 +471,7 @@ static jv f_error(jv input, jv msg) { static struct cfunction function_list[] = { {(cfunction_ptr)f_plus, "_plus", 3}, + {(cfunction_ptr)f_negate, "_negate", 1}, {(cfunction_ptr)f_minus, "_minus", 3}, {(cfunction_ptr)f_multiply, "_multiply", 3}, {(cfunction_ptr)f_divide, "_divide", 3}, diff --git a/lexer.l b/lexer.l index fd0e120e..9d826efa 100644 --- a/lexer.l +++ b/lexer.l @@ -73,7 +73,7 @@ struct lexer_param; yylval->literal = jv_string_sized(yytext + 1, yyleng - 1); return FORMAT; } --?[0-9.]+([eE][+-]?[0-9]+)? { +[0-9.]+([eE][+-]?[0-9]+)? { yylval->literal = jv_parse_sized(yytext, yyleng); return LITERAL; } diff --git a/parser.y b/parser.y index a1be0b7f..92cd9db8 100644 --- a/parser.y +++ b/parser.y @@ -260,6 +260,10 @@ Exp "+=" Exp { $$ = gen_update($1, $3, '+'); } | +'-' Exp { + $$ = BLOCK($2, gen_call("_negate", gen_noop())); +} | + Exp '-' Exp { $$ = gen_binop($1, $3, '-'); } | diff --git a/testdata b/testdata index 4a998d8e..83f91dae 100644 --- a/testdata +++ b/testdata @@ -21,6 +21,11 @@ null null 1 + +-1 +null +-1 + # FIXME: much more number testing needed {} @@ -197,6 +202,14 @@ null "wtasdf" 2.0 +2-1 +null +1 + +2-(-1) +null +3 + 1e+0+0.001e3 "I wonder what this will be?" 20e-1