void CodeGenerateVisitor::Visit(LocalNameListStatement *local_name, void *data) { // Visit local names local_name->name_list_->Accept(this, data); int reg = func_->GetNextRegister(); int names = func_state_->names_register_.size(); // Visit exp list if (local_name->exp_list_) { func_state_->PushExpListValueCount(names); local_name->exp_list_->Accept(this, data); } // Set local name init value int exp_reg = reg; for (int i = 0; i < names; ++i, ++exp_reg) { int name_reg = func_state_->names_register_[i].register_; func_->AddInstruction(Instruction::ABCode(OpType_Move, name_reg, exp_reg), func_state_->names_register_[i].token_->line_); } func_state_->names_register_.clear(); // Restore register func_->SetNextRegister(reg); func_->AddInstruction(Instruction::ACode(OpType_SetTop, reg), 0); }
void CodeGenerateVisitor::Visit(NormalFuncCall *func_call, void *data) { int reg = func_->GetNextRegister(); int result_count = func_state_->PopExpValueCount(); // Load function func_state_->PushExpValueCount(1); func_call->caller_->Accept(this, data); // Prepare args func_call->args_->Accept(this, data); func_->AddInstruction(Instruction::AsBxCode(OpType_Call, reg, result_count), 0); }
void CodeGenerateVisitor::Visit(NameList *name_list, void *data) { // Add all names to local scope for (auto &n : name_list->names_) { assert(n.token_ == Token_Id); int reg = func_->GetNextRegister(); if (scope_name_list_.current_scope_->AddScopeName(n.str_, ®)) func_->AllocaNextRegister(); // Add name register, used by other Visit function to generate code func_state_->names_register_.push_back(NameReg(reg, n)); } }
void CodeGenerateVisitor::Visit(Block *block, void *data) { NameScope current(scope_name_list_, func_); int reg = func_->GetNextRegister(); // Visit all statements for (auto &s : block->statements_) s->Accept(this, data); // Visit return statement if exist if (block->return_stmt_) block->return_stmt_->Accept(this, data); // Restore register func_->SetNextRegister(reg); func_->AddInstruction(Instruction::ACode(OpType_SetTop, reg), 0); }