workaround implementation waiting for closures.
Signed-off-by: Jean Privat <jean@pryen.org>
var ok = v.send(v.get_property("is_ok", it.mtype), [it])
assert ok != null
v.add("if(!{ok}) break;")
- var i = v.send(v.get_property("item", it.mtype), [it])
- assert i != null
- v.assign(v.variable(variables.first), i)
+ if self.variables.length == 1 then
+ var i = v.send(v.get_property("item", it.mtype), [it])
+ assert i != null
+ v.assign(v.variable(variables.first), i)
+ else if self.variables.length == 2 then
+ var i = v.send(v.get_property("key", it.mtype), [it])
+ assert i != null
+ v.assign(v.variable(variables[0]), i)
+ i = v.send(v.get_property("item", it.mtype), [it])
+ assert i != null
+ v.assign(v.variable(variables[1]), i)
+ else
+ abort
+ end
v.stmt(self.n_block)
v.add("CONTINUE_{escapemark.object_id}: (void)0;")
v.send(v.get_property("next", it.mtype), [it])
loop
var isok = v.send(v.mainmodule.force_get_primitive_method("is_ok", iter.mtype), [iter]).as(not null)
if not isok.is_true then return
- var item = v.send(v.mainmodule.force_get_primitive_method("item", iter.mtype), [iter]).as(not null)
- #self.debug("item {item}")
- v.frame.map[self.variables.first] = item
+ if self.variables.length == 1 then
+ var item = v.send(v.mainmodule.force_get_primitive_method("item", iter.mtype), [iter]).as(not null)
+ #self.debug("item {item}")
+ v.frame.map[self.variables.first] = item
+ else if self.variables.length == 2 then
+ var key = v.send(v.mainmodule.force_get_primitive_method("key", iter.mtype), [iter]).as(not null)
+ v.frame.map[self.variables[0]] = key
+ var item = v.send(v.mainmodule.force_get_primitive_method("item", iter.mtype), [iter]).as(not null)
+ v.frame.map[self.variables[1]] = item
+ else
+ abort
+ end
v.stmt(self.n_block)
if v.is_break(self.escapemark) then return
v.is_continue(self.escapemark) # Clear the break
redef fun accept_rapid_type_vistor(v)
do
var recvtype = self.n_expr.mtype.as(not null)
- var colltype = v.get_class("Collection").mclassdefs.first.bound_mtype
- v.add_send(recvtype, v.get_method(colltype, "iterator"))
- var iteratortype = v.get_class("Iterator").mclassdefs.first.bound_mtype
+ var colltype = self.coltype.as(not null)
+ var itmeth = v.get_method(colltype, "iterator")
+ v.add_send(recvtype, itmeth)
+ var iteratortype = itmeth.intro.msignature.return_mtype.as(MClassType).mclass.mclassdefs.first.bound_mtype
var objtype = v.get_class("Object").mclass_type
v.add_send(objtype, v.get_method(iteratortype, "is_ok"))
- v.add_send(objtype, v.get_method(iteratortype, "item"))
+ if self.variables.length == 1 then
+ v.add_send(objtype, v.get_method(iteratortype, "item"))
+ else if self.variables.length == 2 then
+ v.add_send(objtype, v.get_method(iteratortype, "key"))
+ v.add_send(objtype, v.get_method(iteratortype, "item"))
+ else
+ abort
+ end
v.add_send(objtype, v.get_method(iteratortype, "next"))
end
end
end
redef class AForExpr
+ var coltype: nullable MGenericType
redef fun accept_typing(v)
do
var mtype = v.visit_expr(n_expr)
if colcla == null then return
var objcla = v.get_mclass(self, "Object")
if objcla == null then return
+ var mapcla = v.get_mclass(self, "Map")
+ if mapcla == null then return
if v.is_subtype(mtype, colcla.get_mtype([objcla.mclass_type.as_nullable])) then
var coltype = mtype.supertype_to(v.mmodule, v.anchor, colcla)
assert coltype isa MGenericType
+ self.coltype = coltype
var variables = self.variables
if variables.length != 1 then
v.error(self, "Type Error: Expected one variable")
else
variables.first.declared_type = coltype.arguments.first
end
+ else if v.is_subtype(mtype, mapcla.get_mtype([objcla.mclass_type.as_nullable, objcla.mclass_type.as_nullable])) then
+ var coltype = mtype.supertype_to(v.mmodule, v.anchor, mapcla)
+ assert coltype isa MGenericType
+ self.coltype = coltype
+ var variables = self.variables
+ if variables.length != 2 then
+ v.error(self, "Type Error: Expected two variables")
+ else
+ variables[0].declared_type = coltype.arguments[0]
+ variables[1].declared_type = coltype.arguments[1]
+ end
else
v.modelbuilder.error(self, "TODO: Do 'for' on {mtype}")
end