Example #1
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_, &reg))
                func_->AllocaNextRegister();

            // Add name register, used by other Visit function to generate code
            func_state_->names_register_.push_back(NameReg(reg, n));
        }
    }
Example #2
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.");
    }