Implementing AST nodes.
This commit is contained in:
parent
a886ada349
commit
37141d1e7a
188
Nodes.cpp
Normal file
188
Nodes.cpp
Normal 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
533
Nodes.hpp
Normal 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
|
||||
|
Reference in New Issue
Block a user