Add label $name | EXP; fix break
This is to fix the problem where `break` is dynamic, not lexical.
With this it should be possible to do this sort of thing:
label $break | inputs | if ... then $break|error else . end
This is a backwards-incompatible change for master, but the previous
`break` hadn't shipped yet.
Still needed:
- testing
This commit is contained in:
1 parent
cbfc0d6130
commit
7dc34b92af
11 files changed
+225
-33
No files matched your search
@@ -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));
|
||||
} |
|
||||
|
||||
Reference in new issue
Block a user