Example #1
0
        void HandleForEachStatement(ForEachStatement tree)
        {
            EnterBlock();

            var         f = GetCurrentFunction();
            Instruction code;

            // get table iter
            HandleExpRead(tree.exp);
            var table_register = GenerateRegisterId();
            var iter_register  = table_register;

            code = Instruction.AB(OpType.OpType_TableIter, iter_register, table_register);
            f.AddInstruction(code, tree.k.m_line);

            EnterLoop();
            {
                EnterBlock();

                var k_register = GenerateRegisterId();
                if (tree.k != null)
                {
                    InsertName(tree.k.m_string, k_register);
                }
                var v_register = GenerateRegisterId();
                InsertName(tree.v.m_string, v_register);

                code = Instruction.ABC(OpType.OpType_TableIterNext, iter_register, k_register, v_register);
                f.AddInstruction(code, tree.k.m_line);

                // jump to loop tail when the first name value is nil
                code = Instruction.ABx(OpType.OpType_JmpNil, k_register, 0);
                int index = f.AddInstruction(code, tree.k.m_line);
                AddLoopJumpInfo(JumpType.JumpTail, index);

                HandleBlock(tree.block);

                LeaveBlock();
                // jump to loop head
                code  = Instruction.Bx(OpType.OpType_Jmp, 0);
                index = f.AddInstruction(code, -1);
                AddLoopJumpInfo(JumpType.JumpHead, index);
            }

            LeaveLoop();

            LeaveBlock();
        }
Example #2
0
        ForEachStatement ParseForEachStatement()
        {
            NextToken();// skip 'foreach'

            var statement = new ForEachStatement(_current.m_line);

            if (NextToken().m_type != (int)TokenType.NAME)
            {
                throw NewParserException("expect 'id' in foreach-statement", _current);
            }
            if (LookAhead().m_type == (int)',')
            {
                statement.k = _current;
                NextToken();
                if (NextToken().m_type != (int)TokenType.NAME)
                {
                    throw NewParserException("expect 'id' in foreach-statement after ','", _current);
                }
                statement.v = _current;
            }
            else
            {
                statement.v = _current;
            }

            if (NextToken().m_type != (int)TokenType.IN)
            {
                throw NewParserException("expect 'in' in foreach-statement", _current);
            }
            statement.exp = ParseExp();

            if (NextToken().m_type != (int)TokenType.DO)
            {
                throw NewParserException("expect 'do' to start foreach-body", _current);
            }
            statement.block = ParseBlock();
            if (NextToken().m_type != (int)TokenType.END)
            {
                throw NewParserException("expect 'end' to complete foreach-body", _current);
            }

            return(statement);
        }