From 802e1261064ec8ad91c3ba73e3565d0871336f7a Mon Sep 17 00:00:00 2001 From: Louis-Vincent Boudreault Date: Tue, 27 Aug 2019 15:17:48 -0400 Subject: [PATCH] typing: Added typing resolution for `ACallrefExpr` Signed-off-by: Louis-Vincent Boudreault --- lib/functional/functional_gen.nit | 5 +++ lib/functional/functional_types.nit | 4 ++- src/compiler/abstract_compiler.nit | 10 ++++-- src/interpreter/naive_interpreter.nit | 9 +++++- src/semantize/typing.nit | 54 +++++++++++++++++++++++++++++---- tests/syntax_callref.nit | 3 +- 6 files changed, 74 insertions(+), 11 deletions(-) diff --git a/lib/functional/functional_gen.nit b/lib/functional/functional_gen.nit index 0711373..e362474 100644 --- a/lib/functional/functional_gen.nit +++ b/lib/functional/functional_gen.nit @@ -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 diff --git a/lib/functional/functional_types.nit b/lib/functional/functional_types.nit index c428e53..16d67f6 100644 --- a/lib/functional/functional_types.nit +++ b/lib/functional/functional_types.nit @@ -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 diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index a6fdb2c..b512cdd 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -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 diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index 233d758..9b4fb1c 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -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 diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index a85a1b0..0658445 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -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 diff --git a/tests/syntax_callref.nit b/tests/syntax_callref.nit index 074c7c7..37c971f 100644 --- a/tests/syntax_callref.nit +++ b/tests/syntax_callref.nit @@ -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 -- 1.7.9.5