compiler: Updated toolchain for proper byte literal support
[nit.git] / src / astprinter.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012 Jean Privat <jean@pryen.org>
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 # print AST in an human form
18 module astprinter
19
20 import semantize
21 intrude import parser
22 private import literal
23
24 private class ASTPrinterVisitor
25 super Visitor
26 redef fun visit(node)
27 do
28 node.accept_printer(self)
29 end
30
31 var out = new List[String]
32 var indent_level = 0
33
34 var has_eol = true
35
36 fun eol
37 do
38 if has_eol then return
39 out.add("\n")
40 for x in [0..indent_level[ do out.add("\t")
41 has_eol = true
42 end
43
44 var last_current: nullable ANode = null
45
46 fun write(s: String)
47 do
48 if last_current != current_node then
49 last_current = current_node
50 end
51 out.add(s)
52 has_eol = false
53 end
54
55 fun indent do indent_level += 1
56 fun unindent do indent_level -= 1
57 end
58
59 redef class ANode
60 # print the tree (using the semantic information) on screen
61 # This method is used to debug AST transformations
62 fun print_tree
63 do
64 var v = new ASTPrinterVisitor
65 v.enter_visit(self)
66 v.eol
67 for s in v.out do
68 printn s
69 end
70 end
71
72 private fun accept_printer(v: ASTPrinterVisitor)
73 do
74 v.eol
75 v.write("({inspect}")
76 v.indent
77 visit_all(v)
78 v.write(")")
79 v.unindent
80 end
81 end
82
83 redef class ABlockExpr
84 redef fun accept_printer(v)
85 do
86 for x in n_expr do
87 v.enter_visit(x)
88 v.eol
89 end
90 end
91 end
92
93 redef class AIntExpr
94 redef fun accept_printer(v)
95 do
96 v.write(value.to_s)
97 end
98 end
99
100 redef class AByteExpr
101 redef fun accept_printer(v)
102 do
103 v.write(value.to_s)
104 end
105 end
106
107 redef class ANewExpr
108 redef fun accept_printer(v)
109 do
110 v.write("new {mtype.as(not null)}.{callsite.mproperty}")
111 if not n_args.n_exprs.is_empty then
112 v.write("(")
113 v.indent
114 var is_first = true
115 for a in n_args.n_exprs do
116 if is_first then is_first = false else v.write(",")
117 v.enter_visit(a)
118 end
119 v.unindent
120 v.write(")")
121 end
122 end
123 end
124
125 redef class ASendExpr
126 redef fun accept_printer(v)
127 do
128 v.enter_visit(n_expr)
129 v.write(".{callsite.mproperty.name}")
130 if not raw_arguments.is_empty then
131 v.write("(")
132 v.indent
133 var is_first = true
134 for a in raw_arguments do
135 if is_first then is_first = false else v.write(",")
136 v.enter_visit(a)
137 end
138 v.unindent
139 v.write(")")
140 end
141 end
142 end
143
144 redef class AVarExpr
145 redef fun accept_printer(v)
146 do
147 var name = variable.name
148 if name == "" then name = "t{variable.object_id}"
149 v.write(name)
150 end
151 end
152
153 redef class AVarAssignExpr
154 redef fun accept_printer(v)
155 do
156 var name = variable.name
157 if name == "" then name = "t{variable.object_id}"
158 v.write("{name} = ")
159 v.indent
160 v.enter_visit(n_value)
161 v.unindent
162 end
163 end