diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-07-27 14:19:39 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-07-27 15:54:33 +0200 |
| commit | df7f21db093b0f206048b18e977161f91b7c28f1 (patch) | |
| tree | 36c56d12572266bd0b8d2b3379e52d04bf0e9152 /src/comp/syntax/parse | |
| parent | 0e3ee39c41462652f41993a5610265abea6daa96 (diff) | |
| download | rust-df7f21db093b0f206048b18e977161f91b7c28f1.tar.gz rust-df7f21db093b0f206048b18e977161f91b7c28f1.zip | |
Reformat for new syntax
Diffstat (limited to 'src/comp/syntax/parse')
| -rw-r--r-- | src/comp/syntax/parse/eval.rs | 127 | ||||
| -rw-r--r-- | src/comp/syntax/parse/lexer.rs | 779 | ||||
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 2980 | ||||
| -rw-r--r-- | src/comp/syntax/parse/token.rs | 213 |
4 files changed, 2015 insertions, 2084 deletions
diff --git a/src/comp/syntax/parse/eval.rs b/src/comp/syntax/parse/eval.rs index 6f551b92943..08a60404172 100644 --- a/src/comp/syntax/parse/eval.rs +++ b/src/comp/syntax/parse/eval.rs @@ -16,82 +16,79 @@ export mode_parse; tag eval_mode { mode_depend; mode_parse; } type ctx = - @rec(parser p, - eval_mode mode, - mutable str[] deps, - parser::parse_sess sess, - mutable uint chpos, - mutable uint byte_pos, - ast::crate_cfg cfg); + @{p: parser, + mode: eval_mode, + mutable deps: str[], + sess: parser::parse_sess, + mutable chpos: uint, + mutable byte_pos: uint, + cfg: ast::crate_cfg}; -fn eval_crate_directives(ctx cx, &(@ast::crate_directive)[] cdirs, - str prefix, &mutable (@ast::view_item)[] view_items, - &mutable (@ast::item)[] items) { - for (@ast::crate_directive sub_cdir in cdirs) { +fn eval_crate_directives(cx: ctx, cdirs: &(@ast::crate_directive)[], + prefix: str, + view_items: &mutable (@ast::view_item)[], + items: &mutable (@ast::item)[]) { + for sub_cdir: @ast::crate_directive in cdirs { eval_crate_directive(cx, sub_cdir, prefix, view_items, items); } } -fn eval_crate_directives_to_mod(ctx cx, &(@ast::crate_directive)[] cdirs, - str prefix) -> ast::_mod { - let (@ast::view_item)[] view_items = ~[]; - let (@ast::item)[] items = ~[]; +fn eval_crate_directives_to_mod(cx: ctx, cdirs: &(@ast::crate_directive)[], + prefix: str) -> ast::_mod { + let view_items: (@ast::view_item)[] = ~[]; + let items: (@ast::item)[] = ~[]; eval_crate_directives(cx, cdirs, prefix, view_items, items); - ret rec(view_items=view_items, items=items); + ret {view_items: view_items, items: items}; } -fn eval_crate_directive(ctx cx, @ast::crate_directive cdir, str prefix, - &mutable (@ast::view_item)[] view_items, - &mutable (@ast::item)[] items) { - alt (cdir.node) { - case (ast::cdir_src_mod(?id, ?file_opt, ?attrs)) { - auto file_path = id + ".rs"; - alt (file_opt) { - case (some(?f)) { file_path = f; } - case (none) { } - } - auto full_path = if (std::fs::path_is_absolute(file_path)) { +fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, + view_items: &mutable (@ast::view_item)[], + items: &mutable (@ast::item)[]) { + alt cdir.node { + ast::cdir_src_mod(id, file_opt, attrs) { + let file_path = id + ".rs"; + alt file_opt { some(f) { file_path = f; } none. { } } + let full_path = + if std::fs::path_is_absolute(file_path) { file_path - } else { - prefix + std::fs::path_sep() + file_path - }; - if (cx.mode == mode_depend) { cx.deps += ~[full_path]; ret; } - auto p0 = - new_parser_from_file(cx.sess, cx.cfg, full_path, cx.chpos, - cx.byte_pos); - auto inner_attrs = parse_inner_attrs_and_next(p0); - auto mod_attrs = attrs + inner_attrs.inner; - auto first_item_outer_attrs = inner_attrs.next; - auto m0 = parse_mod_items(p0, token::EOF, first_item_outer_attrs); + } else { prefix + std::fs::path_sep() + file_path }; + if cx.mode == mode_depend { cx.deps += ~[full_path]; ret; } + let p0 = + new_parser_from_file(cx.sess, cx.cfg, full_path, cx.chpos, + cx.byte_pos); + let inner_attrs = parse_inner_attrs_and_next(p0); + let mod_attrs = attrs + inner_attrs.inner; + let first_item_outer_attrs = inner_attrs.next; + let m0 = parse_mod_items(p0, token::EOF, first_item_outer_attrs); - auto i = syntax::parse::parser::mk_item - (p0, cdir.span.lo, cdir.span.hi, id, ast::item_mod(m0), - mod_attrs); - // Thread defids, chpos and byte_pos through the parsers - cx.chpos = p0.get_chpos(); - cx.byte_pos = p0.get_byte_pos(); - items += ~[i]; - } - case (ast::cdir_dir_mod(?id, ?dir_opt, ?cdirs, ?attrs)) { - auto path = id; - alt (dir_opt) { case (some(?d)) { path = d; } case (none) { } } - auto full_path = if (std::fs::path_is_absolute(path)) { + let i = + syntax::parse::parser::mk_item(p0, cdir.span.lo, cdir.span.hi, id, + ast::item_mod(m0), mod_attrs); + // Thread defids, chpos and byte_pos through the parsers + cx.chpos = p0.get_chpos(); + cx.byte_pos = p0.get_byte_pos(); + items += ~[i]; + } + ast::cdir_dir_mod(id, dir_opt, cdirs, attrs) { + let path = id; + alt dir_opt { some(d) { path = d; } none. { } } + let full_path = + if std::fs::path_is_absolute(path) { path - } else { - prefix + std::fs::path_sep() + path - }; - auto m0 = eval_crate_directives_to_mod(cx, cdirs, full_path); - auto i = @rec(ident=id, - attrs=attrs, - id=cx.sess.next_id, - node=ast::item_mod(m0), - span=cdir.span); - cx.sess.next_id += 1; - items += ~[i]; - } - case (ast::cdir_view_item(?vi)) { view_items += ~[vi]; } - case (ast::cdir_syntax(?pth)) { } - case (ast::cdir_auth(?pth, ?eff)) { } + } else { prefix + std::fs::path_sep() + path }; + let m0 = eval_crate_directives_to_mod(cx, cdirs, full_path); + let i = + @{ident: id, + attrs: attrs, + id: cx.sess.next_id, + node: ast::item_mod(m0), + span: cdir.span}; + cx.sess.next_id += 1; + items += ~[i]; + } + ast::cdir_view_item(vi) { view_items += ~[vi]; } + ast::cdir_syntax(pth) { } + ast::cdir_auth(pth, eff) { } } } // diff --git a/src/comp/syntax/parse/lexer.rs b/src/comp/syntax/parse/lexer.rs index d011fdc41b2..8163f8d29fc 100644 --- a/src/comp/syntax/parse/lexer.rs +++ b/src/comp/syntax/parse/lexer.rs @@ -28,20 +28,20 @@ type reader = fn err(str) ; }; -fn new_reader(&codemap::codemap cm, str src, codemap::filemap filemap, - @interner::interner[str] itr) -> reader { - obj reader(codemap::codemap cm, - str src, - uint len, - mutable uint col, - mutable uint pos, - mutable char ch, - mutable uint chpos, - mutable str[] strs, - codemap::filemap fm, - @interner::interner[str] itr) { +fn new_reader(cm: &codemap::codemap, src: str, filemap: codemap::filemap, + itr: @interner::interner[str]) -> reader { + obj reader(cm: codemap::codemap, + src: str, + len: uint, + mutable col: uint, + mutable pos: uint, + mutable ch: char, + mutable chpos: uint, + mutable strs: str[], + fm: codemap::filemap, + itr: @interner::interner[str]) { fn is_eof() -> bool { ret ch == -1 as char; } - fn get_str_from(uint start) -> str { + fn get_str_from(start: uint) -> str { // I'm pretty skeptical about this subtraction. What if there's a // multi-byte character before the mark? ret str::slice(src, start - 1u, pos - 1u); @@ -50,26 +50,26 @@ fn new_reader(&codemap::codemap cm, str src, codemap::filemap filemap, fn get_byte_pos() -> uint { ret pos; } fn curr() -> char { ret ch; } fn next() -> char { - if (pos < len) { + if pos < len { ret str::char_at(src, pos); } else { ret -1 as char; } } fn init() { - if (pos < len) { - auto next = str::char_range_at(src, pos); + if pos < len { + let next = str::char_range_at(src, pos); pos = next.next; ch = next.ch; } } fn bump() { - if (pos < len) { + if pos < len { col += 1u; chpos += 1u; - if (ch == '\n') { + if ch == '\n' { codemap::next_line(fm, chpos, pos + fm.start_pos.byte); col = 0u; } - auto next = str::char_range_at(src, pos); + let next = str::char_range_at(src, pos); pos = next.next; ch = next.ch; } else { ch = -1 as char; } @@ -77,86 +77,82 @@ fn new_reader(&codemap::codemap cm, str src, codemap::filemap filemap, fn get_interner() -> @interner::interner[str] { ret itr; } fn get_col() -> uint { ret col; } fn get_filemap() -> codemap::filemap { ret fm; } - fn err(str m) { - codemap::emit_error(some(rec(lo=chpos, hi=chpos)), m, cm); + fn err(m: str) { + codemap::emit_error(some({lo: chpos, hi: chpos}), m, cm); } } - let str[] strs = ~[]; - auto rd = + let strs: str[] = ~[]; + let rd = reader(cm, src, str::byte_len(src), 0u, 0u, -1 as char, filemap.start_pos.ch, strs, filemap, itr); rd.init(); ret rd; } -fn dec_digit_val(char c) -> int { ret (c as int) - ('0' as int); } +fn dec_digit_val(c: char) -> int { ret (c as int) - ('0' as int); } -fn hex_digit_val(char c) -> int { - if (in_range(c, '0', '9')) { ret (c as int) - ('0' as int); } - if (in_range(c, 'a', 'f')) { ret (c as int) - ('a' as int) + 10; } - if (in_range(c, 'A', 'F')) { ret (c as int) - ('A' as int) + 10; } +fn hex_digit_val(c: char) -> int { + if in_range(c, '0', '9') { ret (c as int) - ('0' as int); } + if in_range(c, 'a', 'f') { ret (c as int) - ('a' as int) + 10; } + if in_range(c, 'A', 'F') { ret (c as int) - ('A' as int) + 10; } fail; } -fn bin_digit_value(char c) -> int { if (c == '0') { ret 0; } ret 1; } +fn bin_digit_value(c: char) -> int { if c == '0' { ret 0; } ret 1; } -fn is_whitespace(char c) -> bool { +fn is_whitespace(c: char) -> bool { ret c == ' ' || c == '\t' || c == '\r' || c == '\n'; } -fn may_begin_ident(char c) -> bool { ret is_alpha(c) || c == '_'; } +fn may_begin_ident(c: char) -> bool { ret is_alpha(c) || c == '_'; } -fn in_range(char c, char lo, char hi) -> bool { ret lo <= c && c <= hi; } +fn in_range(c: char, lo: char, hi: char) -> bool { ret lo <= c && c <= hi; } -fn is_alpha(char c) -> bool { +fn is_alpha(c: char) -> bool { ret in_range(c, 'a', 'z') || in_range(c, 'A', 'Z'); } -fn is_dec_digit(char c) -> bool { ret in_range(c, '0', '9'); } +fn is_dec_digit(c: char) -> bool { ret in_range(c, '0', '9'); } -fn is_alnum(char c) -> bool { ret is_alpha(c) || is_dec_digit(c); } +fn is_alnum(c: char) -> bool { ret is_alpha(c) || is_dec_digit(c); } -fn is_hex_digit(char c) -> bool { +fn is_hex_digit(c: char) -> bool { ret in_range(c, '0', '9') || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'); } -fn is_bin_digit(char c) -> bool { ret c == '0' || c == '1'; } +fn is_bin_digit(c: char) -> bool { ret c == '0' || c == '1'; } -fn consume_whitespace_and_comments(&reader rdr) { - while (is_whitespace(rdr.curr())) { rdr.bump(); } +fn consume_whitespace_and_comments(rdr: &reader) { + while is_whitespace(rdr.curr()) { rdr.bump(); } be consume_any_line_comment(rdr); } -fn consume_any_line_comment(&reader rdr) { - if (rdr.curr() == '/') { - alt (rdr.next()) { - case ('/') { - while (rdr.curr() != '\n' && !rdr.is_eof()) { rdr.bump(); } - // Restart whitespace munch. +fn consume_any_line_comment(rdr: &reader) { + if rdr.curr() == '/' { + alt rdr.next() { + '/' { + while rdr.curr() != '\n' && !rdr.is_eof() { rdr.bump(); } + // Restart whitespace munch. - be consume_whitespace_and_comments(rdr); - } - case ('*') { - rdr.bump(); - rdr.bump(); - be consume_block_comment(rdr); - } - case (_) { ret; } + be consume_whitespace_and_comments(rdr); + } + '*' { rdr.bump(); rdr.bump(); be consume_block_comment(rdr); } + _ { ret; } } } } -fn consume_block_comment(&reader rdr) { - let int level = 1; - while (level > 0) { - if (rdr.is_eof()) { rdr.err("unterminated block comment"); fail; } - if (rdr.curr() == '/' && rdr.next() == '*') { +fn consume_block_comment(rdr: &reader) { + let level: int = 1; + while level > 0 { + if rdr.is_eof() { rdr.err("unterminated block comment"); fail; } + if rdr.curr() == '/' && rdr.next() == '*' { rdr.bump(); rdr.bump(); level += 1; } else { - if (rdr.curr() == '*' && rdr.next() == '/') { + if rdr.curr() == '*' && rdr.next() == '/' { rdr.bump(); rdr.bump(); level -= 1; @@ -168,55 +164,55 @@ fn consume_block_comment(&reader rdr) { be consume_whitespace_and_comments(rdr); } -fn digits_to_string(str s) -> int { - let int accum_int = 0; - for (u8 c in s) { +fn digits_to_string(s: str) -> int { + let accum_int: int = 0; + for c: u8 in s { accum_int *= 10; accum_int += dec_digit_val(c as char); } ret accum_int; } -fn scan_exponent(&reader rdr) -> option::t[str] { - auto c = rdr.curr(); - auto rslt = ""; - if (c == 'e' || c == 'E') { +fn scan_exponent(rdr: &reader) -> option::t[str] { + let c = rdr.curr(); + let rslt = ""; + if c == 'e' || c == 'E' { rslt += str::from_bytes([c as u8]); rdr.bump(); c = rdr.curr(); - if (c == '-' || c == '+') { + if c == '-' || c == '+' { rslt += str::from_bytes([c as u8]); rdr.bump(); } - auto exponent = scan_dec_digits(rdr); - if (str::byte_len(exponent) > 0u) { + let exponent = scan_dec_digits(rdr); + if str::byte_len(exponent) > 0u { ret some(rslt + exponent); } else { rdr.err("scan_exponent: bad fp literal"); fail; } } else { ret none[str]; } } -fn scan_dec_digits(&reader rdr) -> str { - auto c = rdr.curr(); - let str rslt = ""; - while (is_dec_digit(c) || c == '_') { - if (c != '_') { rslt += str::from_bytes([c as u8]); } +fn scan_dec_digits(rdr: &reader) -> str { + let c = rdr.curr(); + let rslt: str = ""; + while is_dec_digit(c) || c == '_' { + if c != '_' { rslt += str::from_bytes([c as u8]); } rdr.bump(); c = rdr.curr(); } ret rslt; } -fn scan_number(char c, &reader rdr) -> token::token { - auto accum_int = 0; - let str dec_str = ""; - let bool is_dec_integer = false; - auto n = rdr.next(); - if (c == '0' && n == 'x') { +fn scan_number(c: char, rdr: &reader) -> token::token { + let accum_int = 0; + let dec_str: str = ""; + let is_dec_integer: bool = false; + let n = rdr.next(); + if c == '0' && n == 'x' { rdr.bump(); rdr.bump(); c = rdr.curr(); - while (is_hex_digit(c) || c == '_') { - if (c != '_') { accum_int *= 16; accum_int += hex_digit_val(c); } + while is_hex_digit(c) || c == '_' { + if c != '_' { accum_int *= 16; accum_int += hex_digit_val(c); } rdr.bump(); c = rdr.curr(); } @@ -224,48 +220,48 @@ fn scan_number(char c, &reader rdr) -> token::token { rdr.bump(); rdr.bump(); c = rdr.curr(); - while (is_bin_digit(c) || c == '_') { - if (c != '_') { accum_int *= 2; accum_int += bin_digit_value(c); } + while is_bin_digit(c) || c == '_' { + if c != '_' { accum_int *= 2; accum_int += bin_digit_value(c); } rdr.bump(); c = rdr.curr(); } } else { dec_str = scan_dec_digits(rdr); is_dec_integer = true; } - if (is_dec_integer) { accum_int = digits_to_string(dec_str); } + if is_dec_integer { accum_int = digits_to_string(dec_str); } c = rdr.curr(); n = rdr.next(); - if (c == 'u' || c == 'i') { - let bool signed = c == 'i'; + if c == 'u' || c == 'i' { + let signed: bool = c == 'i'; rdr.bump(); c = rdr.curr(); - if (c == '8') { + if c == '8' { rdr.bump(); - if (signed) { + if signed { ret token::LIT_MACH_INT(ast::ty_i8, accum_int); } else { ret token::LIT_MACH_INT(ast::ty_u8, accum_int); } } n = rdr.next(); - if (c == '1' && n == '6') { + if c == '1' && n == '6' { rdr.bump(); rdr.bump(); - if (signed) { + if signed { ret token::LIT_MACH_INT(ast::ty_i16, accum_int); } else { ret token::LIT_MACH_INT(ast::ty_u16, accum_int); } } - if (c == '3' && n == '2') { + if c == '3' && n == '2' { rdr.bump(); rdr.bump(); - if (signed) { + if signed { ret token::LIT_MACH_INT(ast::ty_i32, accum_int); } else { ret token::LIT_MACH_INT(ast::ty_u32, accum_int); } } - if (c == '6' && n == '4') { + if c == '6' && n == '4' { rdr.bump(); rdr.bump(); - if (signed) { + if signed { ret token::LIT_MACH_INT(ast::ty_i64, accum_int); } else { ret token::LIT_MACH_INT(ast::ty_u64, accum_int); } } - if (signed) { + if signed { ret token::LIT_INT(accum_int); } else { // FIXME: should cast in the target bit-width. @@ -274,24 +270,21 @@ fn scan_number(char c, &reader rdr) -> token::token { } } c = rdr.curr(); - if (c == '.') { + if c == '.' { // Parse a floating-point number. rdr.bump(); - auto dec_part = scan_dec_digits(rdr); - auto float_str = dec_str + "." + dec_part; + let dec_part = scan_dec_digits(rdr); + let float_str = dec_str + "." + dec_part; c = rdr.curr(); - auto exponent_str = scan_exponent(rdr); - alt (exponent_str) { - case (some(?s)) { float_str += s; } - case (none) { } - } + let exponent_str = scan_exponent(rdr); + alt exponent_str { some(s) { float_str += s; } none. { } } c = rdr.curr(); - if (c == 'f') { + if c == 'f' { rdr.bump(); c = rdr.curr(); n = rdr.next(); - if (c == '3' && n == '2') { + if c == '3' && n == '2' { rdr.bump(); rdr.bump(); ret token::LIT_MACH_FLOAT(ast::ty_f32, @@ -312,22 +305,22 @@ fn scan_number(char c, &reader rdr) -> token::token { float_str)); } } - auto maybe_exponent = scan_exponent(rdr); - alt (maybe_exponent) { - case (some(?s)) { - ret token::LIT_FLOAT(interner::intern[str](*rdr.get_interner(), - dec_str + s)); - } - case (none) { ret token::LIT_INT(accum_int); } + let maybe_exponent = scan_exponent(rdr); + alt maybe_exponent { + some(s) { + ret token::LIT_FLOAT(interner::intern[str](*rdr.get_interner(), + dec_str + s)); + } + none. { ret token::LIT_INT(accum_int); } } } -fn scan_numeric_escape(&reader rdr, uint n_hex_digits) -> char { - auto accum_int = 0; - while (n_hex_digits != 0u) { - auto n = rdr.curr(); +fn scan_numeric_escape(rdr: &reader, n_hex_digits: uint) -> char { + let accum_int = 0; + while n_hex_digits != 0u { + let n = rdr.curr(); rdr.bump(); - if (!is_hex_digit(n)) { + if !is_hex_digit(n) { rdr.err(#fmt("illegal numeric character escape: %d", n as int)); fail; } @@ -338,235 +331,215 @@ fn scan_numeric_escape(&reader rdr, uint n_hex_digits) -> char { ret accum_int as char; } -fn next_token(&reader rdr) -> rec(token::token tok, uint chpos, uint bpos) { +fn next_token(rdr: &reader) -> {tok: token::token, chpos: uint, bpos: uint} { consume_whitespace_and_comments(rdr); - auto start_chpos = rdr.get_chpos(); - auto start_bpos = rdr.get_byte_pos(); - auto tok = if rdr.is_eof() { token::EOF } - else { next_token_inner(rdr) }; - ret rec(tok=tok, chpos=start_chpos, bpos=start_bpos); + let start_chpos = rdr.get_chpos(); + let start_bpos = rdr.get_byte_pos(); + let tok = if rdr.is_eof() { token::EOF } else { next_token_inner(rdr) }; + ret {tok: tok, chpos: start_chpos, bpos: start_bpos}; } -fn next_token_inner(&reader rdr) -> token::token { - auto accum_str = ""; - auto c = rdr.curr(); - if (is_alpha(c) || c == '_') { - while (is_alnum(c) || c == '_') { +fn next_token_inner(rdr: &reader) -> token::token { + let accum_str = ""; + let c = rdr.curr(); + if is_alpha(c) || c == '_' { + while is_alnum(c) || c == '_' { str::push_char(accum_str, c); rdr.bump(); c = rdr.curr(); } - if (str::eq(accum_str, "_")) { ret token::UNDERSCORE; } - auto is_mod_name = c == ':' && rdr.next() == ':'; + if str::eq(accum_str, "_") { ret token::UNDERSCORE; } + let is_mod_name = c == ':' && rdr.next() == ':'; ret token::IDENT(interner::intern[str](*rdr.get_interner(), accum_str), is_mod_name); } - if (is_dec_digit(c)) { ret scan_number(c, rdr); } - fn binop(&reader rdr, token::binop op) -> token::token { + if is_dec_digit(c) { ret scan_number(c, rdr); } + fn binop(rdr: &reader, op: token::binop) -> token::token { rdr.bump(); - if (rdr.curr() == '=') { + if rdr.curr() == '=' { rdr.bump(); ret token::BINOPEQ(op); } else { ret token::BINOP(op); } } - alt (c) { - // One-byte tokens. - case ('?') { rdr.bump(); ret token::QUES; } - case (';') { rdr.bump(); ret token::SEMI; } - case (',') { rdr.bump(); ret token::COMMA; } - case ('.') { + alt c { + + // One-byte tokens. + '?' { + rdr.bump(); + ret token::QUES; + } + ';' { rdr.bump(); ret token::SEMI; } + ',' { rdr.bump(); ret token::COMMA; } + '.' { + rdr.bump(); + if rdr.curr() == '.' && rdr.next() == '.' { rdr.bump(); - if (rdr.curr() == '.' && rdr.next() == '.') { - rdr.bump(); - rdr.bump(); - ret token::ELLIPSIS; - } - ret token::DOT; - } - case ('(') { rdr.bump(); ret token::LPAREN; } - case (')') { rdr.bump(); ret token::RPAREN; } - case ('{') { rdr.bump(); ret token::LBRACE; } - case ('}') { rdr.bump(); ret token::RBRACE; } - case ('[') { rdr.bump(); ret token::LBRACKET; } - case (']') { rdr.bump(); ret token::RBRACKET; } - case ('@') { rdr.bump(); ret token::AT; } - case ('#') { rdr.bump(); - if (rdr.curr() == '<') { - rdr.bump(); - ret token::POUND_LT; - } - if (rdr.curr() == '{') { - rdr.bump(); - ret token::POUND_LBRACE; - } - ret token::POUND; - } - case ('~') { rdr.bump(); ret token::TILDE; } - case (':') { + ret token::ELLIPSIS; + } + ret token::DOT; + } + '(' { rdr.bump(); ret token::LPAREN; } + ')' { rdr.bump(); ret token::RPAREN; } + '{' { rdr.bump(); ret token::LBRACE; } + '}' { rdr.bump(); ret token::RBRACE; } + '[' { rdr.bump(); ret token::LBRACKET; } + ']' { rdr.bump(); ret token::RBRACKET; } + '@' { rdr.bump(); ret token::AT; } + '#' { + rdr.bump(); + if rdr.curr() == '<' { rdr.bump(); ret token::POUND_LT; } + if rdr.curr() == '{' { rdr.bump(); ret token::POUND_LBRACE; } + ret token::POUND; + } + '~' { rdr.bump(); ret token::TILDE; } + ':' { + rdr.bump(); + if rdr.curr() == ':' { rdr.bump(); - if (rdr.curr() == ':') { - rdr.bump(); - ret token::MOD_SEP; - } else { ret token::COLON; } - } - // Multi-byte tokens. - case ('=') { + ret token::MOD_SEP; + } else { ret token::COLON; } + } + + // Multi-byte tokens. + '=' { + rdr.bump(); + if rdr.curr() == '=' { rdr.bump(); - if (rdr.curr() == '=') { - rdr.bump(); - ret token::EQEQ; - } else { ret token::EQ; } - } - case ('!') { + ret token::EQEQ; + } else { ret token::EQ; } + } + '!' { + rdr.bump(); + if rdr.curr() == '=' { rdr.bump(); - if (rdr.curr() == '=') { - rdr.bump(); - ret token::NE; - } else { ret token::NOT; } - } - case ('<') { + ret token::NE; + } else { ret token::NOT; } + } + '<' { + rdr.bump(); + alt rdr.curr() { + '=' { rdr.bump(); ret token::LE; } + '<' { ret binop(rdr, token::LSL); } + '|' { rdr.bump(); ret token::SEND; } + '-' { rdr.bump(); - alt (rdr.curr()) { - case ('=') { rdr.bump(); ret token::LE; } - case ('<') { ret binop(rdr, token::LSL); } - case ('|') { rdr.bump(); ret token::SEND; } - case ('-') { - rdr.bump(); - alt (rdr.curr()) { - case ('>') { rdr.bump(); ret token::DARROW; } - case (_) { ret token::LARROW; } - } - } - case (_) { ret token::LT; } + alt rdr.curr() { + '>' { rdr.bump(); ret token::DARROW; } + _ { ret token::LARROW; } } + } + _ { ret token::LT; } } - case ('>') { - rdr.bump(); - alt (rdr.curr()) { - case ('=') { rdr.bump(); ret token::GE; } - case ('>') { - if (rdr.next() == '>') { - rdr.bump(); - ret binop(rdr, token::ASR); - } else { ret binop(rdr, token::LSR); } - } - case (_) { ret token::GT; } - } + } + '>' { + rdr.bump(); + alt rdr.curr() { + '=' { rdr.bump(); ret token::GE; } + '>' { + if rdr.next() == '>' { + rdr.bump(); + ret binop(rdr, token::ASR); + } else { ret binop(rdr, token::LSR); } + } + _ { ret token::GT; } } - case ('\'') { - rdr.bump(); - auto c2 = rdr.curr(); + } + '\'' { + rdr.bump(); + let c2 = rdr.curr(); + rdr.bump(); + if c2 == '\\' { + let escaped = rdr.curr(); rdr.bump(); - if (c2 == '\\') { - auto escaped = rdr.curr(); - rdr.bump(); - alt (escaped) { - case ('n') { c2 = '\n'; } - case ('r') { c2 = '\r'; } - case ('t') { c2 = '\t'; } - case ('\\') { c2 = '\\'; } - case ('\'') { c2 = '\''; } - case ('x') { c2 = scan_numeric_escape(rdr, 2u); } - case ('u') { c2 = scan_numeric_escape(rdr, 4u); } - case ('U') { c2 = scan_numeric_escape(rdr, 8u); } - case (?c2) { - rdr.err(#fmt("unknown character escape: %d", - c2 as int)); - fail; - } - } - } - if (rdr.curr() != '\'') { - rdr.err("unterminated character constant"); + alt escaped { + 'n' { c2 = '\n'; } + 'r' { c2 = '\r'; } + 't' { c2 = '\t'; } + '\\' { c2 = '\\'; } + '\'' { c2 = '\''; } + 'x' { c2 = scan_numeric_escape(rdr, 2u); } + 'u' { c2 = scan_numeric_escape(rdr, 4u); } + 'U' { c2 = scan_numeric_escape(rdr, 8u); } + c2 { + rdr.err(#fmt("unknown character escape: %d", c2 as int)); fail; + } } - rdr.bump(); // advance curr past token - - ret token::LIT_CHAR(c2); } - case ('"') { + if rdr.curr() != '\'' { + rdr.err("unterminated character constant"); + fail; + } + rdr.bump(); // advance curr past token + + ret token::LIT_CHAR(c2); + } + '"' { + rdr.bump(); + while rdr.curr() != '"' { + let ch = rdr.curr(); rdr.bump(); - while (rdr.curr() != '"') { - auto ch = rdr.curr(); + alt ch { + '\\' { + let escaped = rdr.curr(); rdr.bump(); - alt (ch) { - case ('\\') { - auto escaped = rdr.curr(); - rdr.bump(); - alt (escaped) { - case ('n') { - str::push_byte(accum_str, '\n' as u8); - } - case ('r') { - str::push_byte(accum_str, '\r' as u8); - } - case ('t') { - str::push_byte(accum_str, '\t' as u8); - } - case ('\\') { - str::push_byte(accum_str, '\\' as u8); - } - case ('"') { - str::push_byte(accum_str, '"' as u8); - } - case ('\n') { consume_whitespace(rdr); } - case ('x') { - str::push_char(accum_str, - scan_numeric_escape(rdr, 2u)); - } - case ('u') { - str::push_char(accum_str, - scan_numeric_escape(rdr, 4u)); - } - case ('U') { - str::push_char(accum_str, - scan_numeric_escape(rdr, 8u)); - } - case (?c2) { - rdr.err(#fmt("unknown string escape: %d", - c2 as int)); - fail; - } - } - } - case (_) { str::push_char(accum_str, ch); } + alt escaped { + 'n' { str::push_byte(accum_str, '\n' as u8); } + 'r' { str::push_byte(accum_str, '\r' as u8); } + 't' { str::push_byte(accum_str, '\t' as u8); } + '\\' { str::push_byte(accum_str, '\\' as u8); } + '"' { str::push_byte(accum_str, '"' as u8); } + '\n' { consume_whitespace(rdr); } + 'x' { + str::push_char(accum_str, scan_numeric_escape(rdr, 2u)); + } + 'u' { + str::push_char(accum_str, scan_numeric_escape(rdr, 4u)); + } + 'U' { + str::push_char(accum_str, scan_numeric_escape(rdr, 8u)); + } + c2 { + rdr.err(#fmt("unknown string escape: %d", c2 as int)); + fail; + } } + } + _ { str::push_char(accum_str, ch); } } - rdr.bump(); - ret token::LIT_STR(interner::intern[str](*rdr.get_interner(), - accum_str)); - } - case ('-') { - if (rdr.next() == '>') { - rdr.bump(); - rdr.bump(); - ret token::RARROW; - } else { ret binop(rdr, token::MINUS); } - } - case ('&') { - if (rdr.next() == '&') { - rdr.bump(); - rdr.bump(); - ret token::ANDAND; - } else { ret binop(rdr, token::AND); } - } - case ('|') { - alt (rdr.next()) { - case ('|') { rdr.bump(); rdr.bump(); ret token::OROR; } - case ('>') { rdr.bump(); rdr.bump(); ret token::RECV; } - case (_) { ret binop(rdr, token::OR); } - } - } - case ('+') { ret binop(rdr, token::PLUS); } - case ('*') { ret binop(rdr, token::STAR); } - case ('/') { ret binop(rdr, token::SLASH); } - case ('^') { ret binop(rdr, token::CARET); } - case ('%') { ret binop(rdr, token::PERCENT); } - case (?c) { - rdr.err(#fmt("unkown start of token: %d", c as int)); - fail; } + rdr.bump(); + ret token::LIT_STR(interner::intern[str](*rdr.get_interner(), + accum_str)); + } + '-' { + if rdr.next() == '>' { + rdr.bump(); + rdr.bump(); + ret token::RARROW; + } else { ret binop(rdr, token::MINUS); } + } + '&' { + if rdr.next() == '&' { + rdr.bump(); + rdr.bump(); + ret token::ANDAND; + } else { ret binop(rdr, token::AND); } + } + '|' { + alt rdr.next() { + '|' { rdr.bump(); rdr.bump(); ret token::OROR; } + '>' { rdr.bump(); rdr.bump(); ret token::RECV; } + _ { ret binop(rdr, token::OR); } + } + } + '+' { ret binop(rdr, token::PLUS); } + '*' { ret binop(rdr, token::STAR); } + '/' { ret binop(rdr, token::SLASH); } + '^' { ret binop(rdr, token::CARET); } + '%' { ret binop(rdr, token::PERCENT); } + c { rdr.err(#fmt("unkown start of token: %d", c as int)); fail; } } fail; } @@ -574,55 +547,57 @@ fn next_token_inner(&reader rdr) -> token::token { tag cmnt_style { isolated; // No code on either side of each line of the comment + + trailing; // Code exists to the left of the comment + + mixed; // Code before /* foo */ and after the comment + + blank_line; // Just a manual blank linke "\n\n", for layout } -type cmnt = rec(cmnt_style style, str[] lines, uint pos); +type cmnt = {style: cmnt_style, lines: str[], pos: uint}; -fn read_to_eol(&reader rdr) -> str { - auto val = ""; - while (rdr.curr() != '\n' && !rdr.is_eof()) { +fn read_to_eol(rdr: &reader) -> str { + let val = ""; + while rdr.curr() != '\n' && !rdr.is_eof() { str::push_char(val, rdr.curr()); rdr.bump(); } - if rdr.curr() == '\n' { - rdr.bump(); - } + if rdr.curr() == '\n' { rdr.bump(); } ret val; } -fn read_one_line_comment(&reader rdr) -> str { - auto val = read_to_eol(rdr); +fn read_one_line_comment(rdr: &reader) -> str { + let val = read_to_eol(rdr); assert (val.(0) == '/' as u8 && val.(1) == '/' as u8); ret val; } -fn consume_whitespace(&reader rdr) { - while (is_whitespace(rdr.curr()) && !rdr.is_eof()) { rdr.bump(); } +fn consume_whitespace(rdr: &reader) { + while is_whitespace(rdr.curr()) && !rdr.is_eof() { rdr.bump(); } } -fn consume_non_eol_whitespace(&reader rdr) { - while (is_whitespace(rdr.curr()) && rdr.curr() != '\n' && !rdr.is_eof()) { +fn consume_non_eol_whitespace(rdr: &reader) { + while is_whitespace(rdr.curr()) && rdr.curr() != '\n' && !rdr.is_eof() { rdr.bump(); } } -fn push_blank_line_comment(&reader rdr, - &mutable cmnt[] comments) { +fn push_blank_line_comment(rdr: &reader, comments: &mutable cmnt[]) { log ">>> blank-line comment"; - let str[] v = ~[]; - comments += ~[rec(style=blank_line, lines=v, - pos=rdr.get_chpos())]; + let v: str[] = ~[]; + comments += ~[{style: blank_line, lines: v, pos: rdr.get_chpos()}]; } -fn consume_whitespace_counting_blank_lines(&reader rdr, - &mutable cmnt[] comments) { - while (is_whitespace(rdr.curr()) && !rdr.is_eof()) { +fn consume_whitespace_counting_blank_lines(rdr: &reader, + comments: &mutable cmnt[]) { + while is_whitespace(rdr.curr()) && !rdr.is_eof() { if rdr.get_col() == 0u && rdr.curr() == '\n' { push_blank_line_comment(rdr, comments); } @@ -630,36 +605,36 @@ fn consume_whitespace_counting_blank_lines(&reader rdr, } } -fn read_line_comments(&reader rdr, bool code_to_the_left) -> cmnt { +fn read_line_comments(rdr: &reader, code_to_the_left: bool) -> cmnt { log ">>> line comments"; - auto p = rdr.get_chpos(); - let str[] lines = ~[]; - while (rdr.curr() == '/' && rdr.next() == '/') { - auto line = read_one_line_comment(rdr); + let p = rdr.get_chpos(); + let lines: str[] = ~[]; + while rdr.curr() == '/' && rdr.next() == '/' { + let line = read_one_line_comment(rdr); log line; lines += ~[line]; consume_non_eol_whitespace(rdr); } log "<<< line comments"; - ret rec(style=if (code_to_the_left) { trailing } else { isolated }, - lines=lines, - pos=p); + ret {style: if code_to_the_left { trailing } else { isolated }, + lines: lines, + pos: p}; } -fn all_whitespace(&str s, uint begin, uint end) -> bool { - let uint i = begin; - while (i != end) { - if (!is_whitespace(s.(i) as char)) { ret false; } +fn all_whitespace(s: &str, begin: uint, end: uint) -> bool { + let i: uint = begin; + while i != end { + if !is_whitespace(s.(i) as char) { ret false; } i += 1u; } ret true; } -fn trim_whitespace_prefix_and_push_line(&mutable str[] lines, &str s, - uint col) { - auto s1; - if (all_whitespace(s, 0u, col)) { - if (col < str::byte_len(s)) { +fn trim_whitespace_prefix_and_push_line(lines: &mutable str[], s: &str, + col: uint) { + let s1; + if all_whitespace(s, 0u, col) { + if col < str::byte_len(s) { s1 = str::slice(s, col, str::byte_len(s)); } else { s1 = ""; } } else { s1 = s; } @@ -667,31 +642,31 @@ fn trim_whitespace_prefix_and_push_line(&mutable str[] lines, &str s, lines += ~[s1]; } -fn read_block_comment(&reader rdr, bool code_to_the_left) -> cmnt { +fn read_block_comment(rdr: &reader, code_to_the_left: bool) -> cmnt { log ">>> block comment"; - auto p = rdr.get_chpos(); - let str[] lines = ~[]; - let uint col = rdr.get_col(); + let p = rdr.get_chpos(); + let lines: str[] = ~[]; + let col: uint = rdr.get_col(); rdr.bump(); rdr.bump(); - auto curr_line = "/*"; - let int level = 1; - while (level > 0) { + let curr_line = "/*"; + let level: int = 1; + while level > 0 { log #fmt("=== block comment level %d", level); - if (rdr.is_eof()) { rdr.err("unterminated block comment"); fail; } - if (rdr.curr() == '\n') { + if rdr.is_eof() { rdr.err("unterminated block comment"); fail; } + if rdr.curr() == '\n' { trim_whitespace_prefix_and_push_line(lines, curr_line, col); curr_line = ""; rdr.bump(); } else { str::push_char(curr_line, rdr.curr()); - if (rdr.curr() == '/' && rdr.next() == '*') { + if rdr.curr() == '/' && rdr.next() == '*' { rdr.bump(); rdr.bump(); curr_line += "*"; level += 1; } else { - if (rdr.curr() == '*' && rdr.next() == '/') { + if rdr.curr() == '*' && rdr.next() == '/' { rdr.bump(); rdr.bump(); curr_line += "/"; @@ -700,27 +675,27 @@ fn read_block_comment(&reader rdr, bool code_to_the_left) -> cmnt { } } } - if (str::byte_len(curr_line) != 0u) { + if str::byte_len(curr_line) != 0u { trim_whitespace_prefix_and_push_line(lines, curr_line, col); } - auto style = if (code_to_the_left) { trailing } else { isolated }; + let style = if code_to_the_left { trailing } else { isolated }; consume_non_eol_whitespace(rdr); - if (!rdr.is_eof() && rdr.curr() != '\n' && ivec::len(lines) == 1u) { + if !rdr.is_eof() && rdr.curr() != '\n' && ivec::len(lines) == 1u { style = mixed; } log "<<< block comment"; - ret rec(style=style, lines=lines, pos=p); + ret {style: style, lines: lines, pos: p}; } -fn peeking_at_comment(&reader rdr) -> bool { +fn peeking_at_comment(rdr: &reader) -> bool { ret rdr.curr() == '/' && rdr.next() == '/' || rdr.curr() == '/' && rdr.next() == '*'; } -fn consume_comment(&reader rdr, bool code_to_the_left, - &mutable cmnt[] comments) { +fn consume_comment(rdr: &reader, code_to_the_left: bool, + comments: &mutable cmnt[]) { log ">>> consume comment"; - if (rdr.curr() == '/' && rdr.next() == '/') { + if rdr.curr() == '/' && rdr.next() == '/' { comments += ~[read_line_comments(rdr, code_to_the_left)]; } else if (rdr.curr() == '/' && rdr.next() == '*') { comments += ~[read_block_comment(rdr, code_to_the_left)]; @@ -728,53 +703,53 @@ fn consume_comment(&reader rdr, bool code_to_the_left, log "<<< consume comment"; } -fn is_lit(&token::token t) -> bool { - ret alt (t) { - case (token::LIT_INT(_)) { true } - case (token::LIT_UINT(_)) { true } - case (token::LIT_MACH_INT(_, _)) { true } - case (token::LIT_FLOAT(_)) { true } - case (token::LIT_MACH_FLOAT(_, _)) { true } - case (token::LIT_STR(_)) { true } - case (token::LIT_CHAR(_)) { true } - case (token::LIT_BOOL(_)) { true } - case (_) { false } +fn is_lit(t: &token::token) -> bool { + ret alt t { + token::LIT_INT(_) { true } + token::LIT_UINT(_) { true } + token::LIT_MACH_INT(_, _) { true } + token::LIT_FLOAT(_) { true } + token::LIT_MACH_FLOAT(_, _) { true } + token::LIT_STR(_) { true } + token::LIT_CHAR(_) { true } + token::LIT_BOOL(_) { true } + _ { false } } } -type lit = rec(str lit, uint pos); - -fn gather_comments_and_literals(&codemap::codemap cm, str path, - ioivec::reader srdr) - -> rec(cmnt[] cmnts, lit[] lits) { - auto src = str::unsafe_from_bytes_ivec(srdr.read_whole_stream()); - auto itr = @interner::mk[str](str::hash, str::eq); - auto rdr = new_reader(cm, src, codemap::new_filemap(path, 0u, 0u), itr); - let cmnt[] comments = ~[]; - let lit[] literals = ~[]; - let bool first_read = true; - while (!rdr.is_eof()) { - while (true) { - auto code_to_the_left = !first_read; +type lit = {lit: str, pos: uint}; + +fn gather_comments_and_literals(cm: &codemap::codemap, path: str, + srdr: ioivec::reader) -> + {cmnts: cmnt[], lits: lit[]} { + let src = str::unsafe_from_bytes_ivec(srdr.read_whole_stream()); + let itr = @interner::mk[str](str::hash, str::eq); + let rdr = new_reader(cm, src, codemap::new_filemap(path, 0u, 0u), itr); + let comments: cmnt[] = ~[]; + let literals: lit[] = ~[]; + let first_read: bool = true; + while !rdr.is_eof() { + while true { + let code_to_the_left = !first_read; consume_non_eol_whitespace(rdr); - if (rdr.curr() == '\n') { + if rdr.curr() == '\n' { code_to_the_left = false; consume_whitespace_counting_blank_lines(rdr, comments); } - while (peeking_at_comment(rdr)) { + while peeking_at_comment(rdr) { consume_comment(rdr, code_to_the_left, comments); consume_whitespace_counting_blank_lines(rdr, comments); } break; } - auto tok = next_token(rdr); - if (is_lit(tok.tok)) { - literals += ~[rec(lit=rdr.get_str_from(tok.bpos), pos=tok.chpos)]; + let tok = next_token(rdr); + if is_lit(tok.tok) { + literals += ~[{lit: rdr.get_str_from(tok.bpos), pos: tok.chpos}]; } log "tok: " + token::to_str(rdr, tok.tok); first_read = false; } - ret rec(cmnts=comments, lits=literals); + ret {cmnts: comments, lits: literals}; } // // Local Variables: diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index e0ca20a4f1d..c93f8ce52a9 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -10,7 +10,7 @@ import std::either::left; import std::either::right; import std::map::hashmap; import token::can_begin_expr; -import ex=ext::base; +import ex = ext::base; import codemap::span; import std::map::new_str_hash; import util::interner; @@ -23,98 +23,97 @@ tag file_type { CRATE_FILE; SOURCE_FILE; } tag ty_or_bang { a_ty(@ast::ty); a_bang; } -type parse_sess = @rec(codemap::codemap cm, - mutable node_id next_id); +type parse_sess = @{cm: codemap::codemap, mutable next_id: node_id}; -fn next_node_id(&parse_sess sess) -> node_id { - auto rv = sess.next_id; +fn next_node_id(sess: &parse_sess) -> node_id { + let rv = sess.next_id; sess.next_id += 1; ret rv; } type parser = obj { - fn peek() -> token::token; - fn bump(); - fn look_ahead(uint) -> token::token; - fn fatal(str) -> !; - fn warn(str); - fn restrict(restriction); - fn get_restriction() -> restriction; - fn get_file_type() -> file_type; - fn get_cfg() -> ast::crate_cfg; - fn get_span() -> span; - fn get_lo_pos() -> uint; - fn get_hi_pos() -> uint; - fn get_last_lo_pos() -> uint; - fn get_last_hi_pos() -> uint; - fn get_prec_table() -> @op_spec[]; - fn get_str(token::str_num) -> str; - fn get_reader() -> lexer::reader; - fn get_filemap() -> codemap::filemap; - fn get_bad_expr_words() -> hashmap[str, ()]; - fn get_chpos() -> uint; - fn get_byte_pos() -> uint; - fn get_id() -> node_id; - fn get_sess() -> parse_sess; + fn peek() -> token::token ; + fn bump() ; + fn look_ahead(uint) -> token::token ; + fn fatal(str) -> ! ; + fn warn(str) ; + fn restrict(restriction) ; + fn get_restriction() -> restriction ; + fn get_file_type() -> file_type ; + fn get_cfg() -> ast::crate_cfg ; + fn get_span() -> span ; + fn get_lo_pos() -> uint ; + fn get_hi_pos() -> uint ; + fn get_last_lo_pos() -> uint ; + fn get_last_hi_pos() -> uint ; + fn get_prec_table() -> @op_spec[] ; + fn get_str(token::str_num) -> str ; + fn get_reader() -> lexer::reader ; + fn get_filemap() -> codemap::filemap ; + fn get_bad_expr_words() -> hashmap[str, ()] ; + fn get_chpos() -> uint ; + fn get_byte_pos() -> uint ; + fn get_id() -> node_id ; + fn get_sess() -> parse_sess ; }; -fn new_parser_from_file(parse_sess sess, ast::crate_cfg cfg, - str path, uint chpos, uint byte_pos) -> parser { - auto ftype = SOURCE_FILE; - if (str::ends_with(path, ".rc")) { ftype = CRATE_FILE; } - auto srdr = ioivec::file_reader(path); - auto src = str::unsafe_from_bytes_ivec(srdr.read_whole_stream()); - auto filemap = codemap::new_filemap(path, chpos, byte_pos); +fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str, + chpos: uint, byte_pos: uint) -> parser { + let ftype = SOURCE_FILE; + if str::ends_with(path, ".rc") { ftype = CRATE_FILE; } + let srdr = ioivec::file_reader(path); + let src = str::unsafe_from_bytes_ivec(srdr.read_whole_stream()); + let filemap = codemap::new_filemap(path, chpos, byte_pos); sess.cm.files += ~[filemap]; - auto itr = @interner::mk(str::hash, str::eq); - auto rdr = lexer::new_reader(sess.cm, src, filemap, itr); + let itr = @interner::mk(str::hash, str::eq); + let rdr = lexer::new_reader(sess.cm, src, filemap, itr); ret new_parser(sess, cfg, rdr, ftype); } -fn new_parser(parse_sess sess, ast::crate_cfg cfg, lexer::reader rdr, - file_type ftype) -> parser { - obj stdio_parser(parse_sess sess, - ast::crate_cfg cfg, - file_type ftype, - mutable token::token tok, - mutable span tok_span, - mutable span last_tok_span, - mutable rec(token::token tok, span span)[] buffer, - mutable restriction restr, - lexer::reader rdr, - @op_spec[] precs, - hashmap[str, ()] bad_words) { +fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader, + ftype: file_type) -> parser { + obj stdio_parser(sess: parse_sess, + cfg: ast::crate_cfg, + ftype: file_type, + mutable tok: token::token, + mutable tok_span: span, + mutable last_tok_span: span, + mutable buffer: {tok: token::token, span: span}[], + mutable restr: restriction, + rdr: lexer::reader, + precs: @op_spec[], + bad_words: hashmap[str, ()]) { fn peek() -> token::token { ret tok; } fn bump() { last_tok_span = tok_span; if ivec::len(buffer) == 0u { - auto next = lexer::next_token(rdr); + let next = lexer::next_token(rdr); tok = next.tok; - tok_span = rec(lo=next.chpos, hi=rdr.get_chpos()); + tok_span = {lo: next.chpos, hi: rdr.get_chpos()}; } else { - auto next = ivec::pop(buffer); + let next = ivec::pop(buffer); tok = next.tok; tok_span = next.span; } } - fn look_ahead(uint distance) -> token::token { + fn look_ahead(distance: uint) -> token::token { while ivec::len(buffer) < distance { - auto next = lexer::next_token(rdr); - auto sp = rec(lo=next.chpos, hi=rdr.get_chpos()); - buffer = ~[rec(tok=next.tok, span=sp)] + buffer; + let next = lexer::next_token(rdr); + let sp = {lo: next.chpos, hi: rdr.get_chpos()}; + buffer = ~[{tok: next.tok, span: sp}] + buffer; } - ret buffer.(distance-1u).tok; + ret buffer.(distance - 1u).tok; } - fn fatal(str m) -> ! { + fn fatal(m: str) -> ! { codemap::emit_error(some(self.get_span()), m, sess.cm); fail; } - fn warn(str m) { + fn warn(m: str) { codemap::emit_warning(some(self.get_span()), m, sess.cm); } - fn restrict(restriction r) { restr = r; } + fn restrict(r: restriction) { restr = r; } fn get_restriction() -> restriction { ret restr; } fn get_span() -> span { ret tok_span; } fn get_lo_pos() -> uint { ret tok_span.lo; } @@ -124,7 +123,7 @@ fn new_parser(parse_sess sess, ast::crate_cfg cfg, lexer::reader rdr, fn get_file_type() -> file_type { ret ftype; } fn get_cfg() -> ast::crate_cfg { ret cfg; } fn get_prec_table() -> @op_spec[] { ret precs; } - fn get_str(token::str_num i) -> str { + fn get_str(i: token::str_num) -> str { ret interner::get(*rdr.get_interner(), i); } fn get_reader() -> lexer::reader { ret rdr; } @@ -136,18 +135,17 @@ fn new_parser(parse_sess sess, ast::crate_cfg cfg, lexer::reader rdr, fn get_sess() -> parse_sess { ret sess; } } - auto tok0 = lexer::next_token(rdr); - auto span0 = rec(lo=tok0.chpos, hi=rdr.get_chpos()); - ret stdio_parser(sess, cfg, ftype, tok0.tok, - span0, span0, ~[], UNRESTRICTED, rdr, - prec_table(), bad_expr_word_table()); + let tok0 = lexer::next_token(rdr); + let span0 = {lo: tok0.chpos, hi: rdr.get_chpos()}; + ret stdio_parser(sess, cfg, ftype, tok0.tok, span0, span0, ~[], + UNRESTRICTED, rdr, prec_table(), bad_expr_word_table()); } // These are the words that shouldn't be allowed as value identifiers, // because, if used at the start of a line, they will cause the line to be // interpreted as a specific kind of statement, which would be confusing. fn bad_expr_word_table() -> hashmap[str, ()] { - auto words = new_str_hash(); + let words = new_str_hash(); words.insert("mod", ()); words.insert("if", ()); words.insert("else", ()); @@ -188,17 +186,17 @@ fn bad_expr_word_table() -> hashmap[str, ()] { ret words; } -fn unexpected(&parser p, token::token t) -> ! { - let str s = "unexpected token: "; +fn unexpected(p: &parser, t: token::token) -> ! { + let s: str = "unexpected token: "; s += token::to_str(p.get_reader(), t); p.fatal(s); } -fn expect(&parser p, token::token t) { - if (p.peek() == t) { +fn expect(p: &parser, t: token::token) { + if p.peek() == t { p.bump(); } else { - let str s = "expecting "; + let s: str = "expecting "; s += token::to_str(p.get_reader(), t); s += ", found "; s += token::to_str(p.get_reader(), p.peek()); @@ -206,105 +204,105 @@ fn expect(&parser p, token::token t) { } } -fn spanned[T](uint lo, uint hi, &T node) -> spanned[T] { - ret rec(node=node, span=rec(lo=lo, hi=hi)); +fn spanned[T](lo: uint, hi: uint, node: &T) -> spanned[T] { + ret {node: node, span: {lo: lo, hi: hi}}; } -fn parse_ident(&parser p) -> ast::ident { - alt (p.peek()) { - case (token::IDENT(?i, _)) { p.bump(); ret p.get_str(i); } - case (_) { p.fatal("expecting ident"); fail; } +fn parse_ident(p: &parser) -> ast::ident { + alt p.peek() { + token::IDENT(i, _) { p.bump(); ret p.get_str(i); } + _ { p.fatal("expecting ident"); fail; } } } -fn parse_value_ident(&parser p) -> ast::ident { +fn parse_value_ident(p: &parser) -> ast::ident { check_bad_word(p); ret parse_ident(p); } -fn eat(&parser p, &token::token tok) -> bool { - ret if p.peek() == tok { p.bump(); true } - else { false }; +fn eat(p: &parser, tok: &token::token) -> 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)) } - case (_) { false } +fn is_word(p: &parser, word: &str) -> bool { + ret alt p.peek() { + token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) } + _ { false } }; } -fn eat_word(&parser p, &str word) -> bool { - alt (p.peek()) { - case (token::IDENT(?sid, false)) { - if (str::eq(word, p.get_str(sid))) { - p.bump(); - ret true; - } else { ret false; } - } - case (_) { ret false; } +fn eat_word(p: &parser, word: &str) -> bool { + alt p.peek() { + token::IDENT(sid, false) { + if str::eq(word, p.get_str(sid)) { + p.bump(); + ret true; + } else { ret false; } + } + _ { ret false; } } } -fn expect_word(&parser p, &str word) { - if (!eat_word(p, word)) { +fn expect_word(p: &parser, word: &str) { + if !eat_word(p, word) { p.fatal("expecting " + word + ", found " + - token::to_str(p.get_reader(), p.peek())); + token::to_str(p.get_reader(), p.peek())); } } -fn check_bad_word(&parser p) { - alt (p.peek()) { - case (token::IDENT(?sid, false)) { - auto w = p.get_str(sid); - if (p.get_bad_expr_words().contains_key(w)) { - p.fatal("found " + w + " in expression position"); - } +fn check_bad_word(p: &parser) { + alt p.peek() { + token::IDENT(sid, false) { + let w = p.get_str(sid); + if p.get_bad_expr_words().contains_key(w) { + p.fatal("found " + w + " in expression position"); } - case (_) { } + } + _ { } } } -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(); +fn parse_ty_fn(proto: ast::proto, p: &parser, lo: uint) -> ast::ty_ { + fn parse_fn_input_ty(p: &parser) -> ast::ty_arg { + let 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(); + p.bump(); + p.bump(); } - auto mode = ast::val; - if (p.peek() == token::BINOP(token::AND)) { + let mode = ast::val; + if p.peek() == token::BINOP(token::AND) { p.bump(); mode = ast::alias(eat_word(p, "mutable")); } - auto t = parse_ty(p); - ret spanned(lo, t.span.hi, rec(mode=mode, ty=t)); + let t = parse_ty(p); + ret spanned(lo, t.span.hi, {mode: mode, ty: t}); } - auto lo = p.get_lo_pos(); - auto inputs = + let lo = p.get_lo_pos(); + let inputs = parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), - parse_fn_input_ty, p); + parse_fn_input_ty, p); // FIXME: there's no syntax for this right now anyway // auto constrs = parse_constrs(~[], p); - let (@ast::constr)[] constrs = ~[]; - let @ast::ty output; - auto cf = ast::return; - if (p.peek() == token::RARROW) { + let constrs: (@ast::constr)[] = ~[]; + let output: @ast::ty; + let cf = ast::return; + if p.peek() == token::RARROW { p.bump(); - auto tmp = parse_ty_or_bang(p); - alt (tmp) { - case (a_ty(?t)) { output = t; } - case (a_bang) { - output = @spanned(lo, inputs.span.hi, ast::ty_bot); - cf = ast::noreturn; - } + let tmp = parse_ty_or_bang(p); + alt tmp { + a_ty(t) { output = t; } + a_bang. { + output = @spanned(lo, inputs.span.hi, ast::ty_bot); + cf = ast::noreturn; + } } } else { output = @spanned(lo, inputs.span.hi, ast::ty_nil); } ret ast::ty_fn(proto, inputs.node, output, cf, constrs); } -fn parse_proto(&parser p) -> ast::proto { - if (eat_word(p, "iter")) { +fn parse_proto(p: &parser) -> ast::proto { + if eat_word(p, "iter") { ret ast::proto_iter; } else if (eat_word(p, "fn")) { ret ast::proto_fn; @@ -315,183 +313,178 @@ fn parse_proto(&parser p) -> ast::proto { } else { unexpected(p, p.peek()); } } -fn parse_ty_obj(&parser p, &mutable uint hi) -> ast::ty_ { - fn parse_method_sig(&parser p) -> ast::ty_method { - auto flo = p.get_lo_pos(); - let ast::proto proto = parse_proto(p); - auto ident = parse_value_ident(p); - auto f = parse_ty_fn(proto, p, flo); +fn parse_ty_obj(p: &parser, hi: &mutable uint) -> ast::ty_ { + fn parse_method_sig(p: &parser) -> ast::ty_method { + let flo = p.get_lo_pos(); + let proto: ast::proto = parse_proto(p); + let ident = parse_value_ident(p); + let f = parse_ty_fn(proto, p, flo); expect(p, token::SEMI); - alt (f) { - case (ast::ty_fn(?proto, ?inputs, ?output, ?cf, ?constrs)) { - ret spanned(flo, output.span.hi, - rec(proto=proto, - ident=ident, - inputs=inputs, - output=output, - cf=cf, - constrs=constrs)); - } + alt f { + ast::ty_fn(proto, inputs, output, cf, constrs) { + ret spanned(flo, output.span.hi, + {proto: proto, + ident: ident, + inputs: inputs, + output: output, + cf: cf, + constrs: constrs}); + } } fail; } - auto meths = parse_seq(token::LBRACE, token::RBRACE, none, - parse_method_sig, p); + let meths = + parse_seq(token::LBRACE, token::RBRACE, none, parse_method_sig, p); hi = meths.span.hi; ret ast::ty_obj(meths.node); } -fn parse_mt(&parser p) -> ast::mt { - auto mut = parse_mutability(p); - auto t = parse_ty(p); - ret rec(ty=t, mut=mut); +fn parse_mt(p: &parser) -> ast::mt { + let mut = parse_mutability(p); + let t = parse_ty(p); + ret {ty: t, mut: mut}; } -fn parse_ty_field(&parser p) -> ast::ty_field { - auto lo = p.get_lo_pos(); - auto mut = parse_mutability(p); - auto id = parse_ident(p); +fn parse_ty_field(p: &parser) -> ast::ty_field { + let lo = p.get_lo_pos(); + let mut = parse_mutability(p); + let id = parse_ident(p); expect(p, token::COLON); - auto ty = parse_ty(p); - ret spanned(lo, ty.span.hi, rec(ident=id, mt=rec(ty=ty, mut=mut))); + let ty = parse_ty(p); + ret spanned(lo, ty.span.hi, {ident: id, mt: {ty: ty, mut: mut}}); } // if i is the jth ident in args, return j // otherwise, fail -fn ident_index(&parser p, &ast::arg[] args, &ast::ident i) -> uint { - auto j = 0u; - for (ast::arg a in args) { if (a.ident == i) { ret j; } j += 1u; } +fn ident_index(p: &parser, args: &ast::arg[], i: &ast::ident) -> uint { + let j = 0u; + for a: ast::arg in args { if a.ident == i { ret j; } j += 1u; } p.fatal("Unbound variable " + i + " in constraint arg"); } -fn parse_type_constr_arg(&parser p) -> @ast::ty_constr_arg { - auto sp = p.get_span(); - auto carg = ast::carg_base; +fn parse_type_constr_arg(p: &parser) -> @ast::ty_constr_arg { + let sp = p.get_span(); + let carg = ast::carg_base; expect(p, token::BINOP(token::STAR)); - if (p.peek() == token::DOT) { + if p.peek() == token::DOT { // "*..." notation for record fields p.bump(); - let ast::path pth = parse_path(p); + let pth: ast::path = parse_path(p); carg = ast::carg_ident(pth); } // No literals yet, I guess? - ret @rec(node=carg, span=sp); + ret @{node: carg, span: sp}; } -fn parse_constr_arg(&ast::arg[] args, &parser p) -> @ast::constr_arg { - auto sp = p.get_span(); - auto carg = ast::carg_base; - if (p.peek() == token::BINOP(token::STAR)) { +fn parse_constr_arg(args: &ast::arg[], p: &parser) -> @ast::constr_arg { + let sp = p.get_span(); + let carg = ast::carg_base; + if p.peek() == token::BINOP(token::STAR) { p.bump(); } else { - let ast::ident i = parse_value_ident(p); + let i: ast::ident = parse_value_ident(p); carg = ast::carg_ident(ident_index(p, args, i)); } - ret @rec(node=carg, span=sp); + ret @{node: carg, span: sp}; } -fn parse_ty_constr(&ast::arg[] fn_args, &parser p) -> @ast::constr { - auto lo = p.get_lo_pos(); - auto path = parse_path(p); - auto pf = bind parse_constr_arg(fn_args, _); - let rec((@ast::constr_arg)[] node, span span) args = - parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), pf, - p); +fn parse_ty_constr(fn_args: &ast::arg[], p: &parser) -> @ast::constr { + let lo = p.get_lo_pos(); + let path = parse_path(p); + let pf = bind parse_constr_arg(fn_args, _); + let args: {node: (@ast::constr_arg)[], span: span} = + parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), pf, p); ret @spanned(lo, args.span.hi, - rec(path=path, args=args.node, id=p.get_id())); + {path: path, args: args.node, id: p.get_id()}); } -fn parse_constr_in_type(&parser p) -> @ast::ty_constr { - auto lo = p.get_lo_pos(); - auto path = parse_path(p); - let (@ast::ty_constr_arg)[] args = - (parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), - parse_type_constr_arg, p)).node; - auto hi = p.get_lo_pos(); - let ast::ty_constr_ tc = rec(path=path, args=args, id=p.get_id()); +fn parse_constr_in_type(p: &parser) -> @ast::ty_constr { + let lo = p.get_lo_pos(); + let path = parse_path(p); + let args: (@ast::ty_constr_arg)[] = + parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), + parse_type_constr_arg, p).node; + let hi = p.get_lo_pos(); + let tc: ast::ty_constr_ = {path: path, args: args, id: p.get_id()}; ret @spanned(lo, hi, tc); } -fn parse_constrs[T](fn(&parser p) -> - (@ast::constr_general[T]) pser, &parser p) - -> (@ast::constr_general[T])[] { - let (@ast::constr_general[T])[] constrs = ~[]; - while (true) { - auto constr = pser(p); +fn parse_constrs[T](pser: fn(&parser) -> @ast::constr_general[T] , p: &parser) + -> (@ast::constr_general[T])[] { + let constrs: (@ast::constr_general[T])[] = ~[]; + while true { + let constr = pser(p); constrs += ~[constr]; - if (p.peek() == token::COMMA) { p.bump(); } else { break; } + if p.peek() == token::COMMA { p.bump(); } else { break; } } constrs } -fn parse_type_constraints(&parser p) -> (@ast::ty_constr)[] { +fn parse_type_constraints(p: &parser) -> (@ast::ty_constr)[] { ret parse_constrs(parse_constr_in_type, p); } -fn parse_ty_postfix(ast::ty_ orig_t, &parser p) -> @ast::ty { - auto lo = p.get_lo_pos(); - if (p.peek() == token::LBRACKET) { +fn parse_ty_postfix(orig_t: ast::ty_, p: &parser) -> @ast::ty { + let lo = p.get_lo_pos(); + if p.peek() == token::LBRACKET { p.bump(); - auto mut; - if (eat_word(p, "mutable")) { - if (p.peek() == token::QUES) { + let mut; + if eat_word(p, "mutable") { + if p.peek() == token::QUES { p.bump(); mut = ast::maybe_mut; - } else { - mut = ast::mut; - } - } else { - mut = ast::imm; - } + } else { mut = ast::mut; } + } else { mut = ast::imm; } - if (mut == ast::imm && p.peek() != token::RBRACKET) { + if mut == ast::imm && p.peek() != token::RBRACKET { // This is explicit type parameter instantiation. - auto seq = parse_seq_to_end(token::RBRACKET, - some(token::COMMA), parse_ty, p); - - alt (orig_t) { - case (ast::ty_path(?pth, ?ann)) { - auto hi = p.get_hi_pos(); - ret @spanned(lo, hi, - ast::ty_path(spanned(lo, hi, - rec(global=pth.node.global, - idents=pth.node.idents, - types=seq)), - ann)); - } - case (_) { - p.fatal("type parameter instantiation only allowed for " + - "paths"); - } + let seq = + parse_seq_to_end(token::RBRACKET, some(token::COMMA), + parse_ty, p); + + + alt orig_t { + ast::ty_path(pth, ann) { + let hi = p.get_hi_pos(); + ret @spanned(lo, hi, + ast::ty_path(spanned(lo, hi, + {global: pth.node.global, + idents: pth.node.idents, + types: seq}), ann)); + } + _ { + p.fatal("type parameter instantiation only allowed for " + + "paths"); + } } } expect(p, token::RBRACKET); - auto hi = p.get_hi_pos(); + let hi = p.get_hi_pos(); // FIXME: spans are probably wrong - auto t = ast::ty_ivec(rec(ty=@spanned(lo, hi, orig_t), mut=mut)); + let t = ast::ty_ivec({ty: @spanned(lo, hi, orig_t), mut: mut}); ret parse_ty_postfix(t, p); } ret @spanned(lo, p.get_lo_pos(), orig_t); } -fn parse_ty_or_bang(&parser p) -> ty_or_bang { - alt (p.peek()) { - case (token::NOT) { p.bump(); ret a_bang; } - case (_) { ret a_ty(parse_ty(p)); } +fn parse_ty_or_bang(p: &parser) -> ty_or_bang { + alt p.peek() { + token::NOT. { p.bump(); ret a_bang; } + _ { ret a_ty(parse_ty(p)); } } } -fn parse_ty(&parser p) -> @ast::ty { - auto lo = p.get_lo_pos(); - auto hi = lo; - let ast::ty_ t; +fn parse_ty(p: &parser) -> @ast::ty { + let lo = p.get_lo_pos(); + let hi = lo; + let t: ast::ty_; // FIXME: do something with this parse_layer(p); - if (eat_word(p, "bool")) { + if eat_word(p, "bool") { t = ast::ty_bool; } else if (eat_word(p, "int")) { t = ast::ty_int; @@ -529,36 +522,34 @@ fn parse_ty(&parser p) -> @ast::ty { t = ast::ty_machine(ast::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 (_) { - t = parse_ty(p).node; - hi = p.get_hi_pos(); - expect(p, token::RPAREN); - } + alt p.peek() { + token::RPAREN. { hi = p.get_hi_pos(); p.bump(); t = ast::ty_nil; } + _ { + t = parse_ty(p).node; + hi = p.get_hi_pos(); + expect(p, token::RPAREN); + } } } else if (p.peek() == token::AT) { p.bump(); - auto mt = parse_mt(p); + let mt = parse_mt(p); hi = mt.ty.span.hi; t = ast::ty_box(mt); } else if (p.peek() == token::BINOP(token::STAR)) { p.bump(); - auto mt = parse_mt(p); + let mt = parse_mt(p); hi = mt.ty.span.hi; 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, p); + let elems = + parse_seq(token::LBRACE, token::RBRACE, some(token::COMMA), + parse_ty_field, p); hi = elems.span.hi; t = ast::ty_rec(elems.node); - if (p.peek() == token::COLON) { + if p.peek() == token::COLON { p.bump(); - t = ast::ty_constr(@spanned(lo, hi, t), + t = + ast::ty_constr(@spanned(lo, hi, t), parse_type_constraints(p)); } } else if (eat_word(p, "vec")) { @@ -567,17 +558,17 @@ fn parse_ty(&parser p) -> @ast::ty { hi = p.get_hi_pos(); expect(p, token::RBRACKET); } else if (eat_word(p, "fn")) { - auto flo = p.get_last_lo_pos(); + let 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; } } + alt t { ast::ty_fn(_, _, out, _, _) { hi = out.span.hi; } } } else if (eat_word(p, "block")) { - auto flo = p.get_last_lo_pos(); + let flo = p.get_last_lo_pos(); t = parse_ty_fn(ast::proto_block, p, flo); - alt (t) { case (ast::ty_fn(_, _, ?out, _, _)) { hi = out.span.hi; } } + alt t { ast::ty_fn(_, _, out, _, _) { hi = out.span.hi; } } } else if (eat_word(p, "iter")) { - auto flo = p.get_last_lo_pos(); + let 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; } } + alt t { 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")) { @@ -592,45 +583,43 @@ fn parse_ty(&parser p) -> @ast::ty { expect(p, token::RBRACKET); } else if (eat_word(p, "mutable")) { p.warn("ignoring deprecated 'mutable' type constructor"); - auto typ = parse_ty(p); + let typ = parse_ty(p); t = typ.node; hi = typ.span.hi; } else if (p.peek() == token::MOD_SEP || is_ident(p.peek())) { - auto path = parse_path(p); + let path = parse_path(p); t = ast::ty_path(path, p.get_id()); hi = path.span.hi; } else { p.fatal("expecting type"); t = ast::ty_nil; fail; } ret parse_ty_postfix(t, p); } -fn parse_arg(&parser p) -> ast::arg { - let ast::mode m = ast::val; - let ast::ident i = parse_value_ident(p); +fn parse_arg(p: &parser) -> ast::arg { + let m: ast::mode = ast::val; + let i: ast::ident = 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); - ret rec(mode=m, ty=t, ident=i, id=p.get_id()); + let t: @ast::ty = parse_ty(p); + ret {mode: m, ty: t, ident: i, id: p.get_id()}; } -fn parse_seq_to_end[T](token::token ket, option::t[token::token] sep, - fn(&parser)->T f, &parser p) -> T[] { - auto val = parse_seq_to_before_end(ket, sep, f, p); +fn parse_seq_to_end[T](ket: token::token, sep: option::t[token::token], + f: fn(&parser) -> T , p: &parser) -> T[] { + let val = parse_seq_to_before_end(ket, sep, f, p); p.bump(); ret val; } -fn parse_seq_to_before_end[T](token::token ket, option::t[token::token] sep, - fn(&parser)->T f, &parser p) -> T[] { - let bool first = true; - let T[] v = ~[]; - while (p.peek() != ket) { - alt (sep) { - case (some(?t)) { - if (first) { first = false; } else { expect(p, t); } - } - case (_) { } +fn parse_seq_to_before_end[T](ket: token::token, sep: option::t[token::token], + f: fn(&parser) -> T , p: &parser) -> T[] { + let first: bool = true; + let v: T[] = ~[]; + while p.peek() != ket { + alt sep { + some(t) { if first { first = false; } else { expect(p, t); } } + _ { } } v += ~[f(p)]; } @@ -638,170 +627,167 @@ fn parse_seq_to_before_end[T](token::token ket, option::t[token::token] sep, } -fn parse_seq[T](token::token bra, token::token ket, - option::t[token::token] sep, - fn(&parser)->T f, &parser p) -> spanned[T[]] { - auto lo = p.get_lo_pos(); +fn parse_seq[T](bra: token::token, ket: token::token, + sep: option::t[token::token], f: fn(&parser) -> T , + p: &parser) -> spanned[T[]] { + let lo = p.get_lo_pos(); expect(p, bra); - auto result = parse_seq_to_before_end[T](ket, sep, f, p); - auto hi = p.get_hi_pos(); + let result = parse_seq_to_before_end[T](ket, sep, f, p); + let hi = p.get_hi_pos(); p.bump(); ret spanned(lo, hi, result); } -fn parse_lit(&parser p) -> ast::lit { - auto sp = p.get_span(); - let ast::lit_ lit = ast::lit_nil; - if (eat_word(p, "true")) { +fn parse_lit(p: &parser) -> ast::lit { + let sp = p.get_span(); + let lit: ast::lit_ = ast::lit_nil; + 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), ast::sk_rc); - } - case (token::LPAREN) { - p.bump(); - expect(p, token::RPAREN); - lit = ast::lit_nil; - } - case (?t) { unexpected(p, t); } + alt p.peek() { + token::LIT_INT(i) { p.bump(); lit = ast::lit_int(i); } + token::LIT_UINT(u) { p.bump(); lit = ast::lit_uint(u); } + token::LIT_FLOAT(s) { + p.bump(); + lit = ast::lit_float(p.get_str(s)); + } + token::LIT_MACH_INT(tm, i) { + p.bump(); + lit = ast::lit_mach_int(tm, i); + } + token::LIT_MACH_FLOAT(tm, s) { + p.bump(); + lit = ast::lit_mach_float(tm, p.get_str(s)); + } + token::LIT_CHAR(c) { p.bump(); lit = ast::lit_char(c); } + token::LIT_STR(s) { + p.bump(); + lit = ast::lit_str(p.get_str(s), ast::sk_rc); + } + token::LPAREN. { + p.bump(); + expect(p, token::RPAREN); + lit = ast::lit_nil; + } + t { unexpected(p, t); } } } - ret rec(node=lit, span=sp); + ret {node: lit, span: sp}; } -fn is_ident(token::token t) -> bool { - alt (t) { case (token::IDENT(_, _)) { ret true; } case (_) { } } +fn is_ident(t: token::token) -> bool { + alt t { token::IDENT(_, _) { ret true; } _ { } } ret false; } -fn is_plain_ident(&parser p) -> bool { +fn is_plain_ident(p: &parser) -> 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; +fn parse_path(p: &parser) -> ast::path { + let lo = p.get_lo_pos(); + let hi = lo; - auto global; - if (p.peek() == token::MOD_SEP) { - global = true; p.bump(); - } else { - global = false; - } + let global; + if p.peek() == token::MOD_SEP { + global = true; + p.bump(); + } else { global = false; } - let ast::ident[] ids = ~[]; - while (true) { - alt (p.peek()) { - case (token::IDENT(?i, _)) { - hi = p.get_hi_pos(); - ids += ~[p.get_str(i)]; - hi = p.get_hi_pos(); - p.bump(); - if (p.peek() == token::MOD_SEP) { p.bump(); } else { break; } - } - case (_) { break; } + let ids: ast::ident[] = ~[]; + while true { + alt p.peek() { + token::IDENT(i, _) { + hi = p.get_hi_pos(); + ids += ~[p.get_str(i)]; + hi = p.get_hi_pos(); + p.bump(); + if p.peek() == token::MOD_SEP { p.bump(); } else { break; } + } + _ { break; } } } - ret spanned(lo, hi, rec(global=global, idents=ids, types=~[])); -} - -fn parse_path_and_ty_param_substs(&parser p) -> ast::path { - auto lo = p.get_lo_pos(); - auto path = parse_path(p); - if (p.peek() == token::LBRACKET) { - auto seq = parse_seq(token::LBRACKET, token::RBRACKET, - some(token::COMMA), parse_ty, p); - auto hi = seq.span.hi; - path = spanned(lo, hi, rec(global=path.node.global, - idents=path.node.idents, - types=seq.node)); + ret spanned(lo, hi, {global: global, idents: ids, types: ~[]}); +} + +fn parse_path_and_ty_param_substs(p: &parser) -> ast::path { + let lo = p.get_lo_pos(); + let path = parse_path(p); + if p.peek() == token::LBRACKET { + let seq = + parse_seq(token::LBRACKET, token::RBRACKET, some(token::COMMA), + parse_ty, p); + let hi = seq.span.hi; + path = + spanned(lo, hi, + {global: path.node.global, + idents: path.node.idents, + types: seq.node}); } ret path; } -fn parse_mutability(&parser p) -> ast::mutability { - if (eat_word(p, "mutable")) { - if (p.peek() == token::QUES) { p.bump(); ret ast::maybe_mut; } +fn parse_mutability(p: &parser) -> ast::mutability { + if eat_word(p, "mutable") { + if p.peek() == token::QUES { p.bump(); ret ast::maybe_mut; } ret ast::mut; } ret ast::imm; } -fn parse_field(&parser p, &token::token sep) -> ast::field { - auto lo = p.get_lo_pos(); - auto m = parse_mutability(p); - auto i = parse_ident(p); +fn parse_field(p: &parser, sep: &token::token) -> ast::field { + let lo = p.get_lo_pos(); + let m = parse_mutability(p); + let i = parse_ident(p); expect(p, sep); - auto e = parse_expr(p); - ret spanned(lo, e.span.hi, rec(mut=m, ident=i, expr=e)); + let e = parse_expr(p); + ret spanned(lo, e.span.hi, {mut: m, ident: i, expr: e}); } -fn mk_expr(&parser p, uint lo, uint hi, &ast::expr_ node) -> @ast::expr { - ret @rec(id=p.get_id(), - node=node, - span=rec(lo=lo, hi=hi)); +fn mk_expr(p: &parser, lo: uint, hi: uint, node: &ast::expr_) -> @ast::expr { + ret @{id: p.get_id(), node: node, span: {lo: lo, hi: hi}}; } -fn mk_mac_expr(&parser p, uint lo, uint hi, &ast::mac_ m) -> @ast::expr { - ret @rec(id=p.get_id(), - node=ast::expr_mac(rec(node=m, span=rec(lo=lo, hi=hi))), - span=rec(lo=lo, hi=hi)); +fn mk_mac_expr(p: &parser, lo: uint, hi: uint, m: &ast::mac_) -> @ast::expr { + ret @{id: p.get_id(), + node: ast::expr_mac({node: m, span: {lo: lo, hi: hi}}), + span: {lo: lo, hi: hi}}; } -fn parse_bottom_expr(&parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); - auto hi = p.get_hi_pos(); +fn parse_bottom_expr(p: &parser) -> @ast::expr { + let lo = p.get_lo_pos(); + let hi = p.get_hi_pos(); // FIXME: can only remove this sort of thing when both typestate and // alt-exhaustive-match checking are co-operating. - auto lit = @spanned(lo, hi, ast::lit_nil); - let ast::expr_ ex = ast::expr_lit(lit); - if (p.peek() == token::LPAREN) { + let lit = @spanned(lo, hi, ast::lit_nil); + let ex: ast::expr_ = ast::expr_lit(lit); + 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 mk_expr(p, lo, hi, ast::expr_lit(lit)); - } - case (_) {/* fall through */ } + alt p.peek() { + token::RPAREN. { + hi = p.get_hi_pos(); + p.bump(); + let lit = @spanned(lo, hi, ast::lit_nil); + ret mk_expr(p, lo, hi, ast::expr_lit(lit)); + } + _ {/* fall through */ } } - auto e = parse_expr(p); + let e = parse_expr(p); hi = p.get_hi_pos(); expect(p, token::RPAREN); ret mk_expr(p, lo, hi, e.node); } else if (p.peek() == token::LBRACE) { p.bump(); - if (is_word(p, "mutable") || - is_plain_ident(p) && p.look_ahead(1u) == token::COLON) { - auto fields = ~[parse_field(p, token::COLON)]; - auto base = none; + if is_word(p, "mutable") || + is_plain_ident(p) && p.look_ahead(1u) == token::COLON { + let fields = ~[parse_field(p, token::COLON)]; + let base = none; while p.peek() != token::RBRACE { - if eat_word(p, "with") { - base = some(parse_expr(p)); - break; - } + if eat_word(p, "with") { base = some(parse_expr(p)); break; } expect(p, token::COMMA); fields += ~[parse_field(p, token::COLON)]; } @@ -809,7 +795,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { expect(p, token::RBRACE); ex = ast::expr_rec(fields, base); } else { - auto blk = parse_block_tail(p, lo); + let blk = parse_block_tail(p, lo); ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk)); } } else if (eat_word(p, "if")) { @@ -832,64 +818,63 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { ret parse_fn_expr(p, ast::proto_closure); } else if (p.peek() == token::LBRACKET) { p.bump(); - auto mut = parse_mutability(p); - auto es = parse_seq_to_end(token::RBRACKET, some(token::COMMA), - parse_expr, p); + let mut = parse_mutability(p); + let es = + parse_seq_to_end(token::RBRACKET, some(token::COMMA), parse_expr, + p); ex = ast::expr_vec(es, mut, ast::sk_rc); } else if (p.peek() == token::POUND_LT) { p.bump(); - auto ty = parse_ty(p); + let ty = parse_ty(p); expect(p, token::GT); + /* hack: early return to take advantage of specialized function */ ret mk_mac_expr(p, lo, p.get_hi_pos(), ast::mac_embed_type(ty)) } else if (p.peek() == token::POUND_LBRACE) { p.bump(); - auto blk = ast::mac_embed_block(parse_block_tail(p, lo)); + let blk = ast::mac_embed_block(parse_block_tail(p, lo)); ret mk_mac_expr(p, lo, p.get_hi_pos(), blk); } else if (p.peek() == token::ELLIPSIS) { p.bump(); ret mk_mac_expr(p, lo, p.get_hi_pos(), ast::mac_ellipsis) } else if (p.peek() == token::TILDE) { p.bump(); - alt (p.peek()) { - case (token::LBRACKET) { // unique array (temporary) - p.bump(); - auto mut = parse_mutability(p); - auto es = parse_seq_to_end - (token::RBRACKET, some(token::COMMA), parse_expr, p); - ex = ast::expr_vec(es, mut, ast::sk_unique); - } - case (token::LIT_STR(?s)) { - p.bump(); - auto lit = - @rec(node=ast::lit_str(p.get_str(s), ast::sk_unique), - span=p.get_span()); - ex = ast::expr_lit(lit); - } - case (_) { - p.fatal("unimplemented: unique pointer creation"); - } + alt p.peek() { + token::LBRACKET. { // unique array (temporary) + p.bump(); + let mut = parse_mutability(p); + let es = + parse_seq_to_end(token::RBRACKET, some(token::COMMA), + parse_expr, p); + ex = ast::expr_vec(es, mut, ast::sk_unique); + } + token::LIT_STR(s) { + p.bump(); + let lit = + @{node: ast::lit_str(p.get_str(s), ast::sk_unique), + span: p.get_span()}; + ex = ast::expr_lit(lit); + } + _ { p.fatal("unimplemented: unique pointer creation"); } } } else if (eat_word(p, "obj")) { // Anonymous object // Only make people type () if they're actually adding new fields - let option::t[ast::anon_obj_field[]] fields = none; - if (p.peek() == token::LPAREN) { + let fields: option::t[ast::anon_obj_field[]] = none; + if p.peek() == token::LPAREN { p.bump(); fields = some(parse_seq_to_end(token::RPAREN, some(token::COMMA), - parse_anon_obj_field, p)); + parse_anon_obj_field, p)); } - let (@ast::method)[] meths = ~[]; - let option::t[@ast::expr] with_obj = none; + let meths: (@ast::method)[] = ~[]; + let with_obj: option::t[@ast::expr] = none; expect(p, token::LBRACE); - while (p.peek() != token::RBRACE) { - if (eat_word(p, "with")) { + while p.peek() != token::RBRACE { + if eat_word(p, "with") { with_obj = some(parse_expr(p)); - } else { - meths += ~[parse_method(p)]; - } + } else { meths += ~[parse_method(p)]; } } hi = p.get_hi_pos(); expect(p, token::RBRACE); @@ -899,44 +884,42 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { // We don't need to pull ".node" out of fields because it's not a // "spanned". - let ast::anon_obj ob = - rec(fields=fields, methods=meths, with_obj=with_obj); + let ob: ast::anon_obj = + {fields: fields, methods: meths, with_obj: with_obj}; ex = ast::expr_anon_obj(ob); } 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::UNDERSCORE) { p.bump(); ret none; } - case (_) { ret some(parse_expr(p)); } + let e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS); + fn parse_expr_opt(p: &parser) -> option::t[@ast::expr] { + alt p.peek() { + token::UNDERSCORE. { p.bump(); ret none; } + _ { ret some(parse_expr(p)); } } } - auto es = parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), - parse_expr_opt, p); + let es = + parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), + parse_expr_opt, p); hi = es.span.hi; ex = ast::expr_bind(e, es.node); } else if (p.peek() == token::POUND) { - auto ex_ext = parse_syntax_ext(p); + let ex_ext = parse_syntax_ext(p); hi = ex_ext.span.hi; ex = ex_ext.node; } else if (eat_word(p, "fail")) { - if (can_begin_expr(p.peek())) { - auto e = parse_expr(p); + if can_begin_expr(p.peek()) { + let e = parse_expr(p); hi = e.span.hi; ex = ast::expr_fail(some(e)); - } - else { - ex = ast::expr_fail(none); - } + } else { ex = ast::expr_fail(none); } } else if (eat_word(p, "log")) { - auto e = parse_expr(p); + let e = parse_expr(p); ex = ast::expr_log(1, e); hi = e.span.hi; } else if (eat_word(p, "log_err")) { - auto e = parse_expr(p); + let e = parse_expr(p); ex = ast::expr_log(0, e); hi = e.span.hi; } else if (eat_word(p, "assert")) { - auto e = parse_expr(p); + let e = parse_expr(p); ex = ast::expr_assert(e); hi = e.span.hi; } else if (eat_word(p, "check")) { @@ -944,7 +927,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { arguments that are all either slot variables or literals. but the typechecker enforces that. */ - auto e = parse_expr(p); + let e = parse_expr(p); hi = e.span.hi; ex = ast::expr_check(ast::checked, e); } else if (eat_word(p, "claim")) { @@ -952,18 +935,15 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { is enabled (a command-line flag), then the parser turns claims into check */ - auto e = parse_expr(p); + let e = parse_expr(p); hi = e.span.hi; ex = ast::expr_check(ast::unchecked, e); } else if (eat_word(p, "ret")) { - if (can_begin_expr(p.peek())) { - auto e = parse_expr(p); + if can_begin_expr(p.peek()) { + let e = parse_expr(p); hi = e.span.hi; ex = ast::expr_ret(some(e)); - } - else { - ex = ast::expr_ret(none); - } + } else { ex = ast::expr_ret(none); } } else if (eat_word(p, "break")) { ex = ast::expr_break; hi = p.get_hi_pos(); @@ -971,25 +951,26 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { ex = ast::expr_cont; hi = p.get_hi_pos(); } else if (eat_word(p, "put")) { - alt (p.peek()) { - case (token::SEMI) { ex = ast::expr_put(none); } - case (_) { - auto e = parse_expr(p); - hi = e.span.hi; - ex = ast::expr_put(some(e)); - } + alt p.peek() { + token::SEMI. { ex = ast::expr_put(none); } + _ { + let e = parse_expr(p); + hi = e.span.hi; + ex = ast::expr_put(some(e)); + } } } else if (eat_word(p, "be")) { - auto e = parse_expr(p); + let e = parse_expr(p); + // FIXME: Is this the right place for this check? - if (/*check*/ast::is_call_expr(e)) { + if /*check*/ast::is_call_expr(e) { hi = e.span.hi; ex = ast::expr_be(e); } else { p.fatal("Non-call expression in tail call"); } } else if (eat_word(p, "port")) { - auto ty = none; - if(token::LBRACKET == p.peek()) { + let ty = none; + if token::LBRACKET == p.peek() { expect(p, token::LBRACKET); ty = some(parse_ty(p)); expect(p, token::RBRACKET); @@ -1000,7 +981,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { ex = ast::expr_port(ty); } else if (eat_word(p, "chan")) { expect(p, token::LPAREN); - auto e = parse_expr(p); + let e = parse_expr(p); hi = e.span.hi; expect(p, token::RPAREN); ex = ast::expr_chan(e); @@ -1009,536 +990,528 @@ fn parse_bottom_expr(&parser p) -> @ast::expr { expect(p, token::DOT); // The rest is a call expression. - let @ast::expr f = parse_self_method(p); - auto es = parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), - parse_expr, p); + let f: @ast::expr = parse_self_method(p); + let es = + parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), + parse_expr, p); hi = es.span.hi; ex = ast::expr_call(f, es.node); } else if (p.peek() == token::MOD_SEP || - (is_ident(p.peek()) && !is_word(p, "true") && - !is_word(p, "false"))) { + is_ident(p.peek()) && !is_word(p, "true") && + !is_word(p, "false")) { check_bad_word(p); - auto pth = parse_path_and_ty_param_substs(p); + let pth = parse_path_and_ty_param_substs(p); hi = pth.span.hi; ex = ast::expr_path(pth); } else { - auto lit = parse_lit(p); + let lit = parse_lit(p); hi = lit.span.hi; ex = ast::expr_lit(@lit); } ret mk_expr(p, lo, hi, ex); } -fn parse_syntax_ext(&parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); +fn parse_syntax_ext(p: &parser) -> @ast::expr { + let lo = p.get_lo_pos(); expect(p, token::POUND); ret parse_syntax_ext_naked(p, lo); } -fn parse_syntax_ext_naked(&parser p, uint lo) -> @ast::expr { - auto pth = parse_path(p); - if (ivec::len(pth.node.idents) == 0u) { +fn parse_syntax_ext_naked(p: &parser, lo: uint) -> @ast::expr { + let pth = parse_path(p); + if ivec::len(pth.node.idents) == 0u { p.fatal("expected a syntax expander name"); } - auto es = parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), - parse_expr, p); - auto hi = es.span.hi; + let es = + parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), + parse_expr, p); + let hi = es.span.hi; ret mk_mac_expr(p, lo, hi, ast::mac_invoc(pth, es.node, none)); } -fn parse_self_method(&parser p) -> @ast::expr { - auto sp = p.get_span(); - let ast::ident f_name = parse_ident(p); +fn parse_self_method(p: &parser) -> @ast::expr { + let sp = p.get_span(); + let f_name: ast::ident = parse_ident(p); ret mk_expr(p, sp.lo, sp.hi, ast::expr_self_method(f_name)); } -fn parse_dot_or_call_expr(&parser p) -> @ast::expr { +fn parse_dot_or_call_expr(p: &parser) -> @ast::expr { ret parse_dot_or_call_expr_with(p, parse_bottom_expr(p)); } -fn parse_dot_or_call_expr_with(&parser p, @ast::expr e) -> @ast::expr { - auto lo = e.span.lo; - auto hi = e.span.hi; - while (true) { - alt (p.peek()) { - case (token::LPAREN) { - if (p.get_restriction() == RESTRICT_NO_CALL_EXPRS) { - ret e; - } else { - // Call expr. - - auto es = parse_seq(token::LPAREN, token::RPAREN, - some(token::COMMA), parse_expr, p); - hi = es.span.hi; - e = mk_expr(p, lo, hi, ast::expr_call(e, es.node)); - } +fn parse_dot_or_call_expr_with(p: &parser, e: @ast::expr) -> @ast::expr { + let lo = e.span.lo; + let hi = e.span.hi; + while true { + alt p.peek() { + token::LPAREN. { + if p.get_restriction() == RESTRICT_NO_CALL_EXPRS { + ret e; + } else { + // Call expr. + + let es = + parse_seq(token::LPAREN, token::RPAREN, + some(token::COMMA), parse_expr, p); + hi = es.span.hi; + e = mk_expr(p, lo, hi, ast::expr_call(e, es.node)); } - case (token::DOT) { + } + token::DOT. { + p.bump(); + alt p.peek() { + token::IDENT(i, _) { + hi = p.get_hi_pos(); p.bump(); - alt (p.peek()) { - case (token::IDENT(?i, _)) { - hi = p.get_hi_pos(); - p.bump(); - e = mk_expr(p, lo, hi, - ast::expr_field(e, p.get_str(i))); - } - case (token::LPAREN) { - p.bump(); - auto ix = parse_expr(p); - hi = ix.span.hi; - expect(p, token::RPAREN); - e = mk_expr(p, lo, hi, ast::expr_index(e, ix)); - } - case (?t) { unexpected(p, t); } - } + e = mk_expr(p, lo, hi, ast::expr_field(e, p.get_str(i))); + } + token::LPAREN. { + p.bump(); + let ix = parse_expr(p); + hi = ix.span.hi; + expect(p, token::RPAREN); + e = mk_expr(p, lo, hi, ast::expr_index(e, ix)); + } + t { unexpected(p, t); } } - case (_) { ret e; } + } + _ { ret e; } } } ret e; } -fn parse_prefix_expr(&parser p) -> @ast::expr { - if (eat_word(p, "mutable")) { +fn parse_prefix_expr(p: &parser) -> @ast::expr { + if eat_word(p, "mutable") { p.warn("ignoring deprecated 'mutable' prefix operator"); } - auto lo = p.get_lo_pos(); - auto hi = p.get_hi_pos(); + let lo = p.get_lo_pos(); + let hi = p.get_hi_pos(); // FIXME: can only remove this sort of thing when both typestate and // alt-exhaustive-match checking are co-operating. - auto lit = @spanned(lo, lo, ast::lit_nil); - let ast::expr_ ex = ast::expr_lit(lit); - alt (p.peek()) { - case (token::NOT) { + let lit = @spanned(lo, lo, ast::lit_nil); + let ex: ast::expr_ = ast::expr_lit(lit); + alt p.peek() { + token::NOT. { + p.bump(); + let e = parse_prefix_expr(p); + hi = e.span.hi; + ex = ast::expr_unary(ast::not, e); + } + token::BINOP(b) { + alt b { + token::MINUS. { p.bump(); - auto e = parse_prefix_expr(p); + let e = parse_prefix_expr(p); hi = e.span.hi; - ex = ast::expr_unary(ast::not, e); - } - case (token::BINOP(?b)) { - alt (b) { - case (token::MINUS) { - p.bump(); - auto e = parse_prefix_expr(p); - hi = e.span.hi; - ex = ast::expr_unary(ast::neg, e); - } - case (token::STAR) { - p.bump(); - auto e = parse_prefix_expr(p); - hi = e.span.hi; - ex = ast::expr_unary(ast::deref, e); - } - case (_) { ret parse_dot_or_call_expr(p); } - } - } - case (token::AT) { + ex = ast::expr_unary(ast::neg, e); + } + token::STAR. { p.bump(); - auto m = parse_mutability(p); - auto e = parse_prefix_expr(p); + let e = parse_prefix_expr(p); hi = e.span.hi; - ex = ast::expr_unary(ast::box(m), e); + ex = ast::expr_unary(ast::deref, e); + } + _ { ret parse_dot_or_call_expr(p); } } - case (_) { ret parse_dot_or_call_expr(p); } + } + token::AT. { + p.bump(); + let m = parse_mutability(p); + let e = parse_prefix_expr(p); + hi = e.span.hi; + ex = ast::expr_unary(ast::box(m), e); + } + _ { ret parse_dot_or_call_expr(p); } } ret mk_expr(p, lo, hi, ex); } -fn parse_ternary(&parser p) -> @ast::expr { - auto cond_expr = parse_binops(p); - if (p.peek() == token::QUES) { +fn parse_ternary(p: &parser) -> @ast::expr { + let cond_expr = parse_binops(p); + if p.peek() == token::QUES { p.bump(); - auto then_expr = parse_expr(p); + let then_expr = parse_expr(p); expect(p, token::COLON); - auto else_expr = parse_expr(p); + let else_expr = parse_expr(p); ret mk_expr(p, cond_expr.span.lo, else_expr.span.hi, ast::expr_ternary(cond_expr, then_expr, else_expr)); - } else { - ret cond_expr; - } + } else { ret cond_expr; } } -type op_spec = rec(token::token tok, ast::binop op, int prec); +type op_spec = {tok: token::token, op: ast::binop, prec: int}; // FIXME make this a const, don't store it in parser state fn prec_table() -> @op_spec[] { - ret @~[rec(tok=token::BINOP(token::STAR), op=ast::mul, prec=11), - rec(tok=token::BINOP(token::SLASH), op=ast::div, prec=11), - rec(tok=token::BINOP(token::PERCENT), op=ast::rem, prec=11), - rec(tok=token::BINOP(token::PLUS), op=ast::add, prec=10), - rec(tok=token::BINOP(token::MINUS), op=ast::sub, prec=10), - rec(tok=token::BINOP(token::LSL), op=ast::lsl, prec=9), - rec(tok=token::BINOP(token::LSR), op=ast::lsr, prec=9), - rec(tok=token::BINOP(token::ASR), op=ast::asr, prec=9), - 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), + ret @~[{tok: token::BINOP(token::STAR), op: ast::mul, prec: 11}, + {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::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}, + {tok: token::BINOP(token::AND), op: ast::bitand, prec: 8}, + {tok: token::BINOP(token::CARET), op: ast::bitxor, prec: 6}, + {tok: token::BINOP(token::OR), op: ast::bitor, prec: 6}, // '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), - rec(tok=token::GT, op=ast::gt, prec=4), - rec(tok=token::EQEQ, op=ast::eq, prec=3), - rec(tok=token::NE, op=ast::ne, prec=3), - rec(tok=token::ANDAND, op=ast::and, prec=2), - rec(tok=token::OROR, op=ast::or, prec=1)]; + {tok: token::LT, op: ast::lt, prec: 4}, + {tok: token::LE, op: ast::le, prec: 4}, + {tok: token::GE, op: ast::ge, prec: 4}, + {tok: token::GT, op: ast::gt, prec: 4}, + {tok: token::EQEQ, op: ast::eq, prec: 3}, + {tok: token::NE, op: ast::ne, prec: 3}, + {tok: token::ANDAND, op: ast::and, prec: 2}, + {tok: token::OROR, op: ast::or, prec: 1}]; } -fn parse_binops(&parser p) -> @ast::expr { +fn parse_binops(p: &parser) -> @ast::expr { ret parse_more_binops(p, parse_prefix_expr(p), 0); } -const int unop_prec = 100; +const unop_prec: int = 100; -const int as_prec = 5; -const int ternary_prec = 0; +const as_prec: int = 5; +const ternary_prec: int = 0; -fn parse_more_binops(&parser p, @ast::expr lhs, int min_prec) -> @ast::expr { - auto peeked = p.peek(); - for (op_spec cur in *p.get_prec_table()) { - if (cur.prec > min_prec && cur.tok == peeked) { +fn parse_more_binops(p: &parser, lhs: @ast::expr, min_prec: int) -> + @ast::expr { + let peeked = p.peek(); + for cur: op_spec in *p.get_prec_table() { + if cur.prec > min_prec && cur.tok == peeked { p.bump(); - auto rhs = parse_more_binops(p, parse_prefix_expr(p), cur.prec); - auto bin = mk_expr(p, lhs.span.lo, rhs.span.hi, - ast::expr_binary(cur.op, lhs, rhs)); + let rhs = parse_more_binops(p, parse_prefix_expr(p), cur.prec); + let bin = + mk_expr(p, lhs.span.lo, rhs.span.hi, + ast::expr_binary(cur.op, lhs, rhs)); ret parse_more_binops(p, bin, min_prec); } } - if (as_prec > min_prec && eat_word(p, "as")) { - auto rhs = parse_ty(p); - auto _as = mk_expr(p, lhs.span.lo, rhs.span.hi, - ast::expr_cast(lhs, rhs)); + if as_prec > min_prec && eat_word(p, "as") { + let rhs = parse_ty(p); + let _as = + mk_expr(p, lhs.span.lo, rhs.span.hi, ast::expr_cast(lhs, rhs)); ret parse_more_binops(p, _as, min_prec); } ret lhs; } -fn parse_assign_expr(&parser p) -> @ast::expr { - auto lo = p.get_lo_pos(); - auto lhs = parse_ternary(p); - alt (p.peek()) { - case (token::EQ) { - p.bump(); - auto rhs = parse_expr(p); - ret mk_expr(p, lo, rhs.span.hi, ast::expr_assign(lhs, rhs)); - } - case (token::BINOPEQ(?op)) { - p.bump(); - auto rhs = parse_expr(p); - auto aop = ast::add; - alt (op) { - case (token::PLUS) { aop = ast::add; } - case (token::MINUS) { aop = ast::sub; } - case (token::STAR) { aop = ast::mul; } - case (token::SLASH) { aop = ast::div; } - case (token::PERCENT) { aop = ast::rem; } - case (token::CARET) { aop = ast::bitxor; } - case (token::AND) { aop = ast::bitand; } - case (token::OR) { aop = ast::bitor; } - case (token::LSL) { aop = ast::lsl; } - case (token::LSR) { aop = ast::lsr; } - case (token::ASR) { aop = ast::asr; } - } - ret mk_expr(p, lo, rhs.span.hi, - ast::expr_assign_op(aop, lhs, rhs)); - } - case (token::LARROW) { - p.bump(); - auto rhs = parse_expr(p); - ret mk_expr(p, lo, rhs.span.hi, ast::expr_move(lhs, rhs)); - } - case (token::SEND) { - p.bump(); - auto rhs = parse_expr(p); - ret mk_expr(p, lo, rhs.span.hi, ast::expr_send(lhs, rhs)); - } - case (token::RECV) { - p.bump(); - auto rhs = parse_expr(p); - ret mk_expr(p, lo, rhs.span.hi, ast::expr_recv(lhs, rhs)); - } - case (token::DARROW) { - p.bump(); - auto rhs = parse_expr(p); - ret mk_expr(p, lo, rhs.span.hi, ast::expr_swap(lhs, rhs)); - } - case (_) {/* fall through */ } +fn parse_assign_expr(p: &parser) -> @ast::expr { + let lo = p.get_lo_pos(); + let lhs = parse_ternary(p); + alt p.peek() { + token::EQ. { + p.bump(); + let rhs = parse_expr(p); + ret mk_expr(p, lo, rhs.span.hi, ast::expr_assign(lhs, rhs)); + } + token::BINOPEQ(op) { + p.bump(); + let rhs = parse_expr(p); + let aop = ast::add; + alt op { + token::PLUS. { aop = ast::add; } + token::MINUS. { aop = ast::sub; } + token::STAR. { aop = ast::mul; } + token::SLASH. { aop = ast::div; } + token::PERCENT. { aop = ast::rem; } + token::CARET. { aop = ast::bitxor; } + token::AND. { aop = ast::bitand; } + token::OR. { aop = ast::bitor; } + token::LSL. { aop = ast::lsl; } + token::LSR. { aop = ast::lsr; } + token::ASR. { aop = ast::asr; } + } + ret mk_expr(p, lo, rhs.span.hi, ast::expr_assign_op(aop, lhs, rhs)); + } + token::LARROW. { + p.bump(); + let rhs = parse_expr(p); + ret mk_expr(p, lo, rhs.span.hi, ast::expr_move(lhs, rhs)); + } + token::SEND. { + p.bump(); + let rhs = parse_expr(p); + ret mk_expr(p, lo, rhs.span.hi, ast::expr_send(lhs, rhs)); + } + token::RECV. { + p.bump(); + let rhs = parse_expr(p); + ret mk_expr(p, lo, rhs.span.hi, ast::expr_recv(lhs, rhs)); + } + token::DARROW. { + p.bump(); + let rhs = parse_expr(p); + ret mk_expr(p, lo, rhs.span.hi, ast::expr_swap(lhs, rhs)); + } + _ {/* fall through */ } } ret lhs; } -fn parse_if_expr_1(&parser p) -> rec(@ast::expr cond, - ast::blk then, - option::t[@ast::expr] els, - uint lo, uint hi) { - auto lo = p.get_last_lo_pos(); - auto cond = parse_expr(p); - auto thn = parse_block(p); - let option::t[@ast::expr] els = none; - auto hi = thn.span.hi; - if (eat_word(p, "else")) { - auto elexpr = parse_else_expr(p); +fn parse_if_expr_1(p: &parser) -> + {cond: @ast::expr, + then: ast::blk, + els: option::t[@ast::expr], + lo: uint, + hi: uint} { + let lo = p.get_last_lo_pos(); + let cond = parse_expr(p); + let thn = parse_block(p); + let els: option::t[@ast::expr] = none; + let hi = thn.span.hi; + if eat_word(p, "else") { + let elexpr = parse_else_expr(p); els = some(elexpr); hi = elexpr.span.hi; } - ret rec(cond=cond, then=thn, els=els, lo=lo, hi=hi); + ret {cond: cond, then: thn, els: els, lo: lo, hi: hi}; } -fn parse_if_expr(&parser p) -> @ast::expr { - if (eat_word(p, "check")) { - auto q = parse_if_expr_1(p); - ret mk_expr(p, q.lo, q.hi, - ast::expr_if_check(q.cond, q.then, q.els)); - } - else { - auto q = parse_if_expr_1(p); +fn parse_if_expr(p: &parser) -> @ast::expr { + if eat_word(p, "check") { + let q = parse_if_expr_1(p); + ret mk_expr(p, q.lo, q.hi, ast::expr_if_check(q.cond, q.then, q.els)); + } else { + let q = parse_if_expr_1(p); ret mk_expr(p, q.lo, q.hi, ast::expr_if(q.cond, q.then, q.els)); } } -fn parse_fn_expr(&parser p, ast::proto proto) -> @ast::expr { - auto lo = p.get_last_lo_pos(); - auto decl = parse_fn_decl(p, ast::impure_fn); - auto body = parse_block(p); - auto _fn = rec(decl=decl, proto=proto, body=body); +fn parse_fn_expr(p: &parser, proto: ast::proto) -> @ast::expr { + let lo = p.get_last_lo_pos(); + let decl = parse_fn_decl(p, ast::impure_fn); + let body = parse_block(p); + let _fn = {decl: decl, proto: proto, body: body}; ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn)); } -fn parse_else_expr(&parser p) -> @ast::expr { - if (eat_word(p, "if")) { +fn parse_else_expr(p: &parser) -> @ast::expr { + if eat_word(p, "if") { ret parse_if_expr(p); } else { - auto blk = parse_block(p); + let blk = parse_block(p); ret mk_expr(p, blk.span.lo, blk.span.hi, ast::expr_block(blk)); } } -fn parse_for_expr(&parser p) -> @ast::expr { - auto lo = p.get_last_lo_pos(); - auto is_each = eat_word(p, "each"); - auto decl = parse_local(p, false); +fn parse_for_expr(p: &parser) -> @ast::expr { + let lo = p.get_last_lo_pos(); + let is_each = eat_word(p, "each"); + let decl = parse_local(p, false); expect_word(p, "in"); - auto seq = parse_expr(p); - auto body = parse_block(p); - auto hi = body.span.hi; + let seq = parse_expr(p); + let body = parse_block(p); + let hi = body.span.hi; 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)); - } + } else { ret mk_expr(p, lo, hi, ast::expr_for(decl, seq, body)); } } -fn parse_while_expr(&parser p) -> @ast::expr { - auto lo = p.get_last_lo_pos(); - auto cond = parse_expr(p); - auto body = parse_block(p); - auto hi = body.span.hi; +fn parse_while_expr(p: &parser) -> @ast::expr { + let lo = p.get_last_lo_pos(); + let cond = parse_expr(p); + let body = parse_block(p); + let hi = body.span.hi; ret mk_expr(p, lo, hi, ast::expr_while(cond, body)); } -fn parse_do_while_expr(&parser p) -> @ast::expr { - auto lo = p.get_last_lo_pos(); - auto body = parse_block(p); +fn parse_do_while_expr(p: &parser) -> @ast::expr { + let lo = p.get_last_lo_pos(); + let body = parse_block(p); expect_word(p, "while"); - auto cond = parse_expr(p); - auto hi = cond.span.hi; + let cond = parse_expr(p); + let hi = cond.span.hi; ret mk_expr(p, lo, hi, ast::expr_do_while(body, cond)); } -fn parse_alt_expr(&parser p) -> @ast::expr { - auto lo = p.get_last_lo_pos(); - auto discriminant = parse_expr(p); +fn parse_alt_expr(p: &parser) -> @ast::expr { + let lo = p.get_last_lo_pos(); + let discriminant = parse_expr(p); expect(p, token::LBRACE); - let ast::arm[] arms = ~[]; - while (p.peek() != token::RBRACE) { + let arms: ast::arm[] = ~[]; + while p.peek() != token::RBRACE { // Optionally eat the case keyword. // FIXME remove this (and the optional parens) once we've updated our // code to not use the old syntax eat_word(p, "case"); - auto parens = false; - if (p.peek() == token::LPAREN) { parens = true; p.bump(); } - auto pats = parse_pats(p); - if (parens) { expect(p, token::RPAREN); } - auto blk = parse_block(p); - arms += ~[rec(pats=pats, block=blk)]; - } - auto hi = p.get_hi_pos(); + let parens = false; + if p.peek() == token::LPAREN { parens = true; p.bump(); } + let pats = parse_pats(p); + if parens { expect(p, token::RPAREN); } + let blk = parse_block(p); + arms += ~[{pats: pats, block: blk}]; + } + let hi = p.get_hi_pos(); p.bump(); ret mk_expr(p, lo, hi, ast::expr_alt(discriminant, arms)); } -fn parse_spawn_expr(&parser p) -> @ast::expr { - auto lo = p.get_last_lo_pos(); +fn parse_spawn_expr(p: &parser) -> @ast::expr { + let lo = p.get_last_lo_pos(); // FIXME: Parse domain and name // FIXME: why no full expr? - auto fn_expr = parse_bottom_expr(p); - auto es = parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), - parse_expr, p); - auto hi = es.span.hi; - ret mk_expr(p, lo, hi, ast::expr_spawn - (ast::dom_implicit, option::none, fn_expr, es.node)); + let fn_expr = parse_bottom_expr(p); + let es = + parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), + parse_expr, p); + let hi = es.span.hi; + ret mk_expr(p, lo, hi, + ast::expr_spawn(ast::dom_implicit, option::none, fn_expr, + es.node)); } -fn parse_expr(&parser p) -> @ast::expr { +fn parse_expr(p: &parser) -> @ast::expr { ret parse_expr_res(p, UNRESTRICTED); } -fn parse_expr_res(&parser p, restriction r) -> @ast::expr { - auto old = p.get_restriction(); +fn parse_expr_res(p: &parser, r: restriction) -> @ast::expr { + let old = p.get_restriction(); p.restrict(r); - auto e = parse_assign_expr(p); + let e = parse_assign_expr(p); p.restrict(old); ret e; } -fn parse_initializer(&parser p) -> option::t[ast::initializer] { - alt (p.peek()) { - case (token::EQ) { - p.bump(); - ret some(rec(op=ast::init_assign, expr=parse_expr(p))); - } - case (token::LARROW) { - p.bump(); - ret some(rec(op=ast::init_move, expr=parse_expr(p))); - } - // Now that the the channel is the first argument to receive, - // combining it with an initializer doesn't really make sense. - // case (token::RECV) { - // p.bump(); - // ret some(rec(op = ast::init_recv, - // expr = parse_expr(p))); - // } - case (_) { - ret none; - } +fn parse_initializer(p: &parser) -> option::t[ast::initializer] { + alt p.peek() { + token::EQ. { + p.bump(); + ret some({op: ast::init_assign, expr: parse_expr(p)}); + } + token::LARROW. { + p.bump(); + ret some({op: ast::init_move, expr: parse_expr(p)}); + } + + // Now that the the channel is the first argument to receive, + // combining it with an initializer doesn't really make sense. + // case (token::RECV) { + // p.bump(); + // ret some(rec(op = ast::init_recv, + // expr = parse_expr(p))); + // } + _ { + ret none; + } } } -fn parse_pats(&parser p) -> (@ast::pat)[] { - auto pats = ~[]; - while (true) { +fn parse_pats(p: &parser) -> (@ast::pat)[] { + let pats = ~[]; + while true { pats += ~[parse_pat(p)]; - if (p.peek() == token::BINOP(token::OR)) { - p.bump(); - } else { - break; - } + if p.peek() == token::BINOP(token::OR) { p.bump(); } else { break; } } ret pats; } -fn parse_pat(&parser p) -> @ast::pat { - auto lo = p.get_lo_pos(); - auto hi = p.get_hi_pos(); - auto pat; - alt (p.peek()) { - case (token::UNDERSCORE) { - p.bump(); - pat = ast::pat_wild; - } - case (token::AT) { - p.bump(); - auto sub = parse_pat(p); - pat = ast::pat_box(sub); - hi = sub.span.hi; - } - case (token::LBRACE) { - p.bump(); - auto fields = ~[]; - auto etc = false; - auto first = true; - while (p.peek() != token::RBRACE) { - if (first) { first = false; } - else { expect(p, token::COMMA); } - - if (p.peek() == token::UNDERSCORE) { - p.bump(); - if (p.peek() != token::RBRACE) { - p.fatal("expecting }, found " + +fn parse_pat(p: &parser) -> @ast::pat { + let lo = p.get_lo_pos(); + let hi = p.get_hi_pos(); + let pat; + alt p.peek() { + token::UNDERSCORE. { p.bump(); pat = ast::pat_wild; } + token::AT. { + p.bump(); + let sub = parse_pat(p); + pat = ast::pat_box(sub); + hi = sub.span.hi; + } + token::LBRACE. { + p.bump(); + let fields = ~[]; + let etc = false; + let first = true; + while p.peek() != token::RBRACE { + if first { first = false; } else { expect(p, token::COMMA); } + + if p.peek() == token::UNDERSCORE { + p.bump(); + if p.peek() != token::RBRACE { + p.fatal("expecting }, found " + token::to_str(p.get_reader(), p.peek())); - } - etc = true; - break; } + etc = true; + break; + } - auto fieldname = parse_ident(p); - auto subpat; - if (p.peek() == token::COLON) { - p.bump(); - subpat = parse_pat(p); - } else { - if (p.get_bad_expr_words().contains_key(fieldname)) { - p.fatal("found " + fieldname + - " in binding position"); - } - subpat = @rec(id=p.get_id(), - node=ast::pat_bind(fieldname), - span=rec(lo=lo, hi=hi)); + let fieldname = parse_ident(p); + let subpat; + if p.peek() == token::COLON { + p.bump(); + subpat = parse_pat(p); + } else { + if p.get_bad_expr_words().contains_key(fieldname) { + p.fatal("found " + fieldname + " in binding position"); } - fields += ~[rec(ident=fieldname, pat=subpat)]; + subpat = + @{id: p.get_id(), + node: ast::pat_bind(fieldname), + span: {lo: lo, hi: hi}}; } - hi = p.get_hi_pos(); - p.bump(); - pat = ast::pat_rec(fields, etc); + fields += ~[{ident: fieldname, pat: subpat}]; } - 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); - } else if (is_plain_ident(p) && + hi = p.get_hi_pos(); + p.bump(); + pat = ast::pat_rec(fields, etc); + } + tok { + if !is_ident(tok) || is_word(p, "true") || is_word(p, "false") { + let 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 { + 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; - let (@ast::pat)[] args; - alt (p.peek()) { - case (token::LPAREN) { - auto a = parse_seq(token::LPAREN, token::RPAREN, - some(token::COMMA), parse_pat, p); - args = a.node; - hi = a.span.hi; - } - case (token::DOT) { - args = ~[]; - p.bump(); - } - case (_) { expect(p, token::LPAREN); fail; } - } - pat = ast::pat_tag(tag_path, args); + hi = p.get_hi_pos(); + pat = ast::pat_bind(parse_ident(p)); + } else { + let tag_path = parse_path_and_ty_param_substs(p); + hi = tag_path.span.hi; + let args: (@ast::pat)[]; + alt p.peek() { + token::LPAREN. { + let a = + parse_seq(token::LPAREN, token::RPAREN, + some(token::COMMA), parse_pat, p); + args = a.node; + hi = a.span.hi; + } + token::DOT. { args = ~[]; p.bump(); } + _ { expect(p, token::LPAREN); fail; } } + pat = ast::pat_tag(tag_path, args); } + } } - ret @rec(id=p.get_id(), node=pat, span=rec(lo=lo, hi=hi)); + ret @{id: p.get_id(), node: pat, span: {lo: lo, hi: hi}}; } -fn parse_local(&parser p, bool allow_init) -> @ast::local { - auto lo = p.get_lo_pos(); - auto ident = parse_value_ident(p); - auto ty = none; - if eat(p, token::COLON) { - ty = some(parse_ty(p)); - } - auto init = if allow_init { parse_initializer(p) } - else { none }; +fn parse_local(p: &parser, allow_init: bool) -> @ast::local { + let lo = p.get_lo_pos(); + let ident = parse_value_ident(p); + let ty = none; + if eat(p, token::COLON) { ty = some(parse_ty(p)); } + let 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())); + {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, true)]; +fn parse_let(p: &parser) -> @ast::decl { + let lo = p.get_lo_pos(); + let locals = ~[parse_local(p, true)]; while p.peek() == token::COMMA { p.bump(); locals += ~[parse_local(p, true)]; @@ -1546,483 +1519,474 @@ fn parse_let(&parser p) -> @ast::decl { ret @spanned(lo, p.get_last_hi_pos(), ast::decl_local(locals)); } -fn parse_stmt(&parser p) -> @ast::stmt { - if (p.get_file_type() == SOURCE_FILE) { +fn parse_stmt(p: &parser) -> @ast::stmt { + if p.get_file_type() == SOURCE_FILE { ret parse_source_stmt(p); } else { ret parse_crate_stmt(p); } } -fn parse_crate_stmt(&parser p) -> @ast::stmt { - auto cdir = parse_crate_directive(p, ~[]); +fn parse_crate_stmt(p: &parser) -> @ast::stmt { + let cdir = parse_crate_directive(p, ~[]); ret @spanned(cdir.span.lo, cdir.span.hi, ast::stmt_crate_directive(@cdir)); } -fn parse_source_stmt(&parser p) -> @ast::stmt { - auto lo = p.get_lo_pos(); - if (eat_word(p, "let")) { - auto decl = parse_let(p); +fn parse_source_stmt(p: &parser) -> @ast::stmt { + let lo = p.get_lo_pos(); + if eat_word(p, "let") { + let decl = parse_let(p); ret @spanned(lo, decl.span.hi, ast::stmt_decl(decl, p.get_id())); } else { - auto item_attrs; - alt (parse_outer_attrs_or_ext(p)) { - case (none) { - item_attrs = ~[]; - } - case (some(left(?attrs))) { - item_attrs = attrs; - } - case (some(right(?ext))) { - ret @spanned(lo, ext.span.hi, - ast::stmt_expr(ext, p.get_id())); - } + let item_attrs; + alt parse_outer_attrs_or_ext(p) { + none. { item_attrs = ~[]; } + some(left(attrs)) { item_attrs = attrs; } + some(right(ext)) { + ret @spanned(lo, ext.span.hi, ast::stmt_expr(ext, p.get_id())); + } } - auto maybe_item = parse_item(p, item_attrs); + let maybe_item = parse_item(p, item_attrs); // If we have attributes then we should have an item - if (ivec::len(item_attrs) > 0u) { - alt (maybe_item) { - case (got_item(_)) { /* fallthrough */ } - case (_) { - ret p.fatal("expected item"); - } + if ivec::len(item_attrs) > 0u { + alt maybe_item { + got_item(_) {/* fallthrough */ } + _ { ret p.fatal("expected item"); } } } - alt (maybe_item) { - case (got_item(?i)) { - auto hi = i.span.hi; - auto decl = @spanned(lo, hi, ast::decl_item(i)); - ret @spanned(lo, hi, ast::stmt_decl(decl, p.get_id())); - } - case (fn_no_item) { // parse_item will have already skipped "fn" - auto e = parse_fn_expr(p, ast::proto_fn); - e = parse_dot_or_call_expr_with(p, e); - ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_id())); - } - case (no_item) { - // Remainder are line-expr stmts. + alt maybe_item { + got_item(i) { + let hi = i.span.hi; + let decl = @spanned(lo, hi, ast::decl_item(i)); + ret @spanned(lo, hi, ast::stmt_decl(decl, p.get_id())); + } + fn_no_item. { // parse_item will have already skipped "fn" - auto e = parse_expr(p); - ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_id())); - } + let e = parse_fn_expr(p, ast::proto_fn); + e = parse_dot_or_call_expr_with(p, e); + ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_id())); + } + no_item. { + // Remainder are line-expr stmts. + + let e = parse_expr(p); + ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_id())); + } } } p.fatal("expected statement"); fail; } -fn stmt_to_expr(@ast::stmt stmt) -> option::t[@ast::expr] { - ret alt (stmt.node) { - case (ast::stmt_expr(?e, _)) { some(e) } - case (_) { none } - }; +fn stmt_to_expr(stmt: @ast::stmt) -> option::t[@ast::expr] { + ret alt stmt.node { ast::stmt_expr(e, _) { some(e) } _ { none } }; } -fn stmt_ends_with_semi(&ast::stmt stmt) -> bool { - alt (stmt.node) { - case (ast::stmt_decl(?d, _)) { - ret alt (d.node) { - case (ast::decl_local(_)) { true } - case (ast::decl_item(_)) { false } +fn stmt_ends_with_semi(stmt: &ast::stmt) -> bool { + alt stmt.node { + ast::stmt_decl(d, _) { + ret alt d.node { + ast::decl_local(_) { true } + ast::decl_item(_) { false } } - } - case (ast::stmt_expr(?e, _)) { - ret alt (e.node) { - case (ast::expr_vec(_, _, _)) { true } - case (ast::expr_rec(_, _)) { true } - case (ast::expr_call(_, _)) { true } - case (ast::expr_self_method(_)) { false } - case (ast::expr_bind(_, _)) { true } - case (ast::expr_spawn(_, _, _, _)) { true } - case (ast::expr_binary(_, _, _)) { true } - case (ast::expr_unary(_, _)) { true } - case (ast::expr_lit(_)) { true } - case (ast::expr_cast(_, _)) { true } - case (ast::expr_if(_, _, _)) { false } - case (ast::expr_ternary(_, _, _)) { true } - case (ast::expr_for(_, _, _)) { false } - case (ast::expr_for_each(_, _, _)) { false } - case (ast::expr_while(_, _)) { false } - case (ast::expr_do_while(_, _)) { false } - case (ast::expr_alt(_, _)) { false } - case (ast::expr_fn(_)) { false } - case (ast::expr_block(_)) { false } - case (ast::expr_move(_, _)) { true } - case (ast::expr_assign(_, _)) { true } - case (ast::expr_swap(_, _)) { true } - case (ast::expr_assign_op(_, _, _)) { true } - case (ast::expr_send(_, _)) { true } - case (ast::expr_recv(_, _)) { true } - case (ast::expr_field(_, _)) { true } - case (ast::expr_index(_, _)) { true } - case (ast::expr_path(_)) { true } - case (ast::expr_mac(_)) { true } - case (ast::expr_fail(_)) { true } - case (ast::expr_break) { true } - case (ast::expr_cont) { true } - case (ast::expr_ret(_)) { true } - case (ast::expr_put(_)) { true } - case (ast::expr_be(_)) { true } - case (ast::expr_log(_, _)) { true } - case (ast::expr_check(_, _)) { true } - case (ast::expr_if_check(_, _, _)) { false } - case (ast::expr_port(_)) { true } - case (ast::expr_chan(_)) { true } - case (ast::expr_anon_obj(_)) { false } - case (ast::expr_assert(_)) { true } + } + ast::stmt_expr(e, _) { + ret alt e.node { + ast::expr_vec(_, _, _) { true } + ast::expr_rec(_, _) { true } + ast::expr_call(_, _) { true } + ast::expr_self_method(_) { false } + ast::expr_bind(_, _) { true } + ast::expr_spawn(_, _, _, _) { true } + ast::expr_binary(_, _, _) { true } + ast::expr_unary(_, _) { true } + ast::expr_lit(_) { true } + ast::expr_cast(_, _) { true } + ast::expr_if(_, _, _) { false } + ast::expr_ternary(_, _, _) { true } + ast::expr_for(_, _, _) { false } + ast::expr_for_each(_, _, _) { false } + ast::expr_while(_, _) { false } + ast::expr_do_while(_, _) { false } + ast::expr_alt(_, _) { false } + ast::expr_fn(_) { false } + ast::expr_block(_) { false } + ast::expr_move(_, _) { true } + ast::expr_assign(_, _) { true } + ast::expr_swap(_, _) { true } + ast::expr_assign_op(_, _, _) { true } + ast::expr_send(_, _) { true } + ast::expr_recv(_, _) { true } + ast::expr_field(_, _) { true } + ast::expr_index(_, _) { true } + ast::expr_path(_) { true } + ast::expr_mac(_) { true } + ast::expr_fail(_) { true } + ast::expr_break. { true } + ast::expr_cont. { true } + ast::expr_ret(_) { true } + ast::expr_put(_) { true } + ast::expr_be(_) { true } + ast::expr_log(_, _) { true } + ast::expr_check(_, _) { true } + ast::expr_if_check(_, _, _) { false } + ast::expr_port(_) { true } + ast::expr_chan(_) { true } + ast::expr_anon_obj(_) { false } + ast::expr_assert(_) { true } } - } - // We should not be calling this on a cdir. - case (ast::stmt_crate_directive(?cdir)) { - fail; - } + } + + // We should not be calling this on a cdir. + ast::stmt_crate_directive(cdir) { + fail; + } } } -fn parse_block(&parser p) -> ast::blk { - auto lo = p.get_lo_pos(); +fn parse_block(p: &parser) -> ast::blk { + let lo = p.get_lo_pos(); expect(p, token::LBRACE); be parse_block_tail(p, lo); } // some blocks start with "#{"... -fn parse_block_tail(&parser p, uint lo) -> ast::blk { - let (@ast::stmt)[] stmts = ~[]; - let option::t[@ast::expr] expr = none; - while (p.peek() != token::RBRACE) { - alt (p.peek()) { - case (token::SEMI) { - p.bump(); // empty - } - case (_) { - auto stmt = parse_stmt(p); - alt (stmt_to_expr(stmt)) { - case (some(?e)) { - alt (p.peek()) { - case (token::SEMI) { p.bump(); stmts += ~[stmt]; } - case (token::RBRACE) { expr = some(e); } - case (?t) { - if (stmt_ends_with_semi(*stmt)) { - p.fatal("expected ';' or '}' after " + - "expression but found " + - token::to_str(p.get_reader(), - t)); - fail; - } - stmts += ~[stmt]; - } - } - } - case (none) { - // Not an expression statement. - stmts += ~[stmt]; - - if (p.get_file_type() == SOURCE_FILE - && stmt_ends_with_semi(*stmt)) { - expect(p, token::SEMI); - } +fn parse_block_tail(p: &parser, lo: uint) -> ast::blk { + let stmts: (@ast::stmt)[] = ~[]; + let expr: option::t[@ast::expr] = none; + while p.peek() != token::RBRACE { + alt p.peek() { + token::SEMI. { + p.bump(); // empty + } + _ { + let stmt = parse_stmt(p); + alt stmt_to_expr(stmt) { + some(e) { + alt p.peek() { + token::SEMI. { p.bump(); stmts += ~[stmt]; } + token::RBRACE. { expr = some(e); } + t { + if stmt_ends_with_semi(*stmt) { + p.fatal("expected ';' or '}' after " + + "expression but found " + + token::to_str(p.get_reader(), t)); + fail; } + stmts += ~[stmt]; + } } + } + none. { + // Not an expression statement. + stmts += ~[stmt]; + + + if p.get_file_type() == SOURCE_FILE && + stmt_ends_with_semi(*stmt) { + expect(p, token::SEMI); + } + } } + } } } - auto hi = p.get_hi_pos(); + let hi = p.get_hi_pos(); p.bump(); - auto bloc = rec(stmts=stmts, expr=expr, id=p.get_id()); + let bloc = {stmts: stmts, expr: expr, id: p.get_id()}; ret spanned(lo, hi, bloc); } -fn parse_ty_param(&parser p) -> ast::ty_param { ret parse_ident(p); } +fn parse_ty_param(p: &parser) -> ast::ty_param { ret parse_ident(p); } -fn parse_ty_params(&parser p) -> ast::ty_param[] { - let ast::ty_param[] ty_params = ~[]; - if (p.peek() == token::LBRACKET) { - ty_params = parse_seq(token::LBRACKET, token::RBRACKET, - some(token::COMMA), parse_ty_param, p).node; +fn parse_ty_params(p: &parser) -> ast::ty_param[] { + let ty_params: ast::ty_param[] = ~[]; + if p.peek() == token::LBRACKET { + ty_params = + parse_seq(token::LBRACKET, token::RBRACKET, some(token::COMMA), + parse_ty_param, p).node; } ret ty_params; } -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); - let ty_or_bang rslt; +fn parse_fn_decl(p: &parser, purity: ast::purity) -> ast::fn_decl { + let inputs: ast::spanned[ast::arg[]] = + parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), parse_arg, + p); + let rslt: ty_or_bang; // 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) { + let constrs = ~[]; + if p.peek() == token::COLON { p.bump(); - constrs = parse_constrs(bind parse_ty_constr(inputs.node,_), p); + constrs = parse_constrs(bind parse_ty_constr(inputs.node, _), p); } - if (p.peek() == token::RARROW) { + if p.peek() == token::RARROW { p.bump(); rslt = parse_ty_or_bang(p); } else { rslt = a_ty(@spanned(inputs.span.lo, inputs.span.hi, ast::ty_nil)); } - alt (rslt) { - case (a_ty(?t)) { - ret rec(inputs=inputs.node, - output=t, - purity=purity, - cf=ast::return, - constraints=constrs); - } - case (a_bang) { - ret rec(inputs=inputs.node, - output=@spanned(p.get_lo_pos(), p.get_hi_pos(), - ast::ty_bot), - purity=purity, - cf=ast::noreturn, - constraints=constrs); - } - } -} - -fn parse_fn(&parser p, ast::proto proto, ast::purity purity) -> ast::_fn { - auto decl = parse_fn_decl(p, purity); - auto body = parse_block(p); - ret rec(decl=decl, proto=proto, body=body); -} - -fn parse_fn_header(&parser p) -> rec(ast::ident ident, ast::ty_param[] tps) { - auto id = parse_value_ident(p); - auto ty_params = parse_ty_params(p); - ret rec(ident=id, tps=ty_params); -} - -fn mk_item(&parser p, uint lo, uint hi, &ast::ident ident, &ast::item_ node, - &ast::attribute[] attrs) -> @ast::item { - ret @rec(ident=ident, - attrs=attrs, - id=p.get_id(), - node=node, - span=rec(lo=lo, hi=hi)); -} - -fn parse_item_fn_or_iter(&parser p, ast::purity purity, ast::proto proto, - &ast::attribute[] attrs) -> @ast::item { - auto lo = p.get_last_lo_pos(); - auto t = parse_fn_header(p); - auto f = parse_fn(p, proto, purity); - ret mk_item(p, lo, f.body.span.hi, t.ident, - ast::item_fn(f, t.tps), attrs); -} - -fn parse_obj_field(&parser p) -> ast::obj_field { - auto mut = parse_mutability(p); - auto ident = parse_value_ident(p); + alt rslt { + a_ty(t) { + ret {inputs: inputs.node, + output: t, + purity: purity, + cf: ast::return, + constraints: constrs}; + } + a_bang. { + ret {inputs: inputs.node, + output: @spanned(p.get_lo_pos(), p.get_hi_pos(), ast::ty_bot), + purity: purity, + cf: ast::noreturn, + constraints: constrs}; + } + } +} + +fn parse_fn(p: &parser, proto: ast::proto, purity: ast::purity) -> ast::_fn { + let decl = parse_fn_decl(p, purity); + let body = parse_block(p); + ret {decl: decl, proto: proto, body: body}; +} + +fn parse_fn_header(p: &parser) -> {ident: ast::ident, tps: ast::ty_param[]} { + let id = parse_value_ident(p); + let ty_params = parse_ty_params(p); + ret {ident: id, tps: ty_params}; +} + +fn mk_item(p: &parser, lo: uint, hi: uint, ident: &ast::ident, + node: &ast::item_, attrs: &ast::attribute[]) -> @ast::item { + ret @{ident: ident, + attrs: attrs, + id: p.get_id(), + node: node, + span: {lo: lo, hi: hi}}; +} + +fn parse_item_fn_or_iter(p: &parser, purity: ast::purity, proto: ast::proto, + attrs: &ast::attribute[]) -> @ast::item { + let lo = p.get_last_lo_pos(); + let t = parse_fn_header(p); + let f = parse_fn(p, proto, purity); + ret mk_item(p, lo, f.body.span.hi, t.ident, ast::item_fn(f, t.tps), + attrs); +} + +fn parse_obj_field(p: &parser) -> ast::obj_field { + let mut = parse_mutability(p); + let 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()); + let ty = parse_ty(p); + ret {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 ident = parse_value_ident(p); +fn parse_anon_obj_field(p: &parser) -> ast::anon_obj_field { + let mut = parse_mutability(p); + let ident = parse_value_ident(p); expect(p, token::COLON); - auto ty = parse_ty(p); + let 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()); + let expr = parse_expr(p); + ret {mut: mut, ty: ty, expr: expr, ident: ident, id: p.get_id()}; } -fn parse_method(&parser p) -> @ast::method { - auto lo = p.get_lo_pos(); - auto proto = parse_proto(p); - auto ident = parse_value_ident(p); - auto f = parse_fn(p, proto, ast::impure_fn); - auto meth = rec(ident=ident, meth=f, id=p.get_id()); +fn parse_method(p: &parser) -> @ast::method { + let lo = p.get_lo_pos(); + let proto = parse_proto(p); + let ident = parse_value_ident(p); + let f = parse_fn(p, proto, ast::impure_fn); + let meth = {ident: ident, meth: f, id: p.get_id()}; ret @spanned(lo, f.body.span.hi, meth); } -fn parse_dtor(&parser p) -> @ast::method { - auto lo = p.get_last_lo_pos(); - let ast::blk b = parse_block(p); - let ast::arg[] inputs = ~[]; - let @ast::ty output = @spanned(lo, lo, ast::ty_nil); - let ast::fn_decl d = - rec(inputs=inputs, - output=output, - purity=ast::impure_fn, - cf=ast::return, - - // I guess dtors can't have constraints? - constraints=~[]); - let ast::_fn f = rec(decl=d, proto=ast::proto_fn, body=b); - let ast::method_ m = - rec(ident="drop", meth=f, id=p.get_id()); +fn parse_dtor(p: &parser) -> @ast::method { + let lo = p.get_last_lo_pos(); + let b: ast::blk = parse_block(p); + let inputs: ast::arg[] = ~[]; + let output: @ast::ty = @spanned(lo, lo, ast::ty_nil); + let + + // I guess dtors can't have constraints? + d: ast::fn_decl = + {inputs: inputs, + output: output, + purity: ast::impure_fn, + cf: ast::return, + constraints: ~[]}; + let f: ast::_fn = {decl: d, proto: ast::proto_fn, body: b}; + let m: ast::method_ = {ident: "drop", meth: f, id: p.get_id()}; ret @spanned(lo, f.body.span.hi, m); } -fn parse_item_obj(&parser p, ast::layer lyr, &ast::attribute[] attrs) -> +fn parse_item_obj(p: &parser, lyr: ast::layer, attrs: &ast::attribute[]) -> @ast::item { - auto lo = p.get_last_lo_pos(); - auto ident = parse_value_ident(p); - auto ty_params = parse_ty_params(p); - let ast::spanned[ast::obj_field[]] fields = + let lo = p.get_last_lo_pos(); + let ident = parse_value_ident(p); + let ty_params = parse_ty_params(p); + let fields: ast::spanned[ast::obj_field[]] = parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), - parse_obj_field, p); - let (@ast::method)[] meths = ~[]; - let option::t[@ast::method] dtor = none; + parse_obj_field, p); + let meths: (@ast::method)[] = ~[]; + let dtor: option::t[@ast::method] = none; expect(p, token::LBRACE); - while (p.peek() != token::RBRACE) { - if (eat_word(p, "drop")) { + while p.peek() != token::RBRACE { + if eat_word(p, "drop") { dtor = some(parse_dtor(p)); } else { meths += ~[parse_method(p)]; } } - auto hi = p.get_hi_pos(); + let hi = p.get_hi_pos(); expect(p, token::RBRACE); - let ast::_obj ob = rec(fields=fields.node, methods=meths, dtor=dtor); - ret mk_item(p, lo, hi, ident, ast::item_obj(ob, ty_params, - p.get_id()), attrs); + let ob: ast::_obj = {fields: fields.node, methods: meths, dtor: dtor}; + ret mk_item(p, lo, hi, ident, ast::item_obj(ob, ty_params, p.get_id()), + attrs); } -fn parse_item_res(&parser p, ast::layer lyr, &ast::attribute[] attrs) -> +fn parse_item_res(p: &parser, lyr: ast::layer, attrs: &ast::attribute[]) -> @ast::item { - auto lo = p.get_last_lo_pos(); - auto ident = parse_value_ident(p); - auto ty_params = parse_ty_params(p); + let lo = p.get_last_lo_pos(); + let ident = parse_value_ident(p); + let ty_params = parse_ty_params(p); expect(p, token::LPAREN); - auto arg_ident = parse_value_ident(p); + let arg_ident = parse_value_ident(p); expect(p, token::COLON); - auto t = parse_ty(p); + let t = parse_ty(p); expect(p, token::RPAREN); - auto dtor = parse_block(p); - auto decl = rec(inputs=~[rec(mode=ast::alias(false), ty=t, - ident=arg_ident, id=p.get_id())], - output=@spanned(lo, lo, ast::ty_nil), - purity=ast::impure_fn, - cf=ast::return, - constraints=~[]); - auto f = rec(decl=decl, proto=ast::proto_fn, body=dtor); + let dtor = parse_block(p); + let decl = + {inputs: + ~[{mode: ast::alias(false), + ty: t, + ident: arg_ident, + id: p.get_id()}], + output: @spanned(lo, lo, ast::ty_nil), + purity: ast::impure_fn, + cf: ast::return, + constraints: ~[]}; + let f = {decl: decl, proto: ast::proto_fn, body: dtor}; ret mk_item(p, lo, dtor.span.hi, ident, ast::item_res(f, p.get_id(), ty_params, p.get_id()), attrs); } -fn parse_mod_items(&parser p, token::token term, - &ast::attribute[] first_item_attrs) -> ast::_mod { - auto view_items = if (ivec::len(first_item_attrs) == 0u) { - parse_view(p) - } else { +fn parse_mod_items(p: &parser, term: token::token, + first_item_attrs: &ast::attribute[]) -> ast::_mod { + let // Shouldn't be any view items since we've already parsed an item attr - ~[] - }; - let (@ast::item)[] items = ~[]; - auto initial_attrs = first_item_attrs; - while (p.peek() != term) { - auto attrs = initial_attrs + parse_outer_attributes(p); + view_items = + if ivec::len(first_item_attrs) == 0u { parse_view(p) } else { ~[] }; + let items: (@ast::item)[] = ~[]; + let initial_attrs = first_item_attrs; + while p.peek() != term { + let attrs = initial_attrs + parse_outer_attributes(p); initial_attrs = ~[]; - alt (parse_item(p, attrs)) { - case (got_item(?i)) { items += ~[i]; } - case (_) { - p.fatal("expected item but found " + - token::to_str(p.get_reader(), p.peek())); - } + alt parse_item(p, attrs) { + got_item(i) { items += ~[i]; } + _ { + p.fatal("expected item but found " + + token::to_str(p.get_reader(), p.peek())); + } } } - ret rec(view_items=view_items, items=items); + ret {view_items: view_items, items: items}; } -fn parse_item_const(&parser p, &ast::attribute[] attrs) -> @ast::item { - auto lo = p.get_last_lo_pos(); - auto id = parse_value_ident(p); +fn parse_item_const(p: &parser, attrs: &ast::attribute[]) -> @ast::item { + let lo = p.get_last_lo_pos(); + let id = parse_value_ident(p); expect(p, token::COLON); - auto ty = parse_ty(p); + let ty = parse_ty(p); expect(p, token::EQ); - auto e = parse_expr(p); - auto hi = p.get_hi_pos(); + let e = parse_expr(p); + let hi = p.get_hi_pos(); expect(p, token::SEMI); ret mk_item(p, lo, hi, id, ast::item_const(ty, e), attrs); } -fn parse_item_mod(&parser p, &ast::attribute[] attrs) -> @ast::item { - auto lo = p.get_last_lo_pos(); - auto id = parse_ident(p); +fn parse_item_mod(p: &parser, attrs: &ast::attribute[]) -> @ast::item { + let lo = p.get_last_lo_pos(); + let id = parse_ident(p); expect(p, token::LBRACE); - auto inner_attrs = parse_inner_attrs_and_next(p); - auto first_item_outer_attrs = inner_attrs.next; - auto m = parse_mod_items(p, token::RBRACE, first_item_outer_attrs); - auto hi = p.get_hi_pos(); + let inner_attrs = parse_inner_attrs_and_next(p); + let first_item_outer_attrs = inner_attrs.next; + let m = parse_mod_items(p, token::RBRACE, first_item_outer_attrs); + let hi = p.get_hi_pos(); expect(p, token::RBRACE); ret mk_item(p, lo, hi, id, ast::item_mod(m), attrs + inner_attrs.inner); } -fn parse_item_native_type(&parser p, &ast::attribute[] attrs) - -> @ast::native_item { - auto t = parse_type_decl(p); - auto hi = p.get_hi_pos(); +fn parse_item_native_type(p: &parser, attrs: &ast::attribute[]) -> + @ast::native_item { + let t = parse_type_decl(p); + let hi = p.get_hi_pos(); expect(p, token::SEMI); - ret @rec(ident=t.ident, - attrs=attrs, - node=ast::native_item_ty, - id=p.get_id(), - span=rec(lo=t.lo, hi=hi)); -} - -fn parse_item_native_fn(&parser p, &ast::attribute[] attrs) - -> @ast::native_item { - 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; - if (p.peek() == token::EQ) { - p.bump(); - link_name = some(parse_str(p)); - } - auto hi = p.get_hi_pos(); + ret @{ident: t.ident, + attrs: attrs, + node: ast::native_item_ty, + id: p.get_id(), + span: {lo: t.lo, hi: hi}}; +} + +fn parse_item_native_fn(p: &parser, attrs: &ast::attribute[]) -> + @ast::native_item { + let lo = p.get_last_lo_pos(); + let t = parse_fn_header(p); + let decl = parse_fn_decl(p, ast::impure_fn); + let link_name = none; + if p.peek() == token::EQ { p.bump(); link_name = some(parse_str(p)); } + let hi = p.get_hi_pos(); expect(p, token::SEMI); - ret @rec(ident=t.ident, - attrs=attrs, - node=ast::native_item_fn(link_name, decl, t.tps), - id=p.get_id(), - span=rec(lo=lo, hi=hi)); + ret @{ident: t.ident, + attrs: attrs, + node: ast::native_item_fn(link_name, decl, t.tps), + id: p.get_id(), + span: {lo: lo, hi: hi}}; } -fn parse_native_item(&parser p, &ast::attribute[] attrs) - -> @ast::native_item { +fn parse_native_item(p: &parser, attrs: &ast::attribute[]) -> + @ast::native_item { parse_layer(p); - if (eat_word(p, "type")) { + if eat_word(p, "type") { ret parse_item_native_type(p, attrs); } else if (eat_word(p, "fn")) { ret parse_item_native_fn(p, attrs); } else { unexpected(p, p.peek()); fail; } } -fn parse_native_mod_items(&parser p, &str native_name, ast::native_abi abi, - &ast::attribute[] first_item_attrs) - -> ast::native_mod { - auto view_items = if (ivec::len(first_item_attrs) == 0u) { - parse_native_view(p) - } else { +fn parse_native_mod_items(p: &parser, native_name: &str, abi: ast::native_abi, + first_item_attrs: &ast::attribute[]) -> + ast::native_mod { + let // Shouldn't be any view items since we've already parsed an item attr - ~[] - }; - let (@ast::native_item)[] items = ~[]; - auto initial_attrs = first_item_attrs; - while (p.peek() != token::RBRACE) { - auto attrs = initial_attrs + parse_outer_attributes(p); + view_items = + if ivec::len(first_item_attrs) == 0u { + parse_native_view(p) + } else { ~[] }; + let items: (@ast::native_item)[] = ~[]; + let initial_attrs = first_item_attrs; + while p.peek() != token::RBRACE { + let attrs = initial_attrs + parse_outer_attributes(p); initial_attrs = ~[]; items += ~[parse_native_item(p, attrs)]; } - ret rec(native_name=native_name, - abi=abi, - view_items=view_items, - items=items); -} - -fn parse_item_native_mod(&parser p, &ast::attribute[] attrs) -> @ast::item { - auto lo = p.get_last_lo_pos(); - auto abi = ast::native_abi_cdecl; - if (!is_word(p, "mod")) { - auto t = parse_str(p); - if (str::eq(t, "cdecl")) { + ret {native_name: native_name, + abi: abi, + view_items: view_items, + items: items}; +} + +fn parse_item_native_mod(p: &parser, attrs: &ast::attribute[]) -> @ast::item { + let lo = p.get_last_lo_pos(); + let abi = ast::native_abi_cdecl; + if !is_word(p, "mod") { + let t = parse_str(p); + if str::eq(t, "cdecl") { } else if (str::eq(t, "rust")) { abi = ast::native_abi_rust; } else if (str::eq(t, "llvm")) { @@ -2034,105 +1998,101 @@ fn parse_item_native_mod(&parser p, &ast::attribute[] attrs) -> @ast::item { } else { p.fatal("unsupported abi: " + t); fail; } } expect_word(p, "mod"); - auto id = parse_ident(p); - auto native_name; - if (p.peek() == token::EQ) { + let id = parse_ident(p); + let native_name; + if p.peek() == token::EQ { expect(p, token::EQ); native_name = parse_str(p); - } else { - native_name = id; - } + } else { native_name = id; } expect(p, token::LBRACE); - auto more_attrs = parse_inner_attrs_and_next(p); - auto inner_attrs = more_attrs.inner; - auto first_item_outer_attrs = more_attrs.next; - auto m = parse_native_mod_items(p, native_name, abi, - first_item_outer_attrs); - auto hi = p.get_hi_pos(); + let more_attrs = parse_inner_attrs_and_next(p); + let inner_attrs = more_attrs.inner; + let first_item_outer_attrs = more_attrs.next; + let m = + parse_native_mod_items(p, native_name, abi, first_item_outer_attrs); + let hi = p.get_hi_pos(); expect(p, token::RBRACE); ret mk_item(p, lo, hi, id, ast::item_native_mod(m), attrs + inner_attrs); } -fn parse_type_decl(&parser p) -> rec(uint lo, ast::ident ident) { - auto lo = p.get_last_lo_pos(); - auto id = parse_ident(p); - ret rec(lo=lo, ident=id); +fn parse_type_decl(p: &parser) -> {lo: uint, ident: ast::ident} { + let lo = p.get_last_lo_pos(); + let id = parse_ident(p); + ret {lo: lo, ident: id}; } -fn parse_item_type(&parser p, &ast::attribute[] attrs) -> @ast::item { - auto t = parse_type_decl(p); - auto tps = parse_ty_params(p); +fn parse_item_type(p: &parser, attrs: &ast::attribute[]) -> @ast::item { + let t = parse_type_decl(p); + let tps = parse_ty_params(p); expect(p, token::EQ); - auto ty = parse_ty(p); - auto hi = p.get_hi_pos(); + let ty = parse_ty(p); + let hi = p.get_hi_pos(); expect(p, token::SEMI); ret mk_item(p, t.lo, hi, t.ident, ast::item_ty(ty, tps), attrs); } -fn parse_item_tag(&parser p, &ast::attribute[] attrs) -> @ast::item { - auto lo = p.get_last_lo_pos(); - auto id = parse_ident(p); - auto ty_params = parse_ty_params(p); - let ast::variant[] variants = ~[]; +fn parse_item_tag(p: &parser, attrs: &ast::attribute[]) -> @ast::item { + let lo = p.get_last_lo_pos(); + let id = parse_ident(p); + let ty_params = parse_ty_params(p); + let variants: ast::variant[] = ~[]; // Newtype syntax - if (p.peek() == token::EQ) { - if (p.get_bad_expr_words().contains_key(id)) { + if p.peek() == token::EQ { + if p.get_bad_expr_words().contains_key(id) { p.fatal("found " + id + " in tag constructor position"); } p.bump(); - auto ty = parse_ty(p); + let ty = parse_ty(p); expect(p, token::SEMI); - auto variant = spanned(ty.span.lo, ty.span.hi, - rec(name=id, - args=~[rec(ty=ty, id=p.get_id())], - id=p.get_id())); + let variant = + spanned(ty.span.lo, ty.span.hi, + {name: id, + args: ~[{ty: ty, id: p.get_id()}], + id: p.get_id()}); ret mk_item(p, lo, ty.span.hi, id, ast::item_tag(~[variant], ty_params), attrs); } expect(p, token::LBRACE); - while (p.peek() != token::RBRACE) { - auto tok = p.peek(); - alt (tok) { - case (token::IDENT(?name, _)) { - check_bad_word(p); - auto vlo = p.get_lo_pos(); - p.bump(); - let ast::variant_arg[] args = ~[]; - auto vhi = p.get_hi_pos(); - alt (p.peek()) { - case (token::LPAREN) { - auto arg_tys = - parse_seq(token::LPAREN, token::RPAREN, - some(token::COMMA), parse_ty, p); - for (@ast::ty ty in arg_tys.node) { - args += ~[rec(ty=ty, id=p.get_id())]; - } - vhi = arg_tys.span.hi; - } - case (_) {/* empty */ } + while p.peek() != token::RBRACE { + let tok = p.peek(); + alt tok { + token::IDENT(name, _) { + check_bad_word(p); + let vlo = p.get_lo_pos(); + p.bump(); + let args: ast::variant_arg[] = ~[]; + let vhi = p.get_hi_pos(); + alt p.peek() { + token::LPAREN. { + let arg_tys = + parse_seq(token::LPAREN, token::RPAREN, + some(token::COMMA), parse_ty, p); + for ty: @ast::ty in arg_tys.node { + args += ~[{ty: ty, id: p.get_id()}]; } - expect(p, token::SEMI); - p.get_id(); - auto vr = - rec(name=p.get_str(name), - args=args, - id=p.get_id()); - variants += ~[spanned(vlo, vhi, vr)]; + vhi = arg_tys.span.hi; + } + _ {/* empty */ } } - case (token::RBRACE) {/* empty */ } - case (_) { - p.fatal("expected name of variant or '}' but found " + - token::to_str(p.get_reader(), tok)); - } - } - } - auto hi = p.get_hi_pos(); + expect(p, token::SEMI); + p.get_id(); + let vr = {name: p.get_str(name), args: args, id: p.get_id()}; + variants += ~[spanned(vlo, vhi, vr)]; + } + token::RBRACE. {/* empty */ } + _ { + p.fatal("expected name of variant or '}' but found " + + token::to_str(p.get_reader(), tok)); + } + } + } + let hi = p.get_hi_pos(); p.bump(); ret mk_item(p, lo, hi, id, ast::item_tag(variants, ty_params), attrs); } -fn parse_layer(&parser p) -> ast::layer { - if (eat_word(p, "state")) { +fn parse_layer(p: &parser) -> ast::layer { + if eat_word(p, "state") { ret ast::layer_state; } else if (eat_word(p, "gc")) { ret ast::layer_gc; @@ -2140,8 +2100,8 @@ fn parse_layer(&parser p) -> ast::layer { fail; } -fn parse_auth(&parser p) -> ast::_auth { - if (eat_word(p, "unsafe")) { +fn parse_auth(p: &parser) -> ast::_auth { + if eat_word(p, "unsafe") { ret ast::auth_unsafe; } else { unexpected(p, p.peek()); } fail; @@ -2149,13 +2109,13 @@ fn parse_auth(&parser p) -> ast::_auth { tag parsed_item { got_item(@ast::item); no_item; fn_no_item; } -fn parse_item(&parser p, &ast::attribute[] attrs) -> parsed_item { - if (eat_word(p, "const")) { +fn parse_item(p: &parser, attrs: &ast::attribute[]) -> parsed_item { + if eat_word(p, "const") { ret got_item(parse_item_const(p, attrs)); } else if (eat_word(p, "fn")) { // This is an anonymous function - if (p.peek() == token::LPAREN) { ret fn_no_item; } + if p.peek() == token::LPAREN { ret fn_no_item; } ret got_item(parse_item_fn_or_iter(p, ast::impure_fn, ast::proto_fn, attrs)); } else if (eat_word(p, "pred")) { @@ -2169,8 +2129,8 @@ fn parse_item(&parser p, &ast::attribute[] attrs) -> parsed_item { } else if (eat_word(p, "native")) { ret got_item(parse_item_native_mod(p, attrs)); } - auto lyr = parse_layer(p); - if (eat_word(p, "type")) { + let lyr = parse_layer(p); + if eat_word(p, "type") { ret got_item(parse_item_type(p, attrs)); } else if (eat_word(p, "tag")) { ret got_item(parse_item_tag(p, attrs)); @@ -2185,45 +2145,41 @@ fn parse_item(&parser p, &ast::attribute[] attrs) -> parsed_item { // extensions, which both begin with token.POUND type attr_or_ext = option::t[either::t[ast::attribute[], @ast::expr]]; -fn parse_outer_attrs_or_ext(&parser p) -> attr_or_ext { - if (p.peek() == token::POUND) { - auto lo = p.get_lo_pos(); +fn parse_outer_attrs_or_ext(p: &parser) -> attr_or_ext { + if p.peek() == token::POUND { + let lo = p.get_lo_pos(); p.bump(); - if (p.peek() == token::LBRACKET) { - auto first_attr = parse_attribute_naked(p, ast::attr_outer, lo); + if p.peek() == token::LBRACKET { + let first_attr = parse_attribute_naked(p, ast::attr_outer, lo); ret some(left(~[first_attr] + parse_outer_attributes(p))); - } else if (! (p.peek() == token::LT || p.peek() == token::LBRACKET)) { + } else if (!(p.peek() == token::LT || p.peek() == token::LBRACKET)) { ret some(right(parse_syntax_ext_naked(p, lo))); - } else { - ret none; - } - } else { - ret none; - } + } else { ret none; } + } else { ret none; } } // Parse attributes that appear before an item -fn parse_outer_attributes(&parser p) -> ast::attribute[] { - let ast::attribute[] attrs = ~[]; - while (p.peek() == token::POUND) { +fn parse_outer_attributes(p: &parser) -> ast::attribute[] { + let attrs: ast::attribute[] = ~[]; + while p.peek() == token::POUND { attrs += ~[parse_attribute(p, ast::attr_outer)]; } ret attrs; } -fn parse_attribute(&parser p, ast::attr_style style) -> ast::attribute { - auto lo = p.get_lo_pos(); +fn parse_attribute(p: &parser, style: ast::attr_style) -> ast::attribute { + let lo = p.get_lo_pos(); expect(p, token::POUND); ret parse_attribute_naked(p, style, lo); } -fn parse_attribute_naked(&parser p, ast::attr_style style, - uint lo) -> ast::attribute { +fn parse_attribute_naked(p: &parser, style: ast::attr_style, lo: uint) -> + ast::attribute { expect(p, token::LBRACKET); - auto meta_item = parse_meta_item(p); + let meta_item = parse_meta_item(p); expect(p, token::RBRACKET); - auto hi = p.get_hi_pos(); - ret spanned(lo, hi, rec(style=style, value=*meta_item)); + let hi = p.get_hi_pos(); + ret spanned(lo, hi, {style: style, value: *meta_item}); } // Parse attributes that appear after the opening of an item, each terminated @@ -2232,219 +2188,213 @@ fn parse_attribute_naked(&parser p, ast::attr_style style, // next item (since we can't know whether the attribute is an inner attribute // of the containing item or an outer attribute of the first contained item // until we see the semi). -fn parse_inner_attrs_and_next(&parser p) -> rec(ast::attribute[] inner, - ast::attribute[] next) { - let ast::attribute[] inner_attrs = ~[]; - let ast::attribute[] next_outer_attrs = ~[]; - while (p.peek() == token::POUND) { - auto attr = parse_attribute(p, ast::attr_inner); - if (p.peek() == token::SEMI) { +fn parse_inner_attrs_and_next(p: &parser) -> + {inner: ast::attribute[], next: ast::attribute[]} { + let inner_attrs: ast::attribute[] = ~[]; + let next_outer_attrs: ast::attribute[] = ~[]; + while p.peek() == token::POUND { + let attr = parse_attribute(p, ast::attr_inner); + if p.peek() == token::SEMI { p.bump(); inner_attrs += ~[attr]; } else { // It's not really an inner attribute - auto outer_attr = spanned(attr.span.lo, - attr.span.hi, - rec(style=ast::attr_outer, - value=attr.node.value)); + let outer_attr = + spanned(attr.span.lo, attr.span.hi, + {style: ast::attr_outer, value: attr.node.value}); next_outer_attrs += ~[outer_attr]; break; } } - ret rec(inner=inner_attrs, next=next_outer_attrs); -} - -fn parse_meta_item(&parser p) -> @ast::meta_item { - auto lo = p.get_lo_pos(); - auto ident = parse_ident(p); - alt (p.peek()) { - case (token::EQ) { - p.bump(); - auto lit = parse_lit(p); - auto hi = p.get_hi_pos(); - ret @spanned(lo, hi, ast::meta_name_value(ident, lit)); - } - case (token::LPAREN) { - auto inner_items = parse_meta_seq(p); - auto hi = p.get_hi_pos(); - ret @spanned(lo, hi, ast::meta_list(ident, inner_items)); - } - case (_) { - auto hi = p.get_hi_pos(); - ret @spanned(lo, hi, ast::meta_word(ident)); - } - } + ret {inner: inner_attrs, next: next_outer_attrs}; } -fn parse_meta_seq(&parser p) -> (@ast::meta_item)[] { +fn parse_meta_item(p: &parser) -> @ast::meta_item { + let lo = p.get_lo_pos(); + let ident = parse_ident(p); + alt p.peek() { + token::EQ. { + p.bump(); + let lit = parse_lit(p); + let hi = p.get_hi_pos(); + ret @spanned(lo, hi, ast::meta_name_value(ident, lit)); + } + token::LPAREN. { + let inner_items = parse_meta_seq(p); + let hi = p.get_hi_pos(); + ret @spanned(lo, hi, ast::meta_list(ident, inner_items)); + } + _ { + let hi = p.get_hi_pos(); + ret @spanned(lo, hi, ast::meta_word(ident)); + } + } +} + +fn parse_meta_seq(p: &parser) -> (@ast::meta_item)[] { ret parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA), parse_meta_item, p).node; } -fn parse_optional_meta(&parser p) -> (@ast::meta_item)[] { - alt (p.peek()) { - case (token::LPAREN) { ret parse_meta_seq(p); } - case (_) { ret ~[]; } - } +fn parse_optional_meta(p: &parser) -> (@ast::meta_item)[] { + alt p.peek() { token::LPAREN. { ret parse_meta_seq(p); } _ { ret ~[]; } } } -fn parse_use(&parser p) -> ast::view_item_ { - auto ident = parse_ident(p); - auto metadata = parse_optional_meta(p); +fn parse_use(p: &parser) -> ast::view_item_ { + let ident = parse_ident(p); + let metadata = parse_optional_meta(p); ret ast::view_item_use(ident, metadata, p.get_id()); } -fn parse_rest_import_name(&parser p, ast::ident first, - option::t[ast::ident] def_ident) -> +fn parse_rest_import_name(p: &parser, first: ast::ident, + def_ident: option::t[ast::ident]) -> ast::view_item_ { - let ast::ident[] identifiers = ~[first]; - let bool glob = false; - while (true) { - alt (p.peek()) { - case (token::SEMI) { break; } - case (token::MOD_SEP) { - if (glob) { p.fatal("cannot path into a glob"); } - p.bump(); - } - case (_) { p.fatal("expecting '::' or ';'"); } - } - alt (p.peek()) { - case (token::IDENT(_, _)) { identifiers += ~[parse_ident(p)]; } - //the lexer can't tell the different kinds of stars apart ) : - case (token::BINOP(token::STAR)) { - glob = true; - p.bump(); - } - case (_) { p.fatal("expecting an identifier, or '*'"); } - } - } - alt (def_ident) { - case (some(?i)) { - if (glob) { p.fatal("globbed imports can't be renamed"); } - ret ast::view_item_import(i, identifiers, p.get_id()); + let identifiers: ast::ident[] = ~[first]; + let glob: bool = false; + while true { + alt p.peek() { + token::SEMI. { break; } + token::MOD_SEP. { + if glob { p.fatal("cannot path into a glob"); } + p.bump(); + } + _ { p.fatal("expecting '::' or ';'"); } } - case (_) { - if (glob) { - ret ast::view_item_import_glob(identifiers, p.get_id()); - } else { - auto len = ivec::len(identifiers); - ret ast::view_item_import(identifiers.(len - 1u), identifiers, - p.get_id()); - } + alt p.peek() { + token::IDENT(_, _) { identifiers += ~[parse_ident(p)]; } + + //the lexer can't tell the different kinds of stars apart ) : + token::BINOP(token::STAR.) { + glob = true; + p.bump(); + } + _ { p.fatal("expecting an identifier, or '*'"); } + } + } + alt def_ident { + some(i) { + if glob { p.fatal("globbed imports can't be renamed"); } + ret ast::view_item_import(i, identifiers, p.get_id()); + } + _ { + if glob { + ret ast::view_item_import_glob(identifiers, p.get_id()); + } else { + let len = ivec::len(identifiers); + ret ast::view_item_import(identifiers.(len - 1u), identifiers, + p.get_id()); } + } } } -fn parse_full_import_name(&parser p, ast::ident def_ident) -> +fn parse_full_import_name(p: &parser, def_ident: ast::ident) -> ast::view_item_ { - alt (p.peek()) { - case (token::IDENT(?i, _)) { - p.bump(); - ret parse_rest_import_name(p, p.get_str(i), some(def_ident)); - } - case (_) { p.fatal("expecting an identifier"); } + alt p.peek() { + token::IDENT(i, _) { + p.bump(); + ret parse_rest_import_name(p, p.get_str(i), some(def_ident)); + } + _ { p.fatal("expecting an identifier"); } } fail; } -fn parse_import(&parser p) -> ast::view_item_ { - alt (p.peek()) { - case (token::IDENT(?i, _)) { +fn parse_import(p: &parser) -> ast::view_item_ { + alt p.peek() { + token::IDENT(i, _) { + p.bump(); + alt p.peek() { + token::EQ. { p.bump(); - alt (p.peek()) { - case (token::EQ) { - p.bump(); - ret parse_full_import_name(p, p.get_str(i)); - } - case (_) { - ret parse_rest_import_name(p, p.get_str(i), none); - } - } + ret parse_full_import_name(p, p.get_str(i)); + } + _ { ret parse_rest_import_name(p, p.get_str(i), none); } } - case (_) { p.fatal("expecting an identifier"); } + } + _ { p.fatal("expecting an identifier"); } } fail; } -fn parse_export(&parser p) -> ast::view_item_ { - auto id = parse_ident(p); +fn parse_export(p: &parser) -> ast::view_item_ { + let id = parse_ident(p); ret ast::view_item_export(id, p.get_id()); } -fn parse_view_item(&parser p) -> @ast::view_item { - auto lo = p.get_lo_pos(); - auto the_item = if (eat_word(p, "use")) { parse_use(p) } - else if (eat_word(p, "import")) { parse_import(p) } - else if (eat_word(p, "export")) { parse_export(p) } - else { fail }; - auto hi = p.get_lo_pos(); +fn parse_view_item(p: &parser) -> @ast::view_item { + let lo = p.get_lo_pos(); + let the_item = + if eat_word(p, "use") { + parse_use(p) + } else if (eat_word(p, "import")) { + parse_import(p) + } else if (eat_word(p, "export")) { parse_export(p) } else { fail }; + let hi = p.get_lo_pos(); expect(p, token::SEMI); ret @spanned(lo, hi, the_item); } -fn is_view_item(&parser p) -> bool { - alt (p.peek()) { - case (token::IDENT(?sid, false)) { - auto st = p.get_str(sid); - ret str::eq(st, "use") || str::eq(st, "import") || - str::eq(st, "export"); - } - case (_) { ret false; } +fn is_view_item(p: &parser) -> bool { + alt p.peek() { + token::IDENT(sid, false) { + let st = p.get_str(sid); + ret str::eq(st, "use") || str::eq(st, "import") || + str::eq(st, "export"); + } + _ { ret false; } } ret false; } -fn parse_view(&parser p) -> (@ast::view_item)[] { - let (@ast::view_item)[] items = ~[]; - while (is_view_item(p)) { items += ~[parse_view_item(p)]; } +fn parse_view(p: &parser) -> (@ast::view_item)[] { + let items: (@ast::view_item)[] = ~[]; + while is_view_item(p) { items += ~[parse_view_item(p)]; } ret items; } -fn parse_native_view(&parser p) -> (@ast::view_item)[] { - let (@ast::view_item)[] items = ~[]; - while (is_view_item(p)) { items += ~[parse_view_item(p)]; } +fn parse_native_view(p: &parser) -> (@ast::view_item)[] { + let items: (@ast::view_item)[] = ~[]; + while is_view_item(p) { items += ~[parse_view_item(p)]; } ret items; } -fn parse_crate_from_source_file(&str input, &ast::crate_cfg cfg, - &parse_sess sess) -> @ast::crate { - auto p = new_parser_from_file(sess, cfg, input, 0u, 0u); +fn parse_crate_from_source_file(input: &str, cfg: &ast::crate_cfg, + sess: &parse_sess) -> @ast::crate { + let p = new_parser_from_file(sess, cfg, input, 0u, 0u); ret parse_crate_mod(p, cfg, sess); } -fn parse_crate_from_source_str(&str name, &str source, &ast::crate_cfg cfg, - &codemap::codemap cm) -> @ast::crate { - auto sess = @rec(cm=cm, mutable next_id=0); - auto ftype = SOURCE_FILE; - auto filemap = codemap::new_filemap(name, 0u, 0u); +fn parse_crate_from_source_str(name: &str, source: &str, cfg: &ast::crate_cfg, + cm: &codemap::codemap) -> @ast::crate { + let sess = @{cm: cm, mutable next_id: 0}; + let ftype = SOURCE_FILE; + let filemap = codemap::new_filemap(name, 0u, 0u); sess.cm.files += ~[filemap]; - auto itr = @interner::mk(str::hash, str::eq); - auto rdr = lexer::new_reader(sess.cm, source, filemap, itr); - auto p = new_parser(sess, cfg, rdr, ftype); + let itr = @interner::mk(str::hash, str::eq); + let rdr = lexer::new_reader(sess.cm, source, filemap, itr); + let p = new_parser(sess, cfg, rdr, ftype); ret parse_crate_mod(p, cfg, sess); } // Parses a source module as a crate -fn parse_crate_mod(&parser p, &ast::crate_cfg cfg, parse_sess sess) - -> @ast::crate { - auto lo = p.get_lo_pos(); - auto crate_attrs = parse_inner_attrs_and_next(p); - auto first_item_outer_attrs = crate_attrs.next; - auto m = parse_mod_items(p, token::EOF, - first_item_outer_attrs); - ret @spanned(lo, p.get_lo_pos(), rec(directives=~[], - module=m, - attrs=crate_attrs.inner, - config=p.get_cfg())); -} - -fn parse_str(&parser p) -> ast::ident { - alt (p.peek()) { - case (token::LIT_STR(?s)) { - p.bump(); - ret p.get_str(s); - } - case (_) { fail; } +fn parse_crate_mod(p: &parser, cfg: &ast::crate_cfg, sess: parse_sess) -> + @ast::crate { + let lo = p.get_lo_pos(); + let crate_attrs = parse_inner_attrs_and_next(p); + let first_item_outer_attrs = crate_attrs.next; + let m = parse_mod_items(p, token::EOF, first_item_outer_attrs); + ret @spanned(lo, p.get_lo_pos(), + {directives: ~[], + module: m, + attrs: crate_attrs.inner, + config: p.get_cfg()}); +} + +fn parse_str(p: &parser) -> ast::ident { + alt p.peek() { + token::LIT_STR(s) { p.bump(); ret p.get_str(s); } + _ { fail; } } } @@ -2453,109 +2403,105 @@ fn parse_str(&parser p) -> ast::ident { // Each crate file is a sequence of directives. // // Each directive imperatively extends its environment with 0 or more items. -fn parse_crate_directive(&parser p, &ast::attribute[] first_outer_attr) - -> ast::crate_directive { +fn parse_crate_directive(p: &parser, first_outer_attr: &ast::attribute[]) -> + ast::crate_directive { // Collect the next attributes - auto outer_attrs = first_outer_attr + parse_outer_attributes(p); + let outer_attrs = first_outer_attr + parse_outer_attributes(p); // In a crate file outer attributes are only going to apply to mods - auto expect_mod = ivec::len(outer_attrs) > 0u; + let expect_mod = ivec::len(outer_attrs) > 0u; - auto lo = p.get_lo_pos(); - if (expect_mod || is_word(p, "mod")) { + let lo = p.get_lo_pos(); + if expect_mod || is_word(p, "mod") { expect_word(p, "mod"); - auto id = parse_ident(p); - auto file_opt = - alt (p.peek()) { - case (token::EQ) { - p.bump(); - some(parse_str(p)) - } - case (_) { none } + let id = parse_ident(p); + let file_opt = + alt p.peek() { + token::EQ. { p.bump(); some(parse_str(p)) } + _ { none } }; - alt (p.peek()) { - case ( - // mod x = "foo.rs"; - token::SEMI) { - auto hi = p.get_hi_pos(); - p.bump(); - ret spanned(lo, hi, ast::cdir_src_mod(id, file_opt, - outer_attrs)); - } - case ( - // mod x = "foo_dir" { ...directives... } - token::LBRACE) { - p.bump(); - auto inner_attrs = parse_inner_attrs_and_next(p); - auto mod_attrs = outer_attrs + inner_attrs.inner; - auto next_outer_attr = inner_attrs.next; - auto cdirs = parse_crate_directives(p, token::RBRACE, - next_outer_attr); - auto hi = p.get_hi_pos(); - expect(p, token::RBRACE); - ret spanned(lo, hi, ast::cdir_dir_mod(id, file_opt, cdirs, - mod_attrs)); - } - case (?t) { unexpected(p, t); } + alt p.peek() { + + // mod x = "foo.rs"; + token::SEMI. { + let hi = p.get_hi_pos(); + p.bump(); + ret spanned(lo, hi, ast::cdir_src_mod(id, file_opt, outer_attrs)); + } + + // mod x = "foo_dir" { ...directives... } + token::LBRACE. { + p.bump(); + let inner_attrs = parse_inner_attrs_and_next(p); + let mod_attrs = outer_attrs + inner_attrs.inner; + let next_outer_attr = inner_attrs.next; + let cdirs = + parse_crate_directives(p, token::RBRACE, next_outer_attr); + let hi = p.get_hi_pos(); + expect(p, token::RBRACE); + ret spanned(lo, hi, + ast::cdir_dir_mod(id, file_opt, cdirs, mod_attrs)); + } + t { unexpected(p, t); } } } else if (eat_word(p, "auth")) { - auto n = parse_path(p); + let n = parse_path(p); expect(p, token::EQ); - auto a = parse_auth(p); - auto hi = p.get_hi_pos(); + let a = parse_auth(p); + let hi = p.get_hi_pos(); expect(p, token::SEMI); ret spanned(lo, hi, ast::cdir_auth(n, a)); } else if (is_view_item(p)) { - auto vi = parse_view_item(p); + let vi = parse_view_item(p); ret spanned(lo, vi.span.hi, ast::cdir_view_item(vi)); - } else { - ret p.fatal("expected crate directive"); - } + } else { ret p.fatal("expected crate directive"); } } -fn parse_crate_directives(&parser p, token::token term, - &ast::attribute[] first_outer_attr) - -> (@ast::crate_directive)[] { +fn parse_crate_directives(p: &parser, term: token::token, + first_outer_attr: &ast::attribute[]) -> + (@ast::crate_directive)[] { // This is pretty ugly. If we have an outer attribute then we can't accept // seeing the terminator next, so if we do see it then fail the same way // parse_crate_directive would - if (ivec::len(first_outer_attr) > 0u && p.peek() == term) { + if ivec::len(first_outer_attr) > 0u && p.peek() == term { expect_word(p, "mod"); } - let (@ast::crate_directive)[] cdirs = ~[]; - while (p.peek() != term) { - auto cdir = @parse_crate_directive(p, first_outer_attr); + let cdirs: (@ast::crate_directive)[] = ~[]; + while p.peek() != term { + let cdir = @parse_crate_directive(p, first_outer_attr); cdirs += ~[cdir]; } ret cdirs; } -fn parse_crate_from_crate_file(&str input, &ast::crate_cfg cfg, - &parse_sess sess) -> @ast::crate { - auto p = new_parser_from_file(sess, cfg, input, 0u, 0u); - auto lo = p.get_lo_pos(); - auto prefix = std::fs::dirname(p.get_filemap().name); - auto leading_attrs = parse_inner_attrs_and_next(p); - auto crate_attrs = leading_attrs.inner; - auto first_cdir_attr = leading_attrs.next; - auto cdirs = parse_crate_directives(p, token::EOF, first_cdir_attr); - let str[] deps = ~[]; - auto cx = @rec(p=p, - mode=eval::mode_parse, - mutable deps=deps, - sess=sess, - mutable chpos=p.get_chpos(), - mutable byte_pos=p.get_byte_pos(), - cfg = p.get_cfg()); - auto m = eval::eval_crate_directives_to_mod(cx, cdirs, prefix); - auto hi = p.get_hi_pos(); +fn parse_crate_from_crate_file(input: &str, cfg: &ast::crate_cfg, + sess: &parse_sess) -> @ast::crate { + let p = new_parser_from_file(sess, cfg, input, 0u, 0u); + let lo = p.get_lo_pos(); + let prefix = std::fs::dirname(p.get_filemap().name); + let leading_attrs = parse_inner_attrs_and_next(p); + let crate_attrs = leading_attrs.inner; + let first_cdir_attr = leading_attrs.next; + let cdirs = parse_crate_directives(p, token::EOF, first_cdir_attr); + let deps: str[] = ~[]; + let cx = + @{p: p, + mode: eval::mode_parse, + mutable deps: deps, + sess: sess, + mutable chpos: p.get_chpos(), + mutable byte_pos: p.get_byte_pos(), + cfg: p.get_cfg()}; + let m = eval::eval_crate_directives_to_mod(cx, cdirs, prefix); + let hi = p.get_hi_pos(); expect(p, token::EOF); - ret @spanned(lo, hi, rec(directives=cdirs, - module=m, - attrs=crate_attrs, - config=p.get_cfg())); + ret @spanned(lo, hi, + {directives: cdirs, + module: m, + attrs: crate_attrs, + config: p.get_cfg()}); } // // Local Variables: diff --git a/src/comp/syntax/parse/token.rs b/src/comp/syntax/parse/token.rs index 44dadc1a42f..35bd1f1494a 100644 --- a/src/comp/syntax/parse/token.rs +++ b/src/comp/syntax/parse/token.rs @@ -25,6 +25,7 @@ tag binop { tag token { + /* Expression-operator symbols. */ EQ; LT; @@ -40,6 +41,7 @@ tag token { BINOP(binop); BINOPEQ(binop); + /* Structural symbols */ AT; DOT; @@ -64,6 +66,7 @@ tag token { POUND_LBRACE; POUND_LT; + /* Literals */ LIT_INT(int); LIT_UINT(uint); @@ -74,6 +77,7 @@ tag token { LIT_CHAR(char); LIT_BOOL(bool); + /* Name components */ IDENT(str_num, bool); IDX(int); @@ -82,113 +86,122 @@ tag token { EOF; } -fn binop_to_str(binop o) -> str { - alt (o) { - case (PLUS) { ret "+"; } - case (MINUS) { ret "-"; } - case (STAR) { ret "*"; } - case (SLASH) { ret "/"; } - case (PERCENT) { ret "%"; } - case (CARET) { ret "^"; } - case (AND) { ret "&"; } - case (OR) { ret "|"; } - case (LSL) { ret "<<"; } - case (LSR) { ret ">>"; } - case (ASR) { ret ">>>"; } +fn binop_to_str(o: binop) -> str { + alt o { + PLUS. { ret "+"; } + MINUS. { ret "-"; } + STAR. { ret "*"; } + SLASH. { ret "/"; } + PERCENT. { ret "%"; } + CARET. { ret "^"; } + AND. { ret "&"; } + OR. { ret "|"; } + LSL. { ret "<<"; } + LSR. { ret ">>"; } + ASR. { ret ">>>"; } } } -fn to_str(lexer::reader r, token t) -> str { - alt (t) { - case (EQ) { ret "="; } - case (LT) { ret "<"; } - case (LE) { ret "<="; } - case (EQEQ) { ret "=="; } - case (NE) { ret "!="; } - case (GE) { ret ">="; } - case (GT) { ret ">"; } - case (NOT) { ret "!"; } - case (TILDE) { ret "~"; } - case (OROR) { ret "||"; } - case (ANDAND) { ret "&&"; } - case (BINOP(?op)) { ret binop_to_str(op); } - case (BINOPEQ(?op)) { ret binop_to_str(op) + "="; } - /* Structural symbols */ - case (AT) { ret "@"; } - case (DOT) { ret "."; } - case (ELLIPSIS) { ret "..."; } - case (COMMA) { ret ","; } - case (SEMI) { ret ";"; } - case (COLON) { ret ":"; } - case (MOD_SEP) { ret "::"; } - case (QUES) { ret "?"; } - case (RARROW) { ret "->"; } - case (SEND) { ret "<|"; } - case (RECV) { ret "|>"; } - case (LARROW) { ret "<-"; } - case (DARROW) { ret "<->"; } - case (LPAREN) { ret "("; } - case (RPAREN) { ret ")"; } - case (LBRACKET) { ret "["; } - case (RBRACKET) { ret "]"; } - case (LBRACE) { ret "{"; } - case (RBRACE) { ret "}"; } - case (POUND) { ret "#"; } - case (POUND_LBRACE) { ret "#{"; } - case (POUND_LT) { ret "#<"; } - /* Literals */ - case (LIT_INT(?i)) { ret int::to_str(i, 10u); } - case (LIT_UINT(?u)) { ret uint::to_str(u, 10u); } - case (LIT_MACH_INT(?tm, ?i)) { - ret int::to_str(i, 10u) + "_" + ty_mach_to_str(tm); - } - case (LIT_MACH_FLOAT(?tm, ?s)) { - ret interner::get[str](*r.get_interner(), s) + "_" + - ty_mach_to_str(tm); - } - case (LIT_FLOAT(?s)) { ret interner::get[str](*r.get_interner(), s); } - case (LIT_STR(?s)) { // FIXME: escape. - ret "\"" + interner::get[str](*r.get_interner(), s) + "\""; - } - case (LIT_CHAR(?c)) { - // FIXME: escape. - auto tmp = "'"; - str::push_char(tmp, c); - str::push_byte(tmp, '\'' as u8); - ret tmp; - } - case (LIT_BOOL(?b)) { if (b) { ret "true"; } else { ret "false"; } } - /* Name components */ - case (IDENT(?s, _)) { ret interner::get[str](*r.get_interner(), s); } - case (IDX(?i)) { ret "_" + int::to_str(i, 10u); } - case (UNDERSCORE) { ret "_"; } - case (BRACEQUOTE(_)) { ret "<bracequote>"; } - case (EOF) { ret "<eof>"; } +fn to_str(r: lexer::reader, t: token) -> str { + alt t { + EQ. { ret "="; } + LT. { ret "<"; } + LE. { ret "<="; } + EQEQ. { ret "=="; } + NE. { ret "!="; } + GE. { ret ">="; } + GT. { ret ">"; } + NOT. { ret "!"; } + TILDE. { ret "~"; } + OROR. { ret "||"; } + ANDAND. { ret "&&"; } + BINOP(op) { ret binop_to_str(op); } + BINOPEQ(op) { ret binop_to_str(op) + "="; } + + /* Structural symbols */ + AT. { + ret "@"; + } + DOT. { ret "."; } + ELLIPSIS. { ret "..."; } + COMMA. { ret ","; } + SEMI. { ret ";"; } + COLON. { ret ":"; } + MOD_SEP. { ret "::"; } + QUES. { ret "?"; } + RARROW. { ret "->"; } + SEND. { ret "<|"; } + RECV. { ret "|>"; } + LARROW. { ret "<-"; } + DARROW. { ret "<->"; } + LPAREN. { ret "("; } + RPAREN. { ret ")"; } + LBRACKET. { ret "["; } + RBRACKET. { ret "]"; } + LBRACE. { ret "{"; } + RBRACE. { ret "}"; } + POUND. { ret "#"; } + POUND_LBRACE. { ret "#{"; } + POUND_LT. { ret "#<"; } + + /* Literals */ + LIT_INT(i) { + ret int::to_str(i, 10u); + } + LIT_UINT(u) { ret uint::to_str(u, 10u); } + LIT_MACH_INT(tm, i) { + ret int::to_str(i, 10u) + "_" + ty_mach_to_str(tm); + } + LIT_MACH_FLOAT(tm, s) { + ret interner::get[str](*r.get_interner(), s) + "_" + + ty_mach_to_str(tm); + } + LIT_FLOAT(s) { ret interner::get[str](*r.get_interner(), s); } + LIT_STR(s) { // FIXME: escape. + ret "\"" + interner::get[str](*r.get_interner(), s) + "\""; + } + LIT_CHAR(c) { + // FIXME: escape. + let tmp = "'"; + str::push_char(tmp, c); + str::push_byte(tmp, '\'' as u8); + ret tmp; + } + LIT_BOOL(b) { if b { ret "true"; } else { ret "false"; } } + + /* Name components */ + IDENT(s, _) { + ret interner::get[str](*r.get_interner(), s); + } + IDX(i) { ret "_" + int::to_str(i, 10u); } + UNDERSCORE. { ret "_"; } + BRACEQUOTE(_) { ret "<bracequote>"; } + EOF. { ret "<eof>"; } } } -pred can_begin_expr(token t) -> bool { - alt (t) { - case (LPAREN) { true } - case (LBRACE) { true } - case (LBRACKET) { true } - case (IDENT(_,_)) { true } - case (UNDERSCORE) { true } - case (TILDE) { true } - case (LIT_INT(_)) { true } - case (LIT_UINT(_)) { true } - case (LIT_MACH_INT(_,_)) { true } - case (LIT_FLOAT(_)) { true } - case (LIT_MACH_FLOAT(_,_)) { true } - case (LIT_STR(_)) { true } - case (LIT_CHAR(_)) { true } - case (POUND) { true } - case (AT) { true } - case (NOT) { true } - case (BINOP(MINUS)) { true } - case (BINOP(STAR)) { true } - case (_) { false } +pred can_begin_expr(t: token) -> bool { + alt t { + LPAREN. { true } + LBRACE. { true } + LBRACKET. { true } + IDENT(_, _) { true } + UNDERSCORE. { true } + TILDE. { true } + LIT_INT(_) { true } + LIT_UINT(_) { true } + LIT_MACH_INT(_, _) { true } + LIT_FLOAT(_) { true } + LIT_MACH_FLOAT(_, _) { true } + LIT_STR(_) { true } + LIT_CHAR(_) { true } + POUND. { true } + AT. { true } + NOT. { true } + BINOP(MINUS.) { true } + BINOP(STAR.) { true } + _ { false } } } // Local Variables: |
