writable var _self_var: nullable ParamVariable
# Block of the current method
- readable writable var _top_block: nullable PExpr
+ readable writable var _top_block: nullable AExpr
# List of explicit invocation of constructors of super-classes
readable writable var _explicit_super_init_calls: nullable Array[MMMethod]
readable writable var _explicit_other_init_call: Bool = false
# Make the if_true_variable_ctx of the expression effective
- private fun use_if_true_variable_ctx(e: PExpr)
+ private fun use_if_true_variable_ctx(e: AExpr)
do
var ctx = e.if_true_variable_ctx
if ctx != null then variable_ctx = ctx
end
# Make the if_false_variable_ctx of the expression effective
- private fun use_if_false_variable_ctx(e: PExpr)
+ private fun use_if_false_variable_ctx(e: AExpr)
do
var ctx = e.if_false_variable_ctx
if ctx != null then variable_ctx = ctx
init(tc, module) do super
- private fun get_default_constructor_for(n: PNode, c: MMLocalClass, prop: MMSrcMethod): nullable MMMethod
+ private fun get_default_constructor_for(n: ANode, c: MMLocalClass, prop: MMSrcMethod): nullable MMMethod
do
var v = self
#var prop = v.local_property
###############################################################################
-redef class PNode
+redef class ANode
private fun accept_typing(v: TypingVisitor)
do
accept_abs_syntax_visitor(v)
private fun after_typing(v: TypingVisitor) do end
end
-redef class PClassdef
+redef class AClassdef
redef fun accept_typing(v)
do
v.variable_ctx = new RootVariableContext(v, self)
end
end
+redef class APropdef
+ redef fun self_var do return _self_var.as(not null)
+ var _self_var: nullable ParamVariable
+end
+
redef class AAttrPropdef
redef fun accept_typing(v)
do
var old_var_ctx = v.variable_ctx
v.variable_ctx = old_var_ctx.sub(self)
+ _self_var = v.self_var
super
if n_expr != null then
v.check_conform_expr(n_expr.as(not null), prop.signature.return_type.as(not null))
end
redef class AMethPropdef
- redef fun self_var do return _self_var.as(not null)
- var _self_var: nullable ParamVariable
redef fun accept_typing(v)
do
var old_var_ctx = v.variable_ctx
v.explicit_super_init_calls = explicit_super_init_calls
v.explicit_other_init_call = false
super
+ end
+
+ redef fun after_typing(v)
+ do
+ super
if v.explicit_other_init_call or method.global.intro != method then
# TODO: something?
else
end
end
-redef class PParam
+redef class AParam
redef fun after_typing(v)
do
v.variable_ctx.add(variable)
var escapable = new EscapableClosure(self, variable.closure, null)
_escapable = escapable
- v.escapable_ctx.push(escapable)
+ v.escapable_ctx.push(escapable, null)
super
end
end
-redef class PType
+redef class AType
redef fun stype: MMType do return _stype.as(not null)
redef fun is_typed: Bool do return _stype != null
var _stype: nullable MMType
end
end
-redef class PExpr
+redef class AExpr
redef readable var _is_typed: Bool = false
redef fun is_statement: Bool do return _stype == null
redef fun stype
do
if not is_typed then
- print "{locate}: not is_typed"
+ print "{location}: not is_typed"
abort
end
if is_statement then
- print "{locate}: is_statement"
+ print "{location}: is_statement"
abort
end
return _stype.as(not null)
end
var _stype: nullable MMType
+ redef fun after_typing(v)
+ do
+ # Default behavior is to be happy
+ _is_typed = true
+ end
+
# Is the expression the implicit receiver
fun is_implicit_self: Bool do return false
redef fun after_typing(v)
do
- var va = new VarVariable(n_id.to_symbol, self)
+ var va = new VarVariable(n_id.to_symbol, n_id)
_variable = va
v.variable_ctx.add(va)
if n_expr != null then v.variable_ctx.mark_is_set(va)
if esc == null then return
if esc.is_break_block then
- v.error(self, "Error: 'continue' forbiden in break blocks.")
+ v.error(self, "Error: cannot 'continue', only 'break'.")
return
end
redef fun after_typing(v)
do
v.variable_ctx.unreash = true
+ _is_typed = true
+ end
+end
+
+redef class ADoExpr
+ # The corresponding escapable block
+ readable var _escapable: nullable EscapableBlock
+
+ redef fun accept_typing(v)
+ do
+ var escapable = new BreakOnlyEscapableBlock(self)
+ _escapable = escapable
+ v.escapable_ctx.push(escapable, n_label)
+
+ super
+
+ v.escapable_ctx.pop
+ _is_typed = true
end
end
do
var escapable = new EscapableBlock(self)
_escapable = escapable
- v.escapable_ctx.push(escapable)
+ v.escapable_ctx.push(escapable, n_label)
var old_var_ctx = v.variable_ctx
var old_base_var_ctx = v.base_variable_ctx
v.base_variable_ctx = v.variable_ctx
end
end
+redef class ALoopExpr
+ # The corresponding escapable block
+ readable var _escapable: nullable EscapableBlock
+
+ redef fun accept_typing(v)
+ do
+ var escapable = new EscapableBlock(self)
+ _escapable = escapable
+ v.escapable_ctx.push(escapable, n_label)
+ var old_var_ctx = v.variable_ctx
+ var old_base_var_ctx = v.base_variable_ctx
+ v.base_variable_ctx = v.variable_ctx
+ v.variable_ctx = v.variable_ctx.sub(self)
+
+ # Process inside
+ if n_block != null then
+ v.variable_ctx = v.variable_ctx.sub(n_block.as(not null))
+ v.enter_visit(n_block)
+ end
+
+ v.variable_ctx = old_var_ctx
+ v.base_variable_ctx = old_base_var_ctx
+ v.escapable_ctx.pop
+ _is_typed = true
+ end
+end
+
redef class AForExpr
var _variable: nullable AutoVariable
redef fun variable do return _variable.as(not null)
# The corresponding escapable block
readable var _escapable: nullable EscapableBlock
- var _meth_iterator: nullable MMMethod
- redef fun meth_iterator: MMMethod do return _meth_iterator.as(not null)
- var _meth_is_ok: nullable MMMethod
- redef fun meth_is_ok: MMMethod do return _meth_is_ok.as(not null)
- var _meth_item: nullable MMMethod
- redef fun meth_item: MMMethod do return _meth_item.as(not null)
- var _meth_next: nullable MMMethod
- redef fun meth_next: MMMethod do return _meth_next.as(not null)
redef fun accept_typing(v)
do
var escapable = new EscapableBlock(self)
_escapable = escapable
- v.escapable_ctx.push(escapable)
+ v.escapable_ctx.push(escapable, n_label)
var old_var_ctx = v.variable_ctx
var old_base_var_ctx = v.base_variable_ctx
v.base_variable_ctx = v.variable_ctx
v.variable_ctx = v.variable_ctx.sub(self)
- var va = new AutoVariable(n_id.to_symbol, self)
+ var va = new AutoVariable(n_id.to_symbol, n_id)
_variable = va
v.variable_ctx.add(va)
+ # Process collection
v.enter_visit(n_expr)
if not v.check_conform_expr(n_expr, v.type_collection) then return
var expr_type = n_expr.stype
- _meth_iterator = expr_type.local_class.select_method(once ("iterator".to_symbol))
- if _meth_iterator == null then
- v.error(self, "Error: Collection MUST have an iterate method")
- return
- end
- var iter_type = _meth_iterator.signature_for(expr_type).return_type.as(not null)
- _meth_is_ok = iter_type.local_class.select_method(once ("is_ok".to_symbol))
- if _meth_is_ok == null then
- v.error(self, "Error: {iter_type} MUST have an is_ok method")
- return
- end
- _meth_item = iter_type.local_class.select_method(once ("item".to_symbol))
- if _meth_item == null then
- v.error(self, "Error: {iter_type} MUST have an item method")
- return
- end
- _meth_next = iter_type.local_class.select_method(once ("next".to_symbol))
- if _meth_next == null then
- v.error(self, "Error: {iter_type} MUST have a next method")
- return
- end
- var t = _meth_item.signature_for(iter_type).return_type
- if not n_expr.is_self then t = t.not_for_self
- va.stype = t
+ # Get iterator
+ var meth_iterator = v.get_method(expr_type, once "iterator".to_symbol)
+ var iter_type = meth_iterator.signature_for(expr_type).return_type.as(not null)
+ var meth_item = v.get_method(iter_type, once ("item".to_symbol))
+ var va_stype = meth_item.signature_for(iter_type).return_type.as(not null)
+ if not n_expr.is_self then va_stype = va_stype.not_for_self
+ va.stype = va_stype
+ # Body evaluation
if n_block != null then v.enter_visit(n_block)
# pop context
end
redef class AAssertExpr
- redef fun after_typing(v)
+ redef fun accept_typing(v)
do
+ # Process condition
+ v.enter_visit(n_expr)
v.check_conform_expr(n_expr, v.type_bool)
+
+ # Process optional 'else' part
+ if n_else != null then
+ var old_var_ctx = v.variable_ctx
+ v.use_if_false_variable_ctx(n_expr)
+ v.enter_visit(n_else)
+ v.variable_ctx = old_var_ctx
+ end
+
+ # Prepare outside
v.use_if_true_variable_ctx(n_expr)
_is_typed = true
end
redef fun after_typing(v)
do
v.variable_ctx.mark_is_set(variable)
- var t = v.variable_ctx.stype(variable)
# Check the base type
var btype = v.base_variable_ctx.stype(variable)
- if not v.check_conform_expr(n_value, btype) then return
+ if not v.check_expr(n_value) then return
+ if btype != null and not v.check_conform_expr(n_value, btype) then return
# Always cast
v.variable_ctx.stype(variable) = n_value.stype
# Check the base type
var btype = v.base_variable_ctx.stype(variable)
- if not v.check_conform(n_value, t2, btype) then return
+ if not v.check_expr(n_value) then return
+ if btype != null and not v.check_conform(n_value, t2, btype) then return
# Always cast
v.variable_ctx.stype(variable) = t2
end
end
-redef class PAssignOp
+redef class AAssignOp
fun method_name: Symbol is abstract
end
redef class APlusAssignOp
do
var old_var_ctx = v.variable_ctx
+ # Process condition
v.enter_visit(n_expr)
+ v.check_conform_expr(n_expr, v.type_bool)
+
+ # Prepare 'then' context
v.use_if_true_variable_ctx(n_expr)
+
+ # Process 'then'
v.enter_visit(n_then)
+
+ # Prepare 'else' context
v.variable_ctx = old_var_ctx
v.use_if_false_variable_ctx(n_expr)
+
+ # Process 'else'
v.enter_visit(n_else)
- v.check_conform_expr(n_expr, v.type_bool)
+ var stype = v.check_conform_multiexpr(null, [n_then, n_else])
+ if stype == null then return
- _stype = v.check_conform_multiexpr(null, [n_then, n_else])
- _is_typed = _stype != null
+ _stype = stype
+ _is_typed = true
end
end
redef fun accept_typing(v)
do
var old_var_ctx = v.variable_ctx
+ var stype = v.type_bool
+ _stype = stype
+ # Process left operand
v.enter_visit(n_expr)
+
+ # Prepare right operand context
v.use_if_false_variable_ctx(n_expr)
+ # Process right operand
v.enter_visit(n_expr2)
- if n_expr2.if_false_variable_ctx != null then
+ if n_expr2.if_false_variable_ctx != null then
_if_false_variable_ctx = n_expr2.if_false_variable_ctx
else
_if_false_variable_ctx = v.variable_ctx
v.variable_ctx = old_var_ctx
- v.check_conform_expr(n_expr, v.type_bool)
- v.check_conform_expr(n_expr2, v.type_bool)
- _stype = v.type_bool
+ v.check_conform_expr(n_expr, stype)
+ v.check_conform_expr(n_expr2, stype)
+ _stype = stype
_is_typed = true
end
end
redef fun accept_typing(v)
do
var old_var_ctx = v.variable_ctx
+ var stype = v.type_bool
+ # Process left operand
v.enter_visit(n_expr)
+
+ # Prepare right operand context
v.use_if_true_variable_ctx(n_expr)
+ # Process right operand
v.enter_visit(n_expr2)
- if n_expr2.if_true_variable_ctx != null then
+ if n_expr2.if_true_variable_ctx != null then
_if_true_variable_ctx = n_expr2.if_true_variable_ctx
else
_if_true_variable_ctx = v.variable_ctx
v.variable_ctx = old_var_ctx
- v.check_conform_expr(n_expr, v.type_bool)
- v.check_conform_expr(n_expr2, v.type_bool)
- _stype = v.type_bool
+ v.check_conform_expr(n_expr, stype)
+ v.check_conform_expr(n_expr2, stype)
+ _stype = stype
_is_typed = true
end
end
end
redef class AStringFormExpr
- var _meth_with_native: nullable MMMethod
- redef fun meth_with_native: MMMethod do return _meth_with_native.as(not null)
redef fun after_typing(v)
do
_stype = v.type_string
_is_typed = true
- _meth_with_native = _stype.local_class.select_method(once "with_native".to_symbol)
- if _meth_with_native == null then v.error(self, "{_stype} MUST have a with_native method.")
end
end
redef class ASuperstringExpr
- redef fun meth_with_capacity: MMMethod do return _meth_with_capacity.as(not null)
- var _meth_with_capacity: nullable MMMethod
- redef fun meth_add: MMMethod do return _meth_add.as(not null)
- var _meth_add: nullable MMMethod
- redef fun meth_to_s: MMMethod do return _meth_to_s.as(not null)
- var _meth_to_s: nullable MMMethod
redef fun atype do return _atype.as(not null)
var _atype: nullable MMType
redef fun after_typing(v)
_stype = stype
var atype = v.type_array(stype)
_atype = atype
- _meth_with_capacity = atype.local_class.select_method(once "with_capacity".to_symbol)
- if _meth_with_capacity == null then v.error(self, "{_atype} MUST have a with_capacity method.")
- _meth_add = atype.local_class.select_method(once "add".to_symbol)
- if _meth_add == null then v.error(self, "{_atype} MUST have an add method.")
- _meth_to_s = v.type_object.local_class.select_method(once "to_s".to_symbol)
- if _meth_to_s == null then v.error(self, "Object MUST have a to_s method.")
_is_typed = true
end
end
end
redef class AArrayExpr
- redef fun meth_with_capacity: MMMethod do return _meth_with_capacity.as(not null)
- var _meth_with_capacity: nullable MMMethod
- redef fun meth_add: MMMethod do return _meth_add.as(not null)
- var _meth_add: nullable MMMethod
-
redef fun after_typing(v)
do
var stype = v.check_conform_multiexpr(null, n_exprs)
private fun do_typing(v: TypingVisitor, element_type: MMType)
do
_stype = v.type_array(element_type)
-
- _meth_with_capacity = _stype.local_class.select_method(once "with_capacity".to_symbol)
- if _meth_with_capacity == null then v.error(self, "{_stype} MUST have a with_capacity method.")
- _meth_add = _stype.local_class.select_method(once "add".to_symbol)
- if _meth_add == null then v.error(self, "{_stype} MUST have an add method.")
-
_is_typed = true
end
end
redef class ARangeExpr
- redef fun meth_init: MMMethod do return _meth_init.as(not null)
- var _meth_init: nullable MMMethod
redef fun after_typing(v)
do
if not v.check_expr(n_expr) or not v.check_expr(n_expr2) then return
end
end
-redef class ACrangeExpr
- redef fun after_typing(v)
- do
- super
- if not is_typed then return
- _meth_init = stype.local_class.select_method(once "init".to_symbol)
- end
-end
-redef class AOrangeExpr
- redef fun after_typing(v)
- do
- super
- if not is_typed then return
- _meth_init = stype.local_class.select_method(once "without_last".to_symbol)
- end
-end
-
-
redef class ASuperExpr
redef readable var _init_in_superclass: nullable MMMethod
+ redef fun compute_raw_arguments do return n_args.to_a
redef fun after_typing(v)
do
var precs: Array[MMLocalProperty] = v.local_property.prhe.direct_greaters
register_super_init_call(v, p)
if n_args.length > 0 then
var signature = get_signature(v, v.self_var.stype.as(not null), p, true)
- _arguments = process_signature(v, signature, p.name, n_args.to_a)
+ process_signature(v, signature, p.name, compute_raw_arguments)
end
else
v.error(self, "Error: No super method to call for {v.local_property}.")
redef fun prop_signature do return _prop_signature.as(not null)
var _prop_signature: nullable MMSignature
- # The real arguments used (after star transformation) (once computed)
- redef fun arguments do return _arguments.as(not null)
- var _arguments: nullable Array[PExpr]
+ # Raw arguments used (without vararg transformation)
+ redef fun raw_arguments: Array[AExpr]
+ do
+ var res = _raw_arguments_cache
+ if res != null then
+ return res
+ else
+ res = compute_raw_arguments
+ if res == null then res = new Array[AExpr]
+ _raw_arguments_cache = res
+ return res
+ end
+ end
+
+ var _raw_arguments_cache: nullable Array[AExpr] = null
+
+ fun compute_raw_arguments: nullable Array[AExpr]
+ do
+ print "{location} no compute_raw_arguments"
+ return null
+ end
# Check the conformity of a set of arguments `raw_args' to a signature.
- private fun process_signature(v: TypingVisitor, psig: MMSignature, name: Symbol, raw_args: nullable Array[PExpr]): nullable Array[PExpr]
+ private fun process_signature(v: TypingVisitor, psig: MMSignature, name: Symbol, raw_args: nullable Array[AExpr]): Bool
do
var par_vararg = psig.vararg_rank
var par_arity = psig.arity
var raw_arity: Int
if raw_args == null then raw_arity = 0 else raw_arity = raw_args.length
if par_arity > raw_arity or (par_arity != raw_arity and par_vararg == -1) then
- v.error(self, "Error: '{name}' arity missmatch.")
- return null
+ v.error(self, "Error: arity missmatch; prototype is '{name}{psig}'.")
+ return false
end
var arg_idx = 0
- var args = new Array[PExpr]
for par_idx in [0..par_arity[ do
- var a: PExpr
+ var a: AExpr
var par_type = psig[par_idx]
if par_idx == par_vararg then
- var star = new Array[PExpr]
for i in [0..(raw_arity-par_arity)] do
a = raw_args[arg_idx]
v.check_conform_expr(a, par_type)
- star.add(a)
arg_idx = arg_idx + 1
end
- var aa = new AArrayExpr.init_aarrayexpr(star)
- aa.do_typing(v, par_type)
- a = aa
else
a = raw_args[arg_idx]
v.check_conform_expr(a, par_type)
arg_idx = arg_idx + 1
end
- args.add(a)
end
- return args
+ return true
end
# Check the conformity of a set of defined closures
- private fun process_closures(v: TypingVisitor, psig: MMSignature, name: Symbol, cd: nullable Array[PClosureDef]): nullable MMType
+ private fun process_closures(v: TypingVisitor, psig: MMSignature, name: Symbol, cd: nullable Array[AClosureDef]): nullable MMType
do
var t = psig.return_type
var cs = psig.closures # Declared closures
for c in cs do
if not c.is_optional then min_arity += 1
end
- if cd != null then
- if cs.length == 0 then
- v.error(self, "Error: {name} does not require blocks.")
- else if cd.length > cs.length or cd.length < min_arity then
+ var arity = 0
+ if cd != null then arity = cd.length
+ if cs.length > 0 then
+ if arity == 0 and min_arity > 0 then
+ v.error(self, "Error: {name} requires {cs.length} blocks.")
+ else if arity > cs.length or arity < min_arity then
v.error(self, "Error: {name} requires {cs.length} blocks, {cd.length} found.")
else
# Initialize the break list if a value is required for breaks (ie. if the method is a function)
var break_list: nullable Array[ABreakExpr] = null
if t != null then break_list = new Array[ABreakExpr]
+ # The n_label, is any in only set on the last decl
+ var n_label = if arity > 0 then cd[arity-1].n_label else null
+
# Process each closure definition
- for i in [0..cd.length[ do
- var csi = cs[i]
+ for i in [0..arity[ do
var cdi = cd[i]
- var esc = new EscapableClosure(cdi, csi, break_list)
- v.escapable_ctx.push(esc)
- cdi.accept_typing2(v, esc)
- v.escapable_ctx.pop
+ var cni = cdi.n_id.to_symbol
+ var csi = psig.closure_named(cni)
+ if csi != null then
+ var esc = new EscapableClosure(cdi, csi, break_list)
+ v.escapable_ctx.push(esc, n_label)
+ cdi.accept_typing2(v, esc)
+ v.escapable_ctx.pop
+ else if cs.length == 1 then
+ v.error(cdi.n_id, "Error: no closure named '!{cni}' in {name}; only closure is !{cs.first.name}.")
+ else
+ var a = new Array[String]
+ for c in cs do
+ a.add("!{c.name}")
+ end
+ v.error(cdi.n_id, "Error: no closure named '!{cni}' in {name}; only closures are {a.join(",")}.")
+ end
end
# Check break type conformity
t = v.check_conform_multiexpr(t, break_list)
end
end
- else if min_arity != 0 then
- v.error(self, "Error: {name} requires {cs.length} blocks.")
+ else if arity != 0 then
+ v.error(self, "Error: {name} does not require blocks.")
end
return t
end
redef class AAbsSendExpr
# Compute the called global property
- private fun do_typing(v: TypingVisitor, type_recv: MMType, is_implicit_self: Bool, recv_is_self: Bool, name: Symbol, raw_args: nullable Array[PExpr], closure_defs: nullable Array[PClosureDef])
+ private fun do_typing(v: TypingVisitor, type_recv: MMType, is_implicit_self: Bool, recv_is_self: Bool, name: Symbol, raw_args: nullable Array[AExpr], closure_defs: nullable Array[AClosureDef])
do
var prop = get_property(v, type_recv, is_implicit_self, name)
if prop == null then return
var sig = get_signature(v, type_recv, prop, recv_is_self)
- var args = process_signature(v, sig, prop.name, raw_args)
- if args == null then return
+ if not process_signature(v, sig, prop.name, raw_args) then return
var rtype = process_closures(v, sig, prop.name, closure_defs)
if rtype == null and sig.return_type != null then return
_prop = prop
_prop_signature = sig
- _arguments = args
_return_type = rtype
end
end
redef class ANewExpr
+ redef fun compute_raw_arguments do return n_args.to_a
redef fun after_typing(v)
do
if not n_type.is_typed then return
name = n_id.to_symbol
end
- do_typing(v, t, false, false, name, n_args.to_a, null)
+ do_typing(v, t, false, false, name, raw_arguments, null)
if _prop == null then return
if not prop.global.is_init then
# Name of the invoked property
fun name: Symbol is abstract
- # Raw arguments used (withour star transformation)
- fun raw_arguments: nullable Array[PExpr] is abstract
-
# Closure definitions
- redef fun closure_defs: nullable Array[PClosureDef] do return null
+ redef fun closure_defs: nullable Array[AClosureDef] do return null
redef fun after_typing(v)
do
v.check_conform(self, t2, n_value.stype)
_read_prop = prop
- var old_args = arguments
+ raw_args = raw_args.to_a
raw_args.add(n_value)
do_typing(v, n_expr.stype, n_expr.is_implicit_self, n_expr.is_self, "{name}=".to_symbol, raw_args, null)
end
end
- _arguments = old_args # FIXME: What if star parameters do not match betwen the two methods?
_is_typed = true
end
end
redef class ABinopExpr
- redef fun raw_arguments do return [n_expr2]
+ redef fun compute_raw_arguments do return [n_expr2]
end
redef class AEqExpr
redef fun name do return once "==".to_symbol
end
end
- private fun try_to_isa(v: TypingVisitor, n: PExpr)
+ private fun try_to_isa(v: TypingVisitor, n: AExpr)
do
var variable = n.its_variable
if variable != null then
end
end
- private fun try_to_isa(v: TypingVisitor, n: PExpr)
+ private fun try_to_isa(v: TypingVisitor, n: AExpr)
do
var variable = n.its_variable
if variable != null then
redef class AUminusExpr
redef fun name do return once "unary -".to_symbol
- redef fun raw_arguments do return null
+ redef fun compute_raw_arguments do return null
end
redef class ACallFormExpr
var name = n_id.to_symbol
var variable = v.variable_ctx[name]
if variable != null then
+ var n: AExpr
if variable isa ClosureVariable then
- var n = new AClosureCallExpr.init_aclosurecallexpr(n_id, n_args, n_closure_defs)
- replace_with(n)
+ n = new AClosureCallExpr.init_aclosurecallexpr(n_id, n_args, n_closure_defs)
n._variable = variable
- n.after_typing(v)
- return
else
if not n_args.is_empty then
v.error(self, "Error: {name} is variable, not a function.")
return
end
- var vform = variable_create(variable)
- vform._variable = variable
- replace_with(vform)
- vform.after_typing(v)
- return
+ n = variable_create(variable)
+ n._variable = variable
end
+ replace_with(n)
+ n.after_typing(v)
+ return
end
end
end
redef fun name do return n_id.to_symbol
- redef fun raw_arguments do return n_args.to_a
+ redef fun compute_raw_arguments do return n_args.to_a
end
redef class ACallAssignExpr
end
redef fun name do return (n_id.text + "=").to_symbol
- redef fun raw_arguments do
+ redef fun compute_raw_arguments do
var res = n_args.to_a
res.add(n_value)
return res
end
redef fun name do return n_id.to_symbol
- redef fun raw_arguments do return n_args.to_a
+ redef fun compute_raw_arguments do return n_args.to_a
end
redef class ABraExpr
redef fun name do return once "[]".to_symbol
- redef fun raw_arguments do return n_args.to_a
+ redef fun compute_raw_arguments do return n_args.to_a
+ redef fun closure_defs
+ do
+ if n_closure_defs.is_empty then
+ return null
+ else
+ return n_closure_defs.to_a
+ end
+ end
end
redef class ABraAssignExpr
redef fun name do return once "[]=".to_symbol
- redef fun raw_arguments do
+ redef fun compute_raw_arguments do
var res = n_args.to_a
res.add(n_value)
return res
redef class ABraReassignExpr
redef fun name do return once "[]".to_symbol
- redef fun raw_arguments do return n_args.to_a
+ redef fun compute_raw_arguments do return n_args.to_a
end
redef class AInitExpr
redef fun name do return once "init".to_symbol
- redef fun raw_arguments do return n_args.to_a
+ redef fun compute_raw_arguments do return n_args.to_a
end
redef class AClosureCallExpr
var _variable: nullable ClosureVariable
redef fun variable do return _variable.as(not null)
+ redef fun compute_raw_arguments do return n_args.to_a
redef fun after_typing(v)
do
var va = variable
if va.closure.is_break then v.variable_ctx.unreash = true
var sig = va.closure.signature
- var args = process_signature(v, sig, n_id.to_symbol, n_args.to_a)
+ var s = process_signature(v, sig, n_id.to_symbol, compute_raw_arguments)
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
+ if not s then return
_prop_signature = sig
- _arguments = args
_stype = sig.return_type
_is_typed = true
end
end
-redef class PClosureDef
+redef class AClosureId
+ fun to_symbol: Symbol is abstract
+end
+redef class ASimpleClosureId
+ redef fun to_symbol: Symbol do return n_id.to_symbol
+end
+redef class ABreakClosureId
+ redef fun to_symbol: Symbol do return n_kwbreak.to_symbol
+end
+
+redef class AClosureDef
var _closure: nullable MMClosure
redef fun closure do return _closure.as(not null)
if _accept_typing2 then super
end
- private fun accept_typing2(v: TypingVisitor, esc: EscapableClosure) is abstract
-end
-
-redef class AClosureDef
- redef fun accept_typing2(v, esc)
+ private fun accept_typing2(v: TypingVisitor, esc: EscapableClosure)
do
_escapable = esc
var sig = esc.closure.signature
- if sig.arity != n_id.length then
- v.error(self, "Error: {sig.arity} automatic variable names expected, {n_id.length} found.")
+ if sig.arity != n_ids.length then
+ v.error(self, "Error: {sig.arity} automatic variable names expected, {n_ids.length} found.")
return
end
v.base_variable_ctx = v.variable_ctx
v.variable_ctx = v.variable_ctx.sub(self)
variables = new Array[AutoVariable]
- for i in [0..n_id.length[ do
- var va = new AutoVariable(n_id[i].to_symbol, self)
+ for i in [0..n_ids.length[ do
+ var va = new AutoVariable(n_ids[i].to_symbol, n_ids[i])
variables.add(va)
va.stype = sig[i]
v.variable_ctx.add(va)
end
class ATypeCheckExpr
-special PExpr
- private fun check_expr_cast(v: TypingVisitor, n_expr: PExpr, n_type: PType)
+special AExpr
+ private fun check_expr_cast(v: TypingVisitor, n_expr: AExpr, n_type: AType)
do
if not v.check_expr(n_expr) then return
if not n_type.is_typed then return