mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
ASTDumper.cpp
Go to the documentation of this file.
1#include "parse/ASTDumper.hpp"
2
4
5
6using namespace m;
7using namespace m::ast;
8
9
10void ASTDumper::print_type(const Expr &e) const
11{
12 if (e.has_type()) {
13 out << " of type " << *e.type();
14 if (auto pt = cast<const PrimitiveType>(e.type()))
15 out << (pt->is_scalar() ? " scalar" : " vectorial");
16 }
17}
18
19/*===== Expr =========================================================================================================*/
20
21void ASTDumper::operator()(Const<ErrorExpr> &e)
22{
23 indent() << "ErrorExpr '" << e.tok.text << "' (" << e.tok.pos << ')';
24}
25
26void ASTDumper::operator()(Const<Designator> &e)
27{
28 if (e.has_explicit_table_name()) {
29 indent() << "Designator";
30 print_type(e);
31 ++indent_;
32 indent() << "table name '" << e.table_name.text << "' (" << e.table_name.pos << ')';
33 indent() << "attribute name '" << e.attr_name.text << "' (" << e.attr_name.pos << ')';
34 --indent_;
35 } else {
36 indent() << "Identifier '" << e.attr_name.text << '\'';
37 if (e.has_table_name()) out << " deduced to table '" << e.get_table_name() << '\'';
38 print_type(e);
39 out << " (" << e.attr_name.pos << ')';
40 }
41}
42
43void ASTDumper::operator()(Const<Constant> &e)
44{
45 indent() << "Constant " << e.tok.text;
46 if (e.has_type()) out << " of type " << *e.type();
47 out << " (" << e.tok.pos << ')';
48}
49
50void ASTDumper::operator()(Const<FnApplicationExpr> &e)
51{
52 indent() << "FnApplicationExpr";
53 print_type(e);
54 ++indent_;
55 (*this)(*e.fn);
56 if (not e.args.empty()) {
57 indent() << "args";
58 ++indent_;
59 for (auto &expr : e.args)
60 (*this)(*expr);
61 --indent_;
62 }
63 --indent_;
64}
65
66void ASTDumper::operator()(Const<UnaryExpr> &e)
67{
68 indent() << "UnaryExpr '" << e.op().text << "'";
69 print_type(e);
70 out << " (" << e.op().pos << ')';
71 ++indent_;
72 (*this)(*e.expr);
73 --indent_;
74}
75
76void ASTDumper::operator()(Const<BinaryExpr> &e)
77{
78 indent() << "BinaryExpr '" << e.op().text << "'";
79 print_type(e);
80 out << " (" << e.op().pos << ')';
81 ++indent_;
82 (*this)(*e.lhs);
83 (*this)(*e.rhs);
84 --indent_;
85}
86
87void ASTDumper::operator()(Const<QueryExpr> &e)
88{
89 indent() << "QueryExpr";
90 print_type(e);
91 ++indent_;
92 (*this)(*e.query);
93 --indent_;
94}
95
96
97/*===== Clause =======================================================================================================*/
98
99void ASTDumper::operator()(Const<ErrorClause> &c)
100{
101 indent() << "ErrorClause '" << c.tok.text << "' (" << c.tok.pos << ')';
102}
103
104void ASTDumper::operator()(Const<SelectClause> &c)
105{
106 indent() << "SelectClause (" << c.tok.pos << ')';
107 ++indent_;
108 if (c.select_all)
109 indent() << "* (" << c.select_all.pos << ')';
110 for (auto &s : c.select) {
111 if (s.second) {
112 indent() << "AS '" << s.second.text << "' (" << s.second.pos << ')';
113 ++indent_;
114 (*this)(*s.first);
115 --indent_;
116 } else {
117 (*this)(*s.first);
118 }
119 }
120 --indent_;
121}
122
123void ASTDumper::operator()(Const<FromClause> &c)
124{
125 indent() << "FromClause (" << c.tok.pos << ')';
126 ++indent_;
127 for (auto f : c.from) {
128 if (f.alias) {
129 indent() << "AS '" << f.alias.text << "' (" << f.alias.pos << ')';
130 ++indent_;
131 if (auto tok = std::get_if<Token>(&f.source)) {
132 indent() << tok->text << " (" << tok->pos << ')';
133 } else if (auto stmt = std::get_if<Stmt*>(&f.source)) {
134 (*this)(**stmt);
135 } else {
136 M_unreachable("illegal variant");
137 }
138 --indent_;
139 } else {
140 M_insist(std::holds_alternative<Token>(f.source), "nested statements require an alias");
141 Token &tok = std::get<Token>(f.source);
142 indent() << tok.text << " (" << tok.pos << ')';
143 }
144 }
145 --indent_;
146}
147
148void ASTDumper::operator()(Const<WhereClause> &c)
149{
150 indent() << "WhereClause (" << c.tok.pos << ')';
151 ++indent_;
152 (*this)(*c.where);
153 --indent_;
154}
155
156
157void ASTDumper::operator()(Const<GroupByClause> &c)
158{
159 indent() << "GroupByClause (" << c.tok.pos << ')';
160 ++indent_;
161 for (auto &[expr, alias] : c.group_by) {
162 if (alias)
163 indent() << "AS '" << alias.text << "' (" << alias.pos << ')';
164 ++indent_;
165 (*this)(*expr);
166 --indent_;
167 }
168 --indent_;
169}
170
171void ASTDumper::operator()(Const<HavingClause> &c)
172{
173 indent() << "HavingClause (" << c.tok.pos << ')';
174 ++indent_;
175 (*this)(*c.having);
176 --indent_;
177}
178
179void ASTDumper::operator()(Const<OrderByClause> &c)
180{
181 indent() << "OrderByClause (" << c.tok.pos << ')';
182 ++indent_;
183 for (auto &o : c.order_by) {
184 indent() << (o.second ? "ASC" : "DESC");
185 ++indent_;
186 (*this)(*o.first);
187 --indent_;
188 }
189 --indent_;
190}
191
192void ASTDumper::operator()(Const<LimitClause> &c)
193{
194 indent() << "LimitClause (" << c.tok.pos << ')';
195 ++indent_;
196
197 indent() << "LIMIT " << c.limit.text << " (" << c.limit.pos << ')';
198
199 if (c.offset)
200 indent() << "OFFSET " << c.offset.text << " (" << c.offset.pos << ')';
201
202 --indent_;
203}
204
205
206/*===== Constraint ===================================================================================================*/
207
208void ASTDumper::operator()(Const<PrimaryKeyConstraint> &c)
209{
210 indent() << "PrimaryKeyConstraint (" << c.tok.pos << ')';
211}
212
213void ASTDumper::operator()(Const<UniqueConstraint> &c)
214{
215 indent() << "UniqueConstraint (" << c.tok.pos << ')';
216}
217
218void ASTDumper::operator()(Const<NotNullConstraint> &c)
219{
220 indent() << "NotNullConstraint (" << c.tok.pos << ')';
221}
222
223void ASTDumper::operator()(Const<CheckConditionConstraint> &c)
224{
225 indent() << "CheckConditionConstraint (" << c.tok.pos << ')';
226 ++indent_;
227 (*this)(*c.cond);
228 --indent_;
229}
230
231void ASTDumper::operator()(Const<ReferenceConstraint> &c)
232{
233 indent() << "ReferenceConstraint (" << c.tok.pos << ')';
234 ++indent_;
235 indent() << c.table_name.text << '(' << c.attr_name.text << ')';
236 --indent_;
237}
238
239
240/*===== Instruction ==================================================================================================*/
241
242void ASTDumper::operator()(Const<Instruction> &inst)
243{
244 out << "Instruction(" << inst.name;
245 for (auto &arg : inst.args)
246 out << ", " << arg;
247 out << ')';
248}
249
250
251/*===== Stmt =========================================================================================================*/
252
253void ASTDumper::operator()(Const<ErrorStmt> &s)
254{
255 indent() << "ErrorStmt: '" << s.tok.text << "' (" << s.tok.pos << ')';
256}
257
258void ASTDumper::operator()(Const<EmptyStmt> &s)
259{
260 indent() << "EmptyStmt: '" << s.tok.text << "' (" << s.tok.pos << ')';
261}
262
263void ASTDumper::operator()(Const<CreateDatabaseStmt> &s)
264{
265 indent() << "CreateDatabaseStmt: '" << s.database_name.text << "' (" << s.database_name.pos << ')';
266}
267
268void ASTDumper::operator()(Const<DropDatabaseStmt> &s)
269{
270 indent() << "DropDatabaseStmt: '" << s.database_name.text << "' (" << s.database_name.pos << ')';
271 ++indent_;
272 if (s.has_if_exists)
273 indent() << "if exists: true";
274 --indent_;
275}
276
277void ASTDumper::operator()(Const<UseDatabaseStmt> &s)
278{
279 indent() << "UseDatabaseStmt: '" << s.database_name.text << "' (" << s.database_name.pos << ')';
280}
281
282void ASTDumper::operator()(Const<CreateTableStmt> &s)
283{
284 indent() << "CreateTableStmt: table " << s.table_name.text << " (" << s.table_name.pos << ')';
285 ++indent_;
286 indent() << "attributes";
287 ++indent_;
288 for (auto &attr : s.attributes) {
289 indent() << attr->name.text << " : " << *attr->type << " (" << attr->name.pos << ')';
290 ++indent_;
291 for (auto &c : attr->constraints) {
292 if (is<PrimaryKeyConstraint>(c)) {
293 indent() << "PRIMARY KEY (" << c->tok.pos << ')';
294 } else if (is<UniqueConstraint>(c)) {
295 indent() << "UNIQUE (" << c->tok.pos << ')';
296 } else if (is<NotNullConstraint>(c)) {
297 indent() << "NOT NULL (" << c->tok.pos << ')';
298 } else if (auto check = cast<CheckConditionConstraint>(c.get())) {
299 indent() << "CHECK (" << c->tok.pos << ')';
300 ++indent_;
301 (*this)(*check->cond);
302 --indent_;
303 } else if (auto ref = cast<ReferenceConstraint>(c.get())) {
304 indent() << "REFERENCES " << ref->table_name.text << '(' << ref->attr_name.text << ") (" << c->tok.pos
305 << ')';
306 } else {
307 M_unreachable("invalid constraint");
308 }
309 }
310 --indent_;
311 }
312 --indent_;
313 --indent_;
314}
315
316void ASTDumper::operator()(Const<DropTableStmt> &s)
317{
318 indent() << "DropTableStmt:";
319 ++indent_;
320 indent() << "tables";
321 ++indent_;
322 for (auto &table_name : s.table_names)
323 indent() << table_name->text << " (" << table_name->pos << ')';
324 --indent_;
325 if (s.has_if_exists)
326 indent() << "if exists: true";
327 --indent_;
328}
329
330void ASTDumper::operator()(Const<CreateIndexStmt> &s)
331{
332 indent() << "CreateIndexStmt:";
333 ++indent_;
334
335 if (s.has_unique)
336 indent() << "unique: true";
337 if (s.has_if_not_exists)
338 indent() << "if not exists: true";
339 if (s.index_name)
340 indent() << "index name: " << s.index_name.text;
341 if (s.method)
342 indent() << "method: " << s.method.text;
343
344 indent() << "table name: " << s.table_name.text;
345 indent() << "fields";
346 ++indent_;
347 for (auto &expr : s.key_fields) (*this)(*expr);
348 --indent_;
349 --indent_;
350}
351
352void ASTDumper::operator()(Const<DropIndexStmt> &s)
353{
354 indent() << "DropIndexStmt:";
355 ++indent_;
356
357 if (s.has_if_exists)
358 indent() << "if exists: true";
359
360 indent() << "indexes";
361 ++indent_;
362 for (auto &idx : s.index_names) indent() << (*idx).text;
363 --indent_;
364 --indent_;
365
366}
367
368void ASTDumper::operator()(Const<SelectStmt> &s)
369{
370 indent() << "SelectStmt";
371 ++indent_;
372
373 (*this)(*s.select);
374
375 if (s.from) (*this)(*s.from);
376 if (s.where) (*this)(*s.where);
377 if (s.group_by) (*this)(*s.group_by);
378 if (s.having) (*this)(*s.having);
379 if (s.order_by) (*this)(*s.order_by);
380 if (s.limit) (*this)(*s.limit);
381
382 --indent_;
383}
384
385void ASTDumper::operator()(Const<InsertStmt> &s)
386{
387 indent() << "InsertStmt: table " << s.table_name.text << " (" << s.table_name.pos << ')';
388 ++indent_;
389 indent() << "values";
390 ++indent_;
391 for (std::size_t idx = 0, end = s.tuples.size(); idx != end; ++idx) {
392 indent() << '[' << idx << ']';
393 const InsertStmt::tuple_t &v = s.tuples[idx];
394 ++indent_;
395 for (auto &e : v) {
396 switch (e.first) {
398 indent() << "DEFAULT";
399 break;
400
402 indent() << "NULL";
403 break;
404
406 (*this)(*e.second);
407 break;
408 }
409 }
410 --indent_;
411 }
412 --indent_;
413 --indent_;
414}
415
416void ASTDumper::operator()(Const<UpdateStmt> &s)
417{
418 indent() << "UpdateStmt: table " << s.table_name.text << " (" << s.table_name.pos << ')';
419 ++indent_;
420 indent() << "set";
421 ++indent_;
422 for (auto &s : s.set) {
423 indent() << s.first.text << " (" << s.first.pos << ')';
424 ++indent_;
425 (*this)(*s.second);
426 --indent_;
427 }
428 --indent_;
429
430 if (s.where) (*this)(*s.where);
431
432 --indent_;
433}
434
435void ASTDumper::operator()(Const<DeleteStmt> &s)
436{
437 indent() << "DeleteStmt: table " << s.table_name.text << " (" << s.table_name.pos << ')';
438
439 if (s.where) {
440 ++indent_;
441 (*this)(*s.where);
442 --indent_;
443 }
444}
445
446void ASTDumper::operator()(Const<DSVImportStmt> &s)
447{
448 indent() << "ImportStmt (DSV): table " << s.table_name.text << " (" << s.table_name.pos << ')';
449
450 ++indent_;
451 indent() << s.path.text << " (" << s.path.pos << ')';
452 if (s.rows)
453 indent() << "rows " << s.rows.text << " (" << s.rows.pos << ')';
454 if (s.delimiter)
455 indent() << "delimiter " << s.delimiter.text << " (" << s.delimiter.pos << ')';
456 if (s.has_header)
457 indent() << "HAS HEADER";
458 if (s.skip_header)
459 indent() << "SKIP HEADER";
460 --indent_;
461}
#define M_unreachable(MSG)
Definition: macro.hpp:146
#define M_insist(...)
Definition: macro.hpp:129
std::ostream & indent(std::ostream &out, unsigned indentation)
Start a new line with proper indentation.
Definition: DataLayout.cpp:100
‍mutable namespace
Definition: Backend.hpp:10
int indent_
the current level of indentation
Definition: ASTDumper.hpp:15
std::ostream & out
the output stream to write to
Definition: ASTDumper.hpp:13
An expression.
Definition: AST.hpp:39
bool has_type() const
Returns true iff this Expr has been assigned a Type, most likely by Sema.
Definition: AST.hpp:63
const Type * type() const
Returns the Type of this Expr.
Definition: AST.hpp:58
std::vector< element_type > tuple_t
Definition: AST.hpp:970
ThreadSafePooledOptionalString text
declared as optional for dummy tokens
Definition: Token.hpp:16
Position pos
Definition: Token.hpp:15