var method_key: nullable CallSite
var method_finish: nullable CallSite
+ var method_lt: nullable CallSite
+ var method_successor: nullable CallSite
+
private fun do_type_iterator(v: TypeVisitor, mtype: MType)
do
if mtype isa MNullType then
end
self.method_key = keydef
end
+
+ if self.variables.length == 1 and n_expr isa ARangeExpr then
+ var variable = variables.first
+ var vtype = variable.declared_type.as(not null)
+
+ if n_expr isa AOrangeExpr then
+ self.method_lt = v.get_method(self, vtype, "<", false)
+ else
+ self.method_lt = v.get_method(self, vtype, "<=", false)
+ end
+
+ self.method_successor = v.get_method(self, vtype, "successor", false)
+ end
end
redef fun accept_typing(v)
var nexpr = n_expr
+ # Shortcut on explicit range
+ # Avoid the instantiation of the range and the iterator
+ if self.variables.length == 1 and nexpr isa ARangeExpr then
+ var variable = variables.first
+ nblock.add v.builder.make_var_assign(variable, nexpr.n_expr)
+ var to = nexpr.n_expr2
+ nblock.add to
+
+ var nloop = v.builder.make_loop
+ nloop.break_mark = escapemark
+ nblock.add nloop
+
+ var is_ok = v.builder.make_call(v.builder.make_var_read(variable, variable.declared_type.as(not null)), method_lt.as(not null), [to.make_var_read])
+
+ var nif = v.builder.make_if(is_ok, null)
+ nloop.add nif
+
+ var nthen = nif.n_then
+ var ndo = v.builder.make_do
+ ndo.break_mark = escapemark.continue_mark
+ nthen.add ndo
+
+ ndo.add self.n_block.as(not null)
+
+ var one = v.builder.make_int(1)
+ var succ = v.builder.make_call(v.builder.make_var_read(variable, variable.declared_type.as(not null)), method_successor.as(not null), [one])
+ nthen.add v.builder.make_var_assign(variable, succ)
+
+ var nbreak = v.builder.make_break(escapemark)
+ nif.n_else.add nbreak
+
+ replace_with(nblock)
+ return
+ end
+
nblock.add nexpr
var iter = v.builder.make_call(nexpr.make_var_read, method_iterator.as(not null), null)