diff options
Diffstat (limited to 'parser.y')
-rw-r--r-- | parser.y | 44 |
1 files changed, 43 insertions, 1 deletions
@@ -70,6 +70,10 @@ struct lexer_param; %token OR "or" %token TRY "try" %token CATCH "catch" +%token LABEL "label" +%token BREAK "break" +%token BREAK2 "break2" +%token BREAK3 "break3" %token SETPIPE "|=" %token SETPLUS "+=" %token SETMINUS "-=" @@ -149,6 +153,8 @@ int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors, return tok; } +static unsigned int next_label = 0; + static block gen_dictpair(block k, block v) { return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT)); } @@ -335,7 +341,7 @@ Term "as" '$' IDENT '|' Exp { "try" Exp "catch" Exp { //$$ = BLOCK(gen_op_target(FORK_OPT, $2), $2, $4); - $$ = gen_try($2, $4); + $$ = gen_try($2, gen_try_handler($4)); } | "try" Exp { //$$ = BLOCK(gen_op_target(FORK_OPT, $2), $2, gen_op_simple(BACKTRACK)); @@ -346,6 +352,19 @@ Term "as" '$' IDENT '|' Exp { $$ = $2; } | +"label" '|' Exp { + jv v = jv_string_fmt("*anonlabel%u", next_label++); + $$ = gen_location(@$, locations, gen_label(jv_string_value(v), $3)); + jv_free(v); +} | + +"label" '$' IDENT '|' Exp { + jv v = jv_string_fmt("*label-%s", jv_string_value($3)); + $$ = gen_location(@$, locations, gen_label(jv_string_value(v), $5)); + jv_free($3); + jv_free(v); +} | + // This rule conflicts with all the other rules using the '?' operator. // It doesn't matter which bison prefers: all of them result in the same // syntax and semantics, but the more specific rules optimize better @@ -570,6 +589,29 @@ Term: REC { $$ = gen_call("recurse", gen_noop()); } | +BREAK { + $$ = gen_location(@$, locations, + BLOCK(gen_op_unbound(LOADV, "*1"), // impossible symbol + gen_call("error", gen_noop()))); +} | +BREAK2 { + $$ = gen_location(@$, locations, + BLOCK(gen_op_unbound(LOADV, "*2"), // impossible symbol + gen_call("error", gen_noop()))); +} | +BREAK3 { + $$ = gen_location(@$, locations, + BLOCK(gen_op_unbound(LOADV, "*3"), // impossible symbol + gen_call("error", gen_noop()))); +} | +BREAK '$' IDENT { + jv v = jv_string_fmt("*label-%s", jv_string_value($3)); // impossible symbol + $$ = gen_location(@$, locations, + BLOCK(gen_op_unbound(LOADV, jv_string_value(v)), + gen_call("error", gen_noop()))); + jv_free(v); + jv_free($3); +} | Term FIELD '?' { $$ = gen_index_opt($1, gen_const($2)); } | |