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 Closure declaration
37 # The associated closure definition
38 readable var _closure
: MMClosure
40 # The default implementation
41 readable writable var _default
: nullable IRoutine
43 init(c
: MMClosure) do _closure
= c
46 # A routine is a sequence of icodes with entry iregisters (params) and an exit iregister (result)
48 # The parameters of the routine
49 readable var _params
: Sequence[IRegister]
51 # The closure declared
52 readable writable var _closure_decls
: nullable Sequence[IClosureDecl] = null
54 # The local variables (excluding params and result)
55 readable var _registers
: Set[IRegister] = new ArraySet[IRegister]
57 # The result of the routine
58 readable var _result
: nullable IRegister
60 # The sequence of icode
61 readable var _body
: ISeq = new ISeq
63 # The location of the iroutine (if any)
64 readable writable var _location
: nullable Location = null
66 init(p
: Sequence[IRegister], r
: nullable IRegister)
73 # A closure definition in a iroutine body
76 init(p
: Array[IRegister], r
: nullable IRegister)
82 ## INTERMEDIATE CODE ##
84 # The root of the intermediate code representation
86 # The number of registers used by the icode
87 fun arity
: Int is abstract
89 # The result of the icode (if any)
90 readable writable var _result
: nullable IRegister = null
92 # The location of the icode (if any)
93 readable writable var _location
: nullable Location = null
95 # Is the icode side effect free?
96 fun is_pure
: Bool do return false
99 # An icode that uses no registers (no args)
100 abstract class ICode0
102 redef fun arity
do return 0
105 # An icode that uses a single register (1 arg)
106 abstract class ICode1
108 redef fun arity
do return 1
110 # The single argument
111 readable var _expr
: IRegister
113 init(e
: IRegister) do _expr
= e
116 # An icode that uses two single registers (2 args)
117 abstract class ICode2
119 redef fun arity
do return 2
122 readable var _expr1
: IRegister
124 # The second argument
125 readable var _expr2
: IRegister
127 init(e1
, e2
: IRegister)
134 # An icode that uses a variable number of registers (n args) and a variable number of closure definitions
135 abstract class ICodeN
137 redef fun arity
do return _exprs
.length
140 readable var _exprs
: Sequence[IRegister]
142 # All closure definition
143 readable writable var _closure_defs
: nullable Sequence[nullable IClosureDef]
145 init(e
: nullable Sequence[IRegister])
148 _exprs
= new Array[IRegister]
155 #################################################
157 # A linear sequence of ICode
160 # The sequence of icode
161 readable var _icodes
: List[ICode] = new List[ICode]
165 # An infinite loop of ICode
166 # Use IEscape to exit
172 # A Condidianal if-then-else statement
173 # expr is the condition
176 # The 'then' sequence of icode
177 readable var _then_seq
: ISeq = new ISeq
178 # The 'else' sequence of icode
179 readable var _else_seq
: ISeq = new ISeq
180 init(e
: IRegister) do super
183 # Escape to to end of a parent sequence
186 # The seqeuence to escape
187 # The control flow continues at the next icode after the sequence
188 readable var _seq
: ISeq
189 init(seq
: ISeq) do _seq
= seq
195 # The reason the abort occured
196 # tests.first is the format
197 readable var _texts
: Array[String]
198 # The module that has the abort
199 readable var _module_location
: MMModule
200 init(t
: Array[String], ml
: MMModule)
203 _module_location
= ml
207 #################################################
209 # The root of all method invocations
210 abstract class IAbsCall
213 readable var _property
: MMMethod
215 init(p
: MMMethod, e
: Sequence[IRegister])
222 # A simple procedure or function call
223 # exprs.first is the reciever, other are arguments
229 # A super method call
230 # exprs.first is the reciever, other are arguments
237 # no reciever, all exprs are arguments
240 # The type to instantiate
241 readable var _stype
: MMType
242 init(t
: MMType, p
: MMMethod, a
: Sequence[IRegister])
250 # exprs are the arguments
254 readable var _closure_decl
: IClosureDecl
256 # The !break sequence (if any)
257 readable writable var _break_seq
: nullable ISeq = null
259 init(c
: IClosureDecl, e
: Sequence[IRegister])
267 # Mainly used to implements things that do not have a specific ICode yet
268 # expr are the arguments
272 # Special character sequence '@@@' will be substitued in order with the arguments
273 readable var _code
: String
275 init(c
: String, e
: nullable Sequence[IRegister])
281 redef readable writable var _is_pure
: Bool = false
284 # A register assigment
285 # expr is the assigned value
286 # result is the register assigned
289 init(r
: IRegister, e
: IRegister)
295 redef fun is_pure
do return true
298 # An attribute read access
299 # expr is the reciever
302 # The accessed attribute
303 readable var _property
: MMAttribute
305 init(p
: MMAttribute, r
: IRegister)
311 redef fun is_pure
do return true
314 # An attribute assignment
315 # expr1 is the receiver, expr2 is the assigned value
318 # The accessed attribute
319 readable var _property
: MMAttribute
321 init(p
: MMAttribute, r
: IRegister, v
: IRegister)
329 # An attribute is_set check
330 # expr is the reciever
333 # The accessed attribute
334 readable var _property
: MMAttribute
336 init(p
: MMAttribute, r
: IRegister)
342 redef fun is_pure
do return true
346 # expr is the expression checked
349 # The static type checkes to
350 readable var _stype
: MMType
352 init(e
: IRegister, t
: MMType)
358 redef fun is_pure
do return true
362 # expr1 and expr2 are both operands
365 init(e1
, e2
: IRegister)
370 redef fun is_pure
do return true
373 # The unary 'not' operation
374 # expr is the operand
382 redef fun is_pure
do return true
385 # Evaluate body once them return the same value again and again
386 # if result is not null, then it must also be assigned in the body
389 readable var _body
: ISeq = new ISeq
393 # Is a closure given as a parameter?
397 readable var _closure_decl
: IClosureDecl
399 init(c
: IClosureDecl)
404 redef fun is_pure
do return true
407 #################################################
409 redef class MMAttribute
410 # The attached initialisation iroutine if any
411 # To call between the allocate-instance and the initialize-instance
412 fun iroutine
: nullable IRoutine is abstract
416 # The attached body iroutine if any
417 fun iroutine
: nullable IRoutine is abstract