Simplify the Expression hierarchy by moving the operator on the binary father.

As a consequence, the Emitter interface is greatly simplified.
This commit is contained in:
Stefano Sanfilippo 2015-03-05 17:25:02 +01:00
parent 82b63189f4
commit d7494702af
4 changed files with 167 additions and 326 deletions

View File

@ -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<SimpleExpression const*>(&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);
}

View File

@ -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<FunArg> const& funargs);
void emitFunctionArglist(PointerList<Expression> const& args);

View File

@ -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;
};
}

276
Nodes.hpp
View File

@ -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<Expression> left;
Operator op;
Pointer<Expression> 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<Expression> 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