Exemplo n.º 1
0
        public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
        {
            var leftStack  = _leftStack ?? dest;
            var rightStack = _rightStack ?? dest;

            if (_left.GetSingleType() != _type || _right.GetSingleType() != _type)
            {
                //Needs conversion in MOV and ISTC.
                throw new NotImplementedException();
            }
            if (leftStack.Offset > 255 || rightStack.Offset > 255 || dest.Offset > 255)
            {
                throw new NotImplementedException();
            }

            //  emit leftStack = _left
            //  ISFC/ISTC dest, leftStack, exitLabel
            //  emit rightStack = _right
            //  MOV dest, rightStack
            //exitLabel:

            var exitLabel = new LabelStatementSyntaxNode();

            _left.EmitPrep(writer);
            _left.EmitGet(writer, leftStack);
            writer.WriteUUS(_opcode, dest.Offset, leftStack.Offset, 0);
            writer.AddLabelFix(exitLabel, InstructionWriter.FixUUSJump);
            _right.EmitPrep(writer);
            _right.EmitGet(writer, rightStack);
            //We already wrote to dest. No need to MOV.
            Debug.Assert(rightStack.Offset == dest.Offset);
            writer.MarkLabel(exitLabel);
        }
Exemplo n.º 2
0
        public ConditionGenerator(GeneratorFactory factory, BlockGenerator block,
                                  ExpressionSyntaxNode expr, LabelStatementSyntaxNode falseLabel, bool reverseCondition)
        {
            while (expr is UnaryExpressionSyntaxNode unary && unary.Operator == UnaryOperator.Not)
            {
                expr             = unary.Operand;
                reverseCondition = !reverseCondition;
            }

            if (expr is BinaryExpressionSyntaxNode bin && IsComparisonExpr(bin, out _opcode, out _exchangeComparison))
            {
                _isComparison = true;
                //Normally, reverse the cmp (jump to false label if condition is not met).
                if (!reverseCondition)
                {
                    ReverseComparisonResult(ref _opcode);
                }
                _expr1 = factory.CreateExpression(block, bin.Left);
                _expr2 = factory.CreateExpression(block, bin.Right);
                if (!_expr1.TryGetFromStack(out _))
                {
                    _expr1Stack = block.TempAllocator.Allocate(_expr1.GetSingleType());
                }
                if (!_expr2.TryGetFromStack(out _))
                {
                    _expr2Stack = block.TempAllocator.Allocate(_expr2.GetSingleType());
                }
            }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        public RepeatStatementGenerator(GeneratorFactory factory, BlockGenerator block, RepeatBlockSyntaxNode stat)
        {
            _repeatLabel = new LabelStatementSyntaxNode();
            _block       = new BlockGenerator(factory, block.Stack, stat);

            //Jump to _repeatLabel (falseLabel) if false.
            _cond = new ConditionGenerator(factory, _block, stat.StopCondition, _repeatLabel, reverseCondition: false);
        }
Exemplo n.º 5
0
        public override void Emit(InstructionWriter writer)
        {
            var restartLabel = new LabelStatementSyntaxNode();

            writer.MarkLabel(restartLabel);
            _cond.Emit(writer);

            _block.Emit(writer);

            writer.WriteUSx(OpCodes.JMP, 0, 0);
            writer.AddLabelFix(restartLabel, InstructionWriter.FixUSxJump);

            writer.MarkLabel(_exitLabel);
        }
Exemplo n.º 6
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);
        }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
0
 public GotoStatementGenerator(LabelStatementSyntaxNode label)
 {
     _label = label;
 }
Exemplo n.º 9
0
 public WhileStatementGenerator(GeneratorFactory factory, BlockGenerator block, WhileBlockSyntaxNode stat)
 {
     _exitLabel = new LabelStatementSyntaxNode();
     _cond      = new ConditionGenerator(factory, block, stat.Condition, _exitLabel, reverseCondition: false);
     _block     = new BlockGenerator(factory, block.Stack, stat);
 }