コード例 #1
0
 public override void EmitBranchTrue(CodeGen cg, Label label)
 {
     if (NodeType == AstNodeType.Not)
     {
         _operand.EmitBranchFalse(cg, label);
     }
     else
     {
         base.EmitBranchTrue(cg, label);
     }
 }
コード例 #2
0
ファイル: BinaryExpression.cs プロジェクト: tylike/IronScheme
        public override void EmitBranchFalse(CodeGen cg, Label label)
        {
            switch (NodeType)
            {
            case AstNodeType.Equal:
                EmitLocation(cg);
                EmitBranchTrue(cg, AstNodeType.NotEqual, label);
                if (ScriptDomainManager.Options.LightweightDebugging)
                {
                    if (!cg.IsDynamicMethod)
                    {
                        var s = SpanToLong(Span);
                        cg.EmitConstant(s);
                        cg.EmitCall(Debugging.DebugMethods.ExpressionOut);
                    }
                }
                break;

            case AstNodeType.NotEqual:
                EmitLocation(cg);
                EmitBranchTrue(cg, AstNodeType.Equal, label);
                if (ScriptDomainManager.Options.LightweightDebugging)
                {
                    if (!cg.IsDynamicMethod)
                    {
                        var s = SpanToLong(Span);
                        cg.EmitConstant(s);
                        cg.EmitCall(Debugging.DebugMethods.ExpressionOut);
                    }
                }
                break;

            case AstNodeType.AndAlso:
                // if NOT (left AND right) branch label

                if (_left.IsConstant(false))
                {
                    cg.Emit(OpCodes.Br, label);
                }
                else
                {
                    if (!_left.IsConstant(true))
                    {
                        _left.EmitBranchFalse(cg, label);
                    }

                    if (_right.IsConstant(false))
                    {
                        cg.Emit(OpCodes.Br, label);
                    }
                    else if (!_right.IsConstant(true))
                    {
                        _right.EmitBranchFalse(cg, label);
                    }
                }
                break;

            case AstNodeType.OrElse:
                // if NOT left AND NOT right branch label

                if (!_left.IsConstant(true) && !_right.IsConstant(true))
                {
                    if (_left.IsConstant(false))
                    {
                        _right.EmitBranchFalse(cg, label);
                    }
                    else if (_right.IsConstant(false))
                    {
                        _left.EmitBranchFalse(cg, label);
                    }
                    else
                    {
                        // if (NOT left) then
                        //   if (NOT right) branch label
                        // endif

                        Label endif = cg.DefineLabel();
                        _left.EmitBranchTrue(cg, endif);
                        _right.EmitBranchFalse(cg, label);
                        cg.MarkLabel(endif);
                    }
                }
                break;

            case AstNodeType.LessThan:
                EmitLocation(cg);
                EmitBranchTrue(cg, AstNodeType.GreaterThanOrEqual, label);
                break;

            case AstNodeType.LessThanOrEqual:
                EmitLocation(cg);
                EmitBranchTrue(cg, AstNodeType.GreaterThan, label);
                break;

            case AstNodeType.GreaterThan:
                EmitLocation(cg);
                EmitBranchTrue(cg, AstNodeType.LessThanOrEqual, label);
                break;

            case AstNodeType.GreaterThanOrEqual:
                EmitLocation(cg);
                EmitBranchTrue(cg, AstNodeType.LessThan, label);
                break;

            default:

                base.EmitBranchFalse(cg, label);
                break;
            }
        }
コード例 #3
0
ファイル: BinaryExpression.cs プロジェクト: tylike/IronScheme
        private bool EmitBranchTrue(CodeGen cg, AstNodeType nodeType, Label label)
        {
            switch (nodeType)
            {
            case AstNodeType.GreaterThan:
                _left.EmitAs(cg, GetEmitType());
                _right.EmitAs(cg, GetEmitType());
                cg.EmitSequencePointNone();
                cg.Emit(OpCodes.Bgt, label);
                cg.EmitSequencePointNone();
                return(true);

            case AstNodeType.GreaterThanOrEqual:
                _left.EmitAs(cg, GetEmitType());
                _right.EmitAs(cg, GetEmitType());
                cg.EmitSequencePointNone();
                cg.Emit(OpCodes.Bge, label);
                cg.EmitSequencePointNone();
                return(true);

            case AstNodeType.LessThan:
                _left.EmitAs(cg, GetEmitType());
                _right.EmitAs(cg, GetEmitType());
                cg.EmitSequencePointNone();
                cg.Emit(OpCodes.Blt, label);
                cg.EmitSequencePointNone();
                return(true);

            case AstNodeType.LessThanOrEqual:
                _left.EmitAs(cg, GetEmitType());
                _right.EmitAs(cg, GetEmitType());
                cg.EmitSequencePointNone();
                cg.Emit(OpCodes.Ble, label);
                cg.EmitSequencePointNone();
                return(true);

            case AstNodeType.Equal:
                if (_left.IsConstant(null))
                {
                    _right.EmitAsObject(cg);
                    cg.EmitSequencePointNone();
                    cg.Emit(OpCodes.Brfalse, label);
                    cg.EmitSequencePointNone();
                }
                else if (_right.IsConstant(null))
                {
                    _left.EmitAsObject(cg);
                    cg.EmitSequencePointNone();
                    cg.Emit(OpCodes.Brfalse, label);
                    cg.EmitSequencePointNone();
                }
                else
                {
                    _left.EmitAs(cg, GetEmitType());
                    _right.EmitAs(cg, GetEmitType());
                    cg.EmitSequencePointNone();
                    cg.Emit(OpCodes.Beq, label);
                    cg.EmitSequencePointNone();
                }
                return(true);

            case AstNodeType.NotEqual:
                if (_left.IsConstant(null))
                {
                    _right.EmitAsObject(cg);
                    cg.EmitSequencePointNone();
                    cg.Emit(OpCodes.Brtrue, label);
                    cg.EmitSequencePointNone();
                }
                else if (_right.IsConstant(null))
                {
                    _left.EmitAsObject(cg);
                    cg.EmitSequencePointNone();
                    cg.Emit(OpCodes.Brtrue, label);
                    cg.EmitSequencePointNone();
                }
                else
                {
                    _left.EmitAs(cg, GetEmitType());
                    _right.EmitAs(cg, GetEmitType());
                    //cg.Emit(OpCodes.Ceq);
                    cg.EmitSequencePointNone();
                    cg.Emit(OpCodes.Bne_Un, label);
                    cg.EmitSequencePointNone();
                }
                return(true);

            case AstNodeType.AndAlso:
                // if (left AND right) branch label

                // if (left) then
                //   if (right) branch label
                // endif
                Label endif = cg.DefineLabel();
                _left.EmitBranchFalse(cg, endif);
                _right.EmitBranchTrue(cg, label);
                cg.MarkLabel(endif);
                return(true);

            case AstNodeType.OrElse:
                // if (left OR right) branch label

                // if (left) then branch label endif
                // if (right) then branch label endif
                _left.EmitBranchTrue(cg, label);
                _right.EmitBranchTrue(cg, label);
                return(true);

            default:
                return(false);
            }
        }