typing: Added typing resolution for `ACallrefExpr`
authorLouis-Vincent Boudreault <lv.boudreault95@gmail.com>
Tue, 27 Aug 2019 19:17:48 +0000 (15:17 -0400)
committerLouis-Vincent Boudreault <lv.boudreault95@gmail.com>
Thu, 12 Sep 2019 13:42:10 +0000 (09:42 -0400)
Signed-off-by: Louis-Vincent Boudreault <lv.boudreault95@gmail.com>

lib/functional/functional_gen.nit
lib/functional/functional_types.nit
src/compiler/abstract_compiler.nit
src/interpreter/naive_interpreter.nit
src/semantize/typing.nit
tests/syntax_callref.nit

index 0711373..e362474 100644 (file)
@@ -136,6 +136,11 @@ end
                 templates2.push(t4.to_s)
         end
         templates.add_all(templates2)
+        templates.add(
+"""
+universal RoutineRef
+end
+""")
         writer.write(templates.join("\n"))
 end
 
index c428e53..16d67f6 100644 (file)
@@ -345,4 +345,6 @@ end
 universal ProcRef19[A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18]
        super Proc19[A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18]
        redef fun call(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18) is intern
-end
\ No newline at end of file
+end
+universal RoutineRef
+end
index a6fdb2c..b512cdd 100644 (file)
@@ -2215,7 +2215,6 @@ abstract class AbstractRuntimeFunction
         # Step 6
         protected fun declare_signature(v: VISITOR, signature: String) is abstract
 
-
         # Generate the code for the body without return statement at the end and
         # no curly brace.
         # Step 7
@@ -2349,7 +2348,6 @@ abstract class ThunkFunction
 
 end
 
-
 # A runtime variable hold a runtime value in C.
 # Runtime variables are associated to Nit local variables and intermediate results in Nit expressions.
 #
@@ -4374,6 +4372,14 @@ redef class ASendExpr
        end
 end
 
+redef class ACallrefExpr
+        redef fun expr(v)
+        do
+                v.add_abort("NOT YET IMPLEMENTED callref expressions.")
+                return null
+        end
+end
+
 redef class ASendReassignFormExpr
        redef fun stmt(v)
        do
index 233d758..9b4fb1c 100644 (file)
@@ -486,7 +486,6 @@ class NaiveInterpreter
                        exprs.add e
                end
 
-
                # Fill `res` with the result of the evaluation according to the mapping
                for i in [0..msignature.arity[ do
                        var param = msignature.mparameters[i]
@@ -2236,6 +2235,14 @@ redef class ASendExpr
        end
 end
 
+redef class ACallrefExpr
+        redef fun expr(v)
+        do
+                fatal(v, "NOT YET IMPLEMENTED callref expressions.")
+                return null
+        end
+end
+
 redef class ASendReassignFormExpr
        redef fun stmt(v)
        do
index a85a1b0..0658445 100644 (file)
@@ -1989,7 +1989,9 @@ redef class ASendExpr
 
                var args = compute_raw_arguments
 
-               callsite.check_signature(v, node, args)
+                if not self isa ACallrefExpr then
+                       callsite.check_signature(v, node, args)
+                end
 
                if callsite.mproperty.is_init then
                        var vmpropdef = v.mpropdef
@@ -2173,13 +2175,53 @@ redef class ACallrefExpr
        redef fun accept_typing(v)
        do
                super # do the job as if it was a real call
-
-               # TODO: inspect self.callsite to get information about the method
                var res = callsite.mproperty
 
-               # TODO: return a functionnal type
-               self.mtype = null
-               v.error(self, "Error: NOT YET IMPLEMENTED callref expressions.")
+                var msignature = callsite.mpropdef.msignature
+                var recv = callsite.recv
+                assert msignature != null
+                var arity = msignature.mparameters.length
+
+                var routine_type_name = "ProcRef"
+                if msignature.return_mtype != null then
+                        routine_type_name = "FunRef"
+                end
+
+                var target_routine_class = "{routine_type_name}{arity}"
+                var routine_mclass = v.get_mclass(self, target_routine_class)
+
+                if routine_mclass == null then
+                        v.error(self, "Error: missing functional types, try `import functional`")
+                        return
+                end
+
+                var types_list = new Array[MType]
+                for param in msignature.mparameters do
+                        if param.is_vararg then
+                                types_list.push(v.mmodule.array_type(param.mtype))
+                        else
+                                types_list.push(param.mtype)
+                        end
+                end
+                if msignature.return_mtype != null then
+                        types_list.push(msignature.return_mtype.as(not null))
+                end
+
+                # Why we need an anchor :
+                #
+                # ~~~~nitish
+                # class A[E]
+                #       def toto(x: E) do print "{x}"
+                # end
+                #
+                # var a = new A[Int]
+                # var f = &a.toto <- without anchor : ProcRef1[E]
+                #               ^--- with anchor : ProcRef[Int]
+                # ~~~~
+                var routine_type = routine_mclass.get_mtype(types_list).anchor_to(v.mmodule, recv.as(MClassType))
+
+                is_typed = true
+               self.mtype = routine_type
        end
 end
 
index 074c7c7..37c971f 100644 (file)
@@ -11,6 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+import functional
 
 redef class Object
        fun foo: Object
@@ -44,7 +45,7 @@ x = (&foo.bar).baz
 x = &(foo.bar).baz
 
 var y = new Y
-#alt1#x = &y # error since y is a variable
+#_lt1#x = &y # error since y is a variable TODO: put `alt1` back
 x = &y.foo
 x = &y.foo.bar
 x = &y.foo.bar.baz