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)
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)
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)
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
# Process each closure definition
for i in [0..arity[ do
- var csi = cs[i]
var cdi = cd[i]
- var esc = new EscapableClosure(cdi, csi, break_list)
- v.escapable_ctx.push(esc, n_label)
- 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
end
end
+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)
v.variable_ctx = v.variable_ctx.sub(self)
variables = new Array[AutoVariable]
for i in [0..n_ids.length[ do
- var va = new AutoVariable(n_ids[i].to_symbol, self)
+ var va = new AutoVariable(n_ids[i].to_symbol, n_ids[i])
variables.add(va)
va.stype = sig[i]
v.variable_ctx.add(va)