niti: add write_attribute as a unique entry point
[nit.git] / src / naive_interpreter.nit
index 510d0a0..080880f 100644 (file)
@@ -434,6 +434,13 @@ private class NaiveInterpreter
                return recv.attributes[mproperty]
        end
 
+       # Replace in `recv` the value of the attribute `mproperty` by `value`
+       fun write_attribute(mproperty: MAttribute, recv: Instance, value: Instance)
+       do
+               assert recv isa MutableInstance
+               recv.attributes[mproperty] = value
+       end
+
        # Collect attributes of a type in the order of their init
        fun collect_attr_propdef(mtype: MType): Array[AAttrPropdef]
        do
@@ -572,11 +579,11 @@ redef class ANode
        private fun fatal(v: NaiveInterpreter, message: String)
        do
                if v.modelbuilder.toolcontext.opt_no_color.value == true then
-                       stderr.write("Runtime error: {message} ({location.file.filename}:{location.line_start})\n")
+                       sys.stderr.write("Runtime error: {message} ({location.file.filename}:{location.line_start})\n")
                else
-                       stderr.write("{location}: Runtime error: {message}\n{location.colored_line("0;31")}\n")
-                       stderr.write(v.stack_trace)
-                       stderr.write("\n")
+                       sys.stderr.write("{location}: Runtime error: {message}\n{location.colored_line("0;31")}\n")
+                       sys.stderr.write(v.stack_trace)
+                       sys.stderr.write("\n")
                end
                exit(1)
        end
@@ -716,6 +723,12 @@ redef class AMethPropdef
                        else if pname == "rand" then
                                var res = recvval.rand
                                return v.int_instance(res)
+                       else if pname == "bin_and" then
+                               return v.int_instance(args[0].to_i.bin_and(args[1].to_i))
+                       else if pname == "bin_or" then
+                               return v.int_instance(args[0].to_i.bin_or(args[1].to_i))
+                       else if pname == "bin_xor" then
+                               return v.int_instance(args[0].to_i.bin_xor(args[1].to_i))
                        else if pname == "native_int_to_s" then
                                return v.native_string_instance(recvval.to_s)
                        else if pname == "strerror_ext" then
@@ -794,6 +807,9 @@ redef class AMethPropdef
                                return v.bool_instance(args[0].to_f.is_inf != 0)
                        end
                else if cname == "NativeString" then
+                       if pname == "init" then
+                               return v.native_string_instance("!" * args[1].to_i)
+                       end
                        var recvval = args.first.val.as(Buffer)
                        if pname == "[]" then
                                var arg1 = args[1].to_i
@@ -852,6 +868,10 @@ redef class AMethPropdef
                else if pname == "calloc_string" then
                        return v.native_string_instance("!" * args[1].to_i)
                else if cname == "NativeArray" then
+                       if pname == "init" then
+                               var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i)
+                               return new PrimitiveInstance[Array[Instance]](args[0].mtype, val)
+                       end
                        var recvval = args.first.val.as(Array[Instance])
                        if pname == "[]" then
                                if args[1].to_i >= recvval.length or args[1].to_i < 0 then
@@ -869,11 +889,11 @@ redef class AMethPropdef
                        end
                else if cname == "NativeFile" then
                        if pname == "native_stdout" then
-                               return new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, stdout)
+                               return new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, sys.stdout)
                        else if pname == "native_stdin" then
-                               return new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, stdin)
+                               return new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, sys.stdin)
                        else if pname == "native_stderr" then
-                               return new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, stderr)
+                               return new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, sys.stderr)
                        else if pname == "io_open_read" then
                                var a1 = args[1].val.as(Buffer)
                                return new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, new IFStream.open(a1.to_s))
@@ -966,7 +986,7 @@ redef class AAttrPropdef
                        return v.read_attribute(attr, recv)
                else
                        assert args.length == 2
-                       recv.attributes[attr] = args[1]
+                       v.write_attribute(attr, recv, args[1])
                        return null
                end
        end
@@ -983,13 +1003,13 @@ redef class AAttrPropdef
                        assert val != null
                        v.frames.shift
                        assert not v.is_escaping
-                       recv.attributes[self.mpropdef.mproperty] = val
+                       v.write_attribute(self.mpropdef.mproperty, recv, val)
                        return
                end
                var mtype = self.mpropdef.static_mtype.as(not null)
                mtype = mtype.anchor_to(v.mainmodule, recv.mtype.as(MClassType))
                if mtype isa MNullableType then
-                       recv.attributes[self.mpropdef.mproperty] = v.null_instance
+                       v.write_attribute(self.mpropdef.mproperty, recv, v.null_instance)
                end
        end
 end
@@ -1000,11 +1020,11 @@ redef class AClassdef
        do
                var super_inits = self.super_inits
                if super_inits != null then
-                       assert args.length == 1
+                       var args_of_super = args
+                       if args.length > 1 then args_of_super = [args.first]
                        for su in super_inits do
-                               v.send(su, args)
+                               v.send(su, args_of_super)
                        end
-                       return null
                end
                var recv = args.first
                assert recv isa MutableInstance
@@ -1012,7 +1032,7 @@ redef class AClassdef
                # Collect undefined attributes
                for npropdef in self.n_propdefs do
                        if npropdef isa AAttrPropdef and npropdef.n_expr == null then
-                               recv.attributes[npropdef.mpropdef.mproperty] = args[i]
+                               v.write_attribute(npropdef.mpropdef.mproperty, recv, args[i])
                                i += 1
                        end
                end
@@ -1560,7 +1580,7 @@ redef class ASuperExpr
                if callsite != null then
                        # Add additionnals arguments for the super init call
                        if args.length == 1 then
-                               for i in [0..callsite.mproperty.intro.msignature.arity[ do
+                               for i in [0..callsite.msignature.arity[ do
                                        args.add(v.frame.arguments[i+1])
                                end
                        end
@@ -1622,8 +1642,7 @@ redef class AAttrAssignExpr
                var i = v.expr(self.n_value)
                if i == null then return
                var mproperty = self.mproperty.as(not null)
-               assert recv isa MutableInstance
-               recv.attributes[mproperty] = i
+               v.write_attribute(mproperty, recv, i)
        end
 end
 
@@ -1639,8 +1658,7 @@ redef class AAttrReassignExpr
                var attr = v.read_attribute(mproperty, recv)
                var res = v.callsite(reassign_callsite, [attr, value])
                assert res != null
-               assert recv isa MutableInstance
-               recv.attributes[mproperty] = res
+               v.write_attribute(mproperty, recv, res)
        end
 end