1 #include <utils/Error.h>
5 #include "parsetree/ParseTree.h"
6 #include "parsetree/ParseTreeVisitor.h"
10 using pty =
Node::Type;
15 ast::BlockStatement* ptv::visitBlock(
Node* node) {
16 check_node_type(node, pty::Block);
17 check_num_children(node, 1, 1);
18 ast::pmr_vector<ast::Stmt*> stmts;
20 visitListPattern<pty::BlockStatementList, ast::Stmt*,
true>(node->child(0),
23 return sem.BuildBlockStatement(stmts);
27 ast::
Stmt* ptv::visit<pty::BlockStatementList>(
Node* node) {
28 return visitStatement(node);
33 ast::
Stmt* ptv::visitStatement(
Node* node) {
34 check_node_type(node, pty::Statement);
35 check_num_children(node, 0, 1);
37 check_num_children(node, 1, 1);
43 return visitBlock(child);
44 case pty::IfThenStatement:
45 return visitIfThenStatement(child);
46 case pty::WhileStatement:
47 return visitWhileStatement(child);
48 case pty::ForStatement:
49 return visitForStatement(child);
50 case pty::ReturnStatement:
51 return visitReturnStatement(child);
52 case pty::LocalVariableDeclaration:
53 return visitLocalVariableDeclarationStatement(child);
54 case pty::StatementExpression:
55 return visitExpressionStatement(child);
63 ast::IfStmt* ptv::visitIfThenStatement(
Node* node) {
64 check_node_type(node, pty::IfThenStatement);
65 check_num_children(node, 2, 3);
68 throw utils::FatalError(
"Invalid if-then statement");
74 auto stmt = visitStatement(node
->child(1
));
79 auto elseStmt = visitStatement(node
->child(2
));
81 return sem.BuildIfStmt(expr, stmt, elseStmt);
84 return sem.BuildIfStmt(expr, stmt);
89 ast::WhileStmt* ptv::visitWhileStatement(
Node* node) {
90 check_node_type(node, pty::WhileStatement);
91 check_num_children(node, 2, 2);
94 throw utils::FatalError(
"Invalid while statement");
97 auto condition = visitExpr(node
->child(0
));
100 auto body = visitStatement(node
->child(1
));
102 return sem.BuildWhileStmt(condition, body);
107 ast::ForStmt* ptv::visitForStatement(
Node* node) {
108 check_node_type(node, pty::ForStatement);
109 check_num_children(node, 4, 4);
111 if(node
->child(3
) ==
nullptr)
throw utils::FatalError(
"Invalid for statement");
113 ast::
Stmt* init =
nullptr;
114 ast::
Expr* condition =
nullptr;
115 ast::
Stmt* update =
nullptr;
116 ast::
Stmt* body =
nullptr;
125 return sem.BuildForStmt(init, condition, update, body);
130 ast::ReturnStmt* ptv::visitReturnStatement(
Node* node) {
131 check_node_type(node, pty::ReturnStatement);
132 check_num_children(node, 0, 1);
142 ast::ExprStmt* ptv::visitExpressionStatement(
Node* node) {
143 check_node_type(node, pty::StatementExpression);
144 check_num_children(node, 1, 1);
146 return sem.BuildExprStmt(expr);
152 check_node_type(declNode, pty::VariableDeclarator);
153 check_num_children(declNode, 1, 2);
155 auto type = visitType(tyNode);
158 auto name = visitIdentifier(nameNode);
160 ast::
Expr* init =
nullptr;
169 ast::DeclStmt* ptv::visitLocalVariableDeclarationStatement(
Node* node) {
170 check_node_type(node, pty::LocalVariableDeclaration);
171 check_num_children(node, 2, 2);
173 auto nextId = sem.NextScopeID();
178 auto decl = visitVariableDeclarator(tyNode, declNode);
180 sem.BuildVarDecl(decl.type, decl.loc, decl.name, nextId, decl.init);
181 return sem.BuildDeclStmt(astDecl);