Merge: doc: fixed some typos and other misc. corrections
[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 AIntegerExpr
94 redef fun accept_printer(v)
95 do
96 v.write(value.to_s)
97 end
98 end
99
100 redef class ANewExpr
101 redef fun accept_printer(v)
102 do
103 v.write("new {mtype.as(not null)}.{callsite.mproperty}")
104 if not n_args.n_exprs.is_empty then
105 v.write("(")
106 v.indent
107 var is_first = true
108 for a in n_args.n_exprs do
109 if is_first then is_first = false else v.write(",")
110 v.enter_visit(a)
111 end
112 v.unindent
113 v.write(")")
114 end
115 end
116 end
117
118 redef class ASendExpr
119 redef fun accept_printer(v)
120 do
121 v.enter_visit(n_expr)
122 v.write(".{callsite.mproperty.name}")
123 if not raw_arguments.is_empty then
124 v.write("(")
125 v.indent
126 var is_first = true
127 for a in raw_arguments do
128 if is_first then is_first = false else v.write(",")
129 v.enter_visit(a)
130 end
131 v.unindent
132 v.write(")")
133 end
134 end
135 end
136
137 redef class AVarExpr
138 redef fun accept_printer(v)
139 do
140 var name = variable.name
141 if name == "" then name = "t{variable.object_id}"
142 v.write(name)
143 end
144 end
145
146 redef class AVarAssignExpr
147 redef fun accept_printer(v)
148 do
149 var name = variable.name
150 if name == "" then name = "t{variable.object_id}"
151 v.write("{name} = ")
152 v.indent
153 v.enter_visit(n_value)
154 v.unindent
155 end
156 end