src: cleanup importations
[nit.git] / src / naive_interpreter.nit
index a579aa2..291f222 100644 (file)
 module naive_interpreter
 
 import literal
-import typing
-import auto_super_init
-import frontend
 import common_ffi
+import semantize
+private import parser::tables
 
 redef class ToolContext
        # --discover-call-trace
@@ -63,7 +62,8 @@ redef class ModelBuilder
                if initprop != null then
                        interpreter.send(initprop, [mainobj])
                end
-               var mainprop = mainmodule.try_get_primitive_method("main", sys_type.mclass)
+               var mainprop = mainmodule.try_get_primitive_method("run", sys_type.mclass) or else
+                       mainmodule.try_get_primitive_method("main", sys_type.mclass)
                if mainprop != null then
                        interpreter.send(mainprop, [mainobj])
                end
@@ -406,6 +406,22 @@ private class NaiveInterpreter
        # Use this method, instead of `send` to execute and control the aditionnal behavior of the call-sites
        fun callsite(callsite: nullable CallSite, arguments: Array[Instance]): nullable Instance
        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]])
+                               else if p isa MAttribute then
+                                       assert recv isa MutableInstance
+                                       recv.attributes[p] = arguments[i]
+                               else abort
+                               i += 1
+                       end
+                       return send(callsite.mproperty, [recv])
+               end
                return send(callsite.mproperty, arguments)
        end
 
@@ -434,6 +450,20 @@ 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
+
+       # Is the attribute `mproperty` initialized the instance `recv`?
+       fun isset_attribute(mproperty: MAttribute, recv: Instance): Bool
+       do
+               assert recv isa MutableInstance
+               return recv.attributes.has_key(mproperty)
+       end
+
        # Collect attributes of a type in the order of their init
        fun collect_attr_propdef(mtype: MType): Array[AAttrPropdef]
        do
@@ -632,9 +662,15 @@ redef class AMethPropdef
                                for i in [0..auto_super_init.msignature.arity+1[ do
                                        args.add(arguments[i])
                                end
+                               assert auto_super_init.mproperty != mpropdef.mproperty
                                v.callsite(auto_super_init, args)
                        end
                end
+               if auto_super_call then
+                       # standard call-next-method
+                       var superpd = mpropdef.lookup_next_definition(v.mainmodule, arguments.first.mtype)
+                       v.call_without_varargs(superpd, arguments)
+               end
 
                if n_block != null then
                        v.stmt(self.n_block)
@@ -975,42 +1011,66 @@ redef class AAttrPropdef
                var recv = args.first
                assert recv isa MutableInstance
                var attr = self.mpropdef.mproperty
-               if args.length == 1 then
-                       return v.read_attribute(attr, recv)
-               else
+               if mpropdef == mreadpropdef then
+                       assert args.length == 1
+                       if not is_lazy or v.isset_attribute(attr, recv) then return v.read_attribute(attr, recv)
+                       return evaluate_expr(v, recv)
+               else if mpropdef == mwritepropdef then
                        assert args.length == 2
-                       recv.attributes[attr] = args[1]
+                       v.write_attribute(attr, recv, args[1])
                        return null
+               else
+                       abort
                end
        end
 
        # Evaluate and set the default value of the attribute in `recv`
        private fun init_expr(v: NaiveInterpreter, recv: Instance)
        do
-               assert recv isa MutableInstance
+               if is_lazy then return
                var nexpr = self.n_expr
                if nexpr != null then
-                       var f = new Frame(self, self.mpropdef.as(not null), [recv])
-                       v.frames.unshift(f)
-                       var val = v.expr(nexpr)
-                       assert val != null
-                       v.frames.shift
-                       assert not v.is_escaping
-                       recv.attributes[self.mpropdef.mproperty] = val
+                       evaluate_expr(v, recv)
                        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
+
+       private fun evaluate_expr(v: NaiveInterpreter, recv: Instance): Instance
+       do
+               assert recv isa MutableInstance
+               var nexpr = self.n_expr
+               assert nexpr != null
+               var f = new Frame(self, self.mpropdef.as(not null), [recv])
+               v.frames.unshift(f)
+               var val = v.expr(nexpr)
+               assert val != null
+               v.frames.shift
+               assert not v.is_escaping
+               v.write_attribute(self.mpropdef.mproperty, recv, val)
+               return val
+       end
 end
 
 redef class AClassdef
        # Execute an implicit `mpropdef` associated with the current node.
        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
+                               var superpd = mpropdef.lookup_next_definition(v.mainmodule, args.first.mtype)
+                               v.call_without_varargs(superpd, args)
+                       end
+                       return null
+               end
+
                var super_inits = self.super_inits
                if super_inits != null then
                        var args_of_super = args
@@ -1024,8 +1084,8 @@ redef class AClassdef
                var i = 1
                # 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]
+                       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
@@ -1521,7 +1581,7 @@ redef class ASendExpr
                var recv = v.expr(self.n_expr)
                if recv == null then return null
                var args = [recv]
-               for a in self.raw_arguments.as(not null) do
+               for a in self.raw_arguments do
                        var i = v.expr(a)
                        if i == null then return null
                        args.add(i)
@@ -1538,7 +1598,7 @@ redef class ASendReassignFormExpr
                var recv = v.expr(self.n_expr)
                if recv == null then return
                var args = [recv]
-               for a in self.raw_arguments.as(not null) do
+               for a in self.raw_arguments do
                        var i = v.expr(a)
                        if i == null then return
                        args.add(i)
@@ -1635,8 +1695,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
 
@@ -1652,8 +1711,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
 
@@ -1664,8 +1722,7 @@ redef class AIssetAttrExpr
                if recv == null then return null
                if recv.mtype isa MNullType then fatal(v, "Receiver is null")
                var mproperty = self.mproperty.as(not null)
-               assert recv isa MutableInstance
-               return v.bool_instance(recv.attributes.has_key(mproperty))
+               return v.bool_instance(v.isset_attribute(mproperty, recv))
        end
 end