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
25 # Register store local variable and intermediate results
28 readable var _stype
: MMType
35 # A mark used to associate IEscapes to ISeqs
39 # A Closure declaration
41 # The associated closure definition
42 readable var _closure
: MMClosure
44 # The default implementation
45 readable writable var _default
: nullable IRoutine
47 init(c
: MMClosure) do _closure
= c
50 # A routine is a sequence of icodes with entry iregisters (params) and an exit iregister (result)
52 # The parameters of the routine
53 readable var _params
: Sequence[IRegister]
55 # The closure declared
56 readable writable var _closure_decls
: nullable Sequence[IClosureDecl] = null
58 # The local variables (excluding params and result)
59 readable var _registers
: Set[IRegister] = new HashSet[IRegister]
61 # The result of the routine
62 readable var _result
: nullable IRegister
64 # The local escapes marks of the routine
65 readable var _escape_marks
: Set[IEscapeMark] = new HashSet[IEscapeMark]
67 # The sequence of icode
68 readable var _body
: ISeq = new ISeq
70 # The location of the iroutine (if any)
71 readable writable var _location
: nullable Location = null
73 init(p
: Sequence[IRegister], r
: nullable IRegister)
80 # A closure definition in a iroutine body
83 init(p
: Array[IRegister], r
: nullable IRegister)
89 ## INTERMEDIATE CODE ##
91 # The root of the intermediate code representation
93 # The number of registers used by the icode
94 fun arity
: Int is abstract
96 # The result of the icode (if any)
97 readable writable var _result
: nullable IRegister = null
99 # The location of the icode (if any)
100 readable writable var _location
: nullable Location = null
102 # Is the icode side effect free?
103 fun is_pure
: Bool do return false
106 # An icode that uses no registers (no args)
107 abstract class ICode0
109 redef fun arity
do return 0
112 # An icode that uses a single register (1 arg)
113 abstract class ICode1
115 redef fun arity
do return 1
117 # The single argument
118 readable var _expr
: IRegister
120 init(e
: IRegister) do _expr
= e
123 # An icode that uses two single registers (2 args)
124 abstract class ICode2
126 redef fun arity
do return 2
129 readable var _expr1
: IRegister
131 # The second argument
132 readable var _expr2
: IRegister
134 init(e1
, e2
: IRegister)
141 # An icode that uses a variable number of registers (n args) and a variable number of closure definitions
142 abstract class ICodeN
144 redef fun arity
do return _exprs
.length
147 readable var _exprs
: Sequence[IRegister]
149 # All closure definition
150 readable writable var _closure_defs
: nullable Sequence[nullable IClosureDef]
152 init(e
: nullable Sequence[IRegister])
155 _exprs
= new Array[IRegister]
162 #################################################
164 # A linear sequence of ICode
167 # The sequence of icode
168 readable var _icodes
: List[ICode] = new List[ICode]
170 # The associated iescape_mark (if any)
171 readable writable var _iescape_mark
: nullable IEscapeMark
176 # An infinite loop of ICode
177 # Use IEscape to exit
183 # A Condidianal if-then-else statement
184 # expr is the condition
187 # The 'then' sequence of icode
188 readable var _then_seq
: ISeq = new ISeq
189 # The 'else' sequence of icode
190 readable var _else_seq
: ISeq = new ISeq
191 init(e
: IRegister) do super
194 # Escape to to end of a parent sequence
197 # The seqeuence to escape
198 # The control flow continues at the next icode after the associated sequence
199 readable var _iescape_mark
: IEscapeMark
200 init(mark
: IEscapeMark) do _iescape_mark
= mark
206 # The reason the abort occured
207 # tests.first is the format
208 readable var _texts
: Array[String]
209 # The module that has the abort
210 readable var _module_location
: MMModule
211 init(t
: Array[String], ml
: MMModule)
214 _module_location
= ml
218 #################################################
220 # The root of all method invocations
221 abstract class IAbsCall
224 readable var _property
: MMMethod
226 init(p
: MMMethod, e
: Sequence[IRegister])
233 # A simple procedure or function call
234 # exprs.first is the reciever, other are arguments
240 # A super method call
241 # exprs.first is the reciever, other are arguments
248 # no reciever, all exprs are arguments
249 # Will call in order:
250 # - IAllocateInstance
252 # - IStaticCall -> target Initializer
256 # The type to instantiate
257 readable var _stype
: MMType
258 init(t
: MMType, p
: MMMethod, a
: Sequence[IRegister])
265 # An allocation of a new object
266 # No receivers, returns a new object of type 't'
267 # Will allocate memory and ensure dynamic type and object identity
268 class IAllocateInstance
270 # The type to allocate
271 readable var _stype
: MMType
278 # A static call to a specific method
281 init(p
: MMMethod, a
: Sequence[IRegister]) do super
284 # A validation of a newly constructed instance
287 # The type to allocate
288 readable var _stype
: MMType
289 init(t
: MMType, e
: IRegister)
296 # Initialisation of default attributes of a new instance
297 class IInitAttributes
299 # The type to initialize
300 readable var _stype
: MMType
301 init(t
: MMType, e
: IRegister)
309 # exprs are the arguments
313 readable var _closure_decl
: IClosureDecl
315 # The !break sequence (if any)
316 readable writable var _break_seq
: nullable ISeq = null
318 init(c
: IClosureDecl, e
: Sequence[IRegister])
325 # A native inlined call
326 # Native are associated to local properties to distinguish them
327 # expr are the arguments
330 # The associated local property
331 readable var _method
: MMMethod
333 init(m
: MMMethod, e
: nullable Sequence[IRegister])
339 redef readable writable var _is_pure
: Bool = false
342 # A literal Int value
346 readable var _value
: String
348 init(v
: String) do _value
= v
350 redef fun is_pure
do return true
353 # A literal Bool value
357 readable var _value
: Bool
359 init(v
: Bool) do _value
= v
361 redef fun is_pure
do return true
364 # A literal NativeString value
368 readable var _value
: String
370 init(v
: String) do _value
= v
372 redef fun is_pure
do return true
375 # A literal Float value
379 readable var _value
: String
381 init(v
: String) do _value
= v
383 redef fun is_pure
do return true
386 # A literal Char value
390 readable var _value
: String
392 init(v
: String) do _value
= v
394 redef fun is_pure
do return true
397 # A register assigment
398 # expr is the assigned value
399 # result is the register assigned
402 init(r
: IRegister, e
: IRegister)
408 redef fun is_pure
do return true
411 # An attribute read access
412 # expr is the reciever
415 # The accessed attribute
416 readable var _property
: MMAttribute
418 init(p
: MMAttribute, r
: IRegister)
424 redef fun is_pure
do return true
427 # An attribute assignment
428 # expr1 is the receiver, expr2 is the assigned value
431 # The accessed attribute
432 readable var _property
: MMAttribute
434 init(p
: MMAttribute, r
: IRegister, v
: IRegister)
442 # An attribute is_set check
443 # expr is the reciever
446 # The accessed attribute
447 readable var _property
: MMAttribute
449 init(p
: MMAttribute, r
: IRegister)
455 redef fun is_pure
do return true
459 # expr is the expression checked
462 # The static type checkes to
463 readable var _stype
: MMType
465 init(e
: IRegister, t
: MMType)
471 redef fun is_pure
do return true
475 # expr1 and expr2 are both operands
478 init(e1
, e2
: IRegister)
483 redef fun is_pure
do return true
486 # The unary 'not' operation
487 # expr is the operand
495 redef fun is_pure
do return true
498 # Evaluate body once them return the same value again and again
499 # if result is not null, then it must also be assigned in the body
502 readable var _body
: ISeq = new ISeq
506 # Is a closure given as a parameter?
510 readable var _closure_decl
: IClosureDecl
512 init(c
: IClosureDecl)
517 redef fun is_pure
do return true
520 #################################################
522 redef class MMAttribute
523 # The attached initialisation iroutine if any
524 # To call between the allocate-instance and the initialize-instance
525 fun iroutine
: nullable IRoutine is abstract
529 # The attached body iroutine if any
530 fun iroutine
: nullable IRoutine is abstract