diff options
Diffstat (limited to 'src/comp/front')
| -rw-r--r-- | src/comp/front/ast.rs | 4 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 94 |
2 files changed, 45 insertions, 53 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index eda09276..d795d6c2 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -374,10 +374,10 @@ type _obj = rec(vec[obj_field] fields, type anon_obj = rec( // New fields and methods, if they exist. - Option.t[vec[obj_field]] fields, + option::t[vec[obj_field]] fields, vec[@method] methods, // with_obj: the original object being extended, if it exists. - Option.t[ident] with_obj); + option::t[ident] with_obj); type _mod = rec(vec[@view_item] view_items, vec[@item] items); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index a02a2fa4..8eb6c398 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -773,58 +773,21 @@ fn parse_bottom_expr(parser p) -> @ast::expr { some(token::COMMA), pf, hi, p); ex = ast::expr_vec(es, mut, p.get_ann()); - } else if (eat_word(p, "rec")) { - expect(p, token::LPAREN); - auto fields = vec(parse_field(p)); - - auto more = true; - auto base = none[@ast::expr]; - while (more) { - if (p.peek() == token::RPAREN) { - hi = p.get_hi_pos(); - p.bump(); - more = false; - } else if (eat_word(p, "with")) { - base = some[@ast::expr](parse_expr(p)); - hi = p.get_hi_pos(); - expect(p, token::RPAREN); - more = false; - } else if (p.peek() == token::COMMA) { - p.bump(); - fields += vec(parse_field(p)); - } else { - unexpected(p, p.peek()); - } - } - - ex = ast::expr_rec(fields, base, p.get_ann()); - } - // Anonymous object - else if (eat_word(p, "obj")) { + } else if (eat_word(p, "obj")) { + // Anonymous object // FIXME: Can anonymous objects have ty params? auto ty_params = parse_ty_params(p); // Only make people type () if they're actually adding new fields - let option.t[vec[ast::obj_field]] fields = none[vec[ast::obj_field]]; + let option::t[vec[ast::obj_field]] fields = + none[vec[ast::obj_field]]; if (p.peek() == token::LPAREN) { auto pf = parse_obj_field; - expect(p, token::LBRACE); - while (p.peek() != token::RBRACE) { - alt (p.peek()) { - case (token.WITH) { - p.bump(); - with_obj = some[ast::ident](parse_ident(p)); - } - case (_) { - Vec.push[@ast::method](meths, - parse_method(p)); - } - } - } - hi = p.get_hi_pos(); expect(p, token::LPAREN); + + fields = some[vec[ast::obj_field]] (parse_seq_to_end[ast::obj_field] (token::RPAREN, @@ -833,36 +796,65 @@ fn parse_bottom_expr(parser p) -> @ast::expr { } let vec[@ast::method] meths = vec(); - let option.t[ast::ident] with_obj = none[ast::ident]; + let option::t[ast::ident] with_obj = none[ast::ident]; expect(p, token::LBRACE); + while (p.peek() != token::RBRACE) { alt (p.peek()) { case (token::WITH) { + p.bump(); with_obj = some[ast::ident](parse_ident(p)); } case (_) { - // fall through + _vec::push[@ast::method](meths, + parse_method(p)); } } } + hi = p.get_hi_pos(); expect(p, token::RBRACE); - // fields and methods may be *additional* or *overriding* fields and - // methods if there's a with_obj, or they may be the *only* fields and - // methods if there's no with_obj. + // fields and methods may be *additional* or *overriding* fields + // and methods if there's a with_obj, or they may be the *only* + // fields and methods if there's no with_obj. // 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); + methods=meths, + with_obj=with_obj); auto odid = rec(ty=p.next_def_id(), ctor=p.next_def_id()); - ex = ast::expr_anon_obj(ob, ty_params, odid, ast::ann_none); + ex = ast::expr_anon_obj(ob, ty_params, odid, p.get_ann()); + + } else if (eat_word(p, "rec")) { + expect(p, token::LPAREN); + auto fields = vec(parse_field(p)); + + auto more = true; + auto base = none[@ast::expr]; + while (more) { + if (p.peek() == token::RPAREN) { + hi = p.get_hi_pos(); + p.bump(); + more = false; + } else if (eat_word(p, "with")) { + base = some[@ast::expr](parse_expr(p)); + hi = p.get_hi_pos(); + expect(p, token::RPAREN); + more = false; + } else if (p.peek() == token::COMMA) { + p.bump(); + fields += vec(parse_field(p)); + } else { + unexpected(p, p.peek()); + } + } + ex = ast::expr_rec(fields, base, p.get_ann()); } else if (eat_word(p, "bind")) { auto e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS); fn parse_expr_opt(parser p) -> option::t[@ast::expr] { |