Commit 9b245472 authored by zygzagZ's avatar zygzagZ

quadcode względnie działa, brakuje flow zmiennych lokalnych między

blokami prostymi
parent 9f4bdacd
...@@ -196,6 +196,8 @@ public: ...@@ -196,6 +196,8 @@ public:
std::weak_ptr<FunctionInfo> function; std::weak_ptr<FunctionInfo> function;
virtual Block *clone() const = 0; virtual Block *clone() const = 0;
std::shared_ptr<Binding> getBinding() const { return binding; };
}; };
class Stmt : public Visitable class Stmt : public Visitable
......
...@@ -130,13 +130,13 @@ void Compiler::visitNullCast(NullCast *p) { ...@@ -130,13 +130,13 @@ void Compiler::visitNullCast(NullCast *p) {
void Compiler::visitNeg(Neg *p) { void Compiler::visitNeg(Neg *p) {
auto var = evalExpr(p->expr_); auto var = evalExpr(p->expr_);
lastVar = alloc(); lastVar = alloc();
quads.emplace_back(make_shared<QAssign>(lastVar, Op::Neg, var)); addQuad<QAssign>(lastVar, Op::Neg, var);
} }
void Compiler::visitNot(Not *p) { void Compiler::visitNot(Not *p) {
auto var = evalExpr(p->expr_); auto var = evalExpr(p->expr_);
lastVar = alloc(); lastVar = alloc();
quads.emplace_back(make_shared<QAssign>(lastVar, Op::Not, var)); addQuad<QAssign>(lastVar, Op::Not, var);
} }
// binary ops // binary ops
...@@ -146,7 +146,7 @@ void Compiler::visitEMul(EMul *p) { ...@@ -146,7 +146,7 @@ void Compiler::visitEMul(EMul *p) {
auto r = evalExpr(p->expr_2); auto r = evalExpr(p->expr_2);
lastVar = alloc(); lastVar = alloc();
p->mulop_->accept(this); p->mulop_->accept(this);
quads.emplace_back(make_shared<QAssign>(lastVar, l, op, r)); addQuad<QAssign>(lastVar, l, op, r);
} }
void Compiler::visitEAdd(EAdd *p) { void Compiler::visitEAdd(EAdd *p) {
...@@ -154,7 +154,7 @@ void Compiler::visitEAdd(EAdd *p) { ...@@ -154,7 +154,7 @@ void Compiler::visitEAdd(EAdd *p) {
auto r = evalExpr(p->expr_2); auto r = evalExpr(p->expr_2);
lastVar = alloc(); lastVar = alloc();
p->addop_->accept(this); p->addop_->accept(this);
quads.emplace_back(make_shared<QAssign>(lastVar, l, op, r)); addQuad<QAssign>(lastVar, l, op, r);
} }
...@@ -163,7 +163,7 @@ void Compiler::visitERel(ERel *p) { ...@@ -163,7 +163,7 @@ void Compiler::visitERel(ERel *p) {
auto r = evalExpr(p->expr_2); auto r = evalExpr(p->expr_2);
lastVar = alloc(); lastVar = alloc();
p->relop_->accept(this); p->relop_->accept(this);
quads.emplace_back(make_shared<QAssign>(lastVar, l, op, r)); addQuad<QAssign>(lastVar, l, op, r);
} }
// lazy bools // lazy bools
...@@ -173,15 +173,15 @@ void Compiler::visitEAnd(EAnd *p) { ...@@ -173,15 +173,15 @@ void Compiler::visitEAnd(EAnd *p) {
auto labelLeft = make_shared<QLabel>("use_left"); auto labelLeft = make_shared<QLabel>("use_left");
auto labelAfter = make_shared<QLabel>("end_and"); auto labelAfter = make_shared<QLabel>("end_and");
quads.emplace_back(make_shared<QJumpCond>(labelLeft, Op::Not, l)); addQuad<QJumpCond>(labelLeft, Op::Not, l);
auto r = evalExpr(p->expr_2); auto r = evalExpr(p->expr_2);
lastVar = alloc(); lastVar = alloc();
quads.emplace_back(make_shared<QAssign>(lastVar, Op::Copy, r)); addQuad<QAssign>(lastVar, Op::Copy, r);
quads.emplace_back(make_shared<QJump>(labelAfter)); addQuad<QJump>(labelAfter);
quads.emplace_back(labelLeft); addQuad(labelLeft);
quads.emplace_back(make_shared<QAssign>(lastVar, Op::Copy, l)); addQuad<QAssign>(lastVar, Op::Copy, l);
quads.emplace_back(labelAfter); addQuad(labelAfter);
} }
void Compiler::visitEOr(EOr *p) { void Compiler::visitEOr(EOr *p) {
...@@ -189,16 +189,16 @@ void Compiler::visitEOr(EOr *p) { ...@@ -189,16 +189,16 @@ void Compiler::visitEOr(EOr *p) {
auto labelLeft = make_shared<QLabel>("use_left"); auto labelLeft = make_shared<QLabel>("use_left");
auto labelAfter = make_shared<QLabel>("end_or"); auto labelAfter = make_shared<QLabel>("end_or");
quads.emplace_back(make_shared<QJumpCond>(labelLeft, Op::Copy, l)); addQuad<QJumpCond>(labelLeft, Op::Copy, l);
auto r = evalExpr(p->expr_2); auto r = evalExpr(p->expr_2);
lastVar = alloc(); lastVar = alloc();
quads.emplace_back(make_shared<QAssign>(lastVar, Op::Copy, r)); addQuad<QAssign>(lastVar, Op::Copy, r);
quads.emplace_back(make_shared<QJump>(labelAfter)); addQuad<QJump>(labelAfter);
quads.emplace_back(labelLeft); addQuad(labelLeft);
quads.emplace_back(make_shared<QAssign>(lastVar, Op::Copy, l)); addQuad<QAssign>(lastVar, Op::Copy, l);
quads.emplace_back(labelAfter); addQuad(labelAfter);
} }
// complex extensions // complex extensions
...@@ -218,14 +218,14 @@ void Compiler::visitEIndexAcc(EIndexAcc *p) { ...@@ -218,14 +218,14 @@ void Compiler::visitEIndexAcc(EIndexAcc *p) {
// calculate quantifier, we multiply index because size is larger than 4 // calculate quantifier, we multiply index because size is larger than 4
auto q = alloc(type->type_->size() / 4); auto q = alloc(type->type_->size() / 4);
// calculate var = index * quantifier // calculate var = index * quantifier
quads.emplace_back(make_shared<QAssign>(lastVar, index, Op::Mul, q)); addQuad<QAssign>(lastVar, index, Op::Mul, q);
// allocate new lastVar, index is now calculated multiplied index // allocate new lastVar, index is now calculated multiplied index
index = alloc(); index = alloc();
swap(index, lastVar); swap(index, lastVar);
} }
auto quad = make_shared<QAccess>(lastVar, lhs, index, 4, 0); auto quad = make_shared<QAccess>(lastVar, lhs, index, 4, 0);
quads.emplace_back(quad); addQuad(quad);
} }
void Compiler::visitEClsMmbr(EClsMmbr *p) { void Compiler::visitEClsMmbr(EClsMmbr *p) {
...@@ -234,18 +234,18 @@ void Compiler::visitEClsMmbr(EClsMmbr *p) { ...@@ -234,18 +234,18 @@ void Compiler::visitEClsMmbr(EClsMmbr *p) {
assert(var); assert(var);
// it cannot be function, as function might only be used in EApp and are handled directly there // it cannot be function, as function might only be used in EApp and are handled directly there
assert(!var->toFunction()); assert(!var->toFunction());
// Array length calculation works because of arrayLengthVar that has offset 0
size_t offset = var->offset; size_t offset = var->offset;
// TODO: Array length calculation
// if ()
if (dynamic_cast<EIndexAcc*>(p->expr_)) { if (dynamic_cast<EIndexAcc*>(p->expr_)) {
// opt if EIndexAcc is used inside visitEClsMmbr // opt if EIndexAcc is used inside visitEClsMmbr
auto access = dynamic_pointer_cast<QAccess>(quads.back()); auto access = dynamic_pointer_cast<QAccess>(quads.back());
access->offset += offset; access->access.offset += offset;
l->info = var;
lastVar = l; lastVar = l;
} else { } else {
lastVar = alloc(); lastVar = alloc(var);
auto quad = make_shared<QAccess>(lastVar, l, alloc(0), 0, offset); auto quad = make_shared<QAccess>(lastVar, l, alloc(0), 0, offset);
quads.emplace_back(quad); addQuad(quad);
} }
} }
...@@ -280,15 +280,15 @@ void Compiler::visitEApp(EApp *p) { ...@@ -280,15 +280,15 @@ void Compiler::visitEApp(EApp *p) {
int i = 1; int i = 1;
for (auto param : *p->listexpr_) { for (auto param : *p->listexpr_) {
auto var = evalExpr(param); auto var = evalExpr(param);
quads.emplace_back(make_shared<QParam>(var, i++)); addQuad<QParam>(var, i++);
} }
if (self) { if (self) {
quads.emplace_back(make_shared<QParam>(self, 0)); addQuad<QParam>(self, 0);
} }
lastVar = alloc(); lastVar = alloc();
quads.emplace_back(make_shared<QCall>(lastVar, info, i, self)); addQuad<QCall>(lastVar, info, i, self);
} }
void Compiler::visitENewArray(ENewArray *p) { void Compiler::visitENewArray(ENewArray *p) {
...@@ -303,7 +303,7 @@ void Compiler::visitENewArray(ENewArray *p) { ...@@ -303,7 +303,7 @@ void Compiler::visitENewArray(ENewArray *p) {
} }
auto count = evalExpr(p->expr_); auto count = evalExpr(p->expr_);
lastVar = alloc(); lastVar = alloc();
quads.emplace_back(make_shared<QAlloc>(lastVar, size, virtSymbol, count)); addQuad<QAlloc>(lastVar, size, virtSymbol, count);
} }
void Compiler::visitENewClass(ENewClass *p) { void Compiler::visitENewClass(ENewClass *p) {
...@@ -312,7 +312,7 @@ void Compiler::visitENewClass(ENewClass *p) { ...@@ -312,7 +312,7 @@ void Compiler::visitENewClass(ENewClass *p) {
size_t size = info->size; size_t size = info->size;
std::string virtSymbol = getVirtName(info); std::string virtSymbol = getVirtName(info);
lastVar = alloc(); lastVar = alloc();
quads.emplace_back(make_shared<QAlloc>(lastVar, size, virtSymbol)); addQuad<QAlloc>(lastVar, size, virtSymbol);
} }
/// statements /// statements
...@@ -321,35 +321,53 @@ void Compiler::visitInit(Init *p) { ...@@ -321,35 +321,53 @@ void Compiler::visitInit(Init *p) {
auto info = p->pident_->var.lock(); auto info = p->pident_->var.lock();
assert(info); assert(info);
auto var = evalExpr(p->expr_); auto var = evalExpr(p->expr_);
quads.emplace_back(make_shared<QAssign>(alloc(info), Op::Copy, var)); addQuad<QAssign>(alloc(info), Op::Copy, var);
}
void Compiler::assign(Expr* lval, VariablePtr val) {
auto dest = evalLVal(lval);
if (dest->info && dest->info->isInstanceVariable()) {
// instance variable, need to write it to memory
auto quad = dynamic_pointer_cast<QAccess>(quads.empty() ? nullptr : quads.back());
assert(quad);
auto loc = quad->access;
quads.pop_back();
addQuad<QWrite>(loc, val);
return;
} else {
// local variable - only assign
addQuad<QAssign>(dest, Op::Copy, val);
}
} }
void Compiler::visitAss(Ass *p) { void Compiler::visitAss(Ass *p) {
auto dest = evalExpr(p->expr_1); auto val = evalExpr(p->expr_2);
quads.emplace_back(make_shared<QAssign>(dest, Op::Copy, evalExpr(p->expr_2))); assign(p->expr_1, val);
} }
void Compiler::visitIncr(Incr *p) { void Compiler::visitIncr(Incr *p) {
auto dest = evalExpr(p->expr_);
auto lhs = evalExpr(p->expr_); auto lhs = evalExpr(p->expr_);
quads.emplace_back(make_shared<QAssign>(dest, lhs, Op::Plus, alloc(1))); auto tmp = alloc();
addQuad<QAssign>(tmp, lhs, Op::Plus, alloc(1));
assign(p->expr_, tmp);
} }
void Compiler::visitDecr(Decr *p) { void Compiler::visitDecr(Decr *p) {
auto dest = evalExpr(p->expr_);
auto lhs = evalExpr(p->expr_); auto lhs = evalExpr(p->expr_);
quads.emplace_back(make_shared<QAssign>(dest, lhs, Op::Minus, alloc(1))); auto tmp = alloc();
addQuad<QAssign>(tmp, lhs, Op::Minus, alloc(1));
assign(p->expr_, tmp);
} }
void Compiler::visitRet(Ret *p) { void Compiler::visitRet(Ret *p) {
auto var = evalExpr(p->expr_); auto var = evalExpr(p->expr_);
endBasicBlock(); endBasicBlock();
quads.emplace_back(make_shared<QReturn>(var)); addQuad<QReturn>(var);
} }
void Compiler::visitVRet(VRet *p) { void Compiler::visitVRet(VRet *p) {
endBasicBlock(); endBasicBlock();
quads.emplace_back(make_shared<QReturn>(nullptr)); addQuad<QReturn>(nullptr);
} }
void Compiler::visitCond(Cond *p) { void Compiler::visitCond(Cond *p) {
...@@ -357,11 +375,11 @@ void Compiler::visitCond(Cond *p) { ...@@ -357,11 +375,11 @@ void Compiler::visitCond(Cond *p) {
auto after = make_shared<QLabel>("end_if"); auto after = make_shared<QLabel>("end_if");
endBasicBlock(); // possible jump -> after endBasicBlock(); // possible jump -> after
quads.emplace_back(make_shared<QJumpCond>(after, Op::Not, var)); addQuad<QJumpCond>(after, Op::Not, var);
p->stmt_->accept(this); p->stmt_->accept(this);
endBasicBlock(); // possible jump <- cond endBasicBlock(); // possible jump <- cond
quads.emplace_back(after); addQuad(after);
} }
void Compiler::visitCondElse(CondElse *p) { void Compiler::visitCondElse(CondElse *p) {
...@@ -371,36 +389,36 @@ void Compiler::visitCondElse(CondElse *p) { ...@@ -371,36 +389,36 @@ void Compiler::visitCondElse(CondElse *p) {
auto var = evalExpr(p->expr_); auto var = evalExpr(p->expr_);
endBasicBlock(); // possible jump -> else endBasicBlock(); // possible jump -> else
quads.emplace_back(make_shared<QJumpCond>(elseBranch, Op::Not, var)); addQuad<QJumpCond>(elseBranch, Op::Not, var);
p->stmt_1->accept(this); p->stmt_1->accept(this);
endBasicBlock(); // jump -> after endBasicBlock(); // jump -> after
quads.emplace_back(make_shared<QJump>(after)); addQuad<QJump>(after);
quads.emplace_back(elseBranch); addQuad(elseBranch);
p->stmt_2->accept(this); p->stmt_2->accept(this);
endBasicBlock(); // jump <- cond endBasicBlock(); // jump <- cond
quads.emplace_back(after); addQuad(after);
} }
void Compiler::visitWhile(While *p) { void Compiler::visitWhile(While *p) {
auto cond = make_shared<QLabel>("cond"); auto cond = make_shared<QLabel>("cond");
endBasicBlock(); // jump <- loop -> cond endBasicBlock(); // jump <- loop -> cond
quads.emplace_back(make_shared<QJump>(cond)); addQuad<QJump>(cond);
// jump <- loop // jump <- loop
auto loop = make_shared<QLabel>("loop"); auto loop = make_shared<QLabel>("loop");
quads.emplace_back(loop); addQuad(loop);
p->stmt_->accept(this); p->stmt_->accept(this);
endBasicBlock(); // jump <- cond endBasicBlock(); // jump <- cond
quads.emplace_back(cond); addQuad(cond);
auto var = evalExpr(p->expr_); auto var = evalExpr(p->expr_);
endBasicBlock(); // jump -> loop endBasicBlock(); // jump -> loop
quads.emplace_back(make_shared<QJumpCond>(loop, Op::Copy, var)); addQuad<QJumpCond>(loop, Op::Copy, var);
} }
void Compiler::visitSExp(SExp *p) { void Compiler::visitSExp(SExp *p) {
......
...@@ -31,11 +31,22 @@ private: ...@@ -31,11 +31,22 @@ private:
Quadruple::Op op; Quadruple::Op op;
VariablePtr lastVar; VariablePtr lastVar;
int lineno;
void compileFunction(FunctionInfoPtr f); 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);
}
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");
lineno = expr->lineno;
lastVar = nullptr; lastVar = nullptr;
try { try {
expr->accept(this); expr->accept(this);
...@@ -60,7 +71,7 @@ private: ...@@ -60,7 +71,7 @@ private:
}; };
VariablePtr alloc(VarInfoPtr info) { VariablePtr alloc(VarInfoPtr info) {
if (info->loc) { if (info->loc && !info->isInstanceVariable()) {
return info->loc; return info->loc;
} }
auto v = make_shared<Variable>(info); auto v = make_shared<Variable>(info);
...@@ -74,8 +85,23 @@ private: ...@@ -74,8 +85,23 @@ private:
return v; return v;
} }
template<typename T, typename... Args> QuadruplePtr addQuad(Args... args) {
auto quad = make_shared<T>(args...);
quad->lineno = lineno;
quads.emplace_back(quad);
return quad;
}
QuadruplePtr addQuad(QuadruplePtr quad) {
quad->lineno = lineno;
quads.emplace_back(quad);
return quad;
}
void endBasicBlock(); void endBasicBlock();
void assign(Expr* lval, VariablePtr val);
void visitEVar(EVar *p) override; void visitEVar(EVar *p) override;
void visitEIndexAcc(EIndexAcc *p) override; void visitEIndexAcc(EIndexAcc *p) override;
void visitEClsMmbr(EClsMmbr *p) override; void visitEClsMmbr(EClsMmbr *p) override;
......
...@@ -26,7 +26,8 @@ public: ...@@ -26,7 +26,8 @@ public:
string name; string name;
TypePtr type; TypePtr type;
int lineLocation; int lineLocation;
size_t offset; size_t offset = 0;
bool isInstanceVariable() const { return offset; };
VariablePtr loc; VariablePtr loc;
......
...@@ -117,7 +117,7 @@ void TypeCheck::visitClassFld(ClassFld *decl) ...@@ -117,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->getBinding();
if (!binding) { if (!binding) {
binding = make_shared<Binding>(scope->currentBinding); binding = make_shared<Binding>(scope->currentBinding);
blk->binding = binding; blk->binding = binding;
...@@ -310,8 +310,9 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr) ...@@ -310,8 +310,9 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
if (!type) { if (!type) {
// it is an array and we ask for length // it is an array and we ask for length
if (dynamic_pointer_cast<Array>(exprType)) { if (dynamic_pointer_cast<Array>(exprType)) {
if (e_cls_mmbr->pident_->string_ == "length") { if (e_cls_mmbr->pident_->string_ == arrayLengthVar->name) {
lastType = make_shared<Int>(); e_cls_mmbr->pident_->var = arrayLengthVar;
lastType = arrayLengthVar->type;
return; return;
} }
} }
...@@ -558,6 +559,8 @@ void TypeCheck::setupEnv() { ...@@ -558,6 +559,8 @@ void TypeCheck::setupEnv() {
scope->functions << error; scope->functions << error;
} }
arrayLengthVar = make_shared<VarInfo>("length", make_shared<Int>());
} }
void TypeCheck::check(Visitable *v) void TypeCheck::check(Visitable *v)
......
...@@ -22,6 +22,8 @@ class TypeCheck : public Visitor ...@@ -22,6 +22,8 @@ class TypeCheck : public Visitor
vector<pair<ClassInfoPtr, ClassDef*>> classDefs; vector<pair<ClassInfoPtr, ClassDef*>> classDefs;
VarInfoPtr arrayLengthVar;
void checkFunction(FunctionInfoPtr f); void checkFunction(FunctionInfoPtr f);
void checkReturnStatement(shared_ptr<Type> type, Stmt *stmt); void checkReturnStatement(shared_ptr<Type> type, Stmt *stmt);
void checkFunctionRet(); void checkFunctionRet();
......
...@@ -38,8 +38,10 @@ public: ...@@ -38,8 +38,10 @@ public:
} }
}; };
int lineno;
virtual ~Quadruple() {}; virtual ~Quadruple() {};
virtual std::string toString() const = 0; virtual std::string toString() const { return to_string(lineno) + "\t"; };
}; };
class QWriteVar : public Quadruple { class QWriteVar : public Quadruple {
...@@ -47,13 +49,13 @@ public: ...@@ -47,13 +49,13 @@ public:
VariablePtr loc; VariablePtr loc;
explicit QWriteVar(VariablePtr loc) : Quadruple(), loc(std::move(loc)) {}; explicit QWriteVar(VariablePtr loc) : Quadruple(), loc(std::move(loc)) {};
std::string toString() const override { return loc ? ("\t" + loc->name + " := ") : "\t"; } std::string toString() const override { return Quadruple::toString() + "\t" + (loc ? (loc->name + " := ") : ""); }
}; };
class QLabel : public Quadruple { class QLabel : public Quadruple {
public: public:
string label; string label;
std::string toString() const override { return "\"" + label + "\":"; } std::string toString() const override { return Quadruple::toString() + "\"" + label + "\":"; }
QLabel(std::string comment) : label(comment) {} QLabel(std::string comment) : label(comment) {}
}; };
...@@ -80,7 +82,7 @@ public: ...@@ -80,7 +82,7 @@ public:
explicit QJump(shared_ptr<QLabel> target) : target(std::move(target)) {}; explicit QJump(shared_ptr<QLabel> target) : target(std::move(target)) {};
std::string toString() const override { std::string toString() const override {
return "\tjump " + target->label; return Quadruple::toString() + "jump " + target->label;
} }
}; };
...@@ -97,9 +99,9 @@ public: ...@@ -97,9 +99,9 @@ public:
std::string toString() const override { std::string toString() const override {
if (!left) if (!left)
return "\tjump \"" + target->label + "\" if " + Op::name(op) + " " + right->name; return Quadruple::toString() + "jump \"" + target->label + "\" if " + Op::name(op) + " " + right->name;
else else
return "\tjump \"" + target->label + "\" if " + left->name + " " + Op::name(op) + " " + right->name; return Quadruple::toString() + "jump \"" + target->label + "\" if " + left->name + " " + Op::name(op) + " " + right->name;
} }
}; };
...@@ -112,9 +114,9 @@ public: ...@@ -112,9 +114,9 @@ public:
std::string toString() const override { std::string toString() const override {
if (num == 0) { if (num == 0) {
return "\tparam self " + param->name; return Quadruple::toString() + "\tparam self " + param->name;
} else { } else {
return "\tparam #" + to_string(num) + " <- " + param->name; return Quadruple::toString() + "\tparam #" + to_string(num) + " <- " + param->name;
} }
} }
}; };
...@@ -143,9 +145,9 @@ public: ...@@ -143,9 +145,9 @@ public:
std::string toString() const override { std::string toString() const override {
if (ret) { if (ret) {
return "\treturn " + ret->name; return Quadruple::toString() + "\treturn " + ret->name;
} else { } else {
return "\treturn"; return Quadruple::toString() + "\treturn";
} }
} }
}; };
...@@ -153,23 +155,31 @@ public: ...@@ -153,23 +155,31 @@ public:
class QAccess : public QWriteVar { class QAccess : public QWriteVar {
public: public:
QAccess(VariablePtr loc, VariablePtr base, VariablePtr index, int multiplier, int offset) 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) : QWriteVar(std::move(loc)), access(std::move(base), std::move(index), multiplier, offset)
{}; {};
// leal 8(,%eax,4), %eax # Arithmetic: multiply eax by 4 and add 8 // 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 // leal (%edx,%eax,2), %eax # Arithmetic: multiply eax by 2 and add edx
VariablePtr base; VariableLocation access;
VariablePtr index; bool lea = false;
int multiplier;
int offset;
std::string toString() const override { std::string toString() const override {
auto ret = QWriteVar::toString() + "[" + base->name; auto ret = QWriteVar::toString();
if (multiplier || !(index->constExpr || !index->val)) ret += " + " + to_string(multiplier) + "*" + index->name; if (lea) ret += "&";
if (offset) ret += " + " + to_string(offset); return ret + access.toString();
return ret + "]";
} }
}; };
class QWrite : public Quadruple {
public:
QWrite(VariableLocation loc, VariablePtr val)
: Quadruple(), loc(std::move(loc)), val(std::move(val))
{};
VariableLocation loc;
VariablePtr val;
std::string toString() const override { return Quadruple::toString() + "\t" + loc.toString() + " := " + val->name; }
};
class QAlloc : public QWriteVar { class QAlloc : public QWriteVar {
public: public:
size_t size; size_t size;
......
...@@ -27,4 +27,23 @@ public: ...@@ -27,4 +27,23 @@ public:
// where in mem - id or offset // where in mem - id or offset
}; };
class VariableLocation {
public:
VariableLocation() = default;
VariableLocation(VariablePtr base, VariablePtr index, int multiplier, int offset)
: base(std::move(base)), index(std::move(index)), multiplier(multiplier), offset(offset)
{}
VariablePtr base;
VariablePtr index;
int multiplier;
int offset;
string toString() const {
std::string ret = "[" + base->name;
if (multiplier || !(index->constExpr || !index->val)) ret += " + " + to_string(multiplier) + "*" + index->name;
if (offset) ret += " + " + to_string(offset);
return ret + "]";
}
};
#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