diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/front/lexer.rs | 147 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 1406 | ||||
| -rw-r--r-- | src/comp/front/token.rs | 202 | ||||
| -rw-r--r-- | src/comp/pretty/pprust.rs | 5 | ||||
| -rw-r--r-- | src/comp/rustc.rc | 2 | ||||
| -rw-r--r-- | src/lib/std.rc | 2 |
6 files changed, 612 insertions, 1152 deletions
diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs index f01d782a..6f93234f 100644 --- a/src/comp/front/lexer.rs +++ b/src/comp/front/lexer.rs @@ -22,8 +22,6 @@ state type reader = state obj { fn add_str(str) -> token::str_num; fn get_str(token::str_num) -> str; fn get_chpos() -> uint; - fn get_keywords() -> hashmap[str,token::token]; - fn get_reserved() -> hashmap[str,()]; fn get_filemap() -> codemap::filemap; fn err(str m); }; @@ -39,8 +37,6 @@ fn new_reader(session sess, io::reader rdr, mutable uint mark_chpos, mutable uint chpos, mutable vec[str] strs, - hashmap[str,token::token] keywords, - hashmap[str,()] reserved, codemap::filemap fm) { fn is_eof() -> bool { @@ -82,10 +78,6 @@ fn new_reader(session sess, io::reader rdr, } } - fn get_keywords() -> hashmap[str,token::token] { - ret keywords; - } - fn add_str(str s) -> token::str_num { strs += vec(s); ret _vec::len[str](strs) - 1u; @@ -95,10 +87,6 @@ fn new_reader(session sess, io::reader rdr, ret strs.(i); } - fn get_reserved() -> hashmap[str,()] { - ret reserved; - } - fn get_filemap() -> codemap::filemap { ret fm; } @@ -111,133 +99,11 @@ fn new_reader(session sess, io::reader rdr, let vec[str] strs = vec(); auto rd = reader(sess, file, _str::byte_len(file), 0u, -1 as char, filemap.start_pos, filemap.start_pos, - strs, keyword_table(), - reserved_word_table(), - filemap); + strs, filemap); rd.init(); ret rd; } -fn keyword_table() -> std::map::hashmap[str, token::token] { - auto keywords = new_str_hash[token::token](); - - keywords.insert("mod", token::MOD); - keywords.insert("use", token::USE); - keywords.insert("meta", token::META); - keywords.insert("auth", token::AUTH); - - keywords.insert("syntax", token::SYNTAX); - - keywords.insert("if", token::IF); - keywords.insert("else", token::ELSE); - keywords.insert("while", token::WHILE); - keywords.insert("do", token::DO); - keywords.insert("alt", token::ALT); - keywords.insert("case", token::CASE); - - keywords.insert("for", token::FOR); - keywords.insert("each", token::EACH); - keywords.insert("break", token::BREAK); - keywords.insert("cont", token::CONT); - keywords.insert("put", token::PUT); - keywords.insert("ret", token::RET); - keywords.insert("be", token::BE); - - keywords.insert("fail", token::FAIL); - keywords.insert("drop", token::DROP); - - keywords.insert("type", token::TYPE); - keywords.insert("check", token::CHECK); - keywords.insert("assert", token::ASSERT); - keywords.insert("claim", token::CLAIM); - keywords.insert("prove", token::PROVE); - - keywords.insert("state", token::STATE); - keywords.insert("gc", token::GC); - - keywords.insert("unsafe", token::UNSAFE); - - keywords.insert("native", token::NATIVE); - keywords.insert("mutable", token::MUTABLE); - keywords.insert("auto", token::AUTO); - - keywords.insert("fn", token::FN); - keywords.insert("pred", token::PRED); - keywords.insert("iter", token::ITER); - - keywords.insert("import", token::IMPORT); - keywords.insert("export", token::EXPORT); - - keywords.insert("let", token::LET); - keywords.insert("const", token::CONST); - - keywords.insert("log", token::LOG); - keywords.insert("log_err", token::LOG_ERR); - keywords.insert("spawn", token::SPAWN); - keywords.insert("thread", token::THREAD); - keywords.insert("yield", token::YIELD); - keywords.insert("join", token::JOIN); - - keywords.insert("bool", token::BOOL); - - keywords.insert("int", token::INT); - keywords.insert("uint", token::UINT); - keywords.insert("float", token::FLOAT); - - keywords.insert("char", token::CHAR); - keywords.insert("str", token::STR); - - - keywords.insert("rec", token::REC); - keywords.insert("tup", token::TUP); - keywords.insert("tag", token::TAG); - keywords.insert("vec", token::VEC); - keywords.insert("any", token::ANY); - - keywords.insert("obj", token::OBJ); - keywords.insert("self", token::SELF); - - keywords.insert("port", token::PORT); - keywords.insert("chan", token::CHAN); - - keywords.insert("task", token::TASK); - - keywords.insert("true", token::LIT_BOOL(true)); - keywords.insert("false", token::LIT_BOOL(false)); - - keywords.insert("in", token::IN); - - keywords.insert("as", token::AS); - keywords.insert("with", token::WITH); - - keywords.insert("bind", token::BIND); - - keywords.insert("u8", token::MACH(common::ty_u8)); - keywords.insert("u16", token::MACH(common::ty_u16)); - keywords.insert("u32", token::MACH(common::ty_u32)); - keywords.insert("u64", token::MACH(common::ty_u64)); - keywords.insert("i8", token::MACH(common::ty_i8)); - keywords.insert("i16", token::MACH(common::ty_i16)); - keywords.insert("i32", token::MACH(common::ty_i32)); - keywords.insert("i64", token::MACH(common::ty_i64)); - keywords.insert("f32", token::MACH(common::ty_f32)); - keywords.insert("f64", token::MACH(common::ty_f64)); - - ret keywords; -} - -fn reserved_word_table() -> std::map::hashmap[str, ()] { - auto reserved = new_str_hash[()](); - reserved.insert("f16", ()); // IEEE 754-2008 'binary16' interchange fmt - reserved.insert("f80", ()); // IEEE 754-1985 'extended' - reserved.insert("f128", ()); // IEEE 754-2008 'binary128' - reserved.insert("m32", ()); // IEEE 754-2008 'decimal32' - reserved.insert("m64", ()); // IEEE 754-2008 'decimal64' - reserved.insert("m128", ()); // IEEE 754-2008 'decimal128' - reserved.insert("dec", ()); // One of m32, m64, m128 - ret reserved; -} - fn in_range(char c, char lo, char hi) -> bool { ret lo <= c && c <= hi; } @@ -604,17 +470,6 @@ fn next_token(reader rdr) -> token::token { ret token::UNDERSCORE; } - auto kwds = rdr.get_keywords(); - if (kwds.contains_key(accum_str)) { - ret kwds.get(accum_str); - } - - auto rsvd = rdr.get_reserved(); - if (rsvd.contains_key(accum_str)) { - rdr.err(#fmt("reserved keyword: %s", accum_str)); - fail; - } - ret token::IDENT(rdr.add_str(accum_str)); } diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 5292c49c..2cb00bcd 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -35,6 +35,7 @@ state type parser = fn get_span() -> common::span; fn get_lo_pos() -> uint; fn get_hi_pos() -> uint; + fn get_last_lo_pos() -> uint; fn next_def_id() -> ast::def_id; fn set_def(ast::def_num); fn get_prec_table() -> vec[op_spec]; @@ -56,6 +57,7 @@ fn new_parser(session::session sess, mutable token::token tok, mutable uint lo, mutable uint hi, + mutable uint last_lo, mutable ast::def_num def, mutable restriction res, ast::crate_num crate, @@ -70,6 +72,7 @@ fn new_parser(session::session sess, fn bump() { // log rdr.get_filename() // + ":" + common::istr(lo.line as int); + last_lo = lo; tok = lexer::next_token(rdr); lo = rdr.get_mark_chpos(); hi = rdr.get_chpos(); @@ -94,6 +97,7 @@ fn new_parser(session::session sess, fn get_span() -> common::span { ret rec(lo=lo, hi=hi); } fn get_lo_pos() -> uint { ret lo; } fn get_hi_pos() -> uint { ret hi; } + fn get_last_lo_pos() -> uint { ret last_lo; } fn next_def_id() -> ast::def_id { def += 1; @@ -151,8 +155,8 @@ fn new_parser(session::session sess, lexer::consume_any_whitespace(rdr); auto npos = rdr.get_chpos(); ret stdio_parser(sess, env, ftype, lexer::next_token(rdr), - npos, npos, initial_def._1, UNRESTRICTED, initial_def._0, - rdr, prec_table(), next_ann); + npos, npos, npos, initial_def._1, UNRESTRICTED, + initial_def._0, rdr, prec_table(), next_ann); } fn unexpected(parser p, token::token t) { @@ -212,6 +216,30 @@ fn parse_str_lit_or_env_ident(parser p) -> ast::ident { } } +fn is_word(&parser p, &str word) -> bool { + ret alt (p.peek()) { + case (token::IDENT(?sid)) { _str::eq(word, p.get_str(sid)) } + case (_) { false } + }; +} +fn eat_word(&parser p, &str word) -> bool { + alt (p.peek()) { + case (token::IDENT(?sid)) { + if (_str::eq(word, p.get_str(sid))) { + p.bump(); + ret true; + } else { ret false; } + + } + case (_) { ret false; } + } +} +fn expect_word(&parser p, &str word) { + if (!eat_word(p, word)) { + p.err("expecting " + word + ", found " + + token::to_str(p.get_reader(), p.peek())); + } +} fn parse_ty_fn(ast::proto proto, parser p, uint lo) -> ast::ty_ { @@ -221,8 +249,7 @@ fn parse_ty_fn(ast::proto proto, parser p, uint lo) p.bump(); mode = ast::alias; - if (p.peek() == token::MUTABLE) { - p.bump(); + if (eat_word(p, "mutable")) { // TODO: handle mutable alias args } } else { @@ -261,17 +288,13 @@ fn parse_ty_fn(ast::proto proto, parser p, uint lo) } fn parse_proto(parser p) -> ast::proto { - alt (p.peek()) { - case (token::ITER) { p.bump(); ret ast::proto_iter; } - case (token::FN) { p.bump(); ret ast::proto_fn; } - case (token::PRED) { p.bump(); ret ast::proto_fn; } - case (?t) { unexpected(p, t); } - } - fail; + if (eat_word(p, "iter")) { ret ast::proto_iter; } + else if (eat_word(p, "fn")) { ret ast::proto_fn; } + else if (eat_word(p, "pred")) { ret ast::proto_fn; } + else { unexpected(p, p.peek()); } } fn parse_ty_obj(parser p, &mutable uint hi) -> ast::ty_ { - expect(p, token::OBJ); fn parse_method_sig(parser p) -> ast::ty_method { auto flo = p.get_lo_pos(); @@ -367,130 +390,105 @@ fn parse_ty(parser p) -> @ast::ty { // FIXME: do something with this let ast::layer lyr = parse_layer(p); - alt (p.peek()) { - case (token::BOOL) { p.bump(); t = ast::ty_bool; } - case (token::INT) { p.bump(); t = ast::ty_int; } - case (token::UINT) { p.bump(); t = ast::ty_uint; } - case (token::FLOAT) { p.bump(); t = ast::ty_float; } - case (token::STR) { p.bump(); t = ast::ty_str; } - case (token::CHAR) { p.bump(); t = ast::ty_char; } - case (token::MACH(?tm)) { p.bump(); t = ast::ty_machine(tm); } - - case (token::LPAREN) { - p.bump(); - alt (p.peek()) { - case (token::RPAREN) { - hi = p.get_hi_pos(); - p.bump(); - t = ast::ty_nil; - } - case (_) { - t = parse_ty(p).node; - hi = p.get_hi_pos(); - expect(p, token::RPAREN); - } + let ast::ty t; + if (eat_word(p, "bool")) { t = ast::ty_bool; } + else if (eat_word(p, "int")) { t = ast::ty_int; } + else if (eat_word(p, "uint")) { t = ast::ty_uint; } + else if (eat_word(p, "float")) { t = ast::ty_float; } + else if (eat_word(p, "str")) { t = ast::ty_str; } + else if (eat_word(p, "char")) { t = ast::ty_char; } + else if (eat_word(p, "i8")) { t = ast::ty_machine(common::ty_i8); } + else if (eat_word(p, "i16")) { t = ast::ty_machine(common::ty_i16); } + else if (eat_word(p, "i32")) { t = ast::ty_machine(common::ty_i32); } + else if (eat_word(p, "i64")) { t = ast::ty_machine(common::ty_i64); } + else if (eat_word(p, "u8")) { t = ast::ty_machine(common::ty_u8); } + else if (eat_word(p, "u16")) { t = ast::ty_machine(common::ty_u16); } + else if (eat_word(p, "u32")) { t = ast::ty_machine(common::ty_u32); } + else if (eat_word(p, "u64")) { t = ast::ty_machine(common::ty_u64); } + else if (eat_word(p, "f32")) { t = ast::ty_machine(common::ty_f32); } + else if (eat_word(p, "f64")) { t = ast::ty_machine(common::ty_f64); } + else if (p.peek() == token::LPAREN) { + p.bump(); + alt (p.peek()) { + case (token::RPAREN) { + hi = p.get_hi_pos(); + p.bump(); + t = ast::ty_nil; } - } - - case (token::AT) { - p.bump(); - auto mt = parse_mt(p); - hi = mt.ty.span.hi; - t = ast::ty_box(mt); - } - - case (token::VEC) { - p.bump(); - expect(p, token::LBRACKET); - t = ast::ty_vec(parse_mt(p)); - hi = p.get_hi_pos(); - expect(p, token::RBRACKET); - } - - case (token::TUP) { - p.bump(); - auto f = parse_mt; // FIXME: trans_const_lval bug - auto elems = parse_seq[ast::mt] (token::LPAREN, - token::RPAREN, - some(token::COMMA), f, p); - hi = elems.span.hi; - t = ast::ty_tup(elems.node); - } - - case (token::REC) { - p.bump(); - auto f = parse_ty_field; // FIXME: trans_const_lval bug - auto elems = - parse_seq[ast::ty_field](token::LPAREN, - token::RPAREN, - some(token::COMMA), - f, p); - hi = elems.span.hi; - t = ast::ty_rec(elems.node); - } - - case (token::FN) { - auto flo = p.get_lo_pos(); - p.bump(); - t = parse_ty_fn(ast::proto_fn, p, flo); - alt (t) { - case (ast::ty_fn(_, _, ?out)) { - hi = out.span.hi; - } + case (_) { + t = parse_ty(p).node; + hi = p.get_hi_pos(); + expect(p, token::RPAREN); } } - - case (token::ITER) { - auto flo = p.get_lo_pos(); - p.bump(); - t = parse_ty_fn(ast::proto_iter, p, flo); - alt (t) { - case (ast::ty_fn(_, _, ?out)) { - hi = out.span.hi; - } + } else if (p.peek() == token::AT) { + p.bump(); + auto mt = parse_mt(p); + hi = mt.ty.span.hi; + t = ast::ty_box(mt); + } else if (eat_word(p, "vec")) { + expect(p, token::LBRACKET); + t = ast::ty_vec(parse_mt(p)); + hi = p.get_hi_pos(); + expect(p, token::RBRACKET); + } else if (eat_word(p, "tup")) { + auto f = parse_mt; // FIXME: trans_const_lval bug + auto elems = parse_seq[ast::mt] (token::LPAREN, + token::RPAREN, + some(token::COMMA), f, p); + hi = elems.span.hi; + t = ast::ty_tup(elems.node); + } else if (eat_word(p, "rec")) { + auto f = parse_ty_field; // FIXME: trans_const_lval bug + auto elems = + parse_seq[ast::ty_field](token::LPAREN, + token::RPAREN, + some(token::COMMA), + f, p); + hi = elems.span.hi; + t = ast::ty_rec(elems.node); + } else if (eat_word(p, "fn")) { + auto flo = p.get_last_lo_pos(); + t = parse_ty_fn(ast::proto_fn, p, flo); + alt (t) { + case (ast::ty_fn(_, _, ?out)) { + hi = out.span.hi; } } - - case (token::OBJ) { - t = parse_ty_obj(p, hi); - } - - case (token::PORT) { - p.bump(); - expect(p, token::LBRACKET); - t = ast::ty_port(parse_ty(p)); - hi = p.get_hi_pos(); - expect(p, token::RBRACKET); - } - - case (token::CHAN) { - p.bump(); - expect(p, token::LBRACKET); - t = ast::ty_chan(parse_ty(p)); - hi = p.get_hi_pos(); - expect(p, token::RBRACKET); - } - - case (token::IDENT(_)) { - auto path = parse_path(p); - t = ast::ty_path(path, p.get_ann()); - hi = path.span.hi; - } - - case (token::MUTABLE) { - p.bump(); - p.get_session().span_warn(p.get_span(), - "ignoring deprecated 'mutable' type constructor"); - auto typ = parse_ty(p); - t = typ.node; - hi = typ.span.hi; - } - - case (_) { - p.err("expecting type"); - t = ast::ty_nil; - fail; + } else if (eat_word(p, "iter")) { + auto flo = p.get_last_lo_pos(); + t = parse_ty_fn(ast::proto_iter, p, flo); + alt (t) { + case (ast::ty_fn(_, _, ?out)) { + hi = out.span.hi; + } } + } else if (eat_word(p, "obj")) { + t = parse_ty_obj(p, hi); + } else if (eat_word(p, "port")) { + expect(p, token::LBRACKET); + t = ast::ty_port(parse_ty(p)); + hi = p.get_hi_pos(); + expect(p, token::RBRACKET); + } else if (eat_word(p, "chan")) { + expect(p, token::LBRACKET); + t = ast::ty_chan(parse_ty(p)); + hi = p.get_hi_pos(); + expect(p, token::RBRACKET); + } else if (eat_word(p, "mutable")) { + p.get_session().span_warn(p.get_span(), + "ignoring deprecated 'mutable' type constructor"); + auto typ = parse_ty(p); + t = typ.node; + hi = typ.span.hi; + } else if (is_ident(p.peek())) { + auto path = parse_path(p); + t = ast::ty_path(path, p.get_ann()); + hi = path.span.hi; + } else { + p.err("expecting type"); + t = ast::ty_nil; + fail; } ret parse_ty_constrs(@spanned(lo, hi, t), p); @@ -502,10 +500,8 @@ fn parse_arg(parser p) -> ast::arg { m = ast::alias; p.bump(); - if (p.peek() == token::MUTABLE) { - // TODO: handle mutable alias args - p.bump(); - } + // TODO: handle mutable alias args + eat_word(p, "mutable"); } let @ast::ty t = parse_ty(p); let ast::ident i = parse_ident(p); @@ -555,41 +551,43 @@ fn parse_seq[T](token::token bra, fn parse_lit(parser p) -> ast::lit { auto sp = p.get_span(); let ast::lit_ lit = ast::lit_nil; - alt (p.peek()) { - case (token::LIT_INT(?i)) { - p.bump(); - lit = ast::lit_int(i); - } - case (token::LIT_UINT(?u)) { - p.bump(); - lit = ast::lit_uint(u); - } - case (token::LIT_FLOAT(?s)) { - p.bump(); - lit = ast::lit_float(p.get_str(s)); - } - case (token::LIT_MACH_INT(?tm, ?i)) { - p.bump(); - lit = ast::lit_mach_int(tm, i); - } - case (token::LIT_MACH_FLOAT(?tm, ?s)) { - p.bump(); - lit = ast::lit_mach_float(tm, p.get_str(s)); - } - case (token::LIT_CHAR(?c)) { - p.bump(); - lit = ast::lit_char(c); - } - case (token::LIT_BOOL(?b)) { - p.bump(); - lit = ast::lit_bool(b); - } - case (token::LIT_STR(?s)) { - p.bump(); - lit = ast::lit_str(p.get_str(s)); - } - case (?t) { - unexpected(p, t); + if (eat_word(p, "true")) { + lit = ast::lit_bool(true); + } else if (eat_word(p, "false")) { + lit = ast::lit_bool(false); + } else { + alt (p.peek()) { + case (token::LIT_INT(?i)) { + p.bump(); + lit = ast::lit_int(i); + } + case (token::LIT_UINT(?u)) { + p.bump(); + lit = ast::lit_uint(u); + } + case (token::LIT_FLOAT(?s)) { + p.bump(); + lit = ast::lit_float(p.get_str(s)); + } + case (token::LIT_MACH_INT(?tm, ?i)) { + p.bump(); + lit = ast::lit_mach_int(tm, i); + } + case (token::LIT_MACH_FLOAT(?tm, ?s)) { + p.bump(); + lit = ast::lit_mach_float(tm, p.get_str(s)); + } + case (token::LIT_CHAR(?c)) { + p.bump(); + lit = ast::lit_char(c); + } + case (token::LIT_STR(?s)) { + p.bump(); + lit = ast::lit_str(p.get_str(s)); + } + case (?t) { + unexpected(p, t); + } } } ret rec(node=lit, span=sp); @@ -643,8 +641,7 @@ fn parse_path(parser p) -> ast::path { } fn parse_mutability(parser p) -> ast::mutability { - if (p.peek() == token::MUTABLE) { - p.bump(); + if (eat_word(p, "mutable")) { if (p.peek() == token::QUES) { p.bump(); ret ast::maybe_mut; @@ -672,259 +669,195 @@ fn parse_bottom_expr(parser p) -> @ast::expr { auto lit = @spanned(lo, hi, ast::lit_nil); let ast::expr_ ex = ast::expr_lit(lit, p.get_ann()); - alt (p.peek()) { - - case (token::IDENT(_)) { - auto pth = parse_path(p); - hi = pth.span.hi; - ex = ast::expr_path(pth, p.get_ann()); - } - - case (token::LPAREN) { - p.bump(); - alt (p.peek()) { - case (token::RPAREN) { - hi = p.get_hi_pos(); - p.bump(); - auto lit = @spanned(lo, hi, ast::lit_nil); - ret @spanned(lo, hi, - ast::expr_lit(lit, p.get_ann())); - } - case (_) { /* fall through */ } + if (p.peek() == token::LPAREN) { + p.bump(); + alt (p.peek()) { + case (token::RPAREN) { + hi = p.get_hi_pos(); + p.bump(); + auto lit = @spanned(lo, hi, ast::lit_nil); + ret @spanned(lo, hi, + ast::expr_lit(lit, p.get_ann())); } + case (_) { /* fall through */ } + } + auto e = parse_expr(p); + hi = p.get_hi_pos(); + expect(p, token::RPAREN); + ret @spanned(lo, hi, e.node); + } else if (eat_word(p, "tup")) { + fn parse_elt(parser p) -> ast::elt { + auto m = parse_mutability(p); auto e = parse_expr(p); - hi = p.get_hi_pos(); - expect(p, token::RPAREN); - ret @spanned(lo, hi, e.node); - } - - case (token::TUP) { - p.bump(); - fn parse_elt(parser p) -> ast::elt { - auto m = parse_mutability(p); - auto e = parse_expr(p); - ret rec(mut=m, expr=e); - } - auto pf = parse_elt; - auto es = - parse_seq[ast::elt](token::LPAREN, - token::RPAREN, - some(token::COMMA), - pf, p); - hi = es.span.hi; - ex = ast::expr_tup(es.node, p.get_ann()); - } - - case (token::VEC) { - p.bump(); - auto pf = parse_expr; - - expect(p, token::LPAREN); - auto mut = parse_mutability(p); - - auto es = parse_seq_to_end[@ast::expr](token::RPAREN, - some(token::COMMA), - pf, hi, p); - ex = ast::expr_vec(es, mut, p.get_ann()); - } - - case (token::REC) { - p.bump(); - expect(p, token::LPAREN); - auto fields = vec(parse_field(p)); - - auto more = true; - auto base = none[@ast::expr]; - while (more) { - alt (p.peek()) { - case (token::RPAREN) { - hi = p.get_hi_pos(); - p.bump(); - more = false; - } - case (token::WITH) { - p.bump(); - base = some[@ast::expr](parse_expr(p)); - hi = p.get_hi_pos(); - expect(p, token::RPAREN); - more = false; - } - case (token::COMMA) { - p.bump(); - fields += vec(parse_field(p)); - } - case (?t) { - unexpected(p, t); - } - } - - } - - ex = ast::expr_rec(fields, base, p.get_ann()); - } - - case (token::BIND) { - p.bump(); - auto e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS); - fn parse_expr_opt(parser p) -> option::t[@ast::expr] { - alt (p.peek()) { - case (token::UNDERSCORE) { - p.bump(); - ret none[@ast::expr]; - } - case (_) { - ret some[@ast::expr](parse_expr(p)); - } - } + ret rec(mut=m, expr=e); + } + auto pf = parse_elt; + auto es = + parse_seq[ast::elt](token::LPAREN, + token::RPAREN, + some(token::COMMA), + pf, p); + hi = es.span.hi; + ex = ast::expr_tup(es.node, p.get_ann()); + } else if (eat_word(p, "vec")) { + auto pf = parse_expr; + + expect(p, token::LPAREN); + auto mut = parse_mutability(p); + + auto es = parse_seq_to_end[@ast::expr](token::RPAREN, + some(token::COMMA), + pf, hi, p); + ex = ast::expr_vec(es, mut, p.get_ann()); + } else if (eat_word(p, "rec")) { + expect(p, token::LPAREN); + auto fields = vec(parse_field(p)); + + auto more = true; + auto base = none[@ast::expr]; + while (more) { + if (p.peek() == token::RPAREN) { + hi = p.get_hi_pos(); + p.bump(); + more = false; + } else if (eat_word(p, "with")) { + base = some[@ast::expr](parse_expr(p)); + hi = p.get_hi_pos(); + expect(p, token::RPAREN); + more = false; + } else if (p.peek() == token::COMMA) { + p.bump(); + fields += vec(parse_field(p)); + } else { + unexpected(p, p.peek()); } - auto pf = parse_expr_opt; - auto es = parse_seq[option::t[@ast::expr]](token::LPAREN, - token::RPAREN, - some(token::COMMA), - pf, p); - hi = es.span.hi; - ex = ast::expr_bind(e, es.node, p.get_ann()); } - case (token::POUND) { - p.bump(); - auto pth = parse_path(p); - auto pf = parse_expr; - auto es = parse_seq[@ast::expr](token::LPAREN, - token::RPAREN, - some(token::COMMA), - pf, p); - hi = es.span.hi; - ex = expand_syntax_ext(p, es.span, pth, es.node, - none[str]); - } - - case (token::FAIL) { - p.bump(); - ex = ast::expr_fail(p.get_ann()); - } - - case (token::LOG) { - p.bump(); - auto e = parse_expr(p); - auto hi = e.span.hi; - ex = ast::expr_log(1, e, p.get_ann()); - } - - case (token::LOG_ERR) { - p.bump(); - auto e = parse_expr(p); - auto hi = e.span.hi; - ex = ast::expr_log(0, e, p.get_ann()); - } - - case (token::ASSERT) { - p.bump(); - auto e = parse_expr(p); - auto hi = e.span.hi; - ex = ast::expr_assert(e, p.get_ann()); - } - - case (token::CHECK) { - p.bump(); - /* Should be a predicate (pure boolean function) applied to - arguments that are all either slot variables or literals. - but the typechecker enforces that. */ - auto e = parse_expr(p); - auto hi = e.span.hi; - ex = ast::expr_check(e, p.get_ann()); - } - - case (token::RET) { - p.bump(); + ex = ast::expr_rec(fields, base, p.get_ann()); + } 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] { alt (p.peek()) { - case (token::SEMI) { - ex = ast::expr_ret(none[@ast::expr], p.get_ann()); + case (token::UNDERSCORE) { + p.bump(); + ret none[@ast::expr]; } case (_) { - auto e = parse_expr(p); - hi = e.span.hi; - ex = ast::expr_ret(some[@ast::expr](e), p.get_ann()); + ret some[@ast::expr](parse_expr(p)); } } } - case (token::BREAK) { - p.bump(); - ex = ast::expr_break(p.get_ann()); - } - - case (token::CONT) { - p.bump(); - ex = ast::expr_cont(p.get_ann()); - } - - case (token::PUT) { - p.bump(); - alt (p.peek()) { - case (token::SEMI) { - ex = ast::expr_put(none[@ast::expr], p.get_ann()); - } - case (_) { - auto e = parse_expr(p); - hi = e.span.hi; - ex = ast::expr_put(some[@ast::expr](e), p.get_ann()); - } + auto pf = parse_expr_opt; + auto es = parse_seq[option::t[@ast::expr]](token::LPAREN, + token::RPAREN, + some(token::COMMA), + pf, p); + hi = es.span.hi; + ex = ast::expr_bind(e, es.node, p.get_ann()); + } else if (p.peek() == token::POUND) { + p.bump(); + auto pth = parse_path(p); + auto pf = parse_expr; + auto es = parse_seq[@ast::expr](token::LPAREN, + token::RPAREN, + some(token::COMMA), + pf, p); + hi = es.span.hi; + ex = expand_syntax_ext(p, es.span, pth, es.node, + none[str]); + } else if (eat_word(p, "fail")) { + p.bump(); + ex = ast::expr_fail(p.get_ann()); + } else if (eat_word(p, "log")) { + auto e = parse_expr(p); + auto hi = e.span.hi; + ex = ast::expr_log(1, e, p.get_ann()); + } else if (eat_word(p, "log_err")) { + auto e = parse_expr(p); + auto hi = e.span.hi; + ex = ast::expr_log(0, e, p.get_ann()); + } else if (eat_word(p, "assert")) { + auto e = parse_expr(p); + auto hi = e.span.hi; + ex = ast::expr_assert(e, p.get_ann()); + } else if (eat_word(p, "check")) { + /* Should be a predicate (pure boolean function) applied to + arguments that are all either slot variables or literals. + but the typechecker enforces that. */ + auto e = parse_expr(p); + auto hi = e.span.hi; + ex = ast::expr_check(e, p.get_ann()); + } else if (eat_word(p, "ret")) { + alt (p.peek()) { + case (token::SEMI) { + ex = ast::expr_ret(none[@ast::expr], p.get_ann()); + } + case (_) { + auto e = parse_expr(p); + hi = e.span.hi; + ex = ast::expr_ret(some[@ast::expr](e), p.get_ann()); } } - - case (token::BE) { - p.bump(); - auto e = parse_expr(p); - // FIXME: Is this the right place for this check? - if /*check*/ (ast::is_call_expr(e)) { - hi = e.span.hi; - ex = ast::expr_be(e, p.get_ann()); + } else if (eat_word(p, "break")) { + ex = ast::expr_break(p.get_ann()); + } else if (eat_word(p, "cont")) { + ex = ast::expr_cont(p.get_ann()); + } else if (eat_word(p, "put")) { + alt (p.peek()) { + case (token::SEMI) { + ex = ast::expr_put(none[@ast::expr], p.get_ann()); } - else { - p.err("Non-call expression in tail call"); + case (_) { + auto e = parse_expr(p); + hi = e.span.hi; + ex = ast::expr_put(some[@ast::expr](e), p.get_ann()); } } - - case (token::PORT) { - p.bump(); - expect(p, token::LPAREN); - expect(p, token::RPAREN); - hi = p.get_hi_pos(); - ex = ast::expr_port(p.get_ann()); - } - - case (token::CHAN) { - p.bump(); - expect(p, token::LPAREN); - auto e = parse_expr(p); + } else if (eat_word(p, "be")) { + auto e = parse_expr(p); + // FIXME: Is this the right place for this check? + if /*check*/ (ast::is_call_expr(e)) { hi = e.span.hi; - expect(p, token::RPAREN); - ex = ast::expr_chan(e, p.get_ann()); - } - - case (token::SELF) { - log "parsing a self-call..."; - - p.bump(); - expect(p, token::DOT); - // The rest is a call expression. - let @ast::expr f = parse_self_method(p); - auto pf = parse_expr; - auto es = parse_seq[@ast::expr](token::LPAREN, - token::RPAREN, - some(token::COMMA), - pf, p); - hi = es.span.hi; - ex = ast::expr_call(f, es.node, p.get_ann()); - } - - case (_) { - auto lit = parse_lit(p); - hi = lit.span.hi; - ex = ast::expr_lit(@lit, p.get_ann()); - } + ex = ast::expr_be(e, p.get_ann()); + } + else { + p.err("Non-call expression in tail call"); + } + } else if (eat_word(p, "port")) { + expect(p, token::LPAREN); + expect(p, token::RPAREN); + hi = p.get_hi_pos(); + ex = ast::expr_port(p.get_ann()); + } else if (eat_word(p, "chan")) { + expect(p, token::LPAREN); + auto e = parse_expr(p); + hi = e.span.hi; + expect(p, token::RPAREN); + ex = ast::expr_chan(e, p.get_ann()); + } else if (eat_word(p, "self")) { + log "parsing a self-call..."; + + expect(p, token::DOT); + // The rest is a call expression. + let @ast::expr f = parse_self_method(p); + auto pf = parse_expr; + auto es = parse_seq[@ast::expr](token::LPAREN, + token::RPAREN, + some(token::COMMA), + pf, p); + hi = es.span.hi; + ex = ast::expr_call(f, es.node, p.get_ann()); + } else if (is_ident(p.peek()) && !is_word(p, "true") && + !is_word(p, "false")) { + auto pth = parse_path(p); + hi = pth.span.hi; + ex = ast::expr_path(pth, p.get_ann()); + } else { + auto lit = parse_lit(p); + hi = lit.span.hi; + ex = ast::expr_lit(@lit, p.get_ann()); } ret @spanned(lo, hi, ex); @@ -1031,8 +964,7 @@ fn parse_dot_or_call_expr(parser p) -> @ast::expr { fn parse_prefix_expr(parser p) -> @ast::expr { - if (p.peek() == token::MUTABLE) { - p.bump(); + if (eat_word(p, "mutable")) { p.get_session().span_warn(p.get_span(), "ignoring deprecated 'mutable' prefix operator"); } @@ -1113,9 +1045,7 @@ fn prec_table() -> vec[op_spec] { rec(tok=token::BINOP(token::AND), op=ast::bitand, prec=8), rec(tok=token::BINOP(token::CARET), op=ast::bitxor, prec=6), rec(tok=token::BINOP(token::OR), op=ast::bitor, prec=6), - // ast::mul is a bogus placeholder here, AS is special - // cased in parse_more_binops - rec(tok=token::AS, op=ast::mul, prec=5), + // 'as' sits between here with 5 rec(tok=token::LT, op=ast::lt, prec=4), rec(tok=token::LE, op=ast::le, prec=4), rec(tok=token::GE, op=ast::ge, prec=4), @@ -1130,35 +1060,28 @@ fn parse_binops(parser p) -> @ast::expr { ret parse_more_binops(p, parse_prefix_expr(p), 0); } +const int as_prec = 5; + fn parse_more_binops(parser p, @ast::expr lhs, int min_prec) -> @ast::expr { - // Magic nonsense to work around rustboot bug - fn op_eq(token::token a, token::token b) -> bool { - if (a == b) {ret true;} - else {ret false;} - } auto peeked = p.peek(); for (op_spec cur in p.get_prec_table()) { - if (cur.prec > min_prec && op_eq(cur.tok, peeked)) { + if (cur.prec > min_prec && cur.tok == peeked) { p.bump(); - alt (cur.tok) { - case (token::AS) { - auto rhs = parse_ty(p); - auto _as = ast::expr_cast(lhs, rhs, p.get_ann()); - auto span = @spanned(lhs.span.lo, rhs.span.hi, _as); - ret parse_more_binops(p, span, min_prec); - } - case (_) { - auto rhs = parse_more_binops(p, parse_prefix_expr(p), - cur.prec); - auto bin = ast::expr_binary(cur.op, lhs, rhs, - p.get_ann()); - auto span = @spanned(lhs.span.lo, rhs.span.hi, bin); - ret parse_more_binops(p, span, min_prec); - } - } + auto rhs = parse_more_binops(p, parse_prefix_expr(p), + cur.prec); + auto bin = ast::expr_binary(cur.op, lhs, rhs, + p.get_ann()); + auto span = @spanned(lhs.span.lo, rhs.span.hi, bin); + ret parse_more_binops(p, span, min_prec); } } + if (as_prec > min_prec && eat_word(p, "as")) { + auto rhs = parse_ty(p); + auto _as = ast::expr_cast(lhs, rhs, p.get_ann()); + auto span = @spanned(lhs.span.lo, rhs.span.hi, _as); + ret parse_more_binops(p, span, min_prec); + } ret lhs; } @@ -1210,45 +1133,37 @@ fn parse_assign_expr(parser p) -> @ast::expr { } fn parse_if_expr(parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); + auto lo = p.get_last_lo_pos(); - expect(p, token::IF); expect(p, token::LPAREN); auto cond = parse_expr(p); expect(p, token::RPAREN); auto thn = parse_block(p); let option::t[@ast::expr] els = none[@ast::expr]; auto hi = thn.span.hi; - alt (p.peek()) { - case (token::ELSE) { - auto elexpr = parse_else_expr(p); - els = some(elexpr); - hi = elexpr.span.hi; - } - case (_) { /* fall through */ } + if (eat_word(p, "else")) { + auto elexpr = parse_else_expr(p); + els = some(elexpr); + hi = elexpr.span.hi; } ret @spanned(lo, hi, ast::expr_if(cond, thn, els, p.get_ann())); } fn parse_else_expr(parser p) -> @ast::expr { - expect(p, token::ELSE); - alt (p.peek()) { - case (token::IF) { - ret parse_if_expr(p); - } - case (_) { - auto blk = parse_block(p); - ret @spanned(blk.span.lo, blk.span.hi, - ast::expr_block(blk, p.get_ann())); - } + if (eat_word(p, "if")) { + ret parse_if_expr(p); + } else { + auto blk = parse_block(p); + ret @spanned(blk.span.lo, blk.span.hi, + ast::expr_block(blk, p.get_ann())); } } fn parse_head_local(parser p) -> @ast::decl { auto lo = p.get_lo_pos(); let @ast::local local; - if (p.peek() == token::AUTO) { + if (is_word(p, "auto")) { local = parse_auto_local(p); } else { local = parse_typed_local(p); @@ -1259,19 +1174,14 @@ fn parse_head_local(parser p) -> @ast::decl { fn parse_for_expr(parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); - auto is_each = false; + auto lo = p.get_last_lo_pos(); - expect(p, token::FOR); - if (p.peek() == token::EACH) { - is_each = true; - p.bump(); - } + auto is_each = eat_word(p, "each"); expect (p, token::LPAREN); auto decl = parse_head_local(p); - expect(p, token::IN); + expect_word(p, "in"); auto seq = parse_expr(p); expect(p, token::RPAREN); @@ -1288,10 +1198,8 @@ fn parse_for_expr(parser p) -> @ast::expr { fn parse_while_expr(parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); - - expect(p, token::WHILE); - expect (p, token::LPAREN); + auto lo = p.get_last_lo_pos(); + expect(p, token::LPAREN); auto cond = parse_expr(p); expect(p, token::RPAREN); auto body = parse_block(p); @@ -1300,11 +1208,9 @@ fn parse_while_expr(parser p) -> @ast::expr { } fn parse_do_while_expr(parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); - - expect(p, token::DO); + auto lo = p.get_last_lo_pos(); auto body = parse_block(p); - expect(p, token::WHILE); + expect_word(p, "while"); expect (p, token::LPAREN); auto cond = parse_expr(p); expect(p, token::RPAREN); @@ -1313,8 +1219,7 @@ fn parse_do_while_expr(parser p) -> @ast::expr { } fn parse_alt_expr(parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); - expect(p, token::ALT); + auto lo = p.get_last_lo_pos(); expect(p, token::LPAREN); auto discriminant = parse_expr(p); expect(p, token::RPAREN); @@ -1322,36 +1227,17 @@ fn parse_alt_expr(parser p) -> @ast::expr { let vec[ast::arm] arms = vec(); while (p.peek() != token::RBRACE) { - alt (p.peek()) { - case (token::CASE) { - p.bump(); - expect(p, token::LPAREN); - auto pat = parse_pat(p); - expect(p, token::RPAREN); - auto block = parse_block(p); - arms += vec(rec(pat=pat, block=block)); - } - - // FIXME: this is a vestigial form left over from - // rustboot, we're keeping it here for source-compat - // for the time being but it should be flushed out - // once we've bootstrapped. When we see 'else {' here, - // we pretend we saw 'case (_) {'. It has the same - // meaning, and only exists due to the cexp/pexp split - // in rustboot, which we're not maintaining. - - case (token::ELSE) { - p.bump(); - auto hi = p.get_hi_pos(); - auto pat = @spanned(lo, hi, ast::pat_wild(p.get_ann())); - auto block = parse_block(p); - arms += vec(rec(pat=pat, block=block)); - } - case (token::RBRACE) { /* empty */ } - case (?tok) { - p.err("expected 'case' or '}' when parsing 'alt' statement " + - "but found " + token::to_str(p.get_reader(), tok)); - } + if (eat_word(p, "case")) { + expect(p, token::LPAREN); + auto pat = parse_pat(p); + expect(p, token::RPAREN); + auto block = parse_block(p); + arms += vec(rec(pat=pat, block=block)); + } else if (p.peek() == token::RBRACE) { + /* empty */ + } else { + p.err("expected 'case' or '}' when parsing 'alt' statement " + + "but found " + token::to_str(p.get_reader(), p.peek())); } } auto hi = p.get_hi_pos(); @@ -1362,9 +1248,7 @@ fn parse_alt_expr(parser p) -> @ast::expr { } fn parse_spawn_expr(parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); - expect(p, token::SPAWN); - + auto lo = p.get_last_lo_pos(); // FIXME: Parse domain and name // FIXME: why no full expr? auto fn_expr = parse_bottom_expr(p); @@ -1395,34 +1279,24 @@ fn parse_expr_res(parser p, restriction r) -> @ast::expr { } fn parse_expr_inner(parser p) -> @ast::expr { - alt (p.peek()) { - case (token::LBRACE) { - auto blk = parse_block(p); - ret @spanned(blk.span.lo, blk.span.hi, - ast::expr_block(blk, p.get_ann())); - } - case (token::IF) { - ret parse_if_expr(p); - } - case (token::FOR) { - ret parse_for_expr(p); - } - case (token::WHILE) { - ret parse_while_expr(p); - } - case (token::DO) { - ret parse_do_while_expr(p); - } - case (token::ALT) { - ret parse_alt_expr(p); - } - case (token::SPAWN) { - ret parse_spawn_expr(p); - } - case (_) { - ret parse_assign_expr(p); - } - + if (p.peek() == token::LBRACE) { + auto blk = parse_block(p); + ret @spanned(blk.span.lo, blk.span.hi, + ast::expr_block(blk, p.get_ann())); + } else if (eat_word(p, "if")) { + ret parse_if_expr(p); + } else if (eat_word(p, "for")) { + ret parse_for_expr(p); + } else if (eat_word(p, "while")) { + ret parse_while_expr(p); + } else if (eat_word(p, "do")) { + ret parse_do_while_expr(p); + } else if (eat_word(p, "alt")) { + ret parse_alt_expr(p); + } else if (eat_word(p, "spawn")) { + ret parse_spawn_expr(p); + } else { + ret parse_assign_expr(p); } } @@ -1470,29 +1344,30 @@ fn parse_pat(parser p) -> @ast::pat { } } } - case (token::IDENT(_)) { - auto tag_path = parse_path(p); - hi = tag_path.span.hi; + case (?tok) { + if (!is_ident(tok) || is_word(p, "true") || is_word(p, "false")) { + auto lit = parse_lit(p); + hi = lit.span.hi; + pat = ast::pat_lit(@lit, p.get_ann()); + } else { + auto tag_path = parse_path(p); + hi = tag_path.span.hi; - let vec[@ast::pat] args; - alt (p.peek()) { - case (token::LPAREN) { - auto f = parse_pat; - auto a = parse_seq[@ast::pat](token::LPAREN, - token::RPAREN, - some(token::COMMA), f, p); - args = a.node; - hi = a.span.hi; + let vec[@ast::pat] args; + alt (p.peek()) { + case (token::LPAREN) { + auto f = parse_pat; + auto a = parse_seq(token::LPAREN, + token::RPAREN, + some(token::COMMA), f, p); + args = a.node; + hi = a.span.hi; + } + case (_) { args = vec(); } } - case (_) { args = vec(); } - } - pat = ast::pat_tag(tag_path, args, p.get_ann()); - } - case (_) { - auto lit = parse_lit(p); - hi = lit.span.hi; - pat = ast::pat_lit(@lit, p.get_ann()); + pat = ast::pat_tag(tag_path, args, p.get_ann()); + } } } @@ -1521,15 +1396,13 @@ fn parse_auto_local(parser p) -> @ast::local { } fn parse_let(parser p) -> @ast::decl { - auto lo = p.get_lo_pos(); - expect(p, token::LET); + auto lo = p.get_last_lo_pos(); auto local = parse_typed_local(p); ret @spanned(lo, p.get_hi_pos(), ast::decl_local(local)); } fn parse_auto(parser p) -> @ast::decl { - auto lo = p.get_lo_pos(); - expect(p, token::AUTO); + auto lo = p.get_last_lo_pos(); auto local = parse_auto_local(p); ret @spanned(lo, p.get_hi_pos(), ast::decl_local(local)); } @@ -1550,35 +1423,28 @@ fn parse_crate_stmt(parser p) -> @ast::stmt { fn parse_source_stmt(parser p) -> @ast::stmt { auto lo = p.get_lo_pos(); - alt (p.peek()) { - - case (token::LET) { - auto decl = parse_let(p); - auto hi = p.get_span(); - ret @spanned - (lo, decl.span.hi, ast::stmt_decl(decl, p.get_ann())); - } + if (eat_word(p, "let")) { + auto decl = parse_let(p); + auto hi = p.get_span(); + ret @spanned + (lo, decl.span.hi, ast::stmt_decl(decl, p.get_ann())); + } else if (eat_word(p, "auto")) { + auto decl = parse_auto(p); + auto hi = p.get_span(); + ret @spanned(lo, decl.span.hi, ast::stmt_decl(decl, p.get_ann())); + } else { + if (peeking_at_item(p)) { + // Might be a local item decl. + auto i = parse_item(p); + auto hi = i.span.hi; + auto decl = @spanned(lo, hi, ast::decl_item(i)); + ret @spanned(lo, hi, ast::stmt_decl(decl, p.get_ann())); - case (token::AUTO) { - auto decl = parse_auto(p); + } else { + // Remainder are line-expr stmts. + auto e = parse_expr(p); auto hi = p.get_span(); - ret @spanned(lo, decl.span.hi, ast::stmt_decl(decl, p.get_ann())); - } - - case (_) { - if (peeking_at_item(p)) { - // Might be a local item decl. - auto i = parse_item(p); - auto hi = i.span.hi; - auto decl = @spanned(lo, hi, ast::decl_item(i)); - ret @spanned(lo, hi, ast::stmt_decl(decl, p.get_ann())); - - } else { - // Remainder are line-expr stmts. - auto e = parse_expr(p); - auto hi = p.get_span(); - ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_ann())); - } + ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_ann())); } } p.err("expected statement"); @@ -1761,9 +1627,9 @@ fn parse_fn_header(parser p) ret tup(id, ty_params); } -fn parse_item_fn_or_iter(parser p, ast::purity purity) -> @ast::item { - auto lo = p.get_lo_pos(); - auto proto = parse_proto(p); +fn parse_item_fn_or_iter(parser p, ast::purity purity, ast::proto proto) + -> @ast::item { + auto lo = p.get_last_lo_pos(); auto t = parse_fn_header(p); auto f = parse_fn(p, proto, purity); auto item = ast::item_fn(t._0, f, t._1, @@ -1790,8 +1656,7 @@ fn parse_method(parser p) -> @ast::method { } fn parse_dtor(parser p) -> @ast::method { - auto lo = p.get_lo_pos(); - expect(p, token::DROP); + auto lo = p.get_last_lo_pos(); let ast::block b = parse_block(p); let vec[ast::arg] inputs = vec(); let @ast::ty output = @spanned(lo, lo, ast::ty_nil); @@ -1809,8 +1674,7 @@ fn parse_dtor(parser p) -> @ast::method { } fn parse_item_obj(parser p, ast::layer lyr) -> @ast::item { - auto lo = p.get_lo_pos(); - expect(p, token::OBJ); + auto lo = p.get_last_lo_pos(); auto ident = parse_ident(p); auto ty_params = parse_ty_params(p); auto pf = parse_obj_field; @@ -1826,14 +1690,11 @@ fn parse_item_obj(parser p, ast::layer lyr) -> @ast::item { expect(p, token::LBRACE); while (p.peek() != token::RBRACE) { - alt (p.peek()) { - case (token::DROP) { - dtor = some[@ast::method](parse_dtor(p)); - } - case (_) { - _vec::push[@ast::method](meths, - parse_method(p)); - } + if (eat_word(p, "drop")) { + dtor = some[@ast::method](parse_dtor(p)); + } else { + _vec::push[@ast::method](meths, + parse_method(p)); } } auto hi = p.get_hi_pos(); @@ -1859,8 +1720,7 @@ fn parse_mod_items(parser p, token::token term) -> ast::_mod { } fn parse_item_const(parser p) -> @ast::item { - auto lo = p.get_lo_pos(); - expect(p, token::CONST); + auto lo = p.get_last_lo_pos(); auto ty = parse_ty(p); auto id = parse_ident(p); expect(p, token::EQ); @@ -1872,8 +1732,7 @@ fn parse_item_const(parser p) -> @ast::item { } fn parse_item_mod(parser p) -> @ast::item { - auto lo = p.get_lo_pos(); - expect(p, token::MOD); + auto lo = p.get_last_lo_pos(); auto id = parse_ident(p); expect(p, token::LBRACE); auto m = parse_mod_items(p, token::RBRACE); @@ -1892,8 +1751,7 @@ fn parse_item_native_type(parser p) -> @ast::native_item { } fn parse_item_native_fn(parser p) -> @ast::native_item { - auto lo = p.get_lo_pos(); - expect(p, token::FN); + auto lo = p.get_last_lo_pos(); auto t = parse_fn_header(p); auto decl = parse_fn_decl(p, ast::impure_fn); auto link_name = none[str]; @@ -1911,17 +1769,13 @@ fn parse_item_native_fn(parser p) -> @ast::native_item { fn parse_native_item(parser p) -> @ast::native_item { let ast::layer lyr = parse_layer(p); - alt (p.peek()) { - case (token::TYPE) { - ret parse_item_native_type(p); - } - case (token::FN) { - ret parse_item_native_fn(p); - } - case (?t) { - unexpected(p, t); - fail; - } + if (eat_word(p, "type")) { + ret parse_item_native_type(p); + } else if (eat_word(p, "fn")) { + ret parse_item_native_fn(p); + } else { + unexpected(p, p.peek()); + fail; } } @@ -1955,10 +1809,9 @@ fn default_native_name(session::session sess, str id) -> str { } fn parse_item_native_mod(parser p) -> @ast::item { - auto lo = p.get_lo_pos(); - expect(p, token::NATIVE); + auto lo = p.get_last_lo_pos(); auto abi = ast::native_abi_cdecl; - if (p.peek() != token::MOD) { + if (!is_word(p, "mod")) { auto t = parse_str_lit_or_env_ident(p); if (_str::eq(t, "cdecl")) { } else if (_str::eq(t, "rust")) { @@ -1972,7 +1825,7 @@ fn parse_item_native_mod(parser p) -> @ast::item { fail; } } - expect(p, token::MOD); + expect_word(p, "mod"); auto id = parse_ident(p); auto native_name; if (p.peek() == token::EQ) { @@ -1990,8 +1843,7 @@ fn parse_item_native_mod(parser p) -> @ast::item { } fn parse_type_decl(parser p) -> tup(uint, ast::ident) { - auto lo = p.get_lo_pos(); - expect(p, token::TYPE); + auto lo = p.get_last_lo_pos(); auto id = parse_ident(p); ret tup(lo, id); } @@ -2009,8 +1861,7 @@ fn parse_item_type(parser p) -> @ast::item { } fn parse_item_tag(parser p) -> @ast::item { - auto lo = p.get_lo_pos(); - expect(p, token::TAG); + auto lo = p.get_last_lo_pos(); auto id = parse_ident(p); auto ty_params = parse_ty_params(p); @@ -2063,97 +1914,75 @@ fn parse_item_tag(parser p) -> @ast::item { fn parse_layer(parser p) -> ast::layer { - alt (p.peek()) { - case (token::STATE) { - p.bump(); - ret ast::layer_state; - } - case (token::GC) { - p.bump(); - ret ast::layer_gc; - } - case (_) { - ret ast::layer_value; - } + if (eat_word(p, "state")) { + ret ast::layer_state; + } else if (eat_word(p, "gc")) { + ret ast::layer_gc; + } else { + ret ast::layer_value; } fail; } fn parse_auth(parser p) -> ast::_auth { - alt (p.peek()) { - case (token::UNSAFE) { - p.bump(); - ret ast::auth_unsafe; - } - case (?t) { - unexpected(p, t); - } + if (eat_word(p, "unsafe")) { + ret ast::auth_unsafe; + } else { + unexpected(p, p.peek()); } fail; } fn peeking_at_item(parser p) -> bool { alt (p.peek()) { - case (token::STATE) { ret true; } - case (token::GC) { ret true; } - case (token::CONST) { ret true; } - case (token::FN) { ret true; } - case (token::PRED) { ret true; } - case (token::ITER) { ret true; } - case (token::MOD) { ret true; } - case (token::TYPE) { ret true; } - case (token::TAG) { ret true; } - case (token::OBJ) { ret true; } + case (token::IDENT(?sid)) { + auto st = p.get_str(sid); + ret _str::eq(st, "state") || + _str::eq(st, "gc") || + _str::eq(st, "const") || + _str::eq(st, "fn") || + _str::eq(st, "pred") || + _str::eq(st, "iter") || + _str::eq(st, "mod") || + _str::eq(st, "type") || + _str::eq(st, "tag") || + _str::eq(st, "obj"); + } case (_) { ret false; } } - ret false; } fn parse_item(parser p) -> @ast::item { let ast::layer lyr = parse_layer(p); - alt (p.peek()) { - case (token::CONST) { - assert (lyr == ast::layer_value); - ret parse_item_const(p); - } - - case (token::FN) { - assert (lyr == ast::layer_value); - ret parse_item_fn_or_iter(p, ast::impure_fn); - } - - case (token::PRED) { - assert (lyr == ast::layer_value); - ret parse_item_fn_or_iter(p, ast::pure_fn); - } - - case (token::ITER) { - assert (lyr == ast::layer_value); - ret parse_item_fn_or_iter(p, ast::impure_fn); - } - case (token::MOD) { - assert (lyr == ast::layer_value); - ret parse_item_mod(p); - } - case (token::NATIVE) { - assert (lyr == ast::layer_value); - ret parse_item_native_mod(p); - } - case (token::TYPE) { - ret parse_item_type(p); - } - case (token::TAG) { - ret parse_item_tag(p); - } - case (token::OBJ) { - ret parse_item_obj(p, lyr); - } - case (?t) { - p.err("expected item but found " + - token::to_str(p.get_reader(), t)); - } + if (eat_word(p, "const")) { + assert (lyr == ast::layer_value); + ret parse_item_const(p); + } else if (eat_word(p, "fn")) { + assert (lyr == ast::layer_value); + ret parse_item_fn_or_iter(p, ast::impure_fn, ast::proto_fn); + } else if (eat_word(p, "pred")) { + assert (lyr == ast::layer_value); + ret parse_item_fn_or_iter(p, ast::pure_fn, ast::proto_fn); + } else if (eat_word(p, "iter")) { + assert (lyr == ast::layer_value); + ret parse_item_fn_or_iter(p, ast::impure_fn, ast::proto_iter); + } else if (eat_word(p, "mod")) { + assert (lyr == ast::layer_value); + ret parse_item_mod(p); + } else if (eat_word(p, "native")) { + assert (lyr == ast::layer_value); + ret parse_item_native_mod(p); + } else if (eat_word(p, "type")) { + ret parse_item_type(p); + } else if (eat_word(p, "tag")) { + ret parse_item_tag(p); + } else if (eat_word(p, "obj")) { + ret parse_item_obj(p, lyr); + } else { + p.err("expected item but found " + + token::to_str(p.get_reader(), p.peek())); } fail; } @@ -2195,8 +2024,7 @@ fn parse_optional_meta(parser p) -> vec[@ast::meta_item] { } fn parse_use(parser p) -> @ast::view_item { - auto lo = p.get_lo_pos(); - expect(p, token::USE); + auto lo = p.get_last_lo_pos(); auto ident = parse_ident(p); auto metadata = parse_optional_meta(p); auto hi = p.get_hi_pos(); @@ -2248,7 +2076,6 @@ fn parse_full_import_name(parser p, ast::ident def_ident) } fn parse_import(parser p) -> @ast::view_item { - expect(p, token::IMPORT); alt (p.peek()) { case (token::IDENT(?i)) { p.bump(); @@ -2271,8 +2098,7 @@ fn parse_import(parser p) -> @ast::view_item { } fn parse_export(parser p) -> @ast::view_item { - auto lo = p.get_lo_pos(); - expect(p, token::EXPORT); + auto lo = p.get_last_lo_pos(); auto id = parse_ident(p); auto hi = p.get_hi_pos(); expect(p, token::SEMI); @@ -2280,32 +2106,32 @@ fn parse_export(parser p) -> @ast::view_item { } fn parse_view_item(parser p) -> @ast::view_item { - alt (p.peek()) { - case (token::USE) { - ret parse_use(p); - } - case (token::IMPORT) { - ret parse_import(p); - } - case (token::EXPORT) { - ret parse_export(p); - } + if (eat_word(p, "use")) { + ret parse_use(p); + } else if (eat_word(p, "import")) { + ret parse_import(p); + } else if (eat_word(p, "export")) { + ret parse_export(p); + } else { + fail; } } -fn is_view_item(token::token t) -> bool { - alt (t) { - case (token::USE) { ret true; } - case (token::IMPORT) { ret true; } - case (token::EXPORT) { ret true; } - case (_) {} +fn is_view_item(&parser p) -> bool { + alt (p.peek()) { + case (token::IDENT(?sid)) { + auto st = p.get_str(sid); + ret _str::eq(st, "use") || _str::eq(st, "import") || + _str::eq(st, "export"); + } + case (_) { ret false; } } ret false; } fn parse_view(parser p) -> vec[@ast::view_item] { let vec[@ast::view_item] items = vec(); - while (is_view_item(p.peek())) { + while (is_view_item(p)) { items += vec(parse_view_item(p)); } ret items; @@ -2313,7 +2139,7 @@ fn parse_view(parser p) -> vec[@ast::view_item] { fn parse_native_view(parser p) -> vec[@ast::view_item] { let vec[@ast::view_item] items = vec(); - while (is_view_item(p.peek())) { + while (is_view_item(p)) { items += vec(parse_view_item(p)); } ret items; @@ -2337,99 +2163,79 @@ fn parse_crate_from_source_file(parser p) -> @ast::crate { fn parse_crate_directive(parser p) -> ast::crate_directive { auto lo = p.get_lo_pos(); - alt (p.peek()) { - case (token::AUTH) { - p.bump(); - auto n = parse_path(p); - expect(p, token::EQ); - auto a = parse_auth(p); - auto hi = p.get_hi_pos(); - expect(p, token::SEMI); - ret spanned(lo, hi, ast::cdir_auth(n, a)); - } - - case (token::META) { - p.bump(); - auto mis = parse_meta(p); - auto hi = p.get_hi_pos(); - expect(p, token::SEMI); - ret spanned(lo, hi, ast::cdir_meta(mis)); - } - - case (token::MOD) { - p.bump(); - auto id = parse_ident(p); - auto file_opt = none[filename]; - alt (p.peek()) { - case (token::EQ) { - p.bump(); - // FIXME: turn this into parse+eval expr - file_opt = some[filename](parse_str_lit_or_env_ident(p)); - } - case (_) {} + if (eat_word(p, "auth")) { + auto n = parse_path(p); + expect(p, token::EQ); + auto a = parse_auth(p); + auto hi = p.get_hi_pos(); + expect(p, token::SEMI); + ret spanned(lo, hi, ast::cdir_auth(n, a)); + } else if (eat_word(p, "meta")) { + auto mis = parse_meta(p); + auto hi = p.get_hi_pos(); + expect(p, token::SEMI); + ret spanned(lo, hi, ast::cdir_meta(mis)); + } else if (eat_word(p, "mod")) { + auto id = parse_ident(p); + auto file_opt = none[filename]; + alt (p.peek()) { + case (token::EQ) { + p.bump(); + // FIXME: turn this into parse+eval expr + file_opt = some[filename](parse_str_lit_or_env_ident(p)); } + case (_) {} + } - alt (p.peek()) { - - // mod x = "foo.rs"; - - case (token::SEMI) { - auto hi = p.get_hi_pos(); - p.bump(); - ret spanned(lo, hi, ast::cdir_src_mod(id, file_opt)); - } - - // mod x = "foo_dir" { ...directives... } + alt (p.peek()) { - case (token::LBRACE) { - p.bump(); - auto cdirs = parse_crate_directives(p, token::RBRACE); - auto hi = p.get_hi_pos(); - expect(p, token::RBRACE); - ret spanned(lo, hi, - ast::cdir_dir_mod(id, file_opt, cdirs)); - } + // mod x = "foo.rs"; - case (?t) { - unexpected(p, t); - } + case (token::SEMI) { + auto hi = p.get_hi_pos(); + p.bump(); + ret spanned(lo, hi, ast::cdir_src_mod(id, file_opt)); } - } - - case (token::LET) { - p.bump(); - expect(p, token::LPAREN); - auto id = parse_ident(p); - expect(p, token::EQ); - auto x = parse_expr(p); - expect(p, token::RPAREN); - expect(p, token::LBRACE); - auto v = parse_crate_directives(p, token::RBRACE); - auto hi = p.get_hi_pos(); - expect(p, token::RBRACE); - ret spanned(lo, hi, ast::cdir_let(id, x, v)); - } - case (token::USE) { - auto vi = parse_view_item(p); - ret spanned(lo, vi.span.hi, ast::cdir_view_item(vi)); - } + // mod x = "foo_dir" { ...directives... } - case (token::IMPORT) { - auto vi = parse_view_item(p); - ret spanned(lo, vi.span.hi, ast::cdir_view_item(vi)); - } - - case (token::EXPORT) { - auto vi = parse_view_item(p); - ret spanned(lo, vi.span.hi, ast::cdir_view_item(vi)); - } + case (token::LBRACE) { + p.bump(); + auto cdirs = parse_crate_directives(p, token::RBRACE); + auto hi = p.get_hi_pos(); + expect(p, token::RBRACE); + ret spanned(lo, hi, + ast::cdir_dir_mod(id, file_opt, cdirs)); + } - case (_) { - auto x = parse_expr(p); - ret spanned(lo, x.span.hi, ast::cdir_expr(x)); + case (?t) { + unexpected(p, t); + } } + } else if (eat_word(p, "let")) { + expect(p, token::LPAREN); + auto id = parse_ident(p); + expect(p, token::EQ); + auto x = parse_expr(p); + expect(p, token::RPAREN); + expect(p, token::LBRACE); + auto v = parse_crate_directives(p, token::RBRACE); + auto hi = p.get_hi_pos(); + expect(p, token::RBRACE); + ret spanned(lo, hi, ast::cdir_let(id, x, v)); + } else if (is_word(p, "use")) { + auto vi = parse_view_item(p); + ret spanned(lo, vi.span.hi, ast::cdir_view_item(vi)); + } else if (is_word(p, "import")) { + auto vi = parse_view_item(p); + ret spanned(lo, vi.span.hi, ast::cdir_view_item(vi)); + } else if (is_word(p, "export")) { + auto vi = parse_view_item(p); + ret spanned(lo, vi.span.hi, ast::cdir_view_item(vi)); + } else { + auto x = parse_expr(p); + ret spanned(lo, x.span.hi, ast::cdir_expr(x)); } fail; } diff --git a/src/comp/front/token.rs b/src/comp/front/token.rs index 60091afc..171fa5f2 100644 --- a/src/comp/front/token.rs +++ b/src/comp/front/token.rs @@ -38,9 +38,6 @@ tag token { BINOP(binop); BINOPEQ(binop); - AS; - WITH; - /* Structural symbols */ AT; DOT; @@ -59,73 +56,8 @@ tag token { LBRACE; RBRACE; - /* Module and crate keywords */ - MOD; - USE; - AUTH; - META; - - /* Metaprogramming keywords */ - SYNTAX; POUND; - /* Statement keywords */ - IF; - ELSE; - DO; - WHILE; - ALT; - CASE; - - BREAK; - CONT; - - FAIL; - DROP; - - IN; - FOR; - EACH; - PUT; - RET; - BE; - - /* Type and type-state keywords */ - TYPE; - ASSERT; - CHECK; - CLAIM; - PROVE; - - /* Layer keywords */ - STATE; - GC; - - /* Unsafe-block keyword */ - UNSAFE; - - /* Type qualifiers */ - NATIVE; - AUTO; - MUTABLE; - - /* Name management */ - IMPORT; - EXPORT; - - /* Value / stmt declarators */ - LET; - CONST; - - /* Magic runtime services */ - LOG; - LOG_ERR; - SPAWN; - BIND; - THREAD; - YIELD; - JOIN; - /* Literals */ LIT_INT(int); LIT_UINT(uint); @@ -141,36 +73,6 @@ tag token { IDX(int); UNDERSCORE; - /* Reserved type names */ - BOOL; - INT; - UINT; - FLOAT; - CHAR; - STR; - MACH(ty_mach); - - /* Algebraic type constructors */ - REC; - TUP; - TAG; - VEC; - ANY; - - /* Callable type constructors */ - FN; - PRED; - ITER; - - /* Object type and related keywords */ - OBJ; - SELF; - - /* Comm and task types */ - CHAN; - PORT; - TASK; - BRACEQUOTE(str_num); EOF; } @@ -209,10 +111,6 @@ fn to_str(lexer::reader r, token t) -> str { case (BINOP(?op)) { ret binop_to_str(op); } case (BINOPEQ(?op)) { ret binop_to_str(op) + "="; } - case (AS) { ret "as"; } - case (WITH) { ret "with"; } - - /* Structural symbols */ case (AT) { ret "@"; } case (DOT) { ret "."; } @@ -231,73 +129,8 @@ fn to_str(lexer::reader r, token t) -> str { case (LBRACE) { ret "{"; } case (RBRACE) { ret "}"; } - /* Module and crate keywords */ - case (MOD) { ret "mod"; } - case (USE) { ret "use"; } - case (AUTH) { ret "auth"; } - case (META) { ret "meta"; } - - /* Metaprogramming keywords */ - case (SYNTAX) { ret "syntax"; } case (POUND) { ret "#"; } - /* Statement keywords */ - case (IF) { ret "if"; } - case (ELSE) { ret "else"; } - case (DO) { ret "do"; } - case (WHILE) { ret "while"; } - case (ALT) { ret "alt"; } - case (CASE) { ret "case"; } - - case (BREAK) { ret "break"; } - case (CONT) { ret "cont"; } - - case (FAIL) { ret "fail"; } - case (DROP) { ret "drop"; } - - case (IN) { ret "in"; } - case (FOR) { ret "for"; } - case (EACH) { ret "each"; } - case (PUT) { ret "put"; } - case (RET) { ret "ret"; } - case (BE) { ret "be"; } - - /* Type and type-state keywords */ - case (TYPE) { ret "type"; } - case (ASSERT) { ret "assert"; } - case (CHECK) { ret "check"; } - case (CLAIM) { ret "claim"; } - case (PROVE) { ret "prove"; } - - /* Layer keywords */ - case (STATE) { ret "state"; } - case (GC) { ret "gc"; } - - /* Unsafe-block keyword */ - case (UNSAFE) { ret "unsafe"; } - - /* Type qualifiers */ - case (NATIVE) { ret "native"; } - case (AUTO) { ret "auto"; } - case (MUTABLE) { ret "mutable"; } - - /* Name management */ - case (IMPORT) { ret "import"; } - case (EXPORT) { ret "export"; } - - /* Value / stmt declarators */ - case (LET) { ret "let"; } - case (CONST) { ret "const"; } - - /* Magic runtime services */ - case (LOG) { ret "log"; } - case (LOG_ERR) { ret "log_err"; } - case (SPAWN) { ret "spawn"; } - case (BIND) { ret "bind"; } - case (THREAD) { ret "thread"; } - case (YIELD) { ret "yield"; } - case (JOIN) { ret "join"; } - /* Literals */ case (LIT_INT(?i)) { ret _int::to_str(i, 10u); } case (LIT_UINT(?u)) { ret _uint::to_str(u, 10u); } @@ -328,44 +161,11 @@ fn to_str(lexer::reader r, token t) -> str { /* Name components */ case (IDENT(?s)) { - auto si = "ident:"; - si += r.get_str(s); - ret si; + ret r.get_str(s); } case (IDX(?i)) { ret "_" + _int::to_str(i, 10u); } case (UNDERSCORE) { ret "_"; } - /* Reserved type names */ - case (BOOL) { ret "bool"; } - case (INT) { ret "int"; } - case (UINT) { ret "uint"; } - case (FLOAT) { ret "float"; } - case (CHAR) { ret "char"; } - case (STR) { ret "str"; } - case (MACH(?tm)) { ret ty_mach_to_str(tm); } - - /* Algebraic type constructors */ - case (REC) { ret "rec"; } - case (TUP) { ret "tup"; } - case (TAG) { ret "tag"; } - case (VEC) { ret "vec"; } - case (ANY) { ret "any"; } - - /* Callable type constructors */ - case (FN) { ret "fn"; } - case (PRED) { ret "pred"; } - case (ITER) { ret "iter"; } - - /* Object type */ - case (OBJ) { ret "obj"; } - case (SELF) { ret "self"; } - - - /* Comm and task types */ - case (CHAN) { ret "chan"; } - case (PORT) { ret "port"; } - case (TASK) { ret "task"; } - case (BRACEQUOTE(_)) { ret "<bracequote>"; } case (EOF) { ret "<eof>"; } } diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index 3c959b99..0bdd5c83 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -9,7 +9,6 @@ import util::common; import pp::end; import pp::wrd; import pp::space; import pp::line; const uint indent_unit = 4u; -const int as_prec = 5; const uint default_columns = 78u; type ps = @rec(pp::ps s, @@ -494,7 +493,7 @@ fn print_expr(ps s, &@ast::expr expr) { print_literal(s, lit); } case (ast::expr_cast(?expr,?ty,_)) { - print_maybe_parens(s, expr, as_prec); + print_maybe_parens(s, expr, front::parser::as_prec); space(s.s); wrd1(s, "as"); print_type(s, ty); @@ -888,7 +887,7 @@ fn print_maybe_parens(ps s, @ast::expr expr, int outer_prec) { add_them = operator_prec(op) < outer_prec; } case (ast::expr_cast(_,_,_)) { - add_them = as_prec < outer_prec; + add_them = front::parser::as_prec < outer_prec; } case (_) { add_them = false; diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index ca5534b3..0267084e 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -73,7 +73,7 @@ mod lib { mod llvm; } } - else { + case (_) { let (llvm_lib = "librustllvm.so") { mod llvm; } diff --git a/src/lib/std.rc b/src/lib/std.rc index 5c0ea313..6e2650e6 100644 --- a/src/lib/std.rc +++ b/src/lib/std.rc @@ -51,7 +51,7 @@ alt (target_os) { } case ("macos") { mod os = "macos_os.rs"; mod os_fs = "posix_fs.rs"; - } else { + } case (_) { mod os = "linux_os.rs"; mod os_fs = "posix_fs.rs"; } |