Example #1
0
    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);
    }
Example #2
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);
    }
Example #3
0
    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);
    }
Example #4
0
    void CodeGenerateVisitor::Visit(Terminator *term, void *data)
    {
        const TokenDetail &t = term->token_;
        int value_count = func_state_->PopExpValueCount();

        if (t.token_ == Token_Number ||
            t.token_ == Token_String)
        {
            int index = 0;
            if (t.token_ == Token_Number)
                index = func_->AddConstNumber(t.number_);
            else
                index = func_->AddConstString(t.str_);

            if (value_count != 0)
            {
                int reg = func_->AllocaNextRegister();
                func_->AddInstruction(Instruction::ABCode(OpType_LoadConst,
                                                          reg, index), t.line_);
            }
        }
        else if (t.token_ == Token_Id)
        {
            auto s = scope_name_list_.current_scope_->GetBlongsToScope(t.str_);

            // Token_Id not in scope, then this id is in env table
            if (!s.first)
            {
                int index = func_->AddConstString(t.str_);
                if (value_count != 0)
                {
                    int reg = func_->AllocaNextRegister();
                    // Load key
                    func_->AddInstruction(Instruction::ABCode(OpType_LoadConst,
                                                              reg, index), t.line_);
                    // Get value from uptable
                    func_->AddInstruction(Instruction::ABCCode(OpType_GetUpTable,
                                                               reg, ENV_TABLE_INDEX, reg), t.line_);
                }
            }
            else
            {
                if (s.second == scope_name_list_.current_scope_->GetOwnerFunction())
                {
                    int src_reg = s.first->GetNameRegister(t.str_);
                    assert(src_reg >= 0);
                    if (value_count != 0)
                    {
                        int dst_reg = func_->AllocaNextRegister();
                        func_->AddInstruction(Instruction::ABCode(OpType_Move, dst_reg, src_reg), t.line_);
                    }
                }
                else
                {
                    assert(!"TODO: generate code for upvalue.");
                }
            }
        }
        else
            assert(!"maybe miss some term type.");
    }