Exemplo n.º 1
0
        void WhileStatement()
        {
            var surroundingLoopState = InnermostLoop;

            InnermostLoop = LoopState.FromCurrentState(this);

            Expression();
            Consume(TokenType.Colon, "Expect ':' after condition");

            var exitJump = EmitJump(OpCode.JumpIfFalse);

            Emit(OpCode.Pop);
            Statement();

            EmitLoop(InnermostLoop.Start);

            PatchJump(exitJump);
            Emit(OpCode.Pop);

            InnermostLoop.PatchUnresolvedBreaks(this);
            InnermostLoop = surroundingLoopState;
        }
Exemplo n.º 2
0
        void ForStatement()
        {
            BeginScope();

            // Initializer
            if (Match(TokenType.Var))
            {
                VarDeclaration();
            }
            else if (Match(TokenType.Semicolon))
            {
                // No initializer
            }
            else
            {
                ExpressionStatement();
            }

            var surroundingLoopState = InnermostLoop;

            InnermostLoop = LoopState.FromCurrentState(this);

            // Condition
            var exitJump = -1;

            if (!Match(TokenType.Semicolon))
            {
                Expression();
                Consume(TokenType.Semicolon, "Expect ';' after loop condition");
                // Jump out if condition is negative
                exitJump = EmitJump(OpCode.JumpIfFalse);
                Emit(OpCode.Pop); // Condition
            }

            // Increment
            if (!Match(TokenType.Colon))
            {
                var bodyJump = EmitJump(OpCode.Jump);

                var incrementStart = CurrentCodePosition();
                Expression();
                Emit(OpCode.Pop);
                Consume(TokenType.Colon, "Expect ':' after for clauses");

                EmitLoop(InnermostLoop.Start);
                InnermostLoop.Start = incrementStart;
                PatchJump(bodyJump);
            }

            Statement();

            EmitLoop(InnermostLoop.Start);

            if (exitJump != -1)
            {
                PatchJump(exitJump);
                Emit(OpCode.Pop); // Condition, if Pop has been jumped over above
            }

            InnermostLoop.PatchUnresolvedBreaks(this);
            InnermostLoop = surroundingLoopState;

            EndScope();
        }