Skip to content

Commit

Permalink
Resolve operator symbols using visitor
Browse files Browse the repository at this point in the history
In order to maintain a clean separation of logic within our AST nodes, we avoid
mixing operator symbols into the node structures. To accomplish this, we introduce
an auxiliary visitor responsible for retrieving operator symbols, ensuring that
the AST remains focused on the data representation.
  • Loading branch information
Lai-YT authored and leewei05 committed Sep 29, 2023
1 parent 35f41b2 commit 4f3228a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 69 deletions.
24 changes: 0 additions & 24 deletions include/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,6 @@ class BinaryExprNode : public ExprNode {

/// @brief The name of the operator used in the QBE IR, e.g., `add`.
virtual std::string OpName_() const = 0;
/// @brief The mathematical symbol of the operator, e.g., `+`.
virtual std::string Op_() const = 0;
};

class PlusExprNode : public BinaryExprNode {
Expand All @@ -181,8 +179,6 @@ class PlusExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class SubExprNode : public BinaryExprNode {
Expand All @@ -193,8 +189,6 @@ class SubExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class MulExprNode : public BinaryExprNode {
Expand All @@ -205,8 +199,6 @@ class MulExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class DivExprNode : public BinaryExprNode {
Expand All @@ -217,8 +209,6 @@ class DivExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class ModExprNode : public BinaryExprNode {
Expand All @@ -229,8 +219,6 @@ class ModExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class GreaterThanExprNode : public BinaryExprNode {
Expand All @@ -241,8 +229,6 @@ class GreaterThanExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class GreaterThanOrEqualToExprNode : public BinaryExprNode {
Expand All @@ -253,8 +239,6 @@ class GreaterThanOrEqualToExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class LessThanExprNode : public BinaryExprNode {
Expand All @@ -265,8 +249,6 @@ class LessThanExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class LessThanOrEqualToExprNode : public BinaryExprNode {
Expand All @@ -277,8 +259,6 @@ class LessThanOrEqualToExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class EqualToExprNode : public BinaryExprNode {
Expand All @@ -289,8 +269,6 @@ class EqualToExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

class NotEqualToExprNode : public BinaryExprNode {
Expand All @@ -301,8 +279,6 @@ class NotEqualToExprNode : public BinaryExprNode {
virtual void Accept(ModifyingVisitor&) override;

std::string OpName_() const override;

std::string Op_() const override;
};

/// @note This is an abstract class.
Expand Down
44 changes: 0 additions & 44 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,6 @@ std::string PlusExprNode::OpName_() const {
return "add";
}

std::string PlusExprNode::Op_() const {
return "+";
}

void SubExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -235,10 +231,6 @@ std::string SubExprNode::OpName_() const {
return "sub";
}

std::string SubExprNode::Op_() const {
return "-";
}

void MulExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -251,10 +243,6 @@ std::string MulExprNode::OpName_() const {
return "mul";
}

std::string MulExprNode::Op_() const {
return "*";
}

void DivExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -267,10 +255,6 @@ std::string DivExprNode::OpName_() const {
return "div";
}

std::string DivExprNode::Op_() const {
return "/";
}

void ModExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -283,10 +267,6 @@ std::string ModExprNode::OpName_() const {
return "rem";
}

std::string ModExprNode::Op_() const {
return "%";
}

void GreaterThanExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -300,10 +280,6 @@ std::string GreaterThanExprNode::OpName_() const {
return "sgt";
}

std::string GreaterThanExprNode::Op_() const {
return ">";
}

void GreaterThanOrEqualToExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -317,10 +293,6 @@ std::string GreaterThanOrEqualToExprNode::OpName_() const {
return "sge";
}

std::string GreaterThanOrEqualToExprNode::Op_() const {
return ">=";
}

void LessThanExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -334,10 +306,6 @@ std::string LessThanExprNode::OpName_() const {
return "slt";
}

std::string LessThanExprNode::Op_() const {
return "<";
}

void LessThanOrEqualToExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -351,10 +319,6 @@ std::string LessThanOrEqualToExprNode::OpName_() const {
return "sle";
}

std::string LessThanOrEqualToExprNode::Op_() const {
return "<=";
}

void EqualToExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -367,10 +331,6 @@ std::string EqualToExprNode::OpName_() const {
return "eq";
}

std::string EqualToExprNode::Op_() const {
return "==";
}

void NotEqualToExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand All @@ -383,10 +343,6 @@ std::string NotEqualToExprNode::OpName_() const {
return "ne";
}

std::string NotEqualToExprNode::Op_() const {
return "!=";
}

void AssignmentExprNode::Accept(NonModifyingVisitor& v) const {
v.Visit(*this);
}
Expand Down
87 changes: 86 additions & 1 deletion src/ast_dumpr.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
#include <iostream>
#include <memory>
#include <string>

#include "ast.hpp"
#include "ast_dumper.hpp"
#include "type.hpp"
#include "visitor.hpp"

namespace {
class OpGetter {
public:
/// @return The mathematical symbol of the binary operator, e.g., `+`.
std::string OpOf(const BinaryExprNode& bin_expr);

OpGetter();

private:
/// @note An alternative approach would be to directly implement `OpGetter` as
/// a `Visitor`, but this is intended to be used exclusively with binary
/// expressions. Therefore, we encapsulate it to prevent unintended usage in
/// other contexts. We also employ the Pimpl idiom, allowing deferred
/// implementation details later in this file.
class OpGetterImpl;
std::unique_ptr<OpGetterImpl> impl_;
};

} // namespace

void AstDumper::Visit(const DeclNode& decl) {
std::cout << indenter_.Indent() << '(' << decl.id_ << ": "
Expand Down Expand Up @@ -56,7 +79,8 @@ void AstDumper::Visit(const IntConstExprNode& int_expr) {
}

void AstDumper::Visit(const BinaryExprNode& bin_expr) {
std::cout << indenter_.Indent() << '(' << bin_expr.Op_() << std::endl;
std::cout << indenter_.Indent() << '(' << OpGetter{}.OpOf(bin_expr)
<< std::endl;
indenter_.IncreaseLevel();
bin_expr.lhs_->Accept(*this);
bin_expr.rhs_->Accept(*this);
Expand Down Expand Up @@ -97,3 +121,64 @@ void AstDumper::Visit(const SimpleAssignmentExprNode& assign_expr) {
std::cout << indenter_.Indent() << ')' << ": "
<< ExprTypeToCString(assign_expr.expr_->type) << std::endl;
}

class OpGetter::OpGetterImpl : public NonModifyingVisitor {
public:
std::string Op() const {
return op_;
}

void Visit(const PlusExprNode&) override {
op_ = "+";
}

void Visit(const SubExprNode&) override {
op_ = "-";
}

void Visit(const MulExprNode&) override {
op_ = "*";
}

void Visit(const DivExprNode&) override {
op_ = "/";
}

void Visit(const ModExprNode&) override {
op_ = "%";
}

void Visit(const GreaterThanExprNode&) override {
op_ = ">";
}

void Visit(const GreaterThanOrEqualToExprNode&) override {
op_ = ">=";
}

void Visit(const LessThanExprNode&) override {
op_ = "<";
}

void Visit(const LessThanOrEqualToExprNode&) override {
op_ = "<=";
}

void Visit(const EqualToExprNode&) override {
op_ = "==";
}

void Visit(const NotEqualToExprNode&) override {
op_ = "!=";
}

private:
std::string op_;
};

std::string OpGetter::OpOf(const BinaryExprNode& bin_expr) {
bin_expr.Accept(*impl_);
return impl_->Op();
}

OpGetter::OpGetter() : impl_{std::make_unique<OpGetterImpl>()} {}

0 comments on commit 4f3228a

Please sign in to comment.