# Associate symbols to variable and variables to type
# Can be nested
-private class VariableContext
+abstract class VariableContext
# Look for the variable from its name
# Return null if nothing found
meth [](s: Symbol): Variable
_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
attr _dico: Map[Symbol, Variable]
# Build a new VariableContext
- meth sub: SubVariableContext
+ meth sub(node: PNode): SubVariableContext
do
- return new SubVariableContext.with_prev(self)
+ return new SubVariableContext.with_prev(self, node)
end
# Build a nested VariableContext with new variable information
- meth sub_with(v: Variable, t: MMType): SubVariableContext
+ meth sub_with(node: PNode, v: Variable, t: MMType): SubVariableContext
do
- return new CastVariableContext.with_prev(self, v, t)
+ return new CastVariableContext.with_prev(self, node, v, t)
end
- init
- do
+ # 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
-private class SubVariableContext
+class RootVariableContext
+special VariableContext
+ init(visitor: AbsSyntaxVisitor, node: PNode)
+ do
+ super(visitor, node)
+ end
+end
+
+class SubVariableContext
special VariableContext
readable attr _prev: VariableContext
return prev.stype(v)
end
- init with_prev(p: VariableContext)
+ init with_prev(p: VariableContext, node: PNode)
do
- init
+ init(p._visitor, node)
_prev = p
end
end
-private class CastVariableContext
+class CastVariableContext
special SubVariableContext
attr _variable: Variable
attr _var_type: MMType
return prev.stype(v)
end
- init with_prev(p: VariableContext, v: Variable, t: MMType)
+ init with_prev(p: VariableContext, node: PNode, v: Variable, t: MMType)
do
- super(p)
+ super(p, node)
_variable = v
_var_type =t
end
redef readable attr _self_var: ParamVariable
redef meth accept_typing(v)
do
- v.variable_ctx = new VariableContext
+ v.variable_ctx = new RootVariableContext(v, self)
_self_var = v.self_var
super
end
v.variable_ctx.add(variable)
var old_var_ctx = v.variable_ctx
- v.variable_ctx = v.variable_ctx.sub
+ v.variable_ctx = v.variable_ctx.sub(self)
_escapable = new EscapableClosure(self, variable.closure, null)
v.escapable_ctx.push(_escapable)
redef meth accept_typing(v)
do
var old_var_ctx = v.variable_ctx
- v.variable_ctx = v.variable_ctx.sub
+ v.variable_ctx = v.variable_ctx.sub(self)
super
do
_escapable = new EscapableBlock(self)
v.escapable_ctx.push(_escapable)
+ var old_var_ctx = v.variable_ctx
+ v.variable_ctx = v.variable_ctx.sub(self)
super
v.check_conform_expr(n_expr, v.type_bool)
+ v.variable_ctx = old_var_ctx
v.escapable_ctx.pop
_is_typed = true
end
_escapable = new EscapableBlock(self)
v.escapable_ctx.push(_escapable)
- v.variable_ctx = v.variable_ctx.sub
+ var old_var_ctx = v.variable_ctx
+ v.variable_ctx = v.variable_ctx.sub(self)
var va = new AutoVariable(n_id.to_symbol, self)
variable = va
v.variable_ctx.add(va)
if n_block != null then v.visit(n_block)
# pop context
- var varctx = v.variable_ctx
- assert varctx isa SubVariableContext
- v.variable_ctx = varctx.prev
-
+ v.variable_ctx = old_var_ctx
v.escapable_ctx.pop
_is_typed = true
end
closure = esc.closure
- v.variable_ctx = v.variable_ctx.sub
+ var old_var_ctx = v.variable_ctx
+ v.variable_ctx = v.variable_ctx.sub(self)
variables = new Array[AutoVariable]
for i in [0..n_id.length[ do
var va = new AutoVariable(n_id[i].to_symbol, self)
_accept_typing2 = true
accept_typing(v)
+ v.variable_ctx = old_var_ctx
end
end
check_expr_cast(v, n_expr, n_type)
var variable = n_expr.its_variable
if variable != null then
- _if_true_variable_ctx = v.variable_ctx.sub_with(variable, n_type.stype)
+ _if_true_variable_ctx = v.variable_ctx.sub_with(self, variable, n_type.stype)
end
_stype = v.type_bool
_is_typed = true