engines: no more `super_inits` method used in old-style automatic init
[nit.git] / src / interpreter / naive_interpreter.nit
index cd264f1..34fd8f1 100644 (file)
@@ -407,18 +407,24 @@ private class NaiveInterpreter
        do
                var initializers = callsite.mpropdef.initializers
                if not initializers.is_empty then
-                       assert initializers.length == arguments.length - 1 else debug("expected {initializers.length} got {arguments.length - 1}")
                        var recv = arguments.first
                        var i = 1
                        for p in initializers do
                                if p isa MMethod then
-                                       self.send(p, [recv, arguments[i]])
+                                       var args = [recv]
+                                       for x in p.intro.msignature.mparameters do
+                                               args.add arguments[i]
+                                               i += 1
+                                       end
+                                       self.send(p, args)
                                else if p isa MAttribute then
                                        assert recv isa MutableInstance
                                        recv.attributes[p] = arguments[i]
+                                       i += 1
                                else abort
-                               i += 1
                        end
+                       assert i == arguments.length
+
                        return send(callsite.mproperty, [recv])
                end
                return send(callsite.mproperty, arguments)
@@ -501,6 +507,10 @@ private class NaiveInterpreter
        do
                return mtype.anchor_to(self.mainmodule, self.frame.arguments.first.mtype.as(MClassType))
        end
+
+       # Placebo instance used to mark internal error result when `null` already have a meaning.
+       # TODO: replace with multiple return or something better
+       var error_instance = new MutableInstance(modelbuilder.model.null_type) is lazy
 end
 
 # An instance represents a value of the executed program.
@@ -671,14 +681,28 @@ redef class AMethPropdef
                        v.call_without_varargs(superpd, arguments)
                end
 
+               if mpropdef.is_intern or mpropdef.is_extern then
+                       var res = intern_call(v, mpropdef, arguments)
+                       if res != v.error_instance then return res
+               end
+
                if n_block != null then
                        v.stmt(self.n_block)
                        return null
+               end
+
+               if mpropdef.is_intern then
+                       fatal(v, "NOT YET IMPLEMENTED intern {mpropdef}")
+               else if mpropdef.is_extern then
+                       fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
                else
-                       return intern_call(v, mpropdef, arguments)
+                       fatal(v, "NOT YET IMPLEMENTED <wat?> {mpropdef}")
                end
+               abort
        end
 
+       # Interprets a intern or a shortcut extern method.
+       # Returns the result for a function, `null` for a procedure, or `error_instance` if the method is unknown.
        private fun intern_call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
        do
                var pname = mpropdef.mproperty.name
@@ -986,14 +1010,7 @@ redef class AMethPropdef
                else if pname == "address_is_null" then
                        return v.false_instance
                end
-               if mpropdef.is_intern then
-                       fatal(v, "NOT YET IMPLEMENTED intern {mpropdef}")
-               else if mpropdef.is_extern then
-                       fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
-               else
-                       fatal(v, "NOT YET IMPLEMENTED <wat?> {mpropdef}")
-               end
-               abort
+               return v.error_instance
        end
 end
 
@@ -1060,7 +1077,6 @@ redef class AClassdef
        private fun call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
        do
                if mpropdef.mproperty.is_root_init then
-                       assert self.super_inits == null
                        assert args.length == 1
                        if not mpropdef.is_intro then
                                # standard call-next-method
@@ -1068,27 +1084,9 @@ redef class AClassdef
                                v.call_without_varargs(superpd, args)
                        end
                        return null
+               else
+                       abort
                end
-
-               var super_inits = self.super_inits
-               if super_inits != null then
-                       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_of_super)
-                       end
-               end
-               var recv = args.first
-               assert recv isa MutableInstance
-               var i = 1
-               # Collect undefined attributes
-               for npropdef in self.n_propdefs do
-                       if npropdef isa AAttrPropdef and not npropdef.noinit and npropdef.n_expr == null then
-                               v.write_attribute(npropdef.mpropdef.mproperty, recv, args[i])
-                               i += 1
-                       end
-               end
-               return null
        end
 end