aboutsummaryrefslogtreecommitdiff
path: root/src/comp/front/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/comp/front/parser.rs')
-rw-r--r--src/comp/front/parser.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 520090a5..f395ea16 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -799,6 +799,56 @@ fn parse_bottom_expr(parser p) -> @ast::expr {
}
ex = ast::expr_rec(fields, base, p.get_ann());
+ }
+ // Anonymous object
+ else if (eat_word(p, "obj")) {
+
+ // 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]];
+ if (p.peek() == token.LPAREN) {
+ auto pf = parse_obj_field;
+ hi = p.get_hi_pos();
+ expect(p, token.LPAREN);
+ fields = some[vec[ast.obj_field]]
+ (parse_seq_to_end[ast.obj_field]
+ (token.RPAREN,
+ some(token.COMMA),
+ pf, hi, p));
+ }
+
+ let vec[@ast.method] meths = vec();
+ 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) {
+ with_obj = some[ast.ident](parse_ident(p));
+ }
+ case (_) {
+ // fall through
+ }
+ }
+ }
+ 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.
+
+ // 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);
+
+ 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);
} 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] {