VapourSynth-llvmexpr
Loading...
Searching...
No Matches
ASTPrinter.cpp
Go to the documentation of this file.
1
19
20#include "ASTPrinter.hpp"
21#include "Builtins.hpp"
23
24#include <cctype>
25#include <cstring>
26
27namespace infix2postfix {
28
29std::string ASTPrinter::print(const Program* program) {
30 ss.str("");
31 ss.clear();
32 indent_level = 0;
33 if (program != nullptr) {
34 for (const auto& stmt : program->statements) {
35 print(stmt.get());
36 }
37 }
38 return ss.str();
39}
40
41void ASTPrinter::print(const Stmt* stmt) {
42 if (stmt == nullptr) {
43 return;
44 }
45 std::visit([this](const auto& s) { this->visit(s); }, stmt->value);
46}
47
48void ASTPrinter::print(const Expr* expr) {
49 if (expr == nullptr) {
50 line("<null expr>");
51 return;
52 };
53 std::visit([this](const auto& e) { this->visit(e); }, expr->value);
54}
55
56void ASTPrinter::indent() { indent_level++; }
57
58void ASTPrinter::unindent() { indent_level--; }
59
60// Stmt visitors
61void ASTPrinter::visit(const ExprStmt& stmt) {
62 line("ExprStmt:");
63 indent();
64 print(stmt.expr.get());
65 unindent();
66}
67
68void ASTPrinter::visit(const AssignStmt& stmt) {
69 line("AssignStmt: {}", stmt.name.value);
70 if (stmt.symbol) {
71 indent();
72 std::string type_name = std::string(enum_name(stmt.symbol->type));
73 line("Symbol: {} (type: {})", stmt.symbol->name, type_name);
74 unindent();
75 }
76 indent();
77 line("Value:");
78 indent();
79 print(stmt.value.get());
80 unindent();
81 unindent();
82}
83
84void ASTPrinter::visit(const ArrayAssignStmt& stmt) {
85 line("ArrayAssignStmt:");
86 indent();
87 line("Target:");
88 indent();
89 print(stmt.target.get());
90 unindent();
91 line("Value:");
92 indent();
93 print(stmt.value.get());
94 unindent();
95 unindent();
96}
97
98void ASTPrinter::visit(const BlockStmt& stmt) {
99 line("BlockStmt:");
100 indent();
101 for (const auto& s : stmt.statements) {
102 print(s.get());
103 }
104 unindent();
105}
106
107void ASTPrinter::visit(const IfStmt& stmt) {
108 line("IfStmt:");
109 indent();
110 line("Condition:");
111 indent();
112 print(stmt.condition.get());
113 unindent();
114 line("Then:");
115 indent();
116 print(stmt.then_branch.get());
117 unindent();
118 if (stmt.else_branch) {
119 line("Else:");
120 indent();
121 print(stmt.else_branch.get());
122 unindent();
123 }
124 unindent();
125}
126
127void ASTPrinter::visit(const WhileStmt& stmt) {
128 line("WhileStmt:");
129 indent();
130 line("Condition:");
131 indent();
132 print(stmt.condition.get());
133 unindent();
134 line("Body:");
135 indent();
136 print(stmt.body.get());
137 unindent();
138 unindent();
139}
140
141void ASTPrinter::visit(const ReturnStmt& stmt) {
142 line("ReturnStmt:");
143 if (stmt.value) {
144 indent();
145 print(stmt.value.get());
146 unindent();
147 }
148}
149
150void ASTPrinter::visit(const LabelStmt& stmt) {
151 line("LabelStmt: {}", stmt.name.value);
152 if (stmt.symbol) {
153 indent();
154 line("Symbol: {}", stmt.symbol->name);
155 unindent();
156 }
157}
158
159void ASTPrinter::visit(const GotoStmt& stmt) {
160 line("GotoStmt: {}", stmt.label.value);
161 if (stmt.target_label_symbol) {
162 indent();
163 line("Target Symbol: {}", stmt.target_label_symbol->name);
164 unindent();
165 }
166 if (stmt.condition) {
167 indent();
168 line("Condition:");
169 indent();
170 print(stmt.condition.get());
171 unindent();
172 unindent();
173 }
174}
175
176void ASTPrinter::visit(const GlobalDecl& stmt) {
177 std::string mode_name = std::string(enum_name(stmt.mode));
178 line("GlobalDecl: mode={}", mode_name);
179 if (stmt.mode == GlobalMode::Specific) {
180 indent();
181 for (const auto& g : stmt.globals) {
182 line("Global: {}", g.value);
183 }
184 unindent();
185 }
186}
187
188void ASTPrinter::visit(const FunctionDef& stmt) {
189 line("FunctionDef: {}", stmt.name.value);
190 if (stmt.symbol) {
191 indent();
192 line("Symbol: {}", stmt.symbol->name);
193 unindent();
194 }
195 indent();
196 if (!stmt.params.empty()) {
197 line("Params:");
198 indent();
199 for (const auto& p : stmt.params) {
200 std::string type_name = std::string(enum_name(p.type));
201 line("Param: {} (type: {})", p.name.value, type_name);
202 }
203 unindent();
204 }
205 if (stmt.global_decl) {
206 visit(*stmt.global_decl);
207 }
208 line("Body:");
209 indent();
210 if (stmt.body) {
211 visit(*stmt.body);
212 }
213 unindent();
214 unindent();
215}
216
217// Expr visitors
218void ASTPrinter::visit(const NumberExpr& expr) {
219 line("NumberExpr: {}", expr.value.value);
220}
221
222void ASTPrinter::visit(const VariableExpr& expr) {
223 line("VariableExpr: {}", expr.name.value);
224 if (expr.symbol) {
225 indent();
226 std::string type_name = std::string(enum_name(expr.symbol->type));
227 line("Symbol: {} (type: {})", expr.symbol->name, type_name);
228 unindent();
229 }
230}
231
232void ASTPrinter::visit(const UnaryExpr& expr) {
233 line("UnaryExpr: {}", expr.op.value);
234 indent();
235 print(expr.right.get());
236 unindent();
237}
238
239void ASTPrinter::visit(const BinaryExpr& expr) {
240 line("BinaryExpr: {}", expr.op.value);
241 indent();
242 line("Left:");
243 indent();
244 print(expr.left.get());
245 unindent();
246 line("Right:");
247 indent();
248 print(expr.right.get());
249 unindent();
250 unindent();
251}
252
253void ASTPrinter::visit(const TernaryExpr& expr) {
254 line("TernaryExpr:");
255 indent();
256 line("Condition:");
257 indent();
258 print(expr.cond.get());
259 unindent();
260 line("True:");
261 indent();
262 print(expr.true_expr.get());
263 unindent();
264 line("False:");
265 indent();
266 print(expr.false_expr.get());
267 unindent();
268 unindent();
269}
270
271void ASTPrinter::visit(const CallExpr& expr) {
272 line("CallExpr: {}", expr.callee);
273 if (expr.resolved_signature != nullptr) {
274 indent();
275 line("Resolved to user function: {}", expr.resolved_signature->name);
276 unindent();
277 }
278 if (expr.resolved_builtin != nullptr) {
279 indent();
280 line("Resolved to builtin: {}", expr.resolved_builtin->name);
281 unindent();
282 }
283 if (expr.resolved_def != nullptr) {
284 indent();
285 line("Resolved def: {}", expr.resolved_def->name.value);
286 unindent();
287 }
288 if (!expr.args.empty()) {
289 indent();
290 line("Args:");
291 indent();
292 for (const auto& arg : expr.args) {
293 print(arg.get());
294 }
295 unindent();
296 unindent();
297 }
298}
299
300void ASTPrinter::visit(const PropAccessExpr& expr) {
301 line("PropAccessExpr: {}.{}", expr.clip.value, expr.prop.value);
302}
303
304void ASTPrinter::visit(const StaticRelPixelAccessExpr& expr) {
305 line("StaticRelPixelAccessExpr: {}[{},{}]{}", expr.clip.value,
306 expr.offset_x.value, expr.offset_y.value, expr.boundary_suffix);
307}
308
309void ASTPrinter::visit(const FrameDimensionExpr& expr) {
310 line("FrameDimensionExpr: {}.{}", "frame", expr.dimension_name);
311 indent();
312 line("Plane:");
313 indent();
314 print(expr.plane_index_expr.get());
315 unindent();
316 unindent();
317}
318
319void ASTPrinter::visit(const ArrayAccessExpr& expr) {
320 line("ArrayAccessExpr:");
321 if (expr.array_symbol) {
322 indent();
323 line("Array Symbol: {}", expr.array_symbol->name);
324 unindent();
325 }
326 indent();
327 line("Array:");
328 indent();
329 print(expr.array.get());
330 unindent();
331 line("Index:");
332 indent();
333 print(expr.index.get());
334 unindent();
335 unindent();
336}
337
338} // namespace infix2postfix
consteval std::string_view enum_name()
Definition EnumName.hpp:57
std::string print(const Program *program)
std::vector< std::unique_ptr< Stmt > > statements
Definition AST.hpp:415
StmtVariant value
Definition AST.hpp:265