niti: Fixed method NativeString::copy_to in intern_call
[nit.git] / src / interpreter / naive_interpreter.nit
index 064395d..bb0b3b3 100644 (file)
@@ -72,10 +72,12 @@ class NaiveInterpreter
 
        init
        do
-               self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
-               init_instance_primitive(self.true_instance)
-               self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
-               init_instance_primitive(self.false_instance)
+               if mainmodule.model.get_mclasses_by_name("Bool") != null then
+                       self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
+                       init_instance_primitive(self.true_instance)
+                       self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
+                       init_instance_primitive(self.false_instance)
+               end
                self.null_instance = new PrimitiveInstance[nullable Object](mainmodule.model.null_type, null)
        end
 
@@ -171,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`)
@@ -450,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])
@@ -662,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
@@ -848,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
@@ -954,13 +970,13 @@ redef class AMethPropdef
                                if fromval < 0 then
                                        debug("Illegal access on {recvval} for element {fromval}/{recvval.length}")
                                end
-                               if fromval + lenval >= recvval.length then
+                               if fromval + lenval > recvval.length then
                                        debug("Illegal access on {recvval} for element {fromval}+{lenval}/{recvval.length}")
                                end
                                if toval < 0 then
                                        debug("Illegal access on {destval} for element {toval}/{destval.length}")
                                end
-                               if toval + lenval >= destval.length then
+                               if toval + lenval > destval.length then
                                        debug("Illegal access on {destval} for element {toval}+{lenval}/{destval.length}")
                                end
                                recvval.as(FlatBuffer).copy(fromval, lenval, destval, toval)
@@ -1207,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
@@ -1216,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
@@ -1530,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)