Skip to content

Commit 7c2979e

Browse files
lkupergraydon
authored andcommitted
Starting on support for anonymous objects. Just syntax so far.
1 parent ae784df commit 7c2979e

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

src/comp/front/ast.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ tag expr_ {
296296
expr_check(@expr, ann);
297297
expr_port(ann);
298298
expr_chan(@expr, ann);
299+
expr_anon_obj(anon_obj, vec[ty_param], obj_def_ids, ann);
299300
}
300301
301302
type lit = spanned[lit_];
@@ -371,6 +372,25 @@ type _obj = rec(vec[obj_field] fields,
371372
vec[@method] methods,
372373
option::t[@method] dtor);
373374

375+
376+
// Hmm. An anon_obj might extend an existing object, in which case it'll
377+
// probably add fields and methods.
378+
type anon_obj = rec(option.t[vec[obj_field]] fields,
379+
vec[@method] methods,
380+
option.t[ident] with_obj);
381+
382+
tag mod_index_entry {
383+
mie_view_item(@view_item);
384+
mie_item(@item);
385+
mie_tag_variant(@item /* tag item */, uint /* variant index */);
386+
}
387+
388+
tag native_mod_index_entry {
389+
nmie_view_item(@view_item);
390+
nmie_item(@native_item);
391+
}
392+
393+
type mod_index = hashmap[ident,mod_index_entry];
374394
type _mod = rec(vec[@view_item] view_items,
375395
vec[@item] items);
376396

src/comp/front/parser.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,56 @@ fn parse_bottom_expr(parser p) -> @ast::expr {
799799
}
800800

801801
ex = ast::expr_rec(fields, base, p.get_ann());
802+
}
803+
// Anonymous object
804+
else if (eat_word(p, "obj")) {
805+
806+
// FIXME: Can anonymous objects have ty params?
807+
auto ty_params = parse_ty_params(p);
808+
809+
// Only make people type () if they're actually adding new fields
810+
let option.t[vec[ast.obj_field]] fields = none[vec[ast.obj_field]];
811+
if (p.peek() == token.LPAREN) {
812+
auto pf = parse_obj_field;
813+
hi = p.get_hi_pos();
814+
expect(p, token.LPAREN);
815+
fields = some[vec[ast.obj_field]]
816+
(parse_seq_to_end[ast.obj_field]
817+
(token.RPAREN,
818+
some(token.COMMA),
819+
pf, hi, p));
820+
}
821+
822+
let vec[@ast.method] meths = vec();
823+
let option.t[ast.ident] with_obj = none[ast.ident];
824+
825+
expect(p, token.LBRACE);
826+
while (p.peek() != token.RBRACE) {
827+
alt (p.peek()) {
828+
case (token.WITH) {
829+
with_obj = some[ast.ident](parse_ident(p));
830+
}
831+
case (_) {
832+
// fall through
833+
}
834+
}
835+
}
836+
hi = p.get_hi_pos();
837+
expect(p, token.RBRACE);
838+
839+
// fields and methods may be *additional* or *overriding* fields
840+
// and methods if there's a with_obj, or they may be the *only*
841+
// fields and methods if there's no with_obj.
842+
843+
// We don't need to pull ".node" out of fields because it's not a
844+
// "spanned".
845+
let ast.anon_obj ob = rec(fields=fields,
846+
methods=meths,
847+
with_obj=with_obj);
848+
849+
auto odid = rec(ty=p.next_def_id(), ctor=p.next_def_id());
850+
851+
ex = ast.expr_anon_obj(ob, ty_params, odid, ast.ann_none);
802852
} else if (eat_word(p, "bind")) {
803853
auto e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS);
804854
fn parse_expr_opt(parser p) -> option::t[@ast::expr] {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// xfail-boot
2+
// xfail-stage0
3+
use std;
4+
import std._vec.len;
5+
fn main() {
6+
7+
obj a() {
8+
fn foo() -> int {
9+
ret 2;
10+
}
11+
fn bar() -> int {
12+
ret self.foo();
13+
}
14+
}
15+
16+
auto my_a = a();
17+
18+
// Step 1 is to add support for this "with" syntax
19+
auto my_b = obj {
20+
fn baz() -> int {
21+
ret self.foo();
22+
}
23+
with my_a
24+
};
25+
26+
}

0 commit comments

Comments
 (0)