Пример #1
0
 public override void EmitBranchFalse(CodeGen cg, Label label)
 {
     if (NodeType == AstNodeType.Not)
     {
         _operand.EmitBranchTrue(cg, label);
     }
     else
     {
         base.EmitBranchFalse(cg, label);
     }
 }
Пример #2
0
        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);
            }
        }