about summary refs log tree commit diff
path: root/src/comp/front
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-02-01 16:23:48 -0800
committerGraydon Hoare <graydon@mozilla.com>2011-02-01 16:23:48 -0800
commit70bf54bcac587c0bc8a3a593bda75115e4c23aa8 (patch)
treefc04fe2f7bc4fa1dd902689e4db20e193bec9097 /src/comp/front
parenteb16942c1de42c2f30f7e0eb0ff69371a167f7bd (diff)
downloadrust-70bf54bcac587c0bc8a3a593bda75115e4c23aa8.tar.gz
rust-70bf54bcac587c0bc8a3a593bda75115e4c23aa8.zip
Implement 'else if'
Diffstat (limited to 'src/comp/front')
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/parser.rs42
2 files changed, 33 insertions, 11 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 9fddb66f397..be47615a502 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -149,7 +149,7 @@ tag expr_ {
     expr_unary(unop, @expr, ann);
     expr_lit(@lit, ann);
     expr_cast(@expr, @ty, ann);
-    expr_if(@expr, block, option.t[block], ann);
+    expr_if(@expr, block, vec[tup(@expr, block)], option.t[block], ann);
     expr_while(@expr, block, ann);
     expr_for(@decl, @expr, block, ann);
     expr_do_while(block, @expr, ann);
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index bef37a3cc7e..0c90df5c783 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -891,18 +891,40 @@ impure fn parse_if_expr(parser p) -> @ast.expr {
     auto cond = parse_expr(p);
     expect(p, token.RPAREN);
     auto thn = parse_block(p);
-    let option.t[ast.block] els = none[ast.block];
     hi = thn.span;
-    alt (p.peek()) {
-        case (token.ELSE) {
-            p.bump();
-            auto eblk = parse_block(p);
-            els = some(eblk);
-            hi = eblk.span;
+
+    let vec[tup(@ast.expr, ast.block)] elifs = vec();
+    let option.t[ast.block] els = none[ast.block];
+    let bool parsing_elses = true;
+    while (parsing_elses) {
+        alt (p.peek()) {
+            case (token.ELSE) {
+                expect(p, token.ELSE);
+                alt (p.peek()) {
+                    case (token.IF) {
+                        expect(p, token.IF);
+                        expect(p, token.LPAREN);
+                        auto elifcond = parse_expr(p);
+                        expect(p, token.RPAREN);
+                        auto elifthn = parse_block(p);
+                        elifs += tup(elifcond, elifthn);
+                        hi = elifthn.span;
+                    }
+                    case (_) {
+                        auto eblk = parse_block(p);
+                        els = some(eblk);
+                        hi = eblk.span;
+                        parsing_elses = false;
+                    }
+                }
+            }
+            case (_) {
+                parsing_elses = false;
+            }
         }
-        case (_) { /* fall through */ }
     }
-    ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none));
+
+    ret @spanned(lo, hi, ast.expr_if(cond, thn, elifs, els, ast.ann_none));
 }
 
 impure fn parse_head_local(parser p) -> @ast.decl {
@@ -1331,7 +1353,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
                 case (ast.expr_unary(_,_,_))    { ret true; }
                 case (ast.expr_lit(_,_))        { ret true; }
                 case (ast.expr_cast(_,_,_))     { ret true; }
-                case (ast.expr_if(_,_,_,_))     { ret false; }
+                case (ast.expr_if(_,_,_,_,_))   { ret false; }
                 case (ast.expr_for(_,_,_,_))    { ret false; }
                 case (ast.expr_while(_,_,_))    { ret false; }
                 case (ast.expr_do_while(_,_,_)) { ret false; }