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:
Nicolas Williams committed 2014-12-30 11:42:45 -06:00
1 parent cbfc0d6130
commit 7dc34b92af
11 files changed
+225 -33

No files matched your search

+43 -1
View File
@@ -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));
} |