about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorGábor Lehel <glaebhoerl@gmail.com>2014-03-16 22:46:04 +0100
committerSean McArthur <sean.monstar@gmail.com>2014-03-31 22:42:31 -0700
commitbe673e77e75ece1611cdcf7b1b784ccd53cc9011 (patch)
tree83f60a5f11809e936f289734e924d6918880d832 /src/libsyntax/parse
parentb8ef9fd9c9f642ce7b8aed82782a1ed745d08d64 (diff)
downloadrust-be673e77e75ece1611cdcf7b1b784ccd53cc9011.tar.gz
rust-be673e77e75ece1611cdcf7b1b784ccd53cc9011.zip
syntax: allow stmt/expr macro invocations to be delimited by [].
this is useful for macros like vec! which construct containers
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs38
-rw-r--r--src/libsyntax/parse/token.rs18
2 files changed, 22 insertions, 34 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 2d0c4ca488e..83cc92d4828 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1881,12 +1881,9 @@ impl<'a> Parser<'a> {
             if self.token == token::NOT {
                 // MACRO INVOCATION expression
                 self.bump();
-                match self.token {
-                    token::LPAREN | token::LBRACE => {}
-                    _ => self.fatal("expected open delimiter")
-                };
 
-                let ket = token::flip_delimiter(&self.token);
+                let ket = token::close_delimiter_for(&self.token)
+                                .unwrap_or_else(|| self.fatal("expected open delimiter"));
                 self.bump();
 
                 let tts = self.parse_seq_to_end(&ket,
@@ -2109,8 +2106,8 @@ impl<'a> Parser<'a> {
             TTTok(p.span, p.bump_and_get())
         }
 
-        match self.token {
-            token::EOF => {
+        match (&self.token, token::close_delimiter_for(&self.token)) {
+            (&token::EOF, _) => {
                 let open_braces = self.open_braces.clone();
                 for sp in open_braces.iter() {
                     self.span_note(*sp, "Did you mean to close this delimiter?");
@@ -2119,9 +2116,7 @@ impl<'a> Parser<'a> {
                 // if we give it one
                 self.fatal("this file contains an un-closed delimiter ");
             }
-            token::LPAREN | token::LBRACE | token::LBRACKET => {
-                let close_delim = token::flip_delimiter(&self.token);
-
+            (_, Some(close_delim)) => {
                 // Parse the open delimiter.
                 self.open_braces.push(self.span);
                 let mut result = vec!(parse_any_tt_tok(self));
@@ -2157,13 +2152,12 @@ impl<'a> Parser<'a> {
         // the interpolation of Matcher's
         maybe_whole!(self, NtMatchers);
         let mut name_idx = 0u;
-        match self.token {
-            token::LBRACE | token::LPAREN | token::LBRACKET => {
-                let other_delimiter = token::flip_delimiter(&self.token);
+        match token::close_delimiter_for(&self.token) {
+            Some(other_delimiter) => {
                 self.bump();
                 self.parse_matcher_subseq_upto(&mut name_idx, &other_delimiter)
             }
-            _ => self.fatal("expected open delimiter")
+            None => self.fatal("expected open delimiter")
         }
     }
 
@@ -3138,7 +3132,7 @@ impl<'a> Parser<'a> {
             let pth = self.parse_path(NoTypesAllowed).path;
             self.bump();
 
-            let id = if self.token == token::LPAREN || self.token == token::LBRACE {
+            let id = if token::close_delimiter_for(&self.token).is_some() {
                 token::special_idents::invalid // no special identifier
             } else {
                 self.parse_ident()
@@ -3147,10 +3141,9 @@ impl<'a> Parser<'a> {
             // check that we're pointing at delimiters (need to check
             // again after the `if`, because of `parse_ident`
             // consuming more tokens).
-            let (bra, ket) = match self.token {
-                token::LPAREN => (token::LPAREN, token::RPAREN),
-                token::LBRACE => (token::LBRACE, token::RBRACE),
-                _ => {
+            let (bra, ket) = match token::close_delimiter_for(&self.token) {
+                Some(ket) => (self.token.clone(), ket),
+                None      => {
                     // we only expect an ident if we didn't parse one
                     // above.
                     let ident_str = if id == token::special_idents::invalid {
@@ -4724,15 +4717,14 @@ impl<'a> Parser<'a> {
                 token::special_idents::invalid // no special identifier
             };
             // eat a matched-delimiter token tree:
-            let tts = match self.token {
-                token::LPAREN | token::LBRACE => {
-                    let ket = token::flip_delimiter(&self.token);
+            let tts = match token::close_delimiter_for(&self.token) {
+                Some(ket) => {
                     self.bump();
                     self.parse_seq_to_end(&ket,
                                           seq_sep_none(),
                                           |p| p.parse_token_tree())
                 }
-                _ => self.fatal("expected open delimiter")
+                None => self.fatal("expected open delimiter")
             };
             // single-variant-enum... :
             let m = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 2c5698ddec4..ff1509fe23a 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -297,21 +297,17 @@ pub fn can_begin_expr(t: &Token) -> bool {
     }
 }
 
-/// what's the opposite delimiter?
-pub fn flip_delimiter(t: &token::Token) -> token::Token {
+/// Returns the matching close delimiter if this is an open delimiter,
+/// otherwise `None`.
+pub fn close_delimiter_for(t: &Token) -> Option<Token> {
     match *t {
-      LPAREN => RPAREN,
-      LBRACE => RBRACE,
-      LBRACKET => RBRACKET,
-      RPAREN => LPAREN,
-      RBRACE => LBRACE,
-      RBRACKET => LBRACKET,
-      _ => fail!()
+        LPAREN   => Some(RPAREN),
+        LBRACE   => Some(RBRACE),
+        LBRACKET => Some(RBRACKET),
+        _        => None
     }
 }
 
-
-
 pub fn is_lit(t: &Token) -> bool {
     match *t {
       LIT_CHAR(_) => true,