Rename REAMDE to README.md
[nit.git] / src / transform.nit
index 8ae2c28..ebe2c73 100644 (file)
@@ -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
@@ -73,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
@@ -111,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
@@ -291,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
        #