From 37141d1e7a3a4e5c9d752de3f7a99cbeddecad4a Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Thu, 27 Nov 2014 20:01:06 +0100 Subject: [PATCH] Implementing AST nodes. --- Nodes.cpp | 188 +++++++++++++++++++ Nodes.hpp | 533 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 721 insertions(+) create mode 100644 Nodes.cpp create mode 100644 Nodes.hpp diff --git a/Nodes.cpp b/Nodes.cpp new file mode 100644 index 0000000..4e85601 --- /dev/null +++ b/Nodes.cpp @@ -0,0 +1,188 @@ +#include "Nodes.hpp" + +using namespace monicelli; + +static const std::string BLOCK = " "; + +void emitIndent(std::ostream &stream, int indent) { + for (int i = 0; i < indent; ++i) { + stream << BLOCK; + } +} + +void Id::emit(std::ostream &stream, int indent) { + stream << value; +} + +void Integer::emit(std::ostream &stream, int indent) { + stream << value; +} + +void Float::emit(std::ostream &stream, int indent) { + stream << value; +} + +void ExpNode::emit(std::ostream &stream, int indent) { + left->emit(stream); + stream << ' ' << getSym() << ' '; + right->emit(stream); +} + +void SemiExpNode::emit(std::ostream &stream, int indent) { + SimpleExpression *e = dynamic_cast(left); + bool braces = (e == nullptr); + + stream << ' ' << getSym() << ' '; + if (braces) stream << "("; + left->emit(stream); + if (braces) stream << ")"; +} + +void StatementList::emit(std::ostream &stream, int indent) { + for (Statement *s: *this) { + emitIndent(stream, indent); + s->emit(stream, indent); + stream << ";\n"; + } +} + +void Return::emit(std::ostream &stream, int indent) { + stream << "return"; + + if (expression != nullptr) { + stream << ' '; + expression->emit(stream); + } +} + +void Loop::emit(std::ostream &stream, int indent) { + stream << "do {\n"; + + body->emit(stream, indent + 1); + + emitIndent(stream, indent); + stream << "} while ("; + condition->emit(stream); + stream << ")"; +} + +void BranchCase::emit(std::ostream &stream, int indent) { + condition->emit(stream); + stream << ") {\n"; + body->emit(stream, indent); + emitIndent(stream, indent - 1); + stream << "}"; +} + +void Branch::emit(std::ostream &stream, int indent) { + stream << "if ("; + var->emit(stream); + + if (cases->size() > 0) { + BranchCase *last = cases->back(); + for (BranchCase *c: *cases) { + c->emit(stream, indent + 1); + if (c != last) { + stream << " else if ("; + var->emit(stream); + } + } + } + + stream << " else {\n"; + els->emit(stream, indent + 1); + emitIndent(stream, indent); + stream << "}"; +} + +void VarDeclaration::emit(std::ostream &stream, int indent) { + switch (type) { + case TYPENAME_INT: + stream << "int"; + break; + case TYPENAME_CHAR: + stream << "char"; + break; + case TYPENAME_FLOAT: + stream << "float"; + break; + case TYPENAME_BOOL: + stream << "bool"; + break; + case TYPENAME_DOUBLE: + stream << "double"; + break; + } + + stream << ' '; + if (point) stream << '*'; + name->emit(stream); + + if (init != nullptr) { + stream << " = "; + init->emit(stream); + } +} + +void Assignment::emit(std::ostream &stream, int indent) { + name->emit(stream); + stream << " = "; + value->emit(stream); +} + +void Print::emit(std::ostream &stream, int indent) { + stream << "std::cout << "; + expression->emit(stream); + stream << " << std::endl;"; +} + +void Input::emit(std::ostream &stream, int indent) { + stream << "std::cin >> "; + variable->emit(stream); +} + +void Abort::emit(std::ostream &stream, int indent) { + stream << "std::exit(1)"; +} + +void Assert::emit(std::ostream &stream, int indent) { + stream << "std::assert("; + expression->emit(stream); + stream << ")"; +} + +void FunctionCall::emit(std::ostream &stream, int indent) { + name->emit(stream); + stream << "("; + args->emit(stream); + stream << ")"; +} + +void Function::emit(std::ostream &stream, int indent) { + emitIndent(stream, indent); + + stream << "void "; + name->emit(stream); + stream << "("; + args->emit(stream); + stream << ") {\n"; + body->emit(stream, indent + 1); + stream << "}\n"; +} + +void Main::emit(std::ostream &stream, int indent) { + emitIndent(stream, indent); + + stream << "int main() {\n"; + body->emit(stream, indent + 1); + stream << "}\n"; +} + +void Program::emit(std::ostream &stream, int indent) { + for (Function *f: functions) { + f->emit(stream); + } + + main->emit(stream); +} + diff --git a/Nodes.hpp b/Nodes.hpp new file mode 100644 index 0000000..ac9dddf --- /dev/null +++ b/Nodes.hpp @@ -0,0 +1,533 @@ +#ifndef NODES_H +#define NODES_H + +#include +#include + +namespace monicelli { + +typedef enum { + TYPENAME_INT, + TYPENAME_CHAR, + TYPENAME_FLOAT, + TYPENAME_BOOL, + TYPENAME_DOUBLE +} Type; + + +class Emittable { +public: + virtual void emit(std::ostream &stream, int indent = 0) = 0; +}; + + +class Statement: public Emittable { +}; + + +class SemiExpression: public Emittable { +}; + + +class Expression: public Emittable { +}; + + +class StatementList: public std::vector, public Emittable { +public: + virtual void emit(std::ostream &stream, int indent = 0); +}; + + +template +class ListEmittable: public std::vector, public Emittable { +public: + virtual void emit(std::ostream &stream, int indent = 0) { + if (this->size() > 0) { + T last = this->back(); // TODO wut? + for (T e: *this) { + e->emit(stream); + if (e != last) { + stream << getSeparator(); + } + } + } + } + +protected: + virtual std::string getSeparator() const { + return ", "; + } +}; + + +class ExpressionList: public ListEmittable { +}; + + +class SimpleExpression: public Expression { +}; + + +class Id: public SimpleExpression { +public: + explicit Id(const char *c): value(c) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + std::string value; +}; + + +class IdList: public ListEmittable { +}; + + +class Number: public SimpleExpression { +public: + virtual void emit(std::ostream &stream, int indent = 0) {} +}; + + +class Integer: public Number { +public: + Integer(long i): value(i) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + long value; +}; + + +class Float: public Number { +public: + Float(double f): value(f) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + double value; +}; + + +class Return: public Statement { +public: + explicit Return(Expression *e): expression(e) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Expression *expression; +}; + + +class Loop: public Statement { +public: + Loop(StatementList *b, Expression *c): body(b), condition(c) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + StatementList *body; + Expression *condition; +}; + + +class VarDeclaration: public Statement { +public: + VarDeclaration(Id *n, Type t, bool p, Expression *i): + name(n), point(p), init(i), type(t) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Id *name; + bool point; + Expression *init; + Type type; +}; + + +class Assignment: public Statement { +public: + Assignment(Id *n, Expression *v): name(n), value(v) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Id *name; + Expression *value; +}; + + +class Print: public Statement { +public: + explicit Print(Expression *e): expression(e) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Expression *expression; +}; + + +class Input: public Statement { +public: + explicit Input(Id *v): variable(v) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Id *variable; +}; + + +class Abort: public Statement { +public: + virtual void emit(std::ostream &stream, int indent = 0); +}; + + +class Assert: public Statement { +public: + explicit Assert(Expression *e): expression(e) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Expression *expression; +}; + + +class FunctionCall: public Statement, public Expression { +public: + FunctionCall(Id *n, ExpressionList *a): name(n), args(a) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Id *name; + ExpressionList *args; +}; + + +class BranchCase: public Emittable { +public: + BranchCase(SemiExpression *c, StatementList *b): condition(c), body(b) {} + + virtual void emit(std::ostream &stream, int indent = 0); +private: + SemiExpression *condition; + StatementList *body; +}; + + +typedef std::vector BranchCaseList; + + +class Branch: public Statement { +public: + Branch(Id *v, BranchCaseList *c, StatementList *e): + var(v), cases(c), els(e) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Id *var; + BranchCaseList *cases; + StatementList *els; +}; + + +class Main: public Emittable { +public: + Main(StatementList *s): body(s) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + StatementList *body; +}; + + +class Function: public Emittable { +public: + Function(Id *n, IdList *a, StatementList *b): + name(n), args(a), body(b) {} + virtual void emit(std::ostream &stream, int indent = 0); + +private: + Id *name; + IdList *args; + StatementList *body; +}; + +class Program: public Emittable { +public: + virtual void emit(std::ostream &stream, int indent = 0); + + void setMain(Main *m) { + main = m; + } + + void addFunction(Function *f) { + functions.push_back(f); + } + +private: + Main *main; + std::vector functions; +}; + + +class ExpNode: public Expression { +public: + ExpNode(Expression *l, Expression *r): left(l), right(r) {} + virtual void emit(std::ostream &stream, int indent = 0); + +protected: + virtual std::string getSym() = 0; + +private: + Expression *left; + Expression *right; +}; + + +class ExpLt: public ExpNode { +public: + ExpLt(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return "<"; + } +}; + + +class ExpGt: public ExpNode { +public: + ExpGt(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return ">"; + } +}; + + +class ExpLte: public ExpNode { +public: + ExpLte(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return "<="; + } +}; + + +class ExpGte: public ExpNode { +public: + ExpGte(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return ">="; + } +}; + + +class ExpPlus: public ExpNode { +public: + ExpPlus(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return "+"; + } +}; + + +class ExpMinus: public ExpNode { +public: + ExpMinus(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return "-"; + } +}; + + +class ExpTimes: public ExpNode { +public: + ExpTimes(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return "*"; + } +}; + + +class ExpDiv: public ExpNode { +public: + ExpDiv(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return "/"; + } +}; + + +class ExpShl: public ExpNode { +public: + ExpShl(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return "<<"; + } +}; + + +class ExpShr: public ExpNode { +public: + ExpShr(Expression *l, Expression *r): ExpNode(l, r) {} + +protected: + virtual std::string getSym() { + return ">>"; + } +}; + + +class SemiExpNode: public SemiExpression { +public: + SemiExpNode(Expression *l): left(l) {} + virtual void emit(std::ostream &stream, int indent = 0); + +protected: + virtual std::string getSym() = 0; + +private: + Expression *left; +}; + + + +class SemiExpEq: public SemiExpNode { +public: + SemiExpEq(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return "=="; + } +}; + + +class SemiExpLt: public SemiExpNode { +public: + SemiExpLt(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return "<"; + } +}; + + +class SemiExpGt: public SemiExpNode { +public: + SemiExpGt(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return ">"; + } +}; + + +class SemiExpLte: public SemiExpNode { +public: + SemiExpLte(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return "<="; + } +}; + + +class SemiExpGte: public SemiExpNode { +public: + SemiExpGte(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return ">="; + } +}; + + +class SemiExpPlus: public SemiExpNode { +public: + SemiExpPlus(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return "+"; + } +}; + + +class SemiExpMinus: public SemiExpNode { +public: + SemiExpMinus(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return "-"; + } +}; + + +class SemiExpTimes: public SemiExpNode { +public: + SemiExpTimes(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return "*"; + } +}; + + +class SemiExpDiv: public SemiExpNode { +public: + SemiExpDiv(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return "/"; + } +}; + + +class SemiExpShl: public SemiExpNode { +public: + SemiExpShl(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return "<<"; + } +}; + + +class SemiExpShr: public SemiExpNode { +public: + SemiExpShr(Expression *l): SemiExpNode(l) {} + +protected: + virtual std::string getSym() { + return ">>"; + } +}; + +} // namespace + +#endif +