about summary refs log tree commit diff
path: root/src/comp/syntax/parse
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-01-14 16:05:07 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-01-17 10:08:16 -0800
commitc3bc8fada838c15e09e76a9d5d85438667c1636c (patch)
treee0ff1cb9ea73f7ee894e8ff3ab3180260f71aeac /src/comp/syntax/parse
parenta7bd817017c247edb0680936c6cf34ec4d8e7fc0 (diff)
downloadrust-c3bc8fada838c15e09e76a9d5d85438667c1636c.tar.gz
rust-c3bc8fada838c15e09e76a9d5d85438667c1636c.zip
Allow omission of the '.' after nullary tag patterns
This commit allows patterns like:

alt x { some(_) { ... } none { } }

without the '.' after none. The parser suspends judgment about
whether a bare ident is a tag or a new bound variable; instead,
the resolver disambiguates.

This means that any code after resolution that pattern-matches on
patterns needs to call pat_util::normalize_pat, which consults
an environment to do this disambiguation.

In addition, local variables are no longer allowed to shadow
tag names, so this required changing some code (e.g. renaming
variables named "mut", and renaming ast::sub to subtract).

The parser currently accepts patterns with and without the '.'.
Once the compiler and libraries are changed, it will no longer
accept the '.'.
Diffstat (limited to 'src/comp/syntax/parse')
-rw-r--r--src/comp/syntax/parse/parser.rs29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index ef65a0bd897..b8f55dcba96 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -8,6 +8,7 @@ import token::can_begin_expr;
 import codemap::span;
 import util::interner;
 import ast::{node_id, spanned};
+import ast_util::{mk_sp, ident_to_path};
 import front::attr;
 import lexer::reader;
 import driver::diagnostic;
@@ -1097,7 +1098,7 @@ fn prec_table() -> @[op_spec] {
           {tok: token::BINOP(token::SLASH), op: ast::div, prec: 11},
           {tok: token::BINOP(token::PERCENT), op: ast::rem, prec: 11},
           {tok: token::BINOP(token::PLUS), op: ast::add, prec: 10},
-          {tok: token::BINOP(token::MINUS), op: ast::sub, prec: 10},
+          {tok: token::BINOP(token::MINUS), op: ast::subtract, prec: 10},
           {tok: token::BINOP(token::LSL), op: ast::lsl, prec: 9},
           {tok: token::BINOP(token::LSR), op: ast::lsr, prec: 9},
           {tok: token::BINOP(token::ASR), op: ast::asr, prec: 9},
@@ -1165,7 +1166,7 @@ fn parse_assign_expr(p: parser) -> @ast::expr {
         let aop = ast::add;
         alt op {
           token::PLUS. { aop = ast::add; }
-          token::MINUS. { aop = ast::sub; }
+          token::MINUS. { aop = ast::subtract; }
           token::STAR. { aop = ast::mul; }
           token::SLASH. { aop = ast::div; }
           token::PERCENT. { aop = ast::rem; }
@@ -1426,7 +1427,11 @@ fn parse_pat(p: parser) -> @ast::pat {
                 break;
             }
 
+            let lo1 = p.last_span.lo;
             let fieldname = parse_ident(p);
+            let hi1 = p.last_span.lo;
+            let fieldpath = ast_util::ident_to_path(ast_util::mk_sp(lo1, hi1),
+                                          fieldname);
             let subpat;
             if p.token == token::COLON {
                 p.bump();
@@ -1436,7 +1441,7 @@ fn parse_pat(p: parser) -> @ast::pat {
                     p.fatal("found " + fieldname + " in binding position");
                 }
                 subpat = @{id: p.get_id(),
-                           node: ast::pat_bind(fieldname, none),
+                           node: ast::pat_ident(fieldpath, none),
                            span: ast_util::mk_sp(lo, hi)};
             }
             fields += [{ident: fieldname, pat: subpat}];
@@ -1478,7 +1483,10 @@ fn parse_pat(p: parser) -> @ast::pat {
             }
         } else if is_plain_ident(p) &&
                       alt p.look_ahead(1u) {
-                        token::DOT. | token::LPAREN. | token::LBRACKET. {
+                    // Take this out once the libraries change
+                        token::DOT. |
+                        token::LPAREN. | token::LBRACKET. |
+                            token::LT. {
                           false
                         }
                         _ { true }
@@ -1486,7 +1494,7 @@ fn parse_pat(p: parser) -> @ast::pat {
             hi = p.span.hi;
             let name = parse_value_ident(p);
             let sub = eat(p, token::AT) ? some(parse_pat(p)) : none;
-            pat = ast::pat_bind(name, sub);
+            pat = ast::pat_ident(ident_to_path(mk_sp(lo, hi), name), sub);
         } else {
             let tag_path = parse_path_and_ty_param_substs(p, true);
             hi = tag_path.span.hi;
@@ -1499,10 +1507,19 @@ fn parse_pat(p: parser) -> @ast::pat {
                 args = a.node;
                 hi = a.span.hi;
               }
+              token::LBRACE. { args = []; }
+              // take this out once the libraries change
               token::DOT. { args = []; p.bump(); }
               _ { expect(p, token::LPAREN); fail; }
             }
-            pat = ast::pat_tag(tag_path, args);
+            // at this point, we're not sure whether it's a tag or a bind
+            if vec::len(args) == 0u &&
+               vec::len(tag_path.node.idents) == 1u {
+                pat = ast::pat_ident(tag_path, none);
+            }
+            else {
+                pat = ast::pat_tag(tag_path, args);
+            }
         }
       }
     }