1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2008 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Manage nested escapable blocks (while, for and closure) and escape statements (break and continue)
22 # Stack escapable blocks
23 class EscapableContext
25 attr _stack
: Array[EscapableBlock] = new Array[EscapableBlock]
27 # Push a new escapable block
28 meth push
(block
: EscapableBlock)
33 # Is there no block in the stack?
34 meth is_empty
: Bool do return _stack
.is_empty
36 # Return the current block (the last stacked)
37 meth head
: EscapableBlock
42 # Remove the last block (the last stacked)
48 readable attr _visitor
: AbsSyntaxVisitor
49 init (v
: AbsSyntaxVisitor)
55 ###############################################################################
57 # A escapable block correspond to a block statement where break and/or continue can by used
58 # For and while use this class. closures uses the EscapableClosure subclass.
60 # The syntax node of the block
61 readable attr _node
: PNode = null
63 # Is self a break closure ?
64 meth is_break_block
: Bool do return false
66 # Collected expressions used in breaks.
67 # null if break does not accept values.
68 # break_list is used to store expressions used in break statments and perform type checks latter
69 meth break_list
: Array[PExpr] do return null
71 # The static type required by the continue statement (if any)
72 meth continue_stype
: MMType do return null
80 # specific EscapableBlock for closures
81 class EscapableClosure
82 special EscapableBlock
83 # The associated closure
84 readable attr _closure
: MMClosure
86 redef meth is_break_block
do return _closure
.is_break
88 redef readable attr _break_list
: Array[PExpr]
90 redef meth continue_stype
do return _closure
.signature
.return_type
92 init(node
: PNode, closure
: MMClosure, break_list
: Array[PExpr])
96 _break_list
= break_list
100 ###############################################################################
104 # The associated escapable block
105 readable attr _escapable_block
: EscapableBlock
107 # The name of the keyword
108 meth kwname
: String is abstract
110 # Compute, set and return the _abelable_node value
111 meth compute_escapable_block
(lctx
: EscapableContext): EscapableBlock
113 var block
: EscapableBlock
114 if lctx
.is_empty
then
115 lctx
.visitor
.error
(self, "Syntax Error: '{kwname}' statment outside block.")
119 _escapable_block
= block
124 redef class AContinueExpr
126 redef meth kwname
do return "continue"
129 redef class ABreakExpr
131 redef meth kwname
do return "break"