nit: restrict some module visibility
[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
22 ## UTILITY CLASSES ##
23
24 # Register store local variable and intermediate results
25 class IRegister
26 # The static type
27 readable var _stype: MMType
28 init(s: MMType)
29 do
30 _stype = s
31 end
32 end
33
34 # A mark used to associate IEscapes to ISeqs
35 class IEscapeMark
36 end
37
38 # A Closure declaration
39 class IClosureDecl
40 # The associated closure definition
41 readable var _closure: MMClosure
42
43 # The default implementation
44 readable writable var _default: nullable IRoutine
45
46 init(c: MMClosure) do _closure = c
47 end
48
49 # A routine is a sequence of icodes with entry iregisters (params) and an exit iregister (result)
50 class IRoutine
51 # The parameters of the routine
52 readable var _params: Sequence[IRegister]
53
54 # The closure declared
55 readable writable var _closure_decls: nullable Sequence[IClosureDecl] = null
56
57 # The local variables (excluding params and result)
58 readable var _registers: Set[IRegister] = new HashSet[IRegister]
59
60 # The result of the routine
61 readable var _result: nullable IRegister
62
63 # The local escapes marks of the routine
64 readable var _escape_marks: Set[IEscapeMark] = new HashSet[IEscapeMark]
65
66 # The sequence of icode
67 readable var _body: ISeq = new ISeq
68
69 # The location of the iroutine (if any)
70 readable writable var _location: nullable Location = null
71
72 init(p: Sequence[IRegister], r: nullable IRegister)
73 do
74 _params = p.to_a
75 _result = r
76 end
77 end
78
79 # A closure definition in a iroutine body
80 class IClosureDef
81 super IRoutine
82 init(p: Array[IRegister], r: nullable IRegister)
83 do
84 super(p, r)
85 end
86 end
87
88 ## INTERMEDIATE CODE ##
89
90 # The root of the intermediate code representation
91 abstract class ICode
92 # The number of registers used by the icode
93 fun arity: Int is abstract
94
95 # The result of the icode (if any)
96 readable writable var _result: nullable IRegister = null
97
98 # The location of the icode (if any)
99 readable writable var _location: nullable Location = null
100
101 # Is the icode side effect free?
102 fun is_pure: Bool do return false
103 end
104
105 # An icode that uses no registers (no args)
106 abstract class ICode0
107 super ICode
108 redef fun arity do return 0
109 end
110
111 # An icode that uses a single register (1 arg)
112 abstract class ICode1
113 super ICode
114 redef fun arity do return 1
115
116 # The single argument
117 readable var _expr: IRegister
118
119 init(e: IRegister) do _expr = e
120 end
121
122 # An icode that uses two single registers (2 args)
123 abstract class ICode2
124 super ICode
125 redef fun arity do return 2
126
127 # The first argument
128 readable var _expr1: IRegister
129
130 # The second argument
131 readable var _expr2: IRegister
132
133 init(e1, e2: IRegister)
134 do
135 _expr1 = e1
136 _expr2 = e2
137 end
138 end
139
140 # An icode that uses a variable number of registers (n args) and a variable number of closure definitions
141 abstract class ICodeN
142 super ICode
143 redef fun arity do return _exprs.length
144
145 # All arguments
146 readable var _exprs: Sequence[IRegister]
147
148 # All closure definition
149 readable writable var _closure_defs: nullable Sequence[nullable IClosureDef]
150
151 init(e: nullable Sequence[IRegister])
152 do
153 if e == null then
154 _exprs = new Array[IRegister]
155 else
156 _exprs = e
157 end
158 end
159 end
160
161 #################################################
162
163 # A linear sequence of ICode
164 class ISeq
165 super ICode0
166 # The sequence of icode
167 readable var _icodes: List[ICode] = new List[ICode]
168
169 # The associated iescape_mark (if any)
170 readable writable var _iescape_mark: nullable IEscapeMark
171
172 init do end
173 end
174
175 # An infinite loop of ICode
176 # Use IEscape to exit
177 class ILoop
178 super ISeq
179 init do end
180 end
181
182 # A Condidianal if-then-else statement
183 # expr is the condition
184 class IIf
185 super ICode1
186 # The 'then' sequence of icode
187 readable var _then_seq: ISeq = new ISeq
188 # The 'else' sequence of icode
189 readable var _else_seq: ISeq = new ISeq
190 init(e: IRegister) do super
191 end
192
193 # Escape to to end of a parent sequence
194 class IEscape
195 super ICode0
196 # The seqeuence to escape
197 # The control flow continues at the next icode after the associated sequence
198 readable var _iescape_mark: IEscapeMark
199 init(mark: IEscapeMark) do _iescape_mark = mark
200 end
201
202 # An abort statement
203 class IAbort
204 super ICode0
205 # The reason the abort occured
206 # tests.first is the format
207 readable var _texts: Array[String]
208 # The module that has the abort
209 readable var _module_location: MMModule
210 init(t: Array[String], ml: MMModule)
211 do
212 _texts = t
213 _module_location = ml
214 end
215 end
216
217 #################################################
218
219 # The root of all method invocations
220 abstract class IAbsCall
221 super ICodeN
222 # The called method
223 readable var _property: MMMethod
224
225 init(p: MMMethod, e: Sequence[IRegister])
226 do
227 super(e)
228 _property = p
229 end
230 end
231
232 # A simple procedure or function call
233 # exprs.first is the reciever, other are arguments
234 class ICall
235 super IAbsCall
236 init(p, e) do super
237 end
238
239 # A super method call
240 # exprs.first is the reciever, other are arguments
241 class ISuper
242 super IAbsCall
243 init(p, e) do super
244 end
245
246 # An instantiation
247 # no reciever, all exprs are arguments
248 # Will call in order:
249 # - IAllocateInstance
250 # - IInitAttributes
251 # - IStaticCall -> target Initializer
252 # - ICheckInstance
253 class INew
254 super IAbsCall
255 # The type to instantiate
256 readable var _stype: MMType
257 init(t: MMType, p: MMMethod, a: Sequence[IRegister])
258 do
259 super(p, a)
260 _stype = t
261 end
262 end
263
264 # An allocation of a new object
265 # No receivers, returns a new object of type 't'
266 # Will allocate memory and ensure dynamic type and object identity
267 class IAllocateInstance
268 super ICode0
269 # The type to allocate
270 readable var _stype: MMType
271 init(t: MMType)
272 do
273 _stype = t
274 end
275 end
276
277 # A static call to a specific method
278 class IStaticCall
279 super IAbsCall
280 init(p: MMMethod, a: Sequence[IRegister]) do super
281 end
282
283 # A validation of a newly constructed instance
284 class ICheckInstance
285 super ICode1
286 # The type to allocate
287 readable var _stype: MMType
288 init(t: MMType, e: IRegister)
289 do
290 super(e)
291 _stype = t
292 end
293 end
294
295 # Initialisation of default attributes of a new instance
296 class IInitAttributes
297 super ICode1
298 # The type to initialize
299 readable var _stype: MMType
300 init(t: MMType, e: IRegister)
301 do
302 super(e)
303 _stype = t
304 end
305 end
306
307 # A closure call
308 # exprs are the arguments
309 class IClosCall
310 super ICodeN
311 # The called closure
312 readable var _closure_decl: IClosureDecl
313
314 # The !break sequence (if any)
315 readable writable var _break_seq: nullable ISeq = null
316
317 init(c: IClosureDecl, e: Sequence[IRegister])
318 do
319 super(e)
320 _closure_decl = c
321 end
322 end
323
324 # A native inlined call
325 # Native are associated to local properties to distinguish them
326 # expr are the arguments
327 class INative
328 super ICodeN
329 # The associated local property
330 readable var _method: MMMethod
331
332 init(m: MMMethod, e: nullable Sequence[IRegister])
333 do
334 # Checks that arguments contains at least one IRegister element
335 assert e.length == m.signature.arity + 1
336
337 super(e)
338 _method = m
339 end
340
341 redef readable writable var _is_pure: Bool = false
342 end
343
344 # A literal Int value
345 class IIntValue
346 super ICode0
347 # The value
348 readable var _value: String
349
350 init(v: String) do _value = v
351
352 redef fun is_pure do return true
353 end
354
355 # A literal Bool value
356 class IBoolValue
357 super ICode0
358 # The value
359 readable var _value: Bool
360
361 init(v: Bool) do _value = v
362
363 redef fun is_pure do return true
364 end
365
366 # A literal NativeString value
367 class IStringValue
368 super ICode0
369 # The value
370 readable var _value: String
371
372 init(v: String) do _value = v
373
374 redef fun is_pure do return true
375 end
376
377 # A literal Float value
378 class IFloatValue
379 super ICode0
380 # The value
381 readable var _value: String
382
383 init(v: String) do _value = v
384
385 redef fun is_pure do return true
386 end
387
388 # A literal Char value
389 class ICharValue
390 super ICode0
391 # The value
392 readable var _value: String
393
394 init(v: String) do _value = v
395
396 redef fun is_pure do return true
397 end
398
399 # A register assigment
400 # expr is the assigned value
401 # result is the register assigned
402 class IMove
403 super ICode1
404 init(r: IRegister, e: IRegister)
405 do
406 super(e)
407 _result = r
408 end
409
410 redef fun is_pure do return true
411 end
412
413 # An attribute read access
414 # expr is the reciever
415 class IAttrRead
416 super ICode1
417 # The accessed attribute
418 readable var _property: MMAttribute
419
420 init(p: MMAttribute, r: IRegister)
421 do
422 super(r)
423 _property = p
424 end
425
426 redef fun is_pure do return true
427 end
428
429 # An attribute assignment
430 # expr1 is the receiver, expr2 is the assigned value
431 class IAttrWrite
432 super ICode2
433 # The accessed attribute
434 readable var _property: MMAttribute
435
436 init(p: MMAttribute, r: IRegister, v: IRegister)
437 do
438 super(r, v)
439 _property = p
440 end
441 end
442
443
444 # An attribute is_set check
445 # expr is the reciever
446 class IAttrIsset
447 super ICode1
448 # The accessed attribute
449 readable var _property: MMAttribute
450
451 init(p: MMAttribute, r: IRegister)
452 do
453 super(r)
454 _property = p
455 end
456
457 redef fun is_pure do return true
458 end
459
460 # A type check
461 # expr1 is the type reciever (self)
462 # expr2 is the expression checked
463 class ITypeCheck
464 super ICode2
465 # The static type checkes to
466 readable var _stype: MMType
467
468 init(e1, e2: IRegister, t: MMType)
469 do
470 super(e1, e2)
471 _stype = t
472 end
473
474 redef fun is_pure do return true
475 end
476
477 # The 'is' operator
478 # expr1 and expr2 are both operands
479 class IIs
480 super ICode2
481 init(e1, e2: IRegister)
482 do
483 super
484 end
485
486 redef fun is_pure do return true
487 end
488
489 # The unary 'not' operation
490 # expr is the operand
491 class INot
492 super ICode1
493 init(e: IRegister)
494 do
495 super
496 end
497
498 redef fun is_pure do return true
499 end
500
501 # Evaluate body once them return the same value again and again
502 # if result is not null, then it must also be assigned in the body
503 class IOnce
504 super ICode0
505 readable var _body: ISeq = new ISeq
506 init do end
507 end
508
509 # Is a closure given as a parameter?
510 class IHasClos
511 super ICode0
512 # The called closure
513 readable var _closure_decl: IClosureDecl
514
515 init(c: IClosureDecl)
516 do
517 _closure_decl = c
518 end
519
520 redef fun is_pure do return true
521 end
522
523 #################################################
524
525 redef class MMAttribute
526 # The attached initialisation iroutine if any
527 # To call between the allocate-instance and the initialize-instance
528 fun iroutine: nullable IRoutine is abstract
529 end
530
531 redef class MMMethod
532 # The attached body iroutine if any
533 fun iroutine: nullable IRoutine is abstract
534 end