-# Associate symbols to variable and variables to type
-# Can be nested
-private 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: SubVariableContext
- do
- return new SubVariableContext.with_prev(self)
- end
-
- # Build a nested VariableContext with new variable information
- meth sub_with(v: Variable, t: MMType): SubVariableContext
- do
- return new CastVariableContext.with_prev(self, v, t)
- end
-
- init
- do
- _dico = new HashMap[Symbol, Variable]
- end
-end
-
-private 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)
- do
- init
- _prev = p
- end
-end
-
-private 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, v: Variable, t: MMType)
- do
- super(p)
- _variable = v
- _var_type =t
- end
-end