1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2015 Julien Pagès <julien.pages@lirmm.fr>
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 # Handle all numbering operations related to local variables in the Nit virtual machine
18 module variables_numbering
22 redef class VirtualMachine
24 # Number the variables in `n`.
25 # Do nothing if `n` is null
26 fun numbering
(n
: nullable AExpr, position
: Int): Int
28 if n
== null then return position
30 var pos
= n
.numbering
(self, position
)
36 # The position in the environment
41 # Give a position to each variable declared in the node.
42 # NOTE: Do not call this method directly, but use `v.numbering`
43 # This method is here to be implemented by subclasses.
44 # *`v` The current instance of the virtual machine
45 # *`position` The first available position in the environment a variable can have
46 # Return the next available position a variable can have
47 public
fun numbering
(v
: VirtualMachine, position
: Int): Int
54 # Indicate if the variables numbering has been done
55 private var is_numbering
: Bool = false
57 # The size of the environment to create to call this method
58 private var environment_size
: Int = 0
61 redef class AMethPropdef
62 # Assign a position in the environment to each local variable of `mpropdef`
63 # *`v` The current VirtualMachine
64 # *`mpropdef` The method to number
65 private fun numbering_variables
(v
: VirtualMachine, mpropdef
: MMethodDef)
67 # The position in the environment
70 # The `self` variable has the first position
71 if self.selfvariable
!= null then
72 self.selfvariable
.position
= position
76 # Number the parameters
77 for i
in [0..mpropdef
.msignature
.arity
[ do
78 var variable
= self.n_signature
.n_params
[i
].variable
79 variable
.as(not null).position
= position
83 # Recursively go into the AST nodes to number all local variables
84 if n_block
!= null then
85 position
= v
.numbering
(self.n_block
, position
)
90 # The size of the environment to create to execute a call to this method
91 environment_size
= position
95 redef class AAttrPropdef
96 # Assign a position in the environment to each local variable of `mpropdef`
97 # *`v` The current VirtualMachine
98 private fun numbering_variables
(v
: VirtualMachine)
100 # The position in the environment
103 # The `self` variable has the first position
104 if self.selfvariable
!= null then
105 self.selfvariable
.position
= position
109 # Recursively go into the AST nodes to number all local variables
110 if n_block
!= null then
111 position
= v
.numbering
(self.n_block
, position
)
116 # The size of the environment to create to execute a call to this method
117 environment_size
= position
121 redef class AVardeclExpr
122 redef fun numbering
(v
, position
)
124 # Attribute a position to this variable
125 self.variable
.as(not null).position
= position
128 # Recursively continue to numbering the variables
129 position
= v
.numbering
(self.n_expr
, position
)
131 # `position` is the next available position in the environment
136 redef class ABlockExpr
137 redef fun numbering
(v
, position
)
139 for e
in self.n_expr
do
140 position
= v
.numbering
(e
, position
)
147 redef fun numbering
(v
, position
)
149 # Attribute numbers separetely for the two branches
150 var pos
= v
.numbering
(self.n_then
, position
)
151 var pos1
= v
.numbering
(self.n_else
, position
)
161 redef class AIfexprExpr
162 redef fun numbering
(v
, position
)
164 # Attribute numbers separetely for the two branches
165 var pos
= v
.numbering
(self.n_then
, position
)
166 var pos1
= v
.numbering
(self.n_else
, position
)
177 redef fun numbering
(v
, position
)
179 return v
.numbering
(self.n_block
, position
)
183 redef class AWhileExpr
184 redef fun numbering
(v
, position
)
186 return v
.numbering
(self.n_block
, position
)
190 redef class ALoopExpr
191 redef fun numbering
(v
, position
)
193 return v
.numbering
(self.n_block
, position
)
198 redef fun numbering
(v
, position
)
200 # Give a position to each variable declared in the header of the for
201 if self.variables
.length
== 1 then
202 self.variables
.first
.position
= position
203 self.variables
[0].position
= position
205 else if self.variables
.length
== 2 then
206 self.variables
[0].position
= position
208 self.variables
[1].position
= position
211 return v
.numbering
(self.n_block
, position
)
215 redef class AArrayExpr
216 redef fun numbering
(v
, position
)
218 for nexpr
in self.n_exprs
do
219 position
= v
.numbering
(nexpr
, position
)