aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLindsey Kuper <[email protected]>2011-05-06 17:08:41 -0700
committerGraydon Hoare <[email protected]>2011-05-13 17:35:12 -0700
commit7c2979e26f23739b62fcda7500d4c5eac092c42c (patch)
tree64bd9f4fb3176e0d352d9770efb009c9eb8d0d27
parentAdd support for 'T' transition snapshots, which are identical to S snapshots ... (diff)
downloadrust-7c2979e26f23739b62fcda7500d4c5eac092c42c.tar.xz
rust-7c2979e26f23739b62fcda7500d4c5eac092c42c.zip
Starting on support for anonymous objects. Just syntax so far.
-rw-r--r--src/comp/front/ast.rs20
-rw-r--r--src/comp/front/parser.rs50
-rw-r--r--src/test/run-pass/method-overriding.rs26
3 files changed, 96 insertions, 0 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 5e5185bf..51977b5f 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -296,6 +296,7 @@ tag expr_ {
expr_check(@expr, ann);
expr_port(ann);
expr_chan(@expr, ann);
+ expr_anon_obj(anon_obj, vec[ty_param], obj_def_ids, ann);
}
type lit = spanned[lit_];
@@ -371,6 +372,25 @@ type _obj = rec(vec[obj_field] fields,
vec[@method] methods,
option::t[@method] dtor);
+
+// Hmm. An anon_obj might extend an existing object, in which case it'll
+// probably add fields and methods.
+type anon_obj = rec(option.t[vec[obj_field]] fields,
+ vec[@method] methods,
+ option.t[ident] with_obj);
+
+tag mod_index_entry {
+ mie_view_item(@view_item);
+ mie_item(@item);
+ mie_tag_variant(@item /* tag item */, uint /* variant index */);
+}
+
+tag native_mod_index_entry {
+ nmie_view_item(@view_item);
+ nmie_item(@native_item);
+}
+
+type mod_index = hashmap[ident,mod_index_entry];
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 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] {
diff --git a/src/test/run-pass/method-overriding.rs b/src/test/run-pass/method-overriding.rs
new file mode 100644
index 00000000..bf68ddd1
--- /dev/null
+++ b/src/test/run-pass/method-overriding.rs
@@ -0,0 +1,26 @@
+// xfail-boot
+// xfail-stage0
+use std;
+import std._vec.len;
+fn main() {
+
+ obj a() {
+ fn foo() -> int {
+ ret 2;
+ }
+ fn bar() -> int {
+ ret self.foo();
+ }
+ }
+
+ auto my_a = a();
+
+ // Step 1 is to add support for this "with" syntax
+ auto my_b = obj {
+ fn baz() -> int {
+ ret self.foo();
+ }
+ with my_a
+ };
+
+}