Starting on support for anonymous objects. Just syntax so far.
This commit is contained in:
committed by
Graydon Hoare
parent
ae784df3ce
commit
7c2979e26f
@@ -296,6 +296,7 @@ tag expr_ {
|
|||||||
expr_check(@expr, ann);
|
expr_check(@expr, ann);
|
||||||
expr_port(ann);
|
expr_port(ann);
|
||||||
expr_chan(@expr, ann);
|
expr_chan(@expr, ann);
|
||||||
|
expr_anon_obj(anon_obj, vec[ty_param], obj_def_ids, ann);
|
||||||
}
|
}
|
||||||
|
|
||||||
type lit = spanned[lit_];
|
type lit = spanned[lit_];
|
||||||
@@ -371,6 +372,25 @@ type _obj = rec(vec[obj_field] fields,
|
|||||||
vec[@method] methods,
|
vec[@method] methods,
|
||||||
option::t[@method] dtor);
|
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,
|
type _mod = rec(vec[@view_item] view_items,
|
||||||
vec[@item] items);
|
vec[@item] items);
|
||||||
|
|
||||||
|
|||||||
@@ -799,6 +799,56 @@ fn parse_bottom_expr(parser p) -> @ast::expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ex = ast::expr_rec(fields, base, p.get_ann());
|
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")) {
|
} else if (eat_word(p, "bind")) {
|
||||||
auto e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS);
|
auto e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS);
|
||||||
fn parse_expr_opt(parser p) -> option::t[@ast::expr] {
|
fn parse_expr_opt(parser p) -> option::t[@ast::expr] {
|
||||||
|
|||||||
26
src/test/run-pass/method-overriding.rs
Normal file
26
src/test/run-pass/method-overriding.rs
Normal file
@@ -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
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user