From d7494702afc342fd595070153ea8197b195617e4 Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Thu, 5 Mar 2015 17:25:02 +0100 Subject: [PATCH] Simplify the Expression hierarchy by moving the operator on the binary father. As a consequence, the Emitter interface is greatly simplified. --- CppEmitter.cpp | 132 ++++++++--------------- CppEmitter.hpp | 32 ++---- Emitter.hpp | 53 ++-------- Nodes.hpp | 276 +++++++++++++++++++------------------------------ 4 files changed, 167 insertions(+), 326 deletions(-) diff --git a/CppEmitter.cpp b/CppEmitter.cpp index d4c713c..25e01fd 100644 --- a/CppEmitter.cpp +++ b/CppEmitter.cpp @@ -294,102 +294,58 @@ void CppEmitter::emit(VarDeclaration const& decl) { } } -void CppEmitter::emitExp(char const* symbol, ExpNode const& node) { +std::ostream& operator<<(std::ostream &stream, Operator op) { + switch (op) { + case Operator::PLUS: + stream << '+'; + break; + case Operator::MINUS: + stream << '-'; + break; + case Operator::TIMES: + stream << '*'; + break; + case Operator::DIV: + stream << '/'; + break; + case Operator::SHL: + stream << "<<"; + break; + case Operator::SHR: + stream << ">>"; + break; + case Operator::LT: + stream << '<'; + break; + case Operator::GT: + stream << '>'; + break; + case Operator::GTE: + stream << ">="; + break; + case Operator::LTE: + stream << "<="; + break; + case Operator::EQ: + stream << "=="; + break; + } + + return stream; +} + +void CppEmitter::emit(BinaryExpression const& node) { node.getLeft().emit(this); - stream << ' ' << symbol << ' '; + stream << ' ' << node.getOperator() << ' '; node.getRight().emit(this); } -void CppEmitter::emitSemiExp(char const* symbol, SemiExpNode const& node) { +void CppEmitter::emit(BinarySemiExpression const& node) { bool braces = (dynamic_cast(&node.getLeft()) == nullptr); - stream << ' ' << symbol << ' '; + stream << ' ' << node.getOperator() << ' '; if (braces) stream << "("; node.getLeft().emit(this); if (braces) stream << ")"; } -void CppEmitter::emit(ExpLt const& node) { - emitExp("<", node); -} - -void CppEmitter::emit(ExpGt const& node) { - emitExp(">", node); -} - -void CppEmitter::emit(ExpLte const& node) { - emitExp("<=", node); -} - -void CppEmitter::emit(ExpGte const& node) { - emitExp(">=", node); -} - -void CppEmitter::emit(ExpPlus const& node) { - emitExp("+", node); -} - -void CppEmitter::emit(ExpMinus const& node) { - emitExp("-", node); -} - -void CppEmitter::emit(ExpTimes const& node) { - emitExp("*", node); -} - -void CppEmitter::emit(ExpDiv const& node) { - emitExp("/", node); -} - -void CppEmitter::emit(ExpShl const& node) { - emitExp("<<", node); -} - -void CppEmitter::emit(ExpShr const& node) { - emitExp(">>", node); -} - -void CppEmitter::emit(SemiExpEq const& node) { - emitSemiExp("==", node); -} - -void CppEmitter::emit(SemiExpLt const& node) { - emitSemiExp("<", node); -} - -void CppEmitter::emit(SemiExpGt const& node) { - emitSemiExp(">", node); -} - -void CppEmitter::emit(SemiExpLte const& node) { - emitSemiExp("<=", node); -} - -void CppEmitter::emit(SemiExpGte const& node) { - emitSemiExp(">=", node); -} - -void CppEmitter::emit(SemiExpPlus const& node) { - emitSemiExp("+", node); -} - -void CppEmitter::emit(SemiExpMinus const& node) { - emitSemiExp("-", node); -} - -void CppEmitter::emit(SemiExpTimes const& node) { - emitSemiExp("*", node); -} - -void CppEmitter::emit(SemiExpDiv const& node) { - emitSemiExp("/", node); -} - -void CppEmitter::emit(SemiExpShl const& node) { - emitSemiExp("<<", node); -} - -void CppEmitter::emit(SemiExpShr const& node) { - emitSemiExp(">>", node); -} - diff --git a/CppEmitter.hpp b/CppEmitter.hpp index 3df8696..1845b4a 100644 --- a/CppEmitter.hpp +++ b/CppEmitter.hpp @@ -31,9 +31,6 @@ class CppEmitter: public Emitter { public: CppEmitter(std::ostream *stream): stream(*stream), indent_chars(0) {} - virtual void emit(Id const&) override; - virtual void emit(Integer const&) override; - virtual void emit(Float const&) override; virtual void emit(Return const&) override; virtual void emit(Loop const&) override; virtual void emit(VarDeclaration const&) override; @@ -49,32 +46,15 @@ public: virtual void emit(Function const&) override; virtual void emit(Module const&) override; virtual void emit(Program const&) override; - virtual void emit(ExpLt const&) override; - virtual void emit(ExpGt const&) override; - virtual void emit(ExpLte const&) override; - virtual void emit(ExpGte const&) override; - virtual void emit(ExpPlus const&) override; - virtual void emit(ExpMinus const&) override; - virtual void emit(ExpTimes const&) override; - virtual void emit(ExpDiv const&) override; - virtual void emit(ExpShl const&) override; - virtual void emit(ExpShr const&) override; - virtual void emit(SemiExpEq const&) override; - virtual void emit(SemiExpLt const&) override; - virtual void emit(SemiExpGt const&) override; - virtual void emit(SemiExpLte const&) override; - virtual void emit(SemiExpGte const&) override; - virtual void emit(SemiExpPlus const&) override; - virtual void emit(SemiExpMinus const&) override; - virtual void emit(SemiExpTimes const&) override; - virtual void emit(SemiExpDiv const&) override; - virtual void emit(SemiExpShl const&) override; - virtual void emit(SemiExpShr const&) override; + + virtual void emit(Id const&) override; + virtual void emit(Integer const&) override; + virtual void emit(Float const&) override; + virtual void emit(BinaryExpression const&) override; + virtual void emit(BinarySemiExpression const&) override; private: void emitIndent(); - void emitExp(char const* symbol, ExpNode const& node); - void emitSemiExp(char const* symbol, SemiExpNode const& node); void emitFunctionSignature(Function const& function); void emitFunctionParams(PointerList const& funargs); void emitFunctionArglist(PointerList const& args); diff --git a/Emitter.hpp b/Emitter.hpp index 66d6da3..97c7e66 100644 --- a/Emitter.hpp +++ b/Emitter.hpp @@ -41,34 +41,12 @@ class Main; class Function; class Module; class Program; -class ExpLt; -class ExpGt; -class ExpLte; -class ExpGte; -class ExpPlus; -class ExpMinus; -class ExpTimes; -class ExpDiv; -class ExpShl; -class ExpShr; -class SemiExpEq; -class SemiExpLt; -class SemiExpGt; -class SemiExpLte; -class SemiExpGte; -class SemiExpPlus; -class SemiExpMinus; -class SemiExpTimes; -class SemiExpDiv; -class SemiExpShl; -class SemiExpShr; +class BinaryExpression; +class BinarySemiExpression; class Emitter { public: - virtual void emit(Id const&) = 0; - virtual void emit(Integer const&) = 0; - virtual void emit(Float const&) = 0; virtual void emit(Return const&) = 0; virtual void emit(Loop const&) = 0; virtual void emit(VarDeclaration const&) = 0; @@ -84,27 +62,12 @@ public: virtual void emit(Function const&) = 0; virtual void emit(Module const&) = 0; virtual void emit(Program const&) = 0; - virtual void emit(ExpLt const&) = 0; - virtual void emit(ExpGt const&) = 0; - virtual void emit(ExpLte const&) = 0; - virtual void emit(ExpGte const&) = 0; - virtual void emit(ExpPlus const&) = 0; - virtual void emit(ExpMinus const&) = 0; - virtual void emit(ExpTimes const&) = 0; - virtual void emit(ExpDiv const&) = 0; - virtual void emit(ExpShl const&) = 0; - virtual void emit(ExpShr const&) = 0; - virtual void emit(SemiExpEq const&) = 0; - virtual void emit(SemiExpLt const&) = 0; - virtual void emit(SemiExpGt const&) = 0; - virtual void emit(SemiExpLte const&) = 0; - virtual void emit(SemiExpGte const&) = 0; - virtual void emit(SemiExpPlus const&) = 0; - virtual void emit(SemiExpMinus const&) = 0; - virtual void emit(SemiExpTimes const&) = 0; - virtual void emit(SemiExpDiv const&) = 0; - virtual void emit(SemiExpShl const&) = 0; - virtual void emit(SemiExpShr const&) = 0; + + virtual void emit(Id const&) = 0; + virtual void emit(Integer const&) = 0; + virtual void emit(Float const&) = 0; + virtual void emit(BinaryExpression const&) = 0; + virtual void emit(BinarySemiExpression const&) = 0; }; } diff --git a/Nodes.hpp b/Nodes.hpp index b6c93e1..89265e6 100644 --- a/Nodes.hpp +++ b/Nodes.hpp @@ -520,9 +520,21 @@ private: }; -class ExpNode: public Expression { +enum class Operator { + PLUS, MINUS, TIMES, DIV, + SHL, SHR, + LT, GT, GTE, LTE, EQ +}; + + +class BinaryExpression: public Expression { public: - ExpNode(Expression *l, Expression *r): left(l), right(r) {} + BinaryExpression(Expression *l, Operator op, Expression *r): + left(l), op(op), right(r) {} + + virtual void emit(Emitter *emitter) const { + emitter->emit(*this); + } Expression const& getLeft() const { return *left; @@ -532,233 +544,163 @@ public: return *right; } + Operator getOperator() const { + return op; + } + private: Pointer left; + Operator op; Pointer right; }; -class ExpLt: public ExpNode { +class ExpLt: public BinaryExpression { public: - ExpLt(Expression *l, Expression *r): ExpNode(l, r) {} + ExpLt(Expression *l, Expression *r): BinaryExpression(l, Operator::LT, r) {} +}; + + +class ExpGt: public BinaryExpression { +public: + ExpGt(Expression *l, Expression *r): BinaryExpression(l, Operator::GT, r) {} +}; + + +class ExpLte: public BinaryExpression { +public: + ExpLte(Expression *l, Expression *r): BinaryExpression(l, Operator::LTE, r) {} +}; + + +class ExpGte: public BinaryExpression { +public: + ExpGte(Expression *l, Expression *r): BinaryExpression(l, Operator::GTE, r) {} +}; + + +class ExpPlus: public BinaryExpression { +public: + ExpPlus(Expression *l, Expression *r): BinaryExpression(l, Operator::PLUS, r) {} + +}; + + +class ExpMinus: public BinaryExpression { +public: + ExpMinus(Expression *l, Expression *r): BinaryExpression(l, Operator::MINUS, r) {} +}; + + +class ExpTimes: public BinaryExpression { +public: + ExpTimes(Expression *l, Expression *r): BinaryExpression(l, Operator::TIMES, r) {} +}; + + +class ExpDiv: public BinaryExpression { +public: + ExpDiv(Expression *l, Expression *r): BinaryExpression(l, Operator::DIV, r) {} +}; + + +class ExpShl: public BinaryExpression { +public: + ExpShl(Expression *l, Expression *r): BinaryExpression(l, Operator::SHL, r) {} +}; + + +class ExpShr: public BinaryExpression { +public: + ExpShr(Expression *l, Expression *r): BinaryExpression(l, Operator::SHR, r) {} +}; + + +class BinarySemiExpression: public SemiExpression { +public: + BinarySemiExpression(Operator op, Expression *l): op(op), left(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } -}; - - -class ExpGt: public ExpNode { -public: - ExpGt(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class ExpLte: public ExpNode { -public: - ExpLte(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class ExpGte: public ExpNode { -public: - ExpGte(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class ExpPlus: public ExpNode { -public: - ExpPlus(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class ExpMinus: public ExpNode { -public: - ExpMinus(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class ExpTimes: public ExpNode { -public: - ExpTimes(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class ExpDiv: public ExpNode { -public: - ExpDiv(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class ExpShl: public ExpNode { -public: - ExpShl(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class ExpShr: public ExpNode { -public: - ExpShr(Expression *l, Expression *r): ExpNode(l, r) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } -}; - - -class SemiExpNode: public SemiExpression { -public: - SemiExpNode(Expression *l): left(l) {} Expression const& getLeft() const { return *left; } + Operator getOperator() const { + return op; + } + private: + Operator op; Pointer left; }; - -class SemiExpEq: public SemiExpNode { +class SemiExpEq: public BinarySemiExpression { public: - SemiExpEq(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpEq(Expression *l): BinarySemiExpression(Operator::EQ, l) {} }; -class SemiExpLt: public SemiExpNode { +class SemiExpLt: public BinarySemiExpression { public: - SemiExpLt(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpLt(Expression *l): BinarySemiExpression(Operator::LT, l) {} }; -class SemiExpGt: public SemiExpNode { +class SemiExpGt: public BinarySemiExpression { public: - SemiExpGt(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpGt(Expression *l): BinarySemiExpression(Operator::GT, l) {} }; -class SemiExpLte: public SemiExpNode { +class SemiExpLte: public BinarySemiExpression { public: - SemiExpLte(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpLte(Expression *l): BinarySemiExpression(Operator::LTE, l) {} }; -class SemiExpGte: public SemiExpNode { +class SemiExpGte: public BinarySemiExpression { public: - SemiExpGte(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpGte(Expression *l): BinarySemiExpression(Operator::GTE, l) {} }; -class SemiExpPlus: public SemiExpNode { +class SemiExpPlus: public BinarySemiExpression { public: - SemiExpPlus(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpPlus(Expression *l): BinarySemiExpression(Operator::PLUS, l) {} }; -class SemiExpMinus: public SemiExpNode { +class SemiExpMinus: public BinarySemiExpression { public: - SemiExpMinus(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpMinus(Expression *l): BinarySemiExpression(Operator::MINUS, l) {} }; -class SemiExpTimes: public SemiExpNode { +class SemiExpTimes: public BinarySemiExpression { public: - SemiExpTimes(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpTimes(Expression *l): BinarySemiExpression(Operator::TIMES, l) {} }; -class SemiExpDiv: public SemiExpNode { +class SemiExpDiv: public BinarySemiExpression { public: - SemiExpDiv(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpDiv(Expression *l): BinarySemiExpression(Operator::DIV, l) {} }; -class SemiExpShl: public SemiExpNode { +class SemiExpShl: public BinarySemiExpression { public: - SemiExpShl(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpShl(Expression *l): BinarySemiExpression(Operator::SHR, l) {} }; -class SemiExpShr: public SemiExpNode { +class SemiExpShr: public BinarySemiExpression { public: - SemiExpShr(Expression *l): SemiExpNode(l) {} - - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); - } + SemiExpShr(Expression *l): BinarySemiExpression(Operator::SHL, l) {} }; } // namespace