Implementing AST nodes.

This commit is contained in:
Stefano Sanfilippo 2014-11-27 20:01:06 +01:00
parent a886ada349
commit 37141d1e7a
2 changed files with 721 additions and 0 deletions

188
Nodes.cpp Normal file
View File

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

533
Nodes.hpp Normal file
View File

@ -0,0 +1,533 @@
#ifndef NODES_H
#define NODES_H
#include <vector>
#include <iostream>
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<Statement*>, public Emittable {
public:
virtual void emit(std::ostream &stream, int indent = 0);
};
template <class T>
class ListEmittable: public std::vector<T>, 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<Expression*> {
};
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<Id*> {
};
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<BranchCase*> 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<Function*> 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