Yume
ast.cpp
Go to the documentation of this file.
1#include "ast.hpp"
2
4#include "token.hpp"
5#include <memory>
6#include <stdexcept>
7
8namespace yume::ast {
9
11 for (const auto* other : m_attach->depends) {
12 if (m_val_ty == other->m_val_ty || !other->m_val_ty)
13 return;
14
15 if (!m_val_ty) {
16 m_val_ty = other->m_val_ty;
17 } else {
18 const auto merged = m_val_ty->coalesce(*other->m_val_ty);
19 if (!merged) {
20 throw std::logic_error("Conflicting types between AST nodes that are attached: `"s + m_val_ty->name() +
21 "` vs `" + other->m_val_ty->name() + "`!");
22 }
23 m_val_ty = merged;
24 }
25 }
26}
27
28auto AST::location() const -> Loc {
29 if (m_tok.empty())
30 return Loc{};
31 if (m_tok.size() == 1)
32 return m_tok[0].loc;
33
34 return m_tok[0].loc + m_tok[m_tok.size() - 1].loc;
35}
36
37auto AST::equals_by_hash(ast::AST& other) const -> bool {
38 auto this_hash = std::hash<ast::AST>{}(*this);
39 auto other_hash = std::hash<ast::AST>{}(other);
40
41 return this_hash == other_hash;
42}
43
44namespace {
45template <typename T> auto dup(const vector<AnyBase<T>>& items) {
46 auto dup = vector<AnyBase<T>>();
47 dup.reserve(items.size());
48 for (auto& i : items)
49 dup.emplace_back(unique_ptr<T>(i->clone()));
50
51 return dup;
52}
53
54template <typename T> auto dup(const OptionalAnyBase<T>& ptr) -> OptionalAnyBase<T> {
55 if (ptr)
56 return unique_ptr<T>(ptr->clone());
57 return {};
58}
59template <typename T> auto dup(const AnyBase<T>& ptr) -> AnyBase<T> { return unique_ptr<T>(ptr->clone()); }
60
61template <std::derived_from<ast::AST> T> auto dup(const T& ast) -> T {
62 auto cloned = unique_ptr<T>(ast.clone());
63 return move(*cloned);
64}
65
66template <std::copy_constructible T> auto dup(const T& obj) -> T { return T(obj); }
67
68template <visitable T> auto dup(const T& var) -> T {
69 return var.visit([](auto&& x) { return T{dup(std::forward<decltype(x)>(x))}; });
70}
71
72template <typename T> auto dup(const optional<T>& opt) {
73 return opt.has_value() ? optional<T>{dup(opt.value())} : optional<T>{};
74}
75
76template <typename T> auto dup(const vector<T>& items) {
77 auto dup_vec = vector<T>();
78 dup_vec.reserve(items.size());
79 for (auto& i : items)
80 dup_vec.push_back(move(dup(i)));
81
82 return dup_vec;
83}
84} // namespace
85
86auto IfStmt::clone() const -> IfStmt* { return new IfStmt(tok(), dup(clauses), dup(else_clause)); }
87auto IfClause::clone() const -> IfClause* { return new IfClause(tok(), dup(cond), dup(body)); }
88auto NumberExpr::clone() const -> NumberExpr* { return new NumberExpr(tok(), val); }
89auto StringExpr::clone() const -> StringExpr* { return new StringExpr(tok(), val); }
90auto CharExpr::clone() const -> CharExpr* { return new CharExpr(tok(), val); }
91auto BoolExpr::clone() const -> BoolExpr* { return new BoolExpr(tok(), val); }
92auto ReturnStmt::clone() const -> ReturnStmt* { return new ReturnStmt(tok(), dup(expr)); }
93auto WhileStmt::clone() const -> WhileStmt* { return new WhileStmt(tok(), dup(cond), dup(body)); }
94auto VarDecl::clone() const -> VarDecl* { return new VarDecl(tok(), name, dup(type), dup(init)); }
95auto ConstDecl::clone() const -> ConstDecl* { return new ConstDecl(tok(), name, dup(type), dup(init)); }
96auto FnDecl::clone() const -> FnDecl* {
97 return new FnDecl(tok(), name, dup(args), dup(type_args), dup(ret), dup(body), dup(annotations));
98}
99auto CtorDecl::clone() const -> CtorDecl* { return new CtorDecl(tok(), dup(args), dup(body)); }
101 return new StructDecl(tok(), name, dup(fields), dup(type_args), dup(body), dup(implements), dup(annotations),
103}
104auto SimpleType::clone() const -> SimpleType* { return new SimpleType(tok(), name); }
105auto QualType::clone() const -> QualType* { return new QualType(tok(), dup(base), qualifier); }
106auto TemplatedType::clone() const -> TemplatedType* { return new TemplatedType(tok(), dup(base), dup(type_args)); }
107auto SelfType::clone() const -> SelfType* { return new SelfType(tok()); }
108auto ProxyType::clone() const -> ProxyType* { return new ProxyType(tok(), field); }
109auto FunctionType::clone() const -> FunctionType* { return new FunctionType(tok(), dup(ret), dup(args), fn_ptr); }
110auto TypeName::clone() const -> TypeName* { return new TypeName(tok(), dup(type), name); }
111auto GenericParam::clone() const -> GenericParam* { return new GenericParam(tok(), dup(type), name); }
112auto Compound::clone() const -> Compound* { return new Compound(tok(), dup(body)); }
113auto VarExpr::clone() const -> VarExpr* { return new VarExpr(tok(), name); }
114auto ConstExpr::clone() const -> ConstExpr* { return new ConstExpr(tok(), name, parent); }
115auto CallExpr::clone() const -> CallExpr* { return new CallExpr(tok(), name, dup(receiver), dup(args)); }
117 return new BinaryLogicExpr(tok(), operation, dup(lhs), dup(rhs));
118}
119auto CtorExpr::clone() const -> CtorExpr* { return new CtorExpr(tok(), dup(type), dup(args)); }
120auto DtorExpr::clone() const -> DtorExpr* { return new DtorExpr(tok(), dup(base)); }
121auto SliceExpr::clone() const -> SliceExpr* { return new SliceExpr(tok(), dup(type), dup(args)); }
123 return new LambdaExpr(tok(), dup(args), dup(ret), dup(body), dup(annotations));
124}
125auto AssignExpr::clone() const -> AssignExpr* { return new AssignExpr(tok(), dup(target), dup(value)); }
126auto FieldAccessExpr::clone() const -> FieldAccessExpr* { return new FieldAccessExpr(tok(), dup(base), field); }
128auto TypeExpr::clone() const -> TypeExpr* { return new TypeExpr(tok(), dup(type)); }
129auto Program::clone() const -> Program* { return new Program(tok(), dup(body)); }
130} // namespace yume::ast
131
132auto std::hash<yume::ast::AST>::operator()(const yume::ast::AST& s) const noexcept -> std::size_t {
133 uint64_t seed = 0;
135 visitor.visit(s, "");
136
137 return seed;
138}
virtual auto visit(const ast::AST &, string_view) -> Visitor &=0
All nodes in the AST tree of the program inherit from this class.
Definition: ast.hpp:224
void unify_val_ty()
Verify the type compatibility of the depends of this node, and merge the types if possible....
Definition: ast.cpp:10
auto equals_by_hash(ast::AST &other) const -> bool
Definition: ast.cpp:37
auto location() const -> Loc
The union of the locations of the Tokens making up this node.
Definition: ast.cpp:28
auto tok() const noexcept -> span< Token >
Definition: ast.hpp:239
Represents "any" kind of ast node of type T. See AnyExpr, AnyStmt and AnyType.
Definition: ast.hpp:184
Definition: ast.cpp:8
Represents a location in source code, as a range starting at a line and column and ending at some oth...
Definition: token.hpp:26
An assignment (=).
Definition: ast.hpp:652
auto clone() const -> AssignExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:125
AssignExpr(span< Token > tok, AnyExpr target, AnyExpr value)
Definition: ast.hpp:657
A logical operator such as || or &&. Since these aren't overloadable, they have their own AST node.
Definition: ast.hpp:581
BinaryLogicExpr(span< Token > tok, Atom operation, AnyExpr lhs, AnyExpr rhs)
Definition: ast.hpp:587
auto clone() const -> BinaryLogicExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:116
Bool literals (true or false).
Definition: ast.hpp:508
BoolExpr(span< Token > tok, bool val)
Definition: ast.hpp:512
auto clone() const -> BoolExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:91
A function call or operator.
Definition: ast.hpp:562
CallExpr(span< Token > tok, string name, OptionalType receiver, vector< AnyExpr > args)
Definition: ast.hpp:571
OptionalType receiver
Definition: ast.hpp:565
vector< AnyExpr > args
Definition: ast.hpp:566
auto clone() const -> CallExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:115
Char literals.
Definition: ast.hpp:495
CharExpr(span< Token > tok, uint8_t val)
Definition: ast.hpp:499
auto clone() const -> CharExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:90
A statement consisting of multiple other statements, i.e. the body of a function.
Definition: ast.hpp:712
Compound(span< Token > tok, vector< AnyStmt > body)
Definition: ast.hpp:717
auto clone() const -> Compound *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:112
vector< AnyStmt > body
Definition: ast.hpp:714
A declaration of a constant (const).
Definition: ast.hpp:888
ConstDecl(span< Token > tok, string name, AnyType type, AnyExpr init)
Definition: ast.hpp:894
auto clone() const -> ConstDecl *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:95
A constant. Currently global.
Definition: ast.hpp:547
auto clone() const -> ConstExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:114
optional< string > parent
Definition: ast.hpp:550
ConstExpr(span< Token > tok, string name, optional< string > parent)
Definition: ast.hpp:552
A declaration of a custom constructor (def :new).
Definition: ast.hpp:832
Compound body
Definition: ast.hpp:835
vector< TypeName > args
Definition: ast.hpp:834
CtorDecl(span< Token > tok, vector< TypeName > args, Compound body)
Definition: ast.hpp:837
auto clone() const -> CtorDecl *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:99
A construction of a struct or cast of a primitive.
Definition: ast.hpp:597
auto clone() const -> CtorExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:119
vector< AnyExpr > args
Definition: ast.hpp:600
AnyType type
Definition: ast.hpp:599
CtorExpr(span< Token > tok, AnyType type, vector< AnyExpr > args)
Definition: ast.hpp:605
A destruction of an object upon leaving its scope.
Definition: ast.hpp:619
AnyExpr base
Definition: ast.hpp:621
auto clone() const -> DtorExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:120
DtorExpr(span< Token > tok, AnyExpr base)
Definition: ast.hpp:623
Direct access of a field of a struct (::).
Definition: ast.hpp:666
FieldAccessExpr(span< Token > tok, OptionalExpr base, string field)
Definition: ast.hpp:672
auto clone() const -> FieldAccessExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:126
OptionalExpr base
Definition: ast.hpp:668
A declaration of a function (def).
Definition: ast.hpp:762
Body body
If this function declaration refers to a primitive, this field is a string representing the name of t...
Definition: ast.hpp:786
vector< TypeName > args
Definition: ast.hpp:780
auto clone() const -> FnDecl *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:96
FnDecl(span< Token > tok, string name, vector< TypeName > args, vector< GenericParam > type_args, OptionalType ret, Body body, std::unordered_set< string > annotations)
Definition: ast.hpp:791
std::unordered_set< string > annotations
Definition: ast.hpp:779
vector< GenericParam > type_args
Definition: ast.hpp:781
string name
Definition: ast.hpp:778
OptionalType ret
Definition: ast.hpp:782
A function type i.e. ->(Foo,Bar)Baz.
Definition: ast.hpp:380
OptionalType ret
Definition: ast.hpp:382
vector< AnyType > args
Definition: ast.hpp:383
FunctionType(span< Token > tok, OptionalType ret, vector< AnyType > args, bool fn_ptr)
Definition: ast.hpp:386
auto clone() const -> FunctionType *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:109
A generic, compile-time argument to a struct or function definition, comparable to C++ template param...
Definition: ast.hpp:422
OptionalType type
Definition: ast.hpp:423
auto clone() const -> GenericParam *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:111
GenericParam(span< Token > tok, OptionalType type, string name)
Definition: ast.hpp:426
Clauses of an if statement IfStmt.
Definition: ast.hpp:917
Compound body
Definition: ast.hpp:920
auto clone() const -> IfClause *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:87
IfClause(span< Token > tok, AnyExpr cond, Compound body)
Definition: ast.hpp:922
AnyExpr cond
Definition: ast.hpp:919
An if statement (if), with one or more IfClauses, and optionally an else clause.
Definition: ast.hpp:930
auto clone() const -> IfStmt *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:86
optional< Compound > else_clause
Definition: ast.hpp:933
vector< IfClause > clauses
Definition: ast.hpp:932
IfStmt(span< Token > tok, vector< IfClause > clauses, optional< Compound > else_clause)
Definition: ast.hpp:935
Represents an implicit cast to a different type, performed during semantic analysis.
Definition: ast.hpp:685
ty::Conv conversion
The conversion steps performed during this cast.
Definition: ast.hpp:689
auto clone() const -> ImplicitCastExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:127
ImplicitCastExpr(span< Token > tok, AnyExpr base, ty::Conv conversion)
Definition: ast.hpp:691
A local definition of an anonymous function.
Definition: ast.hpp:729
OptionalType ret
Definition: ast.hpp:732
auto clone() const -> LambdaExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:122
vector< TypeName > args
Definition: ast.hpp:731
LambdaExpr(span< Token > tok, vector< TypeName > args, OptionalType ret, Compound body, std::set< string > annotations)
Definition: ast.hpp:739
std::set< string > annotations
Definition: ast.hpp:734
Number literals.
Definition: ast.hpp:482
NumberExpr(span< Token > tok, int64_t val)
Definition: ast.hpp:486
auto clone() const -> NumberExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:88
The top level structure of a file of source code.
Definition: ast.hpp:957
auto clone() const -> Program *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:129
Program(span< Token > tok, vector< AnyStmt > body)
Definition: ast.hpp:961
vector< AnyStmt > body
Definition: ast.hpp:959
A type which refers to a different type, specifically that of a struct field.
Definition: ast.hpp:367
ProxyType(span< Token > tok, string field)
Definition: ast.hpp:371
auto clone() const -> ProxyType *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:108
A type with a Qualifier like mut or [] following.
Definition: ast.hpp:341
AnyType base
Definition: ast.hpp:343
QualType(span< Token > tok, AnyType base, Qualifier qualifier)
Definition: ast.hpp:346
auto clone() const -> QualType *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:105
Qualifier qualifier
Definition: ast.hpp:344
Return from a function body.
Definition: ast.hpp:944
auto clone() const -> ReturnStmt *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:92
OptionalExpr expr
Definition: ast.hpp:946
ReturnStmt(span< Token > tok, OptionalExpr expr)
Definition: ast.hpp:949
The self type.
Definition: ast.hpp:356
SelfType(span< Token > tok)
Definition: ast.hpp:358
auto clone() const -> SelfType *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:107
Just the name of a type, always capitalized.
Definition: ast.hpp:328
SimpleType(span< Token > tok, string name)
Definition: ast.hpp:332
auto clone() const -> SimpleType *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:104
A slice literal, i.e. an array.
Definition: ast.hpp:632
SliceExpr(span< Token > tok, AnyType type, vector< AnyExpr > args)
Definition: ast.hpp:637
auto clone() const -> SliceExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:121
vector< AnyExpr > args
Definition: ast.hpp:635
String literals.
Definition: ast.hpp:521
StringExpr(span< Token > tok, string val)
Definition: ast.hpp:525
auto clone() const -> StringExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:89
A declaration of a struct (struct) or an interface (interface).
Definition: ast.hpp:847
vector< GenericParam > type_args
Definition: ast.hpp:851
auto clone() const -> StructDecl *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:100
std::unordered_set< string > annotations
Definition: ast.hpp:854
StructDecl(span< Token > tok, string name, vector< TypeName > fields, vector< GenericParam > type_args, Compound body, OptionalType implements, std::unordered_set< string > annotations, bool is_interface=false)
Definition: ast.hpp:860
OptionalType implements
Definition: ast.hpp:853
vector< TypeName > fields
Definition: ast.hpp:850
A type with explicit type parameters i.e. Foo<Bar,Baz>.
Definition: ast.hpp:467
TemplatedType(span< Token > tok, AnyType base, vector< AnyTypeOrExpr > type_args)
Definition: ast.hpp:472
auto clone() const -> TemplatedType *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:106
vector< AnyTypeOrExpr > type_args
Definition: ast.hpp:470
Represents a reference to a type.
Definition: ast.hpp:700
AnyType type
Definition: ast.hpp:702
TypeExpr(span< Token > tok, AnyType type)
Definition: ast.hpp:704
auto clone() const -> TypeExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:128
A pair of a Type and an identifier, i.e. a parameter name.
Definition: ast.hpp:396
auto clone() const -> TypeName *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:110
AnyType type
Definition: ast.hpp:397
TypeName(span< Token > tok, AnyType type, string name)
Definition: ast.hpp:400
A declaration of a local variable (let).
Definition: ast.hpp:872
VarDecl(span< Token > tok, string name, OptionalType type, AnyExpr init)
Definition: ast.hpp:878
AnyExpr init
Definition: ast.hpp:876
auto clone() const -> VarDecl *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:94
OptionalType type
Definition: ast.hpp:875
A variable, i.e. just an identifier.
Definition: ast.hpp:534
auto clone() const -> VarExpr *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:113
VarExpr(span< Token > tok, string name)
Definition: ast.hpp:538
A while loop (while).
Definition: ast.hpp:904
WhileStmt(span< Token > tok, AnyExpr cond, Compound body)
Definition: ast.hpp:909
Compound body
Definition: ast.hpp:907
auto clone() const -> WhileStmt *override
Deep copy, except for the type and attachments.
Definition: ast.cpp:93
Visitor & visitor
Definition: visit.cpp:17