1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2009 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 # Base classes for Nit intermediate code representation
24 # Register store local variable and intermediate results
27 readable var _stype
: MMType
34 # A mark used to associate IEscapes to ISeqs
38 # A Closure declaration
40 # The associated closure definition
41 readable var _closure
: MMClosure
43 # The default implementation
44 readable writable var _default
: nullable IRoutine
46 init(c
: MMClosure) do _closure
= c
49 # A routine is a sequence of icodes with entry iregisters (params) and an exit iregister (result)
51 # The parameters of the routine
52 readable var _params
: Sequence[IRegister]
54 # The closure declared
55 readable writable var _closure_decls
: nullable Sequence[IClosureDecl] = null
57 # The local variables (excluding params and result)
58 readable var _registers
: Set[IRegister] = new HashSet[IRegister]
60 # The result of the routine
61 readable var _result
: nullable IRegister
63 # The local escapes marks of the routine
64 readable var _escape_marks
: Set[IEscapeMark] = new HashSet[IEscapeMark]
66 # The sequence of icode
67 readable var _body
: ISeq = new ISeq
69 # The location of the iroutine (if any)
70 readable writable var _location
: nullable Location = null
72 init(p
: Sequence[IRegister], r
: nullable IRegister)
79 # A closure definition in a iroutine body
82 init(p
: Array[IRegister], r
: nullable IRegister)
88 ## INTERMEDIATE CODE ##
90 # The root of the intermediate code representation
92 # The number of registers used by the icode
93 fun arity
: Int is abstract
95 # The result of the icode (if any)
96 readable writable var _result
: nullable IRegister = null
98 # The location of the icode (if any)
99 readable writable var _location
: nullable Location = null
101 # Is the icode side effect free?
102 fun is_pure
: Bool do return false
105 # An icode that uses no registers (no args)
106 abstract class ICode0
108 redef fun arity
do return 0
111 # An icode that uses a single register (1 arg)
112 abstract class ICode1
114 redef fun arity
do return 1
116 # The single argument
117 readable var _expr
: IRegister
119 init(e
: IRegister) do _expr
= e
122 # An icode that uses two single registers (2 args)
123 abstract class ICode2
125 redef fun arity
do return 2
128 readable var _expr1
: IRegister
130 # The second argument
131 readable var _expr2
: IRegister
133 init(e1
, e2
: IRegister)
140 # An icode that uses a variable number of registers (n args) and a variable number of closure definitions
141 abstract class ICodeN
143 redef fun arity
do return _exprs
.length
146 readable var _exprs
: Sequence[IRegister]
148 # All closure definition
149 readable writable var _closure_defs
: nullable Sequence[nullable IClosureDef]
151 init(e
: nullable Sequence[IRegister])
154 _exprs
= new Array[IRegister]
161 #################################################
163 # A linear sequence of ICode
166 # The sequence of icode
167 readable var _icodes
: List[ICode] = new List[ICode]
169 # The associated iescape_mark (if any)
170 readable writable var _iescape_mark
: nullable IEscapeMark
175 # An infinite loop of ICode
176 # Use IEscape to exit
182 # A Condidianal if-then-else statement
183 # expr is the condition
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
193 # Escape to to end of a parent sequence
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
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)
213 _module_location
= ml
217 #################################################
219 # The root of all method invocations
220 abstract class IAbsCall
223 readable var _property
: MMMethod
225 init(p
: MMMethod, e
: Sequence[IRegister])
232 # A simple procedure or function call
233 # exprs.first is the reciever, other are arguments
239 # A super method call
240 # exprs.first is the reciever, other are arguments
247 # no reciever, all exprs are arguments
248 # Will call in order:
249 # - IAllocateInstance
251 # - IStaticCall -> target Initializer
255 # The type to instantiate
256 readable var _stype
: MMType
257 init(t
: MMType, p
: MMMethod, a
: Sequence[IRegister])
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
269 # The type to allocate
270 readable var _stype
: MMType
277 # A static call to a specific method
280 init(p
: MMMethod, a
: Sequence[IRegister]) do super
283 # A validation of a newly constructed instance
286 # The type to allocate
287 readable var _stype
: MMType
288 init(t
: MMType, e
: IRegister)
295 # Initialisation of default attributes of a new instance
296 class IInitAttributes
298 # The type to initialize
299 readable var _stype
: MMType
300 init(t
: MMType, e
: IRegister)
308 # exprs are the arguments
312 readable var _closure_decl
: IClosureDecl
314 # The !break sequence (if any)
315 readable writable var _break_seq
: nullable ISeq = null
317 init(c
: IClosureDecl, e
: Sequence[IRegister])
324 # A native inlined call
325 # Native are associated to local properties to distinguish them
326 # expr are the arguments
329 # The associated local property
330 readable var _method
: MMMethod
332 init(m
: MMMethod, e
: nullable Sequence[IRegister])
334 # Checks that arguments contains at least one IRegister element
335 assert e
.length
== m
.signature
.arity
+ 1
341 redef readable writable var _is_pure
: Bool = false
344 # A literal Int value
348 readable var _value
: String
350 init(v
: String) do _value
= v
352 redef fun is_pure
do return true
355 # A literal Bool value
359 readable var _value
: Bool
361 init(v
: Bool) do _value
= v
363 redef fun is_pure
do return true
366 # A literal NativeString value
370 readable var _value
: String
372 init(v
: String) do _value
= v
374 redef fun is_pure
do return true
377 # A literal Float value
381 readable var _value
: String
383 init(v
: String) do _value
= v
385 redef fun is_pure
do return true
388 # A literal Char value
392 readable var _value
: String
394 init(v
: String) do _value
= v
396 redef fun is_pure
do return true
399 # A register assigment
400 # expr is the assigned value
401 # result is the register assigned
404 init(r
: IRegister, e
: IRegister)
410 redef fun is_pure
do return true
413 # An attribute read access
414 # expr is the reciever
417 # The accessed attribute
418 readable var _property
: MMAttribute
420 init(p
: MMAttribute, r
: IRegister)
426 redef fun is_pure
do return true
429 # An attribute assignment
430 # expr1 is the receiver, expr2 is the assigned value
433 # The accessed attribute
434 readable var _property
: MMAttribute
436 init(p
: MMAttribute, r
: IRegister, v
: IRegister)
444 # An attribute is_set check
445 # expr is the reciever
448 # The accessed attribute
449 readable var _property
: MMAttribute
451 init(p
: MMAttribute, r
: IRegister)
457 redef fun is_pure
do return true
461 # expr1 is the type reciever (self)
462 # expr2 is the expression checked
465 # The static type checkes to
466 readable var _stype
: MMType
468 init(e1
, e2
: IRegister, t
: MMType)
474 redef fun is_pure
do return true
478 # expr1 and expr2 are both operands
481 init(e1
, e2
: IRegister)
486 redef fun is_pure
do return true
489 # The unary 'not' operation
490 # expr is the operand
498 redef fun is_pure
do return true
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
505 readable var _body
: ISeq = new ISeq
509 # Is a closure given as a parameter?
513 readable var _closure_decl
: IClosureDecl
515 init(c
: IClosureDecl)
520 redef fun is_pure
do return true
523 #################################################
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
532 # The attached body iroutine if any
533 fun iroutine
: nullable IRoutine is abstract