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 # if this call is to be made from native code
226 var is_explicit_from_extern
: Bool writable = false
228 init(p
: MMMethod, e
: Sequence[IRegister])
235 # A simple procedure or function call
236 # exprs.first is the reciever, other are arguments
242 # A super method call
243 # exprs.first is the reciever, other are arguments
250 # no reciever, all exprs are arguments
251 # Will call in order:
252 # - IAllocateInstance
254 # - IStaticCall -> target Initializer
258 # The type to instantiate
259 readable var _stype
: MMType
260 init(t
: MMType, p
: MMMethod, a
: Sequence[IRegister])
267 # An allocation of a new object
268 # No receivers, returns a new object of type 't'
269 # Will allocate memory and ensure dynamic type and object identity
270 class IAllocateInstance
272 # The type to allocate
273 readable var _stype
: MMType
280 # A static call to a specific method
283 init(p
: MMMethod, a
: Sequence[IRegister]) do super
286 # A validation of a newly constructed instance
289 # The type to allocate
290 readable var _stype
: MMType
291 init(t
: MMType, e
: IRegister)
298 # Initialisation of default attributes of a new instance
299 class IInitAttributes
301 # The type to initialize
302 readable var _stype
: MMType
303 init(t
: MMType, e
: IRegister)
311 # exprs are the arguments
315 readable var _closure_decl
: IClosureDecl
317 # The !break sequence (if any)
318 readable writable var _break_seq
: nullable ISeq = null
320 init(c
: IClosureDecl, e
: Sequence[IRegister])
327 # A native inlined call
328 # Native are associated to local properties to distinguish them
329 # expr are the arguments
332 # The associated local property
333 readable var _method
: MMMethod
335 init(m
: MMMethod, e
: nullable Sequence[IRegister])
337 # Checks that arguments contains at least one IRegister element
338 assert e
.length
== m
.signature
.arity
+ 1
344 redef readable writable var _is_pure
: Bool = false
347 # A literal Int value
351 readable var _value
: String
353 init(v
: String) do _value
= v
355 redef fun is_pure
do return true
358 # A literal Bool value
362 readable var _value
: Bool
364 init(v
: Bool) do _value
= v
366 redef fun is_pure
do return true
369 # A literal NativeString value
373 readable var _value
: String
375 init(v
: String) do _value
= v
377 redef fun is_pure
do return true
380 # A literal Float value
384 readable var _value
: String
386 init(v
: String) do _value
= v
388 redef fun is_pure
do return true
391 # A literal Char value
395 readable var _value
: String
397 init(v
: String) do _value
= v
399 redef fun is_pure
do return true
402 # A register assigment
403 # expr is the assigned value
404 # result is the register assigned
407 init(r
: IRegister, e
: IRegister)
413 redef fun is_pure
do return true
416 # An attribute read access
417 # expr is the reciever
420 # The accessed attribute
421 readable var _property
: MMAttribute
423 init(p
: MMAttribute, r
: IRegister)
429 redef fun is_pure
do return true
432 # An attribute assignment
433 # expr1 is the receiver, expr2 is the assigned value
436 # The accessed attribute
437 readable var _property
: MMAttribute
439 init(p
: MMAttribute, r
: IRegister, v
: IRegister)
447 # An attribute is_set check
448 # expr is the reciever
451 # The accessed attribute
452 readable var _property
: MMAttribute
454 init(p
: MMAttribute, r
: IRegister)
460 redef fun is_pure
do return true
464 # expr1 is the type reciever (self)
465 # expr2 is the expression checked
468 # The static type checkes to
469 readable var _stype
: MMType
471 init(e1
, e2
: IRegister, t
: MMType)
477 redef fun is_pure
do return true
481 # expr1 and expr2 are both operands
484 init(e1
, e2
: IRegister)
489 redef fun is_pure
do return true
492 # The unary 'not' operation
493 # expr is the operand
501 redef fun is_pure
do return true
504 # Evaluate body once them return the same value again and again
505 # if result is not null, then it must also be assigned in the body
508 readable var _body
: ISeq = new ISeq
512 # Is a closure given as a parameter?
516 readable var _closure_decl
: IClosureDecl
518 init(c
: IClosureDecl)
523 redef fun is_pure
do return true
526 #################################################
528 redef class MMAttribute
529 # The attached initialisation iroutine if any
530 # To call between the allocate-instance and the initialize-instance
531 fun iroutine
: nullable IRoutine is abstract
535 # The attached body iroutine if any
536 fun iroutine
: nullable IRoutine is abstract