typing+engines: handle reverse-vararg: passing an array as-is.
authorJean Privat <jean@pryen.org>
Wed, 15 Oct 2014 14:46:39 +0000 (10:46 -0400)
committerJean Privat <jean@pryen.org>
Fri, 17 Oct 2014 00:17:38 +0000 (20:17 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/compiler/abstract_compiler.nit
src/interpreter/naive_interpreter.nit
src/semantize/typing.nit

index e83739d..8ddd662 100644 (file)
@@ -1105,6 +1105,12 @@ abstract class AbstractCompilerVisitor
 
                for i in [0..msignature.arity[ do
                        if i == vararg_rank then
+                               var ne = args[i]
+                               if ne isa AVarargExpr then
+                                       var e = self.expr(ne.n_expr, null)
+                                       res.add(e)
+                                       continue
+                               end
                                var vararg = new Array[RuntimeVariable]
                                for j in [vararg_rank..vararg_rank+vararg_len] do
                                        var e = self.expr(args[j], null)
index 21e7cf5..7ee3ff7 100644 (file)
@@ -354,6 +354,13 @@ class NaiveInterpreter
 
                for i in [0..msignature.arity[ do
                        if i == vararg_rank then
+                               var ne = args[i]
+                               if ne isa AVarargExpr then
+                                       var e = self.expr(ne.n_expr)
+                                       if e == null then return null
+                                       res.add(e)
+                                       continue
+                               end
                                var vararg = new Array[Instance]
                                for j in [vararg_rank..vararg_rank+vararg_len] do
                                        var e = self.expr(args[j])
index d5ff672..8369a10 100644 (file)
@@ -377,11 +377,18 @@ private class TypeVisitor
                        self.visit_expr_subtype(args[j], paramtype)
                end
                if vararg_rank >= 0 then
-                       var varargs = new Array[AExpr]
                        var paramtype = msignature.mparameters[vararg_rank].mtype
-                       for j in [vararg_rank..vararg_rank+vararg_decl] do
-                               varargs.add(args[j])
-                               self.visit_expr_subtype(args[j], paramtype)
+                       var first = args[vararg_rank]
+                       if vararg_decl == 0 and first isa AVarargExpr then
+                               var mclass = get_mclass(node, "Array")
+                               if mclass == null then return false # Forward error
+                               var array_mtype = mclass.get_mtype([paramtype])
+                               self.visit_expr_subtype(first.n_expr, array_mtype)
+                               first.mtype  = first.n_expr.mtype
+                       else
+                               for j in [vararg_rank..vararg_rank+vararg_decl] do
+                                       self.visit_expr_subtype(args[j], paramtype)
+                               end
                        end
                end
                return true
@@ -1778,6 +1785,16 @@ redef class AIssetAttrExpr
        end
 end
 
+redef class AVarargExpr
+       redef fun accept_typing(v)
+       do
+               # This kind of pseudo-expression can be only processed trough a signature
+               # See `check_signature`
+               # Other cases are a syntax error.
+               v.error(self, "Syntax error: unexpected `...`")
+       end
+end
+
 ###
 
 redef class ADebugTypeExpr