#ifndef NODES_HPP #define NODES_HPP /* * Monicelli: an esoteric language compiler * * Copyright (C) 2014 Stefano Sanfilippo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "Emitter.hpp" #include "Pointers.hpp" #include #include #include #define maybe_return(val) \ if ((val) != nullptr) return *(val); else return boost::none; namespace monicelli { enum class Type { INT, CHAR, FLOAT, BOOL, DOUBLE, VOID }; class Emittable { public: virtual ~Emittable() {} virtual void emit(Emitter *emitter) const = 0; }; class Statement: public Emittable { public: virtual void emit(Emitter *) const {} }; class SemiExpression: public Emittable { public: virtual void emit(Emitter *) const {} }; class Expression: public Emittable { public: virtual void emit(Emitter *) const {} }; class SimpleExpression: public Expression { public: virtual void emit(Emitter *) const {} }; class Id: public SimpleExpression { public: explicit Id(std::string *c): value(c) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } std::string const& getValue() const { return *value; } private: Pointer value; }; class Number: public SimpleExpression {}; class Integer: public Number { public: Integer(long i): value(i) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } long getValue() const { return value; } private: long value; }; class Float: public Number { public: Float(double f): value(f) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } double getValue() const { return value; } private: double value; }; class Return: public Statement { public: explicit Return(Expression *e): expression(e) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } boost::optional getExpression() const { maybe_return(expression); } private: Pointer expression; }; class Loop: public Statement { public: Loop(PointerList *b, Expression *c): body(b), condition(c) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } PointerList const& getBody() const { return *body; } Expression const& getCondition() const { return *condition; } private: Pointer> body; Pointer 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(Emitter *emitter) const { emitter->emit(*this); } Id const& getId() const { return *name; } bool isPointer() const { return point; } boost::optional getInitializer() const { maybe_return(init); } Type getType() const { return type; } private: Pointer name; bool point; Pointer init; Type type; }; class Assignment: public Statement { public: Assignment(Id *n, Expression *v): name(n), value(v) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } Id const& getName() const { return *name; } Expression const& getValue() const { return *value; } private: Pointer name; Pointer value; }; class Print: public Statement { public: explicit Print(Expression *e): expression(e) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } Expression const& getExpression() const { return *expression; } private: Pointer expression; }; class Input: public Statement { public: explicit Input(Id *v): variable(v) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } Id const& getVariable() const { return *variable; } private: Pointer variable; }; class Abort: public Statement { public: virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class Assert: public Statement { public: explicit Assert(Expression *e): expression(e) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } Expression const& getExpression() const { return *expression; } private: Pointer expression; }; class FunctionCall: public Statement, public Expression { public: FunctionCall(Id *n, PointerList *a): name(n), args(a) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } Id const& getName() const { return *name; } PointerList const& getArgs() const { return *args; } private: Pointer name; Pointer> args; }; class BranchCase: public Emittable { public: BranchCase(SemiExpression *c, PointerList *b): condition(c), body(b) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } SemiExpression const& getCondition() const { return *condition; } PointerList const& getBody() const { return *body; } private: Pointer condition; Pointer> body; }; class Branch: public Statement { public: class Body { public: Body(PointerList *c, PointerList *e = nullptr): cases(c), els(e) {} PointerList const& getCases() const { return *cases; } boost::optional const&> getElse() const { maybe_return(els); } private: Pointer> cases; Pointer> els; }; Branch(Id *v, Branch::Body *b): var(v), body(b) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } Id const& getVar() const { return *var; } Branch::Body const& getBody() const { return *body; } private: Pointer var; Pointer body; }; class Main: public Emittable { public: Main(PointerList *s): body(s) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } PointerList const& getBody() const { return *body; } private: Pointer> body; }; class FunArg { public: FunArg(Id *n, Type t, bool p): name(n), type(t), pointer(p) {} Id const& getName() const { return *name; } Type getType() const { return type; } bool isPointer() const { return pointer; } private: Pointer name; Type type; bool pointer; }; class Function: public Emittable { public: Function(Id *n, Type r, PointerList *a, PointerList *b): name(n), type(r), args(a), body(b) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } Id const& getName() const { return *name; } Type getType() const { return type; } PointerList const& getArgs() const { return *args; } PointerList const& getBody() const { return *body; } private: Pointer name; Type type; Pointer> args; Pointer> body; }; class Module: public Emittable { public: enum Type { SYSTEM, USER }; Module(const std::string &n, Type s): name(n), type(s) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } bool operator==(const Module &other) const noexcept { return (name == other.name) && (type == other.type); } size_t hash() const noexcept { return std::hash()(name) ^ std::hash()(type); } std::string const& getName() const { return name; } Type getType() const { return type; } private: std::string name; Type type; }; } // namespace namespace std { template<> struct hash { public: size_t operator ()(const monicelli::Module &e) const noexcept { return e.hash(); } }; } namespace monicelli { class Program: public Emittable { public: virtual void emit(Emitter *emitter) const { emitter->emit(*this); } void setMain(Main *m) { main = Pointer
(m); } void addFunction(Function *f) { functions.push_back(f); } void addModule(Module *m) { modules.insert(std::move(*m)); delete m; } boost::optional
getMain() const { maybe_return(main); } PointerList const& getFunctions() const { return functions; } std::unordered_set const& getModules() const { return modules; } private: Pointer
main; PointerList functions; std::unordered_set modules; }; class ExpNode: public Expression { public: ExpNode(Expression *l, Expression *r): left(l), right(r) {} Expression const& getLeft() const { return *left; } Expression const& getRight() const { return *right; } private: Pointer left; Pointer right; }; class ExpLt: public ExpNode { public: ExpLt(Expression *l, Expression *r): ExpNode(l, r) {} 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; } private: Pointer left; }; class SemiExpEq: public SemiExpNode { public: SemiExpEq(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpLt: public SemiExpNode { public: SemiExpLt(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpGt: public SemiExpNode { public: SemiExpGt(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpLte: public SemiExpNode { public: SemiExpLte(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpGte: public SemiExpNode { public: SemiExpGte(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpPlus: public SemiExpNode { public: SemiExpPlus(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpMinus: public SemiExpNode { public: SemiExpMinus(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpTimes: public SemiExpNode { public: SemiExpTimes(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpDiv: public SemiExpNode { public: SemiExpDiv(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpShl: public SemiExpNode { public: SemiExpShl(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; class SemiExpShr: public SemiExpNode { public: SemiExpShr(Expression *l): SemiExpNode(l) {} virtual void emit(Emitter *emitter) const { emitter->emit(*this); } }; } // namespace #undef maybe_return #endif