From df14edf419651d73915521c3760815f8806ccd05 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Fri, 4 Aug 2023 00:12:48 +0200 Subject: [PATCH] Constant fold all kinds of constants This patch exports all the binary operator builtins functions from builtin.c and uses them for constant folding in the parser, allowing constant folding to work will all kinds and combinations of constants. Now string*number $ARGS+$ARGS etc will also be constant folded and the implementation of constant folded operators and runtime operators will be the same. --- src/builtin.c | 63 ++-- src/builtin.h | 18 + src/parser.c | 925 ++++++++++++++++++++++++-------------------------- src/parser.h | 4 +- src/parser.y | 69 ++-- 5 files changed, 516 insertions(+), 563 deletions(-) diff --git a/src/builtin.c b/src/builtin.c index 793b597666..0d0ac2340e 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -45,6 +45,15 @@ void *alloca (size_t); #include "jv_alloc.h" +#define BINOP(name) \ +static jv f_ ## name(jq_state *jq, jv input, jv a, jv b) { \ + jv_free(input); \ + return binop_ ## name(a, b); \ +} +BINOPS +#undef BINOP + + static jv type_error(jv bad, const char* msg) { char errbuf[15]; jv err = jv_invalid_with_msg(jv_string_fmt("%s (%s) %s", @@ -79,8 +88,7 @@ static inline jv ret_error2(jv bad1, jv bad2, jv msg) { return jv_invalid_with_msg(msg); } -static jv f_plus(jq_state *jq, jv input, jv a, jv b) { - jv_free(input); +jv binop_plus(jv a, jv b) { if (jv_get_kind(a) == JV_KIND_NULL) { jv_free(a); return b; @@ -312,8 +320,7 @@ static jv f_rtrimstr(jq_state *jq, jv input, jv right) { return input; } -static jv f_minus(jq_state *jq, jv input, jv a, jv b) { - jv_free(input); +jv binop_minus(jv a, jv b) { if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { jv r = jv_number(jv_number_value(a) - jv_number_value(b)); jv_free(a); @@ -341,10 +348,9 @@ static jv f_minus(jq_state *jq, jv input, jv a, jv b) { } } -static jv f_multiply(jq_state *jq, jv input, jv a, jv b) { +jv binop_multiply(jv a, jv b) { jv_kind ak = jv_get_kind(a); jv_kind bk = jv_get_kind(b); - jv_free(input); if (ak == JV_KIND_NUMBER && bk == JV_KIND_NUMBER) { jv r = jv_number(jv_number_value(a) * jv_number_value(b)); jv_free(a); @@ -380,8 +386,7 @@ static jv f_multiply(jq_state *jq, jv input, jv a, jv b) { } } -static jv f_divide(jq_state *jq, jv input, jv a, jv b) { - jv_free(input); +jv binop_divide(jv a, jv b) { if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { if (jv_number_value(b) == 0.0) return type_error2(a, b, "cannot be divided because the divisor is zero"); @@ -397,8 +402,7 @@ static jv f_divide(jq_state *jq, jv input, jv a, jv b) { } #define dtoi(n) ((n) < INTMAX_MIN ? INTMAX_MIN : -(n) < INTMAX_MIN ? INTMAX_MAX : (intmax_t)(n)) -static jv f_mod(jq_state *jq, jv input, jv a, jv b) { - jv_free(input); +jv binop_mod(jv a, jv b) { if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { double na = jv_number_value(a); double nb = jv_number_value(b); @@ -421,13 +425,11 @@ static jv f_mod(jq_state *jq, jv input, jv a, jv b) { } #undef dtoi -static jv f_equal(jq_state *jq, jv input, jv a, jv b) { - jv_free(input); +jv binop_equal(jv a, jv b) { return jv_bool(jv_equal(a, b)); } -static jv f_notequal(jq_state *jq, jv input, jv a, jv b) { - jv_free(input); +jv binop_notequal(jv a, jv b) { return jv_bool(!jv_equal(a, b)); } @@ -438,8 +440,7 @@ enum cmp_op { CMP_OP_GREATEREQ }; -static jv order_cmp(jv input, jv a, jv b, enum cmp_op op) { - jv_free(input); +static jv order_cmp(jv a, jv b, enum cmp_op op) { int r = jv_cmp(a, b); return jv_bool((op == CMP_OP_LESS && r < 0) || (op == CMP_OP_LESSEQ && r <= 0) || @@ -447,20 +448,20 @@ static jv order_cmp(jv input, jv a, jv b, enum cmp_op op) { (op == CMP_OP_GREATER && r > 0)); } -static jv f_less(jq_state *jq, jv input, jv a, jv b) { - return order_cmp(input, a, b, CMP_OP_LESS); +jv binop_less(jv a, jv b) { + return order_cmp(a, b, CMP_OP_LESS); } -static jv f_greater(jq_state *jq, jv input, jv a, jv b) { - return order_cmp(input, a, b, CMP_OP_GREATER); +jv binop_greater(jv a, jv b) { + return order_cmp(a, b, CMP_OP_GREATER); } -static jv f_lesseq(jq_state *jq, jv input, jv a, jv b) { - return order_cmp(input, a, b, CMP_OP_LESSEQ); +jv binop_lesseq(jv a, jv b) { + return order_cmp(a, b, CMP_OP_LESSEQ); } -static jv f_greatereq(jq_state *jq, jv input, jv a, jv b) { - return order_cmp(input, a, b, CMP_OP_GREATEREQ); +jv binop_greatereq(jv a, jv b) { + return order_cmp(a, b, CMP_OP_GREATEREQ); } static jv f_contains(jq_state *jq, jv a, jv b) { @@ -1735,12 +1736,10 @@ static const struct cfunction function_list[] = { #ifdef HAVE_LGAMMA_R {f_lgamma_r,"lgamma_r", 1}, #endif - {f_plus, "_plus", 3}, {f_negate, "_negate", 1}, - {f_minus, "_minus", 3}, - {f_multiply, "_multiply", 3}, - {f_divide, "_divide", 3}, - {f_mod, "_mod", 3}, +#define BINOP(name) {f_ ## name, "_" #name, 3}, +BINOPS +#undef BINOP {f_dump, "tojson", 1}, {f_json_parse, "fromjson", 1}, {f_tonumber, "tonumber", 1}, @@ -1759,12 +1758,6 @@ static const struct cfunction function_list[] = { {f_getpath, "getpath", 2}, {f_delpaths, "delpaths", 2}, {f_has, "has", 2}, - {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", 2}, {f_length, "length", 1}, {f_utf8bytelength, "utf8bytelength", 1}, diff --git a/src/builtin.h b/src/builtin.h index bca9bae1fb..38f3e54c9c 100644 --- a/src/builtin.h +++ b/src/builtin.h @@ -7,4 +7,22 @@ int builtins_bind(jq_state *, block*); +#define BINOPS \ + BINOP(plus) \ + BINOP(minus) \ + BINOP(multiply) \ + BINOP(divide) \ + BINOP(mod) \ + BINOP(equal) \ + BINOP(notequal) \ + BINOP(less) \ + BINOP(lesseq) \ + BINOP(greater) \ + BINOP(greatereq) \ + + +#define BINOP(name) jv binop_ ## name(jv, jv); +BINOPS +#undef BINOP + #endif diff --git a/src/parser.c b/src/parser.c index 429a430471..50a8ccc580 100644 --- a/src/parser.c +++ b/src/parser.c @@ -75,10 +75,11 @@ #include #include "compile.h" #include "jv_alloc.h" +#include "builtin.h" #define YYMALLOC jv_mem_alloc #define YYFREE jv_mem_free -#line 82 "src/parser.c" +#line 83 "src/parser.c" # ifndef YY_CAST # ifdef __cplusplus @@ -113,7 +114,7 @@ extern int yydebug; #endif /* "%code requires" blocks. */ -#line 11 "src/parser.y" +#line 12 "src/parser.y" #include "locfile.h" struct lexer_param; @@ -130,7 +131,7 @@ struct lexer_param; } \ } while (0) -#line 134 "src/parser.c" +#line 135 "src/parser.c" /* Token kinds. */ #ifndef YYTOKENTYPE @@ -246,12 +247,12 @@ struct lexer_param; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 31 "src/parser.y" +#line 32 "src/parser.y" jv literal; block blk; -#line 255 "src/parser.c" +#line 256 "src/parser.c" }; typedef union YYSTYPE YYSTYPE; @@ -388,7 +389,7 @@ typedef enum yysymbol_kind_t yysymbol_kind_t; /* Second part of user prologue. */ -#line 126 "src/parser.y" +#line 127 "src/parser.y" #include "lexer.h" struct lexer_param { @@ -468,63 +469,33 @@ static block constant_fold(block a, block b, int op) { if (!block_is_single(a) || !block_is_const(a) || !block_is_single(b) || !block_is_const(b)) return gen_noop(); - if (op == '+') { - if (block_const_kind(a) == JV_KIND_NULL) { - block_free(a); - return b; - } - if (block_const_kind(b) == JV_KIND_NULL) { - block_free(b); - return a; - } - } - if (block_const_kind(a) != block_const_kind(b)) - return gen_noop(); - jv res = jv_invalid(); + jv jv_a = block_const(a); + jv jv_b = block_const(b); - if (block_const_kind(a) == JV_KIND_NUMBER) { - jv jv_a = block_const(a); - jv jv_b = block_const(b); - - double na = jv_number_value(jv_a); - double nb = jv_number_value(jv_b); - - int cmp = jv_cmp(jv_a, jv_b); - - switch (op) { - case '+': res = jv_number(na + nb); break; - case '-': res = jv_number(na - nb); break; - case '*': res = jv_number(na * nb); break; - case '/': - if (nb == 0.0) return gen_noop(); - res = jv_number(na / nb); - break; - case '%': -#define is_unsafe_to_int_cast(n) (isnan(n) || (n) < INTMAX_MIN || -(n) < INTMAX_MIN) - if (is_unsafe_to_int_cast(na) || is_unsafe_to_int_cast(nb) || (intmax_t)nb == 0) return gen_noop(); -#undef is_unsafe_to_int_cast - res = jv_number((intmax_t)na % (intmax_t)nb); - break; - case EQ: res = (cmp == 0 ? jv_true() : jv_false()); break; - case NEQ: res = (cmp != 0 ? jv_true() : jv_false()); break; - case '<': res = (cmp < 0 ? jv_true() : jv_false()); break; - case '>': res = (cmp > 0 ? jv_true() : jv_false()); break; - case LESSEQ: res = (cmp <= 0 ? jv_true() : jv_false()); break; - case GREATEREQ: res = (cmp >= 0 ? jv_true() : jv_false()); break; - default: break; - } - } else if (op == '+' && block_const_kind(a) == JV_KIND_STRING) { - res = jv_string_concat(block_const(a), block_const(b)); - } else { - return gen_noop(); + jv res = jv_invalid(); + switch (op) { + case '+': res = binop_plus(jv_a, jv_b); break; + case '-': res = binop_minus(jv_a, jv_b); break; + case '*': res = binop_multiply(jv_a, jv_b); break; + case '/': res = binop_divide(jv_a, jv_b); break; + case '%': res = binop_mod(jv_a, jv_b); break; + case EQ: res = binop_equal(jv_a, jv_b); break; + case NEQ: res = binop_notequal(jv_a, jv_b); break; + case '<': res = binop_less(jv_a, jv_b); break; + case '>': res = binop_greater(jv_a, jv_b); break; + case LESSEQ: res = binop_lesseq(jv_a, jv_b); break; + case GREATEREQ: res = binop_greatereq(jv_a, jv_b); break; } - if (jv_get_kind(res) == JV_KIND_INVALID) + if (!jv_is_valid(res)) { + jv_free(res); return gen_noop(); + } block_free(a); block_free(b); + return gen_const(res); } @@ -582,7 +553,7 @@ static block gen_loc_object(location *loc, struct locfile *locations) { } -#line 586 "src/parser.c" +#line 557 "src/parser.c" #ifdef short @@ -972,23 +943,23 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 322, 322, 325, 330, 333, 348, 351, 356, 359, - 364, 368, 371, 375, 379, 383, 386, 391, 394, 397, - 402, 409, 413, 417, 421, 425, 429, 433, 437, 441, - 445, 449, 453, 457, 461, 465, 469, 473, 477, 481, - 485, 489, 493, 497, 501, 505, 509, 513, 518, 521, - 538, 547, 554, 562, 573, 578, 584, 587, 592, 596, - 603, 606, 612, 619, 622, 625, 631, 634, 637, 642, - 645, 648, 654, 657, 660, 668, 672, 675, 678, 681, - 684, 687, 690, 693, 696, 700, 706, 709, 712, 715, - 718, 721, 724, 727, 730, 733, 736, 739, 742, 745, - 748, 751, 754, 757, 760, 763, 766, 788, 792, 796, - 799, 811, 816, 817, 818, 819, 822, 825, 830, 835, - 838, 843, 846, 851, 855, 858, 863, 866, 871, 874, - 879, 882, 885, 888, 891, 894, 902, 908, 911, 914, - 917, 920, 923, 926, 929, 932, 935, 938, 941, 944, - 947, 950, 953, 956, 959, 964, 967, 968, 969, 972, - 975, 978, 981, 985, 990, 994, 998, 1002, 1006, 1014 + 0, 293, 293, 296, 301, 304, 319, 322, 327, 330, + 335, 339, 342, 346, 350, 354, 357, 362, 365, 368, + 373, 380, 384, 388, 392, 396, 400, 404, 408, 412, + 416, 420, 424, 428, 432, 436, 440, 444, 448, 452, + 456, 460, 464, 468, 472, 476, 480, 484, 489, 492, + 509, 518, 525, 533, 544, 549, 555, 558, 563, 567, + 574, 577, 583, 590, 593, 596, 602, 605, 608, 613, + 616, 619, 625, 628, 631, 639, 643, 646, 649, 652, + 655, 658, 661, 664, 667, 671, 677, 680, 683, 686, + 689, 692, 695, 698, 701, 704, 707, 710, 713, 716, + 719, 722, 725, 728, 731, 734, 737, 759, 763, 767, + 770, 782, 787, 788, 789, 790, 793, 796, 801, 806, + 809, 814, 817, 822, 826, 829, 834, 837, 842, 845, + 850, 853, 856, 859, 862, 865, 873, 879, 882, 885, + 888, 891, 894, 897, 900, 903, 906, 909, 912, 915, + 918, 921, 924, 927, 930, 935, 938, 939, 940, 943, + 946, 949, 952, 956, 961, 965, 969, 973, 977, 985 }; #endif @@ -2202,201 +2173,201 @@ yydestruct (const char *yymsg, switch (yykind) { case YYSYMBOL_IDENT: /* IDENT */ -#line 36 "src/parser.y" +#line 37 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2208 "src/parser.c" +#line 2179 "src/parser.c" break; case YYSYMBOL_FIELD: /* FIELD */ -#line 36 "src/parser.y" +#line 37 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2214 "src/parser.c" +#line 2185 "src/parser.c" break; case YYSYMBOL_BINDING: /* BINDING */ -#line 36 "src/parser.y" +#line 37 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2220 "src/parser.c" +#line 2191 "src/parser.c" break; case YYSYMBOL_LITERAL: /* LITERAL */ -#line 36 "src/parser.y" +#line 37 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2226 "src/parser.c" +#line 2197 "src/parser.c" break; case YYSYMBOL_FORMAT: /* FORMAT */ -#line 36 "src/parser.y" +#line 37 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2232 "src/parser.c" +#line 2203 "src/parser.c" break; case YYSYMBOL_QQSTRING_TEXT: /* QQSTRING_TEXT */ -#line 36 "src/parser.y" +#line 37 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2238 "src/parser.c" +#line 2209 "src/parser.c" break; case YYSYMBOL_Module: /* Module */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2244 "src/parser.c" +#line 2215 "src/parser.c" break; case YYSYMBOL_Imports: /* Imports */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2250 "src/parser.c" +#line 2221 "src/parser.c" break; case YYSYMBOL_FuncDefs: /* FuncDefs */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2256 "src/parser.c" +#line 2227 "src/parser.c" break; case YYSYMBOL_Exp: /* Exp */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2262 "src/parser.c" +#line 2233 "src/parser.c" break; case YYSYMBOL_Import: /* Import */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2268 "src/parser.c" +#line 2239 "src/parser.c" break; case YYSYMBOL_ImportWhat: /* ImportWhat */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2274 "src/parser.c" +#line 2245 "src/parser.c" break; case YYSYMBOL_ImportFrom: /* ImportFrom */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2280 "src/parser.c" +#line 2251 "src/parser.c" break; case YYSYMBOL_FuncDef: /* FuncDef */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2286 "src/parser.c" +#line 2257 "src/parser.c" break; case YYSYMBOL_Params: /* Params */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2292 "src/parser.c" +#line 2263 "src/parser.c" break; case YYSYMBOL_Param: /* Param */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2298 "src/parser.c" +#line 2269 "src/parser.c" break; case YYSYMBOL_StringStart: /* StringStart */ -#line 36 "src/parser.y" +#line 37 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2304 "src/parser.c" +#line 2275 "src/parser.c" break; case YYSYMBOL_String: /* String */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2310 "src/parser.c" +#line 2281 "src/parser.c" break; case YYSYMBOL_QQString: /* QQString */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2316 "src/parser.c" +#line 2287 "src/parser.c" break; case YYSYMBOL_ElseBody: /* ElseBody */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2322 "src/parser.c" +#line 2293 "src/parser.c" break; case YYSYMBOL_ExpD: /* ExpD */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2328 "src/parser.c" +#line 2299 "src/parser.c" break; case YYSYMBOL_Term: /* Term */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2334 "src/parser.c" +#line 2305 "src/parser.c" break; case YYSYMBOL_Args: /* Args */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2340 "src/parser.c" +#line 2311 "src/parser.c" break; case YYSYMBOL_Arg: /* Arg */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2346 "src/parser.c" +#line 2317 "src/parser.c" break; case YYSYMBOL_RepPatterns: /* RepPatterns */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2352 "src/parser.c" +#line 2323 "src/parser.c" break; case YYSYMBOL_Patterns: /* Patterns */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2358 "src/parser.c" +#line 2329 "src/parser.c" break; case YYSYMBOL_Pattern: /* Pattern */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2364 "src/parser.c" +#line 2335 "src/parser.c" break; case YYSYMBOL_ArrayPats: /* ArrayPats */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2370 "src/parser.c" +#line 2341 "src/parser.c" break; case YYSYMBOL_ObjPats: /* ObjPats */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2376 "src/parser.c" +#line 2347 "src/parser.c" break; case YYSYMBOL_ObjPat: /* ObjPat */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2382 "src/parser.c" +#line 2353 "src/parser.c" break; case YYSYMBOL_Keyword: /* Keyword */ -#line 36 "src/parser.y" +#line 37 "src/parser.y" { jv_free(((*yyvaluep).literal)); } -#line 2388 "src/parser.c" +#line 2359 "src/parser.c" break; case YYSYMBOL_MkDict: /* MkDict */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2394 "src/parser.c" +#line 2365 "src/parser.c" break; case YYSYMBOL_MkDictPair: /* MkDictPair */ -#line 37 "src/parser.y" +#line 38 "src/parser.y" { block_free(((*yyvaluep).blk)); } -#line 2400 "src/parser.c" +#line 2371 "src/parser.c" break; default: @@ -2700,31 +2671,31 @@ YYLTYPE yylloc = yyloc_default; switch (yyn) { case 2: /* TopLevel: Module Imports Exp */ -#line 322 "src/parser.y" +#line 293 "src/parser.y" { *answer = BLOCK((yyvsp[-2].blk), (yyvsp[-1].blk), gen_op_simple(TOP), (yyvsp[0].blk)); } -#line 2708 "src/parser.c" +#line 2679 "src/parser.c" break; case 3: /* TopLevel: Module Imports FuncDefs */ -#line 325 "src/parser.y" +#line 296 "src/parser.y" { *answer = BLOCK((yyvsp[-2].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 2716 "src/parser.c" +#line 2687 "src/parser.c" break; case 4: /* Module: %empty */ -#line 330 "src/parser.y" +#line 301 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 2724 "src/parser.c" +#line 2695 "src/parser.c" break; case 5: /* Module: "module" Exp ';' */ -#line 333 "src/parser.y" +#line 304 "src/parser.y" { if (!block_is_const((yyvsp[-1].blk))) { FAIL((yyloc), "Module metadata must be constant"); @@ -2738,360 +2709,360 @@ YYLTYPE yylloc = yyloc_default; (yyval.blk) = gen_module((yyvsp[-1].blk)); } } -#line 2742 "src/parser.c" +#line 2713 "src/parser.c" break; case 6: /* Imports: %empty */ -#line 348 "src/parser.y" +#line 319 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 2750 "src/parser.c" +#line 2721 "src/parser.c" break; case 7: /* Imports: Import Imports */ -#line 351 "src/parser.y" +#line 322 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 2758 "src/parser.c" +#line 2729 "src/parser.c" break; case 8: /* FuncDefs: %empty */ -#line 356 "src/parser.y" +#line 327 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 2766 "src/parser.c" +#line 2737 "src/parser.c" break; case 9: /* FuncDefs: FuncDef FuncDefs */ -#line 359 "src/parser.y" +#line 330 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 2774 "src/parser.c" +#line 2745 "src/parser.c" break; case 10: /* Exp: FuncDef Exp */ -#line 364 "src/parser.y" +#line 335 "src/parser.y" { (yyval.blk) = block_bind_referenced((yyvsp[-1].blk), (yyvsp[0].blk), OP_IS_CALL_PSEUDO); } -#line 2782 "src/parser.c" +#line 2753 "src/parser.c" break; case 11: /* Exp: Term "as" Patterns '|' Exp */ -#line 368 "src/parser.y" +#line 339 "src/parser.y" { (yyval.blk) = gen_destructure((yyvsp[-4].blk), (yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2790 "src/parser.c" +#line 2761 "src/parser.c" break; case 12: /* Exp: "reduce" Term "as" Patterns '(' Exp ';' Exp ')' */ -#line 371 "src/parser.y" +#line 342 "src/parser.y" { (yyval.blk) = gen_reduce((yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk)); } -#line 2798 "src/parser.c" +#line 2769 "src/parser.c" break; case 13: /* Exp: "foreach" Term "as" Patterns '(' Exp ';' Exp ';' Exp ')' */ -#line 375 "src/parser.y" +#line 346 "src/parser.y" { (yyval.blk) = gen_foreach((yyvsp[-9].blk), (yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk)); } -#line 2806 "src/parser.c" +#line 2777 "src/parser.c" break; case 14: /* Exp: "foreach" Term "as" Patterns '(' Exp ';' Exp ')' */ -#line 379 "src/parser.y" +#line 350 "src/parser.y" { (yyval.blk) = gen_foreach((yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk), gen_noop()); } -#line 2814 "src/parser.c" +#line 2785 "src/parser.c" break; case 15: /* Exp: "if" Exp "then" Exp ElseBody */ -#line 383 "src/parser.y" +#line 354 "src/parser.y" { (yyval.blk) = gen_cond((yyvsp[-3].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 2822 "src/parser.c" +#line 2793 "src/parser.c" break; case 16: /* Exp: "if" Exp "then" error */ -#line 386 "src/parser.y" +#line 357 "src/parser.y" { FAIL((yyloc), "Possibly unterminated 'if' statement"); (yyval.blk) = (yyvsp[-2].blk); } -#line 2831 "src/parser.c" +#line 2802 "src/parser.c" break; case 17: /* Exp: "try" Exp "catch" Exp */ -#line 391 "src/parser.y" +#line 362 "src/parser.y" { (yyval.blk) = gen_try((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2839 "src/parser.c" +#line 2810 "src/parser.c" break; case 18: /* Exp: "try" Exp */ -#line 394 "src/parser.y" +#line 365 "src/parser.y" { (yyval.blk) = gen_try((yyvsp[0].blk), gen_op_simple(BACKTRACK)); } -#line 2847 "src/parser.c" +#line 2818 "src/parser.c" break; case 19: /* Exp: "try" Exp "catch" error */ -#line 397 "src/parser.y" +#line 368 "src/parser.y" { FAIL((yyloc), "Possibly unterminated 'try' statement"); (yyval.blk) = (yyvsp[-2].blk); } -#line 2856 "src/parser.c" +#line 2827 "src/parser.c" break; case 20: /* Exp: "label" BINDING '|' Exp */ -#line 402 "src/parser.y" +#line 373 "src/parser.y" { jv v = jv_string_fmt("*label-%s", jv_string_value((yyvsp[-2].literal))); (yyval.blk) = gen_location((yyloc), locations, gen_label(jv_string_value(v), (yyvsp[0].blk))); jv_free((yyvsp[-2].literal)); jv_free(v); } -#line 2867 "src/parser.c" +#line 2838 "src/parser.c" break; case 21: /* Exp: Exp '?' */ -#line 409 "src/parser.y" +#line 380 "src/parser.y" { (yyval.blk) = gen_try((yyvsp[-1].blk), gen_op_simple(BACKTRACK)); } -#line 2875 "src/parser.c" +#line 2846 "src/parser.c" break; case 22: /* Exp: Exp '=' Exp */ -#line 413 "src/parser.y" +#line 384 "src/parser.y" { (yyval.blk) = gen_call("_assign", BLOCK(gen_lambda((yyvsp[-2].blk)), gen_lambda((yyvsp[0].blk)))); } -#line 2883 "src/parser.c" +#line 2854 "src/parser.c" break; case 23: /* Exp: Exp "or" Exp */ -#line 417 "src/parser.y" +#line 388 "src/parser.y" { (yyval.blk) = gen_or((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2891 "src/parser.c" +#line 2862 "src/parser.c" break; case 24: /* Exp: Exp "and" Exp */ -#line 421 "src/parser.y" +#line 392 "src/parser.y" { (yyval.blk) = gen_and((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2899 "src/parser.c" +#line 2870 "src/parser.c" break; case 25: /* Exp: Exp "//" Exp */ -#line 425 "src/parser.y" +#line 396 "src/parser.y" { (yyval.blk) = gen_definedor((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2907 "src/parser.c" +#line 2878 "src/parser.c" break; case 26: /* Exp: Exp "//=" Exp */ -#line 429 "src/parser.y" +#line 400 "src/parser.y" { (yyval.blk) = gen_definedor_assign((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2915 "src/parser.c" +#line 2886 "src/parser.c" break; case 27: /* Exp: Exp "|=" Exp */ -#line 433 "src/parser.y" +#line 404 "src/parser.y" { (yyval.blk) = gen_call("_modify", BLOCK(gen_lambda((yyvsp[-2].blk)), gen_lambda((yyvsp[0].blk)))); } -#line 2923 "src/parser.c" +#line 2894 "src/parser.c" break; case 28: /* Exp: Exp '|' Exp */ -#line 437 "src/parser.y" +#line 408 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2931 "src/parser.c" +#line 2902 "src/parser.c" break; case 29: /* Exp: Exp ',' Exp */ -#line 441 "src/parser.y" +#line 412 "src/parser.y" { (yyval.blk) = gen_both((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 2939 "src/parser.c" +#line 2910 "src/parser.c" break; case 30: /* Exp: Exp '+' Exp */ -#line 445 "src/parser.y" +#line 416 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '+'); } -#line 2947 "src/parser.c" +#line 2918 "src/parser.c" break; case 31: /* Exp: Exp "+=" Exp */ -#line 449 "src/parser.y" +#line 420 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '+'); } -#line 2955 "src/parser.c" +#line 2926 "src/parser.c" break; case 32: /* Exp: '-' Exp */ -#line 453 "src/parser.y" +#line 424 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[0].blk), gen_call("_negate", gen_noop())); } -#line 2963 "src/parser.c" +#line 2934 "src/parser.c" break; case 33: /* Exp: Exp '-' Exp */ -#line 457 "src/parser.y" +#line 428 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '-'); } -#line 2971 "src/parser.c" +#line 2942 "src/parser.c" break; case 34: /* Exp: Exp "-=" Exp */ -#line 461 "src/parser.y" +#line 432 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '-'); } -#line 2979 "src/parser.c" +#line 2950 "src/parser.c" break; case 35: /* Exp: Exp '*' Exp */ -#line 465 "src/parser.y" +#line 436 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '*'); } -#line 2987 "src/parser.c" +#line 2958 "src/parser.c" break; case 36: /* Exp: Exp "*=" Exp */ -#line 469 "src/parser.y" +#line 440 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '*'); } -#line 2995 "src/parser.c" +#line 2966 "src/parser.c" break; case 37: /* Exp: Exp '/' Exp */ -#line 473 "src/parser.y" +#line 444 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '/'); } -#line 3003 "src/parser.c" +#line 2974 "src/parser.c" break; case 38: /* Exp: Exp '%' Exp */ -#line 477 "src/parser.y" +#line 448 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '%'); } -#line 3011 "src/parser.c" +#line 2982 "src/parser.c" break; case 39: /* Exp: Exp "/=" Exp */ -#line 481 "src/parser.y" +#line 452 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '/'); } -#line 3019 "src/parser.c" +#line 2990 "src/parser.c" break; case 40: /* Exp: Exp "%=" Exp */ -#line 485 "src/parser.y" +#line 456 "src/parser.y" { (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '%'); } -#line 3027 "src/parser.c" +#line 2998 "src/parser.c" break; case 41: /* Exp: Exp "==" Exp */ -#line 489 "src/parser.y" +#line 460 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), EQ); } -#line 3035 "src/parser.c" +#line 3006 "src/parser.c" break; case 42: /* Exp: Exp "!=" Exp */ -#line 493 "src/parser.y" +#line 464 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), NEQ); } -#line 3043 "src/parser.c" +#line 3014 "src/parser.c" break; case 43: /* Exp: Exp '<' Exp */ -#line 497 "src/parser.y" +#line 468 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '<'); } -#line 3051 "src/parser.c" +#line 3022 "src/parser.c" break; case 44: /* Exp: Exp '>' Exp */ -#line 501 "src/parser.y" +#line 472 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '>'); } -#line 3059 "src/parser.c" +#line 3030 "src/parser.c" break; case 45: /* Exp: Exp "<=" Exp */ -#line 505 "src/parser.y" +#line 476 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), LESSEQ); } -#line 3067 "src/parser.c" +#line 3038 "src/parser.c" break; case 46: /* Exp: Exp ">=" Exp */ -#line 509 "src/parser.y" +#line 480 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), GREATEREQ); } -#line 3075 "src/parser.c" +#line 3046 "src/parser.c" break; case 47: /* Exp: Term */ -#line 513 "src/parser.y" +#line 484 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3083 "src/parser.c" +#line 3054 "src/parser.c" break; case 48: /* Import: ImportWhat ';' */ -#line 518 "src/parser.y" +#line 489 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); } -#line 3091 "src/parser.c" +#line 3062 "src/parser.c" break; case 49: /* Import: ImportWhat Exp ';' */ -#line 521 "src/parser.y" +#line 492 "src/parser.y" { if (!block_is_const((yyvsp[-1].blk))) { FAIL((yyloc), "Module metadata must be constant"); @@ -3107,11 +3078,11 @@ YYLTYPE yylloc = yyloc_default; (yyval.blk) = gen_import_meta((yyvsp[-2].blk), (yyvsp[-1].blk)); } } -#line 3111 "src/parser.c" +#line 3082 "src/parser.c" break; case 50: /* ImportWhat: "import" ImportFrom "as" BINDING */ -#line 538 "src/parser.y" +#line 509 "src/parser.y" { jv v = block_const((yyvsp[-2].blk)); // XXX Make gen_import take only blocks and the int is_data so we @@ -3121,11 +3092,11 @@ YYLTYPE yylloc = yyloc_default; jv_free((yyvsp[0].literal)); jv_free(v); } -#line 3125 "src/parser.c" +#line 3096 "src/parser.c" break; case 51: /* ImportWhat: "import" ImportFrom "as" IDENT */ -#line 547 "src/parser.y" +#line 518 "src/parser.y" { jv v = block_const((yyvsp[-2].blk)); (yyval.blk) = gen_import(jv_string_value(v), jv_string_value((yyvsp[0].literal)), 0); @@ -3133,22 +3104,22 @@ YYLTYPE yylloc = yyloc_default; jv_free((yyvsp[0].literal)); jv_free(v); } -#line 3137 "src/parser.c" +#line 3108 "src/parser.c" break; case 52: /* ImportWhat: "include" ImportFrom */ -#line 554 "src/parser.y" +#line 525 "src/parser.y" { jv v = block_const((yyvsp[0].blk)); (yyval.blk) = gen_import(jv_string_value(v), NULL, 0); block_free((yyvsp[0].blk)); jv_free(v); } -#line 3148 "src/parser.c" +#line 3119 "src/parser.c" break; case 53: /* ImportFrom: String */ -#line 562 "src/parser.y" +#line 533 "src/parser.y" { if (!block_is_const((yyvsp[0].blk))) { FAIL((yyloc), "Import path must be constant"); @@ -3158,176 +3129,176 @@ YYLTYPE yylloc = yyloc_default; (yyval.blk) = (yyvsp[0].blk); } } -#line 3162 "src/parser.c" +#line 3133 "src/parser.c" break; case 54: /* FuncDef: "def" IDENT ':' Exp ';' */ -#line 573 "src/parser.y" +#line 544 "src/parser.y" { (yyval.blk) = gen_function(jv_string_value((yyvsp[-3].literal)), gen_noop(), (yyvsp[-1].blk)); jv_free((yyvsp[-3].literal)); } -#line 3171 "src/parser.c" +#line 3142 "src/parser.c" break; case 55: /* FuncDef: "def" IDENT '(' Params ')' ':' Exp ';' */ -#line 578 "src/parser.y" +#line 549 "src/parser.y" { (yyval.blk) = gen_function(jv_string_value((yyvsp[-6].literal)), (yyvsp[-4].blk), (yyvsp[-1].blk)); jv_free((yyvsp[-6].literal)); } -#line 3180 "src/parser.c" +#line 3151 "src/parser.c" break; case 56: /* Params: Param */ -#line 584 "src/parser.y" +#line 555 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3188 "src/parser.c" +#line 3159 "src/parser.c" break; case 57: /* Params: Params ';' Param */ -#line 587 "src/parser.y" +#line 558 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3196 "src/parser.c" +#line 3167 "src/parser.c" break; case 58: /* Param: BINDING */ -#line 592 "src/parser.y" +#line 563 "src/parser.y" { (yyval.blk) = gen_param_regular(jv_string_value((yyvsp[0].literal))); jv_free((yyvsp[0].literal)); } -#line 3205 "src/parser.c" +#line 3176 "src/parser.c" break; case 59: /* Param: IDENT */ -#line 596 "src/parser.y" +#line 567 "src/parser.y" { (yyval.blk) = gen_param(jv_string_value((yyvsp[0].literal))); jv_free((yyvsp[0].literal)); } -#line 3214 "src/parser.c" +#line 3185 "src/parser.c" break; case 60: /* StringStart: FORMAT QQSTRING_START */ -#line 603 "src/parser.y" +#line 574 "src/parser.y" { (yyval.literal) = (yyvsp[-1].literal); } -#line 3222 "src/parser.c" +#line 3193 "src/parser.c" break; case 61: /* StringStart: QQSTRING_START */ -#line 606 "src/parser.y" +#line 577 "src/parser.y" { (yyval.literal) = jv_string("text"); } -#line 3230 "src/parser.c" +#line 3201 "src/parser.c" break; case 62: /* String: StringStart QQString QQSTRING_END */ -#line 612 "src/parser.y" +#line 583 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); jv_free((yyvsp[-2].literal)); } -#line 3239 "src/parser.c" +#line 3210 "src/parser.c" break; case 63: /* QQString: %empty */ -#line 619 "src/parser.y" +#line 590 "src/parser.y" { (yyval.blk) = gen_const(jv_string("")); } -#line 3247 "src/parser.c" +#line 3218 "src/parser.c" break; case 64: /* QQString: QQString QQSTRING_TEXT */ -#line 622 "src/parser.y" +#line 593 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-1].blk), gen_const((yyvsp[0].literal)), '+'); } -#line 3255 "src/parser.c" +#line 3226 "src/parser.c" break; case 65: /* QQString: QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END */ -#line 625 "src/parser.y" +#line 596 "src/parser.y" { (yyval.blk) = gen_binop((yyvsp[-3].blk), gen_format((yyvsp[-1].blk), jv_copy((yyvsp[-4].literal))), '+'); } -#line 3263 "src/parser.c" +#line 3234 "src/parser.c" break; case 66: /* ElseBody: "elif" Exp "then" Exp ElseBody */ -#line 631 "src/parser.y" +#line 602 "src/parser.y" { (yyval.blk) = gen_cond((yyvsp[-3].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); } -#line 3271 "src/parser.c" +#line 3242 "src/parser.c" break; case 67: /* ElseBody: "else" Exp "end" */ -#line 634 "src/parser.y" +#line 605 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); } -#line 3279 "src/parser.c" +#line 3250 "src/parser.c" break; case 68: /* ElseBody: "end" */ -#line 637 "src/parser.y" +#line 608 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3287 "src/parser.c" +#line 3258 "src/parser.c" break; case 69: /* ExpD: ExpD '|' ExpD */ -#line 642 "src/parser.y" +#line 613 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3295 "src/parser.c" +#line 3266 "src/parser.c" break; case 70: /* ExpD: '-' ExpD */ -#line 645 "src/parser.y" +#line 616 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[0].blk), gen_call("_negate", gen_noop())); } -#line 3303 "src/parser.c" +#line 3274 "src/parser.c" break; case 71: /* ExpD: Term */ -#line 648 "src/parser.y" +#line 619 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3311 "src/parser.c" +#line 3282 "src/parser.c" break; case 72: /* Term: '.' */ -#line 654 "src/parser.y" +#line 625 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3319 "src/parser.c" +#line 3290 "src/parser.c" break; case 73: /* Term: ".." */ -#line 657 "src/parser.y" +#line 628 "src/parser.y" { (yyval.blk) = gen_call("recurse", gen_noop()); } -#line 3327 "src/parser.c" +#line 3298 "src/parser.c" break; case 74: /* Term: "break" BINDING */ -#line 660 "src/parser.y" +#line 631 "src/parser.y" { jv v = jv_string_fmt("*label-%s", jv_string_value((yyvsp[0].literal))); // impossible symbol (yyval.blk) = gen_location((yyloc), locations, @@ -3336,263 +3307,263 @@ YYLTYPE yylloc = yyloc_default; jv_free(v); jv_free((yyvsp[0].literal)); } -#line 3340 "src/parser.c" +#line 3311 "src/parser.c" break; case 75: /* Term: "break" error */ -#line 668 "src/parser.y" +#line 639 "src/parser.y" { FAIL((yyloc), "break requires a label to break to"); (yyval.blk) = gen_noop(); } -#line 3349 "src/parser.c" +#line 3320 "src/parser.c" break; case 76: /* Term: Term FIELD '?' */ -#line 672 "src/parser.y" +#line 643 "src/parser.y" { (yyval.blk) = gen_index_opt((yyvsp[-2].blk), gen_const((yyvsp[-1].literal))); } -#line 3357 "src/parser.c" +#line 3328 "src/parser.c" break; case 77: /* Term: FIELD '?' */ -#line 675 "src/parser.y" +#line 646 "src/parser.y" { (yyval.blk) = gen_index_opt(gen_noop(), gen_const((yyvsp[-1].literal))); } -#line 3365 "src/parser.c" +#line 3336 "src/parser.c" break; case 78: /* Term: Term '.' String '?' */ -#line 678 "src/parser.y" +#line 649 "src/parser.y" { (yyval.blk) = gen_index_opt((yyvsp[-3].blk), (yyvsp[-1].blk)); } -#line 3373 "src/parser.c" +#line 3344 "src/parser.c" break; case 79: /* Term: '.' String '?' */ -#line 681 "src/parser.y" +#line 652 "src/parser.y" { (yyval.blk) = gen_index_opt(gen_noop(), (yyvsp[-1].blk)); } -#line 3381 "src/parser.c" +#line 3352 "src/parser.c" break; case 80: /* Term: Term FIELD */ -#line 684 "src/parser.y" +#line 655 "src/parser.y" { (yyval.blk) = gen_index((yyvsp[-1].blk), gen_const((yyvsp[0].literal))); } -#line 3389 "src/parser.c" +#line 3360 "src/parser.c" break; case 81: /* Term: FIELD */ -#line 687 "src/parser.y" +#line 658 "src/parser.y" { (yyval.blk) = gen_index(gen_noop(), gen_const((yyvsp[0].literal))); } -#line 3397 "src/parser.c" +#line 3368 "src/parser.c" break; case 82: /* Term: Term '.' String */ -#line 690 "src/parser.y" +#line 661 "src/parser.y" { (yyval.blk) = gen_index((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3405 "src/parser.c" +#line 3376 "src/parser.c" break; case 83: /* Term: '.' String */ -#line 693 "src/parser.y" +#line 664 "src/parser.y" { (yyval.blk) = gen_index(gen_noop(), (yyvsp[0].blk)); } -#line 3413 "src/parser.c" +#line 3384 "src/parser.c" break; case 84: /* Term: '.' error */ -#line 696 "src/parser.y" +#line 667 "src/parser.y" { FAIL((yyloc), "try .[\"field\"] instead of .field for unusually named fields"); (yyval.blk) = gen_noop(); } -#line 3422 "src/parser.c" +#line 3393 "src/parser.c" break; case 85: /* Term: '.' IDENT error */ -#line 700 "src/parser.y" +#line 671 "src/parser.y" { jv_free((yyvsp[-1].literal)); FAIL((yyloc), "try .[\"field\"] instead of .field for unusually named fields"); (yyval.blk) = gen_noop(); } -#line 3432 "src/parser.c" +#line 3403 "src/parser.c" break; case 86: /* Term: Term '[' Exp ']' '?' */ -#line 706 "src/parser.y" +#line 677 "src/parser.y" { (yyval.blk) = gen_index_opt((yyvsp[-4].blk), (yyvsp[-2].blk)); } -#line 3440 "src/parser.c" +#line 3411 "src/parser.c" break; case 87: /* Term: Term '[' Exp ']' */ -#line 709 "src/parser.y" +#line 680 "src/parser.y" { (yyval.blk) = gen_index((yyvsp[-3].blk), (yyvsp[-1].blk)); } -#line 3448 "src/parser.c" +#line 3419 "src/parser.c" break; case 88: /* Term: Term '.' '[' Exp ']' '?' */ -#line 712 "src/parser.y" +#line 683 "src/parser.y" { (yyval.blk) = gen_index_opt((yyvsp[-5].blk), (yyvsp[-2].blk)); } -#line 3456 "src/parser.c" +#line 3427 "src/parser.c" break; case 89: /* Term: Term '.' '[' Exp ']' */ -#line 715 "src/parser.y" +#line 686 "src/parser.y" { (yyval.blk) = gen_index((yyvsp[-4].blk), (yyvsp[-1].blk)); } -#line 3464 "src/parser.c" +#line 3435 "src/parser.c" break; case 90: /* Term: Term '[' ']' '?' */ -#line 718 "src/parser.y" +#line 689 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-3].blk), gen_op_simple(EACH_OPT)); } -#line 3472 "src/parser.c" +#line 3443 "src/parser.c" break; case 91: /* Term: Term '[' ']' */ -#line 721 "src/parser.y" +#line 692 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-2].blk), gen_op_simple(EACH)); } -#line 3480 "src/parser.c" +#line 3451 "src/parser.c" break; case 92: /* Term: Term '.' '[' ']' '?' */ -#line 724 "src/parser.y" +#line 695 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-4].blk), gen_op_simple(EACH_OPT)); } -#line 3488 "src/parser.c" +#line 3459 "src/parser.c" break; case 93: /* Term: Term '.' '[' ']' */ -#line 727 "src/parser.y" +#line 698 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-3].blk), gen_op_simple(EACH)); } -#line 3496 "src/parser.c" +#line 3467 "src/parser.c" break; case 94: /* Term: Term '[' Exp ':' Exp ']' '?' */ -#line 730 "src/parser.y" +#line 701 "src/parser.y" { (yyval.blk) = gen_slice_index((yyvsp[-6].blk), (yyvsp[-4].blk), (yyvsp[-2].blk), INDEX_OPT); } -#line 3504 "src/parser.c" +#line 3475 "src/parser.c" break; case 95: /* Term: Term '[' Exp ':' ']' '?' */ -#line 733 "src/parser.y" +#line 704 "src/parser.y" { (yyval.blk) = gen_slice_index((yyvsp[-5].blk), (yyvsp[-3].blk), gen_const(jv_null()), INDEX_OPT); } -#line 3512 "src/parser.c" +#line 3483 "src/parser.c" break; case 96: /* Term: Term '[' ':' Exp ']' '?' */ -#line 736 "src/parser.y" +#line 707 "src/parser.y" { (yyval.blk) = gen_slice_index((yyvsp[-5].blk), gen_const(jv_null()), (yyvsp[-2].blk), INDEX_OPT); } -#line 3520 "src/parser.c" +#line 3491 "src/parser.c" break; case 97: /* Term: Term '[' Exp ':' Exp ']' */ -#line 739 "src/parser.y" +#line 710 "src/parser.y" { (yyval.blk) = gen_slice_index((yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk), INDEX); } -#line 3528 "src/parser.c" +#line 3499 "src/parser.c" break; case 98: /* Term: Term '[' Exp ':' ']' */ -#line 742 "src/parser.y" +#line 713 "src/parser.y" { (yyval.blk) = gen_slice_index((yyvsp[-4].blk), (yyvsp[-2].blk), gen_const(jv_null()), INDEX); } -#line 3536 "src/parser.c" +#line 3507 "src/parser.c" break; case 99: /* Term: Term '[' ':' Exp ']' */ -#line 745 "src/parser.y" +#line 716 "src/parser.y" { (yyval.blk) = gen_slice_index((yyvsp[-4].blk), gen_const(jv_null()), (yyvsp[-1].blk), INDEX); } -#line 3544 "src/parser.c" +#line 3515 "src/parser.c" break; case 100: /* Term: LITERAL */ -#line 748 "src/parser.y" +#line 719 "src/parser.y" { (yyval.blk) = gen_const((yyvsp[0].literal)); } -#line 3552 "src/parser.c" +#line 3523 "src/parser.c" break; case 101: /* Term: String */ -#line 751 "src/parser.y" +#line 722 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3560 "src/parser.c" +#line 3531 "src/parser.c" break; case 102: /* Term: FORMAT */ -#line 754 "src/parser.y" +#line 725 "src/parser.y" { (yyval.blk) = gen_format(gen_noop(), (yyvsp[0].literal)); } -#line 3568 "src/parser.c" +#line 3539 "src/parser.c" break; case 103: /* Term: '(' Exp ')' */ -#line 757 "src/parser.y" +#line 728 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); } -#line 3576 "src/parser.c" +#line 3547 "src/parser.c" break; case 104: /* Term: '[' Exp ']' */ -#line 760 "src/parser.y" +#line 731 "src/parser.y" { (yyval.blk) = gen_collect((yyvsp[-1].blk)); } -#line 3584 "src/parser.c" +#line 3555 "src/parser.c" break; case 105: /* Term: '[' ']' */ -#line 763 "src/parser.y" +#line 734 "src/parser.y" { (yyval.blk) = gen_const(jv_array()); } -#line 3592 "src/parser.c" +#line 3563 "src/parser.c" break; case 106: /* Term: '{' MkDict '}' */ -#line 766 "src/parser.y" +#line 737 "src/parser.y" { block o = gen_const_object((yyvsp[-1].blk)); if (o.first != NULL) @@ -3600,37 +3571,37 @@ YYLTYPE yylloc = yyloc_default; else (yyval.blk) = BLOCK(gen_subexp(gen_const(jv_object())), (yyvsp[-1].blk), gen_op_simple(POP)); } -#line 3604 "src/parser.c" +#line 3575 "src/parser.c" break; case 107: /* Term: '$' '$' '$' BINDING */ -#line 788 "src/parser.y" +#line 759 "src/parser.y" { (yyval.blk) = gen_location((yyloc), locations, gen_op_unbound(LOADVN, jv_string_value((yyvsp[0].literal)))); jv_free((yyvsp[0].literal)); } -#line 3613 "src/parser.c" +#line 3584 "src/parser.c" break; case 108: /* Term: BINDING */ -#line 792 "src/parser.y" +#line 763 "src/parser.y" { (yyval.blk) = gen_location((yyloc), locations, gen_op_unbound(LOADV, jv_string_value((yyvsp[0].literal)))); jv_free((yyvsp[0].literal)); } -#line 3622 "src/parser.c" +#line 3593 "src/parser.c" break; case 109: /* Term: "$__loc__" */ -#line 796 "src/parser.y" +#line 767 "src/parser.y" { (yyval.blk) = gen_loc_object(&(yyloc), locations); } -#line 3630 "src/parser.c" +#line 3601 "src/parser.c" break; case 110: /* Term: IDENT */ -#line 799 "src/parser.y" +#line 770 "src/parser.y" { const char *s = jv_string_value((yyvsp[0].literal)); if (strcmp(s, "false") == 0) @@ -3643,198 +3614,198 @@ YYLTYPE yylloc = yyloc_default; (yyval.blk) = gen_location((yyloc), locations, gen_call(s, gen_noop())); jv_free((yyvsp[0].literal)); } -#line 3647 "src/parser.c" +#line 3618 "src/parser.c" break; case 111: /* Term: IDENT '(' Args ')' */ -#line 811 "src/parser.y" +#line 782 "src/parser.y" { (yyval.blk) = gen_call(jv_string_value((yyvsp[-3].literal)), (yyvsp[-1].blk)); (yyval.blk) = gen_location((yylsp[-3]), locations, (yyval.blk)); jv_free((yyvsp[-3].literal)); } -#line 3657 "src/parser.c" +#line 3628 "src/parser.c" break; case 112: /* Term: '(' error ')' */ -#line 816 "src/parser.y" +#line 787 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3663 "src/parser.c" +#line 3634 "src/parser.c" break; case 113: /* Term: '[' error ']' */ -#line 817 "src/parser.y" +#line 788 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3669 "src/parser.c" +#line 3640 "src/parser.c" break; case 114: /* Term: Term '[' error ']' */ -#line 818 "src/parser.y" +#line 789 "src/parser.y" { (yyval.blk) = (yyvsp[-3].blk); } -#line 3675 "src/parser.c" +#line 3646 "src/parser.c" break; case 115: /* Term: '{' error '}' */ -#line 819 "src/parser.y" +#line 790 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3681 "src/parser.c" +#line 3652 "src/parser.c" break; case 116: /* Args: Arg */ -#line 822 "src/parser.y" +#line 793 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3689 "src/parser.c" +#line 3660 "src/parser.c" break; case 117: /* Args: Args ';' Arg */ -#line 825 "src/parser.y" +#line 796 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3697 "src/parser.c" +#line 3668 "src/parser.c" break; case 118: /* Arg: Exp */ -#line 830 "src/parser.y" +#line 801 "src/parser.y" { (yyval.blk) = gen_lambda((yyvsp[0].blk)); } -#line 3705 "src/parser.c" +#line 3676 "src/parser.c" break; case 119: /* RepPatterns: RepPatterns "?//" Pattern */ -#line 835 "src/parser.y" +#line 806 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), gen_destructure_alt((yyvsp[0].blk))); } -#line 3713 "src/parser.c" +#line 3684 "src/parser.c" break; case 120: /* RepPatterns: Pattern */ -#line 838 "src/parser.y" +#line 809 "src/parser.y" { (yyval.blk) = gen_destructure_alt((yyvsp[0].blk)); } -#line 3721 "src/parser.c" +#line 3692 "src/parser.c" break; case 121: /* Patterns: RepPatterns "?//" Pattern */ -#line 843 "src/parser.y" +#line 814 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3729 "src/parser.c" +#line 3700 "src/parser.c" break; case 122: /* Patterns: Pattern */ -#line 846 "src/parser.y" +#line 817 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3737 "src/parser.c" +#line 3708 "src/parser.c" break; case 123: /* Pattern: BINDING */ -#line 851 "src/parser.y" +#line 822 "src/parser.y" { (yyval.blk) = gen_op_unbound(STOREV, jv_string_value((yyvsp[0].literal))); jv_free((yyvsp[0].literal)); } -#line 3746 "src/parser.c" +#line 3717 "src/parser.c" break; case 124: /* Pattern: '[' ArrayPats ']' */ -#line 855 "src/parser.y" +#line 826 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-1].blk), gen_op_simple(POP)); } -#line 3754 "src/parser.c" +#line 3725 "src/parser.c" break; case 125: /* Pattern: '{' ObjPats '}' */ -#line 858 "src/parser.y" +#line 829 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-1].blk), gen_op_simple(POP)); } -#line 3762 "src/parser.c" +#line 3733 "src/parser.c" break; case 126: /* ArrayPats: Pattern */ -#line 863 "src/parser.y" +#line 834 "src/parser.y" { (yyval.blk) = gen_array_matcher(gen_noop(), (yyvsp[0].blk)); } -#line 3770 "src/parser.c" +#line 3741 "src/parser.c" break; case 127: /* ArrayPats: ArrayPats ',' Pattern */ -#line 866 "src/parser.y" +#line 837 "src/parser.y" { (yyval.blk) = gen_array_matcher((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3778 "src/parser.c" +#line 3749 "src/parser.c" break; case 128: /* ObjPats: ObjPat */ -#line 871 "src/parser.y" +#line 842 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3786 "src/parser.c" +#line 3757 "src/parser.c" break; case 129: /* ObjPats: ObjPats ',' ObjPat */ -#line 874 "src/parser.y" +#line 845 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3794 "src/parser.c" +#line 3765 "src/parser.c" break; case 130: /* ObjPat: BINDING */ -#line 879 "src/parser.y" +#line 850 "src/parser.y" { (yyval.blk) = gen_object_matcher(gen_const((yyvsp[0].literal)), gen_op_unbound(STOREV, jv_string_value((yyvsp[0].literal)))); } -#line 3802 "src/parser.c" +#line 3773 "src/parser.c" break; case 131: /* ObjPat: BINDING ':' Pattern */ -#line 882 "src/parser.y" +#line 853 "src/parser.y" { (yyval.blk) = gen_object_matcher(gen_const((yyvsp[-2].literal)), BLOCK(gen_op_simple(DUP), gen_op_unbound(STOREV, jv_string_value((yyvsp[-2].literal))), (yyvsp[0].blk))); } -#line 3810 "src/parser.c" +#line 3781 "src/parser.c" break; case 132: /* ObjPat: IDENT ':' Pattern */ -#line 885 "src/parser.y" +#line 856 "src/parser.y" { (yyval.blk) = gen_object_matcher(gen_const((yyvsp[-2].literal)), (yyvsp[0].blk)); } -#line 3818 "src/parser.c" +#line 3789 "src/parser.c" break; case 133: /* ObjPat: Keyword ':' Pattern */ -#line 888 "src/parser.y" +#line 859 "src/parser.y" { (yyval.blk) = gen_object_matcher(gen_const((yyvsp[-2].literal)), (yyvsp[0].blk)); } -#line 3826 "src/parser.c" +#line 3797 "src/parser.c" break; case 134: /* ObjPat: String ':' Pattern */ -#line 891 "src/parser.y" +#line 862 "src/parser.y" { (yyval.blk) = gen_object_matcher((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3834 "src/parser.c" +#line 3805 "src/parser.c" break; case 135: /* ObjPat: '(' Exp ')' ':' Pattern */ -#line 894 "src/parser.y" +#line 865 "src/parser.y" { jv msg = check_object_key((yyvsp[-3].blk)); if (jv_is_valid(msg)) { @@ -3843,269 +3814,269 @@ YYLTYPE yylloc = yyloc_default; jv_free(msg); (yyval.blk) = gen_object_matcher((yyvsp[-3].blk), (yyvsp[0].blk)); } -#line 3847 "src/parser.c" +#line 3818 "src/parser.c" break; case 136: /* ObjPat: error ':' Pattern */ -#line 902 "src/parser.y" +#line 873 "src/parser.y" { FAIL((yyloc), "May need parentheses around object key expression"); (yyval.blk) = (yyvsp[0].blk); } -#line 3856 "src/parser.c" +#line 3827 "src/parser.c" break; case 137: /* Keyword: "as" */ -#line 908 "src/parser.y" +#line 879 "src/parser.y" { (yyval.literal) = jv_string("as"); } -#line 3864 "src/parser.c" +#line 3835 "src/parser.c" break; case 138: /* Keyword: "def" */ -#line 911 "src/parser.y" +#line 882 "src/parser.y" { (yyval.literal) = jv_string("def"); } -#line 3872 "src/parser.c" +#line 3843 "src/parser.c" break; case 139: /* Keyword: "module" */ -#line 914 "src/parser.y" +#line 885 "src/parser.y" { (yyval.literal) = jv_string("module"); } -#line 3880 "src/parser.c" +#line 3851 "src/parser.c" break; case 140: /* Keyword: "import" */ -#line 917 "src/parser.y" +#line 888 "src/parser.y" { (yyval.literal) = jv_string("import"); } -#line 3888 "src/parser.c" +#line 3859 "src/parser.c" break; case 141: /* Keyword: "include" */ -#line 920 "src/parser.y" +#line 891 "src/parser.y" { (yyval.literal) = jv_string("include"); } -#line 3896 "src/parser.c" +#line 3867 "src/parser.c" break; case 142: /* Keyword: "if" */ -#line 923 "src/parser.y" +#line 894 "src/parser.y" { (yyval.literal) = jv_string("if"); } -#line 3904 "src/parser.c" +#line 3875 "src/parser.c" break; case 143: /* Keyword: "then" */ -#line 926 "src/parser.y" +#line 897 "src/parser.y" { (yyval.literal) = jv_string("then"); } -#line 3912 "src/parser.c" +#line 3883 "src/parser.c" break; case 144: /* Keyword: "else" */ -#line 929 "src/parser.y" +#line 900 "src/parser.y" { (yyval.literal) = jv_string("else"); } -#line 3920 "src/parser.c" +#line 3891 "src/parser.c" break; case 145: /* Keyword: "elif" */ -#line 932 "src/parser.y" +#line 903 "src/parser.y" { (yyval.literal) = jv_string("elif"); } -#line 3928 "src/parser.c" +#line 3899 "src/parser.c" break; case 146: /* Keyword: "reduce" */ -#line 935 "src/parser.y" +#line 906 "src/parser.y" { (yyval.literal) = jv_string("reduce"); } -#line 3936 "src/parser.c" +#line 3907 "src/parser.c" break; case 147: /* Keyword: "foreach" */ -#line 938 "src/parser.y" +#line 909 "src/parser.y" { (yyval.literal) = jv_string("foreach"); } -#line 3944 "src/parser.c" +#line 3915 "src/parser.c" break; case 148: /* Keyword: "end" */ -#line 941 "src/parser.y" +#line 912 "src/parser.y" { (yyval.literal) = jv_string("end"); } -#line 3952 "src/parser.c" +#line 3923 "src/parser.c" break; case 149: /* Keyword: "and" */ -#line 944 "src/parser.y" +#line 915 "src/parser.y" { (yyval.literal) = jv_string("and"); } -#line 3960 "src/parser.c" +#line 3931 "src/parser.c" break; case 150: /* Keyword: "or" */ -#line 947 "src/parser.y" +#line 918 "src/parser.y" { (yyval.literal) = jv_string("or"); } -#line 3968 "src/parser.c" +#line 3939 "src/parser.c" break; case 151: /* Keyword: "try" */ -#line 950 "src/parser.y" +#line 921 "src/parser.y" { (yyval.literal) = jv_string("try"); } -#line 3976 "src/parser.c" +#line 3947 "src/parser.c" break; case 152: /* Keyword: "catch" */ -#line 953 "src/parser.y" +#line 924 "src/parser.y" { (yyval.literal) = jv_string("catch"); } -#line 3984 "src/parser.c" +#line 3955 "src/parser.c" break; case 153: /* Keyword: "label" */ -#line 956 "src/parser.y" +#line 927 "src/parser.y" { (yyval.literal) = jv_string("label"); } -#line 3992 "src/parser.c" +#line 3963 "src/parser.c" break; case 154: /* Keyword: "break" */ -#line 959 "src/parser.y" +#line 930 "src/parser.y" { (yyval.literal) = jv_string("break"); } -#line 4000 "src/parser.c" +#line 3971 "src/parser.c" break; case 155: /* MkDict: %empty */ -#line 964 "src/parser.y" +#line 935 "src/parser.y" { (yyval.blk)=gen_noop(); } -#line 4008 "src/parser.c" +#line 3979 "src/parser.c" break; case 156: /* MkDict: MkDictPair */ -#line 967 "src/parser.y" +#line 938 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 4014 "src/parser.c" +#line 3985 "src/parser.c" break; case 157: /* MkDict: MkDictPair ',' MkDict */ -#line 968 "src/parser.y" +#line 939 "src/parser.y" { (yyval.blk)=block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 4020 "src/parser.c" +#line 3991 "src/parser.c" break; case 158: /* MkDict: error ',' MkDict */ -#line 969 "src/parser.y" +#line 940 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 4026 "src/parser.c" +#line 3997 "src/parser.c" break; case 159: /* MkDictPair: IDENT ':' ExpD */ -#line 972 "src/parser.y" +#line 943 "src/parser.y" { (yyval.blk) = gen_dictpair(gen_const((yyvsp[-2].literal)), (yyvsp[0].blk)); } -#line 4034 "src/parser.c" +#line 4005 "src/parser.c" break; case 160: /* MkDictPair: Keyword ':' ExpD */ -#line 975 "src/parser.y" +#line 946 "src/parser.y" { (yyval.blk) = gen_dictpair(gen_const((yyvsp[-2].literal)), (yyvsp[0].blk)); } -#line 4042 "src/parser.c" +#line 4013 "src/parser.c" break; case 161: /* MkDictPair: String ':' ExpD */ -#line 978 "src/parser.y" +#line 949 "src/parser.y" { (yyval.blk) = gen_dictpair((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 4050 "src/parser.c" +#line 4021 "src/parser.c" break; case 162: /* MkDictPair: String */ -#line 981 "src/parser.y" +#line 952 "src/parser.y" { (yyval.blk) = gen_dictpair((yyvsp[0].blk), BLOCK(gen_op_simple(POP), gen_op_simple(DUP2), gen_op_simple(DUP2), gen_op_simple(INDEX))); } -#line 4059 "src/parser.c" +#line 4030 "src/parser.c" break; case 163: /* MkDictPair: BINDING ':' ExpD */ -#line 985 "src/parser.y" +#line 956 "src/parser.y" { (yyval.blk) = gen_dictpair(gen_location((yyloc), locations, gen_op_unbound(LOADV, jv_string_value((yyvsp[-2].literal)))), (yyvsp[0].blk)); jv_free((yyvsp[-2].literal)); } -#line 4069 "src/parser.c" +#line 4040 "src/parser.c" break; case 164: /* MkDictPair: BINDING */ -#line 990 "src/parser.y" +#line 961 "src/parser.y" { (yyval.blk) = gen_dictpair(gen_const((yyvsp[0].literal)), gen_location((yyloc), locations, gen_op_unbound(LOADV, jv_string_value((yyvsp[0].literal))))); } -#line 4078 "src/parser.c" +#line 4049 "src/parser.c" break; case 165: /* MkDictPair: IDENT */ -#line 994 "src/parser.y" +#line 965 "src/parser.y" { (yyval.blk) = gen_dictpair(gen_const(jv_copy((yyvsp[0].literal))), gen_index(gen_noop(), gen_const((yyvsp[0].literal)))); } -#line 4087 "src/parser.c" +#line 4058 "src/parser.c" break; case 166: /* MkDictPair: "$__loc__" */ -#line 998 "src/parser.y" +#line 969 "src/parser.y" { (yyval.blk) = gen_dictpair(gen_const(jv_string("__loc__")), gen_loc_object(&(yyloc), locations)); } -#line 4096 "src/parser.c" +#line 4067 "src/parser.c" break; case 167: /* MkDictPair: Keyword */ -#line 1002 "src/parser.y" +#line 973 "src/parser.y" { (yyval.blk) = gen_dictpair(gen_const(jv_copy((yyvsp[0].literal))), gen_index(gen_noop(), gen_const((yyvsp[0].literal)))); } -#line 4105 "src/parser.c" +#line 4076 "src/parser.c" break; case 168: /* MkDictPair: '(' Exp ')' ':' ExpD */ -#line 1006 "src/parser.y" +#line 977 "src/parser.y" { jv msg = check_object_key((yyvsp[-3].blk)); if (jv_is_valid(msg)) { @@ -4114,20 +4085,20 @@ YYLTYPE yylloc = yyloc_default; jv_free(msg); (yyval.blk) = gen_dictpair((yyvsp[-3].blk), (yyvsp[0].blk)); } -#line 4118 "src/parser.c" +#line 4089 "src/parser.c" break; case 169: /* MkDictPair: error ':' ExpD */ -#line 1014 "src/parser.y" +#line 985 "src/parser.y" { FAIL((yyloc), "May need parentheses around object key expression"); (yyval.blk) = (yyvsp[0].blk); } -#line 4127 "src/parser.c" +#line 4098 "src/parser.c" break; -#line 4131 "src/parser.c" +#line 4102 "src/parser.c" default: break; } @@ -4356,7 +4327,7 @@ YYLTYPE yylloc = yyloc_default; return yyresult; } -#line 1018 "src/parser.y" +#line 989 "src/parser.y" int jq_parse(struct locfile* locations, block* answer) { diff --git a/src/parser.h b/src/parser.h index 1e4369fa03..228db303b5 100644 --- a/src/parser.h +++ b/src/parser.h @@ -45,7 +45,7 @@ extern int yydebug; #endif /* "%code requires" blocks. */ -#line 11 "src/parser.y" +#line 12 "src/parser.y" #include "locfile.h" struct lexer_param; @@ -178,7 +178,7 @@ struct lexer_param; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 31 "src/parser.y" +#line 32 "src/parser.y" jv literal; block blk; diff --git a/src/parser.y b/src/parser.y index af722a7c6f..cd12ebef05 100644 --- a/src/parser.y +++ b/src/parser.y @@ -5,6 +5,7 @@ #include #include "compile.h" #include "jv_alloc.h" +#include "builtin.h" #define YYMALLOC jv_mem_alloc #define YYFREE jv_mem_free %} @@ -202,63 +203,33 @@ static block constant_fold(block a, block b, int op) { if (!block_is_single(a) || !block_is_const(a) || !block_is_single(b) || !block_is_const(b)) return gen_noop(); - if (op == '+') { - if (block_const_kind(a) == JV_KIND_NULL) { - block_free(a); - return b; - } - if (block_const_kind(b) == JV_KIND_NULL) { - block_free(b); - return a; - } - } - if (block_const_kind(a) != block_const_kind(b)) - return gen_noop(); - jv res = jv_invalid(); + jv jv_a = block_const(a); + jv jv_b = block_const(b); - if (block_const_kind(a) == JV_KIND_NUMBER) { - jv jv_a = block_const(a); - jv jv_b = block_const(b); - - double na = jv_number_value(jv_a); - double nb = jv_number_value(jv_b); - - int cmp = jv_cmp(jv_a, jv_b); - - switch (op) { - case '+': res = jv_number(na + nb); break; - case '-': res = jv_number(na - nb); break; - case '*': res = jv_number(na * nb); break; - case '/': - if (nb == 0.0) return gen_noop(); - res = jv_number(na / nb); - break; - case '%': -#define is_unsafe_to_int_cast(n) (isnan(n) || (n) < INTMAX_MIN || -(n) < INTMAX_MIN) - if (is_unsafe_to_int_cast(na) || is_unsafe_to_int_cast(nb) || (intmax_t)nb == 0) return gen_noop(); -#undef is_unsafe_to_int_cast - res = jv_number((intmax_t)na % (intmax_t)nb); - break; - case EQ: res = (cmp == 0 ? jv_true() : jv_false()); break; - case NEQ: res = (cmp != 0 ? jv_true() : jv_false()); break; - case '<': res = (cmp < 0 ? jv_true() : jv_false()); break; - case '>': res = (cmp > 0 ? jv_true() : jv_false()); break; - case LESSEQ: res = (cmp <= 0 ? jv_true() : jv_false()); break; - case GREATEREQ: res = (cmp >= 0 ? jv_true() : jv_false()); break; - default: break; - } - } else if (op == '+' && block_const_kind(a) == JV_KIND_STRING) { - res = jv_string_concat(block_const(a), block_const(b)); - } else { - return gen_noop(); + jv res = jv_invalid(); + switch (op) { + case '+': res = binop_plus(jv_a, jv_b); break; + case '-': res = binop_minus(jv_a, jv_b); break; + case '*': res = binop_multiply(jv_a, jv_b); break; + case '/': res = binop_divide(jv_a, jv_b); break; + case '%': res = binop_mod(jv_a, jv_b); break; + case EQ: res = binop_equal(jv_a, jv_b); break; + case NEQ: res = binop_notequal(jv_a, jv_b); break; + case '<': res = binop_less(jv_a, jv_b); break; + case '>': res = binop_greater(jv_a, jv_b); break; + case LESSEQ: res = binop_lesseq(jv_a, jv_b); break; + case GREATEREQ: res = binop_greatereq(jv_a, jv_b); break; } - if (jv_get_kind(res) == JV_KIND_INVALID) + if (!jv_is_valid(res)) { + jv_free(res); return gen_noop(); + } block_free(a); block_free(b); + return gen_const(res); }