# Used for debuging
var _variables: Array[Variable] = new Array[Variable]
- # Known labels
- # (all labels, even out of scopes ones)
- # Used to find duplicates
- var _labels: Array[ALabel] = new Array[ALabel]
-
# Return the variable associated with a name
fun [](n: Symbol): nullable Variable
do
_stack.push(block)
if n_label != null then
var lab = n_label.n_id.to_symbol
- for nl in _labels do
- if n_label != nl and lab == nl.n_id.to_symbol then
- visitor.error(n_label, "Syntax error: label {lab} already defined at {nl.location.relative_to(n_label.location)}.")
+ var i = _stack.length - 1
+ while i >= 0 do
+ var b = _stack[i]
+ if b isa EscapableBlock and b.lab == lab then
+ visitor.error(n_label, "Syntax error: label {lab} already defined at {b.lab_location.relative_to(n_label.location)}.")
return
end
+ i -= 1
end
- _labels.add(n_label)
block._lab = lab
+ block._lab_location = n_label.location
end
end
# labeled 'do' uses the BreakOnlyEscapableBlock subclass
# closures uses the EscapableClosure subclass
class EscapableBlock
-special ScopeBlock
+ super ScopeBlock
# The label of the block (if any)
# Set by the push in EscapableContext
readable var _lab: nullable Symbol
+ # The location of the label (if any)
+ readable var _lab_location: nullable Location
+
# Is self a break closure ?
fun is_break_block: Bool do return false
# specific EscapableBlock where only labelled break can be used
class BreakOnlyEscapableBlock
-special EscapableBlock
+ super EscapableBlock
redef fun is_break_block: Bool do return true
init(node: ANode) do super
# specific EscapableBlock for closures
class EscapableClosure
-special EscapableBlock
+ super EscapableBlock
# The associated closure
readable var _closure: MMClosure
###############################################################################
-class AEscapeExpr
-special ALabelable
+abstract class AEscapeExpr
+ super ALabelable
# The associated escapable block
readable var _escapable: nullable EscapableBlock
end
redef class AContinueExpr
-special AEscapeExpr
+ super AEscapeExpr
redef fun kwname do return "continue"
end
redef class ABreakExpr
-special AEscapeExpr
+ super AEscapeExpr
redef fun kwname do return "break"
end