Yume
visit.cpp
Go to the documentation of this file.
1#include "ast.hpp"
2
5#include "util.hpp"
6#include <concepts>
7#include <ranges>
8#include <string>
9#include <variant>
10#include <vector>
11
12namespace yume::ast {
13
14namespace {
15
16struct VisitorHelper {
17 Visitor& visitor;
18
19 auto visit(const ast::AST& value, string_view label) -> auto& { return visitor.visit(value, label), *this; }
20 auto visit(std::nullptr_t value, string_view label) -> auto& { return visitor.visit(value, label), *this; }
21 auto visit(const string& value, string_view label) -> auto& { return visitor.visit(value, label), *this; }
22
23 template <typename T> auto visit(const ast::OptionalAnyBase<T>& any_base, string_view label) -> auto& {
24 if (any_base.raw_ptr() != nullptr)
25 return visit(*any_base, label);
26 return visit(nullptr, label);
27 }
28
29 template <typename T> auto maybe(const ast::OptionalAnyBase<T>& any_base, string_view label) -> auto& {
30 if (any_base.raw_ptr() != nullptr)
31 return visit(*any_base, label);
32 return *this;
33 }
34
35 template <typename T> auto visit(const ast::AnyBase<T>& any_base, string_view label) -> auto& {
36 YUME_ASSERT(any_base.raw_ptr() != nullptr, "AnyBase should never be null");
37 return visit(*any_base, label);
38 }
39
40 template <std::ranges::range Range>
41 requires (!std::convertible_to<Range, const char*>)
42 auto visit(const Range& iter, string_view label) -> auto& {
43 for (auto& i : iter)
44 visit(i, label);
45 return *this;
46 }
47
48 template <typename T> auto visit(const optional<T>& opt, string_view label) -> auto& {
49 if (opt.has_value())
50 visit(*opt, label);
51 return *this;
52 }
53
54 template <visitable T> auto visit(const T& var, string_view label) -> auto& {
55 var.visit([this, label](auto&& x) { this->visit(std::forward<decltype(x)>(x), label); });
56 return *this;
57 }
58
59 template <typename T> auto visit(std::pair<T, string_view>& pair) -> auto& { return visit(pair.first, pair.second); }
60
61 auto visit(std::same_as<bool> auto value, string_view label) -> auto& {
62 return visit(value ? "true" : "false", label);
63 }
64
65 auto maybe(bool value, string_view label) -> auto& {
66 if (value)
67 visit("true", label);
68 return *this;
69 }
70};
71
72auto helper(Visitor& visitor) { return VisitorHelper{visitor}; }
73} // namespace
74
75void IfStmt::visit(Visitor& visitor) const { helper(visitor).visit(clauses, "clause").visit(else_clause, "else"); }
76void IfClause::visit(Visitor& visitor) const { helper(visitor).visit(cond, "cond").visit(body, "body"); }
77void NumberExpr::visit(Visitor& visitor) const { helper(visitor).visit(describe(), "value"); }
78void StringExpr::visit(Visitor& visitor) const { helper(visitor).visit(val, "value"); }
79void CharExpr::visit(Visitor& visitor) const { helper(visitor).visit(string{static_cast<char>(val)}, "value"); }
80void BoolExpr::visit(Visitor& visitor) const { helper(visitor).visit(describe(), "value"); }
81void ReturnStmt::visit(Visitor& visitor) const { helper(visitor).visit(expr, "expr"); }
82void WhileStmt::visit(Visitor& visitor) const { helper(visitor).visit(cond, "cond").visit(body, "body"); }
84 helper(visitor).visit(name, "name").visit(type, "type").visit(init, "init");
85}
87 helper(visitor).visit(name, "name").visit(type, "type").visit(init, "init");
88}
90 auto vis = helper(visitor)
91 .visit(name, "name")
92 .visit(args, "arg")
93 .visit(type_args, "type-arg")
94 .visit(annotations, "annotation")
95 .maybe(ret, "ret");
96
97 body.visit([&](const string& s) { vis.visit(s, "primitive"); },
98 [&](const extern_decl_t& s) { vis.visit(s.name, "extern").maybe(s.varargs, "varargs"); },
99 [&](const Compound& s) { vis.visit(s, "body"); },
100 [&](const abstract_decl_t& /*s*/) { vis.visit(true, "abstract"); });
101}
102void CtorDecl::visit(Visitor& visitor) const { helper(visitor).visit(args, "arg").visit(body, "body"); }
104 helper(visitor)
105 .visit(name, "name")
106 .maybe(implements, "implements")
107 .visit(fields, "field")
108 .visit(type_args, "type-arg")
109 .visit(body, "body")
110 .visit(annotations, "annotation")
111 .maybe(is_interface, "interface");
112}
113void SimpleType::visit(Visitor& visitor) const { helper(visitor).visit(name, "name"); }
114void QualType::visit(Visitor& visitor) const { helper(visitor).visit(base, describe().c_str()); }
115void TemplatedType::visit(Visitor& visitor) const { helper(visitor).visit(base, "base").visit(type_args, "type-arg"); }
117 helper(visitor).visit(ret, "ret").visit(args, "args").maybe(fn_ptr, "fn-ptr");
118}
119void ProxyType::visit(Visitor& visitor) const { helper(visitor).visit(field, "field"); }
120void TypeName::visit(Visitor& visitor) const { helper(visitor).visit(name, "name").visit(type, "type"); }
121void GenericParam::visit(Visitor& visitor) const { helper(visitor).visit(name, "name").visit(type, "type"); }
122void Compound::visit(Visitor& visitor) const { helper(visitor).visit(body, "body"); }
123void VarExpr::visit(Visitor& visitor) const { helper(visitor).visit(name, "name"); }
124void ConstExpr::visit(Visitor& visitor) const { helper(visitor).visit(name, "name").visit(parent, "name"); }
126 helper(visitor).visit(name, "name").maybe(receiver, "receiver").visit(args, "args");
127}
129 helper(visitor).visit(string{operation}, "operation").visit(lhs, "lhs").visit(rhs, "rhs");
130}
131void CtorExpr::visit(Visitor& visitor) const { helper(visitor).visit(type, "type").visit(args, "args"); }
132void DtorExpr::visit(Visitor& visitor) const { helper(visitor).visit(base, "base"); }
133void SliceExpr::visit(Visitor& visitor) const { helper(visitor).visit(type, "type").visit(args, "args"); }
135 helper(visitor).visit(args, "args").visit(annotations, "annotation").visit(ret, "ret").visit(body, "body");
136}
137void AssignExpr::visit(Visitor& visitor) const { helper(visitor).visit(target, "target").visit(value, "value"); }
138void FieldAccessExpr::visit(Visitor& visitor) const { helper(visitor).visit(base, "base").visit(field, "field"); }
140 helper(visitor).visit(conversion.to_string(), "conversion").visit(base, "base");
141}
142void TypeExpr::visit(Visitor& visitor) const { helper(visitor).visit(type, "type"); }
143void Program::visit(Visitor& visitor) const { helper(visitor).visit(body, "body"); }
144
145} // namespace yume::ast
Definition: ast.cpp:8
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:137
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:128
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:80
auto describe() const -> string override
A short, string representation for debugging.
Definition: ast.hpp:514
OptionalType receiver
Definition: ast.hpp:565
vector< AnyExpr > args
Definition: ast.hpp:566
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:125
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:79
A statement consisting of multiple other statements, i.e. the body of a function.
Definition: ast.hpp:712
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:122
vector< AnyStmt > body
Definition: ast.hpp:714
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:86
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:124
optional< string > parent
Definition: ast.hpp:550
Compound body
Definition: ast.hpp:835
vector< TypeName > args
Definition: ast.hpp:834
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:102
vector< AnyExpr > args
Definition: ast.hpp:600
AnyType type
Definition: ast.hpp:599
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:131
AnyExpr base
Definition: ast.hpp:621
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:132
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:138
OptionalExpr base
Definition: ast.hpp:668
Body body
If this function declaration refers to a primitive, this field is a string representing the name of t...
Definition: ast.hpp:786
{ string name extern_decl_t
Definition: ast.hpp:765
vector< TypeName > args
Definition: ast.hpp:780
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:89
std::unordered_set< string > annotations
Definition: ast.hpp:779
{} abstract_decl_t
Definition: ast.hpp:768
vector< GenericParam > type_args
Definition: ast.hpp:781
string name
Definition: ast.hpp:778
OptionalType ret
Definition: ast.hpp:782
OptionalType ret
Definition: ast.hpp:382
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:116
vector< AnyType > args
Definition: ast.hpp:383
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:121
OptionalType type
Definition: ast.hpp:423
Compound body
Definition: ast.hpp:920
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:76
AnyExpr cond
Definition: ast.hpp:919
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:75
optional< Compound > else_clause
Definition: ast.hpp:933
vector< IfClause > clauses
Definition: ast.hpp:932
ty::Conv conversion
The conversion steps performed during this cast.
Definition: ast.hpp:689
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:139
OptionalType ret
Definition: ast.hpp:732
vector< TypeName > args
Definition: ast.hpp:731
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:134
std::set< string > annotations
Definition: ast.hpp:734
auto describe() const -> string override
A short, string representation for debugging.
Definition: ast.hpp:488
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:77
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:143
vector< AnyStmt > body
Definition: ast.hpp:959
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:119
AnyType base
Definition: ast.hpp:343
auto describe() const -> string override
A short, string representation for debugging.
Definition: describe.cpp:12
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:114
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:81
OptionalExpr expr
Definition: ast.hpp:946
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:113
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:133
vector< AnyExpr > args
Definition: ast.hpp:635
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:78
vector< GenericParam > type_args
Definition: ast.hpp:851
std::unordered_set< string > annotations
Definition: ast.hpp:854
OptionalType implements
Definition: ast.hpp:853
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:103
vector< TypeName > fields
Definition: ast.hpp:850
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:115
vector< AnyTypeOrExpr > type_args
Definition: ast.hpp:470
AnyType type
Definition: ast.hpp:702
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:142
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:120
AnyType type
Definition: ast.hpp:397
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:83
AnyExpr init
Definition: ast.hpp:876
OptionalType type
Definition: ast.hpp:875
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:123
Compound body
Definition: ast.hpp:907
void visit(Visitor &visitor) const override
Recursively visit this ast node and all its constituents.
Definition: visit.cpp:82
auto to_string() const -> string
auto visit(Us... us) -> decltype(auto)
Definition: util.hpp:55
#define YUME_ASSERT(assertion, message)
Definition: util.hpp:81
Visitor & visitor
Definition: visit.cpp:17