コード例 #1
0
        public override void Emit(InstructionWriter writer)
        {
            Debug.Assert(_firstLoopVarStack.Offset == _hiddenVariableStack.Offset + 3);

            _forBlock.EmitUpvalLists(writer);

            var exitLabel = new LabelStatementSyntaxNode();
            var loopLabel = new LabelStatementSyntaxNode();

            //Insert assignment and FORG instruction (call iterator function and check for exit condition).
            _assignment.Emit(writer);

            writer.MarkLabel(loopLabel);
            if (_hiddenVariableStack.Offset > 255 || _loopVarSig > 255)
            {
                throw new NotImplementedException();
            }
            writer.WriteUUS(Opcodes.FORG, _hiddenVariableStack.Offset, _loopVarSig, 0);
            writer.AddLabelFix(exitLabel, InstructionWriter.FixUUSJump);

            //Emit inner block.
            _forBlock.EmitStatements(writer);

            //Jump back.
            writer.WriteUSx(Opcodes.JMP, 0, 0);
            writer.AddLabelFix(loopLabel, InstructionWriter.FixUSxJump);

            writer.MarkLabel(exitLabel);
        }
コード例 #2
0
        public override void Emit(InstructionWriter writer)
        {
            Debug.Assert(_firstLoopVarStack.Offset == _hiddenVariableStack.Offset + 3);

            _forBlock.EmitUpvalLists(writer);

            var exitLabel = new LabelStatementSyntaxNode();
            var loopLabel = new LabelStatementSyntaxNode();

            //Insert assignment and FORG instruction (call iterator function and check for exit condition).
            _assignment.Emit(writer);

            writer.MarkLabel(loopLabel);
            if (_hiddenVariableStack.Offset > 255 || _loopVarSig > 255 || _loopVarSigType.FixedSize > 127)
            {
                throw new NotImplementedException();
            }

            writer.WriteUSx(OpCodes.FORG, _hiddenVariableStack.Offset, 0);
            writer.AddLabelFix(exitLabel, InstructionWriter.FixUSxJump);
            //Adjust right parameter: assume EmptyV.
            if (_loopVarSigType.IsCompatibleWith(StackSignature.EmptyV))
            {
                writer.WriteUUS(OpCodes.FORG_CTN,
                                _loopVarSig, (int)WellKnownStackSignature.EmptyV, _loopVarSigType.FixedSize);
            }
            else
            {
                writer.WriteUUS(OpCodes.FORG_CTN, _loopVarSig, 0, 0);
            }

            //Emit inner block.
            _forBlock.EmitStatements(writer);

            //Jump back.
            writer.WriteUSx(OpCodes.JMP, 0, 0);
            writer.AddLabelFix(loopLabel, InstructionWriter.FixUSxJump);

            writer.MarkLabel(exitLabel);
        }
コード例 #3
0
        public override void Emit(InstructionWriter writer)
        {
            var restartLabel = new LabelStatementSyntaxNode();
            var exitLabel    = new LabelStatementSyntaxNode();

            if (_e1Stack.Offset > 255 || _loopVar.Offset > 255)
            {
                throw new NotImplementedException();
            }

            //Calc expressions.
            _e1.EmitPrep(writer);
            _e1.EmitGet(writer, _e1Stack);
            _e2.EmitPrep(writer);
            _e2.EmitGet(writer, _e2Stack);
            _e3.EmitPrep(writer);
            _e3.EmitGet(writer, _e3Stack);

            //Init instruction (check type, check exit condition).
            writer.WriteUSx(_initOp, _e1Stack.Offset, 0);
            writer.AddLabelFix(exitLabel, InstructionWriter.FixUSxJump);

            //This is where we restart.
            writer.MarkLabel(restartLabel);

            //Start of the actual block (creates upvals).
            _forBlock.EmitUpvalLists(writer);
            //Copy hidden control variable to the visible loop var.
            writer.WriteUUU(Opcodes.MOV, _loopVar.Offset, _e1Stack.Offset, 0);

            //Emit inner aux block.
            _forBlock.EmitStatements(writer);

            //Loop instruction.
            writer.WriteUSx(_loopOp, _e1Stack.Offset, 0);
            writer.AddLabelFix(restartLabel, InstructionWriter.FixUSxJump);

            writer.MarkLabel(exitLabel);
        }