From: Jean Privat Date: Sat, 11 Oct 2014 04:28:37 +0000 (-0400) Subject: transform: transforms `while` and `for` X-Git-Tag: v0.6.10~30^2~2 X-Git-Url: http://nitlanguage.org transform: transforms `while` and `for` Signed-off-by: Jean Privat --- diff --git a/src/astbuilder.nit b/src/astbuilder.nit index 428a5ca..fd2e22e 100644 --- a/src/astbuilder.nit +++ b/src/astbuilder.nit @@ -154,7 +154,7 @@ redef class AExpr # Note: this method, aimed to `ABlockExpr` is promoted to `AExpr` because of the limitations of the hierarchies generated by sablecc3 fun add(expr: AExpr) do - print "add not inplemented in {inspect}" + print "add not implemented in {inspect}" abort end end diff --git a/src/transform.nit b/src/transform.nit index 6a209c3..50ea215 100644 --- a/src/transform.nit +++ b/src/transform.nit @@ -19,6 +19,7 @@ module transform import astbuilder import astvalidation import semantize +intrude import semantize::scope redef class ToolContext var transform_phase: Phase = new TransformPhase(self, [typing_phase, auto_super_init_phase]) @@ -151,14 +152,78 @@ end redef class AWhileExpr redef fun accept_transform_visitor(v) do - # TODO + var nloop = v.builder.make_loop + var nif = v.builder.make_if(n_expr, null) + nloop.add nif + + var nblock = n_block + if nblock != null then nif.n_then.add nblock + + var escapemark = self.break_mark.as(not null) + var nbreak = v.builder.make_break(escapemark) + nif.n_else.add nbreak + + nloop.break_mark = self.break_mark + nloop.continue_mark = self.continue_mark + + replace_with(nloop) end end redef class AForExpr redef fun accept_transform_visitor(v) do - # TODO + var escapemark = self.break_mark + assert escapemark != null + + var nblock = v.builder.make_block + + var nexpr = n_expr + + nblock.add nexpr + + var iter = v.builder.make_call(nexpr.make_var_read, method_iterator.as(not null), null) + nblock.add iter + + var nloop = v.builder.make_loop + nloop.break_mark = escapemark + nblock.add nloop + + var is_ok = v.builder.make_call(iter.make_var_read, method_is_ok.as(not null), null) + + 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 + + if self.variables.length == 1 then + var item = v.builder.make_call(iter.make_var_read, method_item.as(not null), null) + ndo.add v.builder.make_var_assign(variables.first, item) + else if self.variables.length == 2 then + var key = v.builder.make_call(iter.make_var_read, method_key.as(not null), null) + ndo.add v.builder.make_var_assign(variables[0], key) + var item = v.builder.make_call(iter.make_var_read, method_item.as(not null), null) + ndo.add v.builder.make_var_assign(variables[1], item) + else + abort + end + + ndo.add self.n_block.as(not null) + + nthen.add v.builder.make_call(iter.make_var_read, method_next.as(not null), null) + + var nbreak = v.builder.make_break(escapemark) + nif.n_else.add nbreak + + var method_finish = self.method_finish + if method_finish != null then + nblock.add v.builder.make_call(iter.make_var_read, method_finish, null) + end + + replace_with(nblock) end end