syntax: new method check_conform_multiexpr
authorJean Privat <jean@pryen.org>
Fri, 12 Jun 2009 01:58:40 +0000 (21:58 -0400)
committerJean Privat <jean@pryen.org>
Wed, 24 Jun 2009 19:47:30 +0000 (15:47 -0400)
This method is used to check conformance among multiple expressions.
It is used to factorize code between AIfexprExpr, AArrayExpr and process_closure.
Tests are also updated to use the new error messages.

Signed-off-by: Jean Privat <jean@pryen.org>

src/syntax/syntax_base.nit
src/syntax/typing.nit
tests/sav/base_array_alt1.sav
tests/sav/base_closure5_alt2.sav
tests/sav/base_closure6.sav
tests/sav/base_closure6_alt1.sav
tests/sav/base_if_expr_alt1.sav
tests/sav/error_array_ambig.sav

index 977be5b..e7311a8 100644 (file)
@@ -388,6 +388,37 @@ special Visitor
                if check_expr(n) then return check_conform(n, n.stype, stype) else return false
        end
 
+       # Check conformance between multiple expressions and a static type
+       # Conformance is granted if among them there is a most general type
+       # Return the most general type if a conformance is found
+       # Display an error and return null if no conformance is found
+       # @param stype is a possible additional type (without node)
+       # Examples:
+       #   Int, Int, Object => return Object
+       #   Int, Float => display error, return null
+       meth check_conform_multiexpr(stype: MMType, nodes: Collection[PExpr]): MMType
+       do
+               var node: PExpr = null # candidate node
+               for n in nodes do
+                       if not check_expr(n) then return null
+                       var ntype = n.stype
+                       if stype == null or (ntype != null and stype < ntype) then
+                               stype = ntype
+                               node = n
+                       end
+               end
+               for n in nodes do
+                       if not n.stype < stype then
+                               if node == null then
+                                       error(n, "Type error: no most general type. Got {n.stype} and {stype}.")
+                               else
+                                       error(n, "Type error: no most general type. Got {n.stype} and {stype} at {node.locate}.")
+                               end
+                               return null
+                       end
+               end
+               return stype
+       end
 
        protected init(tc: ToolContext, module: MMSrcModule)
        do
index d8ca9de..aa3581c 100644 (file)
@@ -617,18 +617,7 @@ redef class AIfexprExpr
 
                v.check_conform_expr(n_expr, v.type_bool)
 
-               if not v.check_expr(n_then) or not v.check_expr(n_else) then return
-
-               var t = n_then.stype
-               var te = n_else.stype
-               if t < te then
-                       t = te
-               else if not te < t then
-                       v.error(self, "Type error: {te} is not a subtype of {t}.")
-                       return
-               end
-               
-               _stype = t
+               _stype = v.check_conform_multiexpr(null, [n_then, n_else])
        end
 end
 
@@ -742,16 +731,8 @@ redef class AArrayExpr
 
        redef meth after_typing(v)
        do
-               var stype: MMType = null
-               for n in n_exprs do
-                       var ntype = n.stype
-                       if stype == null or (ntype != null and stype < ntype) then
-                               stype = ntype
-                       end
-               end
-               for n in n_exprs do
-                       v.check_conform_expr(n, stype)
-               end
+               var stype = v.check_conform_multiexpr(null, n_exprs)
+               if stype == null then return
                do_typing(v, stype)
        end
 
@@ -1053,15 +1034,7 @@ special PExpr
 
                                # Check break type conformity
                                if break_list != null then
-                                       for n in break_list do
-                                               var ntype = n.stype
-                                               if t == null or (t != null and t < ntype) then
-                                                       t = ntype
-                                               end
-                                       end
-                                       for n in break_list do
-                                               v.check_conform_expr(n, t)
-                                       end
+                                       t = v.check_conform_multiexpr(t, break_list)
                                end
                        end
                else if min_arity != 0 then
index 225cbcb..26d2566 100644 (file)
@@ -1 +1 @@
-alt/base_array_alt1.nit:27,15--18: Type error: expected Int, got Bool
+alt/base_array_alt1.nit:27,15--18: Type error: no most general type. Got Bool and Int at alt/base_array_alt1.nit:27,11--12.
index 89f09a2..e875438 100644 (file)
@@ -1 +1 @@
-alt/base_closure5_alt2.nit:36,9--11: Type error: expected Int, got Char
+alt/base_closure5_alt2.nit:36,9--11: Type error: no most general type. Got Char and Int.
index 8608be2..2bb3eee 100644 (file)
@@ -1,2 +1,2 @@
-./base_closure6.nit:55,25--25: Type error: expected U, got V
-./base_closure6.nit:65,8--8: Type error: expected U, got V
+./base_closure6.nit:55,25--25: Type error: no most general type. Got V and U.
+./base_closure6.nit:65,8--8: Type error: no most general type. Got V and U at ./base_closure6.nit:64,8--8.
index 7098be8..12ab6ff 100644 (file)
@@ -1,4 +1,4 @@
 alt/base_closure6_alt1.nit:53,5--25: Type error: expected U, got T
-alt/base_closure6_alt1.nit:55,25--25: Type error: expected U, got V
+alt/base_closure6_alt1.nit:55,25--25: Type error: no most general type. Got V and U.
 alt/base_closure6_alt1.nit:57,5--61:8: Type error: expected U, got T
-alt/base_closure6_alt1.nit:65,8--8: Type error: expected U, got V
+alt/base_closure6_alt1.nit:65,8--8: Type error: no most general type. Got V and U at alt/base_closure6_alt1.nit:64,8--8.
index 522294d..a2aa7e9 100644 (file)
@@ -1 +1 @@
-alt/base_if_expr_alt1.nit:39,11--35: Type error: Int is not a subtype of A.
+alt/base_if_expr_alt1.nit:39,35--35: Type error: no most general type. Got Int and A at alt/base_if_expr_alt1.nit:39,24--28.
index 950150d..e06ed05 100644 (file)
@@ -1 +1 @@
-./error_array_ambig.nit:17,13--15: Type error: expected Int, got Char
+./error_array_ambig.nit:17,13--15: Type error: no most general type. Got Char and Int at ./error_array_ambig.nit:17,10--10.