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:
parent
82b63189f4
commit
d7494702af
132
CppEmitter.cpp
132
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<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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
53
Emitter.hpp
53
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
276
Nodes.hpp
276
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<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
|
||||
|
|
Reference in New Issue
Block a user