Commit 9f4bdacd authored by zygzagZ's avatar zygzagZ

WIP code generation

parent 0c32bb1e
CC=g++ CC=g++
CCFLAGS=-g -W -Wall -O0 -std=c++2a -Wno-unused-parameter 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 OBJS=Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o Skeleton.o ParseError.o Compiler.o Quadruple.o BasicBlock.o
.PHONY : clean distclean .PHONY : clean distclean
...@@ -32,7 +32,7 @@ Skeleton.o : src/Skeleton.cpp src/Skeleton.h src/Absyn.h ...@@ -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 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 ${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 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
${CC} ${CCFLAGS} -c src/Compiler.cpp ${CC} ${CCFLAGS} -c src/Compiler.cpp
Info.o : src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h Info.o : src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h
...@@ -47,6 +47,9 @@ Quadruple.o : src/codeGen/Quadruple.cpp src/Info.h src/InfoList.h src/Absyn.h sr ...@@ -47,6 +47,9 @@ Quadruple.o : src/codeGen/Quadruple.cpp src/Info.h src/InfoList.h src/Absyn.h sr
Variable.o : src/codeGen/Quadruple.h src/codeGen/Variable.cpp src/Info.h src/InfoList.h src/Absyn.h Variable.o : src/codeGen/Quadruple.h src/codeGen/Variable.cpp src/Info.h src/InfoList.h src/Absyn.h
${CC} ${CCFLAGS} -c src/codeGen/Variable.cpp ${CC} ${CCFLAGS} -c src/codeGen/Variable.cpp
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 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
${CC} ${CCFLAGS} -c src/Latte.cpp ${CC} ${CCFLAGS} -c src/Latte.cpp
......
...@@ -12,6 +12,8 @@ hello: ...@@ -12,6 +12,8 @@ hello:
_start: _start:
pushl %ebp pushl %ebp
movl %esp, %ebp movl %esp, %ebp
# subl $8, %esp
andl $-16, %esp
call main call main
pushl %eax pushl %eax
call exit call exit
...@@ -24,3 +26,6 @@ call printStr ...@@ -24,3 +26,6 @@ call printStr
movl $0, %eax movl $0, %eax
leave leave
ret ret
"fun test::label XD":
ret
...@@ -45,3 +45,21 @@ void error() { ...@@ -45,3 +45,21 @@ void error() {
puts("runtime error"); puts("runtime error");
exit(1); exit(1);
} }
char* __latte_mem_init(size_t size, void* virtTab) {
char *buf = calloc(len, size);
if (!buf) error();
*((void**)buf) = virtTab;
return buf;
}
char* __latte_mem_init_array(int len, size_t size, void* virtTab) {
if (len < 0) error();
char *buf = calloc(len, size);
if (!buf) error();
if (virtTab) {
for (size_t i = 0; i < len; i++) {
*((void**)(buf + i * size)) = virtTab;
}
}
return buf;
}
...@@ -192,7 +192,7 @@ public: ...@@ -192,7 +192,7 @@ public:
class Block : public Visitable class Block : public Visitable
{ {
public: public:
std::weak_ptr<Binding> binding; std::shared_ptr<Binding> binding;
std::weak_ptr<FunctionInfo> function; std::weak_ptr<FunctionInfo> function;
virtual Block *clone() const = 0; virtual Block *clone() const = 0;
...@@ -234,13 +234,14 @@ public: ...@@ -234,13 +234,14 @@ public:
bool isEqual(shared_ptr<T> f, bool sub = false) const { return isEqual((T*)&*f, sub); }; bool isEqual(shared_ptr<T> f, bool sub = false) const { return isEqual((T*)&*f, sub); };
bool operator==(Type const & f) const { return isEqual(&f); } bool operator==(Type const & f) const { return isEqual(&f); }
bool operator!=(Type const & f) const { return !isEqual(&f); } bool operator!=(Type const & f) const { return !isEqual(&f); }
virtual size_t size() const = 0;
}; };
class Expr : public Visitable class Expr : public Visitable
{ {
public: public:
virtual Expr *clone() const = 0; virtual Expr *clone() const = 0;
shared_ptr<Type> type;
}; };
class AddOp : public Visitable class AddOp : public Visitable
...@@ -656,6 +657,7 @@ public: ...@@ -656,6 +657,7 @@ public:
return true; return true;
return false; return false;
} }
size_t size() const override { return 4; };
}; };
class Str : public Type class Str : public Type
...@@ -674,6 +676,7 @@ public: ...@@ -674,6 +676,7 @@ public:
return true; return true;
return false; return false;
} }
size_t size() const override { return 4; };
}; };
class Bool : public Type class Bool : public Type
...@@ -693,6 +696,7 @@ public: ...@@ -693,6 +696,7 @@ public:
return true; return true;
return false; return false;
} }
size_t size() const override { return 4; };
}; };
class Void : public Type class Void : public Type
...@@ -712,6 +716,7 @@ public: ...@@ -712,6 +716,7 @@ public:
return true; return true;
return false; return false;
} }
size_t size() const override { return 0; };
}; };
class Array : public Type class Array : public Type
...@@ -733,6 +738,7 @@ public: ...@@ -733,6 +738,7 @@ public:
return type_->isEqual(casted->type_, sub); return type_->isEqual(casted->type_, sub);
return false; return false;
} }
size_t size() const { return 4; } // wskaźnik na stertę
}; };
class ClassT : public Type class ClassT : public Type
...@@ -750,6 +756,7 @@ public: ...@@ -750,6 +756,7 @@ public:
void swap(ClassT &); void swap(ClassT &);
std::string printName() const { return pident_ ? ("class " + pident_->string_) : "class"; } std::string printName() const { return pident_ ? ("class " + pident_->string_) : "class"; }
bool isEqual(Type const *other, bool sub = false) const; bool isEqual(Type const *other, bool sub = false) const;
size_t size() const override { return 4; };
}; };
class Fun : public Type class Fun : public Type
...@@ -768,6 +775,7 @@ public: ...@@ -768,6 +775,7 @@ public:
void swap(Fun &); void swap(Fun &);
std::string printName() const; std::string printName() const;
bool isEqual(Type const *other, bool sub = false) const; bool isEqual(Type const *other, bool sub = false) const;
size_t size() const override { return 0; };
}; };
class EVar : public Expr class EVar : public Expr
......
This diff is collapsed.
...@@ -9,7 +9,10 @@ ...@@ -9,7 +9,10 @@
#include "codeGen/Variable.h" #include "codeGen/Variable.h"
#include "ParseError.h" #include "ParseError.h"
#include "Info.h" #include "Info.h"
#include "codeGen/Quadruple.h"
#include "codeGen/BasicBlock.h"
using Op = Quadruple::Op;
class Compiler : public Skeleton class Compiler : public Skeleton
{ {
public: public:
...@@ -23,9 +26,14 @@ private: ...@@ -23,9 +26,14 @@ private:
std::filesystem::path file; std::filesystem::path file;
std::stringstream buf; std::stringstream buf;
shared_ptr<Scope> scope; shared_ptr<Scope> scope;
vector<VariablePtr> vars;
vector<QuadruplePtr> quads;
Quadruple::Op op;
VariablePtr lastVar; VariablePtr lastVar;
void compileFunction(FunctionInfoPtr f);
VariablePtr evalExpr(Visitable *expr) { VariablePtr evalExpr(Visitable *expr) {
if (!expr) throw runtime_error("No expr to eval"); if (!expr) throw runtime_error("No expr to eval");
lastVar = nullptr; lastVar = nullptr;
...@@ -39,6 +47,80 @@ private: ...@@ -39,6 +47,80 @@ private:
lastVar = nullptr; lastVar = nullptr;
return ret; return ret;
}; };
std::string mangleFunctionName(FunctionInfoPtr f) const {
if (auto c = f->klass.lock()) {
return c->name + "::" + f->name;
}
return f->name;
};
std::string getVirtName(ClassInfoPtr c) const {
return c->name + ":virt_table";
};
VariablePtr alloc(VarInfoPtr info) {
if (info->loc) {
return info->loc;
}
auto v = make_shared<Variable>(info);
vars.emplace_back(v);
info->loc = v;
return v;
}
template<typename... Args> VariablePtr alloc(Args... args) {
auto v = make_shared<Variable>(args...);
vars.emplace_back(v);
return v;
}
void endBasicBlock();
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 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 #endif
...@@ -24,14 +24,35 @@ Binding::Binding(shared_ptr<Binding> parent) ...@@ -24,14 +24,35 @@ Binding::Binding(shared_ptr<Binding> parent)
} }
ClassInfo::ClassInfo(PIdent *ident, BindingPtr parent /*= nullptr*/) ClassInfo::ClassInfo(PIdent *ident, BindingPtr parent /*= nullptr*/)
: VarInfo(ident), : VarInfo(ident),
Binding(parent) Binding(parent),
size(0), functionCount(0)
{ {
type = make_shared<ClassT>(ident->clone()); type = make_shared<ClassT>(ident->clone());
type->binding = parent; type->binding = parent;
}
size_t ClassInfo::calculateSize() {
if (size) return size;
size = 4; // pointer to virtual methods table
if (auto p = getParent()) { // parent already has virt pointer included
p->calculateSize();
size = p->size;
functionCount = p->functionCount;
}
for (const auto& var : variables) {
var->offset = size;
size += var->type->size();
}
for (auto f : functions) {
f->offset = functionCount++;
}
return size;
}; };
Scope::Scope() Scope::Scope()
......
...@@ -26,6 +26,9 @@ public: ...@@ -26,6 +26,9 @@ public:
string name; string name;
TypePtr type; TypePtr type;
int lineLocation; int lineLocation;
size_t offset;
VariablePtr loc;
bool operator<(const VarInfo &other) const { bool operator<(const VarInfo &other) const {
return name != other.name ? name < other.name : type < other.type; return name != other.name ? name < other.name : type < other.type;
...@@ -58,7 +61,7 @@ public: ...@@ -58,7 +61,7 @@ public:
Binding(BindingPtr parent = nullptr); Binding(BindingPtr parent = nullptr);
virtual ~Binding() {}; virtual ~Binding() {};
BindingPtr getParent() const { return parent.lock(); }; BindingPtr getParent() { return parent.lock(); };
}; };
class ClassInfo : public VarInfo, public Binding class ClassInfo : public VarInfo, public Binding
...@@ -68,7 +71,9 @@ public: ...@@ -68,7 +71,9 @@ public:
ClassInfo(PIdent *ident, BindingPtr parent = nullptr); ClassInfo(PIdent *ident, BindingPtr parent = nullptr);
virtual string kind() const { return "class"; } virtual string kind() const { return "class"; }
ClassInfoPtr getParent() const { return dynamic_pointer_cast<ClassInfo>(parent.lock()); }; ClassInfoPtr getParent() { return dynamic_pointer_cast<ClassInfo>(parent.lock()); };
size_t calculateSize();
size_t size, functionCount;
}; };
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <stdexcept> #include <stdexcept>
#include "Printer.h" #include "Printer.h"
#include <climits> #include <climits>
#include <cassert>
void TypeCheck::visitClassDef(ClassDef *t) { void TypeCheck::visitClassDef(ClassDef *t) {
const string name = t->getName()->string_; const string name = t->getName()->string_;
...@@ -116,7 +117,7 @@ void TypeCheck::visitClassFld(ClassFld *decl) ...@@ -116,7 +117,7 @@ void TypeCheck::visitClassFld(ClassFld *decl)
void TypeCheck::visitBlk(Blk *blk) void TypeCheck::visitBlk(Blk *blk)
{ {
BindingPtr binding = blk->binding.lock(); BindingPtr binding = blk->binding/*.lock()*/;
if (!binding) { if (!binding) {
binding = make_shared<Binding>(scope->currentBinding); binding = make_shared<Binding>(scope->currentBinding);
blk->binding = binding; blk->binding = binding;
...@@ -317,13 +318,12 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr) ...@@ -317,13 +318,12 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
throw ParseError("Class expected", e_cls_mmbr->expr_); throw ParseError("Class expected", e_cls_mmbr->expr_);
} }
ClassInfoPtr klass = scope->classes[type->pident_]; ClassInfoPtr klass = scope->classes[type->pident_];
if (klass != type->pident_->var.lock()) { assert(klass == type->pident_->var.lock());
throw ParseError("ej lol inny var");
}
VarInfoPtr var = klass->variables[e_cls_mmbr->pident_]; VarInfoPtr var = klass->variables[e_cls_mmbr->pident_];
if (!var || var == scope->variables.local(e_cls_mmbr->pident_->string_)) { if (!var || var == scope->variables.local(e_cls_mmbr->pident_->string_)) {
throw UndefinedError(e_cls_mmbr->pident_); throw UndefinedError(e_cls_mmbr->pident_);
} }
e_cls_mmbr->pident_->var = var;
lastType = var->type; lastType = var->type;
} }
...@@ -392,19 +392,11 @@ void TypeCheck::visitENewArray(ENewArray *e) ...@@ -392,19 +392,11 @@ void TypeCheck::visitENewArray(ENewArray *e)
void TypeCheck::visitENewClass(ENewClass *e_new_class) void TypeCheck::visitENewClass(ENewClass *e_new_class)
{ {
// e_new_class->pident_->accept(this); e_new_class->pident_->accept(this);
lastType = evalExpr<ClassT>(e_new_class->pident_); if (!dynamic_pointer_cast<ClassT>(lastType)) {
// if (!e_new_class->pident_->var.lock()) { ClassT expect;
throw InvalidTypeError(expect, {lastType}, e_new_class);
// } }
// ClassInfoPtr klass = dynamic_pointer_cast<ClassInfo>(e_new_class->pident_->var.lock());
// if (!klass) {
// throw ParseError("Class expected", e_new_class->pident_);
// }
// auto ret = make_shared<ClassT>(e_new_class->pident_); // make type
// ret->binding = scope->currentBinding;
// lastType = ret;
} }
void TypeCheck::visitNullCast(NullCast *null_cast) void TypeCheck::visitNullCast(NullCast *null_cast)
......
...@@ -29,7 +29,7 @@ class TypeCheck : public Visitor ...@@ -29,7 +29,7 @@ class TypeCheck : public Visitor
void setupEnv(); void setupEnv();
template<typename T> template<typename T>
shared_ptr<T> evalExpr(Visitable *expr) { shared_ptr<T> evalExpr(Expr *expr) {
if (!expr) throw runtime_error("No expr to eval"); if (!expr) throw runtime_error("No expr to eval");
lastType = nullptr; lastType = nullptr;
try { try {
...@@ -42,11 +42,12 @@ class TypeCheck : public Visitor ...@@ -42,11 +42,12 @@ class TypeCheck : public Visitor
T expect; T expect;
throw InvalidTypeError(expect, {lastType}, expr); throw InvalidTypeError(expect, {lastType}, expr);
} }
expr->type = lastType;
lastType = nullptr; lastType = nullptr;
return ret; return ret;
}; };
shared_ptr<Type> evalExpr(Visitable *expr) { shared_ptr<Type> evalExpr(Expr *expr) {
if (!expr) throw runtime_error("No expr to eval"); if (!expr) throw runtime_error("No expr to eval");
try { try {
expr->accept(this); expr->accept(this);
...@@ -54,9 +55,12 @@ class TypeCheck : public Visitor ...@@ -54,9 +55,12 @@ class TypeCheck : public Visitor
throw ParseError(err, expr); throw ParseError(err, expr);
} }
if (!lastType) throw ParseError("No expression type", expr); if (!lastType) throw ParseError("No expression type", expr);
auto ret = lastType; if (auto fun = dynamic_pointer_cast<Fun>(lastType)) {
throw ParseError("Unexpected function access", expr);
}
expr->type = lastType;
lastType = nullptr; lastType = nullptr;
return ret; return expr->type;
}; };
public: public:
BindingPtr getParentBinding() const { return scope->currentClass ? static_pointer_cast<Binding>(scope->currentClass) : static_pointer_cast<Binding>(scope); } BindingPtr getParentBinding() const { return scope->currentClass ? static_pointer_cast<Binding>(scope->currentClass) : static_pointer_cast<Binding>(scope); }
......
...@@ -6,16 +6,21 @@ ...@@ -6,16 +6,21 @@
using namespace std; using namespace std;
class VarInfo; class VarInfo;
class FunctionInfo;
class ClassInfo;
class Binding;
class Type;
using VarInfoPtr = shared_ptr<VarInfo>; using VarInfoPtr = shared_ptr<VarInfo>;
class FunctionInfo;
using FunctionInfoPtr = shared_ptr<FunctionInfo>; using FunctionInfoPtr = shared_ptr<FunctionInfo>;
class ClassInfo;
using ClassInfoPtr = shared_ptr<ClassInfo>; using ClassInfoPtr = shared_ptr<ClassInfo>;
class Binding;
using BindingPtr = shared_ptr<Binding>; using BindingPtr = shared_ptr<Binding>;
class Type;
using TypePtr = shared_ptr<Type>; using TypePtr = shared_ptr<Type>;
class Variable;
using VariablePtr = shared_ptr<Variable>;
class Quadruple;
using QuadruplePtr = shared_ptr<Quadruple>;
class BasicBlock;
using BasicBlockPtr = shared_ptr<BasicBlock>;
class Visitable; class Visitable;
class Program; class Program;
......
//
// Created by zygzagz on 03.01.2021.
//
#include "BasicBlock.h"
//
// Created by zygzagz on 03.01.2021.
//
#ifndef ZAD2_BASICBLOCK_H
#define ZAD2_BASICBLOCK_H
#include "../TypeDefs.h"
#include <vector>
using namespace std;
class BasicBlock {
vector<QuadruplePtr> quads;
vector<BasicBlockPtr> in, out;
};
#endif //ZAD2_BASICBLOCK_H
#ifndef ZAD2_QUAD_H #ifndef ZAD2_QUAD_H
#define ZAD2_QUAD_H #define ZAD2_QUAD_H
#include <string> #include <string>
#include <utility>
#include "../Info.h" #include "../Info.h"
#include "Variable.h" #include "Variable.h"
using namespace std; using namespace std;
class Quadruple { static const std::string opNames[] = { "_U", "-", "!", "", "_UE",
"_B", "+", "-", "*", "/", "%", "&", "|", "^", "_BE",
"_C", "<", "<=", "==", "!=", ">=", ">", "_CE"};
class Quadruple : std::enable_shared_from_this<Quadruple> {
public: public:
enum Op { class Op {
public:
enum OpType {
UNARY, UNARY,
Neg, Neg, Not, Copy, UNARY_END,
Not,
BINARY, BINARY,
Plus, Plus, Minus, Mul, Div, Mod, And, Or, Xor, BINARY_END,
Minus, CMP,
Mul, LT, LE, EQ, NEQ, GE, GT, CMP_END
Div,
And,
Or,
Xor,
}; };
OpType op;
string label; Op(OpType op = UNARY) : op(op) {};
operator OpType() const { return op; };
static OpType kind(OpType op) {
if (op <= UNARY_END) return UNARY;
if (op <= BINARY_END) return BINARY;
return CMP;
};
static const std::string& name(OpType op) {
return opNames[op];
}
};
virtual ~Quadruple() {};
virtual std::string toString() const = 0;
}; };
class QAssign : Quadruple { class QWriteVar : public Quadruple {
public:
VariablePtr loc; VariablePtr loc;
explicit QWriteVar(VariablePtr loc) : Quadruple(), loc(std::move(loc)) {};
std::string toString() const override { return loc ? ("\t" + loc->name + " := ") : "\t"; }
};
class QLabel : public Quadruple {
public:
string label;
std::string toString() const override { return "\"" + label + "\":"; }
QLabel(std::string comment) : label(comment) {}
};
class QAssign : public QWriteVar {
public:
Op op; Op op;
vector<VariablePtr> args; vector<VariablePtr> args;
VarInfoPtr varInfo;
QAssign(VariablePtr loc, Op op, vector<VariablePtr> list) : QWriteVar(std::move(loc)), op(op), args(std::move(list)) {};
QAssign(VariablePtr loc, VariablePtr l, Op op, VariablePtr r) : QWriteVar(std::move(loc)), op(op), args({std::move(l), std::move(r)}) {};
QAssign(VariablePtr loc, Op op, VariablePtr x) : QWriteVar(std::move(loc)), op(op), args({std::move(x)}) {};
std::string toString() const override {
if (args.size() == 1)
return QWriteVar::toString() + Op::name(op) + " " + args[0]->name;
else
return QWriteVar::toString() + args[0]->name + " " + Op::name(op) + " " + args[1]->name;
}
};
class QJump : public Quadruple {
public:
shared_ptr<QLabel> target;
explicit QJump(shared_ptr<QLabel> target) : target(std::move(target)) {};
std::string toString() const override {
return "\tjump " + target->label;
}
};
class QJumpCond : public QJump {
public:
VariablePtr left;
Op op;
VariablePtr right;
QJumpCond(shared_ptr<QLabel> to, VariablePtr left, Op op, VariablePtr right)
: QJump(std::move(to)), left(std::move(left)), op(op), right(std::move(right)) {};
QJumpCond(shared_ptr<QLabel> to, Op op, VariablePtr right)
: QJumpCond(std::move(to), nullptr, op, std::move(right)) {};
std::string toString() const override {
if (!left)
return "\tjump \"" + target->label + "\" if " + Op::name(op) + " " + right->name;
else
return "\tjump \"" + target->label + "\" if " + left->name + " " + Op::name(op) + " " + right->name;
}
};
class QParam : public Quadruple {
public:
VariablePtr param;
int num;
QParam(VariablePtr param, int num) : param(std::move(param)), num(num) {};
std::string toString() const override {
if (num == 0) {
return "\tparam self " + param->name;
} else {
return "\tparam #" + to_string(num) + " <- " + param->name;
}
}
};
class QCall : public QWriteVar {
public:
FunctionInfoPtr fn;
int params;
VariablePtr self;
QCall(VariablePtr loc, FunctionInfoPtr fn, int params, VariablePtr self)
: QWriteVar(std::move(loc)), fn(std::move(fn)), params(params), self(std::move(self)) {};
std::string toString() const override {
if (self) {
return QWriteVar::toString() + "call " + fn->name + " of " + self->name + " with " + to_string(params) + " params";
} else {
return QWriteVar::toString() + "call " + fn->name + " with " + to_string(params) + " params";
}
}
};
class QReturn : public Quadruple {
public:
VariablePtr ret;
explicit QReturn(VariablePtr ret) : ret(std::move(ret)) {};
std::string toString() const override {
if (ret) {
return "\treturn " + ret->name;
} else {
return "\treturn";
}
}
};
class QAccess : public QWriteVar {
public:
QAccess(VariablePtr loc, VariablePtr base, VariablePtr index, int multiplier, int offset)
: QWriteVar(std::move(loc)), base(std::move(base)), index(std::move(index)), multiplier(multiplier), offset(offset)
{};
// leal 8(,%eax,4), %eax # Arithmetic: multiply eax by 4 and add 8
// leal (%edx,%eax,2), %eax # Arithmetic: multiply eax by 2 and add edx
VariablePtr base;
VariablePtr index;
int multiplier;
int offset;
std::string toString() const override {
auto ret = QWriteVar::toString() + "[" + base->name;
if (multiplier || !(index->constExpr || !index->val)) ret += " + " + to_string(multiplier) + "*" + index->name;
if (offset) ret += " + " + to_string(offset);
return ret + "]";
}
};
class QAlloc : public QWriteVar {
public:
size_t size;
VariablePtr count;
std::string virtSymbol;
QAlloc(VariablePtr loc, size_t size, std::string virtSymbol, VariablePtr count = nullptr)
: QWriteVar(std::move(loc)), size(size), count(std::move(count)), virtSymbol(std::move(virtSymbol)) {};
std::string toString() const override {
std::string ret = QWriteVar::toString() + "alloc (" + to_string(size) + ")";
if (count) { ret += " [" + count->name + "]"; }
if (!virtSymbol.empty()) { ret += " " + virtSymbol; }
return ret;
}
}; };
......
...@@ -5,14 +5,26 @@ ...@@ -5,14 +5,26 @@
#ifndef ZAD2_VARIABLE_H #ifndef ZAD2_VARIABLE_H
#define ZAD2_VARIABLE_H #define ZAD2_VARIABLE_H
#include <utility>
#include "../TypeDefs.h"
class Variable : std::enable_shared_from_this<Variable> { class Variable : std::enable_shared_from_this<Variable> {
public:
Variable() = default;
explicit Variable(VarInfoPtr info) : info(std::move(info)), constExpr(false), val(0) {};
explicit Variable(int constVal) : type(new Int), constExpr(true), val(constVal) {};
explicit Variable(std::string symbolName) {};
VarInfoPtr info;
TypePtr type;
bool constExpr;
int val;
std::string name;
// chcemy znać lokalizację w pamięci gdzie zapisać z powrotem i gdzie leży ogólnie
// lok. może nie być, jeśli to tymczasowa
// registers // registers
// is mem? // is mem?
// where in mem - id or offset // where in mem - id or offset
}; };
using VariablePtr = shared_ptr<Variable>;
#endif //ZAD2_VARIABLE_H #endif //ZAD2_VARIABLE_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