From 220823e713cef8915241679a614fbfb53ddaece0 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Wed, 19 Aug 2009 22:29:55 -0400 Subject: [PATCH] syntax: allow untyped variable declaration It means there is now a distinction between variables with a null static type because of a previous error and untyped variables that also have null static type. So introduce Variable::is_typed. Enhance check_is_set with untyped variable verification. Compile untyped variable as 'nullable Object' registers. Signed-off-by: Jean Privat --- src/syntax/control_flow.nit | 2 ++ src/syntax/icode_generation.nit | 4 ++- src/syntax/syntax_base.nit | 7 ++++- src/syntax/typing.nit | 15 ++++++--- tests/base_var_untyped.nit | 58 +++++++++++++++++++++++++++++++++++ tests/sav/base_var_untyped.sav | 5 +++ tests/sav/base_var_untyped_alt1.sav | 1 + tests/sav/base_var_untyped_alt2.sav | 1 + tests/sav/base_var_untyped_alt3.sav | 1 + tests/sav/base_var_untyped_alt4.sav | 1 + tests/sav/base_var_untyped_alt5.sav | 1 + tests/sav/base_var_untyped_alt6.sav | 1 + tests/sav/base_var_untyped_alt7.sav | 1 + tests/sav/base_var_untyped_alt8.sav | 2 ++ 14 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 tests/base_var_untyped.nit create mode 100644 tests/sav/base_var_untyped.sav create mode 100644 tests/sav/base_var_untyped_alt1.sav create mode 100644 tests/sav/base_var_untyped_alt2.sav create mode 100644 tests/sav/base_var_untyped_alt3.sav create mode 100644 tests/sav/base_var_untyped_alt4.sav create mode 100644 tests/sav/base_var_untyped_alt5.sav create mode 100644 tests/sav/base_var_untyped_alt6.sav create mode 100644 tests/sav/base_var_untyped_alt7.sav create mode 100644 tests/sav/base_var_untyped_alt8.sav diff --git a/src/syntax/control_flow.nit b/src/syntax/control_flow.nit index 4b8d0fc..dd3ca06 100644 --- a/src/syntax/control_flow.nit +++ b/src/syntax/control_flow.nit @@ -53,6 +53,8 @@ abstract class VariableContext do if v.must_be_set and not is_set(v) then _visitor.error(n, "Error: variable '{v}' is possibly unset.") + else if v.is_typed and stype(v) == null then + _visitor.error(n, "Error: variable '{v}' is untyped.") end end diff --git a/src/syntax/icode_generation.nit b/src/syntax/icode_generation.nit index fab9e98..fb4a801 100644 --- a/src/syntax/icode_generation.nit +++ b/src/syntax/icode_generation.nit @@ -58,7 +58,9 @@ special ICodeBuilder if _variables.has_key(v) then return _variables[v] else - var reg = new_register(v.stype.as(not null)) + var t = v.stype + if t == null then t = visitor.type_object.as_nullable + var reg = new_register(t) _variables[v] = reg return reg end diff --git a/src/syntax/syntax_base.nit b/src/syntax/syntax_base.nit index 512ccf4..13e1372 100644 --- a/src/syntax/syntax_base.nit +++ b/src/syntax/syntax_base.nit @@ -229,7 +229,12 @@ abstract class Variable # Declaration AST node readable var _decl: nullable ANode - # Static type + # Is the variable correcly declared + # Return false if typed was not yet computed or + # if an error occured during the typing computation + fun is_typed: Bool do return _stype != null + + # The declaration static type of the variable readable writable var _stype: nullable MMType redef fun to_s do return _name.to_s diff --git a/src/syntax/typing.nit b/src/syntax/typing.nit index fb4c838..c3a5ffc 100644 --- a/src/syntax/typing.nit +++ b/src/syntax/typing.nit @@ -136,6 +136,9 @@ special AbsSyntaxVisitor end end +redef class VarVariable + redef readable var _is_typed: Bool = false +end ############################################################################### @@ -353,18 +356,20 @@ redef class AVardeclExpr var va = new VarVariable(n_id.to_symbol, n_id) _variable = va v.variable_ctx.add(va) - if n_expr != null then v.variable_ctx.mark_is_set(va) + var ne = n_expr + if ne != null then v.variable_ctx.mark_is_set(va) if n_type != null then if not n_type.is_typed then return va.stype = n_type.stype - if n_expr != null then - v.check_conform_expr(n_expr.as(not null), va.stype) + if ne != null then + v.check_conform_expr(ne, va.stype) end - else - if not v.check_expr(n_expr.as(not null)) then return + else if ne != null then + if not v.check_expr(ne) then return va.stype = n_expr.stype end + va._is_typed = true _is_typed = true end end diff --git a/tests/base_var_untyped.nit b/tests/base_var_untyped.nit new file mode 100644 index 0000000..e7a4a6a --- /dev/null +++ b/tests/base_var_untyped.nit @@ -0,0 +1,58 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2009 Jean Privat +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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 kernel + +fun rand: Bool do return true + +var a +#alt1#a.output +a = 1 +(a*10).output +a = 2 +(a*10).output +a = false +(not a).output + +var b1 +var b2 +var b3 +if rand then + b1 = 3 + b2 = 4 + b3 = 5 +else + b1 = -3 + b2 = true +end +(b1*10).output +#alt2#b2.output +#alt3#b3.output +#alt4#b2 += 1 + +var c +while rand do + c = 4 + #alt5#c = b2 + #alt6#c = b3 + (c*10).output + if rand then break +end +#alt7#c.output + +var d +#alt8#d = fail +#alt8#d.output diff --git a/tests/sav/base_var_untyped.sav b/tests/sav/base_var_untyped.sav new file mode 100644 index 0000000..ed4f859 --- /dev/null +++ b/tests/sav/base_var_untyped.sav @@ -0,0 +1,5 @@ +10 +20 +true +30 +40 diff --git a/tests/sav/base_var_untyped_alt1.sav b/tests/sav/base_var_untyped_alt1.sav new file mode 100644 index 0000000..6ec044f --- /dev/null +++ b/tests/sav/base_var_untyped_alt1.sav @@ -0,0 +1 @@ +alt/base_var_untyped_alt1.nit:22,1: Error: variable 'a' is possibly unset. diff --git a/tests/sav/base_var_untyped_alt2.sav b/tests/sav/base_var_untyped_alt2.sav new file mode 100644 index 0000000..a5c54ef --- /dev/null +++ b/tests/sav/base_var_untyped_alt2.sav @@ -0,0 +1 @@ +alt/base_var_untyped_alt2.nit:42,1--2: Error: variable 'b2' is untyped. diff --git a/tests/sav/base_var_untyped_alt3.sav b/tests/sav/base_var_untyped_alt3.sav new file mode 100644 index 0000000..dc1fe07 --- /dev/null +++ b/tests/sav/base_var_untyped_alt3.sav @@ -0,0 +1 @@ +alt/base_var_untyped_alt3.nit:43,1--2: Error: variable 'b3' is possibly unset. diff --git a/tests/sav/base_var_untyped_alt4.sav b/tests/sav/base_var_untyped_alt4.sav new file mode 100644 index 0000000..a18278f --- /dev/null +++ b/tests/sav/base_var_untyped_alt4.sav @@ -0,0 +1 @@ +alt/base_var_untyped_alt4.nit:44,1--7: Error: variable 'b2' is untyped. diff --git a/tests/sav/base_var_untyped_alt5.sav b/tests/sav/base_var_untyped_alt5.sav new file mode 100644 index 0000000..892ac1b --- /dev/null +++ b/tests/sav/base_var_untyped_alt5.sav @@ -0,0 +1 @@ +alt/base_var_untyped_alt5.nit:49,6--7: Error: variable 'b2' is untyped. diff --git a/tests/sav/base_var_untyped_alt6.sav b/tests/sav/base_var_untyped_alt6.sav new file mode 100644 index 0000000..798387e --- /dev/null +++ b/tests/sav/base_var_untyped_alt6.sav @@ -0,0 +1 @@ +alt/base_var_untyped_alt6.nit:50,6--7: Error: variable 'b3' is possibly unset. diff --git a/tests/sav/base_var_untyped_alt7.sav b/tests/sav/base_var_untyped_alt7.sav new file mode 100644 index 0000000..d5c703d --- /dev/null +++ b/tests/sav/base_var_untyped_alt7.sav @@ -0,0 +1 @@ +alt/base_var_untyped_alt7.nit:54,1: Error: variable 'c' is possibly unset. diff --git a/tests/sav/base_var_untyped_alt8.sav b/tests/sav/base_var_untyped_alt8.sav new file mode 100644 index 0000000..b4cd0ba --- /dev/null +++ b/tests/sav/base_var_untyped_alt8.sav @@ -0,0 +1,2 @@ +alt/base_var_untyped_alt8.nit:57,5--8: Error: Method or variable 'fail' unknown in Sys. +alt/base_var_untyped_alt8.nit:58,1: Error: variable 'd' is untyped. -- 1.7.9.5