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 # Output the intermediate code unded a textual representation
21 import allocate_iregister_slots
24 # Output the intermediate code representation of the iroutine
25 fun dump
(icd
: ICodeDumper)
27 if not params
.is_empty
then
28 var a
= new Array[String]
30 a
.add
(icd
.register
(p
))
32 icd
.write
"Parameters: {a.join(", ")}"
36 icd
.write
"Result: {icd.register(r)}"
38 if std_slots_nb
> 0 then
39 icd
.write
"StdSlots: {std_slots_nb}"
41 if tag_slots_nb
> 0 then
42 icd
.write
"TagSlots: {tag_slots_nb}"
44 var closdecls
= closure_decls
45 if closdecls
!= null then
54 redef class IClosureDecl
55 # Output the intermediate code representation of the iclosuredecl
56 fun dump
(icd
: ICodeDumper)
58 icd
.write
"Closure: {icd.closdecl(self)}"
59 if default
!= null then
68 readable var _dump_locations
: Bool
69 readable var _dump_line_numbers
: Bool
70 var _ids
: HashMap[Object, String] = new HashMap[Object, String]
71 var _last_value
: Int = 0
73 init(dump_locations
: Bool, dump_line_numbers
: Bool) do
74 _dump_locations
= dump_locations
75 _dump_line_numbers
= dump_line_numbers
78 # Return the name of e
79 # If e is unknown, a new name is gived
80 fun register
(e
: IRegister): String
82 if _ids
.has_key
(e
) then
88 var s
= "r{_last_value}"
94 if e
.in_tag_slots
then
95 s
= "BREG{i}(r{_last_value})"
96 else if e
.is_local
then
97 s
= "LREG{i}(r{_last_value})"
99 s
= "REG{i}(r{_last_value})"
107 # Returns the names of es (separated with comma)
108 fun register_all
(es
: nullable Collection[IRegister]): String
110 if es
== null then return ""
111 var a
= new Array[String]
118 var _last_clos
: Int = 0
120 # Return the name of e
121 # If e is unknown, a new name is gived
122 fun closdecl
(e
: IClosureDecl): String
124 if _ids
.has_key
(e
) then
128 var s
= "clos{_last_clos}"
134 var _last_label
: Int = 0
135 # Return the name of e
136 # If e is unknown, a new name is gived
137 fun lab
(e
: IEscapeMark): String
139 if _ids
.has_key
(e
) then
143 var s
= "[l{_last_label}]"
149 var _last_line
: Int = 0
150 # Return the line index of e
151 fun line
(e
: ICode): String
153 if _ids
.has_key
(e
) then
157 var s
= "{_last_line}"
163 # Is the label e known? (because we goto to it)
164 fun has_lab
(e
: IEscapeMark): Bool
166 return _ids
.has_key
(e
)
172 for i
in [0.._indent_level
[ do
178 readable var _indent_level
: Int = 0
180 # Indent the next writes
181 fun indent
do _indent_level
+= 1
183 # Outdent the next writes
184 fun unindent
do _indent_level
-= 1
188 # Output the intermediate code representation
189 fun dump
(icd
: ICodeDumper)
195 if loc
!= null and icd
.dump_locations
then
198 if icd
.dump_line_numbers
then
199 s_line
= "{icd.line(self)}: "
201 if result
== null then
202 icd
.write
"{s_line}{dump_intern(icd)}{s_loc}"
204 icd
.write
"{s_line}{icd.register(result)} := {dump_intern(icd)}{s_loc}"
208 # Output the intermediate code representation (inner method)
209 fun dump_intern
(icd
: ICodeDumper): String do return "???"
213 redef fun dump
(icd
: ICodeDumper)
216 var closure_defs
= closure_defs
217 if closure_defs
!= null then
218 for clos
in closure_defs
do
220 icd
.write
"CLOSURE = NULL"
238 var mark
= iescape_mark
239 if mark
!= null and icd
.has_lab
(mark
) then icd
.write
("{icd.lab(mark)}:")
246 icd
.write
"IF({icd.register(expr)}) \{"
250 icd
.write
"} ELSE \{"
268 var mark
= iescape_mark
269 if mark
!= null and icd
.has_lab
(mark
) then icd
.write
("{icd.lab(mark)}:")
274 redef fun dump_intern
(icd
)
276 return "ESCAPE {icd.lab(iescape_mark)}"
281 redef fun dump_intern
(icd
)
283 return "ABORT (\"{texts.join("\", \"")}\
")"
288 redef fun dump_intern
(icd
)
290 return "CALL {property.full_name}({icd.register_all(exprs)})"
295 redef fun dump_intern
(icd
)
297 return "NEW {stype}.{property.full_name}({icd.register_all(exprs)})"
302 redef fun dump_intern
(icd
)
304 return "SUPER {property.full_name}({icd.register_all(exprs)})"
308 redef class IStaticCall
309 redef fun dump_intern
(icd
)
311 return "STATIC_CALL {property.full_name}({icd.register_all(exprs)})"
315 redef class IAllocateInstance
316 redef fun dump_intern
(icd
)
318 return "ALLOCATE NEW_{stype}"
322 redef class ICheckInstance
323 redef fun dump_intern
(icd
)
325 return "CHECK_INSTANCE CHECKNEW_{stype}({icd.register(expr)})"
329 redef class IInitAttributes
330 redef fun dump_intern
(icd
)
332 return "INIT_ATTRIBUTES INIT_ATTRIBUTES_{stype}({icd.register(expr)})"
336 redef class IClosCall
337 redef fun dump_intern
(icd
)
339 return "CLOS_CALL {icd.closdecl(closure_decl)}({icd.register_all(exprs)})"
343 redef class IAttrRead
344 redef fun dump_intern
(icd
)
346 return "ATTR_READ {property.full_name}({icd.register(expr)})"
350 redef class IAttrWrite
351 redef fun dump_intern
(icd
)
353 return "ATTR_WRITE {property.full_name}({icd.register(expr1)}) := {icd.register(expr2)}"
357 redef class IAttrIsset
358 redef fun dump_intern
(icd
)
360 return "ATTR_ISSET {property.full_name}({icd.register(expr)})"
364 redef class ITypeCheck
365 redef fun dump_intern
(icd
)
367 return "CHECKTYPE {icd.register(expr2)} isa {stype}"
372 redef fun dump_intern
(icd
)
374 return "NATIVE \"{method.full_name}\
"({icd.register_all(exprs)})"
378 redef class IIntValue
379 redef fun dump_intern
(icd
)
381 return "INTVALUE {value}"
385 redef class IBoolValue
386 redef fun dump_intern
(icd
)
388 return "BOOLVALUE {value}"
392 redef class IStringValue
393 redef fun dump_intern
(icd
)
395 return "STRINGVALUE {value}"
399 redef class ICharValue
400 redef fun dump_intern
(icd
)
402 return "CHARVALUE {value}"
406 redef class IFloatValue
407 redef fun dump_intern
(icd
)
409 return "FLOATVALUE {value}"
414 redef fun dump_intern
(icd
)
416 return "{icd.register(expr)}"
421 redef fun dump_intern
(icd
)
423 return "{icd.register(expr1)} is {icd.register(expr2)}"
428 redef fun dump_intern
(icd
)
430 return "NOT {icd.register(expr)}"
437 icd
.write
"{icd.register(result.as(not null))} := ONCE \{"
446 redef fun dump_intern
(icd
)
448 return "HASCLOS {icd.closdecl(closure_decl)}"