public override void EmitBranchTrue(CodeGen cg, Label label) { if (NodeType == AstNodeType.Not) { _operand.EmitBranchFalse(cg, label); } else { base.EmitBranchTrue(cg, label); } }
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; } }
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); } }