summaryrefslogtreecommitdiffstats
path: root/parser.y
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-03-22 17:10:09 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-03-22 17:10:09 -0700
commit6e06daed77cb0d3f34643975b50026e3e3699966 (patch)
tree5080fa4538b3a47238a576456caf96b6267a2813 /parser.y
parentf6e5d12ff65b4b500efef9a5494997130f98cad3 (diff)
downloadtxr-6e06daed77cb0d3f34643975b50026e3e3699966.tar.gz
txr-6e06daed77cb0d3f34643975b50026e3e3699966.tar.bz2
txr-6e06daed77cb0d3f34643975b50026e3e3699966.zip
New semantics for @(if) directive.
* eval.h (if_s): Declared. * match.c (v_if): New static function. (dir_tables_init): Register v_if in v_directive_table under if symbol. * parser.y (IF): Token assigned to <lineno> type. (if_clause, elif_clauses_opt, else_clause_opt): New syntactic representation, understood by v_if. * txr.1: Documented if semantics more precisely, dropped the text about it being syntactic sugar for a cases with require, added compatibility note.
Diffstat (limited to 'parser.y')
-rw-r--r--parser.y43
1 files changed, 33 insertions, 10 deletions
diff --git a/parser.y b/parser.y
index 3849e86b..e4a1552e 100644
--- a/parser.y
+++ b/parser.y
@@ -100,7 +100,7 @@ int yyparse(scanner_t *, parser_t *);
%token <lineno> ALL SOME NONE MAYBE CASES BLOCK CHOOSE GATHER
%token <lineno> AND OR END COLLECT
%token <lineno> UNTIL COLL OUTPUT REPEAT REP SINGLE FIRST LAST EMPTY
-%token <lineno> MOD MODLAST DEFINE TRY CATCH FINALLY
+%token <lineno> MOD MODLAST DEFINE TRY CATCH FINALLY IF
%token <lineno> ERRTOK /* deliberately not used in grammar */
%token <lineno> HASH_BACKSLASH HASH_SLASH DOTDOT HASH_H HASH_S HASH_R
%token <lineno> WORDS WSPLICE QWORDS QWSPLICE
@@ -358,25 +358,48 @@ if_clause : IF exprs_opt ')'
newl clauses_opt
elif_clauses_opt
else_clause_opt
- END newl { val req = rlcp(cons(require_s, $2), $2);
- val iff = rlcp(cons(cons(cons(req, nil), $5), nil), $2);
- val elifs = $6;
- val els = cons($7, nil);
- val cases = nappend2(nappend2(iff, elifs), els);
- $$ = list(cases_s, cases, nao); }
+ END newl { if (opt_compat && opt_compat <= 136)
+ { val req = rlcp(cons(require_s, $2), $2);
+ val iff = rlcp(cons(cons(cons(req, nil), $5), nil), $2);
+ val elifs = $6;
+ val els = cons($7, nil);
+ val cases = nappend2(nappend2(iff, elifs), els);
+ $$ = list(cases_s, cases, nao); }
+ else
+ { val expr = car($2);
+ val ifs = $5;
+ val branch = cons(cons(expr, ifs), nil);
+ val elifs = $6;
+ val els = $7;
+ if (cdr($2))
+ yyerr("extra expression in if");
+ $$ = cons(if_s,
+ nappend2(branch, nappend2(elifs, els)));
+ rl($$, num($1)); } }
| IF exprs_opt ')'
newl error { $$ = nil; yybadtok(yychar, lit("if clause")); }
;
elif_clauses_opt : ELIF exprs_opt ')' newl
clauses_opt
- elif_clauses_opt { val req = rlcp(cons(require_s, $2), $2);
- $$ = cons(cons(cons(req, nil), $5), $6); }
+ elif_clauses_opt { if (opt_compat && opt_compat <= 136)
+ { val req = rlcp(cons(require_s, $2), $2);
+ $$ = cons(cons(cons(req, nil), $5), $6); }
+ else
+ { val expr = car($2);
+ val elifs = $5;
+ val branch = cons(cons(expr, elifs), nil);
+ if (cdr($2))
+ yyerr("extra expression in elif");
+ $$ = nappend2(branch, $6); } }
| { $$ = nil; }
;
else_clause_opt : ELSE newl
- clauses_opt { $$ = $3; }
+ clauses_opt { if (opt_compat && opt_compat <= 136)
+ { $$ = $3; }
+ else
+ { $$ = cons(cons(t, $3), nil); } }
| { $$ = nil; }
;