Add a alternative in the grammar to profit from generated walkers.
Makes AClosureCallExpr a subclass of AAbsAbsSendExpr instead of ACallFormExpr.
Signed-off-by: Jean Privat <jean@pryen.org>
end
redef class AClosureCallExpr
- redef meth intern_compile_call(v)
+ meth intern_compile_call(v: CompilerVisitor): String
do
var cargs = new Array[String]
compile_arguments_in(v, cargs)
end
return va
end
+
+ redef meth compile_expr(v)
+ do
+ var e = intern_compile_call(v)
+ assert e != null
+ return e
+ end
+
+ redef meth compile_stmt(v)
+ do
+ var e = intern_compile_call(v)
+ if e != null then
+ v.add_instr(e + ";")
+ end
+ end
end
redef class AProxyExpr
| {bra} expr [args]:expr* [closure_defs]:closure_def*
| {bra_assign} expr [args]:expr* assign [value]:expr
| {bra_reassign} expr [args]:expr* assign_op [value]:expr
+ | {closure_call} id [args]:expr* [closure_defs]:closure_def*
| {var} id
| {var_assign} id assign [value]:expr
| {var_reassign} id assign_op [value]:expr
readable writable attr _n_assign_op: PAssignOp = null
readable writable attr _n_value: PExpr = null
end
+class AClosureCallExpr
+special PExpr
+ readable writable attr _n_id: TId = null
+ readable writable attr _n_args: List[PExpr] = null
+ readable writable attr _n_closure_defs: List[PClosureDef] = null
+end
class AVarExpr
special PExpr
readable writable attr _n_id: TId = null
special ABraFormExpr
special AReassignFormExpr
end
+class AClosureCallExpr
+special PExpr
+ readable writable attr _n_id: TId = null
+ readable writable attr _n_args: List[PExpr] = null
+ readable writable attr _n_closure_defs: List[PClosureDef] = null
+end
class AVarExpr
special AVarFormExpr
end
special AVarFormExpr
special AReassignFormExpr
end
-class AClosureCallExpr
-special ACallFormExpr
- init(i: TId, a: List[PExpr], c: List[PClosureDef])
- do
- _n_id = i
- _n_args = a
- _n_closure_defs = c
- _n_expr = null
- end
-end
class ARangeExpr
special PExpr
readable writable attr _n_expr: PExpr = null
end
end
end
+redef class AClosureCallExpr
+ redef meth n_id=(n: TId)
+ do
+ _n_id = n
+ if n != null then
+ n.parent = self
+ end
+ end
+
+ private init empty_init do end
+
+ init init_aclosurecallexpr (
+ n_id: TId ,
+ n_args: Collection[Object] , # Should be Collection[PExpr]
+ n_closure_defs: Collection[Object] # Should be Collection[PClosureDef]
+ )
+ do
+ empty_init
+ _n_id = n_id
+ if n_id != null then
+ n_id.parent = self
+ end
+ _n_args = new List[PExpr]
+ for n in n_args do
+ assert n isa PExpr
+ _n_args.add(n)
+ n.parent = self
+ end
+ _n_closure_defs = new List[PClosureDef]
+ for n in n_closure_defs do
+ assert n isa PClosureDef
+ _n_closure_defs.add(n)
+ n.parent = self
+ end
+ end
+
+ redef meth replace_child(old_child: PNode, new_child: PNode)
+ do
+ assert old_child != null
+ if _n_id == old_child then
+ if new_child != null then
+ new_child.parent = self
+ assert new_child isa TId
+ _n_id = new_child
+ else
+ _n_id = null
+ end
+ return
+ end
+ for i in [0.._n_args.length[ do
+ if _n_args[i] == old_child then
+ if new_child != null then
+ assert new_child isa PExpr
+ _n_args[i] = new_child
+ new_child.parent = self
+ else
+ _n_args.remove_at(i)
+ end
+ return
+ end
+ end
+ for i in [0.._n_closure_defs.length[ do
+ if _n_closure_defs[i] == old_child then
+ if new_child != null then
+ assert new_child isa PClosureDef
+ _n_closure_defs[i] = new_child
+ new_child.parent = self
+ else
+ _n_closure_defs.remove_at(i)
+ end
+ return
+ end
+ end
+ end
+
+ redef meth visit_all(v: Visitor)
+ do
+ if _n_id != null then
+ v.visit(_n_id)
+ end
+ for n in _n_args do
+ v.visit(n)
+ end
+ for n in _n_closure_defs do
+ v.visit(n)
+ end
+ end
+
+ redef meth visit_all_reverse(v: Visitor)
+ do
+ if _n_id != null then
+ v.visit(_n_id)
+ end
+ do
+ var i = _n_args.length
+ while i >= 0 do
+ v.visit(_n_args[i])
+ i = i - 1
+ end
+ end
+ do
+ var i = _n_closure_defs.length
+ while i >= 0 do
+ v.visit(_n_closure_defs[i])
+ i = i - 1
+ end
+ end
+ end
+end
redef class AVarExpr
redef meth n_id=(n: TId)
do
var variable = v.variable_ctx[name]
if variable != null then
if variable isa ClosureVariable then
- var n = new AClosureCallExpr(n_id, n_args, n_closure_defs)
+ var n = new AClosureCallExpr.init_aclosurecallexpr(n_id, n_args, n_closure_defs)
replace_with(n)
n.variable = variable
n.after_typing(v)
end
redef class AClosureCallExpr
+special AAbsAbsSendExpr
redef meth after_typing(v)
do
var va = variable
var sig = va.closure.signature
var args = process_signature(v, sig, n_id.to_symbol, n_args.to_a)
- if closure_defs != null then
- process_closures(v, sig, n_id.to_symbol, closure_defs)
+ if not n_closure_defs.is_empty then
+ process_closures(v, sig, n_id.to_symbol, n_closure_defs.to_a)
end
if args == null then return
- _prop = null
_prop_signature = sig
_arguments = args
_stype = sig.return_type