ea13a9ffc23013837f9366ef52f9a61cb7c92b3c
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])
335 # Checks that arguments contains at least one IRegister element
336 assert e
.length
== m
.signature
.arity
+ 1
342 redef readable writable var _is_pure
: Bool = false
345 # A literal Int value
349 readable var _value
: String
351 init(v
: String) do _value
= v
353 redef fun is_pure
do return true
356 # A literal Bool value
360 readable var _value
: Bool
362 init(v
: Bool) do _value
= v
364 redef fun is_pure
do return true
367 # A literal NativeString value
371 readable var _value
: String
373 init(v
: String) do _value
= v
375 redef fun is_pure
do return true
378 # A literal Float value
382 readable var _value
: String
384 init(v
: String) do _value
= v
386 redef fun is_pure
do return true
389 # A literal Char value
393 readable var _value
: String
395 init(v
: String) do _value
= v
397 redef fun is_pure
do return true
400 # A register assigment
401 # expr is the assigned value
402 # result is the register assigned
405 init(r
: IRegister, e
: IRegister)
411 redef fun is_pure
do return true
414 # An attribute read access
415 # expr is the reciever
418 # The accessed attribute
419 readable var _property
: MMAttribute
421 init(p
: MMAttribute, r
: IRegister)
427 redef fun is_pure
do return true
430 # An attribute assignment
431 # expr1 is the receiver, expr2 is the assigned value
434 # The accessed attribute
435 readable var _property
: MMAttribute
437 init(p
: MMAttribute, r
: IRegister, v
: IRegister)
445 # An attribute is_set check
446 # expr is the reciever
449 # The accessed attribute
450 readable var _property
: MMAttribute
452 init(p
: MMAttribute, r
: IRegister)
458 redef fun is_pure
do return true
462 # expr1 is the type reciever (self)
463 # expr2 is the expression checked
466 # The static type checkes to
467 readable var _stype
: MMType
469 init(e1
, e2
: IRegister, t
: MMType)
475 redef fun is_pure
do return true
479 # expr1 and expr2 are both operands
482 init(e1
, e2
: IRegister)
487 redef fun is_pure
do return true
490 # The unary 'not' operation
491 # expr is the operand
499 redef fun is_pure
do return true
502 # Evaluate body once them return the same value again and again
503 # if result is not null, then it must also be assigned in the body
506 readable var _body
: ISeq = new ISeq
510 # Is a closure given as a parameter?
514 readable var _closure_decl
: IClosureDecl
516 init(c
: IClosureDecl)
521 redef fun is_pure
do return true
524 #################################################
526 redef class MMAttribute
527 # The attached initialisation iroutine if any
528 # To call between the allocate-instance and the initialize-instance
529 fun iroutine
: nullable IRoutine is abstract
533 # The attached body iroutine if any
534 fun iroutine
: nullable IRoutine is abstract