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
: ISeq): 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
: ISeq): 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 if icd
.has_lab
(self) then icd
.write
("{icd.lab(self)}:")
234 icd
.write
"IF({icd.register(expr)}) \{"
238 icd
.write
"} ELSE \{"
256 if icd
.has_lab
(self) then icd
.write
("{icd.lab(self)}:")
261 redef fun dump_intern
(icd
)
263 return "ESCAPE {icd.lab(seq)}"
268 redef fun dump_intern
(icd
)
270 return "ABORT (\"{texts.join("\", \"")}\
")"
275 redef fun dump_intern
(icd
)
277 return "CALL {property.full_name}({icd.register_all(exprs)})"
282 redef fun dump_intern
(icd
)
284 return "NEW {stype}.{property.full_name}({icd.register_all(exprs)})"
289 redef fun dump_intern
(icd
)
291 return "SUPER {property.full_name}({icd.register_all(exprs)})"
295 redef class IStaticCall
296 redef fun dump_intern
(icd
)
298 return "STATIC_CALL {property.full_name}({icd.register_all(exprs)})"
302 redef class IAllocateInstance
303 redef fun dump_intern
(icd
)
305 return "ALLOCATE NEW_{stype}"
309 redef class ICheckInstance
310 redef fun dump_intern
(icd
)
312 return "CHECK_INSTANCE CHECKNEW_{stype}({icd.register(expr)})"
316 redef class IInitAttributes
317 redef fun dump_intern
(icd
)
319 return "INIT_ATTRIBUTES INIT_ATTRIBUTES_{stype}({icd.register(expr)})"
323 redef class IClosCall
324 redef fun dump_intern
(icd
)
326 return "CLOS_CALL {icd.closdecl(closure_decl)}({icd.register_all(exprs)})"
330 redef class IAttrRead
331 redef fun dump_intern
(icd
)
333 return "ATTR_READ {property.full_name}({icd.register(expr)})"
337 redef class IAttrWrite
338 redef fun dump_intern
(icd
)
340 return "ATTR_WRITE {property.full_name}({icd.register(expr1)}) := {icd.register(expr2)}"
344 redef class IAttrIsset
345 redef fun dump_intern
(icd
)
347 return "ATTR_ISSET {property.full_name}({icd.register(expr)})"
351 redef class ITypeCheck
352 redef fun dump_intern
(icd
)
354 return "CHECKTYPE {icd.register(expr)} isa {stype}"
359 redef fun dump_intern
(icd
)
361 if exprs
.is_empty
then
362 return "NATIVE \"{code}\
""
364 return "NATIVE \"{code}\
"({icd.register_all(exprs)})"
370 redef fun dump_intern
(icd
)
372 return "{icd.register(expr)}"
377 redef fun dump_intern
(icd
)
379 return "{icd.register(expr1)} is {icd.register(expr2)}"
384 redef fun dump_intern
(icd
)
386 return "NOT {icd.register(expr)}"
393 icd
.write
"{icd.register(result.as(not null))} := ONCE \{"
402 redef fun dump_intern
(icd
)
404 return "HASCLOS {icd.closdecl(closure_decl)}"