diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-07-27 09:13:00 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-07-27 15:19:31 +0200 |
| commit | 66c1ca857bf8e7c27b61d02c4e2127a724551ba8 (patch) | |
| tree | a32e8f493db000c730568548b1873951dcb11379 /src/comp/syntax/parse | |
| parent | 300eb3011355d81f95b79de4ca85e6190f1935a4 (diff) | |
Update the parser to accept the new syntax
Diffstat (limited to 'src/comp/syntax/parse')
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 214 |
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(); |
