Commit f63ff4e9 authored by zygzagZ's avatar zygzagZ

Refactor Compiler - oddzielony generator kodu czwórkowego

parent 5b9b463e
CC=g++
CCFLAGS=-g -W -Wall -O0 -std=c++2a -Wno-unused-parameter
OBJS=Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o Skeleton.o ParseError.o Compiler.o Quadruple.o BasicBlock.o
OBJS=Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o Skeleton.o ParseError.o Compiler.o Quadruple.o BasicBlock.o QuadrupleGenerator.o
.PHONY : clean distclean
......@@ -32,7 +32,7 @@ Skeleton.o : src/Skeleton.cpp src/Skeleton.h src/Absyn.h
TypeCheck.o : src/TypeCheck.cpp src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h
${CC} ${CCFLAGS} -c src/TypeCheck.cpp
Compiler.o : src/Compiler.cpp src/Compiler.h src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h src/codeGen/Quadruple.h src/codeGen/Variable.h
Compiler.o : src/Compiler.cpp src/Compiler.h src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h src/codeGen/Quadruple.h src/codeGen/Variable.h src/codeGen/QuadrupleGenerator.h
${CC} ${CCFLAGS} -c src/Compiler.cpp
Info.o : src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h
......@@ -50,7 +50,10 @@ Variable.o : src/codeGen/Quadruple.h src/codeGen/Variable.cpp src/Info.h src/Inf
BasicBlock.o : src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/codeGen/BasicBlock.cpp src/codeGen/Variable.h src/Info.h src/InfoList.h src/Absyn.h
${CC} ${CCFLAGS} -c src/codeGen/BasicBlock.cpp
Latte.o : src/Latte.cpp src/Parser.h src/Printer.h src/Absyn.h src/ParseError.h src/TypeCheck.h src/Compiler.h src/Info.h src/InfoList.h
QuadrupleGenerator.o : src/codeGen/QuadrupleGenerator.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h src/Compiler.h src/codeGen/QuadrupleGenerator.h
${CC} ${CCFLAGS} -c src/codeGen/QuadrupleGenerator.cpp
Latte.o : src/Latte.cpp src/Parser.h src/Printer.h src/Absyn.h src/ParseError.h src/TypeCheck.h src/Compiler.h src/Info.h src/InfoList.h src/codeGen/QuadrupleGenerator.h
${CC} ${CCFLAGS} -c src/Latte.cpp
lib/runtime.o : lib/runtime.c Makefile
......
This diff is collapsed.
......@@ -11,157 +11,35 @@
#include "Info.h"
#include "codeGen/Quadruple.h"
#include "codeGen/BasicBlock.h"
#include "codeGen/QuadrupleGenerator.h"
using Op = Quadruple::Op;
class Compiler : public Skeleton
{
class Compiler {
public:
Compiler(const std::string& f, shared_ptr<Scope> s) : file(f), buf(), scope(std::move(s)) {};
std::string compile(Visitable *v);
Compiler(const std::string& f, shared_ptr<Scope> s) : file(f), buf(), scope(s), quadGen(std::move(s)) {};
static const std::string extension;
static void externalCommand(std::filesystem::path file);
string compile(Visitable *v);
static std::string getVirtName(const ClassInfoPtr& c) {
return c->name + ":virt_table";
}
private:
std::filesystem::path file;
std::stringstream buf;
shared_ptr<Scope> scope;
vector<VariablePtr> vars;
vector<BasicBlockPtr> blocks;
Quadruple::Op op;
BasicBlockPtr block;
VariablePtr lastVar;
int lineno;
void compileFunction(FunctionInfoPtr f);
VariablePtr evalLVal(Visitable *expr) {
auto info = evalExpr(expr)->info;
if (!info) {
throw ParseError("LValue expected", expr);
}
info->loc = nullptr;
return alloc(info);
}
QuadrupleGenerator quadGen;
VariablePtr evalExpr(Visitable *expr) {
if (!expr) throw runtime_error("No expr to eval");
lineno = expr->lineno;
lastVar = nullptr;
try {
expr->accept(this);
} catch (const ParseError &err) {
throw ParseError(err, expr);
}
if (!lastVar) throw ParseError("No variable found", expr);
auto ret = lastVar;
lastVar = nullptr;
return ret;
};
void compileFunction(const FunctionInfoPtr& f);
static std::string mangleFunctionName(const FunctionInfoPtr& f) {
if (auto c = f->klass.lock()) {
return c->name + "::" + f->name;
}
return f->name;
};
static std::string getVirtName(const ClassInfoPtr& c) {
return c->name + ":virt_table";
};
VariablePtr alloc(const VarInfoPtr& info) {
if (info->loc) {
return info->loc;
}
auto v = make_shared<Variable>(info);
vars.emplace_back(v);
if (!info->isInstanceVariable()) {
info->loc = v;
}
return v;
}
template<typename... Args> VariablePtr alloc(Args... args) {
auto v = make_shared<Variable>(args...);
vars.emplace_back(v);
return v;
}
template<typename T, typename... Args> QuadruplePtr addQuad(Args... args) {
return addQuad(make_shared<T>(args...));
}
QuadruplePtr addQuad(QuadruplePtr quad) {
quad->lineno = lineno;
flushLastQuad();
lastQuad = quad;
return quad;
}
QuadruplePtr lastQuad;
void flushLastQuad() {
if (lastQuad) {
block->quads.emplace_back(lastQuad);
lastQuad = nullptr;
}
}
BasicBlockPtr flushBasicBlock();
void assign(Expr* lval, VariablePtr val);
VariableLayout captureEnv();
void merge2Envs(VariableLayout *env1, BasicBlockPtr b1, VariableLayout *env2, BasicBlockPtr b2);
void compileCond(Expr *cond, Stmt *stmt1, Stmt *stmt2);
void visitEVar(EVar *p) override;
void visitEIndexAcc(EIndexAcc *p) override;
void visitEClsMmbr(EClsMmbr *p) override;
void visitEApp(EApp *p) override;
void visitELitInt(ELitInt *p) override;
void visitELitTrue(ELitTrue *p) override;
void visitELitFalse(ELitFalse *p) override;
void visitEString(EString *p) override;
void visitENewArray(ENewArray *p) override;
void visitENewClass(ENewClass *p) override;
void visitNullCast(NullCast *p) override;
void visitNeg(Neg *p) override;
void visitNot(Not *p) override;
void visitEMul(EMul *p) override;
void visitEAdd(EAdd *p) override;
void visitERel(ERel *p) override;
void visitEAnd(EAnd *p) override;
void visitEOr(EOr *p) override;
void visitBlk(Blk *p) override;
void visitInit(Init *p) override;
void visitAss(Ass *p) override;
void visitIncr(Incr *p) override;
void visitDecr(Decr *p) override;
void visitRet(Ret *p) override;
void visitVRet(VRet *p) override;
void visitCond(Cond *p) override;
void visitCondElse(CondElse *p) override;
void visitWhile(While *p) override;
void visitSExp(SExp *p) override;
void visitForEach(ForEach *p) override;
void visitPlus(Plus *p) override { op = Op::Plus; };
void visitMinus(Minus *p) override { op = Op::Minus; };
void visitTimes(Times *p) override { op = Op::Mul; };
void visitDiv(Div *p) override { op = Op::Div; };
void visitMod(Mod *p) override { op = Op::Mod; };
void visitLTH(LTH *p) override { op = Op::LT; };
void visitLE(LE *p) override { op = Op::LE; };
void visitGTH(GTH *p) override { op = Op::GT; };
void visitGE(GE *p) override { op = Op::GE; };
void visitEQU(EQU *p) override { op = Op::EQ; };
void visitNE(NE *p) override { op = Op::NEQ; };
};
#endif
This diff is collapsed.
//
// Created by zygzagz on 05.01.2021.
//
#ifndef ZAD2_QUADRUPLEGENERATOR_H
#define ZAD2_QUADRUPLEGENERATOR_H
#include <filesystem>
#include <utility>
#include "../TypeDefs.h"
#include "../Absyn.h"
#include "../Skeleton.h"
#include "Variable.h"
#include "../ParseError.h"
#include "../Info.h"
#include "Quadruple.h"
#include "BasicBlock.h"
class QuadrupleGenerator : public Skeleton {
public:
QuadrupleGenerator(shared_ptr<Scope> s) : lineno(0), scope(std::move(s)) {}
vector<BasicBlockPtr> compileFunction(FunctionInfoPtr f);
private:
vector<VariablePtr> vars;
vector<BasicBlockPtr> blocks;
Quadruple::Op op;
BasicBlockPtr block;
VariablePtr lastVar;
int lineno;
shared_ptr<Scope> scope;
VariablePtr evalLVal(Visitable *expr) {
auto info = evalExpr(expr)->info;
if (!info) {
throw ParseError("LValue expected", expr);
}
info->loc = nullptr;
return alloc(info);
}
VariablePtr evalExpr(Visitable *expr) {
if (!expr) throw runtime_error("No expr to eval");
lineno = expr->lineno;
lastVar = nullptr;
try {
expr->accept(this);
} catch (const ParseError &err) {
throw ParseError(err, expr);
}
if (!lastVar) throw ParseError("No variable found", expr);
auto ret = lastVar;
lastVar = nullptr;
return ret;
}
VariablePtr alloc(const VarInfoPtr& info) {
if (info->loc) {
return info->loc;
}
auto v = make_shared<Variable>(info);
vars.emplace_back(v);
if (!info->isInstanceVariable()) {
info->loc = v;
}
return v;
}
template<typename... Args> VariablePtr alloc(Args... args) {
auto v = make_shared<Variable>(args...);
vars.emplace_back(v);
return v;
}
template<typename T, typename... Args> QuadruplePtr addQuad(Args... args) {
return addQuad(make_shared<T>(args...));
}
QuadruplePtr addQuad(QuadruplePtr quad) {
quad->lineno = lineno;
flushLastQuad();
lastQuad = quad;
return quad;
}
QuadruplePtr lastQuad;
void flushLastQuad() {
if (lastQuad) {
block->quads.emplace_back(lastQuad);
lastQuad = nullptr;
}
}
BasicBlockPtr flushBasicBlock();
void visitPlus(Plus *p) override { op = Quadruple::Op::Plus; }
void visitMinus(Minus *p) override { op = Quadruple::Op::Minus; }
VariableLayout captureEnv();
void visitTimes(Times *p) override { op = Quadruple::Op::Mul; }
void visitDiv(Div *p) override { op = Quadruple::Op::Div; }
void visitMod(Mod *p) override { op = Quadruple::Op::Mod; }
void visitLTH(LTH *p) override { op = Quadruple::Op::LT; }
void visitLE(LE *p) override { op = Quadruple::Op::LE; }
void visitEVar(EVar *p) override;
void visitGTH(GTH *p) override { op = Quadruple::Op::GT; }
void visitGE(GE *p) override { op = Quadruple::Op::GE; }
void visitELitInt(ELitInt *p) override;
void visitEQU(EQU *p) override { op = Quadruple::Op::EQ; }
void visitNE(NE *p) override { op = Quadruple::Op::NEQ; }
void visitELitTrue(ELitTrue *p) override;
void visitELitFalse(ELitFalse *p) override;
void visitEString(EString *p) override;
void visitNullCast(NullCast *p) override;
void visitNeg(Neg *p) override;
void visitNot(Not *p) override;
void visitEMul(EMul *p) override;
void visitEAdd(EAdd *p) override;
void visitERel(ERel *p) override;
void visitEAnd(EAnd *p) override;
void visitEOr(EOr *p) override;
void visitEIndexAcc(EIndexAcc *p) override;
void visitEClsMmbr(EClsMmbr *p) override;
void visitEApp(EApp *p) override;
void visitENewArray(ENewArray *p) override;
void visitENewClass(ENewClass *p) override;
void visitInit(Init *p) override;
void assign(Expr* lval, VariablePtr val);
void visitAss(Ass *p) override;
void visitIncr(Incr *p) override;
void visitDecr(Decr *p) override;
void visitRet(Ret *p) override;
void visitVRet(VRet *p) override;
void visitCond(Cond *p) override;
void visitCondElse(CondElse *p) override;
void compileCond(Expr *cond, Stmt *stmt1, Stmt *stmt2);
void merge2Envs(VariableLayout *env1, BasicBlockPtr b1, VariableLayout *env2, BasicBlockPtr b2);
void visitWhile(While *expr) override;
void visitSExp(SExp *p) override;
void visitForEach(ForEach *p) override;
void visitBlk(Blk *p) override;
};
#endif //ZAD2_QUADRUPLEGENERATOR_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment