syntax: allow untyped variable declaration
[nit.git] / src / syntax / control_flow.nit
index 44d1270..dd3ca06 100644 (file)
@@ -36,6 +36,10 @@ abstract class VariableContext
        # Register a new variable with its name
        fun add(v: Variable)
        do
+               var old_var = self[v.name]
+               if old_var != null then
+                       _visitor.error(v.decl, "Error: '{v}' already defined at {old_var.decl.location.relative_to(v.decl.location)}.")
+               end
                _dico[v.name] = v
                _all_variables.add(v)
        end
@@ -45,20 +49,12 @@ abstract class VariableContext
                _set_variables.add(v)
        end
 
-       fun check_is_set(n: PNode, v: Variable)
+       fun check_is_set(n: ANode, v: Variable)
        do
                if v.must_be_set and not is_set(v) then
                        _visitor.error(n, "Error: variable '{v}' is possibly unset.")
-                       var x = self
-                       while true do
-                               print "  {x.node.locate}: {x._set_variables.join(", ")} ; {x._dico.join(", ")}"
-                               var x0 = x
-                               if x0 isa SubVariableContext then
-                                       x = x0.prev
-                               else
-                                       break
-                               end
-                       end
+               else if v.is_typed and stype(v) == null then
+                       _visitor.error(n, "Error: variable '{v}' is untyped.")
                end
        end
 
@@ -90,13 +86,13 @@ abstract class VariableContext
        var _stypes: Map[Variable, nullable MMType] = new HashMap[Variable, nullable MMType]
 
        # Build a new VariableContext
-       fun sub(node: PNode): SubVariableContext
+       fun sub(node: ANode): SubVariableContext
        do
                return new SubVariableContext.with_prev(self, node)
        end
 
        # Build a nested VariableContext with new variable information
-       fun sub_with(node: PNode, v: Variable, t: MMType): SubVariableContext
+       fun sub_with(node: ANode, v: Variable, t: MMType): SubVariableContext
        do
                var ctx = sub(node)
                ctx.stype(v) = t
@@ -107,9 +103,9 @@ abstract class VariableContext
        var _visitor: AbsSyntaxVisitor
 
        # The syntax node that introduced the context
-       readable var _node: PNode
+       readable var _node: ANode
 
-       init(visitor: AbsSyntaxVisitor, node: PNode)
+       init(visitor: AbsSyntaxVisitor, node: ANode)
        do
                _visitor = visitor
                _node = node
@@ -183,7 +179,7 @@ abstract class VariableContext
        redef fun to_s
        do
                var s = new Buffer
-               s.append(node.locate)
+               s.append(node.location.to_s)
                for v in _all_variables do
                        var t = stype(v)
                        if t == null then continue
@@ -195,7 +191,7 @@ end
 
 class RootVariableContext
 special VariableContext
-       init(visitor: AbsSyntaxVisitor, node: PNode)
+       init(visitor: AbsSyntaxVisitor, node: ANode)
        do
                super(visitor, node)
                _all_variables = new HashSet[Variable]
@@ -224,7 +220,7 @@ special VariableContext
                end
        end
 
-       init with_prev(p: VariableContext, node: PNode)
+       init with_prev(p: VariableContext, node: ANode)
        do
                init(p._visitor, node)
                _prev = p