1 #include <utils/Error.h>
5 #include "diagnostics/Location.h"
6 #include "parsetree/ParseTreeVisitor.h"
10 using pty =
Node::Type;
12 using ast::ExprNodeList;
14 using namespace ast::exprnode;
17 static_assert(std::is_standard_layout_v<ptv::TmpVarDecl>);
18 static_assert(std::is_trivially_copyable_v<ptv::TmpVarDecl>);
21 #define sem_alloc sem.allocator().new_object
27 return sem_alloc<UnaryOp>(UnaryOp::OpType::Not, loc);
29 return sem_alloc<UnaryOp>(UnaryOp::OpType::Minus, loc);
31 throw utils::FatalError(
"Invalid operator type");
39 return sem_alloc<BinaryOp>(BinaryOp::OpType::Assignment, loc);
41 return sem_alloc<BinaryOp>(BinaryOp::OpType::Or, loc);
43 return sem_alloc<BinaryOp>(BinaryOp::OpType::And, loc);
45 return sem_alloc<BinaryOp>(BinaryOp::OpType::BitwiseOr, loc);
47 return sem_alloc<BinaryOp>(BinaryOp::OpType::BitwiseXor, loc);
49 return sem_alloc<BinaryOp>(BinaryOp::OpType::BitwiseAnd, loc);
51 return sem_alloc<BinaryOp>(BinaryOp::OpType::Equal, loc);
53 return sem_alloc<BinaryOp>(BinaryOp::OpType::NotEqual, loc);
55 return sem_alloc<BinaryOp>(BinaryOp::OpType::LessThan, loc);
57 case oty::LessThanOrEqual:
58 return sem_alloc<BinaryOp>(BinaryOp::OpType::LessThanOrEqual, loc);
59 case oty::GreaterThan:
60 return sem_alloc<BinaryOp>(BinaryOp::OpType::GreaterThan, loc);
61 case oty::GreaterThanOrEqual:
62 return sem_alloc<BinaryOp>(BinaryOp::OpType::GreaterThanOrEqual, loc);
64 return sem_alloc<BinaryOp>(BinaryOp::OpType::InstanceOf, loc);
66 return sem_alloc<BinaryOp>(BinaryOp::OpType::Add, loc);
68 return sem_alloc<BinaryOp>(BinaryOp::OpType::Subtract, loc);
70 return sem_alloc<BinaryOp>(BinaryOp::OpType::Multiply, loc);
72 return sem_alloc<BinaryOp>(BinaryOp::OpType::Divide, loc);
74 return sem_alloc<BinaryOp>(BinaryOp::OpType::Modulo, loc);
76 assert(
false &&
"Invalid operator type");
83 visitExprChild(node), node
->location(), sem.CurrentScopeID());
86 ExprNodeList ptv::visitExprNode(parsetree::
Node* node) {
87 check_node_type(node, pty::Expression);
88 check_num_children(node, 1, 3);
90 auto list = visitExprChild(node
->child(0
));
91 list.isBracketed =
true;
96 auto right = visitExprChild(node
->child(1
));
99 ops.push_back(convertToUnaryOp(op->get_type(), op->location()));
105 auto left = visitExprChild(node
->child(0
));
106 auto right = visitExprChild(node
->child(2
));
110 ops.push_back(convertToBinaryOp(op->get_type(), op->location()));
121 ExprNodeList ptv::visitExprChild(
Node* node) {
123 case pty::Expression:
124 return visitExprNode(node);
126 return ExprNodeList(visitLiteral(node));
128 return ExprNodeList(visitRegularType(node));
130 return ExprNodeList(visitArrayType(node));
131 case pty::Identifier: {
132 auto name = visitIdentifier(node);
139 case pty::QualifiedIdentifier:
140 return visitQualifiedIdentifierInExpr(node);
141 case pty::MethodInvocation:
142 return visitMethodInvocation(node);
143 case pty::ArrayAccess:
144 return visitArrayAccess(node);
145 case pty::FieldAccess:
146 return visitFieldAccess(node);
147 case pty::CastExpression:
148 return visitCastExpression(node);
149 case pty::ArrayCreationExpression:
150 return visitArrayCreation(node);
151 case pty::ClassInstanceCreationExpression:
152 return visitClassCreation(node);
154 assert(
false &&
"Invalid node type");
159 ExprNodeList ptv::visitQualifiedIdentifierInExpr(
Node* node,
160 bool isMethodInvocation) {
161 check_node_type(node, pty::QualifiedIdentifier);
162 check_num_children(node, 1, 2);
165 if(isMethodInvocation) {
176 ops = visitQualifiedIdentifierInExpr(node
->child(0
));
177 if(isMethodInvocation) {
191 ExprNodeList ptv::visitMethodInvocation(
Node* node) {
192 check_node_type(node, pty::MethodInvocation);
193 check_num_children(node, 2, 3);
199 auto size = visitArgumentList(node
->child(1
), args) + 1;
212 auto size = visitArgumentList(node
->child(2
), args) + 1;
221 ExprNodeList ptv::visitFieldAccess(
Node* node) {
222 check_node_type(node, pty::FieldAccess);
223 check_num_children(node, 2, 2);
233 ExprNodeList ptv::visitClassCreation(
Node* node) {
234 check_node_type(node, pty::ClassInstanceCreationExpression);
235 check_num_children(node, 2, 2);
237 auto type = visitReferenceType(node
->child(0
));
240 auto size = visitArgumentList(node
->child(1
), args) + 1;
246 ExprNodeList ptv::visitArrayAccess(
Node* node) {
247 check_node_type(node, pty::ArrayAccess);
248 check_num_children(node, 2, 2);
256 ExprNodeList ptv::visitCastExpression(
Node* node) {
257 check_node_type(node, pty::CastExpression);
258 check_num_children(node, 2, 3);
267 type = sem.BuildArrayType(type, type->location());
281 ExprNodeList ptv::visitArrayCreation(
Node* node) {
282 check_node_type(node, pty::ArrayCreationExpression);
283 check_num_children(node, 2, 2);
284 ExprNodeList ops(visitArrayType(node
->child(0
)));
296 check_node_type(node, pty::ArrayType);
300 LiteralNode* ptv::visitLiteral(
Node* node) {
301 check_node_type(node, pty::Literal);
302 auto lit = cast<parsetree::
Literal>(node);
303 return sem_alloc<LiteralNode>(sem.allocator(),
305 sem.BuildBuiltInType(lit->get_type()),
309 int ptv::visitArgumentList(
Node* node, ExprNodeList& ops) {
310 if(node ==
nullptr)
return 0;
311 check_node_type(node, pty::ArgumentList);
312 check_num_children(node, 1, 2);
318 args = visitArgumentList(node
->child(0
), ops) + 1;