From: Jean Privat Date: Fri, 12 Jun 2009 01:58:40 +0000 (-0400) Subject: syntax: new method check_conform_multiexpr X-Git-Tag: v0.3~271 X-Git-Url: http://nitlanguage.org syntax: new method check_conform_multiexpr 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 --- diff --git a/src/syntax/syntax_base.nit b/src/syntax/syntax_base.nit index 977be5b..e7311a8 100644 --- a/src/syntax/syntax_base.nit +++ b/src/syntax/syntax_base.nit @@ -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 diff --git a/src/syntax/typing.nit b/src/syntax/typing.nit index d8ca9de..aa3581c 100644 --- a/src/syntax/typing.nit +++ b/src/syntax/typing.nit @@ -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 diff --git a/tests/sav/base_array_alt1.sav b/tests/sav/base_array_alt1.sav index 225cbcb..26d2566 100644 --- a/tests/sav/base_array_alt1.sav +++ b/tests/sav/base_array_alt1.sav @@ -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. diff --git a/tests/sav/base_closure5_alt2.sav b/tests/sav/base_closure5_alt2.sav index 89f09a2..e875438 100644 --- a/tests/sav/base_closure5_alt2.sav +++ b/tests/sav/base_closure5_alt2.sav @@ -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. diff --git a/tests/sav/base_closure6.sav b/tests/sav/base_closure6.sav index 8608be2..2bb3eee 100644 --- a/tests/sav/base_closure6.sav +++ b/tests/sav/base_closure6.sav @@ -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. diff --git a/tests/sav/base_closure6_alt1.sav b/tests/sav/base_closure6_alt1.sav index 7098be8..12ab6ff 100644 --- a/tests/sav/base_closure6_alt1.sav +++ b/tests/sav/base_closure6_alt1.sav @@ -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. diff --git a/tests/sav/base_if_expr_alt1.sav b/tests/sav/base_if_expr_alt1.sav index 522294d..a2aa7e9 100644 --- a/tests/sav/base_if_expr_alt1.sav +++ b/tests/sav/base_if_expr_alt1.sav @@ -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. diff --git a/tests/sav/error_array_ambig.sav b/tests/sav/error_array_ambig.sav index 950150d..e06ed05 100644 --- a/tests/sav/error_array_ambig.sav +++ b/tests/sav/error_array_ambig.sav @@ -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.