X-Git-Url: http://nitlanguage.org diff --git a/src/transform.nit b/src/transform.nit index 2fda94e..ebe2c73 100644 --- a/src/transform.nit +++ b/src/transform.nit @@ -20,12 +20,13 @@ import astbuilder import astvalidation import semantize intrude import semantize::scope +intrude import semantize::typing redef class ToolContext var transform_phase: Phase = new TransformPhase(self, [typing_phase, auto_super_init_phase]) # --no-shortcut-range - var opt_no_shortcut_range: OptionBool = new OptionBool("Always insantiate a range and its iterator on 'for' loops", "--no-shortcut-range") + var opt_no_shortcut_range: OptionBool = new OptionBool("Always instantiate a range and its iterator on 'for' loops", "--no-shortcut-range") redef init do @@ -41,7 +42,9 @@ private class TransformPhase do var val - var v = new TransformVisitor(self, npropdef.mpropdef.as(not null)) + var m = npropdef.mpropdef + if m == null then return + var v = new TransformVisitor(self, m) v.enter_visit(npropdef) val = new ASTValidationVisitor @@ -71,12 +74,6 @@ private class TransformVisitor node.full_transform_visitor(self) end - # Get a primitive class or display a fatal error on `location`. - fun get_class(location: AExpr, name: String): MClass - do - return mmodule.get_primitive_class(name) - end - # Get a primitive method or display a fatal error on `location`. fun get_method(location: AExpr, name: String, recv: MClass): MMethod do @@ -109,6 +106,14 @@ redef class AExpr end super end + + redef fun replace_with(other) + do + super + if other isa AExpr then + if other.implicit_cast_to == null then other.implicit_cast_to = implicit_cast_to + end + end end redef class AVardeclExpr @@ -289,6 +294,57 @@ redef class AForExpr end end +redef class AWithExpr + # is replaced with a do/end and injected calls to `start` and `finish` + # + # Basically, the following + # + # ~~~nitish + # with expr do + # block + # end label l + # ~~~ + # + # is transformed into + # + # ~~~nitish + # var x = expr + # do + # x.start + # block + # end label l + # x.finish + # ~~~ + # + # The point is that `finish` is called even if the block is escaped. + redef fun accept_transform_visitor(v) + do + var escapemark = self.break_mark + assert escapemark != null + + var nblock = v.builder.make_block + + var nexpr = n_expr + + nblock.add nexpr + + var ndo = v.builder.make_do + ndo.break_mark = escapemark + + var start = v.builder.make_call(nexpr.make_var_read, method_start.as(not null), null) + + ndo.add start + + ndo.add self.n_block.as(not null) + + nblock.add ndo + + nblock.add v.builder.make_call(nexpr.make_var_read, method_finish.as(not null), null) + + replace_with(nblock) + end +end + redef class AArrayExpr # `[x,y]` is replaced with #