-# 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
- 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]
-
- # 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
-end
-
-class RootVariableContext
-special VariableContext
- init(visitor: AbsSyntaxVisitor, node: PNode)
- do
- super(visitor, node)
- 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
- 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