From 55fbed3d8d7078bfd3864e64cc044cbe876c5d1a Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Tue, 29 Mar 2011 15:51:53 -0700 Subject: [PATCH] Beginnings of support for magical self prefix; nothing profound happening yet. --- src/comp/front/ast.rs | 1 + src/comp/front/lexer.rs | 1 + src/comp/front/parser.rs | 15 +++++++++++++++ src/comp/front/token.rs | 3 ++- src/comp/middle/ty.rs | 1 + src/comp/middle/typeck.rs | 7 +++++++ src/test/compile-fail/self-missing-method.rs | 13 +++++++++++++ src/test/run-pass/obj-self.rs | 16 ++++++++++++++++ 8 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/self-missing-method.rs create mode 100644 src/test/run-pass/obj-self.rs diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 4493bea8739fc..9e7c3cc144e5d 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -252,6 +252,7 @@ tag expr_ { expr_tup(vec[elt], ann); expr_rec(vec[field], option.t[@expr], ann); expr_call(@expr, vec[@expr], ann); + expr_call_self(@expr, vec[@expr], ann); expr_bind(@expr, vec[option.t[@expr]], ann); expr_spawn(spawn_dom, option.t[str], @expr, vec[@expr], ann); expr_binary(binop, @expr, @expr, ann); diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs index 878940b73bc98..86b872da708d5 100644 --- a/src/comp/front/lexer.rs +++ b/src/comp/front/lexer.rs @@ -169,6 +169,7 @@ impure fn new_reader(io.reader rdr, str filename) -> reader keywords.insert("any", token.ANY); keywords.insert("obj", token.OBJ); + keywords.insert("self", token.SELF); keywords.insert("port", token.PORT); keywords.insert("chan", token.CHAN); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 7bec44e64b577..25c9f4a50fa62 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -883,6 +883,20 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr { ex = ast.expr_chan(e, ast.ann_none); } + case (token.SELF) { + p.bump(); + expect(p, token.DOT); + // The rest is a call expression. + auto e = parse_bottom_expr(p); + auto pf = parse_expr; + auto es = parse_seq[@ast.expr](token.LPAREN, + token.RPAREN, + some(token.COMMA), + pf, p); + hi = es.span; + auto ex = ast.expr_call_self(e, es.node, ast.ann_none); + } + case (_) { auto lit = parse_lit(p); hi = lit.span; @@ -1646,6 +1660,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool { case (ast.expr_tup(_,_)) { ret true; } case (ast.expr_rec(_,_,_)) { ret true; } case (ast.expr_call(_,_,_)) { ret true; } + case (ast.expr_call_self(_,_,_)){ ret true; } case (ast.expr_binary(_,_,_,_)) { ret true; } case (ast.expr_unary(_,_,_)) { ret true; } case (ast.expr_lit(_,_)) { ret true; } diff --git a/src/comp/front/token.rs b/src/comp/front/token.rs index bb0cea80bb812..5ac9d662f1cfe 100644 --- a/src/comp/front/token.rs +++ b/src/comp/front/token.rs @@ -160,8 +160,9 @@ tag token { FN; ITER; - /* Object type */ + /* Object type and related keywords */ OBJ; + SELF; /* Comm and task types */ CHAN; diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index f9822d97e55b3..d1d7c5e30f806 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -757,6 +757,7 @@ fn expr_ty(@ast.expr expr) -> @t { case (ast.expr_rec(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_bind(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_call(_, _, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_call_self(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_spawn(_, _, _, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_binary(_, _, _, ?ann)) { ret ann_to_type(ann); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index cdb61cbd3856a..daab4b49aee99 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1312,6 +1312,13 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e, ann_to_type(ann), adk); e_1 = ast.expr_call(sube, es, ast.ann_type(t, none[vec[@ty.t]])); } + case (ast.expr_call_self(?sube, ?es, ?ann)) { + auto t = demand_full(fcx, e.span, expected, + ann_to_type(ann), adk); + e_1 = ast.expr_call_self(sube, + es, + ast.ann_type(t, none[vec[@ty.t]])); + } case (ast.expr_binary(?bop, ?lhs, ?rhs, ?ann)) { auto t = demand(fcx, e.span, expected, ann_to_type(ann)); e_1 = ast.expr_binary(bop, lhs, rhs, diff --git a/src/test/compile-fail/self-missing-method.rs b/src/test/compile-fail/self-missing-method.rs new file mode 100644 index 0000000000000..01c4ea14de32a --- /dev/null +++ b/src/test/compile-fail/self-missing-method.rs @@ -0,0 +1,13 @@ +// xfail-boot +// error-pattern:expecting ., found ( +fn main() { + + obj foo() { + fn m() { + self(); + } + } + + auto a = foo; + a.m(); +} diff --git a/src/test/run-pass/obj-self.rs b/src/test/run-pass/obj-self.rs new file mode 100644 index 0000000000000..741624fb6b23e --- /dev/null +++ b/src/test/run-pass/obj-self.rs @@ -0,0 +1,16 @@ +// xfail-boot +fn main() { + + obj foo() { + fn m1() { + log "hi!"; + } + fn m2() { + self.m1(); + } + } + + auto a = foo(); + a.m1(); + a.m2(); +}