From a80dd502456a469772be263a84f06f71251923a4 Mon Sep 17 00:00:00 2001 From: Tomas Halman Date: Mon, 16 Oct 2023 11:34:51 +0200 Subject: [PATCH] Make jq 1.6 fast Resolves: RHEL-5052 --- 0004-make-jq-fast.patch | 4562 +++++++++++++++++++++++++++++++++++++++ jq.spec | 7 +- 2 files changed, 4568 insertions(+), 1 deletion(-) create mode 100644 0004-make-jq-fast.patch diff --git a/0004-make-jq-fast.patch b/0004-make-jq-fast.patch new file mode 100644 index 0000000..196d08a --- /dev/null +++ b/0004-make-jq-fast.patch @@ -0,0 +1,4562 @@ +commit 8edf58a95fdebfba7b6a614..e843a4fdf9f6f446f5ddeb +Author: Muh Muhten + + Set of patches to improve jq performance + +diff -up jq-1.6/src/builtin.c.orig jq-1.6/src/builtin.c +--- jq-1.6/src/builtin.c.orig 2023-10-13 13:36:10.297515083 +0200 ++++ jq-1.6/src/builtin.c 2023-10-13 13:36:36.108510379 +0200 +@@ -1720,12 +1720,10 @@ static block bind_bytecoded_builtins(blo + BLOCK(gen_param("start"), gen_param("end")), + range)); + } +- return block_bind(builtins, b, OP_IS_CALL_PSEUDO); ++ return BLOCK(builtins, b); + } + +- +- +-static const char* const jq_builtins = ++static const char jq_builtins[] = + /* Include jq-coded builtins */ + #include "src/builtin.inc" + +@@ -1761,46 +1759,18 @@ static block gen_builtin_list(block buil + return BLOCK(builtins, gen_function("builtins", gen_noop(), gen_const(list))); + } + +-static int builtins_bind_one(jq_state *jq, block* bb, const char* code) { +- struct locfile* src; +- src = locfile_init(jq, "", code, strlen(code)); +- block funcs; +- int nerrors = jq_parse_library(src, &funcs); +- if (nerrors == 0) { +- *bb = block_bind(funcs, *bb, OP_IS_CALL_PSEUDO); +- } +- locfile_free(src); +- return nerrors; +-} +- +-static int slurp_lib(jq_state *jq, block* bb) { +- int nerrors = 0; +- char* home = getenv("HOME"); +- if (home) { // silently ignore no $HOME +- jv filename = jv_string_append_str(jv_string(home), "/.jq"); +- jv data = jv_load_file(jv_string_value(filename), 1); +- if (jv_is_valid(data)) { +- nerrors = builtins_bind_one(jq, bb, jv_string_value(data) ); +- } +- jv_free(filename); +- jv_free(data); +- } +- return nerrors; +-} +- + int builtins_bind(jq_state *jq, block* bb) { +- block builtins = gen_noop(); +- int nerrors = slurp_lib(jq, bb); +- if (nerrors) { +- block_free(*bb); +- return nerrors; +- } +- nerrors = builtins_bind_one(jq, &builtins, jq_builtins); ++ block builtins; ++ struct locfile* src = locfile_init(jq, "", jq_builtins, sizeof(jq_builtins)-1); ++ int nerrors = jq_parse_library(src, &builtins); + assert(!nerrors); ++ locfile_free(src); ++ + builtins = bind_bytecoded_builtins(builtins); + builtins = gen_cbinding(function_list, sizeof(function_list)/sizeof(function_list[0]), builtins); + builtins = gen_builtin_list(builtins); +- *bb = block_bind(builtins, *bb, OP_IS_CALL_PSEUDO); ++ ++ *bb = block_bind_incremental(builtins, *bb, OP_IS_CALL_PSEUDO); + *bb = block_drop_unreferenced(*bb); + return nerrors; + } +diff -up jq-1.6/src/compile.c.orig jq-1.6/src/compile.c +--- jq-1.6/src/compile.c.orig 2018-11-02 02:49:29.000000000 +0100 ++++ jq-1.6/src/compile.c 2023-10-13 13:43:27.534415849 +0200 +@@ -216,8 +216,9 @@ block gen_op_unbound(opcode op, const ch + + block gen_op_var_fresh(opcode op, const char* name) { + assert(opcode_describe(op)->flags & OP_HAS_VARIABLE); +- return block_bind(gen_op_unbound(op, name), +- gen_noop(), OP_HAS_VARIABLE); ++ block b = gen_op_unbound(op, name); ++ b.first->bound_by = b.first; ++ return b; + } + + block gen_op_bound(opcode op, block binder) { +@@ -375,7 +376,7 @@ static int block_bind_each(block binder, + return nrefs; + } + +-block block_bind(block binder, block body, int bindflags) { ++static block block_bind(block binder, block body, int bindflags) { + block_bind_each(binder, body, bindflags); + return block_join(binder, body); + } +@@ -413,6 +414,48 @@ block block_bind_library(block binder, b + return body; // We don't return a join because we don't want those sticking around... + } + ++static inst* block_take_last(block* b) { ++ inst* i = b->last; ++ if (i == 0) ++ return 0; ++ if (i->prev) { ++ i->prev->next = i->next; ++ b->last = i->prev; ++ i->prev = 0; ++ } else { ++ b->first = 0; ++ b->last = 0; ++ } ++ return i; ++} ++ ++// Binds a sequence of binders, which *must not* alrady be bound to each other, ++// to body, throwing away unreferenced defs ++block block_bind_incremental(block binder, block body, int bindflags) { ++ assert(block_has_only_binders(binder, bindflags)); ++ bindflags |= OP_HAS_BINDING; ++ ++ inst* curr; ++ while ((curr = block_take_last(&binder))) { ++ body = block_bind_referenced(inst_block(curr), body, bindflags); ++ } ++ return body; ++} ++ ++block block_bind_self(block binder, int bindflags) { ++ assert(block_has_only_binders(binder, bindflags)); ++ bindflags |= OP_HAS_BINDING; ++ block body = gen_noop(); ++ ++ inst* curr; ++ while ((curr = block_take_last(&binder))) { ++ block b = inst_block(curr); ++ block_bind_subblock(b, body, bindflags, 0); ++ body = BLOCK(b, body); ++ } ++ return body; ++} ++ + // Bind binder to body and throw away any defs in binder not referenced + // (directly or indirectly) from body. + block block_bind_referenced(block binder, block body, int bindflags) { +@@ -475,10 +518,10 @@ block block_drop_unreferenced(block body + jv block_take_imports(block* body) { + jv imports = jv_array(); + +- inst* top = NULL; +- if (body->first && body->first->op == TOP) { +- top = block_take(body); +- } ++ /* Parser should never generate TOP before imports */ ++ assert(!(body->first && body->first->op == TOP && body->first->next && ++ (body->first->next->op == MODULEMETA || body->first->next->op == DEPS))); ++ + while (body->first && (body->first->op == MODULEMETA || body->first->op == DEPS)) { + inst* dep = block_take(body); + if (dep->op == DEPS) { +@@ -486,9 +529,6 @@ jv block_take_imports(block* body) { + } + inst_free(dep); + } +- if (top) { +- *body = block_join(inst_block(top),*body); +- } + return imports; + } + +@@ -1081,7 +1121,7 @@ block gen_cbinding(const struct cfunctio + inst* i = inst_new(CLOSURE_CREATE_C); + i->imm.cfunc = &cfunctions[cfunc]; + i->symbol = strdup(i->imm.cfunc->name); +- code = block_bind(inst_block(i), code, OP_IS_CALL_PSEUDO); ++ code = BLOCK(inst_block(i), code); + } + return code; + } +diff -up jq-1.6/src/compile.h.orig jq-1.6/src/compile.h +--- jq-1.6/src/compile.h.orig 2018-11-02 02:49:29.000000000 +0100 ++++ jq-1.6/src/compile.h 2023-10-13 13:36:36.109510379 +0200 +@@ -72,9 +72,10 @@ int block_has_only_binders(block, int bi + int block_has_main(block); + int block_is_funcdef(block b); + int block_is_single(block b); +-block block_bind(block binder, block body, int bindflags); + block block_bind_library(block binder, block body, int bindflags, const char* libname); + block block_bind_referenced(block binder, block body, int bindflags); ++block block_bind_incremental(block binder, block body, int bindflags); ++block block_bind_self(block binder, int bindflags); + block block_drop_unreferenced(block body); + + jv block_take_imports(block* body); +diff -up jq-1.6/src/linker.c.orig jq-1.6/src/linker.c +--- jq-1.6/src/linker.c.orig 2018-11-02 02:49:29.000000000 +0100 ++++ jq-1.6/src/linker.c 2023-10-13 13:36:36.109510379 +0200 +@@ -98,12 +98,9 @@ static jv validate_relpath(jv name) { + return res; + } + jv components = jv_string_split(jv_copy(name), jv_string("/")); +- jv rp = jv_array_get(jv_copy(components), 0); +- components = jv_array_slice(components, 1, jv_array_length(jv_copy(components))); + jv_array_foreach(components, i, x) { + if (!strcmp(jv_string_value(x), "..")) { + jv_free(x); +- jv_free(rp); + jv_free(components); + jv res = jv_invalid_with_msg(jv_string_fmt("Relative paths to modules may not traverse to parent directories (%s)", s)); + jv_free(name); +@@ -111,18 +108,16 @@ static jv validate_relpath(jv name) { + } + if (i > 0 && jv_equal(jv_copy(x), jv_array_get(jv_copy(components), i - 1))) { + jv_free(x); +- jv_free(rp); + jv_free(components); + jv res = jv_invalid_with_msg(jv_string_fmt("module names must not have equal consecutive components: %s", + jv_string_value(name))); + jv_free(name); + return res; + } +- rp = jv_string_concat(rp, jv_string_concat(jv_string("/"), x)); ++ jv_free(x); + } + jv_free(components); +- jv_free(name); +- return rp; ++ return name; + } + + // Assumes name has been validated +@@ -138,10 +133,20 @@ static jv jv_basename(jv name) { + + // Asummes validated relative path to module + static jv find_lib(jq_state *jq, jv rel_path, jv search, const char *suffix, jv jq_origin, jv lib_origin) { +- if (jv_get_kind(search) != JV_KIND_ARRAY) +- return jv_invalid_with_msg(jv_string_fmt("Module search path must be an array")); +- if (jv_get_kind(rel_path) != JV_KIND_STRING) ++ if (!jv_is_valid(rel_path)) { ++ jv_free(search); ++ return rel_path; ++ } ++ if (jv_get_kind(rel_path) != JV_KIND_STRING) { ++ jv_free(rel_path); ++ jv_free(search); + return jv_invalid_with_msg(jv_string_fmt("Module path must be a string")); ++ } ++ if (jv_get_kind(search) != JV_KIND_ARRAY) { ++ jv_free(rel_path); ++ jv_free(search); ++ return jv_invalid_with_msg(jv_string_fmt("Module search path must be an array")); ++ } + + struct stat st; + int ret; +@@ -241,6 +246,9 @@ static int process_dependencies(jq_state + jv v = jv_object_get(jv_copy(dep), jv_string("raw")); + if (jv_get_kind(v) == JV_KIND_TRUE) + raw = 1; ++ int optional = 0; ++ if (jv_get_kind(jv_object_get(jv_copy(dep), jv_string("optional"))) == JV_KIND_TRUE) ++ optional = 1; + jv_free(v); + jv relpath = validate_relpath(jv_object_get(jv_copy(dep), jv_string("relpath"))); + jv as = jv_object_get(jv_copy(dep), jv_string("as")); +@@ -254,10 +262,14 @@ static int process_dependencies(jq_state + jv resolved = find_lib(jq, relpath, search, is_data ? ".json" : ".jq", jv_copy(jq_origin), jv_copy(lib_origin)); + // XXX ...move the rest of this into a callback. + if (!jv_is_valid(resolved)) { ++ jv_free(as); ++ if (optional) { ++ jv_free(resolved); ++ continue; ++ } + jv emsg = jv_invalid_get_msg(resolved); + jq_report_error(jq, jv_string_fmt("jq: error: %s\n",jv_string_value(emsg))); + jv_free(emsg); +- jv_free(as); + jv_free(deps); + jv_free(jq_origin); + jv_free(lib_origin); +@@ -324,6 +336,7 @@ static int load_library(jq_state *jq, jv + jv_string(dirname(lib_origin)), + &program, lib_state); + free(lib_origin); ++ program = block_bind_self(program, OP_IS_CALL_PSEUDO); + } + } + state_idx = lib_state->ct++; +@@ -375,6 +388,16 @@ int load_program(jq_state *jq, struct lo + if (nerrors) + return nerrors; + ++ char* home = getenv("HOME"); ++ if (home) { // silently ignore no $HOME ++ /* Import ~/.jq as a library named "" found in $HOME */ ++ block import = gen_import_meta(gen_import("", NULL, 0), ++ gen_const(JV_OBJECT( ++ jv_string("optional"), jv_true(), ++ jv_string("search"), jv_string(home)))); ++ program = BLOCK(import, program); ++ } ++ + nerrors = process_dependencies(jq, jq_get_jq_origin(jq), jq_get_prog_origin(jq), &program, &lib_state); + block libs = gen_noop(); + for (uint64_t i = 0; i < lib_state.ct; ++i) { +diff -up jq-1.6/src/parser.c.orig jq-1.6/src/parser.c +--- jq-1.6/src/parser.c.orig 2023-10-13 13:36:10.305515082 +0200 ++++ jq-1.6/src/parser.c 2023-10-13 13:45:07.846387953 +0200 +@@ -1,8 +1,8 @@ +-/* A Bison parser, made by GNU Bison 3.3.2. */ ++/* A Bison parser, made by GNU Bison 3.8.2. */ + + /* Bison implementation for Yacc-like parsers in C + +- Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, ++ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify +@@ -16,7 +16,7 @@ + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ ++ along with this program. If not, see . */ + + /* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work +@@ -34,6 +34,10 @@ + /* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + ++/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, ++ especially those whose name start with YY_ or yy_. They are ++ private implementation details that can be changed or removed. */ ++ + /* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. +@@ -41,14 +45,11 @@ + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +-/* Undocumented macros, especially those whose name start with YY_, +- are private implementation details. Do not rely on them. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 ++/* Identify Bison output, and Bison version. */ ++#define YYBISON 30802 + +-/* Bison version. */ +-#define YYBISON_VERSION "3.3.2" ++/* Bison version string. */ ++#define YYBISON_VERSION "3.8.2" + + /* Skeleton name. */ + #define YYSKELETON_NAME "yacc.c" +@@ -66,7 +67,7 @@ + + + /* First part of user prologue. */ +-#line 1 "src/parser.y" /* yacc.c:337 */ ++#line 1 "src/parser.y" + + #include + #include +@@ -77,7 +78,17 @@ + #define YYMALLOC jv_mem_alloc + #define YYFREE jv_mem_free + +-#line 81 "src/parser.c" /* yacc.c:337 */ ++#line 82 "src/parser.c" ++ ++# ifndef YY_CAST ++# ifdef __cplusplus ++# define YY_CAST(Type, Val) static_cast (Val) ++# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) ++# else ++# define YY_CAST(Type, Val) ((Type) (Val)) ++# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) ++# endif ++# endif + # ifndef YY_NULLPTR + # if defined __cplusplus + # if 201103L <= __cplusplus +@@ -90,16 +101,8 @@ + # endif + # endif + +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 1 +-#endif +- +-/* In a future release of Bison, this section will be replaced +- by #include "y.tab.h". */ ++/* Use api.header.include to #include this header ++ instead of duplicating it here. */ + #ifndef YY_YY_SRC_PARSER_H_INCLUDED + # define YY_YY_SRC_PARSER_H_INCLUDED + /* Debug traces. */ +@@ -110,7 +113,7 @@ + extern int yydebug; + #endif + /* "%code requires" blocks. */ +-#line 11 "src/parser.y" /* yacc.c:352 */ ++#line 11 "src/parser.y" + + #include "locfile.h" + struct lexer_param; +@@ -127,61 +130,70 @@ struct lexer_param; + } \ + } while (0) + +-#line 131 "src/parser.c" /* yacc.c:352 */ ++#line 134 "src/parser.c" + +-/* Token type. */ ++/* Token kinds. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE + enum yytokentype + { +- INVALID_CHARACTER = 258, +- IDENT = 259, +- FIELD = 260, +- LITERAL = 261, +- FORMAT = 262, +- REC = 263, +- SETMOD = 264, +- EQ = 265, +- NEQ = 266, +- DEFINEDOR = 267, +- AS = 268, +- DEF = 269, +- MODULE = 270, +- IMPORT = 271, +- INCLUDE = 272, +- IF = 273, +- THEN = 274, +- ELSE = 275, +- ELSE_IF = 276, +- REDUCE = 277, +- FOREACH = 278, +- END = 279, +- AND = 280, +- OR = 281, +- TRY = 282, +- CATCH = 283, +- LABEL = 284, +- BREAK = 285, +- LOC = 286, +- SETPIPE = 287, +- SETPLUS = 288, +- SETMINUS = 289, +- SETMULT = 290, +- SETDIV = 291, +- SETDEFINEDOR = 292, +- LESSEQ = 293, +- GREATEREQ = 294, +- ALTERNATION = 295, +- QQSTRING_START = 296, +- QQSTRING_TEXT = 297, +- QQSTRING_INTERP_START = 298, +- QQSTRING_INTERP_END = 299, +- QQSTRING_END = 300, +- FUNCDEF = 301, +- NONOPT = 302 ++ YYEMPTY = -2, ++ YYEOF = 0, /* "end of file" */ ++ YYerror = 256, /* error */ ++ YYUNDEF = 257, /* "invalid token" */ ++ INVALID_CHARACTER = 258, /* INVALID_CHARACTER */ ++ IDENT = 259, /* IDENT */ ++ FIELD = 260, /* FIELD */ ++ LITERAL = 261, /* LITERAL */ ++ FORMAT = 262, /* FORMAT */ ++ REC = 263, /* ".." */ ++ SETMOD = 264, /* "%=" */ ++ EQ = 265, /* "==" */ ++ NEQ = 266, /* "!=" */ ++ DEFINEDOR = 267, /* "//" */ ++ AS = 268, /* "as" */ ++ DEF = 269, /* "def" */ ++ MODULE = 270, /* "module" */ ++ IMPORT = 271, /* "import" */ ++ INCLUDE = 272, /* "include" */ ++ IF = 273, /* "if" */ ++ THEN = 274, /* "then" */ ++ ELSE = 275, /* "else" */ ++ ELSE_IF = 276, /* "elif" */ ++ REDUCE = 277, /* "reduce" */ ++ FOREACH = 278, /* "foreach" */ ++ END = 279, /* "end" */ ++ AND = 280, /* "and" */ ++ OR = 281, /* "or" */ ++ TRY = 282, /* "try" */ ++ CATCH = 283, /* "catch" */ ++ LABEL = 284, /* "label" */ ++ BREAK = 285, /* "break" */ ++ LOC = 286, /* "__loc__" */ ++ SETPIPE = 287, /* "|=" */ ++ SETPLUS = 288, /* "+=" */ ++ SETMINUS = 289, /* "-=" */ ++ SETMULT = 290, /* "*=" */ ++ SETDIV = 291, /* "/=" */ ++ SETDEFINEDOR = 292, /* "//=" */ ++ LESSEQ = 293, /* "<=" */ ++ GREATEREQ = 294, /* ">=" */ ++ ALTERNATION = 295, /* "?//" */ ++ QQSTRING_START = 296, /* QQSTRING_START */ ++ QQSTRING_TEXT = 297, /* QQSTRING_TEXT */ ++ QQSTRING_INTERP_START = 298, /* QQSTRING_INTERP_START */ ++ QQSTRING_INTERP_END = 299, /* QQSTRING_INTERP_END */ ++ QQSTRING_END = 300, /* QQSTRING_END */ ++ FUNCDEF = 301, /* FUNCDEF */ ++ NONOPT = 302 /* NONOPT */ + }; ++ typedef enum yytokentype yytoken_kind_t; + #endif +-/* Tokens. */ ++/* Token kinds. */ ++#define YYEMPTY -2 ++#define YYEOF 0 ++#define YYerror 256 ++#define YYUNDEF 257 + #define INVALID_CHARACTER 258 + #define IDENT 259 + #define FIELD 260 +@@ -230,17 +242,16 @@ struct lexer_param; + + /* Value type. */ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +- + union YYSTYPE + { +-#line 31 "src/parser.y" /* yacc.c:352 */ ++#line 31 "src/parser.y" + + jv literal; + block blk; + +-#line 242 "src/parser.c" /* yacc.c:352 */ +-}; ++#line 253 "src/parser.c" + ++}; + typedef union YYSTYPE YYSTYPE; + # define YYSTYPE_IS_TRIVIAL 1 + # define YYSTYPE_IS_DECLARED 1 +@@ -262,12 +273,120 @@ struct YYLTYPE + + + ++ + int yyparse (block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr); + ++ + #endif /* !YY_YY_SRC_PARSER_H_INCLUDED */ ++/* Symbol kind. */ ++enum yysymbol_kind_t ++{ ++ YYSYMBOL_YYEMPTY = -2, ++ YYSYMBOL_YYEOF = 0, /* "end of file" */ ++ YYSYMBOL_YYerror = 1, /* error */ ++ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ ++ YYSYMBOL_INVALID_CHARACTER = 3, /* INVALID_CHARACTER */ ++ YYSYMBOL_IDENT = 4, /* IDENT */ ++ YYSYMBOL_FIELD = 5, /* FIELD */ ++ YYSYMBOL_LITERAL = 6, /* LITERAL */ ++ YYSYMBOL_FORMAT = 7, /* FORMAT */ ++ YYSYMBOL_REC = 8, /* ".." */ ++ YYSYMBOL_SETMOD = 9, /* "%=" */ ++ YYSYMBOL_EQ = 10, /* "==" */ ++ YYSYMBOL_NEQ = 11, /* "!=" */ ++ YYSYMBOL_DEFINEDOR = 12, /* "//" */ ++ YYSYMBOL_AS = 13, /* "as" */ ++ YYSYMBOL_DEF = 14, /* "def" */ ++ YYSYMBOL_MODULE = 15, /* "module" */ ++ YYSYMBOL_IMPORT = 16, /* "import" */ ++ YYSYMBOL_INCLUDE = 17, /* "include" */ ++ YYSYMBOL_IF = 18, /* "if" */ ++ YYSYMBOL_THEN = 19, /* "then" */ ++ YYSYMBOL_ELSE = 20, /* "else" */ ++ YYSYMBOL_ELSE_IF = 21, /* "elif" */ ++ YYSYMBOL_REDUCE = 22, /* "reduce" */ ++ YYSYMBOL_FOREACH = 23, /* "foreach" */ ++ YYSYMBOL_END = 24, /* "end" */ ++ YYSYMBOL_AND = 25, /* "and" */ ++ YYSYMBOL_OR = 26, /* "or" */ ++ YYSYMBOL_TRY = 27, /* "try" */ ++ YYSYMBOL_CATCH = 28, /* "catch" */ ++ YYSYMBOL_LABEL = 29, /* "label" */ ++ YYSYMBOL_BREAK = 30, /* "break" */ ++ YYSYMBOL_LOC = 31, /* "__loc__" */ ++ YYSYMBOL_SETPIPE = 32, /* "|=" */ ++ YYSYMBOL_SETPLUS = 33, /* "+=" */ ++ YYSYMBOL_SETMINUS = 34, /* "-=" */ ++ YYSYMBOL_SETMULT = 35, /* "*=" */ ++ YYSYMBOL_SETDIV = 36, /* "/=" */ ++ YYSYMBOL_SETDEFINEDOR = 37, /* "//=" */ ++ YYSYMBOL_LESSEQ = 38, /* "<=" */ ++ YYSYMBOL_GREATEREQ = 39, /* ">=" */ ++ YYSYMBOL_ALTERNATION = 40, /* "?//" */ ++ YYSYMBOL_QQSTRING_START = 41, /* QQSTRING_START */ ++ YYSYMBOL_QQSTRING_TEXT = 42, /* QQSTRING_TEXT */ ++ YYSYMBOL_QQSTRING_INTERP_START = 43, /* QQSTRING_INTERP_START */ ++ YYSYMBOL_QQSTRING_INTERP_END = 44, /* QQSTRING_INTERP_END */ ++ YYSYMBOL_QQSTRING_END = 45, /* QQSTRING_END */ ++ YYSYMBOL_FUNCDEF = 46, /* FUNCDEF */ ++ YYSYMBOL_47_ = 47, /* '|' */ ++ YYSYMBOL_48_ = 48, /* ',' */ ++ YYSYMBOL_49_ = 49, /* '=' */ ++ YYSYMBOL_50_ = 50, /* '<' */ ++ YYSYMBOL_51_ = 51, /* '>' */ ++ YYSYMBOL_52_ = 52, /* '+' */ ++ YYSYMBOL_53_ = 53, /* '-' */ ++ YYSYMBOL_54_ = 54, /* '*' */ ++ YYSYMBOL_55_ = 55, /* '/' */ ++ YYSYMBOL_56_ = 56, /* '%' */ ++ YYSYMBOL_NONOPT = 57, /* NONOPT */ ++ YYSYMBOL_58_ = 58, /* '?' */ ++ YYSYMBOL_59_ = 59, /* ';' */ ++ YYSYMBOL_60_ = 60, /* '(' */ ++ YYSYMBOL_61_ = 61, /* ')' */ ++ YYSYMBOL_62_ = 62, /* '$' */ ++ YYSYMBOL_63_ = 63, /* ':' */ ++ YYSYMBOL_64_ = 64, /* '.' */ ++ YYSYMBOL_65_ = 65, /* '[' */ ++ YYSYMBOL_66_ = 66, /* ']' */ ++ YYSYMBOL_67_ = 67, /* '{' */ ++ YYSYMBOL_68_ = 68, /* '}' */ ++ YYSYMBOL_YYACCEPT = 69, /* $accept */ ++ YYSYMBOL_TopLevel = 70, /* TopLevel */ ++ YYSYMBOL_Module = 71, /* Module */ ++ YYSYMBOL_Imports = 72, /* Imports */ ++ YYSYMBOL_FuncDefs = 73, /* FuncDefs */ ++ YYSYMBOL_Exp = 74, /* Exp */ ++ YYSYMBOL_Import = 75, /* Import */ ++ YYSYMBOL_ImportWhat = 76, /* ImportWhat */ ++ YYSYMBOL_ImportFrom = 77, /* ImportFrom */ ++ YYSYMBOL_FuncDef = 78, /* FuncDef */ ++ YYSYMBOL_Params = 79, /* Params */ ++ YYSYMBOL_Param = 80, /* Param */ ++ YYSYMBOL_String = 81, /* String */ ++ YYSYMBOL_82_1 = 82, /* @1 */ ++ YYSYMBOL_83_2 = 83, /* @2 */ ++ YYSYMBOL_QQString = 84, /* QQString */ ++ YYSYMBOL_ElseBody = 85, /* ElseBody */ ++ YYSYMBOL_ExpD = 86, /* ExpD */ ++ YYSYMBOL_Term = 87, /* Term */ ++ YYSYMBOL_Args = 88, /* Args */ ++ YYSYMBOL_Arg = 89, /* Arg */ ++ YYSYMBOL_RepPatterns = 90, /* RepPatterns */ ++ YYSYMBOL_Patterns = 91, /* Patterns */ ++ YYSYMBOL_Pattern = 92, /* Pattern */ ++ YYSYMBOL_ArrayPats = 93, /* ArrayPats */ ++ YYSYMBOL_ObjPats = 94, /* ObjPats */ ++ YYSYMBOL_ObjPat = 95, /* ObjPat */ ++ YYSYMBOL_Keyword = 96, /* Keyword */ ++ YYSYMBOL_MkDict = 97, /* MkDict */ ++ YYSYMBOL_MkDictPair = 98 /* MkDictPair */ ++}; ++typedef enum yysymbol_kind_t yysymbol_kind_t; ++ + + /* Second part of user prologue. */ +-#line 124 "src/parser.y" /* yacc.c:354 */ ++#line 124 "src/parser.y" + + #include "lexer.h" + struct lexer_param { +@@ -447,34 +566,94 @@ static block gen_update(block object, bl + } + + +-#line 451 "src/parser.c" /* yacc.c:354 */ ++#line 570 "src/parser.c" ++ + + #ifdef short + # undef short + #endif + +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; ++/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure ++ and (if available) are included ++ so that the code can choose integer types of a good width. */ ++ ++#ifndef __PTRDIFF_MAX__ ++# include /* INFRINGES ON USER NAME SPACE */ ++# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ ++# include /* INFRINGES ON USER NAME SPACE */ ++# define YY_STDINT_H ++# endif + #endif + +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; ++/* Narrow types that promote to a signed type and that can represent a ++ signed or unsigned integer of at least N bits. In tables they can ++ save space and decrease cache pressure. Promoting to a signed type ++ helps avoid bugs in integer arithmetic. */ ++ ++#ifdef __INT_LEAST8_MAX__ ++typedef __INT_LEAST8_TYPE__ yytype_int8; ++#elif defined YY_STDINT_H ++typedef int_least8_t yytype_int8; + #else + typedef signed char yytype_int8; + #endif + +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; ++#ifdef __INT_LEAST16_MAX__ ++typedef __INT_LEAST16_TYPE__ yytype_int16; ++#elif defined YY_STDINT_H ++typedef int_least16_t yytype_int16; + #else +-typedef unsigned short yytype_uint16; ++typedef short yytype_int16; ++#endif ++ ++/* Work around bug in HP-UX 11.23, which defines these macros ++ incorrectly for preprocessor constants. This workaround can likely ++ be removed in 2023, as HPE has promised support for HP-UX 11.23 ++ (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of ++ . */ ++#ifdef __hpux ++# undef UINT_LEAST8_MAX ++# undef UINT_LEAST16_MAX ++# define UINT_LEAST8_MAX 255 ++# define UINT_LEAST16_MAX 65535 + #endif + +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; ++#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ ++typedef __UINT_LEAST8_TYPE__ yytype_uint8; ++#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ ++ && UINT_LEAST8_MAX <= INT_MAX) ++typedef uint_least8_t yytype_uint8; ++#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX ++typedef unsigned char yytype_uint8; + #else +-typedef short yytype_int16; ++typedef short yytype_uint8; ++#endif ++ ++#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ ++typedef __UINT_LEAST16_TYPE__ yytype_uint16; ++#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ ++ && UINT_LEAST16_MAX <= INT_MAX) ++typedef uint_least16_t yytype_uint16; ++#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX ++typedef unsigned short yytype_uint16; ++#else ++typedef int yytype_uint16; ++#endif ++ ++#ifndef YYPTRDIFF_T ++# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ ++# define YYPTRDIFF_T __PTRDIFF_TYPE__ ++# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ ++# elif defined PTRDIFF_MAX ++# ifndef ptrdiff_t ++# include /* INFRINGES ON USER NAME SPACE */ ++# endif ++# define YYPTRDIFF_T ptrdiff_t ++# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX ++# else ++# define YYPTRDIFF_T long ++# define YYPTRDIFF_MAXIMUM LONG_MAX ++# endif + #endif + + #ifndef YYSIZE_T +@@ -482,7 +661,7 @@ typedef short yytype_int16; + # define YYSIZE_T __SIZE_TYPE__ + # elif defined size_t + # define YYSIZE_T size_t +-# elif ! defined YYSIZE_T ++# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ + # include /* INFRINGES ON USER NAME SPACE */ + # define YYSIZE_T size_t + # else +@@ -490,7 +669,20 @@ typedef short yytype_int16; + # endif + #endif + +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) ++#define YYSIZE_MAXIMUM \ ++ YY_CAST (YYPTRDIFF_T, \ ++ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ++ ? YYPTRDIFF_MAXIMUM \ ++ : YY_CAST (YYSIZE_T, -1))) ++ ++#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) ++ ++ ++/* Stored state numbers (used for stacks). */ ++typedef yytype_int16 yy_state_t; ++ ++/* State numbers in computations. */ ++typedef int yy_state_fast_t; + + #ifndef YY_ + # if defined YYENABLE_NLS && YYENABLE_NLS +@@ -504,38 +696,43 @@ typedef short yytype_int16; + # endif + #endif + +-#ifndef YY_ATTRIBUTE +-# if (defined __GNUC__ \ +- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ +- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +-# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +-# else +-# define YY_ATTRIBUTE(Spec) /* empty */ +-# endif +-#endif + + #ifndef YY_ATTRIBUTE_PURE +-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) ++# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) ++# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) ++# else ++# define YY_ATTRIBUTE_PURE ++# endif + #endif + + #ifndef YY_ATTRIBUTE_UNUSED +-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) ++# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) ++# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) ++# else ++# define YY_ATTRIBUTE_UNUSED ++# endif + #endif + + /* Suppress unused-variable warnings by "using" E. */ + #if ! defined lint || defined __GNUC__ +-# define YYUSE(E) ((void) (E)) ++# define YY_USE(E) ((void) (E)) + #else +-# define YYUSE(E) /* empty */ ++# define YY_USE(E) /* empty */ + #endif + +-#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ + /* Suppress an incorrect diagnostic about yylval being uninitialized. */ +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ ++#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ ++# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 ++# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ ++ _Pragma ("GCC diagnostic push") \ ++ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") ++# else ++# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ ++ _Pragma ("GCC diagnostic push") \ ++ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ ++# endif ++# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") + #else + # define YY_INITIAL_VALUE(Value) Value +@@ -548,8 +745,22 @@ typedef short yytype_int16; + # define YY_INITIAL_VALUE(Value) /* Nothing. */ + #endif + ++#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ ++# define YY_IGNORE_USELESS_CAST_BEGIN \ ++ _Pragma ("GCC diagnostic push") \ ++ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") ++# define YY_IGNORE_USELESS_CAST_END \ ++ _Pragma ("GCC diagnostic pop") ++#endif ++#ifndef YY_IGNORE_USELESS_CAST_BEGIN ++# define YY_IGNORE_USELESS_CAST_BEGIN ++# define YY_IGNORE_USELESS_CAST_END ++#endif ++ ++ ++#define YY_ASSERT(E) ((void) (0 && (E))) + +-#if ! defined yyoverflow || YYERROR_VERBOSE ++#if 1 + + /* The parser invokes alloca or malloc; define the necessary symbols. */ + +@@ -614,8 +825,7 @@ void free (void *); /* INFRINGES ON USER + # endif + # endif + # endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- ++#endif /* 1 */ + + #if (! defined yyoverflow \ + && (! defined __cplusplus \ +@@ -625,18 +835,19 @@ void free (void *); /* INFRINGES ON USER + /* A type that is properly aligned for any stack member. */ + union yyalloc + { +- yytype_int16 yyss_alloc; ++ yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; + }; + + /* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) ++# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + + /* The size of an array large to enough to hold all stacks, each with + N elements. */ + # define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ ++ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ ++ + YYSIZEOF (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + + # define YYCOPY_NEEDED 1 +@@ -649,11 +860,11 @@ union yyalloc + # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ +- YYSIZE_T yynewbytes; \ ++ YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ ++ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +@@ -665,12 +876,12 @@ union yyalloc + # ifndef YYCOPY + # if defined __GNUC__ && 1 < __GNUC__ + # define YYCOPY(Dst, Src, Count) \ +- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) ++ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) + # else + # define YYCOPY(Dst, Src, Count) \ + do \ + { \ +- YYSIZE_T yyi; \ ++ YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ +@@ -693,17 +904,20 @@ union yyalloc + /* YYNSTATES -- Number of states. */ + #define YYNSTATES 313 + +-#define YYUNDEFTOK 2 ++/* YYMAXUTOK -- Last valid token kind. */ + #define YYMAXUTOK 302 + ++ + /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +-#define YYTRANSLATE(YYX) \ +- ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) ++#define YYTRANSLATE(YYX) \ ++ (0 <= (YYX) && (YYX) <= YYMAXUTOK \ ++ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ ++ : YYSYMBOL_YYUNDEF) + + /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +-static const yytype_uint8 yytranslate[] = ++static const yytype_int8 yytranslate[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +@@ -739,80 +953,78 @@ static const yytype_uint8 yytranslate[] + }; + + #if YYDEBUG +- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +-static const yytype_uint16 yyrline[] = ++/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ ++static const yytype_int16 yyrline[] = + { +- 0, 300, 300, 303, 308, 311, 322, 325, 330, 333, +- 338, 342, 345, 349, 353, 357, 360, 365, 369, 373, +- 378, 385, 389, 393, 397, 401, 405, 409, 413, 417, +- 421, 425, 429, 433, 437, 441, 445, 449, 455, 461, +- 465, 469, 473, 477, 481, 485, 489, 493, 498, 501, +- 518, 527, 534, 542, 553, 558, 564, 567, 572, 577, +- 584, 584, 588, 588, 595, 598, 601, 607, 610, 615, +- 618, 621, 627, 630, 633, 641, 645, 648, 651, 654, +- 657, 660, 663, 666, 669, 673, 679, 682, 685, 688, +- 691, 694, 697, 700, 703, 706, 709, 712, 715, 718, +- 721, 724, 727, 734, 738, 742, 754, 759, 760, 761, +- 762, 765, 768, 773, 778, 781, 786, 789, 794, 798, +- 801, 806, 809, 814, 817, 822, 825, 828, 831, 834, +- 837, 845, 851, 854, 857, 860, 863, 866, 869, 872, +- 875, 878, 881, 884, 887, 890, 893, 896, 899, 902, +- 905, 910, 913, 914, 915, 918, 921, 924, 927, 931, +- 935, 939, 947 ++ 0, 306, 306, 309, 314, 317, 328, 331, 336, 339, ++ 344, 348, 351, 355, 359, 363, 366, 371, 375, 379, ++ 384, 391, 395, 399, 403, 407, 411, 415, 419, 423, ++ 427, 431, 435, 439, 443, 447, 451, 455, 461, 467, ++ 471, 475, 479, 483, 487, 491, 495, 499, 504, 507, ++ 524, 533, 540, 548, 559, 564, 570, 573, 578, 583, ++ 590, 590, 594, 594, 601, 604, 607, 613, 616, 621, ++ 624, 627, 633, 636, 639, 647, 651, 654, 657, 660, ++ 663, 666, 669, 672, 675, 679, 685, 688, 691, 694, ++ 697, 700, 703, 706, 709, 712, 715, 718, 721, 724, ++ 727, 730, 733, 740, 744, 748, 760, 765, 766, 767, ++ 768, 771, 774, 779, 784, 787, 792, 795, 800, 804, ++ 807, 812, 815, 820, 823, 828, 831, 834, 837, 840, ++ 843, 851, 857, 860, 863, 866, 869, 872, 875, 878, ++ 881, 884, 887, 890, 893, 896, 899, 902, 905, 908, ++ 911, 916, 919, 920, 921, 924, 927, 930, 933, 937, ++ 941, 945, 953 + }; + #endif + +-#if YYDEBUG || YYERROR_VERBOSE || 1 ++/** Accessing symbol of state STATE. */ ++#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) ++ ++#if 1 ++/* The user-facing name of the symbol whose (internal) number is ++ YYSYMBOL. No bounds checking. */ ++static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; ++ + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ + static const char *const yytname[] = + { +- "$end", "error", "$undefined", "INVALID_CHARACTER", "IDENT", "FIELD", +- "LITERAL", "FORMAT", "\"..\"", "\"%=\"", "\"==\"", "\"!=\"", "\"//\"", +- "\"as\"", "\"def\"", "\"module\"", "\"import\"", "\"include\"", "\"if\"", +- "\"then\"", "\"else\"", "\"elif\"", "\"reduce\"", "\"foreach\"", +- "\"end\"", "\"and\"", "\"or\"", "\"try\"", "\"catch\"", "\"label\"", +- "\"break\"", "\"__loc__\"", "\"|=\"", "\"+=\"", "\"-=\"", "\"*=\"", +- "\"/=\"", "\"//=\"", "\"<=\"", "\">=\"", "\"?//\"", "QQSTRING_START", +- "QQSTRING_TEXT", "QQSTRING_INTERP_START", "QQSTRING_INTERP_END", +- "QQSTRING_END", "FUNCDEF", "'|'", "','", "'='", "'<'", "'>'", "'+'", +- "'-'", "'*'", "'/'", "'%'", "NONOPT", "'?'", "';'", "'('", "')'", "'$'", +- "':'", "'.'", "'['", "']'", "'{'", "'}'", "$accept", "TopLevel", +- "Module", "Imports", "FuncDefs", "Exp", "Import", "ImportWhat", +- "ImportFrom", "FuncDef", "Params", "Param", "String", "@1", "@2", +- "QQString", "ElseBody", "ExpD", "Term", "Args", "Arg", "RepPatterns", +- "Patterns", "Pattern", "ArrayPats", "ObjPats", "ObjPat", "Keyword", +- "MkDict", "MkDictPair", YY_NULLPTR ++ "\"end of file\"", "error", "\"invalid token\"", "INVALID_CHARACTER", ++ "IDENT", "FIELD", "LITERAL", "FORMAT", "\"..\"", "\"%=\"", "\"==\"", ++ "\"!=\"", "\"//\"", "\"as\"", "\"def\"", "\"module\"", "\"import\"", ++ "\"include\"", "\"if\"", "\"then\"", "\"else\"", "\"elif\"", ++ "\"reduce\"", "\"foreach\"", "\"end\"", "\"and\"", "\"or\"", "\"try\"", ++ "\"catch\"", "\"label\"", "\"break\"", "\"__loc__\"", "\"|=\"", "\"+=\"", ++ "\"-=\"", "\"*=\"", "\"/=\"", "\"//=\"", "\"<=\"", "\">=\"", "\"?//\"", ++ "QQSTRING_START", "QQSTRING_TEXT", "QQSTRING_INTERP_START", ++ "QQSTRING_INTERP_END", "QQSTRING_END", "FUNCDEF", "'|'", "','", "'='", ++ "'<'", "'>'", "'+'", "'-'", "'*'", "'/'", "'%'", "NONOPT", "'?'", "';'", ++ "'('", "')'", "'$'", "':'", "'.'", "'['", "']'", "'{'", "'}'", "$accept", ++ "TopLevel", "Module", "Imports", "FuncDefs", "Exp", "Import", ++ "ImportWhat", "ImportFrom", "FuncDef", "Params", "Param", "String", "@1", ++ "@2", "QQString", "ElseBody", "ExpD", "Term", "Args", "Arg", ++ "RepPatterns", "Patterns", "Pattern", "ArrayPats", "ObjPats", "ObjPat", ++ "Keyword", "MkDict", "MkDictPair", YY_NULLPTR + }; +-#endif + +-# ifdef YYPRINT +-/* YYTOKNUM[NUM] -- (External) token number corresponding to the +- (internal) symbol number NUM (which must be that of a token). */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, +- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, +- 295, 296, 297, 298, 299, 300, 301, 124, 44, 61, +- 60, 62, 43, 45, 42, 47, 37, 302, 63, 59, +- 40, 41, 36, 58, 46, 91, 93, 123, 125 +-}; +-# endif ++static const char * ++yysymbol_name (yysymbol_kind_t yysymbol) ++{ ++ return yytname[yysymbol]; ++} ++#endif + +-#define YYPACT_NINF -158 ++#define YYPACT_NINF (-158) + +-#define yypact_value_is_default(Yystate) \ +- (!!((Yystate) == (-158))) ++#define yypact_value_is_default(Yyn) \ ++ ((Yyn) == YYPACT_NINF) + +-#define YYTABLE_NINF -152 ++#define YYTABLE_NINF (-152) + +-#define yytable_value_is_error(Yytable_value) \ +- (!!((Yytable_value) == (-152))) ++#define yytable_value_is_error(Yyn) \ ++ ((Yyn) == YYTABLE_NINF) + +- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ + static const yytype_int16 yypact[] = + { + 21, 772, 43, 63, -6, 12, -158, 80, -158, 122, +@@ -849,9 +1061,9 @@ static const yytype_int16 yypact[] = + -158, 1256, -158 + }; + +- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +- Performed when YYTABLE does not specify something else to do. Zero +- means the default is an error. */ ++/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. ++ Performed when YYTABLE does not specify something else to do. Zero ++ means the default is an error. */ + static const yytype_uint8 yydefact[] = + { + 4, 0, 0, 6, 105, 81, 96, 98, 73, 0, +@@ -888,7 +1100,7 @@ static const yytype_uint8 yydefact[] = + 14, 0, 13 + }; + +- /* YYPGOTO[NTERM-NUM]. */ ++/* YYPGOTO[NTERM-NUM]. */ + static const yytype_int16 yypgoto[] = + { + -158, -158, -158, 201, 115, -1, -158, -158, 204, -8, +@@ -896,17 +1108,17 @@ static const yytype_int16 yypgoto[] = + 48, -158, 16, -149, -158, -158, -22, -157, -104, -158 + }; + +- /* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int16 yydefgoto[] = ++/* YYDEFGOTO[NTERM-NUM]. */ ++static const yytype_uint8 yydefgoto[] = + { +- -1, 2, 3, 30, 118, 110, 31, 32, 115, 24, ++ 0, 2, 3, 30, 118, 110, 31, 32, 115, 24, + 197, 198, 25, 44, 127, 136, 249, 213, 26, 125, + 126, 181, 182, 183, 222, 228, 229, 81, 82, 83 + }; + +- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule whose +- number is the opposite. If YYTABLE_NINF, syntax error. */ ++/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule whose ++ number is the opposite. If YYTABLE_NINF, syntax error. */ + static const yytype_int16 yytable[] = + { + 23, 4, 5, 6, 7, 8, 42, 38, 39, 37, +@@ -1311,9 +1523,9 @@ static const yytype_int16 yycheck[] = + 56, -1, 58 + }; + +- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = ++/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of ++ state STATE-NUM. */ ++static const yytype_int8 yystos[] = + { + 0, 15, 70, 71, 4, 5, 6, 7, 8, 14, + 18, 22, 23, 27, 29, 30, 41, 53, 60, 62, +@@ -1349,8 +1561,8 @@ static const yytype_uint8 yystos[] = + 61, 74, 61 + }; + +- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = ++/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ ++static const yytype_int8 yyr1[] = + { + 0, 69, 70, 70, 71, 71, 72, 72, 73, 73, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, +@@ -1371,8 +1583,8 @@ static const yytype_uint8 yyr1[] = + 98, 98, 98 + }; + +- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = ++/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ ++static const yytype_int8 yyr2[] = + { + 0, 2, 3, 3, 0, 3, 0, 2, 0, 2, + 2, 5, 9, 11, 9, 5, 4, 4, 2, 4, +@@ -1394,14 +1606,15 @@ static const yytype_uint8 yyr2[] = + }; + + ++enum { YYENOMEM = -2 }; ++ + #define yyerrok (yyerrstatus = 0) + #define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 + + #define YYACCEPT goto yyacceptlab + #define YYABORT goto yyabortlab + #define YYERROR goto yyerrorlab ++#define YYNOMEM goto yyexhaustedlab + + + #define YYRECOVERING() (!!yyerrstatus) +@@ -1423,10 +1636,9 @@ static const yytype_uint8 yyr2[] = + } \ + while (0) + +-/* Error token number */ +-#define YYTERROR 1 +-#define YYERRCODE 256 +- ++/* Backward compatibility with an undocumented macro. ++ Use YYerror or YYUNDEF. */ ++#define YYERRCODE YYUNDEF + + /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends +@@ -1470,12 +1682,19 @@ do { + } while (0) + + +-/* YY_LOCATION_PRINT -- Print the location on the stream. ++/* YYLOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +-#ifndef YY_LOCATION_PRINT +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL ++# ifndef YYLOCATION_PRINT ++ ++# if defined YY_LOCATION_PRINT ++ ++ /* Temporary convenience wrapper in case some people defined the ++ undocumented and private YY_LOCATION_PRINT macros. */ ++# define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) ++ ++# elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL + + /* Print *YYLOCP on YYO. Private, do not rely on its existence. */ + +@@ -1503,24 +1722,32 @@ yy_location_print_ (FILE *yyo, YYLTYPE c + res += YYFPRINTF (yyo, "-%d", end_col); + } + return res; +- } ++} + +-# define YY_LOCATION_PRINT(File, Loc) \ +- yy_location_print_ (File, &(Loc)) ++# define YYLOCATION_PRINT yy_location_print_ + +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-# endif +-#endif ++ /* Temporary convenience wrapper in case some people defined the ++ undocumented and private YY_LOCATION_PRINT macros. */ ++# define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) ++ ++# else ++ ++# define YYLOCATION_PRINT(File, Loc) ((void) 0) ++ /* Temporary convenience wrapper in case some people defined the ++ undocumented and private YY_LOCATION_PRINT macros. */ ++# define YY_LOCATION_PRINT YYLOCATION_PRINT ++ ++# endif ++# endif /* !defined YYLOCATION_PRINT */ + + +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ ++# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ + do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ +- Type, Value, Location, answer, errors, locations, lexer_param_ptr); \ ++ Kind, Value, Location, answer, errors, locations, lexer_param_ptr); \ + YYFPRINTF (stderr, "\n"); \ + } \ + } while (0) +@@ -1531,22 +1758,21 @@ do { + `-----------------------------------*/ + + static void +-yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) ++yy_symbol_value_print (FILE *yyo, ++ yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) + { + FILE *yyoutput = yyo; +- YYUSE (yyoutput); +- YYUSE (yylocationp); +- YYUSE (answer); +- YYUSE (errors); +- YYUSE (locations); +- YYUSE (lexer_param_ptr); ++ YY_USE (yyoutput); ++ YY_USE (yylocationp); ++ YY_USE (answer); ++ YY_USE (errors); ++ YY_USE (locations); ++ YY_USE (lexer_param_ptr); + if (!yyvaluep) + return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +-# endif +- YYUSE (yytype); ++ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN ++ YY_USE (yykind); ++ YY_IGNORE_MAYBE_UNINITIALIZED_END + } + + +@@ -1555,14 +1781,15 @@ yy_symbol_value_print (FILE *yyo, int yy + `---------------------------*/ + + static void +-yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) ++yy_symbol_print (FILE *yyo, ++ yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) + { + YYFPRINTF (yyo, "%s %s (", +- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); ++ yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); + +- YY_LOCATION_PRINT (yyo, *yylocationp); ++ YYLOCATION_PRINT (yyo, yylocationp); + YYFPRINTF (yyo, ": "); +- yy_symbol_value_print (yyo, yytype, yyvaluep, yylocationp, answer, errors, locations, lexer_param_ptr); ++ yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, answer, errors, locations, lexer_param_ptr); + YYFPRINTF (yyo, ")"); + } + +@@ -1572,7 +1799,7 @@ yy_symbol_print (FILE *yyo, int yytype, + `------------------------------------------------------------------*/ + + static void +-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) ++yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) + { + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) +@@ -1595,21 +1822,22 @@ do { + `------------------------------------------------*/ + + static void +-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) ++yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, ++ int yyrule, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) + { +- unsigned long yylno = yyrline[yyrule]; ++ int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", ++ YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, +- yystos[yyssp[yyi + 1 - yynrhs]], +- &yyvsp[(yyi + 1) - (yynrhs)] +- , &(yylsp[(yyi + 1) - (yynrhs)]) , answer, errors, locations, lexer_param_ptr); ++ YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), ++ &yyvsp[(yyi + 1) - (yynrhs)], ++ &(yylsp[(yyi + 1) - (yynrhs)]), answer, errors, locations, lexer_param_ptr); + YYFPRINTF (stderr, "\n"); + } + } +@@ -1624,8 +1852,8 @@ do { + multiple parsers can coexist. */ + int yydebug; + #else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) ++# define YYDPRINTF(Args) ((void) 0) ++# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) + # define YY_STACK_PRINT(Bottom, Top) + # define YY_REDUCE_PRINT(Rule) + #endif /* !YYDEBUG */ +@@ -1648,28 +1876,77 @@ int yydebug; + #endif + + +-#if YYERROR_VERBOSE ++/* Context of a parse error. */ ++typedef struct ++{ ++ yy_state_t *yyssp; ++ yysymbol_kind_t yytoken; ++ YYLTYPE *yylloc; ++} yypcontext_t; ++ ++/* Put in YYARG at most YYARGN of the expected tokens given the ++ current YYCTX, and return the number of tokens stored in YYARG. If ++ YYARG is null, return the number of expected tokens (guaranteed to ++ be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. ++ Return 0 if there are more than YYARGN expected tokens, yet fill ++ YYARG up to YYARGN. */ ++static int ++yypcontext_expected_tokens (const yypcontext_t *yyctx, ++ yysymbol_kind_t yyarg[], int yyargn) ++{ ++ /* Actual size of YYARG. */ ++ int yycount = 0; ++ int yyn = yypact[+*yyctx->yyssp]; ++ if (!yypact_value_is_default (yyn)) ++ { ++ /* Start YYX at -YYN if negative to avoid negative indexes in ++ YYCHECK. In other words, skip the first -YYN actions for ++ this state because they are default actions. */ ++ int yyxbegin = yyn < 0 ? -yyn : 0; ++ /* Stay within bounds of both yycheck and yytname. */ ++ int yychecklim = YYLAST - yyn + 1; ++ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; ++ int yyx; ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror ++ && !yytable_value_is_error (yytable[yyx + yyn])) ++ { ++ if (!yyarg) ++ ++yycount; ++ else if (yycount == yyargn) ++ return 0; ++ else ++ yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); ++ } ++ } ++ if (yyarg && yycount == 0 && 0 < yyargn) ++ yyarg[0] = YYSYMBOL_YYEMPTY; ++ return yycount; ++} ++ + +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else ++ ++ ++#ifndef yystrlen ++# if defined __GLIBC__ && defined _STRING_H ++# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) ++# else + /* Return the length of YYSTR. */ +-static YYSIZE_T ++static YYPTRDIFF_T + yystrlen (const char *yystr) + { +- YYSIZE_T yylen; ++ YYPTRDIFF_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; + } +-# endif + # endif ++#endif + +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else ++#ifndef yystpcpy ++# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE ++# define yystpcpy stpcpy ++# else + /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ + static char * +@@ -1683,10 +1960,10 @@ yystpcpy (char *yydest, const char *yysr + + return yyd - 1; + } +-# endif + # endif ++#endif + +-# ifndef yytnamerr ++#ifndef yytnamerr + /* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string +@@ -1694,14 +1971,13 @@ yystpcpy (char *yydest, const char *yysr + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +-static YYSIZE_T ++static YYPTRDIFF_T + yytnamerr (char *yyres, const char *yystr) + { + if (*yystr == '"') + { +- YYSIZE_T yyn = 0; ++ YYPTRDIFF_T yyn = 0; + char const *yyp = yystr; +- + for (;;) + switch (*++yyp) + { +@@ -1730,36 +2006,20 @@ yytnamerr (char *yyres, const char *yyst + do_not_strip_quotes: ; + } + +- if (! yyres) ++ if (yyres) ++ return yystpcpy (yyres, yystr) - yyres; ++ else + return yystrlen (yystr); +- +- return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); + } +-# endif ++#endif + +-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message +- about the unexpected token YYTOKEN for the state stack whose top is +- YYSSP. + +- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is +- not large enough to hold the message. In that case, also set +- *YYMSG_ALLOC to the required number of bytes. Return 2 if the +- required number of bytes is too large to store. */ + static int +-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, +- yytype_int16 *yyssp, int yytoken) ++yy_syntax_error_arguments (const yypcontext_t *yyctx, ++ yysymbol_kind_t yyarg[], int yyargn) + { +- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); +- YYSIZE_T yysize = yysize0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- /* Internationalized format string. */ +- const char *yyformat = YY_NULLPTR; +- /* Arguments of yyformat. */ +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- /* Number of reported tokens (one for the "unexpected", one per +- "expected"). */ ++ /* Actual size of YYARG. */ + int yycount = 0; +- + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action +@@ -1783,49 +2043,54 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, c + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ +- if (yytoken != YYEMPTY) ++ if (yyctx->yytoken != YYSYMBOL_YYEMPTY) + { +- int yyn = yypact[*yyssp]; +- yyarg[yycount++] = yytname[yytoken]; +- if (!yypact_value_is_default (yyn)) +- { +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. In other words, skip the first -YYN actions for +- this state because they are default actions. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yyx; +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR +- && !yytable_value_is_error (yytable[yyx + yyn])) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- { +- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); +- if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) +- yysize = yysize1; +- else +- return 2; +- } +- } +- } ++ int yyn; ++ if (yyarg) ++ yyarg[yycount] = yyctx->yytoken; ++ ++yycount; ++ yyn = yypcontext_expected_tokens (yyctx, ++ yyarg ? yyarg + 1 : yyarg, yyargn - 1); ++ if (yyn == YYENOMEM) ++ return YYENOMEM; ++ else ++ yycount += yyn; + } ++ return yycount; ++} ++ ++/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message ++ about the unexpected token YYTOKEN for the state stack whose top is ++ YYSSP. ++ ++ Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is ++ not large enough to hold the message. In that case, also set ++ *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the ++ required number of bytes is too large to store. */ ++static int ++yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, ++ const yypcontext_t *yyctx) ++{ ++ enum { YYARGS_MAX = 5 }; ++ /* Internationalized format string. */ ++ const char *yyformat = YY_NULLPTR; ++ /* Arguments of yyformat: reported tokens (one for the "unexpected", ++ one per "expected"). */ ++ yysymbol_kind_t yyarg[YYARGS_MAX]; ++ /* Cumulated lengths of YYARG. */ ++ YYPTRDIFF_T yysize = 0; ++ ++ /* Actual size of YYARG. */ ++ int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); ++ if (yycount == YYENOMEM) ++ return YYENOMEM; + + switch (yycount) + { +-# define YYCASE_(N, S) \ ++#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ +- break ++ break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); +@@ -1833,15 +2098,23 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, c + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +-# undef YYCASE_ ++#undef YYCASE_ + } + ++ /* Compute error message size. Don't count the "%s"s, but reserve ++ room for the terminator. */ ++ yysize = yystrlen (yyformat) - 2 * yycount + 1; + { +- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); +- if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) +- yysize = yysize1; +- else +- return 2; ++ int yyi; ++ for (yyi = 0; yyi < yycount; ++yyi) ++ { ++ YYPTRDIFF_T yysize1 ++ = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); ++ if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) ++ yysize = yysize1; ++ else ++ return YYENOMEM; ++ } + } + + if (*yymsg_alloc < yysize) +@@ -1850,7 +2123,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, c + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; +- return 1; ++ return -1; + } + + /* Avoid sprintf, as that infringes on the user's name space. +@@ -1862,226 +2135,226 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, c + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { +- yyp += yytnamerr (yyp, yyarg[yyi++]); ++ yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); + yyformat += 2; + } + else + { +- yyp++; +- yyformat++; ++ ++yyp; ++ ++yyformat; + } + } + return 0; + } +-#endif /* YYERROR_VERBOSE */ ++ + + /*-----------------------------------------------. + | Release the memory associated to this symbol. | + `-----------------------------------------------*/ + + static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) ++yydestruct (const char *yymsg, ++ yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) + { +- YYUSE (yyvaluep); +- YYUSE (yylocationp); +- YYUSE (answer); +- YYUSE (errors); +- YYUSE (locations); +- YYUSE (lexer_param_ptr); ++ YY_USE (yyvaluep); ++ YY_USE (yylocationp); ++ YY_USE (answer); ++ YY_USE (errors); ++ YY_USE (locations); ++ YY_USE (lexer_param_ptr); + if (!yymsg) + yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); ++ YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- switch (yytype) ++ switch (yykind) + { +- case 4: /* IDENT */ +-#line 36 "src/parser.y" /* yacc.c:1257 */ +- { jv_free(((*yyvaluep).literal)); } +-#line 1893 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_IDENT: /* IDENT */ ++#line 36 "src/parser.y" ++ { jv_free(((*yyvaluep).literal)); } ++#line 2176 "src/parser.c" + break; + +- case 5: /* FIELD */ +-#line 36 "src/parser.y" /* yacc.c:1257 */ +- { jv_free(((*yyvaluep).literal)); } +-#line 1899 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_FIELD: /* FIELD */ ++#line 36 "src/parser.y" ++ { jv_free(((*yyvaluep).literal)); } ++#line 2182 "src/parser.c" + break; + +- case 6: /* LITERAL */ +-#line 36 "src/parser.y" /* yacc.c:1257 */ +- { jv_free(((*yyvaluep).literal)); } +-#line 1905 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_LITERAL: /* LITERAL */ ++#line 36 "src/parser.y" ++ { jv_free(((*yyvaluep).literal)); } ++#line 2188 "src/parser.c" + break; + +- case 7: /* FORMAT */ +-#line 36 "src/parser.y" /* yacc.c:1257 */ +- { jv_free(((*yyvaluep).literal)); } +-#line 1911 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_FORMAT: /* FORMAT */ ++#line 36 "src/parser.y" ++ { jv_free(((*yyvaluep).literal)); } ++#line 2194 "src/parser.c" + break; + +- case 42: /* QQSTRING_TEXT */ +-#line 36 "src/parser.y" /* yacc.c:1257 */ +- { jv_free(((*yyvaluep).literal)); } +-#line 1917 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_QQSTRING_TEXT: /* QQSTRING_TEXT */ ++#line 36 "src/parser.y" ++ { jv_free(((*yyvaluep).literal)); } ++#line 2200 "src/parser.c" + break; + +- case 71: /* Module */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1923 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Module: /* Module */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2206 "src/parser.c" + break; + +- case 72: /* Imports */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1929 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Imports: /* Imports */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2212 "src/parser.c" + break; + +- case 73: /* FuncDefs */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1935 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_FuncDefs: /* FuncDefs */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2218 "src/parser.c" + break; + +- case 74: /* Exp */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1941 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Exp: /* Exp */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2224 "src/parser.c" + break; + +- case 75: /* Import */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1947 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Import: /* Import */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2230 "src/parser.c" + break; + +- case 76: /* ImportWhat */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1953 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_ImportWhat: /* ImportWhat */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2236 "src/parser.c" + break; + +- case 77: /* ImportFrom */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1959 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_ImportFrom: /* ImportFrom */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2242 "src/parser.c" + break; + +- case 78: /* FuncDef */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1965 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_FuncDef: /* FuncDef */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2248 "src/parser.c" + break; + +- case 79: /* Params */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1971 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Params: /* Params */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2254 "src/parser.c" + break; + +- case 80: /* Param */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1977 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Param: /* Param */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2260 "src/parser.c" + break; + +- case 81: /* String */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1983 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_String: /* String */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2266 "src/parser.c" + break; + +- case 84: /* QQString */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1989 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_QQString: /* QQString */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2272 "src/parser.c" + break; + +- case 85: /* ElseBody */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 1995 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_ElseBody: /* ElseBody */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2278 "src/parser.c" + break; + +- case 86: /* ExpD */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2001 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_ExpD: /* ExpD */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2284 "src/parser.c" + break; + +- case 87: /* Term */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2007 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Term: /* Term */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2290 "src/parser.c" + break; + +- case 88: /* Args */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2013 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Args: /* Args */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2296 "src/parser.c" + break; + +- case 89: /* Arg */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2019 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Arg: /* Arg */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2302 "src/parser.c" + break; + +- case 90: /* RepPatterns */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2025 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_RepPatterns: /* RepPatterns */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2308 "src/parser.c" + break; + +- case 91: /* Patterns */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2031 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Patterns: /* Patterns */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2314 "src/parser.c" + break; + +- case 92: /* Pattern */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2037 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Pattern: /* Pattern */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2320 "src/parser.c" + break; + +- case 93: /* ArrayPats */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2043 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_ArrayPats: /* ArrayPats */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2326 "src/parser.c" + break; + +- case 94: /* ObjPats */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2049 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_ObjPats: /* ObjPats */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2332 "src/parser.c" + break; + +- case 95: /* ObjPat */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2055 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_ObjPat: /* ObjPat */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2338 "src/parser.c" + break; + +- case 96: /* Keyword */ +-#line 36 "src/parser.y" /* yacc.c:1257 */ +- { jv_free(((*yyvaluep).literal)); } +-#line 2061 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_Keyword: /* Keyword */ ++#line 36 "src/parser.y" ++ { jv_free(((*yyvaluep).literal)); } ++#line 2344 "src/parser.c" + break; + +- case 97: /* MkDict */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2067 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_MkDict: /* MkDict */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2350 "src/parser.c" + break; + +- case 98: /* MkDictPair */ +-#line 37 "src/parser.y" /* yacc.c:1257 */ +- { block_free(((*yyvaluep).blk)); } +-#line 2073 "src/parser.c" /* yacc.c:1257 */ ++ case YYSYMBOL_MkDictPair: /* MkDictPair */ ++#line 37 "src/parser.y" ++ { block_free(((*yyvaluep).blk)); } ++#line 2356 "src/parser.c" + break; + +- + default: + break; + } +@@ -2091,6 +2364,8 @@ yydestruct (const char *yymsg, int yytyp + + + ++ ++ + /*----------. + | yyparse. | + `----------*/ +@@ -2098,7 +2373,7 @@ yydestruct (const char *yymsg, int yytyp + int + yyparse (block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr) + { +-/* The lookahead symbol. */ ++/* Lookahead token kind. */ + int yychar; + + +@@ -2117,55 +2392,50 @@ static YYLTYPE yyloc_default + YYLTYPE yylloc = yyloc_default; + + /* Number of syntax errors so far. */ +- int yynerrs; ++ int yynerrs = 0; + +- int yystate; ++ yy_state_fast_t yystate = 0; + /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- +- /* The stacks and their tools: +- 'yyss': related to states. +- 'yyvs': related to semantic values. +- 'yyls': related to locations. ++ int yyerrstatus = 0; + +- Refer to the stacks through separate pointers, to allow yyoverflow ++ /* Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss; +- yytype_int16 *yyssp; ++ /* Their size. */ ++ YYPTRDIFF_T yystacksize = YYINITDEPTH; + +- /* The semantic value stack. */ ++ /* The state stack: array, bottom, top. */ ++ yy_state_t yyssa[YYINITDEPTH]; ++ yy_state_t *yyss = yyssa; ++ yy_state_t *yyssp = yyss; ++ ++ /* The semantic value stack: array, bottom, top. */ + YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs; +- YYSTYPE *yyvsp; ++ YYSTYPE *yyvs = yyvsa; ++ YYSTYPE *yyvsp = yyvs; + +- /* The location stack. */ ++ /* The location stack: array, bottom, top. */ + YYLTYPE yylsa[YYINITDEPTH]; +- YYLTYPE *yyls; +- YYLTYPE *yylsp; +- +- /* The locations where the error started and ended. */ +- YYLTYPE yyerror_range[3]; +- +- YYSIZE_T yystacksize; ++ YYLTYPE *yyls = yylsa; ++ YYLTYPE *yylsp = yyls; + + int yyn; ++ /* The return value of yyparse. */ + int yyresult; +- /* Lookahead token as an internal (translated) token number. */ +- int yytoken = 0; ++ /* Lookahead symbol kind. */ ++ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + +-#if YYERROR_VERBOSE ++ /* The locations where the error started and ended. */ ++ YYLTYPE yyerror_range[3]; ++ + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif ++ YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; + + #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + +@@ -2173,17 +2443,10 @@ YYLTYPE yylloc = yyloc_default; + Keep to zero when no symbol should be popped. */ + int yylen = 0; + +- yyssp = yyss = yyssa; +- yyvsp = yyvs = yyvsa; +- yylsp = yyls = yylsa; +- yystacksize = YYINITDEPTH; +- + YYDPRINTF ((stderr, "Starting parse\n")); + +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ ++ + yylsp[0] = yylloc; + goto yysetstate; + +@@ -2198,26 +2461,31 @@ yynewstate: + + + /*--------------------------------------------------------------------. +-| yynewstate -- set current state (the top of the stack) to yystate. | ++| yysetstate -- set current state (the top of the stack) to yystate. | + `--------------------------------------------------------------------*/ + yysetstate: +- *yyssp = (yytype_int16) yystate; ++ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); ++ YY_ASSERT (0 <= yystate && yystate < YYNSTATES); ++ YY_IGNORE_USELESS_CAST_BEGIN ++ *yyssp = YY_CAST (yy_state_t, yystate); ++ YY_IGNORE_USELESS_CAST_END ++ YY_STACK_PRINT (yyss, yyssp); + + if (yyss + yystacksize - 1 <= yyssp) + #if !defined yyoverflow && !defined YYSTACK_RELOCATE +- goto yyexhaustedlab; ++ YYNOMEM; + #else + { + /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); ++ YYPTRDIFF_T yysize = yyssp - yyss + 1; + + # if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ ++ yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the +@@ -2225,9 +2493,9 @@ yysetstate: + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- &yyls1, yysize * sizeof (*yylsp), ++ &yyss1, yysize * YYSIZEOF (*yyssp), ++ &yyvs1, yysize * YYSIZEOF (*yyvsp), ++ &yyls1, yysize * YYSIZEOF (*yylsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; +@@ -2236,21 +2504,22 @@ yysetstate: + # else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; ++ YYNOMEM; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { +- yytype_int16 *yyss1 = yyss; ++ yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ YY_CAST (union yyalloc *, ++ YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) +- goto yyexhaustedlab; ++ YYNOMEM; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); +-# undef YYSTACK_RELOCATE ++# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +@@ -2260,15 +2529,16 @@ yysetstate: + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; + +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long) yystacksize)); ++ YY_IGNORE_USELESS_CAST_BEGIN ++ YYDPRINTF ((stderr, "Stack size increased to %ld\n", ++ YY_CAST (long, yystacksize))); ++ YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; +@@ -2290,18 +2560,30 @@ yybackup: + + /* Not known => get a lookahead token if don't already have one. */ + +- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ ++ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ + if (yychar == YYEMPTY) + { +- YYDPRINTF ((stderr, "Reading a token: ")); ++ YYDPRINTF ((stderr, "Reading a token\n")); + yychar = yylex (&yylval, &yylloc, answer, errors, locations, lexer_param_ptr); + } + + if (yychar <= YYEOF) + { +- yychar = yytoken = YYEOF; ++ yychar = YYEOF; ++ yytoken = YYSYMBOL_YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } ++ else if (yychar == YYerror) ++ { ++ /* The scanner already issued an error message, process directly ++ to error recovery. But do not keep the error token as ++ lookahead, it is too special and may lead us to an endless ++ loop in error recovery. */ ++ yychar = YYUNDEF; ++ yytoken = YYSYMBOL_YYerror; ++ yyerror_range[1] = yylloc; ++ goto yyerrlab1; ++ } + else + { + yytoken = YYTRANSLATE (yychar); +@@ -2329,15 +2611,14 @@ yybackup: + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token. */ +- yychar = YYEMPTY; +- + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + *++yylsp = yylloc; ++ ++ /* Discard the shifted token. */ ++ yychar = YYEMPTY; + goto yynewstate; + + +@@ -2368,38 +2649,39 @@ yyreduce: + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + +- /* Default location. */ ++ /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); ++ yyerror_range[1] = yyloc; + YY_REDUCE_PRINT (yyn); + switch (yyn) + { +- case 2: +-#line 300 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 2: /* TopLevel: Module Imports Exp */ ++#line 306 "src/parser.y" ++ { + *answer = BLOCK((yyvsp[-2].blk), (yyvsp[-1].blk), gen_op_simple(TOP), (yyvsp[0].blk)); + } +-#line 2369 "src/parser.c" /* yacc.c:1646 */ ++#line 2664 "src/parser.c" + break; + +- case 3: +-#line 303 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 3: /* TopLevel: Module Imports FuncDefs */ ++#line 309 "src/parser.y" ++ { + *answer = BLOCK((yyvsp[-2].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); + } +-#line 2377 "src/parser.c" /* yacc.c:1646 */ ++#line 2672 "src/parser.c" + break; + +- case 4: +-#line 308 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 4: /* Module: %empty */ ++#line 314 "src/parser.y" ++ { + (yyval.blk) = gen_noop(); + } +-#line 2385 "src/parser.c" /* yacc.c:1646 */ ++#line 2680 "src/parser.c" + break; + +- case 5: +-#line 311 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 5: /* Module: "module" Exp ';' */ ++#line 317 "src/parser.y" ++ { + if (!block_is_const((yyvsp[-1].blk))) { + FAIL((yyloc), "Module metadata must be constant"); + (yyval.blk) = gen_noop(); +@@ -2408,367 +2690,367 @@ yyreduce: + (yyval.blk) = gen_module((yyvsp[-1].blk)); + } + } +-#line 2399 "src/parser.c" /* yacc.c:1646 */ ++#line 2694 "src/parser.c" + break; + +- case 6: +-#line 322 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 6: /* Imports: %empty */ ++#line 328 "src/parser.y" ++ { + (yyval.blk) = gen_noop(); + } +-#line 2407 "src/parser.c" /* yacc.c:1646 */ ++#line 2702 "src/parser.c" + break; + +- case 7: +-#line 325 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 7: /* Imports: Import Imports */ ++#line 331 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[-1].blk), (yyvsp[0].blk)); + } +-#line 2415 "src/parser.c" /* yacc.c:1646 */ ++#line 2710 "src/parser.c" + break; + +- case 8: +-#line 330 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 8: /* FuncDefs: %empty */ ++#line 336 "src/parser.y" ++ { + (yyval.blk) = gen_noop(); + } +-#line 2423 "src/parser.c" /* yacc.c:1646 */ ++#line 2718 "src/parser.c" + break; + +- case 9: +-#line 333 "src/parser.y" /* yacc.c:1646 */ +- { +- (yyval.blk) = block_bind((yyvsp[-1].blk), (yyvsp[0].blk), OP_IS_CALL_PSEUDO); ++ case 9: /* FuncDefs: FuncDef FuncDefs */ ++#line 339 "src/parser.y" ++ { ++ (yyval.blk) = block_join((yyvsp[-1].blk), (yyvsp[0].blk)); + } +-#line 2431 "src/parser.c" /* yacc.c:1646 */ ++#line 2726 "src/parser.c" + break; + +- case 10: +-#line 338 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 10: /* Exp: FuncDef Exp */ ++#line 344 "src/parser.y" ++ { + (yyval.blk) = block_bind_referenced((yyvsp[-1].blk), (yyvsp[0].blk), OP_IS_CALL_PSEUDO); + } +-#line 2439 "src/parser.c" /* yacc.c:1646 */ ++#line 2734 "src/parser.c" + break; + +- case 11: +-#line 342 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 11: /* Exp: Term "as" Patterns '|' Exp */ ++#line 348 "src/parser.y" ++ { + (yyval.blk) = gen_destructure((yyvsp[-4].blk), (yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2447 "src/parser.c" /* yacc.c:1646 */ ++#line 2742 "src/parser.c" + break; + +- case 12: +-#line 345 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 12: /* Exp: "reduce" Term "as" Patterns '(' Exp ';' Exp ')' */ ++#line 351 "src/parser.y" ++ { + (yyval.blk) = gen_reduce((yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk)); + } +-#line 2455 "src/parser.c" /* yacc.c:1646 */ ++#line 2750 "src/parser.c" + break; + +- case 13: +-#line 349 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 13: /* Exp: "foreach" Term "as" Patterns '(' Exp ';' Exp ';' Exp ')' */ ++#line 355 "src/parser.y" ++ { + (yyval.blk) = gen_foreach((yyvsp[-9].blk), (yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk)); + } +-#line 2463 "src/parser.c" /* yacc.c:1646 */ ++#line 2758 "src/parser.c" + break; + +- case 14: +-#line 353 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 14: /* Exp: "foreach" Term "as" Patterns '(' Exp ';' Exp ')' */ ++#line 359 "src/parser.y" ++ { + (yyval.blk) = gen_foreach((yyvsp[-7].blk), (yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk), gen_noop()); + } +-#line 2471 "src/parser.c" /* yacc.c:1646 */ ++#line 2766 "src/parser.c" + break; + +- case 15: +-#line 357 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 15: /* Exp: "if" Exp "then" Exp ElseBody */ ++#line 363 "src/parser.y" ++ { + (yyval.blk) = gen_cond((yyvsp[-3].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); + } +-#line 2479 "src/parser.c" /* yacc.c:1646 */ ++#line 2774 "src/parser.c" + break; + +- case 16: +-#line 360 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 16: /* Exp: "if" Exp "then" error */ ++#line 366 "src/parser.y" ++ { + FAIL((yyloc), "Possibly unterminated 'if' statement"); + (yyval.blk) = (yyvsp[-2].blk); + } +-#line 2488 "src/parser.c" /* yacc.c:1646 */ ++#line 2783 "src/parser.c" + break; + +- case 17: +-#line 365 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 17: /* Exp: "try" Exp "catch" Exp */ ++#line 371 "src/parser.y" ++ { + //$$ = BLOCK(gen_op_target(FORK_OPT, $2), $2, $4); + (yyval.blk) = gen_try((yyvsp[-2].blk), gen_try_handler((yyvsp[0].blk))); + } +-#line 2497 "src/parser.c" /* yacc.c:1646 */ ++#line 2792 "src/parser.c" + break; + +- case 18: +-#line 369 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 18: /* Exp: "try" Exp */ ++#line 375 "src/parser.y" ++ { + //$$ = BLOCK(gen_op_target(FORK_OPT, $2), $2, gen_op_simple(BACKTRACK)); + (yyval.blk) = gen_try((yyvsp[0].blk), gen_op_simple(BACKTRACK)); + } +-#line 2506 "src/parser.c" /* yacc.c:1646 */ ++#line 2801 "src/parser.c" + break; + +- case 19: +-#line 373 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 19: /* Exp: "try" Exp "catch" error */ ++#line 379 "src/parser.y" ++ { + FAIL((yyloc), "Possibly unterminated 'try' statement"); + (yyval.blk) = (yyvsp[-2].blk); + } +-#line 2515 "src/parser.c" /* yacc.c:1646 */ ++#line 2810 "src/parser.c" + break; + +- case 20: +-#line 378 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 20: /* Exp: "label" '$' IDENT '|' Exp */ ++#line 384 "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 2526 "src/parser.c" /* yacc.c:1646 */ ++#line 2821 "src/parser.c" + break; + +- case 21: +-#line 385 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 21: /* Exp: Exp '?' */ ++#line 391 "src/parser.y" ++ { + (yyval.blk) = gen_try((yyvsp[-1].blk), gen_op_simple(BACKTRACK)); + } +-#line 2534 "src/parser.c" /* yacc.c:1646 */ ++#line 2829 "src/parser.c" + break; + +- case 22: +-#line 389 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 22: /* Exp: Exp '=' Exp */ ++#line 395 "src/parser.y" ++ { + (yyval.blk) = gen_call("_assign", BLOCK(gen_lambda((yyvsp[-2].blk)), gen_lambda((yyvsp[0].blk)))); + } +-#line 2542 "src/parser.c" /* yacc.c:1646 */ ++#line 2837 "src/parser.c" + break; + +- case 23: +-#line 393 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 23: /* Exp: Exp "or" Exp */ ++#line 399 "src/parser.y" ++ { + (yyval.blk) = gen_or((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2550 "src/parser.c" /* yacc.c:1646 */ ++#line 2845 "src/parser.c" + break; + +- case 24: +-#line 397 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 24: /* Exp: Exp "and" Exp */ ++#line 403 "src/parser.y" ++ { + (yyval.blk) = gen_and((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2558 "src/parser.c" /* yacc.c:1646 */ ++#line 2853 "src/parser.c" + break; + +- case 25: +-#line 401 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 25: /* Exp: Exp "//" Exp */ ++#line 407 "src/parser.y" ++ { + (yyval.blk) = gen_definedor((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2566 "src/parser.c" /* yacc.c:1646 */ ++#line 2861 "src/parser.c" + break; + +- case 26: +-#line 405 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 26: /* Exp: Exp "//=" Exp */ ++#line 411 "src/parser.y" ++ { + (yyval.blk) = gen_definedor_assign((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2574 "src/parser.c" /* yacc.c:1646 */ ++#line 2869 "src/parser.c" + break; + +- case 27: +-#line 409 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 27: /* Exp: Exp "|=" Exp */ ++#line 415 "src/parser.y" ++ { + (yyval.blk) = gen_call("_modify", BLOCK(gen_lambda((yyvsp[-2].blk)), gen_lambda((yyvsp[0].blk)))); + } +-#line 2582 "src/parser.c" /* yacc.c:1646 */ ++#line 2877 "src/parser.c" + break; + +- case 28: +-#line 413 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 28: /* Exp: Exp '|' Exp */ ++#line 419 "src/parser.y" ++ { + (yyval.blk) = block_join((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2590 "src/parser.c" /* yacc.c:1646 */ ++#line 2885 "src/parser.c" + break; + +- case 29: +-#line 417 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 29: /* Exp: Exp ',' Exp */ ++#line 423 "src/parser.y" ++ { + (yyval.blk) = gen_both((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2598 "src/parser.c" /* yacc.c:1646 */ ++#line 2893 "src/parser.c" + break; + +- case 30: +-#line 421 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 30: /* Exp: Exp '+' Exp */ ++#line 427 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '+'); + } +-#line 2606 "src/parser.c" /* yacc.c:1646 */ ++#line 2901 "src/parser.c" + break; + +- case 31: +-#line 425 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 31: /* Exp: Exp "+=" Exp */ ++#line 431 "src/parser.y" ++ { + (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '+'); + } +-#line 2614 "src/parser.c" /* yacc.c:1646 */ ++#line 2909 "src/parser.c" + break; + +- case 32: +-#line 429 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 32: /* Exp: '-' Exp */ ++#line 435 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[0].blk), gen_call("_negate", gen_noop())); + } +-#line 2622 "src/parser.c" /* yacc.c:1646 */ ++#line 2917 "src/parser.c" + break; + +- case 33: +-#line 433 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 33: /* Exp: Exp '-' Exp */ ++#line 439 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '-'); + } +-#line 2630 "src/parser.c" /* yacc.c:1646 */ ++#line 2925 "src/parser.c" + break; + +- case 34: +-#line 437 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 34: /* Exp: Exp "-=" Exp */ ++#line 443 "src/parser.y" ++ { + (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '-'); + } +-#line 2638 "src/parser.c" /* yacc.c:1646 */ ++#line 2933 "src/parser.c" + break; + +- case 35: +-#line 441 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 35: /* Exp: Exp '*' Exp */ ++#line 447 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '*'); + } +-#line 2646 "src/parser.c" /* yacc.c:1646 */ ++#line 2941 "src/parser.c" + break; + +- case 36: +-#line 445 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 36: /* Exp: Exp "*=" Exp */ ++#line 451 "src/parser.y" ++ { + (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '*'); + } +-#line 2654 "src/parser.c" /* yacc.c:1646 */ ++#line 2949 "src/parser.c" + break; + +- case 37: +-#line 449 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 37: /* Exp: Exp '/' Exp */ ++#line 455 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '/'); + if (block_is_const_inf((yyval.blk))) + FAIL((yyloc), "Division by zero?"); + } +-#line 2664 "src/parser.c" /* yacc.c:1646 */ ++#line 2959 "src/parser.c" + break; + +- case 38: +-#line 455 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 38: /* Exp: Exp '%' Exp */ ++#line 461 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '%'); + if (block_is_const_inf((yyval.blk))) + FAIL((yyloc), "Remainder by zero?"); + } +-#line 2674 "src/parser.c" /* yacc.c:1646 */ ++#line 2969 "src/parser.c" + break; + +- case 39: +-#line 461 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 39: /* Exp: Exp "/=" Exp */ ++#line 467 "src/parser.y" ++ { + (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '/'); + } +-#line 2682 "src/parser.c" /* yacc.c:1646 */ ++#line 2977 "src/parser.c" + break; + +- case 40: +-#line 465 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 40: /* Exp: Exp "%=" Exp */ ++#line 471 "src/parser.y" ++ { + (yyval.blk) = gen_update((yyvsp[-2].blk), (yyvsp[0].blk), '%'); + } +-#line 2690 "src/parser.c" /* yacc.c:1646 */ ++#line 2985 "src/parser.c" + break; + +- case 41: +-#line 469 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 41: /* Exp: Exp "==" Exp */ ++#line 475 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), EQ); + } +-#line 2698 "src/parser.c" /* yacc.c:1646 */ ++#line 2993 "src/parser.c" + break; + +- case 42: +-#line 473 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 42: /* Exp: Exp "!=" Exp */ ++#line 479 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), NEQ); + } +-#line 2706 "src/parser.c" /* yacc.c:1646 */ ++#line 3001 "src/parser.c" + break; + +- case 43: +-#line 477 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 43: /* Exp: Exp '<' Exp */ ++#line 483 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '<'); + } +-#line 2714 "src/parser.c" /* yacc.c:1646 */ ++#line 3009 "src/parser.c" + break; + +- case 44: +-#line 481 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 44: /* Exp: Exp '>' Exp */ ++#line 487 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), '>'); + } +-#line 2722 "src/parser.c" /* yacc.c:1646 */ ++#line 3017 "src/parser.c" + break; + +- case 45: +-#line 485 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 45: /* Exp: Exp "<=" Exp */ ++#line 491 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), LESSEQ); + } +-#line 2730 "src/parser.c" /* yacc.c:1646 */ ++#line 3025 "src/parser.c" + break; + +- case 46: +-#line 489 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 46: /* Exp: Exp ">=" Exp */ ++#line 495 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-2].blk), (yyvsp[0].blk), GREATEREQ); + } +-#line 2738 "src/parser.c" /* yacc.c:1646 */ ++#line 3033 "src/parser.c" + break; + +- case 47: +-#line 493 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 47: /* Exp: Term */ ++#line 499 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[0].blk); + } +-#line 2746 "src/parser.c" /* yacc.c:1646 */ ++#line 3041 "src/parser.c" + break; + +- case 48: +-#line 498 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 48: /* Import: ImportWhat ';' */ ++#line 504 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[-1].blk); + } +-#line 2754 "src/parser.c" /* yacc.c:1646 */ ++#line 3049 "src/parser.c" + break; + +- case 49: +-#line 501 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 49: /* Import: ImportWhat Exp ';' */ ++#line 507 "src/parser.y" ++ { + if (!block_is_const((yyvsp[-1].blk))) { + FAIL((yyloc), "Module metadata must be constant"); + (yyval.blk) = gen_noop(); +@@ -2783,12 +3065,12 @@ yyreduce: + (yyval.blk) = gen_import_meta((yyvsp[-2].blk), (yyvsp[-1].blk)); + } + } +-#line 2774 "src/parser.c" /* yacc.c:1646 */ ++#line 3069 "src/parser.c" + break; + +- case 50: +-#line 518 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 50: /* ImportWhat: "import" ImportFrom "as" '$' IDENT */ ++#line 524 "src/parser.y" ++ { + jv v = block_const((yyvsp[-3].blk)); + // XXX Make gen_import take only blocks and the int is_data so we + // don't have to free so much stuff here +@@ -2797,35 +3079,35 @@ yyreduce: + jv_free((yyvsp[0].literal)); + jv_free(v); + } +-#line 2788 "src/parser.c" /* yacc.c:1646 */ ++#line 3083 "src/parser.c" + break; + +- case 51: +-#line 527 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 51: /* ImportWhat: "import" ImportFrom "as" IDENT */ ++#line 533 "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); + block_free((yyvsp[-2].blk)); + jv_free((yyvsp[0].literal)); + jv_free(v); + } +-#line 2800 "src/parser.c" /* yacc.c:1646 */ ++#line 3095 "src/parser.c" + break; + +- case 52: +-#line 534 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 52: /* ImportWhat: "include" ImportFrom */ ++#line 540 "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 2811 "src/parser.c" /* yacc.c:1646 */ ++#line 3106 "src/parser.c" + break; + +- case 53: +-#line 542 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 53: /* ImportFrom: String */ ++#line 548 "src/parser.y" ++ { + if (!block_is_const((yyvsp[0].blk))) { + FAIL((yyloc), "Import path must be constant"); + (yyval.blk) = gen_const(jv_string("")); +@@ -2834,174 +3116,174 @@ yyreduce: + (yyval.blk) = (yyvsp[0].blk); + } + } +-#line 2825 "src/parser.c" /* yacc.c:1646 */ ++#line 3120 "src/parser.c" + break; + +- case 54: +-#line 553 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 54: /* FuncDef: "def" IDENT ':' Exp ';' */ ++#line 559 "src/parser.y" ++ { + (yyval.blk) = gen_function(jv_string_value((yyvsp[-3].literal)), gen_noop(), (yyvsp[-1].blk)); + jv_free((yyvsp[-3].literal)); + } +-#line 2834 "src/parser.c" /* yacc.c:1646 */ ++#line 3129 "src/parser.c" + break; + +- case 55: +-#line 558 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 55: /* FuncDef: "def" IDENT '(' Params ')' ':' Exp ';' */ ++#line 564 "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 2843 "src/parser.c" /* yacc.c:1646 */ ++#line 3138 "src/parser.c" + break; + +- case 56: +-#line 564 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 56: /* Params: Param */ ++#line 570 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[0].blk); + } +-#line 2851 "src/parser.c" /* yacc.c:1646 */ ++#line 3146 "src/parser.c" + break; + +- case 57: +-#line 567 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 57: /* Params: Params ';' Param */ ++#line 573 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2859 "src/parser.c" /* yacc.c:1646 */ ++#line 3154 "src/parser.c" + break; + +- case 58: +-#line 572 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 58: /* Param: '$' IDENT */ ++#line 578 "src/parser.y" ++ { + (yyval.blk) = gen_param_regular(jv_string_value((yyvsp[0].literal))); + jv_free((yyvsp[0].literal)); + } +-#line 2868 "src/parser.c" /* yacc.c:1646 */ ++#line 3163 "src/parser.c" + break; + +- case 59: +-#line 577 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 59: /* Param: IDENT */ ++#line 583 "src/parser.y" ++ { + (yyval.blk) = gen_param(jv_string_value((yyvsp[0].literal))); + jv_free((yyvsp[0].literal)); + } +-#line 2877 "src/parser.c" /* yacc.c:1646 */ ++#line 3172 "src/parser.c" + break; + +- case 60: +-#line 584 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.literal) = jv_string("text"); } +-#line 2883 "src/parser.c" /* yacc.c:1646 */ ++ case 60: /* @1: %empty */ ++#line 590 "src/parser.y" ++ { (yyval.literal) = jv_string("text"); } ++#line 3178 "src/parser.c" + break; + +- case 61: +-#line 584 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 61: /* String: QQSTRING_START @1 QQString QQSTRING_END */ ++#line 590 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[-1].blk); + jv_free((yyvsp[-2].literal)); + } +-#line 2892 "src/parser.c" /* yacc.c:1646 */ ++#line 3187 "src/parser.c" + break; + +- case 62: +-#line 588 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.literal) = (yyvsp[-1].literal); } +-#line 2898 "src/parser.c" /* yacc.c:1646 */ ++ case 62: /* @2: %empty */ ++#line 594 "src/parser.y" ++ { (yyval.literal) = (yyvsp[-1].literal); } ++#line 3193 "src/parser.c" + break; + +- case 63: +-#line 588 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 63: /* String: FORMAT QQSTRING_START @2 QQString QQSTRING_END */ ++#line 594 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[-1].blk); + jv_free((yyvsp[-2].literal)); + } +-#line 2907 "src/parser.c" /* yacc.c:1646 */ ++#line 3202 "src/parser.c" + break; + +- case 64: +-#line 595 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 64: /* QQString: %empty */ ++#line 601 "src/parser.y" ++ { + (yyval.blk) = gen_const(jv_string("")); + } +-#line 2915 "src/parser.c" /* yacc.c:1646 */ ++#line 3210 "src/parser.c" + break; + +- case 65: +-#line 598 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 65: /* QQString: QQString QQSTRING_TEXT */ ++#line 604 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-1].blk), gen_const((yyvsp[0].literal)), '+'); + } +-#line 2923 "src/parser.c" /* yacc.c:1646 */ ++#line 3218 "src/parser.c" + break; + +- case 66: +-#line 601 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 66: /* QQString: QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END */ ++#line 607 "src/parser.y" ++ { + (yyval.blk) = gen_binop((yyvsp[-3].blk), gen_format((yyvsp[-1].blk), jv_copy((yyvsp[-4].literal))), '+'); + } +-#line 2931 "src/parser.c" /* yacc.c:1646 */ ++#line 3226 "src/parser.c" + break; + +- case 67: +-#line 607 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 67: /* ElseBody: "elif" Exp "then" Exp ElseBody */ ++#line 613 "src/parser.y" ++ { + (yyval.blk) = gen_cond((yyvsp[-3].blk), (yyvsp[-1].blk), (yyvsp[0].blk)); + } +-#line 2939 "src/parser.c" /* yacc.c:1646 */ ++#line 3234 "src/parser.c" + break; + +- case 68: +-#line 610 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 68: /* ElseBody: "else" Exp "end" */ ++#line 616 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[-1].blk); + } +-#line 2947 "src/parser.c" /* yacc.c:1646 */ ++#line 3242 "src/parser.c" + break; + +- case 69: +-#line 615 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 69: /* ExpD: ExpD '|' ExpD */ ++#line 621 "src/parser.y" ++ { + (yyval.blk) = block_join((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 2955 "src/parser.c" /* yacc.c:1646 */ ++#line 3250 "src/parser.c" + break; + +- case 70: +-#line 618 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 70: /* ExpD: '-' ExpD */ ++#line 624 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[0].blk), gen_call("_negate", gen_noop())); + } +-#line 2963 "src/parser.c" /* yacc.c:1646 */ ++#line 3258 "src/parser.c" + break; + +- case 71: +-#line 621 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 71: /* ExpD: Term */ ++#line 627 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[0].blk); + } +-#line 2971 "src/parser.c" /* yacc.c:1646 */ ++#line 3266 "src/parser.c" + break; + +- case 72: +-#line 627 "src/parser.y" /* yacc.c:1646 */ ++ case 72: /* Term: '.' */ ++#line 633 "src/parser.y" + { + (yyval.blk) = gen_noop(); + } +-#line 2979 "src/parser.c" /* yacc.c:1646 */ ++#line 3274 "src/parser.c" + break; + +- case 73: +-#line 630 "src/parser.y" /* yacc.c:1646 */ ++ case 73: /* Term: ".." */ ++#line 636 "src/parser.y" + { + (yyval.blk) = gen_call("recurse", gen_noop()); + } +-#line 2987 "src/parser.c" /* yacc.c:1646 */ ++#line 3282 "src/parser.c" + break; + +- case 74: +-#line 633 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 74: /* Term: "break" '$' IDENT */ ++#line 639 "src/parser.y" ++ { + jv v = jv_string_fmt("*label-%s", jv_string_value((yyvsp[0].literal))); // impossible symbol + (yyval.blk) = gen_location((yyloc), locations, + BLOCK(gen_op_unbound(LOADV, jv_string_value(v)), +@@ -3009,262 +3291,262 @@ yyreduce: + jv_free(v); + jv_free((yyvsp[0].literal)); + } +-#line 3000 "src/parser.c" /* yacc.c:1646 */ ++#line 3295 "src/parser.c" + break; + +- case 75: +-#line 641 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 75: /* Term: "break" error */ ++#line 647 "src/parser.y" ++ { + FAIL((yyloc), "break requires a label to break to"); + (yyval.blk) = gen_noop(); + } +-#line 3009 "src/parser.c" /* yacc.c:1646 */ ++#line 3304 "src/parser.c" + break; + +- case 76: +-#line 645 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 76: /* Term: Term FIELD '?' */ ++#line 651 "src/parser.y" ++ { + (yyval.blk) = gen_index_opt((yyvsp[-2].blk), gen_const((yyvsp[-1].literal))); + } +-#line 3017 "src/parser.c" /* yacc.c:1646 */ ++#line 3312 "src/parser.c" + break; + +- case 77: +-#line 648 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 77: /* Term: FIELD '?' */ ++#line 654 "src/parser.y" ++ { + (yyval.blk) = gen_index_opt(gen_noop(), gen_const((yyvsp[-1].literal))); + } +-#line 3025 "src/parser.c" /* yacc.c:1646 */ ++#line 3320 "src/parser.c" + break; + +- case 78: +-#line 651 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 78: /* Term: Term '.' String '?' */ ++#line 657 "src/parser.y" ++ { + (yyval.blk) = gen_index_opt((yyvsp[-3].blk), (yyvsp[-1].blk)); + } +-#line 3033 "src/parser.c" /* yacc.c:1646 */ ++#line 3328 "src/parser.c" + break; + +- case 79: +-#line 654 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 79: /* Term: '.' String '?' */ ++#line 660 "src/parser.y" ++ { + (yyval.blk) = gen_index_opt(gen_noop(), (yyvsp[-1].blk)); + } +-#line 3041 "src/parser.c" /* yacc.c:1646 */ ++#line 3336 "src/parser.c" + break; + +- case 80: +-#line 657 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 80: /* Term: Term FIELD */ ++#line 663 "src/parser.y" ++ { + (yyval.blk) = gen_index((yyvsp[-1].blk), gen_const((yyvsp[0].literal))); + } +-#line 3049 "src/parser.c" /* yacc.c:1646 */ ++#line 3344 "src/parser.c" + break; + +- case 81: +-#line 660 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 81: /* Term: FIELD */ ++#line 666 "src/parser.y" ++ { + (yyval.blk) = gen_index(gen_noop(), gen_const((yyvsp[0].literal))); + } +-#line 3057 "src/parser.c" /* yacc.c:1646 */ ++#line 3352 "src/parser.c" + break; + +- case 82: +-#line 663 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 82: /* Term: Term '.' String */ ++#line 669 "src/parser.y" ++ { + (yyval.blk) = gen_index((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 3065 "src/parser.c" /* yacc.c:1646 */ ++#line 3360 "src/parser.c" + break; + +- case 83: +-#line 666 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 83: /* Term: '.' String */ ++#line 672 "src/parser.y" ++ { + (yyval.blk) = gen_index(gen_noop(), (yyvsp[0].blk)); + } +-#line 3073 "src/parser.c" /* yacc.c:1646 */ ++#line 3368 "src/parser.c" + break; + +- case 84: +-#line 669 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 84: /* Term: '.' error */ ++#line 675 "src/parser.y" ++ { + FAIL((yyloc), "try .[\"field\"] instead of .field for unusually named fields"); + (yyval.blk) = gen_noop(); + } +-#line 3082 "src/parser.c" /* yacc.c:1646 */ ++#line 3377 "src/parser.c" + break; + +- case 85: +-#line 673 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 85: /* Term: '.' IDENT error */ ++#line 679 "src/parser.y" ++ { + jv_free((yyvsp[-1].literal)); + FAIL((yyloc), "try .[\"field\"] instead of .field for unusually named fields"); + (yyval.blk) = gen_noop(); + } +-#line 3092 "src/parser.c" /* yacc.c:1646 */ ++#line 3387 "src/parser.c" + break; + +- case 86: +-#line 679 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 86: /* Term: Term '[' Exp ']' '?' */ ++#line 685 "src/parser.y" ++ { + (yyval.blk) = gen_index_opt((yyvsp[-4].blk), (yyvsp[-2].blk)); + } +-#line 3100 "src/parser.c" /* yacc.c:1646 */ ++#line 3395 "src/parser.c" + break; + +- case 87: +-#line 682 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 87: /* Term: Term '[' Exp ']' */ ++#line 688 "src/parser.y" ++ { + (yyval.blk) = gen_index((yyvsp[-3].blk), (yyvsp[-1].blk)); + } +-#line 3108 "src/parser.c" /* yacc.c:1646 */ ++#line 3403 "src/parser.c" + break; + +- case 88: +-#line 685 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 88: /* Term: Term '[' ']' '?' */ ++#line 691 "src/parser.y" ++ { + (yyval.blk) = block_join((yyvsp[-3].blk), gen_op_simple(EACH_OPT)); + } +-#line 3116 "src/parser.c" /* yacc.c:1646 */ ++#line 3411 "src/parser.c" + break; + +- case 89: +-#line 688 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 89: /* Term: Term '[' ']' */ ++#line 694 "src/parser.y" ++ { + (yyval.blk) = block_join((yyvsp[-2].blk), gen_op_simple(EACH)); + } +-#line 3124 "src/parser.c" /* yacc.c:1646 */ ++#line 3419 "src/parser.c" + break; + +- case 90: +-#line 691 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 90: /* Term: Term '[' Exp ':' Exp ']' '?' */ ++#line 697 "src/parser.y" ++ { + (yyval.blk) = gen_slice_index((yyvsp[-6].blk), (yyvsp[-4].blk), (yyvsp[-2].blk), INDEX_OPT); + } +-#line 3132 "src/parser.c" /* yacc.c:1646 */ ++#line 3427 "src/parser.c" + break; + +- case 91: +-#line 694 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 91: /* Term: Term '[' Exp ':' ']' '?' */ ++#line 700 "src/parser.y" ++ { + (yyval.blk) = gen_slice_index((yyvsp[-5].blk), (yyvsp[-3].blk), gen_const(jv_null()), INDEX_OPT); + } +-#line 3140 "src/parser.c" /* yacc.c:1646 */ ++#line 3435 "src/parser.c" + break; + +- case 92: +-#line 697 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 92: /* Term: Term '[' ':' Exp ']' '?' */ ++#line 703 "src/parser.y" ++ { + (yyval.blk) = gen_slice_index((yyvsp[-5].blk), gen_const(jv_null()), (yyvsp[-2].blk), INDEX_OPT); + } +-#line 3148 "src/parser.c" /* yacc.c:1646 */ ++#line 3443 "src/parser.c" + break; + +- case 93: +-#line 700 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 93: /* Term: Term '[' Exp ':' Exp ']' */ ++#line 706 "src/parser.y" ++ { + (yyval.blk) = gen_slice_index((yyvsp[-5].blk), (yyvsp[-3].blk), (yyvsp[-1].blk), INDEX); + } +-#line 3156 "src/parser.c" /* yacc.c:1646 */ ++#line 3451 "src/parser.c" + break; + +- case 94: +-#line 703 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 94: /* Term: Term '[' Exp ':' ']' */ ++#line 709 "src/parser.y" ++ { + (yyval.blk) = gen_slice_index((yyvsp[-4].blk), (yyvsp[-2].blk), gen_const(jv_null()), INDEX); + } +-#line 3164 "src/parser.c" /* yacc.c:1646 */ ++#line 3459 "src/parser.c" + break; + +- case 95: +-#line 706 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 95: /* Term: Term '[' ':' Exp ']' */ ++#line 712 "src/parser.y" ++ { + (yyval.blk) = gen_slice_index((yyvsp[-4].blk), gen_const(jv_null()), (yyvsp[-1].blk), INDEX); + } +-#line 3172 "src/parser.c" /* yacc.c:1646 */ ++#line 3467 "src/parser.c" + break; + +- case 96: +-#line 709 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 96: /* Term: LITERAL */ ++#line 715 "src/parser.y" ++ { + (yyval.blk) = gen_const((yyvsp[0].literal)); + } +-#line 3180 "src/parser.c" /* yacc.c:1646 */ ++#line 3475 "src/parser.c" + break; + +- case 97: +-#line 712 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 97: /* Term: String */ ++#line 718 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[0].blk); + } +-#line 3188 "src/parser.c" /* yacc.c:1646 */ ++#line 3483 "src/parser.c" + break; + +- case 98: +-#line 715 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 98: /* Term: FORMAT */ ++#line 721 "src/parser.y" ++ { + (yyval.blk) = gen_format(gen_noop(), (yyvsp[0].literal)); + } +-#line 3196 "src/parser.c" /* yacc.c:1646 */ ++#line 3491 "src/parser.c" + break; + +- case 99: +-#line 718 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 99: /* Term: '(' Exp ')' */ ++#line 724 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[-1].blk); + } +-#line 3204 "src/parser.c" /* yacc.c:1646 */ ++#line 3499 "src/parser.c" + break; + +- case 100: +-#line 721 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 100: /* Term: '[' Exp ']' */ ++#line 727 "src/parser.y" ++ { + (yyval.blk) = gen_collect((yyvsp[-1].blk)); + } +-#line 3212 "src/parser.c" /* yacc.c:1646 */ ++#line 3507 "src/parser.c" + break; + +- case 101: +-#line 724 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 101: /* Term: '[' ']' */ ++#line 730 "src/parser.y" ++ { + (yyval.blk) = gen_const(jv_array()); + } +-#line 3220 "src/parser.c" /* yacc.c:1646 */ ++#line 3515 "src/parser.c" + break; + +- case 102: +-#line 727 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 102: /* Term: '{' MkDict '}' */ ++#line 733 "src/parser.y" ++ { + block o = gen_const_object((yyvsp[-1].blk)); + if (o.first != NULL) + (yyval.blk) = o; + else + (yyval.blk) = BLOCK(gen_subexp(gen_const(jv_object())), (yyvsp[-1].blk), gen_op_simple(POP)); + } +-#line 3232 "src/parser.c" /* yacc.c:1646 */ ++#line 3527 "src/parser.c" + break; + +- case 103: +-#line 734 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 103: /* Term: '$' "__loc__" */ ++#line 740 "src/parser.y" ++ { + (yyval.blk) = gen_const(JV_OBJECT(jv_string("file"), jv_copy(locations->fname), + jv_string("line"), jv_number(locfile_get_line(locations, (yyloc).start) + 1))); + } +-#line 3241 "src/parser.c" /* yacc.c:1646 */ ++#line 3536 "src/parser.c" + break; + +- case 104: +-#line 738 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 104: /* Term: '$' IDENT */ ++#line 744 "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 3250 "src/parser.c" /* yacc.c:1646 */ ++#line 3545 "src/parser.c" + break; + +- case 105: +-#line 742 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 105: /* Term: IDENT */ ++#line 748 "src/parser.y" ++ { + const char *s = jv_string_value((yyvsp[0].literal)); + if (strcmp(s, "false") == 0) + (yyval.blk) = gen_const(jv_false()); +@@ -3276,199 +3558,199 @@ yyreduce: + (yyval.blk) = gen_location((yyloc), locations, gen_call(s, gen_noop())); + jv_free((yyvsp[0].literal)); + } +-#line 3267 "src/parser.c" /* yacc.c:1646 */ ++#line 3562 "src/parser.c" + break; + +- case 106: +-#line 754 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 106: /* Term: IDENT '(' Args ')' */ ++#line 760 "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 3277 "src/parser.c" /* yacc.c:1646 */ ++#line 3572 "src/parser.c" + break; + +- case 107: +-#line 759 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.blk) = gen_noop(); } +-#line 3283 "src/parser.c" /* yacc.c:1646 */ ++ case 107: /* Term: '(' error ')' */ ++#line 765 "src/parser.y" ++ { (yyval.blk) = gen_noop(); } ++#line 3578 "src/parser.c" + break; + +- case 108: +-#line 760 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.blk) = gen_noop(); } +-#line 3289 "src/parser.c" /* yacc.c:1646 */ ++ case 108: /* Term: '[' error ']' */ ++#line 766 "src/parser.y" ++ { (yyval.blk) = gen_noop(); } ++#line 3584 "src/parser.c" + break; + +- case 109: +-#line 761 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.blk) = (yyvsp[-3].blk); } +-#line 3295 "src/parser.c" /* yacc.c:1646 */ ++ case 109: /* Term: Term '[' error ']' */ ++#line 767 "src/parser.y" ++ { (yyval.blk) = (yyvsp[-3].blk); } ++#line 3590 "src/parser.c" + break; + +- case 110: +-#line 762 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.blk) = gen_noop(); } +-#line 3301 "src/parser.c" /* yacc.c:1646 */ ++ case 110: /* Term: '{' error '}' */ ++#line 768 "src/parser.y" ++ { (yyval.blk) = gen_noop(); } ++#line 3596 "src/parser.c" + break; + +- case 111: +-#line 765 "src/parser.y" /* yacc.c:1646 */ ++ case 111: /* Args: Arg */ ++#line 771 "src/parser.y" + { + (yyval.blk) = (yyvsp[0].blk); + } +-#line 3309 "src/parser.c" /* yacc.c:1646 */ ++#line 3604 "src/parser.c" + break; + +- case 112: +-#line 768 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 112: /* Args: Args ';' Arg */ ++#line 774 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 3317 "src/parser.c" /* yacc.c:1646 */ ++#line 3612 "src/parser.c" + break; + +- case 113: +-#line 773 "src/parser.y" /* yacc.c:1646 */ ++ case 113: /* Arg: Exp */ ++#line 779 "src/parser.y" + { + (yyval.blk) = gen_lambda((yyvsp[0].blk)); + } +-#line 3325 "src/parser.c" /* yacc.c:1646 */ ++#line 3620 "src/parser.c" + break; + +- case 114: +-#line 778 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 114: /* RepPatterns: RepPatterns "?//" Pattern */ ++#line 784 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[-2].blk), gen_destructure_alt((yyvsp[0].blk))); + } +-#line 3333 "src/parser.c" /* yacc.c:1646 */ ++#line 3628 "src/parser.c" + break; + +- case 115: +-#line 781 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 115: /* RepPatterns: Pattern */ ++#line 787 "src/parser.y" ++ { + (yyval.blk) = gen_destructure_alt((yyvsp[0].blk)); + } +-#line 3341 "src/parser.c" /* yacc.c:1646 */ ++#line 3636 "src/parser.c" + break; + +- case 116: +-#line 786 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 116: /* Patterns: RepPatterns "?//" Pattern */ ++#line 792 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 3349 "src/parser.c" /* yacc.c:1646 */ ++#line 3644 "src/parser.c" + break; + +- case 117: +-#line 789 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 117: /* Patterns: Pattern */ ++#line 795 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[0].blk); + } +-#line 3357 "src/parser.c" /* yacc.c:1646 */ ++#line 3652 "src/parser.c" + break; + +- case 118: +-#line 794 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 118: /* Pattern: '$' IDENT */ ++#line 800 "src/parser.y" ++ { + (yyval.blk) = gen_op_unbound(STOREV, jv_string_value((yyvsp[0].literal))); + jv_free((yyvsp[0].literal)); + } +-#line 3366 "src/parser.c" /* yacc.c:1646 */ ++#line 3661 "src/parser.c" + break; + +- case 119: +-#line 798 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 119: /* Pattern: '[' ArrayPats ']' */ ++#line 804 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[-1].blk), gen_op_simple(POP)); + } +-#line 3374 "src/parser.c" /* yacc.c:1646 */ ++#line 3669 "src/parser.c" + break; + +- case 120: +-#line 801 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 120: /* Pattern: '{' ObjPats '}' */ ++#line 807 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[-1].blk), gen_op_simple(POP)); + } +-#line 3382 "src/parser.c" /* yacc.c:1646 */ ++#line 3677 "src/parser.c" + break; + +- case 121: +-#line 806 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 121: /* ArrayPats: Pattern */ ++#line 812 "src/parser.y" ++ { + (yyval.blk) = gen_array_matcher(gen_noop(), (yyvsp[0].blk)); + } +-#line 3390 "src/parser.c" /* yacc.c:1646 */ ++#line 3685 "src/parser.c" + break; + +- case 122: +-#line 809 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 122: /* ArrayPats: ArrayPats ',' Pattern */ ++#line 815 "src/parser.y" ++ { + (yyval.blk) = gen_array_matcher((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 3398 "src/parser.c" /* yacc.c:1646 */ ++#line 3693 "src/parser.c" + break; + +- case 123: +-#line 814 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 123: /* ObjPats: ObjPat */ ++#line 820 "src/parser.y" ++ { + (yyval.blk) = (yyvsp[0].blk); + } +-#line 3406 "src/parser.c" /* yacc.c:1646 */ ++#line 3701 "src/parser.c" + break; + +- case 124: +-#line 817 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 124: /* ObjPats: ObjPats ',' ObjPat */ ++#line 823 "src/parser.y" ++ { + (yyval.blk) = BLOCK((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 3414 "src/parser.c" /* yacc.c:1646 */ ++#line 3709 "src/parser.c" + break; + +- case 125: +-#line 822 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 125: /* ObjPat: '$' IDENT */ ++#line 828 "src/parser.y" ++ { + (yyval.blk) = gen_object_matcher(gen_const((yyvsp[0].literal)), gen_op_unbound(STOREV, jv_string_value((yyvsp[0].literal)))); + } +-#line 3422 "src/parser.c" /* yacc.c:1646 */ ++#line 3717 "src/parser.c" + break; + +- case 126: +-#line 825 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 126: /* ObjPat: '$' IDENT ':' Pattern */ ++#line 831 "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 3430 "src/parser.c" /* yacc.c:1646 */ ++#line 3725 "src/parser.c" + break; + +- case 127: +-#line 828 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 127: /* ObjPat: IDENT ':' Pattern */ ++#line 834 "src/parser.y" ++ { + (yyval.blk) = gen_object_matcher(gen_const((yyvsp[-2].literal)), (yyvsp[0].blk)); + } +-#line 3438 "src/parser.c" /* yacc.c:1646 */ ++#line 3733 "src/parser.c" + break; + +- case 128: +-#line 831 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 128: /* ObjPat: Keyword ':' Pattern */ ++#line 837 "src/parser.y" ++ { + (yyval.blk) = gen_object_matcher(gen_const((yyvsp[-2].literal)), (yyvsp[0].blk)); + } +-#line 3446 "src/parser.c" /* yacc.c:1646 */ ++#line 3741 "src/parser.c" + break; + +- case 129: +-#line 834 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 129: /* ObjPat: String ':' Pattern */ ++#line 840 "src/parser.y" ++ { + (yyval.blk) = gen_object_matcher((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 3454 "src/parser.c" /* yacc.c:1646 */ ++#line 3749 "src/parser.c" + break; + +- case 130: +-#line 837 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 130: /* ObjPat: '(' Exp ')' ':' Pattern */ ++#line 843 "src/parser.y" ++ { + jv msg = check_object_key((yyvsp[-3].blk)); + if (jv_is_valid(msg)) { + FAIL((yyloc), jv_string_value(msg)); +@@ -3476,250 +3758,250 @@ yyreduce: + jv_free(msg); + (yyval.blk) = gen_object_matcher((yyvsp[-3].blk), (yyvsp[0].blk)); + } +-#line 3467 "src/parser.c" /* yacc.c:1646 */ ++#line 3762 "src/parser.c" + break; + +- case 131: +-#line 845 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 131: /* ObjPat: error ':' Pattern */ ++#line 851 "src/parser.y" ++ { + FAIL((yyloc), "May need parentheses around object key expression"); + (yyval.blk) = (yyvsp[0].blk); + } +-#line 3476 "src/parser.c" /* yacc.c:1646 */ ++#line 3771 "src/parser.c" + break; + +- case 132: +-#line 851 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 132: /* Keyword: "as" */ ++#line 857 "src/parser.y" ++ { + (yyval.literal) = jv_string("as"); + } +-#line 3484 "src/parser.c" /* yacc.c:1646 */ ++#line 3779 "src/parser.c" + break; + +- case 133: +-#line 854 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 133: /* Keyword: "def" */ ++#line 860 "src/parser.y" ++ { + (yyval.literal) = jv_string("def"); + } +-#line 3492 "src/parser.c" /* yacc.c:1646 */ ++#line 3787 "src/parser.c" + break; + +- case 134: +-#line 857 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 134: /* Keyword: "module" */ ++#line 863 "src/parser.y" ++ { + (yyval.literal) = jv_string("module"); + } +-#line 3500 "src/parser.c" /* yacc.c:1646 */ ++#line 3795 "src/parser.c" + break; + +- case 135: +-#line 860 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 135: /* Keyword: "import" */ ++#line 866 "src/parser.y" ++ { + (yyval.literal) = jv_string("import"); + } +-#line 3508 "src/parser.c" /* yacc.c:1646 */ ++#line 3803 "src/parser.c" + break; + +- case 136: +-#line 863 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 136: /* Keyword: "include" */ ++#line 869 "src/parser.y" ++ { + (yyval.literal) = jv_string("include"); + } +-#line 3516 "src/parser.c" /* yacc.c:1646 */ ++#line 3811 "src/parser.c" + break; + +- case 137: +-#line 866 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 137: /* Keyword: "if" */ ++#line 872 "src/parser.y" ++ { + (yyval.literal) = jv_string("if"); + } +-#line 3524 "src/parser.c" /* yacc.c:1646 */ ++#line 3819 "src/parser.c" + break; + +- case 138: +-#line 869 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 138: /* Keyword: "then" */ ++#line 875 "src/parser.y" ++ { + (yyval.literal) = jv_string("then"); + } +-#line 3532 "src/parser.c" /* yacc.c:1646 */ ++#line 3827 "src/parser.c" + break; + +- case 139: +-#line 872 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 139: /* Keyword: "else" */ ++#line 878 "src/parser.y" ++ { + (yyval.literal) = jv_string("else"); + } +-#line 3540 "src/parser.c" /* yacc.c:1646 */ ++#line 3835 "src/parser.c" + break; + +- case 140: +-#line 875 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 140: /* Keyword: "elif" */ ++#line 881 "src/parser.y" ++ { + (yyval.literal) = jv_string("elif"); + } +-#line 3548 "src/parser.c" /* yacc.c:1646 */ ++#line 3843 "src/parser.c" + break; + +- case 141: +-#line 878 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 141: /* Keyword: "reduce" */ ++#line 884 "src/parser.y" ++ { + (yyval.literal) = jv_string("reduce"); + } +-#line 3556 "src/parser.c" /* yacc.c:1646 */ ++#line 3851 "src/parser.c" + break; + +- case 142: +-#line 881 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 142: /* Keyword: "foreach" */ ++#line 887 "src/parser.y" ++ { + (yyval.literal) = jv_string("foreach"); + } +-#line 3564 "src/parser.c" /* yacc.c:1646 */ ++#line 3859 "src/parser.c" + break; + +- case 143: +-#line 884 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 143: /* Keyword: "end" */ ++#line 890 "src/parser.y" ++ { + (yyval.literal) = jv_string("end"); + } +-#line 3572 "src/parser.c" /* yacc.c:1646 */ ++#line 3867 "src/parser.c" + break; + +- case 144: +-#line 887 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 144: /* Keyword: "and" */ ++#line 893 "src/parser.y" ++ { + (yyval.literal) = jv_string("and"); + } +-#line 3580 "src/parser.c" /* yacc.c:1646 */ ++#line 3875 "src/parser.c" + break; + +- case 145: +-#line 890 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 145: /* Keyword: "or" */ ++#line 896 "src/parser.y" ++ { + (yyval.literal) = jv_string("or"); + } +-#line 3588 "src/parser.c" /* yacc.c:1646 */ ++#line 3883 "src/parser.c" + break; + +- case 146: +-#line 893 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 146: /* Keyword: "try" */ ++#line 899 "src/parser.y" ++ { + (yyval.literal) = jv_string("try"); + } +-#line 3596 "src/parser.c" /* yacc.c:1646 */ ++#line 3891 "src/parser.c" + break; + +- case 147: +-#line 896 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 147: /* Keyword: "catch" */ ++#line 902 "src/parser.y" ++ { + (yyval.literal) = jv_string("catch"); + } +-#line 3604 "src/parser.c" /* yacc.c:1646 */ ++#line 3899 "src/parser.c" + break; + +- case 148: +-#line 899 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 148: /* Keyword: "label" */ ++#line 905 "src/parser.y" ++ { + (yyval.literal) = jv_string("label"); + } +-#line 3612 "src/parser.c" /* yacc.c:1646 */ ++#line 3907 "src/parser.c" + break; + +- case 149: +-#line 902 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 149: /* Keyword: "break" */ ++#line 908 "src/parser.y" ++ { + (yyval.literal) = jv_string("break"); + } +-#line 3620 "src/parser.c" /* yacc.c:1646 */ ++#line 3915 "src/parser.c" + break; + +- case 150: +-#line 905 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 150: /* Keyword: "__loc__" */ ++#line 911 "src/parser.y" ++ { + (yyval.literal) = jv_string("__loc__"); + } +-#line 3628 "src/parser.c" /* yacc.c:1646 */ ++#line 3923 "src/parser.c" + break; + +- case 151: +-#line 910 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 151: /* MkDict: %empty */ ++#line 916 "src/parser.y" ++ { + (yyval.blk)=gen_noop(); + } +-#line 3636 "src/parser.c" /* yacc.c:1646 */ ++#line 3931 "src/parser.c" + break; + +- case 152: +-#line 913 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.blk) = (yyvsp[0].blk); } +-#line 3642 "src/parser.c" /* yacc.c:1646 */ ++ case 152: /* MkDict: MkDictPair */ ++#line 919 "src/parser.y" ++ { (yyval.blk) = (yyvsp[0].blk); } ++#line 3937 "src/parser.c" + break; + +- case 153: +-#line 914 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.blk)=block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } +-#line 3648 "src/parser.c" /* yacc.c:1646 */ ++ case 153: /* MkDict: MkDictPair ',' MkDict */ ++#line 920 "src/parser.y" ++ { (yyval.blk)=block_join((yyvsp[-2].blk), (yyvsp[0].blk)); } ++#line 3943 "src/parser.c" + break; + +- case 154: +-#line 915 "src/parser.y" /* yacc.c:1646 */ +- { (yyval.blk) = (yyvsp[0].blk); } +-#line 3654 "src/parser.c" /* yacc.c:1646 */ ++ case 154: /* MkDict: error ',' MkDict */ ++#line 921 "src/parser.y" ++ { (yyval.blk) = (yyvsp[0].blk); } ++#line 3949 "src/parser.c" + break; + +- case 155: +-#line 918 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 155: /* MkDictPair: IDENT ':' ExpD */ ++#line 924 "src/parser.y" ++ { + (yyval.blk) = gen_dictpair(gen_const((yyvsp[-2].literal)), (yyvsp[0].blk)); + } +-#line 3662 "src/parser.c" /* yacc.c:1646 */ ++#line 3957 "src/parser.c" + break; + +- case 156: +-#line 921 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 156: /* MkDictPair: Keyword ':' ExpD */ ++#line 927 "src/parser.y" ++ { + (yyval.blk) = gen_dictpair(gen_const((yyvsp[-2].literal)), (yyvsp[0].blk)); + } +-#line 3670 "src/parser.c" /* yacc.c:1646 */ ++#line 3965 "src/parser.c" + break; + +- case 157: +-#line 924 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 157: /* MkDictPair: String ':' ExpD */ ++#line 930 "src/parser.y" ++ { + (yyval.blk) = gen_dictpair((yyvsp[-2].blk), (yyvsp[0].blk)); + } +-#line 3678 "src/parser.c" /* yacc.c:1646 */ ++#line 3973 "src/parser.c" + break; + +- case 158: +-#line 927 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 158: /* MkDictPair: String */ ++#line 933 "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 3687 "src/parser.c" /* yacc.c:1646 */ ++#line 3982 "src/parser.c" + break; + +- case 159: +-#line 931 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 159: /* MkDictPair: '$' IDENT */ ++#line 937 "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 3696 "src/parser.c" /* yacc.c:1646 */ ++#line 3991 "src/parser.c" + break; + +- case 160: +-#line 935 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 160: /* MkDictPair: IDENT */ ++#line 941 "src/parser.y" ++ { + (yyval.blk) = gen_dictpair(gen_const(jv_copy((yyvsp[0].literal))), + gen_index(gen_noop(), gen_const((yyvsp[0].literal)))); + } +-#line 3705 "src/parser.c" /* yacc.c:1646 */ ++#line 4000 "src/parser.c" + break; + +- case 161: +-#line 939 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 161: /* MkDictPair: '(' Exp ')' ':' ExpD */ ++#line 945 "src/parser.y" ++ { + jv msg = check_object_key((yyvsp[-3].blk)); + if (jv_is_valid(msg)) { + FAIL((yyloc), jv_string_value(msg)); +@@ -3727,20 +4009,21 @@ yyreduce: + jv_free(msg); + (yyval.blk) = gen_dictpair((yyvsp[-3].blk), (yyvsp[0].blk)); + } +-#line 3718 "src/parser.c" /* yacc.c:1646 */ ++#line 4013 "src/parser.c" + break; + +- case 162: +-#line 947 "src/parser.y" /* yacc.c:1646 */ +- { ++ case 162: /* MkDictPair: error ':' ExpD */ ++#line 953 "src/parser.y" ++ { + FAIL((yyloc), "May need parentheses around object key expression"); + (yyval.blk) = (yyvsp[0].blk); + } +-#line 3727 "src/parser.c" /* yacc.c:1646 */ ++#line 4022 "src/parser.c" + break; + + +-#line 3731 "src/parser.c" /* yacc.c:1646 */ ++#line 4026 "src/parser.c" ++ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires +@@ -3754,11 +4037,10 @@ yyreduce: + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); ++ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + *++yylsp = yyloc; +@@ -3783,50 +4065,45 @@ yyreduce: + yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ +- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); +- ++ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (&yylloc, answer, errors, locations, lexer_param_ptr, YY_("syntax error")); +-#else +-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ +- yyssp, yytoken) + { ++ yypcontext_t yyctx ++ = {yyssp, yytoken, &yylloc}; + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; +- yysyntax_error_status = YYSYNTAX_ERROR; ++ yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + if (yysyntax_error_status == 0) + yymsgp = yymsg; +- else if (yysyntax_error_status == 1) ++ else if (yysyntax_error_status == -1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); +- if (!yymsg) ++ yymsg = YY_CAST (char *, ++ YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); ++ if (yymsg) + { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- yysyntax_error_status = 2; ++ yysyntax_error_status ++ = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); ++ yymsgp = yymsg; + } + else + { +- yysyntax_error_status = YYSYNTAX_ERROR; +- yymsgp = yymsg; ++ yymsg = yymsgbuf; ++ yymsg_alloc = sizeof yymsgbuf; ++ yysyntax_error_status = YYENOMEM; + } + } + yyerror (&yylloc, answer, errors, locations, lexer_param_ptr, yymsgp); +- if (yysyntax_error_status == 2) +- goto yyexhaustedlab; ++ if (yysyntax_error_status == YYENOMEM) ++ YYNOMEM; + } +-# undef YYSYNTAX_ERROR +-#endif + } + + yyerror_range[1] = yylloc; +- + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an +@@ -3859,6 +4136,7 @@ yyerrorlab: + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; ++ ++yynerrs; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ +@@ -3875,13 +4153,14 @@ yyerrorlab: + yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + ++ /* Pop stack until we find a state that shifts the error token. */ + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ yyn += YYSYMBOL_YYerror; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) + { + yyn = yytable[yyn]; + if (0 < yyn) +@@ -3895,7 +4174,7 @@ yyerrlab1: + + yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", +- yystos[yystate], yyvsp, yylsp, answer, errors, locations, lexer_param_ptr); ++ YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, answer, errors, locations, lexer_param_ptr); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); +@@ -3906,13 +4185,11 @@ yyerrlab1: + YY_IGNORE_MAYBE_UNINITIALIZED_END + + yyerror_range[2] = yylloc; +- /* Using YYLLOC is tempting, but would change the location of +- the lookahead. YYLOC is available though. */ +- YYLLOC_DEFAULT (yyloc, yyerror_range, 2); +- *++yylsp = yyloc; ++ ++yylsp; ++ YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); + + /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); ++ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; +@@ -3923,7 +4200,7 @@ yyerrlab1: + `-------------------------------------*/ + yyacceptlab: + yyresult = 0; +- goto yyreturn; ++ goto yyreturnlab; + + + /*-----------------------------------. +@@ -3931,24 +4208,22 @@ yyacceptlab: + `-----------------------------------*/ + yyabortlab: + yyresult = 1; +- goto yyreturn; ++ goto yyreturnlab; + + +-#if !defined yyoverflow || YYERROR_VERBOSE +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ ++/*-----------------------------------------------------------. ++| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | ++`-----------------------------------------------------------*/ + yyexhaustedlab: + yyerror (&yylloc, answer, errors, locations, lexer_param_ptr, YY_("memory exhausted")); + yyresult = 2; +- /* Fall through. */ +-#endif ++ goto yyreturnlab; + + +-/*-----------------------------------------------------. +-| yyreturn -- parsing is finished, return the result. | +-`-----------------------------------------------------*/ +-yyreturn: ++/*----------------------------------------------------------. ++| yyreturnlab -- parsing is finished, clean up and return. | ++`----------------------------------------------------------*/ ++yyreturnlab: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at +@@ -3964,20 +4239,19 @@ yyreturn: + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp, yylsp, answer, errors, locations, lexer_param_ptr); ++ YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, answer, errors, locations, lexer_param_ptr); + YYPOPSTACK (1); + } + #ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); + #endif +-#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +-#endif + return yyresult; + } +-#line 951 "src/parser.y" /* yacc.c:1906 */ ++ ++#line 957 "src/parser.y" + + + int jq_parse(struct locfile* locations, block* answer) { +diff -up jq-1.6/src/parser.y.orig jq-1.6/src/parser.y +--- jq-1.6/src/parser.y.orig 2023-10-13 13:36:10.305515082 +0200 ++++ jq-1.6/src/parser.y 2023-10-13 13:36:36.110510379 +0200 +@@ -337,7 +337,7 @@ FuncDefs: + $$ = gen_noop(); + } | + FuncDef FuncDefs { +- $$ = block_bind($1, $2, OP_IS_CALL_PSEUDO); ++ $$ = block_join($1, $2); + } + + Exp: diff --git a/jq.spec b/jq.spec index 95f25ae..0be414c 100644 --- a/jq.spec +++ b/jq.spec @@ -1,6 +1,6 @@ Name: jq Version: 1.6 -Release: 7%{?dist} +Release: 8%{?dist} Summary: Command-line JSON processor License: MIT and ASL 2.0 and CC-BY and GPLv3 @@ -10,6 +10,7 @@ Patch0: 0000-jq-decimal-literal-number.patch Patch1: 0001-iterration-problem-for-non-decimal-string.patch Patch2: 0002-add-mantest.patch Patch3: 0003-fix-pthread-segfault.patch +Patch4: 0004-make-jq-fast.patch BuildRequires: flex BuildRequires: bison @@ -98,6 +99,10 @@ make check %changelog +* Fri Oct 13 2023 Tomas Halman - 1.6-8 +- Make jq 1.6 fast +- Resolves: RHEL-5052 + * Tue Mar 14 2023 Tomas Halman - 1.6-7 - Fix jq segfault when used in threads - Resolves: rhbz#2092160