icode: remove method information in IAbort
[nit.git] / src / icode / icode_base.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2009 Jean Privat <jean@pryen.org>
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 # Base classes for Nit intermediate code representation
18 package icode_base
19
20 import metamodel
21 import mmloader
22
23 ## UTILITY CLASSES ##
24
25 # Register store local variable and intermediate results
26 class IRegister
27 # The static type
28 readable var _stype: MMType
29 init(s: MMType)
30 do
31 _stype = s
32 end
33 end
34
35 # A Closure declaration
36 class IClosureDecl
37 # The associated closure definition
38 readable var _closure: MMClosure
39
40 # The default implementation
41 readable writable var _default: nullable IRoutine
42
43 init(c: MMClosure) do _closure = c
44 end
45
46 # A routine is a sequence of icodes with entry iregisters (params) and an exit iregister (result)
47 class IRoutine
48 # The parameters of the routine
49 readable var _params: Sequence[IRegister]
50
51 # The closure declared
52 readable writable var _closure_decls: nullable Sequence[IClosureDecl] = null
53
54 # The result of the routine
55 readable var _result: nullable IRegister
56
57 # The sequence of icode
58 readable var _body: ISeq = new ISeq
59
60 # The location of the iroutine (if any)
61 readable writable var _location: nullable Location = null
62
63 init(p: Sequence[IRegister], r: nullable IRegister)
64 do
65 _params = p.to_a
66 _result = r
67 end
68 end
69
70 # A closure definition in a iroutine body
71 class IClosureDef
72 special IRoutine
73 init(p: Array[IRegister], r: nullable IRegister)
74 do
75 super(p, r)
76 end
77 end
78
79 ## INTERMEDIATE CODE ##
80
81 # The root of the intermediate code representation
82 abstract class ICode
83 # The number of registers used by the icode
84 fun arity: Int is abstract
85
86 # The result of the icode (if any)
87 readable writable var _result: nullable IRegister = null
88
89 # The location of the icode (if any)
90 readable writable var _location: nullable Location = null
91
92 # Is the icode side effect free?
93 fun is_pure: Bool do return false
94 end
95
96 # An icode that uses no registers (no args)
97 abstract class ICode0
98 special ICode
99 redef fun arity do return 0
100 end
101
102 # An icode that uses a single register (1 arg)
103 abstract class ICode1
104 special ICode
105 redef fun arity do return 1
106
107 # The single argument
108 readable var _expr: IRegister
109
110 init(e: IRegister) do _expr = e
111 end
112
113 # An icode that uses two single registers (2 args)
114 abstract class ICode2
115 special ICode
116 redef fun arity do return 2
117
118 # The first argument
119 readable var _expr1: IRegister
120
121 # The second argument
122 readable var _expr2: IRegister
123
124 init(e1, e2: IRegister)
125 do
126 _expr1 = e1
127 _expr2 = e2
128 end
129 end
130
131 # An icode that uses a variable number of registers (n args) and a variable number of closure definitions
132 abstract class ICodeN
133 special ICode
134 redef fun arity do return _exprs.length
135
136 # All arguments
137 readable var _exprs: Sequence[IRegister]
138
139 # All closure definition
140 readable writable var _closure_defs: nullable Sequence[nullable IClosureDef]
141
142 init(e: nullable Sequence[IRegister])
143 do
144 if e == null then
145 _exprs = new Array[IRegister]
146 else
147 _exprs = e
148 end
149 end
150 end
151
152 #################################################
153
154 # A linear sequence of ICode
155 class ISeq
156 special ICode0
157 # The sequence of icode
158 readable var _icodes: List[ICode] = new List[ICode]
159 init do end
160 end
161
162 # An infinite loop of ICode
163 # Use IEscape to exit
164 class ILoop
165 special ISeq
166 init do end
167 end
168
169 # A Condidianal if-then-else statement
170 # expr is the condition
171 class IIf
172 special ICode1
173 # The 'then' sequence of icode
174 readable var _then_seq: ISeq = new ISeq
175 # The 'else' sequence of icode
176 readable var _else_seq: ISeq = new ISeq
177 init(e: IRegister) do super
178 end
179
180 # Escape to to end of a parent sequence
181 class IEscape
182 special ICode0
183 # The seqeuence to escape
184 # The control flow continues at the next icode after the sequence
185 readable var _seq: ISeq
186 init(seq: ISeq) do _seq = seq
187 end
188
189 # An abort statement
190 class IAbort
191 special ICode0
192 # The reason the abort occured
193 # tests.first is the format
194 readable var _texts: Array[String]
195 # The module that has the abort
196 readable var _module_location: MMModule
197 init(t: Array[String], ml: MMModule)
198 do
199 _texts = t
200 _module_location = ml
201 end
202 end
203
204 #################################################
205
206 # The root of all method invocations
207 abstract class IAbsCall
208 special ICodeN
209 # The called method
210 readable var _property: MMMethod
211
212 init(p: MMMethod, e: Sequence[IRegister])
213 do
214 super(e)
215 _property = p
216 end
217 end
218
219 # A simple procedure or function call
220 # exprs.first is the reciever, other are arguments
221 class ICall
222 special IAbsCall
223 init(p, e) do super
224 end
225
226 # A super method call
227 # exprs.first is the reciever, other are arguments
228 class ISuper
229 special IAbsCall
230 init(p, e) do super
231 end
232
233 # An instantiation
234 # no reciever, all exprs are arguments
235 class INew
236 special ICall
237 # The type to instantiate
238 readable var _stype: MMType
239 init(t: MMType, p: MMMethod, a: Sequence[IRegister])
240 do
241 super(p, a)
242 _stype = t
243 end
244 end
245
246 # A closure call
247 # exprs are the arguments
248 class IClosCall
249 special ICodeN
250 # The called closure
251 readable var _closure_decl: IClosureDecl
252
253 # The !break sequence (if any)
254 readable writable var _break_seq: nullable ISeq = null
255
256 init(c: IClosureDecl, e: Sequence[IRegister])
257 do
258 super(e)
259 _closure_decl = c
260 end
261 end
262
263 # A native C code
264 # Mainly used to implements things that do not have a specific ICode yet
265 # expr are the arguments
266 class INative
267 special ICodeN
268 # The native C code
269 # Special character sequence '@@@' will be substitued in order with the arguments
270 readable var _code: String
271
272 init(c: String, e: nullable Sequence[IRegister])
273 do
274 super(e)
275 _code = c
276 end
277
278 redef readable writable var _is_pure: Bool = false
279 end
280
281 # A register assigment
282 # expr is the assigned value
283 # result is the register assigned
284 class IMove
285 special ICode1
286 init(r: IRegister, e: IRegister)
287 do
288 super(e)
289 _result = r
290 end
291
292 redef fun is_pure do return true
293 end
294
295 # An attribute read access
296 # expr is the reciever
297 class IAttrRead
298 special ICode1
299 # The accessed attribute
300 readable var _property: MMAttribute
301
302 init(p: MMAttribute, r: IRegister)
303 do
304 super(r)
305 _property = p
306 end
307
308 redef fun is_pure do return true
309 end
310
311 # An attribute assignment
312 # expr1 is the receiver, expr2 is the assigned value
313 class IAttrWrite
314 special ICode2
315 # The accessed attribute
316 readable var _property: MMAttribute
317
318 init(p: MMAttribute, r: IRegister, v: IRegister)
319 do
320 super(r, v)
321 _property = p
322 end
323 end
324
325
326 # An attribute is_set check
327 # expr is the reciever
328 class IAttrIsset
329 special ICode1
330 # The accessed attribute
331 readable var _property: MMAttribute
332
333 init(p: MMAttribute, r: IRegister)
334 do
335 super(r)
336 _property = p
337 end
338
339 redef fun is_pure do return true
340 end
341
342 # A type check
343 # expr is the expression checked
344 class ITypeCheck
345 special ICode1
346 # The static type checkes to
347 readable var _stype: MMType
348
349 init(e: IRegister, t: MMType)
350 do
351 super(e)
352 _stype = t
353 end
354
355 redef fun is_pure do return true
356 end
357
358 # The 'is' operator
359 # expr1 and expr2 are both operands
360 class IIs
361 special ICode2
362 init(e1, e2: IRegister)
363 do
364 super
365 end
366
367 redef fun is_pure do return true
368 end
369
370 # The unary 'not' operation
371 # expr is the operand
372 class INot
373 special ICode1
374 init(e: IRegister)
375 do
376 super
377 end
378
379 redef fun is_pure do return true
380 end
381
382 # Evaluate body once them return the same value again and again
383 # if result is not null, then it must also be assigned in the body
384 class IOnce
385 special ICode0
386 readable var _body: ISeq = new ISeq
387 init do end
388 end
389
390 # Is a closure given as a parameter?
391 class IHasClos
392 special ICode0
393 # The called closure
394 readable var _closure_decl: IClosureDecl
395
396 init(c: IClosureDecl)
397 do
398 _closure_decl = c
399 end
400
401 redef fun is_pure do return true
402 end
403
404 #################################################
405
406 redef class MMAttribute
407 # The attached initialisation iroutine if any
408 # To call between the allocate-instance and the initialize-instance
409 fun iroutine: nullable IRoutine is abstract
410 end
411
412 redef class MMMethod
413 # The attached body iroutine if any
414 fun iroutine: nullable IRoutine is abstract
415 end