예제 #1
0
        void HandleTableDefine(TableDefine tree)
        {
            var         f = GetCurrentFunction();
            Instruction code;
            // new table
            int table_register = GenerateRegisterId();

            code = Instruction.A(OpType.OpType_NewTable, table_register);
            f.AddInstruction(code, tree.line);

            // add field
            int count          = tree.last_field_append_table ? tree.fields.Count - 1 : tree.fields.Count;
            int arr_index      = 1;//number index start from 1
            int key_register   = table_register + 1;
            int value_register = table_register + 2;

            for (int i = 0; i < count; ++i)
            {
                var field = tree.fields[i];
                if (field.index == null)
                {
                    code = Instruction.ABx(OpType.OpType_LoadInt, key_register, arr_index++);
                    f.AddInstruction(code, field.line);
                }
                else
                {
                    HandleExpRead(field.index);
                }
                GenerateRegisterId();// for key register
                HandleExpRead(field.value);

                code = Instruction.ABC(OpType.OpType_SetTable, table_register, key_register, value_register);
                f.AddInstruction(code, field.line);
                ResetRegisterId(key_register);
            }
            // last field
            if (tree.last_field_append_table)
            {
                var last_field = tree.fields[count];
                HandleExpRead(last_field.value);
                code = Instruction.AB(OpType.OpType_AppendTable, table_register, key_register);
                f.AddInstruction(code, last_field.line);
            }

            ResetRegisterId(table_register);
        }
예제 #2
0
        TableDefine ParseTableConstructor()
        {
            NextToken();
            var        table      = new TableDefine(_current.m_line);
            TableField last_field = null;

            while (LookAhead().m_type != '}')
            {
                if (LookAhead().m_type == (int)'[')
                {
                    last_field = ParseTableIndexField();
                }
                else if (LookAhead().m_type == (int)TokenType.NAME &&
                         LookAhead2().m_type == (int)'=')
                {
                    last_field = ParseTableNameField();
                }
                else
                {
                    last_field = ParseTableArrayField();
                }

                table.fields.Add(last_field);

                if (LookAhead().m_type != '}')
                {
                    NextToken();
                    if (_current.m_type != (int)',' &&
                        _current.m_type != (int)';')
                    {
                        throw NewParserException("expect ',' or ';' to split table fields", _current);
                    }
                }
            }
            if (NextToken().m_type != '}')
            {
                throw NewParserException("expect '}' for table", _current);
            }

            if (last_field != null && last_field.index == null)
            {
                table.last_field_append_table = IsExpReturnAnyCountValue(last_field.value);
            }

            return(table);
        }