Exemplo n.º 1
0
        FunctionName ParseFunctionName()
        {
            if (NextToken().m_type != (int)TokenType.NAME)
            {
                throw NewParserException("expect 'id' after 'function'", _current);
            }

            var func_name = new FunctionName(_current.m_line);

            func_name.names.Add(_current);
            while (LookAhead().m_type == (int)'.')
            {
                NextToken();
                if (NextToken().m_type != (int)TokenType.NAME)
                {
                    throw NewParserException("unexpect token in function name after '.'", _current);
                }
                func_name.names.Add(_current);
            }

            return(func_name);
        }
Exemplo n.º 2
0
        void HandleFunctionName(FunctionName tree)
        {
            int         func_register = GenerateRegisterId();
            var         f             = GetCurrentFunction();
            Instruction code          = new Instruction();

            var          first_name = tree.names[0];
            LexicalScope scope;
            int          index = SearchNameAndScope(first_name.m_string, out scope);

            if (tree.names.Count == 1)
            {
                if (scope == LexicalScope.Global)
                {
                    code = Instruction.ABx(OpType.OpType_SetGlobal, func_register, index);
                }
                else if (scope == LexicalScope.Upvalue)
                {
                    code = Instruction.ABx(OpType.OpType_SetUpvalue, func_register, index);
                }
                else if (scope == LexicalScope.Local)
                {
                    code = Instruction.AB(OpType.OpType_Move, index, func_register);
                }
                f.AddInstruction(code, first_name.m_line);
            }
            else
            {
                var table_register = GenerateRegisterId();
                int key_register   = GenerateRegisterId();

                if (scope == LexicalScope.Global)
                {
                    code = Instruction.ABx(OpType.OpType_GetGlobal, table_register, index);
                }
                else if (scope == LexicalScope.Upvalue)
                {
                    code = Instruction.AB(OpType.OpType_GetUpvalue, table_register, index);
                }
                else if (scope == LexicalScope.Local)
                {
                    code = Instruction.AB(OpType.OpType_Move, table_register, index);
                }
                f.AddInstruction(code, tree.line);

                Action <Token> load_key = (Token name) => {
                    int l_index = f.AddConstString(name.m_string);
                    CheckConstIdx(l_index);
                    var l_code = Instruction.ABx(OpType.OpType_LoadConst, key_register, l_index);
                    f.AddInstruction(l_code, name.m_line);
                };

                for (int i = 1; i < tree.names.Count - 1; ++i)
                {
                    load_key(tree.names[i]);
                    code = Instruction.ABC(OpType.OpType_GetTable,
                                           table_register, key_register, table_register);
                    f.AddInstruction(code, tree.line);
                }
                load_key(tree.names.Last <Token>());
                code = Instruction.ABC(OpType.OpType_SetTable,
                                       table_register, key_register, func_register);
                f.AddInstruction(code, tree.line);
            }
            // 回收寄存器
            ResetRegisterId(func_register);
        }