diff options
| author | Gábor Lehel <glaebhoerl@gmail.com> | 2014-03-16 22:46:04 +0100 |
|---|---|---|
| committer | Sean McArthur <sean.monstar@gmail.com> | 2014-03-31 22:42:31 -0700 |
| commit | be673e77e75ece1611cdcf7b1b784ccd53cc9011 (patch) | |
| tree | 83f60a5f11809e936f289734e924d6918880d832 /src/libsyntax/parse | |
| parent | b8ef9fd9c9f642ce7b8aed82782a1ed745d08d64 (diff) | |
| download | rust-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.rs | 38 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 18 |
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, |
