132 lines
6.3 KiB
C++
132 lines
6.3 KiB
C++
#include "Public/Public.h"
|
|
#include "TCG/BlockTranslator.h"
|
|
#include "TCG/ConstructASM.h"
|
|
#include "TCG/SentenceTranslator/BaseTranslator.h"
|
|
#include "TCG/SentenceTranslator/CommonTranslator.h"
|
|
#include "TCG/SentenceTranslator/AssignTranslator.h"
|
|
#include "TCG/SentenceTranslator/CallTranslator.h"
|
|
#include "TCG/SentenceTranslator/FunparaTranslator.h"
|
|
#include "TCG/SentenceTranslator/FunretTranslator.h"
|
|
#include "TCG/SentenceTranslator/ParaTranslator.h"
|
|
#include "TCG/SentenceTranslator/RetTranslator.h"
|
|
#include "TCG/SentenceTranslator/GotoTranslator.h"
|
|
#include "TCG/SentenceTranslator/LabelTranslator.h"
|
|
#include "TCG/SentenceTranslator/IfTranslator.h"
|
|
#include "TCG/SentenceTranslator/CreatelistTranslator.h"
|
|
#include "TCG/SentenceTranslator/MulTranslator.h"
|
|
|
|
|
|
ASMBlock BlockTranslator::BlockTranslate(SymbolManager& SymbolManager_, std::shared_ptr<TACBlock> TACBlock_) {
|
|
ASMBlock ASMBlock_;
|
|
SymbolManager_.push_reg(REG::EBP, 0);
|
|
ASMBlock_.asmlines.push_back(construct_asm("push", REG::EBP));
|
|
ASMBlock_.asmlines.push_back(construct_asm("mov", REG::EBP, REG::ESP));
|
|
|
|
if (SymbolManager_.get_name() == "main") {
|
|
ASMBlock_.name = "_start";
|
|
} else {
|
|
ASMBlock_.name = SymbolManager_.get_name();
|
|
|
|
SymbolManager_.push_reg(REG::EAX, 0);
|
|
SymbolManager_.push_reg(REG::EBX, 0);
|
|
SymbolManager_.push_reg(REG::ECX, 0);
|
|
SymbolManager_.push_reg(REG::EDX, 0);
|
|
SymbolManager_.push_reg(REG::ESI, 0);
|
|
ASMBlock_.asmlines.push_back(construct_asm("push", REG::EAX));
|
|
ASMBlock_.asmlines.push_back(construct_asm("push", REG::EBX));
|
|
ASMBlock_.asmlines.push_back(construct_asm("push", REG::ECX));
|
|
ASMBlock_.asmlines.push_back(construct_asm("push", REG::EDX));
|
|
ASMBlock_.asmlines.push_back(construct_asm("push", REG::ESI));
|
|
}
|
|
|
|
SymbolManager_.cal_use_info(TACBlock_);
|
|
SymbolManager_.set_zero_len();
|
|
// todo 完成对每个语句的翻译
|
|
for (int i = 0; i < TACBlock_->size(); i++) {
|
|
LOG(INFO) << std::left
|
|
<< std::setw(20) << std::setfill(' ') << (*TACBlock_)[i].to_string()
|
|
<< (*TACBlock_)[i].src1.use_info << "\t"
|
|
<< (*TACBlock_)[i].src2.use_info << "\t"
|
|
<< (*TACBlock_)[i].dst.use_info << "\t"
|
|
<< "scope " << (*TACBlock_)[i].scope;
|
|
// 更新 SymbolManager 的 scope 和 待用信息
|
|
SymbolManager_.set_scope((*TACBlock_)[i].scope);
|
|
if ((*TACBlock_)[i].src1.OperType == TACOPERANDTYPE::VAR) {
|
|
SymbolManager_.set_use_info((*TACBlock_)[i].src1.value, (*TACBlock_)[i].src1.use_info);
|
|
}
|
|
if ((*TACBlock_)[i].src2.OperType == TACOPERANDTYPE::VAR) {
|
|
SymbolManager_.set_use_info((*TACBlock_)[i].src2.value, (*TACBlock_)[i].src2.use_info);
|
|
}
|
|
if ((*TACBlock_)[i].dst.OperType == TACOPERANDTYPE::VAR) {
|
|
SymbolManager_.set_use_info((*TACBlock_)[i].dst.value, (*TACBlock_)[i].dst.use_info);
|
|
}
|
|
|
|
// 翻译
|
|
std::shared_ptr<BaseTranslator> trans;
|
|
switch ((*TACBlock_)[i].op) {
|
|
case TACOP::ASSIGN: trans = std::make_shared<AssignTranslator>(); break;
|
|
case TACOP::CALL: trans = std::make_shared<CallTranslator>(); break;
|
|
case TACOP::FUN_PARA: trans = std::make_shared<FunparaTranslator>(); break;
|
|
case TACOP::FUN_RET: trans = std::make_shared<FunretTranslator>(); break;
|
|
case TACOP::PARA: trans = std::make_shared<ParaTranslator>(); break;
|
|
case TACOP::RET: trans = std::make_shared<RetTranslator>(); break;
|
|
case TACOP::GOTO: trans = std::make_shared<GotoTranslator>(); break;
|
|
case TACOP::LABEL: trans = std::make_shared<LabelTranslator>(); break;
|
|
case TACOP::CREATLIST: trans = std::make_shared<CreatelistTranslator>(); break;
|
|
case TACOP::IFEQ: trans = std::make_shared<IfTranslator>(); break;
|
|
case TACOP::IFGE: trans = std::make_shared<IfTranslator>(); break;
|
|
case TACOP::IFGT: trans = std::make_shared<IfTranslator>(); break;
|
|
case TACOP::IFLE: trans = std::make_shared<IfTranslator>(); break;
|
|
case TACOP::IFLT: trans = std::make_shared<IfTranslator>(); break;
|
|
case TACOP::IFNEQ: trans = std::make_shared<IfTranslator>(); break;
|
|
case TACOP::MUL:
|
|
case TACOP::DIV: trans = std::make_shared<MulTranslator>(); break;
|
|
default: trans = std::make_shared<CommonTranslator>(); break;
|
|
}
|
|
ASMLines tmp_res = trans->SentenceTranslate(SymbolManager_, (*TACBlock_)[i]);
|
|
ASMBlock_.asmlines.insert(ASMBlock_.asmlines.end(), tmp_res.begin(), tmp_res.end());
|
|
|
|
// 查看寄存器和内存中存的变量
|
|
// SymbolManager_.show_reg();
|
|
// SymbolManager_.show_mem();
|
|
}
|
|
|
|
|
|
|
|
int stack_len = SymbolManager_.get_stack_len();
|
|
if (stack_len > 0) {
|
|
SymbolManager_.set_esp_bias(-4 * stack_len);
|
|
ASMBlock_.asmlines.push_back(construct_asm("add", REG::ESP, std::to_string(4 * stack_len)));
|
|
} else if(stack_len < 0) {
|
|
LOG(FATAL) << stack_len << "stack overflow";
|
|
throw "ERROR";
|
|
}
|
|
|
|
if (SymbolManager_.get_name() == "main") {
|
|
SymbolManager_.pop_reg(REG::EBP);
|
|
ASMBlock_.asmlines.push_back(construct_asm("pop", REG::EBP));
|
|
// mov eax,1
|
|
// mov ebx,0
|
|
// int 80h
|
|
ASMBlock_.asmlines.push_back(construct_asm("mov", REG::EAX, std::to_string(1)));
|
|
ASMBlock_.asmlines.push_back(construct_asm("mov", REG::EBX, std::to_string(0)));
|
|
ASMBlock_.asmlines.push_back(construct_asm("int", "80h"));
|
|
} else {
|
|
SymbolManager_.pop_reg(REG::ESI);
|
|
SymbolManager_.pop_reg(REG::EDX);
|
|
SymbolManager_.pop_reg(REG::ECX);
|
|
SymbolManager_.pop_reg(REG::EBX);
|
|
SymbolManager_.pop_reg(REG::EAX);
|
|
ASMBlock_.asmlines.push_back(construct_asm("pop", REG::ESI));
|
|
ASMBlock_.asmlines.push_back(construct_asm("pop", REG::EDX));
|
|
ASMBlock_.asmlines.push_back(construct_asm("pop", REG::ECX));
|
|
ASMBlock_.asmlines.push_back(construct_asm("pop", REG::EBX));
|
|
ASMBlock_.asmlines.push_back(construct_asm("pop", REG::EAX));
|
|
SymbolManager_.pop_reg(REG::EBP);
|
|
ASMBlock_.asmlines.push_back(construct_asm("pop", REG::EBP));
|
|
ASMBlock_.asmlines.push_back(construct_asm("ret"));
|
|
}
|
|
|
|
return ASMBlock_;
|
|
}
|