syntax: Move VariableContext and related to a new control_flow.nit
authorJean Privat <jean@pryen.org>
Fri, 19 Jun 2009 06:03:54 +0000 (02:03 -0400)
committerJean Privat <jean@pryen.org>
Wed, 24 Jun 2009 19:47:48 +0000 (15:47 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/syntax/control_flow.nit [new file with mode: 0644]
src/syntax/typing.nit

diff --git a/src/syntax/control_flow.nit b/src/syntax/control_flow.nit
new file mode 100644 (file)
index 0000000..ceadd4e
--- /dev/null
@@ -0,0 +1,218 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2008-2009 Jean Privat <jean@pryen.org>
+#
+# 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.
+
+# Analysis control flow and variable visibility in property bodies, statements and expressions
+package control_flow
+
+import syntax_base
+
+# Associate symbols to variable and variables to type
+# Can be nested
+abstract class VariableContext
+       # Look for the variable from its name
+       # Return null if nothing found
+       meth [](s: Symbol): Variable
+       do
+               if _dico.has_key(s) then
+                       return _dico[s]
+               else
+                       return null
+               end
+       end
+
+       # Register a new variable with its name
+       meth add(v: Variable)
+       do
+               _dico[v.name] = v
+               _all_variables.add(v)
+       end
+
+       meth mark_is_set(v: Variable)
+       do
+               _set_variables.add(v)
+       end
+
+       meth check_is_set(n: PNode, 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
+               end
+       end
+
+       # The effective static type of a given variable
+       # May be different from the declaration static type
+       meth stype(v: Variable): MMType
+       do
+               return v.stype
+       end
+
+       # Variables by name (in the current context only)
+       attr _dico: Map[Symbol, Variable]
+
+       # All variables in all contextes
+       attr _all_variables: Set[Variable]
+
+       # Build a new VariableContext
+       meth sub(node: PNode): SubVariableContext
+       do
+               return new SubVariableContext.with_prev(self, node)
+       end
+
+       # Build a nested VariableContext with new variable information
+       meth sub_with(node: PNode, v: Variable, t: MMType): SubVariableContext
+       do
+               return new CastVariableContext.with_prev(self, node, v, t)
+       end
+
+       # The visitor of the context (used to display error)
+       attr _visitor: AbsSyntaxVisitor
+
+       # The syntax node that introduced the context
+       readable attr _node: PNode
+
+       init(visitor: AbsSyntaxVisitor, node: PNode)
+       do
+               _visitor = visitor
+               _node = node
+               _dico = new HashMap[Symbol, Variable]
+       end
+
+       # Is a control flow break met? (return, break, continue)
+       readable writable attr _unreash: Bool = false
+
+       # Is a control flow already broken?
+       # Used to avoid repeating the same error message
+       readable writable attr _already_unreash: Bool = false
+
+       # Set of variable that are set (assigned)
+       readable attr _set_variables: HashSet[Variable] = new HashSet[Variable]
+
+       # Is a variable set?
+       meth is_set(v: Variable): Bool
+       do
+               return _set_variables.has(v)
+       end
+
+       # Merge back one flow context information
+       meth merge(ctx: VariableContext)
+       do
+               if ctx.unreash then
+                       unreash = true
+                       if ctx.already_unreash then already_unreash = true
+                       return
+               end
+               for v in _all_variables do
+                       if not is_set(v) and ctx.is_set(v) then
+                               mark_is_set(v)
+                       end
+               end
+       end
+
+       # Merge back two alternative flow context informations
+       meth merge2(ctx1, ctx2: VariableContext)
+       do
+               if ctx1.unreash then
+                       merge(ctx2)
+               else if ctx2.unreash then
+                       merge(ctx1)
+               end
+               for v in _all_variables do
+                       if not is_set(v) and ctx1.is_set(v) and ctx2.is_set(v) then
+                               mark_is_set(v)
+                       end
+               end
+       end
+end
+
+class RootVariableContext
+special VariableContext
+       init(visitor: AbsSyntaxVisitor, node: PNode)
+       do
+               super(visitor, node)
+               _all_variables = new HashSet[Variable]
+       end
+end
+
+class SubVariableContext
+special VariableContext
+       readable attr _prev: VariableContext
+
+       redef meth [](s)
+       do
+               if _dico.has_key(s) then
+                       return _dico[s]
+               else
+                       return prev[s]
+               end
+       end
+
+       redef meth stype(v)
+       do
+               return prev.stype(v)
+       end
+
+       init with_prev(p: VariableContext, node: PNode)
+       do
+               init(p._visitor, node)
+               _prev = p
+               _all_variables = p._all_variables
+       end
+
+       redef meth is_set(v)
+       do
+               return _set_variables.has(v) or _prev.is_set(v)
+       end
+end
+
+class CastVariableContext
+special SubVariableContext
+       attr _variable: Variable
+       attr _var_type: MMType
+
+       redef meth stype(v)
+       do
+               if _variable == v then
+                       return _var_type
+               end
+               return prev.stype(v)
+       end
+
+       init with_prev(p: VariableContext, node: PNode, v: Variable, t: MMType)
+       do
+               super(p, node)
+               _variable = v
+               _var_type =t
+       end
+end
+
+redef class Variable
+       # Is the variable must be set before being used ?
+       meth must_be_set: Bool do return false
+end
+
+redef class VarVariable
+       redef meth must_be_set do return true
+end
index ee2eb0a..721c76b 100644 (file)
@@ -19,6 +19,7 @@ package typing
 
 import syntax_base
 import escape
+import control_flow
 
 redef class MMSrcModule
        # Walk trough the module and type statments and expressions
@@ -124,204 +125,6 @@ special AbsSyntaxVisitor
        end
 end
 
-# Associate symbols to variable and variables to type
-# Can be nested
-abstract class VariableContext
-       # Look for the variable from its name
-       # Return null if nothing found
-       meth [](s: Symbol): Variable
-       do
-               if _dico.has_key(s) then
-                       return _dico[s]
-               else
-                       return null
-               end
-       end
-
-       # Register a new variable with its name
-       meth add(v: Variable)
-       do
-               _dico[v.name] = v
-               _all_variables.add(v)
-       end
-
-       meth mark_is_set(v: Variable)
-       do
-               _set_variables.add(v)
-       end
-
-       meth check_is_set(n: PNode, 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
-               end
-       end
-
-       # The effective static type of a given variable
-       # May be different from the declaration static type
-       meth stype(v: Variable): MMType
-       do
-               return v.stype
-       end
-
-       # Variables by name (in the current context only)
-       attr _dico: Map[Symbol, Variable]
-
-       # All variables in all contextes
-       attr _all_variables: Set[Variable]
-
-       # Build a new VariableContext
-       meth sub(node: PNode): SubVariableContext
-       do
-               return new SubVariableContext.with_prev(self, node)
-       end
-
-       # Build a nested VariableContext with new variable information
-       meth sub_with(node: PNode, v: Variable, t: MMType): SubVariableContext
-       do
-               return new CastVariableContext.with_prev(self, node, v, t)
-       end
-
-       # The visitor of the context (used to display error)
-       attr _visitor: AbsSyntaxVisitor
-
-       # The syntax node that introduced the context
-       readable attr _node: PNode
-
-       init(visitor: AbsSyntaxVisitor, node: PNode)
-       do
-               _visitor = visitor
-               _node = node
-               _dico = new HashMap[Symbol, Variable]
-       end
-
-       # Is a control flow break met? (return, break, continue)
-       readable writable attr _unreash: Bool = false
-
-       # Is a control flow already broken?
-       # Used to avoid repeating the same error message
-       readable writable attr _already_unreash: Bool = false
-
-       # Set of variable that are set (assigned)
-       readable attr _set_variables: HashSet[Variable] = new HashSet[Variable]
-
-       # Is a variable set?
-       meth is_set(v: Variable): Bool
-       do
-               return _set_variables.has(v)
-       end
-
-       # Merge back one flow context information
-       meth merge(ctx: VariableContext)
-       do
-               if ctx.unreash then
-                       unreash = true
-                       if ctx.already_unreash then already_unreash = true
-                       return
-               end
-               for v in _all_variables do
-                       if not is_set(v) and ctx.is_set(v) then
-                               mark_is_set(v)
-                       end
-               end
-       end
-
-       # Merge back two alternative flow context informations
-       meth merge2(ctx1, ctx2: VariableContext)
-       do
-               if ctx1.unreash then
-                       merge(ctx2)
-               else if ctx2.unreash then
-                       merge(ctx1)
-               end
-               for v in _all_variables do
-                       if not is_set(v) and ctx1.is_set(v) and ctx2.is_set(v) then
-                               mark_is_set(v)
-                       end
-               end
-       end
-end
-
-class RootVariableContext
-special VariableContext
-       init(visitor: AbsSyntaxVisitor, node: PNode)
-       do
-               super(visitor, node)
-               _all_variables = new HashSet[Variable]
-       end
-end
-
-class SubVariableContext
-special VariableContext
-       readable attr _prev: VariableContext
-
-       redef meth [](s)
-       do
-               if _dico.has_key(s) then
-                       return _dico[s]
-               else
-                       return prev[s]
-               end
-       end
-
-       redef meth stype(v)
-       do
-               return prev.stype(v)
-       end
-
-       init with_prev(p: VariableContext, node: PNode)
-       do
-               init(p._visitor, node)
-               _prev = p
-               _all_variables = p._all_variables
-       end
-
-       redef meth is_set(v)
-       do
-               return _set_variables.has(v) or _prev.is_set(v)
-       end
-end
-
-class CastVariableContext
-special SubVariableContext
-       attr _variable: Variable
-       attr _var_type: MMType
-
-       redef meth stype(v)
-       do
-               if _variable == v then
-                       return _var_type
-               end
-               return prev.stype(v)
-       end
-
-       init with_prev(p: VariableContext, node: PNode, v: Variable, t: MMType)
-       do
-               super(p, node)
-               _variable = v
-               _var_type =t
-       end
-end
-
-redef class Variable
-       # Is the variable must be set before being used ?
-       meth must_be_set: Bool do return false
-end
-
-redef class VarVariable
-       redef meth must_be_set do return true
-end
-
 
 ###############################################################################