about summary refs log tree commit diff
path: root/src/comp/syntax/parse
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-07-27 09:13:00 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-07-27 15:19:31 +0200
commit66c1ca857bf8e7c27b61d02c4e2127a724551ba8 (patch)
treea32e8f493db000c730568548b1873951dcb11379 /src/comp/syntax/parse
parent300eb3011355d81f95b79de4ca85e6190f1935a4 (diff)
Update the parser to accept the new syntax
Diffstat (limited to 'src/comp/syntax/parse')
-rw-r--r--src/comp/syntax/parse/parser.rs214
1 files changed, 59 insertions, 155 deletions
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 50fe1ff35af..e0ca20a4f1d 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -155,6 +155,7 @@ fn bad_expr_word_table() -> hashmap[str, ()] {
     words.insert("do", ());
     words.insert("alt", ());
     words.insert("for", ());
+    words.insert("each", ());
     words.insert("break", ());
     words.insert("cont", ());
     words.insert("put", ());
@@ -221,6 +222,11 @@ fn parse_value_ident(&parser p) -> ast::ident {
     ret parse_ident(p);
 }
 
+fn eat(&parser p, &token::token tok) -> bool {
+    ret if p.peek() == tok { p.bump(); true }
+        else { false };
+}
+
 fn is_word(&parser p, &str word) -> bool {
     ret alt (p.peek()) {
             case (token::IDENT(?sid, false)) { str::eq(word, p.get_str(sid)) }
@@ -262,16 +268,16 @@ fn check_bad_word(&parser p) {
 fn parse_ty_fn(ast::proto proto, &parser p, uint lo) -> ast::ty_ {
     fn parse_fn_input_ty(&parser p) -> ast::ty_arg {
         auto lo = p.get_lo_pos();
+        // Ignore arg name, if present
+        if is_plain_ident(p) && p.look_ahead(1u) == token::COLON {
+            p.bump(); p.bump();
+        }
         auto mode = ast::val;
         if (p.peek() == token::BINOP(token::AND)) {
             p.bump();
             mode = ast::alias(eat_word(p, "mutable"));
         }
         auto t = parse_ty(p);
-        alt (p.peek()) {
-            case (token::IDENT(_, _)) { p.bump();/* ignore param name */ }
-            case (_) {/* no param name present */ }
-        }
         ret spanned(lo, t.span.hi, rec(mode=mode, ty=t));
     }
     auto lo = p.get_lo_pos();
@@ -343,14 +349,6 @@ fn parse_mt(&parser p) -> ast::mt {
 
 fn parse_ty_field(&parser p) -> ast::ty_field {
     auto lo = p.get_lo_pos();
-    auto mt = parse_mt(p);
-    auto id = parse_ident(p);
-    ret spanned(lo, mt.ty.span.hi, rec(ident=id, mt=mt));
-}
-
-// FIXME rename to parse_ty_field once the other one is dropped
-fn parse_ty_field_modern(&parser p) -> ast::ty_field {
-    auto lo = p.get_lo_pos();
     auto mut = parse_mutability(p);
     auto id = parse_ident(p);
     expect(p, token::COLON);
@@ -555,7 +553,7 @@ fn parse_ty(&parser p) -> @ast::ty {
         t = ast::ty_ptr(mt);
     } else if (p.peek() == token::LBRACE) {
         auto elems = parse_seq(token::LBRACE, token::RBRACE,
-                               some(token::COMMA), parse_ty_field_modern, p);
+                               some(token::COMMA), parse_ty_field, p);
         hi = elems.span.hi;
         t = ast::ty_rec(elems.node);
         if (p.peek() == token::COLON) {
@@ -568,20 +566,6 @@ fn parse_ty(&parser p) -> @ast::ty {
         t = ast::ty_vec(parse_mt(p));
         hi = p.get_hi_pos();
         expect(p, token::RBRACKET);
-    } else if (eat_word(p, "rec")) {
-        auto elems =
-            parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA),
-                           parse_ty_field, p);
-        hi = elems.span.hi;
-        // possible constrs
-        // FIXME: something seems dodgy or at least repetitive
-        // about how constrained types get parsed
-        t = ast::ty_rec(elems.node);
-        if (p.peek() == token::COLON) {
-            p.bump();
-            t = ast::ty_constr(@spanned(lo, hi, t),
-                               parse_type_constraints(p));
-        }
     } else if (eat_word(p, "fn")) {
         auto flo = p.get_last_lo_pos();
         t = parse_ty_fn(ast::proto_fn, p, flo);
@@ -621,12 +605,12 @@ fn parse_ty(&parser p) -> @ast::ty {
 
 fn parse_arg(&parser p) -> ast::arg {
     let ast::mode m = ast::val;
-    if (p.peek() == token::BINOP(token::AND)) {
-        p.bump();
+    let ast::ident i = parse_value_ident(p);
+    expect(p, token::COLON);
+    if eat(p, token::BINOP(token::AND)) {
         m = ast::alias(eat_word(p, "mutable"));
     }
     let @ast::ty t = parse_ty(p);
-    let ast::ident i = parse_value_ident(p);
     ret rec(mode=m, ty=t, ident=i, id=p.get_id());
 }
 
@@ -710,6 +694,10 @@ fn is_ident(token::token t) -> bool {
     ret false;
 }
 
+fn is_plain_ident(&parser p) -> bool {
+    ret alt p.peek() { token::IDENT(_, false) { true } _ { false } };
+}
+
 fn parse_path(&parser p) -> ast::path {
     auto lo = p.get_lo_pos();
     auto hi = lo;
@@ -806,8 +794,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
     } else if (p.peek() == token::LBRACE) {
         p.bump();
         if (is_word(p, "mutable") ||
-            alt p.peek() { token::IDENT(_, false) { true } _ { false } } &&
-            p.look_ahead(1u) == token::COLON) {
+            is_plain_ident(p) && p.look_ahead(1u) == token::COLON) {
             auto fields = ~[parse_field(p, token::COLON)];
             auto base = none;
             while p.peek() != token::RBRACE {
@@ -915,27 +902,6 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
         let ast::anon_obj ob =
             rec(fields=fields, methods=meths, with_obj=with_obj);
         ex = ast::expr_anon_obj(ob);
-    } else if (eat_word(p, "rec")) {
-        expect(p, token::LPAREN);
-        auto fields = ~[parse_field(p, token::EQ)];
-        auto more = true;
-        auto base = none;
-        while (more) {
-            if (p.peek() == token::RPAREN) {
-                hi = p.get_hi_pos();
-                p.bump();
-                more = false;
-            } else if (eat_word(p, "with")) {
-                base = some(parse_expr(p));
-                hi = p.get_hi_pos();
-                expect(p, token::RPAREN);
-                more = false;
-            } else if (p.peek() == token::COMMA) {
-                p.bump();
-                fields += ~[parse_field(p, token::EQ)];
-            } else { unexpected(p, p.peek()); }
-        }
-        ex = ast::expr_rec(fields, base);
     } else if (eat_word(p, "bind")) {
         auto e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS);
         fn parse_expr_opt(&parser p) -> option::t[@ast::expr] {
@@ -1349,25 +1315,15 @@ fn parse_else_expr(&parser p) -> @ast::expr {
     }
 }
 
-fn parse_head_local(&parser p) -> @ast::local {
-    if (eat_word(p, "auto")) {
-        ret parse_auto_local(p);
-    } else {
-        ret parse_typed_local(p);
-    }
-}
-
 fn parse_for_expr(&parser p) -> @ast::expr {
     auto lo = p.get_last_lo_pos();
     auto is_each = eat_word(p, "each");
-    expect(p, token::LPAREN);
-    auto decl = parse_head_local(p);
+    auto decl = parse_local(p, false);
     expect_word(p, "in");
     auto seq = parse_expr(p);
-    expect(p, token::RPAREN);
     auto body = parse_block(p);
     auto hi = body.span.hi;
-    if (is_each) {
+    if is_each {
         ret mk_expr(p, lo, hi, ast::expr_for_each(decl, seq, body));
     } else {
         ret mk_expr(p, lo, hi, ast::expr_for(decl, seq, body));
@@ -1483,21 +1439,6 @@ fn parse_pat(&parser p) -> @ast::pat {
             p.bump();
             pat = ast::pat_wild;
         }
-        case (token::QUES) {
-            p.bump();
-            alt (p.peek()) {
-                case (token::IDENT(?id, _)) {
-                    hi = p.get_hi_pos();
-                    p.bump();
-                    pat = ast::pat_bind(p.get_str(id));
-                }
-                case (?tok) {
-                    p.fatal("expected identifier after '?' in pattern but " +
-                              "found " + token::to_str(p.get_reader(), tok));
-                    fail;
-                }
-            }
-        }
         case (token::AT) {
             p.bump();
             auto sub = parse_pat(p);
@@ -1548,6 +1489,15 @@ fn parse_pat(&parser p) -> @ast::pat {
                 auto lit = parse_lit(p);
                 hi = lit.span.hi;
                 pat = ast::pat_lit(@lit);
+            } else if (is_plain_ident(p) &&
+                       alt p.look_ahead(1u) {
+                         token::DOT | token::LPAREN | token::LBRACKET {
+                           false
+                         }
+                         _ { true }
+                       }) {
+                hi = p.get_hi_pos();
+                pat = ast::pat_bind(parse_ident(p));
             } else {
                 auto tag_path = parse_path_and_ty_param_substs(p);
                 hi = tag_path.span.hi;
@@ -1559,7 +1509,11 @@ fn parse_pat(&parser p) -> @ast::pat {
                         args = a.node;
                         hi = a.span.hi;
                     }
-                    case (_) { args = ~[]; }
+                    case (token::DOT) {
+                        args = ~[];
+                        p.bump();
+                    }
+                    case (_) { expect(p, token::LPAREN); fail; }
                 }
                 pat = ast::pat_tag(tag_path, args);
             }
@@ -1568,81 +1522,30 @@ fn parse_pat(&parser p) -> @ast::pat {
     ret @rec(id=p.get_id(), node=pat, span=rec(lo=lo, hi=hi));
 }
 
-fn parse_local_full(&option::t[@ast::ty] tyopt, &parser p)
-    -> @ast::local {
+fn parse_local(&parser p, bool allow_init) -> @ast::local {
     auto lo = p.get_lo_pos();
     auto ident = parse_value_ident(p);
-    auto init = parse_initializer(p);
-    ret @spanned(lo, p.get_hi_pos(),
-                 rec(ty=tyopt,
-                     infer=false,
-                     ident=ident,
-                     init=init,
-                     id=p.get_id()));
-}
-
-fn parse_typed_local(&parser p) -> @ast::local {
-    auto ty = parse_ty(p);
-    ret parse_local_full(some(ty), p);
-}
-
-fn parse_auto_local(&parser p) -> @ast::local {
-    ret parse_local_full(none, p);
-}
-
-// FIXME simplify when old syntax is no longer supported
-fn parse_let(&parser p) -> @ast::decl {
-    if alt p.peek() { token::IDENT(_, false) { true } _ { false } } {
-        alt p.look_ahead(1u) {
-          token::COLON | token::SEMI | token::COMMA | token::EQ |
-          token::LARROW {
-            ret parse_let_modern(p);
-          }
-          _ {}
-        }
+    auto ty = none;
+    if eat(p, token::COLON) {
+        ty = some(parse_ty(p));
     }
-    auto lo = p.get_last_lo_pos();
-    auto locals = ~[parse_typed_local(p)];
-    while p.peek() == token::COMMA {
-        p.bump();
-        locals += ~[parse_typed_local(p)];
-    }
-    ret @spanned(lo, p.get_hi_pos(), ast::decl_local(locals));
+    auto init = if allow_init { parse_initializer(p) }
+                else { none };
+    ret @spanned(lo, p.get_last_hi_pos(),
+                 rec(ty=ty, infer=false, ident=ident,
+                     init=init, id=p.get_id()));
 }
 
-fn parse_let_modern(&parser p) -> @ast::decl {
-    fn parse_local(&parser p) -> @ast::local {
-        auto lo = p.get_lo_pos();
-        auto ident = parse_value_ident(p);
-        auto ty = none;
-        if p.peek() == token::COLON {
-            p.bump();
-            ty = some(parse_ty(p));
-        }
-        auto init = parse_initializer(p);
-        ret @spanned(lo, p.get_last_hi_pos(),
-                     rec(ty=ty, infer=false, ident=ident,
-                         init=init, id=p.get_id()));
-    }
+fn parse_let(&parser p) -> @ast::decl {
     auto lo = p.get_lo_pos();
-    auto locals = ~[parse_local(p)];
+    auto locals = ~[parse_local(p, true)];
     while p.peek() == token::COMMA {
         p.bump();
-        locals += ~[parse_local(p)];
+        locals += ~[parse_local(p, true)];
     }
     ret @spanned(lo, p.get_last_hi_pos(), ast::decl_local(locals));
 }
 
-fn parse_auto(&parser p) -> @ast::decl {
-    auto lo = p.get_last_lo_pos();
-    auto locals = ~[parse_auto_local(p)];
-    while p.peek() == token::COMMA {
-        p.bump();
-        locals += ~[parse_auto_local(p)];
-    }
-    ret @spanned(lo, p.get_hi_pos(), ast::decl_local(locals));
-}
-
 fn parse_stmt(&parser p) -> @ast::stmt {
     if (p.get_file_type() == SOURCE_FILE) {
         ret parse_source_stmt(p);
@@ -1660,9 +1563,6 @@ fn parse_source_stmt(&parser p) -> @ast::stmt {
     if (eat_word(p, "let")) {
         auto decl = parse_let(p);
         ret @spanned(lo, decl.span.hi, ast::stmt_decl(decl, p.get_id()));
-    } else if (eat_word(p, "auto")) {
-        auto decl = parse_auto(p);
-        ret @spanned(lo, decl.span.hi, ast::stmt_decl(decl, p.get_id()));
     } else {
 
         auto item_attrs;
@@ -1850,11 +1750,11 @@ fn parse_ty_params(&parser p) -> ast::ty_param[] {
 fn parse_fn_decl(&parser p, ast::purity purity) -> ast::fn_decl {
     let ast::spanned[ast::arg[]] inputs =
         parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA),
-                       parse_arg, p);
+                  parse_arg, p);
     let ty_or_bang rslt;
-// Use the args list to translate each bound variable
-// mentioned in a constraint to an arg index.
-// Seems weird to do this in the parser, but I'm not sure how else to.
+    // Use the args list to translate each bound variable
+    // mentioned in a constraint to an arg index.
+    // Seems weird to do this in the parser, but I'm not sure how else to.
     auto constrs = ~[];
     if (p.peek() == token::COLON) {
         p.bump();
@@ -1917,15 +1817,17 @@ fn parse_item_fn_or_iter(&parser p, ast::purity purity, ast::proto proto,
 
 fn parse_obj_field(&parser p) -> ast::obj_field {
     auto mut = parse_mutability(p);
-    auto ty = parse_ty(p);
     auto ident = parse_value_ident(p);
+    expect(p, token::COLON);
+    auto ty = parse_ty(p);
     ret rec(mut=mut, ty=ty, ident=ident, id=p.get_id());
 }
 
 fn parse_anon_obj_field(&parser p) -> ast::anon_obj_field {
     auto mut = parse_mutability(p);
-    auto ty = parse_ty(p);
     auto ident = parse_value_ident(p);
+    expect(p, token::COLON);
+    auto ty = parse_ty(p);
     expect(p, token::EQ);
     auto expr = parse_expr(p);
     ret rec(mut=mut, ty=ty, expr=expr, ident=ident, id=p.get_id());
@@ -1988,8 +1890,9 @@ fn parse_item_res(&parser p, ast::layer lyr, &ast::attribute[] attrs) ->
     auto ident = parse_value_ident(p);
     auto ty_params = parse_ty_params(p);
     expect(p, token::LPAREN);
-    auto t = parse_ty(p);
     auto arg_ident = parse_value_ident(p);
+    expect(p, token::COLON);
+    auto t = parse_ty(p);
     expect(p, token::RPAREN);
     auto dtor = parse_block(p);
     auto decl = rec(inputs=~[rec(mode=ast::alias(false), ty=t,
@@ -2029,8 +1932,9 @@ fn parse_mod_items(&parser p, token::token term,
 
 fn parse_item_const(&parser p, &ast::attribute[] attrs) -> @ast::item {
     auto lo = p.get_last_lo_pos();
-    auto ty = parse_ty(p);
     auto id = parse_value_ident(p);
+    expect(p, token::COLON);
+    auto ty = parse_ty(p);
     expect(p, token::EQ);
     auto e = parse_expr(p);
     auto hi = p.get_hi_pos();