summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorKevin Ballard <kevin@sb.org>2014-08-24 18:04:29 -0700
committerJakub Wieczorek <jakub@jakub.cc>2014-09-30 18:54:02 +0200
commit5d8cfd53b513d999ffff22f17e3066a30a8ed949 (patch)
treeb4eb0d6572d11b9e33959534f3389366011b8327 /src/libsyntax/parse/parser.rs
parent38015eeb7010e5954a1bc60fddc1214a5f359627 (diff)
downloadrust-5d8cfd53b513d999ffff22f17e3066a30a8ed949.tar.gz
rust-5d8cfd53b513d999ffff22f17e3066a30a8ed949.zip
Teach libsyntax about `if let`
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 415ff6a4097..d4ba81c737b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -23,7 +23,7 @@ use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, Explicit
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
 use ast::{ExprBreak, ExprCall, ExprCast};
-use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex, ExprSlice};
+use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIfLet, ExprIndex, ExprSlice};
 use ast::{ExprLit, ExprLoop, ExprMac};
 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn};
@@ -576,13 +576,10 @@ impl<'a> Parser<'a> {
     /// If the next token is the given keyword, eat it and return
     /// true. Otherwise, return false.
     pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
-        match self.token {
-            token::IDENT(sid, false) if kw.to_name() == sid.name => {
-                self.bump();
-                true
-            }
-            _ => false
-        }
+        if self.is_keyword(kw) {
+            self.bump();
+            true
+        } else { false }
     }
 
     /// If the given word is not a keyword, signal an error.
@@ -2860,8 +2857,11 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse an 'if' expression ('if' token already eaten)
+    /// Parse an 'if' or 'if let' expression ('if' token already eaten)
     pub fn parse_if_expr(&mut self) -> P<Expr> {
+        if self.is_keyword(keywords::Let) {
+            return self.parse_if_let_expr();
+        }
         let lo = self.last_span.lo;
         let cond = self.parse_expr_res(RestrictionNoStructLiteral);
         let thn = self.parse_block();
@@ -2875,6 +2875,23 @@ impl<'a> Parser<'a> {
         self.mk_expr(lo, hi, ExprIf(cond, thn, els))
     }
 
+    /// Parse an 'if let' expression ('if' token already eaten)
+    pub fn parse_if_let_expr(&mut self) -> P<Expr> {
+        let lo = self.last_span.lo;
+        self.expect_keyword(keywords::Let);
+        let pat = self.parse_pat();
+        self.expect(&token::EQ);
+        let expr = self.parse_expr_res(RestrictionNoStructLiteral);
+        let thn = self.parse_block();
+        let (hi, els) = if self.eat_keyword(keywords::Else) {
+            let expr = self.parse_else_expr();
+            (expr.span.hi, Some(expr))
+        } else {
+            (thn.span.hi, None)
+        };
+        self.mk_expr(lo, hi, ExprIfLet(pat, expr, thn, els))
+    }
+
     // `|args| expr`
     pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause)
                              -> P<Expr> {