interpreter&vm: handle multi-iterator
authorJean Privat <jean@pryen.org>
Wed, 7 Oct 2015 01:50:45 +0000 (21:50 -0400)
committerJean Privat <jean@pryen.org>
Wed, 7 Oct 2015 02:02:34 +0000 (22:02 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/interpreter/naive_interpreter.nit
src/ssa.nit
src/vm/variables_numbering.nit

index da7b288..f2aabe4 100644 (file)
@@ -1757,37 +1757,47 @@ end
 redef class AForExpr
        redef fun stmt(v)
        do
-               var col = v.expr(self.n_expr)
-               if col == null then return
-               if col.mtype isa MNullType then fatal(v, "Receiver is null")
+               var iters = new Array[Instance]
+
+               for g in n_groups do
+                       var col = v.expr(g.n_expr)
+                       if col == null then return
+                       if col.mtype isa MNullType then fatal(v, "Receiver is null")
+
+                       var iter = v.callsite(g.method_iterator, [col]).as(not null)
+                       iters.add iter
+               end
 
-               #self.debug("col {col}")
-               var iter = v.callsite(method_iterator, [col]).as(not null)
-               #self.debug("iter {iter}")
                loop
-                       var isok = v.callsite(method_is_ok, [iter]).as(not null)
-                       if not isok.is_true then break
-                       if self.variables.length == 1 then
-                               var item = v.callsite(method_item, [iter]).as(not null)
-                               #self.debug("item {item}")
-                               v.write_variable(self.variables.first, item)
-                       else if self.variables.length == 2 then
-                               var key = v.callsite(method_key, [iter]).as(not null)
-                               v.write_variable(self.variables[0], key)
-                               var item = v.callsite(method_item, [iter]).as(not null)
-                               v.write_variable(self.variables[1], item)
-                       else
-                               abort
+                       for g in n_groups, iter in iters do
+                               var isok = v.callsite(g.method_is_ok, [iter]).as(not null)
+                               if not isok.is_true then break label
+                               if g.variables.length == 1 then
+                                       var item = v.callsite(g.method_item, [iter]).as(not null)
+                                       #self.debug("item {item}")
+                                       v.write_variable(g.variables.first, item)
+                               else if g.variables.length == 2 then
+                                       var key = v.callsite(g.method_key, [iter]).as(not null)
+                                       v.write_variable(g.variables[0], key)
+                                       var item = v.callsite(g.method_item, [iter]).as(not null)
+                                       v.write_variable(g.variables[1], item)
+                               else
+                                       abort
+                               end
                        end
                        v.stmt(self.n_block)
                        if v.is_escape(self.break_mark) then break
                        v.is_escape(self.continue_mark) # Clear the break
                        if v.is_escaping then break
-                       v.callsite(method_next, [iter])
-               end
-               var method_finish = self.method_finish
-               if method_finish != null then
-                       v.callsite(method_finish, [iter])
+                       for g in n_groups, iter in iters do
+                               v.callsite(g.method_next, [iter])
+                       end
+               end label
+               for g in n_groups, iter in iters do
+                       var method_finish = g.method_finish
+                       if method_finish != null then
+                               v.callsite(method_finish, [iter])
+                       end
                end
        end
 end
index 65a4de6..dbaac2e 100644 (file)
@@ -1117,15 +1117,17 @@ redef class AForExpr
 
                # The beginning of the block is the first instruction
                var block = new BasicBlock
-               block.first = self.n_expr
+               block.first = self.n_groups.first.n_expr
                block.last = self.n_block.as(not null)
 
-               # Visit the test of the if
-               self.n_expr.generate_basic_blocks(ssa, block)
+               for g in n_groups do
+                       # Visit the test of the if
+                       g.n_expr.generate_basic_blocks(ssa, block)
 
-               # Collect the variables declared in the for
-               for v in variables do
-                       ssa.propdef.variables.add(v)
+                       # Collect the variables declared in the for
+                       for v in g.variables do
+                               ssa.propdef.variables.add(v)
+                       end
                end
 
                old_block.link(block)
index d01b390..75bff69 100644 (file)
@@ -254,18 +254,21 @@ end
 redef class AForExpr
        redef fun numbering(v, position)
        do
-               # Give a position to each variable declared in the header of the for
-               if self.variables.length == 1 then
-                       self.variables.first.position = position
-                       self.variables[0].position = position
-                       position += 1
-               else if self.variables.length == 2 then
-                       self.variables[0].position = position
-                       position += 1
-                       self.variables[1].position = position
-                       position += 1
+               for g in n_groups do
+                       # Give a position to each variable declared in the header of the for
+                       if g.variables.length == 1 then
+                               g.variables.first.position = position
+                               g.variables[0].position = position
+                               position += 1
+                       else if g.variables.length == 2 then
+                               g.variables[0].position = position
+                               position += 1
+                               g.variables[1].position = position
+                               position += 1
+                       end
+                       position = v.numbering(self.n_block, position)
                end
-               return v.numbering(self.n_block, position)
+               return position
        end
 end