-
Notifications
You must be signed in to change notification settings - Fork 0
/
TypeNodes.hpp
159 lines (121 loc) · 4.14 KB
/
TypeNodes.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#pragma once
#include <variant>
#include "ExpressionNode.hpp"
#include "IdentifierNode.hpp"
#include "Symbol.hpp"
class TypeNode : public SyntaxNode, public ISymbolType {
public:
virtual ~TypeNode() = default;
protected:
TypeNode() = default;
};
class ParenthesizedTypeNode final : public TypeNode {
public:
explicit ParenthesizedTypeNode(std::unique_ptr<TypeNode> &&type);
void Visit(ISyntaxTreeVisitor *visitor) const override {
visitor->PostVisit(this);
}
const TypeNode *GetType() const {
return type_.get();
}
private:
std::unique_ptr<TypeNode> type_;
};
class TupleTypeNode final : public TypeNode {
public:
TupleTypeNode() = default;
explicit TupleTypeNode(std::vector<std::unique_ptr<TypeNode>> &&types);
void Visit(ISyntaxTreeVisitor *visitor) const override {
visitor->PostVisit(this);
}
std::vector<const TypeNode *> GetTypes() const {
std::vector<const TypeNode *> types;
for (const auto &type : types_) {
types.push_back(type.get());
}
return types;
}
private:
std::vector<std::unique_ptr<TypeNode>> types_;
};
class ReferenceTypeNode final : public TypeNode {
public:
ReferenceTypeNode(bool is_mut, std::unique_ptr<TypeNode> &&type);
ReferenceTypeNode(bool is_mut, const ISymbolType *type) : is_mut_(is_mut), type2_(type) {}
void Visit(ISyntaxTreeVisitor *visitor) const override {
visitor->PostVisit(this);
}
bool IsMut() const {
return is_mut_;
}
const TypeNode *GetType() const {
if (type2_ != nullptr) {
throw std::exception();
}
return type_.get();
}
const ISymbolType *GetRawType() const {
return type2_ != nullptr ? type2_ : type_.get();
}
bool Equals(const ISymbolType &other) const override {
if (auto p = dynamic_cast<const ReferenceTypeNode *>(&other); p != nullptr) {
return p->GetRawType()->Equals(*GetRawType()) && p->is_mut_ == is_mut_;
}
return false;
}
private:
bool is_mut_;
std::unique_ptr<TypeNode> type_;
const ISymbolType *type2_ = nullptr;
};
class ArrayTypeNode final : public TypeNode {
public:
ArrayTypeNode(std::unique_ptr<TypeNode> &&type, std::unique_ptr<ExpressionNode> &&expression);
void Visit(ISyntaxTreeVisitor *visitor) const override {
visitor->PostVisit(this);
}
const TypeNode *GetType() const {
return type_.get();
}
const ExpressionNode *GetExpression() const {
return expression_.get();
}
private:
std::unique_ptr<TypeNode> type_;
std::unique_ptr<ExpressionNode> expression_;
};
class IdentifierTypeNode final : public TypeNode {
public:
explicit IdentifierTypeNode(std::unique_ptr<IdentifierNode> &&identifier);
void Visit(ISyntaxTreeVisitor *visitor) const override {
visitor->PostVisit(this);
}
const IdentifierNode *GetIdentifier() const {
return identifier_.get();
}
std::variant<const semantic::SubsetStructType *, const semantic::DefaultType *> type;
bool Equals(const ISymbolType &other) const override {
if (auto const_node = dynamic_cast<const IdentifierTypeNode *>(&other); const_node != nullptr) {
auto node = const_cast<IdentifierTypeNode *>(const_node);
if (auto p = std::get_if<const semantic::SubsetStructType *>(&node->type)) {
return this->Equals(**p);
}
if (auto p = std::get_if<const semantic::DefaultType *>(&node->type)) {
return this->Equals(**p);
}
}
if (auto node = dynamic_cast<const semantic::SubsetStructType *>(&other); node != nullptr) {
if (auto p = std::get_if<const semantic::SubsetStructType *>(&type)) {
return node->Equals(**p);
}
}
if (auto node = dynamic_cast<const semantic::DefaultType *>(&other); node != nullptr) {
if (auto p = std::get_if<const semantic::DefaultType *>(&type)) {
return node->Equals(**p);
}
}
return false;
}
private:
std::unique_ptr<IdentifierNode> identifier_;
};