Skip to content

Commit

Permalink
Implement if statement ast_dumper and type_checker
Browse files Browse the repository at this point in the history
  • Loading branch information
leewei05 authored and Lai-YT committed Nov 27, 2023
1 parent e227f3c commit f2eb940
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 3 deletions.
12 changes: 12 additions & 0 deletions include/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ struct NullStmtNode : public StmtNode {
virtual void Accept(ModifyingVisitor&) override;
};

struct IfStmtNode : public StmtNode {
IfStmtNode(std::unique_ptr<ExprNode> expr,
std::unique_ptr<BlockStmtNode> block)
: predicate{std::move(expr)}, body{std::move(block)} {}

virtual void Accept(NonModifyingVisitor&) const override;
virtual void Accept(ModifyingVisitor&) override;

std::unique_ptr<ExprNode> predicate;
std::unique_ptr<BlockStmtNode> body;
};

struct ReturnStmtNode : public StmtNode {
ReturnStmtNode(std::unique_ptr<ExprNode> expr) : expr{std::move(expr)} {}

Expand Down
1 change: 1 addition & 0 deletions include/ast_dumper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class AstDumper : public NonModifyingVisitor {
void Visit(const BlockStmtNode&) override;
void Visit(const ProgramNode&) override;
void Visit(const NullStmtNode&) override;
void Visit(const IfStmtNode&) override;
void Visit(const ReturnStmtNode&) override;
void Visit(const ExprStmtNode&) override;
void Visit(const IdExprNode&) override;
Expand Down
1 change: 1 addition & 0 deletions include/qbe_ir_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class QbeIrGenerator : public NonModifyingVisitor {
void Visit(const BlockStmtNode&) override;
void Visit(const ProgramNode&) override;
void Visit(const NullStmtNode&) override;
void Visit(const IfStmtNode&) override;
void Visit(const ReturnStmtNode&) override;
void Visit(const ExprStmtNode&) override;
void Visit(const IdExprNode&) override;
Expand Down
1 change: 1 addition & 0 deletions include/type_checker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class TypeChecker : public ModifyingVisitor {
void Visit(BlockStmtNode&) override;
void Visit(ProgramNode&) override;
void Visit(NullStmtNode&) override;
void Visit(IfStmtNode&) override;
void Visit(ReturnStmtNode&) override;
void Visit(ExprStmtNode&) override;
void Visit(IdExprNode&) override;
Expand Down
2 changes: 2 additions & 0 deletions include/visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct DeclNode;
struct BlockStmtNode;
struct ProgramNode;
struct NullStmtNode;
struct IfStmtNode;
struct ReturnStmtNode;
struct ExprStmtNode;
struct IdExprNode;
Expand Down Expand Up @@ -55,6 +56,7 @@ class Visitor {
virtual void Visit(CondMut<BlockStmtNode>&){};
virtual void Visit(CondMut<ProgramNode>&){};
virtual void Visit(CondMut<NullStmtNode>&){};
virtual void Visit(CondMut<IfStmtNode>&){};
virtual void Visit(CondMut<ReturnStmtNode>&){};
virtual void Visit(CondMut<ExprStmtNode>&){};
virtual void Visit(CondMut<IdExprNode>&){};
Expand Down
2 changes: 1 addition & 1 deletion parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ stmts: stmts stmt {
stmt: ';' { $$ = std::make_unique<NullStmtNode>(); }
| RETURN expr ';' { $$ = std::make_unique<ReturnStmtNode>($2); }
| expr ';' { $$ = std::make_unique<ExprStmtNode>($1); }
| IF '(' expr ')' block {}
| IF '(' expr ')' block { $$ = std::make_unique<IfStmtNode>($3, $5); }
;

expr: ID { $$ = std::make_unique<IdExprNode>($1); }
Expand Down
8 changes: 8 additions & 0 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ void NullStmtNode::Accept(ModifyingVisitor& v) {
v.Visit(*this);
}

void IfStmtNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}

void IfStmtNode::Accept(ModifyingVisitor& v) {
v.Visit(*this);
}

void ReturnStmtNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand Down
9 changes: 9 additions & 0 deletions src/ast_dumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ void AstDumper::Visit(const NullStmtNode& stmt) {
std::cout << indenter_.Indent() << "()" << std::endl;
}

void AstDumper::Visit(const IfStmtNode& if_stmt) {
std::cout << indenter_.Indent() << "(if" << std::endl;
indenter_.IncreaseLevel();
if_stmt.predicate->Accept(*this);
if_stmt.body->Accept(*this);
indenter_.DecreaseLevel();
std::cout << indenter_.Indent() << ')' << std::endl;
}

void AstDumper::Visit(const ReturnStmtNode& ret_stmt) {
std::cout << indenter_.Indent() << "(ret" << std::endl;
indenter_.IncreaseLevel();
Expand Down
2 changes: 2 additions & 0 deletions src/qbe_ir_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ void QbeIrGenerator::Visit(const NullStmtNode&) {
/* do nothing */
}

void QbeIrGenerator::Visit(const IfStmtNode& if_stmt) {}

void QbeIrGenerator::Visit(const ReturnStmtNode& ret_stmt) {
ret_stmt.expr->Accept(*this);
int ret_num = num_recorder.NumOfPrevExpr();
Expand Down
9 changes: 7 additions & 2 deletions src/type_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ void TypeChecker::Visit(NullStmtNode&) {
/* do nothing */
}

void TypeChecker::Visit(IfStmtNode& if_stmt) {
if_stmt.predicate->Accept(*this);
if_stmt.body->Accept(*this);
}

void TypeChecker::Visit(ReturnStmtNode& ret_stmt) {
ret_stmt.expr->Accept(*this);
if (ret_stmt.expr->type != ExprType::kInt) {
Expand Down Expand Up @@ -100,8 +105,8 @@ void TypeChecker::Visit(SimpleAssignmentExprNode& assign_expr) {
if (assign_expr.expr->type == symbol->expr_type) {
// 6.5.16 Assignment operators
// The type of an assignment expression is the type of the left
// operand unless the left operand has qualified type, in which case it is
// the unqualified version of the type of the left operand.
// operand unless the left operand has qualified type, in which case it
// is the unqualified version of the type of the left operand.
assign_expr.type = symbol->expr_type;
} else {
// TODO: assigning to 'symbol->expr_type' from incompatible type
Expand Down

0 comments on commit f2eb940

Please sign in to comment.