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 a1987d34a6..5b3a8f6fc5 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; @@ -389,7 +390,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 { @@ -469,63 +470,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); } @@ -583,7 +554,7 @@ static block gen_loc_object(location *loc, struct locfile *locations) { } -#line 587 "src/parser.c" +#line 558 "src/parser.c" #ifdef short @@ -973,24 +944,24 @@ 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, 608, 612, 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, 579, 583, 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_NoFormat: /* NoFormat */ -#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,183 +3129,183 @@ 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: /* NoFormat: %empty */ -#line 603 "src/parser.y" +#line 574 "src/parser.y" { (yyval.literal) = jv_string("text"); } -#line 3222 "src/parser.c" +#line 3193 "src/parser.c" break; case 61: /* String: QQSTRING_START NoFormat QQString QQSTRING_END */ -#line 608 "src/parser.y" +#line 579 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); jv_free((yyvsp[-2].literal)); } -#line 3231 "src/parser.c" +#line 3202 "src/parser.c" break; case 62: /* @1: %empty */ -#line 612 "src/parser.y" +#line 583 "src/parser.y" { (yyval.literal) = (yyvsp[-1].literal); } -#line 3237 "src/parser.c" +#line 3208 "src/parser.c" break; case 63: /* String: FORMAT QQSTRING_START @1 QQString QQSTRING_END */ -#line 612 "src/parser.y" +#line 583 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); jv_free((yyvsp[-2].literal)); } -#line 3246 "src/parser.c" +#line 3217 "src/parser.c" break; case 64: /* QQString: %empty */ -#line 619 "src/parser.y" +#line 590 "src/parser.y" { (yyval.blk) = gen_const(jv_string("")); } -#line 3254 "src/parser.c" +#line 3225 "src/parser.c" break; case 65: /* 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 3262 "src/parser.c" +#line 3233 "src/parser.c" break; case 66: /* 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 3270 "src/parser.c" +#line 3241 "src/parser.c" break; case 67: /* 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 3278 "src/parser.c" +#line 3249 "src/parser.c" break; case 68: /* ElseBody: "else" Exp "end" */ -#line 634 "src/parser.y" +#line 605 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); } -#line 3286 "src/parser.c" +#line 3257 "src/parser.c" break; case 69: /* ElseBody: "end" */ -#line 637 "src/parser.y" +#line 608 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3294 "src/parser.c" +#line 3265 "src/parser.c" break; case 70: /* ExpD: ExpD '|' ExpD */ -#line 642 "src/parser.y" +#line 613 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3302 "src/parser.c" +#line 3273 "src/parser.c" break; case 71: /* ExpD: '-' ExpD */ -#line 645 "src/parser.y" +#line 616 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[0].blk), gen_call("_negate", gen_noop())); } -#line 3310 "src/parser.c" +#line 3281 "src/parser.c" break; case 72: /* ExpD: Term */ -#line 648 "src/parser.y" +#line 619 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3318 "src/parser.c" +#line 3289 "src/parser.c" break; case 73: /* Term: '.' */ -#line 654 "src/parser.y" +#line 625 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3326 "src/parser.c" +#line 3297 "src/parser.c" break; case 74: /* Term: ".." */ -#line 657 "src/parser.y" +#line 628 "src/parser.y" { (yyval.blk) = gen_call("recurse", gen_noop()); } -#line 3334 "src/parser.c" +#line 3305 "src/parser.c" break; case 75: /* 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, @@ -3343,263 +3314,263 @@ YYLTYPE yylloc = yyloc_default; jv_free(v); jv_free((yyvsp[0].literal)); } -#line 3347 "src/parser.c" +#line 3318 "src/parser.c" break; case 76: /* 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 3356 "src/parser.c" +#line 3327 "src/parser.c" break; case 77: /* 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 3364 "src/parser.c" +#line 3335 "src/parser.c" break; case 78: /* 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 3372 "src/parser.c" +#line 3343 "src/parser.c" break; case 79: /* 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 3380 "src/parser.c" +#line 3351 "src/parser.c" break; case 80: /* Term: '.' String '?' */ -#line 681 "src/parser.y" +#line 652 "src/parser.y" { (yyval.blk) = gen_index_opt(gen_noop(), (yyvsp[-1].blk)); } -#line 3388 "src/parser.c" +#line 3359 "src/parser.c" break; case 81: /* 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 3396 "src/parser.c" +#line 3367 "src/parser.c" break; case 82: /* Term: FIELD */ -#line 687 "src/parser.y" +#line 658 "src/parser.y" { (yyval.blk) = gen_index(gen_noop(), gen_const((yyvsp[0].literal))); } -#line 3404 "src/parser.c" +#line 3375 "src/parser.c" break; case 83: /* Term: Term '.' String */ -#line 690 "src/parser.y" +#line 661 "src/parser.y" { (yyval.blk) = gen_index((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3412 "src/parser.c" +#line 3383 "src/parser.c" break; case 84: /* Term: '.' String */ -#line 693 "src/parser.y" +#line 664 "src/parser.y" { (yyval.blk) = gen_index(gen_noop(), (yyvsp[0].blk)); } -#line 3420 "src/parser.c" +#line 3391 "src/parser.c" break; case 85: /* 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 3429 "src/parser.c" +#line 3400 "src/parser.c" break; case 86: /* 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 3439 "src/parser.c" +#line 3410 "src/parser.c" break; case 87: /* 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 3447 "src/parser.c" +#line 3418 "src/parser.c" break; case 88: /* Term: Term '[' Exp ']' */ -#line 709 "src/parser.y" +#line 680 "src/parser.y" { (yyval.blk) = gen_index((yyvsp[-3].blk), (yyvsp[-1].blk)); } -#line 3455 "src/parser.c" +#line 3426 "src/parser.c" break; case 89: /* 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 3463 "src/parser.c" +#line 3434 "src/parser.c" break; case 90: /* Term: Term '.' '[' Exp ']' */ -#line 715 "src/parser.y" +#line 686 "src/parser.y" { (yyval.blk) = gen_index((yyvsp[-4].blk), (yyvsp[-1].blk)); } -#line 3471 "src/parser.c" +#line 3442 "src/parser.c" break; case 91: /* 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 3479 "src/parser.c" +#line 3450 "src/parser.c" break; case 92: /* Term: Term '[' ']' */ -#line 721 "src/parser.y" +#line 692 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-2].blk), gen_op_simple(EACH)); } -#line 3487 "src/parser.c" +#line 3458 "src/parser.c" break; case 93: /* 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 3495 "src/parser.c" +#line 3466 "src/parser.c" break; case 94: /* Term: Term '.' '[' ']' */ -#line 727 "src/parser.y" +#line 698 "src/parser.y" { (yyval.blk) = block_join((yyvsp[-3].blk), gen_op_simple(EACH)); } -#line 3503 "src/parser.c" +#line 3474 "src/parser.c" break; case 95: /* 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 3511 "src/parser.c" +#line 3482 "src/parser.c" break; case 96: /* 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 3519 "src/parser.c" +#line 3490 "src/parser.c" break; case 97: /* 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 3527 "src/parser.c" +#line 3498 "src/parser.c" break; case 98: /* 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 3535 "src/parser.c" +#line 3506 "src/parser.c" break; case 99: /* 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 3543 "src/parser.c" +#line 3514 "src/parser.c" break; case 100: /* 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 3551 "src/parser.c" +#line 3522 "src/parser.c" break; case 101: /* Term: LITERAL */ -#line 748 "src/parser.y" +#line 719 "src/parser.y" { (yyval.blk) = gen_const((yyvsp[0].literal)); } -#line 3559 "src/parser.c" +#line 3530 "src/parser.c" break; case 102: /* Term: String */ -#line 751 "src/parser.y" +#line 722 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3567 "src/parser.c" +#line 3538 "src/parser.c" break; case 103: /* Term: FORMAT */ -#line 754 "src/parser.y" +#line 725 "src/parser.y" { (yyval.blk) = gen_format(gen_noop(), (yyvsp[0].literal)); } -#line 3575 "src/parser.c" +#line 3546 "src/parser.c" break; case 104: /* Term: '(' Exp ')' */ -#line 757 "src/parser.y" +#line 728 "src/parser.y" { (yyval.blk) = (yyvsp[-1].blk); } -#line 3583 "src/parser.c" +#line 3554 "src/parser.c" break; case 105: /* Term: '[' Exp ']' */ -#line 760 "src/parser.y" +#line 731 "src/parser.y" { (yyval.blk) = gen_collect((yyvsp[-1].blk)); } -#line 3591 "src/parser.c" +#line 3562 "src/parser.c" break; case 106: /* Term: '[' ']' */ -#line 763 "src/parser.y" +#line 734 "src/parser.y" { (yyval.blk) = gen_const(jv_array()); } -#line 3599 "src/parser.c" +#line 3570 "src/parser.c" break; case 107: /* Term: '{' MkDict '}' */ -#line 766 "src/parser.y" +#line 737 "src/parser.y" { block o = gen_const_object((yyvsp[-1].blk)); if (o.first != NULL) @@ -3607,37 +3578,37 @@ YYLTYPE yylloc = yyloc_default; else (yyval.blk) = BLOCK(gen_subexp(gen_const(jv_object())), (yyvsp[-1].blk), gen_op_simple(POP)); } -#line 3611 "src/parser.c" +#line 3582 "src/parser.c" break; case 108: /* 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 3620 "src/parser.c" +#line 3591 "src/parser.c" break; case 109: /* 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 3629 "src/parser.c" +#line 3600 "src/parser.c" break; case 110: /* Term: "$__loc__" */ -#line 796 "src/parser.y" +#line 767 "src/parser.y" { (yyval.blk) = gen_loc_object(&(yyloc), locations); } -#line 3637 "src/parser.c" +#line 3608 "src/parser.c" break; case 111: /* 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) @@ -3650,198 +3621,198 @@ YYLTYPE yylloc = yyloc_default; (yyval.blk) = gen_location((yyloc), locations, gen_call(s, gen_noop())); jv_free((yyvsp[0].literal)); } -#line 3654 "src/parser.c" +#line 3625 "src/parser.c" break; case 112: /* 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 3664 "src/parser.c" +#line 3635 "src/parser.c" break; case 113: /* Term: '(' error ')' */ -#line 816 "src/parser.y" +#line 787 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3670 "src/parser.c" +#line 3641 "src/parser.c" break; case 114: /* Term: '[' error ']' */ -#line 817 "src/parser.y" +#line 788 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3676 "src/parser.c" +#line 3647 "src/parser.c" break; case 115: /* Term: Term '[' error ']' */ -#line 818 "src/parser.y" +#line 789 "src/parser.y" { (yyval.blk) = (yyvsp[-3].blk); } -#line 3682 "src/parser.c" +#line 3653 "src/parser.c" break; case 116: /* Term: '{' error '}' */ -#line 819 "src/parser.y" +#line 790 "src/parser.y" { (yyval.blk) = gen_noop(); } -#line 3688 "src/parser.c" +#line 3659 "src/parser.c" break; case 117: /* Args: Arg */ -#line 822 "src/parser.y" +#line 793 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3696 "src/parser.c" +#line 3667 "src/parser.c" break; case 118: /* Args: Args ';' Arg */ -#line 825 "src/parser.y" +#line 796 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3704 "src/parser.c" +#line 3675 "src/parser.c" break; case 119: /* Arg: Exp */ -#line 830 "src/parser.y" +#line 801 "src/parser.y" { (yyval.blk) = gen_lambda((yyvsp[0].blk)); } -#line 3712 "src/parser.c" +#line 3683 "src/parser.c" break; case 120: /* 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 3720 "src/parser.c" +#line 3691 "src/parser.c" break; case 121: /* RepPatterns: Pattern */ -#line 838 "src/parser.y" +#line 809 "src/parser.y" { (yyval.blk) = gen_destructure_alt((yyvsp[0].blk)); } -#line 3728 "src/parser.c" +#line 3699 "src/parser.c" break; case 122: /* Patterns: RepPatterns "?//" Pattern */ -#line 843 "src/parser.y" +#line 814 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3736 "src/parser.c" +#line 3707 "src/parser.c" break; case 123: /* Patterns: Pattern */ -#line 846 "src/parser.y" +#line 817 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3744 "src/parser.c" +#line 3715 "src/parser.c" break; case 124: /* 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 3753 "src/parser.c" +#line 3724 "src/parser.c" break; case 125: /* Pattern: '[' ArrayPats ']' */ -#line 855 "src/parser.y" +#line 826 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-1].blk), gen_op_simple(POP)); } -#line 3761 "src/parser.c" +#line 3732 "src/parser.c" break; case 126: /* Pattern: '{' ObjPats '}' */ -#line 858 "src/parser.y" +#line 829 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-1].blk), gen_op_simple(POP)); } -#line 3769 "src/parser.c" +#line 3740 "src/parser.c" break; case 127: /* ArrayPats: Pattern */ -#line 863 "src/parser.y" +#line 834 "src/parser.y" { (yyval.blk) = gen_array_matcher(gen_noop(), (yyvsp[0].blk)); } -#line 3777 "src/parser.c" +#line 3748 "src/parser.c" break; case 128: /* 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 3785 "src/parser.c" +#line 3756 "src/parser.c" break; case 129: /* ObjPats: ObjPat */ -#line 871 "src/parser.y" +#line 842 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 3793 "src/parser.c" +#line 3764 "src/parser.c" break; case 130: /* ObjPats: ObjPats ',' ObjPat */ -#line 874 "src/parser.y" +#line 845 "src/parser.y" { (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 3801 "src/parser.c" +#line 3772 "src/parser.c" break; case 131: /* 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 3809 "src/parser.c" +#line 3780 "src/parser.c" break; case 132: /* 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 3817 "src/parser.c" +#line 3788 "src/parser.c" break; case 133: /* 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 3825 "src/parser.c" +#line 3796 "src/parser.c" break; case 134: /* 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 3833 "src/parser.c" +#line 3804 "src/parser.c" break; case 135: /* 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 3841 "src/parser.c" +#line 3812 "src/parser.c" break; case 136: /* 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)) { @@ -3850,269 +3821,269 @@ YYLTYPE yylloc = yyloc_default; jv_free(msg); (yyval.blk) = gen_object_matcher((yyvsp[-3].blk), (yyvsp[0].blk)); } -#line 3854 "src/parser.c" +#line 3825 "src/parser.c" break; case 137: /* 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 3863 "src/parser.c" +#line 3834 "src/parser.c" break; case 138: /* Keyword: "as" */ -#line 908 "src/parser.y" +#line 879 "src/parser.y" { (yyval.literal) = jv_string("as"); } -#line 3871 "src/parser.c" +#line 3842 "src/parser.c" break; case 139: /* Keyword: "def" */ -#line 911 "src/parser.y" +#line 882 "src/parser.y" { (yyval.literal) = jv_string("def"); } -#line 3879 "src/parser.c" +#line 3850 "src/parser.c" break; case 140: /* Keyword: "module" */ -#line 914 "src/parser.y" +#line 885 "src/parser.y" { (yyval.literal) = jv_string("module"); } -#line 3887 "src/parser.c" +#line 3858 "src/parser.c" break; case 141: /* Keyword: "import" */ -#line 917 "src/parser.y" +#line 888 "src/parser.y" { (yyval.literal) = jv_string("import"); } -#line 3895 "src/parser.c" +#line 3866 "src/parser.c" break; case 142: /* Keyword: "include" */ -#line 920 "src/parser.y" +#line 891 "src/parser.y" { (yyval.literal) = jv_string("include"); } -#line 3903 "src/parser.c" +#line 3874 "src/parser.c" break; case 143: /* Keyword: "if" */ -#line 923 "src/parser.y" +#line 894 "src/parser.y" { (yyval.literal) = jv_string("if"); } -#line 3911 "src/parser.c" +#line 3882 "src/parser.c" break; case 144: /* Keyword: "then" */ -#line 926 "src/parser.y" +#line 897 "src/parser.y" { (yyval.literal) = jv_string("then"); } -#line 3919 "src/parser.c" +#line 3890 "src/parser.c" break; case 145: /* Keyword: "else" */ -#line 929 "src/parser.y" +#line 900 "src/parser.y" { (yyval.literal) = jv_string("else"); } -#line 3927 "src/parser.c" +#line 3898 "src/parser.c" break; case 146: /* Keyword: "elif" */ -#line 932 "src/parser.y" +#line 903 "src/parser.y" { (yyval.literal) = jv_string("elif"); } -#line 3935 "src/parser.c" +#line 3906 "src/parser.c" break; case 147: /* Keyword: "reduce" */ -#line 935 "src/parser.y" +#line 906 "src/parser.y" { (yyval.literal) = jv_string("reduce"); } -#line 3943 "src/parser.c" +#line 3914 "src/parser.c" break; case 148: /* Keyword: "foreach" */ -#line 938 "src/parser.y" +#line 909 "src/parser.y" { (yyval.literal) = jv_string("foreach"); } -#line 3951 "src/parser.c" +#line 3922 "src/parser.c" break; case 149: /* Keyword: "end" */ -#line 941 "src/parser.y" +#line 912 "src/parser.y" { (yyval.literal) = jv_string("end"); } -#line 3959 "src/parser.c" +#line 3930 "src/parser.c" break; case 150: /* Keyword: "and" */ -#line 944 "src/parser.y" +#line 915 "src/parser.y" { (yyval.literal) = jv_string("and"); } -#line 3967 "src/parser.c" +#line 3938 "src/parser.c" break; case 151: /* Keyword: "or" */ -#line 947 "src/parser.y" +#line 918 "src/parser.y" { (yyval.literal) = jv_string("or"); } -#line 3975 "src/parser.c" +#line 3946 "src/parser.c" break; case 152: /* Keyword: "try" */ -#line 950 "src/parser.y" +#line 921 "src/parser.y" { (yyval.literal) = jv_string("try"); } -#line 3983 "src/parser.c" +#line 3954 "src/parser.c" break; case 153: /* Keyword: "catch" */ -#line 953 "src/parser.y" +#line 924 "src/parser.y" { (yyval.literal) = jv_string("catch"); } -#line 3991 "src/parser.c" +#line 3962 "src/parser.c" break; case 154: /* Keyword: "label" */ -#line 956 "src/parser.y" +#line 927 "src/parser.y" { (yyval.literal) = jv_string("label"); } -#line 3999 "src/parser.c" +#line 3970 "src/parser.c" break; case 155: /* Keyword: "break" */ -#line 959 "src/parser.y" +#line 930 "src/parser.y" { (yyval.literal) = jv_string("break"); } -#line 4007 "src/parser.c" +#line 3978 "src/parser.c" break; case 156: /* MkDict: %empty */ -#line 964 "src/parser.y" +#line 935 "src/parser.y" { (yyval.blk)=gen_noop(); } -#line 4015 "src/parser.c" +#line 3986 "src/parser.c" break; case 157: /* MkDict: MkDictPair */ -#line 967 "src/parser.y" +#line 938 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 4021 "src/parser.c" +#line 3992 "src/parser.c" break; case 158: /* MkDict: MkDictPair ',' MkDict */ -#line 968 "src/parser.y" +#line 939 "src/parser.y" { (yyval.blk)=block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 4027 "src/parser.c" +#line 3998 "src/parser.c" break; case 159: /* MkDict: error ',' MkDict */ -#line 969 "src/parser.y" +#line 940 "src/parser.y" { (yyval.blk) = (yyvsp[0].blk); } -#line 4033 "src/parser.c" +#line 4004 "src/parser.c" break; case 160: /* 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 4041 "src/parser.c" +#line 4012 "src/parser.c" break; case 161: /* 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 4049 "src/parser.c" +#line 4020 "src/parser.c" break; case 162: /* MkDictPair: String ':' ExpD */ -#line 978 "src/parser.y" +#line 949 "src/parser.y" { (yyval.blk) = gen_dictpair((yyvsp[-2].blk), (yyvsp[0].blk)); } -#line 4057 "src/parser.c" +#line 4028 "src/parser.c" break; case 163: /* 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 4066 "src/parser.c" +#line 4037 "src/parser.c" break; case 164: /* 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 4076 "src/parser.c" +#line 4047 "src/parser.c" break; case 165: /* 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 4085 "src/parser.c" +#line 4056 "src/parser.c" break; case 166: /* 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 4094 "src/parser.c" +#line 4065 "src/parser.c" break; case 167: /* 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 4103 "src/parser.c" +#line 4074 "src/parser.c" break; case 168: /* 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 4112 "src/parser.c" +#line 4083 "src/parser.c" break; case 169: /* 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)) { @@ -4121,20 +4092,20 @@ YYLTYPE yylloc = yyloc_default; jv_free(msg); (yyval.blk) = gen_dictpair((yyvsp[-3].blk), (yyvsp[0].blk)); } -#line 4125 "src/parser.c" +#line 4096 "src/parser.c" break; case 170: /* 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 4134 "src/parser.c" +#line 4105 "src/parser.c" break; -#line 4138 "src/parser.c" +#line 4109 "src/parser.c" default: break; } @@ -4363,7 +4334,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 94ede7c4ab..8c4ad347e5 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); }