lib/standard/string: Fixed leaking Int.to_s method
[nit.git] / src / interpreter / naive_interpreter.nit
index 5d24e6c..aa95eb4 100644 (file)
@@ -173,14 +173,20 @@ class NaiveInterpreter
        # If `n` cannot be evaluated, then aborts.
        fun stmt(n: nullable AExpr)
        do
-               if n != null then
-                       var frame = self.frame
-                       var old = frame.current_node
-                       frame.current_node = n
-                       #n.debug("Execute stmt")
-                       n.stmt(self)
-                       frame.current_node = old
+               if n == null then return
+
+               if n.comprehension != null then
+                       var comprehension = frame.comprehension.as(not null)
+                       var i = expr(n)
+                       if i != null then comprehension.add(i)
+                       return
                end
+
+               var frame = self.frame
+               var old = frame.current_node
+               frame.current_node = n
+               n.stmt(self)
+               frame.current_node = old
        end
 
        # Map used to store values of nodes that must be evaluated once in the system (`AOnceExpr`)
@@ -452,7 +458,7 @@ class NaiveInterpreter
        fun send_commons(mproperty: MMethod, args: Array[Instance], mtype: MType): nullable Instance
        do
                if mtype isa MNullType then
-                       if mproperty.name == "==" then
+                       if mproperty.name == "==" or mproperty.name == "is_same_instance" then
                                return self.bool_instance(args[0] == args[1])
                        else if mproperty.name == "!=" then
                                return self.bool_instance(args[0] != args[1])
@@ -664,6 +670,7 @@ class Frame
        var arguments: Array[Instance]
        # Mapping between a variable and the current value
        private var map: Map[Variable, Instance] = new HashMap[Variable, Instance]
+       var comprehension: nullable Array[Instance] = null
 end
 
 redef class ANode
@@ -850,8 +857,15 @@ redef class AMethPropdef
                                return v.int_instance(args[0].to_i.bin_xor(args[1].to_i))
                        else if pname == "bin_not" then
                                return v.int_instance(args[0].to_i.bin_not)
+                       else if pname == "int_to_s_len" then
+                               return v.int_instance(recvval.to_s.length)
                        else if pname == "native_int_to_s" then
-                               return v.native_string_instance(recvval.to_s)
+                               var s = recvval.to_s
+                               var srecv = args[1].val.as(Buffer)
+                               srecv.clear
+                               srecv.append(s)
+                               srecv.add('\0')
+                               return null
                        else if pname == "strerror_ext" then
                                return v.native_string_instance(recvval.strerror)
                        end
@@ -1209,7 +1223,7 @@ redef class AExpr
        # Return a possible value
        # NOTE: Do not call this method directly, but use `v.expr`
        # This method is here to be implemented by subclasses.
-       private fun expr(v: NaiveInterpreter): nullable Instance
+       protected fun expr(v: NaiveInterpreter): nullable Instance
        do
                fatal(v, "NOT YET IMPLEMENTED expr {class_name}")
                abort
@@ -1218,7 +1232,7 @@ redef class AExpr
        # Evaluate the node as a statement.
        # NOTE: Do not call this method directly, but use `v.stmt`
        # This method is here to be implemented by subclasses (no need to return something).
-       private fun stmt(v: NaiveInterpreter)
+       protected fun stmt(v: NaiveInterpreter)
        do
                expr(v)
        end
@@ -1532,11 +1546,18 @@ redef class AArrayExpr
        redef fun expr(v)
        do
                var val = new Array[Instance]
-               for nexpr in self.n_exprs.n_exprs do
-                       var i = v.expr(nexpr)
-                       if i == null then return null
-                       val.add(i)
+               var old_comprehension = v.frame.comprehension
+               v.frame.comprehension = val
+               for nexpr in self.n_exprs do
+                       if nexpr isa AForExpr then
+                               v.stmt(nexpr)
+                       else
+                               var i = v.expr(nexpr)
+                               if i == null then return null
+                               val.add(i)
+                       end
                end
+               v.frame.comprehension = old_comprehension
                var mtype = v.unanchor_type(self.mtype.as(not null)).as(MClassType)
                var elttype = mtype.arguments.first
                return v.array_instance(val, elttype)