From 40dadcdacbc9a931cf56585df393ee3b25122332 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Tue, 6 Oct 2015 21:50:45 -0400 Subject: [PATCH] interpreter&vm: handle multi-iterator Signed-off-by: Jean Privat --- src/interpreter/naive_interpreter.nit | 58 +++++++++++++++++++-------------- src/ssa.nit | 14 ++++---- src/vm/variables_numbering.nit | 25 +++++++------- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index da7b288..f2aabe4 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -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 diff --git a/src/ssa.nit b/src/ssa.nit index 65a4de6..dbaac2e 100644 --- a/src/ssa.nit +++ b/src/ssa.nit @@ -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) diff --git a/src/vm/variables_numbering.nit b/src/vm/variables_numbering.nit index d01b390..75bff69 100644 --- a/src/vm/variables_numbering.nit +++ b/src/vm/variables_numbering.nit @@ -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 -- 1.7.9.5