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 var _ids
: HashMap[Object, String] = new HashMap[Object, String]
69 var _last_value
: Int = 0
71 # Return the name of e
72 # If e is unknown, a new name is gived
73 fun register
(e
: IRegister): String
75 if _ids
.has_key
(e
) then
81 var s
= "r{_last_value}"
87 if e
.in_tag_slots
then
88 s
= "BREG{i}(r{_last_value})"
89 else if e
.is_local
then
90 s
= "LREG{i}(r{_last_value})"
92 s
= "REG{i}(r{_last_value})"
100 # Returns the names of es (separated with comma)
101 fun register_all
(es
: nullable Collection[IRegister]): String
103 if es
== null then return ""
104 var a
= new Array[String]
111 var _last_clos
: Int = 0
113 # Return the name of e
114 # If e is unknown, a new name is gived
115 fun closdecl
(e
: IClosureDecl): String
117 if _ids
.has_key
(e
) then
121 var s
= "clos{_last_clos}"
127 var _last_label
: Int = 0
128 # Return the name of e
129 # If e is unknown, a new name is gived
130 fun lab
(e
: IEscapeMark): String
132 if _ids
.has_key
(e
) then
136 var s
= "[l{_last_label}]"
142 var _last_line
: Int = 0
143 # Return the line index of e
144 fun line
(e
: ICode): String
146 if _ids
.has_key
(e
) then
150 var s
= "{_last_line}"
156 # Is the label e known? (because we goto to it)
157 fun has_lab
(e
: IEscapeMark): Bool
159 return _ids
.has_key
(e
)
165 for i
in [0.._indent_level
[ do
171 var _indent_level
: Int = 0
173 # Indent the next writes
174 fun indent
do _indent_level
+= 1
176 # Outdent the next writes
177 fun unindent
do _indent_level
-= 1
181 # Output the intermediate code representation
182 fun dump
(icd
: ICodeDumper)
190 if result
== null then
191 icd
.write
"{icd.line(self)}: {dump_intern(icd)}{s}"
193 icd
.write
"{icd.line(self)}: {icd.register(result)} := {dump_intern(icd)}{s}"
197 # Output the intermediate code representation (inner method)
198 fun dump_intern
(icd
: ICodeDumper): String do return "???"
202 redef fun dump
(icd
: ICodeDumper)
205 var closure_defs
= closure_defs
206 if closure_defs
!= null then
207 for clos
in closure_defs
do
209 icd
.write
"CLOSURE = NULL"
227 var mark
= iescape_mark
228 if mark
!= null and icd
.has_lab
(mark
) then icd
.write
("{icd.lab(mark)}:")
235 icd
.write
"IF({icd.register(expr)}) \{"
239 icd
.write
"} ELSE \{"
257 var mark
= iescape_mark
258 if mark
!= null and icd
.has_lab
(mark
) then icd
.write
("{icd.lab(mark)}:")
263 redef fun dump_intern
(icd
)
265 return "ESCAPE {icd.lab(iescape_mark)}"
270 redef fun dump_intern
(icd
)
272 return "ABORT (\"{texts.join("\", \"")}\
")"
277 redef fun dump_intern
(icd
)
279 return "CALL {property.full_name}({icd.register_all(exprs)})"
284 redef fun dump_intern
(icd
)
286 return "NEW {stype}.{property.full_name}({icd.register_all(exprs)})"
291 redef fun dump_intern
(icd
)
293 return "SUPER {property.full_name}({icd.register_all(exprs)})"
297 redef class IStaticCall
298 redef fun dump_intern
(icd
)
300 return "STATIC_CALL {property.full_name}({icd.register_all(exprs)})"
304 redef class IAllocateInstance
305 redef fun dump_intern
(icd
)
307 return "ALLOCATE NEW_{stype}"
311 redef class ICheckInstance
312 redef fun dump_intern
(icd
)
314 return "CHECK_INSTANCE CHECKNEW_{stype}({icd.register(expr)})"
318 redef class IInitAttributes
319 redef fun dump_intern
(icd
)
321 return "INIT_ATTRIBUTES INIT_ATTRIBUTES_{stype}({icd.register(expr)})"
325 redef class IClosCall
326 redef fun dump_intern
(icd
)
328 return "CLOS_CALL {icd.closdecl(closure_decl)}({icd.register_all(exprs)})"
332 redef class IAttrRead
333 redef fun dump_intern
(icd
)
335 return "ATTR_READ {property.full_name}({icd.register(expr)})"
339 redef class IAttrWrite
340 redef fun dump_intern
(icd
)
342 return "ATTR_WRITE {property.full_name}({icd.register(expr1)}) := {icd.register(expr2)}"
346 redef class IAttrIsset
347 redef fun dump_intern
(icd
)
349 return "ATTR_ISSET {property.full_name}({icd.register(expr)})"
353 redef class ITypeCheck
354 redef fun dump_intern
(icd
)
356 return "CHECKTYPE {icd.register(expr)} isa {stype}"
361 redef fun dump_intern
(icd
)
363 if exprs
.is_empty
then
364 return "NATIVE \"{code}\
""
366 return "NATIVE \"{code}\
"({icd.register_all(exprs)})"
372 redef fun dump_intern
(icd
)
374 return "{icd.register(expr)}"
379 redef fun dump_intern
(icd
)
381 return "{icd.register(expr1)} is {icd.register(expr2)}"
386 redef fun dump_intern
(icd
)
388 return "NOT {icd.register(expr)}"
395 icd
.write
"{icd.register(result.as(not null))} := ONCE \{"
404 redef fun dump_intern
(icd
)
406 return "HASCLOS {icd.closdecl(closure_decl)}"