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 var closdecls
= closure_decls
39 if closdecls
!= null then
48 redef class IClosureDecl
49 # Output the intermediate code representation of the iclosuredecl
50 fun dump
(icd
: ICodeDumper)
52 icd
.write
"Closure: {icd.closdecl(self)}"
53 if default
!= null then
62 var _ids
: HashMap[Object, String] = new HashMap[Object, String]
63 var _last_value
: Int = 0
65 # Return the name of e
66 # If e is unknown, a new name is gived
67 fun register
(e
: IRegister): String
69 if _ids
.has_key
(e
) then
75 var s
= "r{_last_value}"
80 var s
= "REG{i}(r{_last_value})"
87 # Returns the names of es (separated with comma)
88 fun register_all
(es
: nullable Collection[IRegister]): String
90 if es
== null then return ""
91 var a
= new Array[String]
98 var _last_clos
: Int = 0
100 # Return the name of e
101 # If e is unknown, a new name is gived
102 fun closdecl
(e
: IClosureDecl): String
104 if _ids
.has_key
(e
) then
108 var s
= "clos{_last_clos}"
114 var _last_label
: Int = 0
115 # Return the name of e
116 # If e is unknown, a new name is gived
117 fun lab
(e
: ISeq): String
119 if _ids
.has_key
(e
) then
123 var s
= "[l{_last_label}]"
129 var _last_line
: Int = 0
130 # Return the line index of e
131 fun line
(e
: ICode): String
133 if _ids
.has_key
(e
) then
137 var s
= "{_last_line}"
143 # Is the label e known? (because we goto to it)
144 fun has_lab
(e
: ISeq): Bool
146 return _ids
.has_key
(e
)
152 for i
in [0.._indent_level
[ do
158 var _indent_level
: Int = 0
160 # Indent the next writes
161 fun indent
do _indent_level
+= 1
163 # Outdent the next writes
164 fun unindent
do _indent_level
-= 1
168 # Output the intermediate code representation
169 fun dump
(icd
: ICodeDumper)
177 if result
== null then
178 icd
.write
"{icd.line(self)}: {dump_intern(icd)}{s}"
180 icd
.write
"{icd.line(self)}: {icd.register(result)} := {dump_intern(icd)}{s}"
184 # Output the intermediate code representation (inner method)
185 fun dump_intern
(icd
: ICodeDumper): String do return "???"
189 redef fun dump
(icd
: ICodeDumper)
192 var closure_defs
= closure_defs
193 if closure_defs
!= null then
194 for clos
in closure_defs
do
196 icd
.write
"CLOSURE = NULL"
214 if icd
.has_lab
(self) then icd
.write
("{icd.lab(self)}:")
221 icd
.write
"IF({icd.register(expr)}) \{"
225 icd
.write
"} ELSE \{"
243 if icd
.has_lab
(self) then icd
.write
("{icd.lab(self)}:")
248 redef fun dump_intern
(icd
)
250 return "ESCAPE {icd.lab(seq)}"
255 redef fun dump_intern
(icd
)
257 return "ABORT (\"{texts.join("\", \"")}\
")"
262 redef fun dump_intern
(icd
)
264 return "CALL {property.full_name}({icd.register_all(exprs)})"
268 redef class IStaticCall
269 redef fun dump_intern
(icd
)
271 return "STATIC_CALL {property.full_name}({icd.register_all(exprs)})"
275 redef class IClosCall
276 redef fun dump_intern
(icd
)
278 return "CLOS_CALL {icd.closdecl(closure_decl)}({icd.register_all(exprs)})"
282 redef class IAttrRead
283 redef fun dump_intern
(icd
)
285 return "ATTR_READ {property.full_name}({icd.register(expr)})"
289 redef class IAttrWrite
290 redef fun dump_intern
(icd
)
292 return "ATTR_WRITE {property.full_name}({icd.register(expr1)}) := {icd.register(expr2)}"
296 redef class IAttrIsset
297 redef fun dump_intern
(icd
)
299 return "ATTR_ISSET {property.full_name}({icd.register(expr)})"
303 redef class ITypeCheck
304 redef fun dump_intern
(icd
)
306 return "CHECKTYPE {icd.register(expr)} isa {stype}"
311 redef fun dump_intern
(icd
)
313 if exprs
.is_empty
then
314 return "NATIVE \"{code}\
""
316 return "NATIVE \"{code}\
"({icd.register_all(exprs)})"
322 redef fun dump_intern
(icd
)
324 return "{icd.register(expr)}"
329 redef fun dump_intern
(icd
)
331 return "{icd.register(expr1)} is {icd.register(expr2)}"
336 redef fun dump_intern
(icd
)
338 return "NOT {icd.register(expr)}"
345 icd
.write
"{icd.register(result.as(not null))} := ONCE \{"
354 redef fun dump_intern
(icd
)
356 return "HASCLOS {icd.closdecl(closure_decl)}"