syntax: add call reference (funref+recv capture) `&x.foo`
authorJean Privat <jean@pryen.org>
Tue, 9 Jul 2019 15:09:29 +0000 (11:09 -0400)
committerJean Privat <jean@pryen.org>
Tue, 13 Aug 2019 15:02:28 +0000 (11:02 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/parser/nit.sablecc3xx
src/parser/parser_abs.nit
src/parser/parser_nodes.nit

index d7380c5..8e8bce4 100644 (file)
@@ -639,6 +639,7 @@ expr_new~nopar~nobra {-> expr}
        = expr_atom~nopar~nobra {-> expr_atom~nopar~nobra.expr}
        | {new} kwnew no type_atom~nobra_nopar args {-> New expr.new(kwnew, type_atom~nobra_nopar.type, Null, args.exprs)}
        | {isset_attr} kwisset recv~nopar~nobra qualified_o attrid {-> New expr.isset_attr(kwisset, recv~nopar~nobra.expr, attrid)}
+       | {callref} amp recv~nopar~nobra qid args {-> New expr.callref(amp, recv~nopar~nobra.expr, qid, args.exprs)}
        ;
 
 expr_atom~nopar~nobra {-> expr}
@@ -1021,6 +1022,7 @@ expr      = {block} expr* kwend?
        | {attr_assign} expr [id]:attrid assign [value]:expr
        | {attr_reassign} expr [id]:attrid assign_op [value]:expr
        | {call} expr qid [args]:exprs
+       | {callref} amp expr qid [args]:exprs
        | {call_assign} expr qid [args]:exprs assign [value]:expr
        | {call_reassign} expr qid [args]:exprs assign_op [value]:expr
        | {super} qualified? kwsuper [args]:exprs
index 8c0930c..5815230 100644 (file)
@@ -1000,6 +1000,13 @@ class ACallExpr
        var n_qid: AQid is writable, noinit
        var n_args: AExprs is writable, noinit
 end
+class ACallrefExpr
+       super AExpr
+       var n_amp: TAmp is writable, noinit
+       var n_expr: AExpr is writable, noinit
+       var n_qid: AQid is writable, noinit
+       var n_args: AExprs is writable, noinit
+end
 class ACallAssignExpr
        super AExpr
        var n_expr: AExpr is writable, noinit
index 92dbea0..10e732a 100644 (file)
@@ -2456,6 +2456,27 @@ class ACallReassignExpr
        super ASendReassignFormExpr
 end
 
+# A reference to a method with a captured receiver. eg. `&x.foo` or just `&foo` is self is captured.
+#
+# Currently, the syntax is analogous to a simple call (`recv.foo`) with a prefix `&`.
+# On chains, only the last call is captured (`.` has a higher precedence than `&`).
+#
+# The syntax is analogous to a call (except the &), there is always a receiver (including the implicit self or sys) and arguments are accepted by the parser.
+#
+# TODO There is no clear syntax proposal
+#
+# * to avoid the capture of a receiver since a receiver is statically expected to resolve the method name
+# * for special method names (setters, brackets and operators)
+#
+# Note: The class specializes `ASendExpr` (trough `ACallFormExpr`) so some behavior of a genuine send expression must be redefined.
+class ACallrefExpr
+       super ACallFormExpr
+
+       # The `&` operator
+       var n_amp: TAmp is writable, noinit
+end
+
+
 # A call to `super`. OR a call of a super-constructor
 class ASuperExpr
        super AExpr