protected override void emitCode(Context ctx, bool mustReturn) { var gen = ctx.CurrentMethod.Generator; var condType = Condition.Resolve(ctx); if (!condType.IsExtendablyAssignableFrom(typeof(bool))) { error(Condition, CompilerMessages.ConditionTypeMismatch, condType); } if (Condition.IsConstant && ctx.Options.UnrollConstants) { var node = Condition.ConstantValue ? (NodeBase)TrueAction : FalseAction; if (node != null) { var nodeType = node.Resolve(ctx); var desiredType = Resolve(ctx); if (!nodeType.IsVoid() && !desiredType.IsVoid()) { node = Expr.Cast(node, desiredType); } node.Emit(ctx, mustReturn); if (!mustReturn && !node.Resolve(ctx).IsVoid()) { gen.EmitPop(); } } return; } var endLabel = gen.DefineLabel(); var falseLabel = gen.DefineLabel(); Expr.Cast(Condition, typeof(bool)).Emit(ctx, true); if (FalseAction == null) { gen.EmitBranchFalse(endLabel); TrueAction.Emit(ctx, mustReturn); if (!TrueAction.Resolve(ctx).IsVoid()) { gen.EmitPop(); } gen.MarkLabel(endLabel); } else { gen.EmitBranchFalse(falseLabel); emitBranch(ctx, TrueAction, mustReturn); gen.EmitJump(endLabel); gen.MarkLabel(falseLabel); emitBranch(ctx, FalseAction, mustReturn); gen.MarkLabel(endLabel); } }
protected override Type ResolveInternal(Context ctx, bool mustReturn) { if (!mustReturn || FalseAction == null) { return(typeof(UnitType)); } var type = TrueAction.Resolve(ctx); var otherType = FalseAction.Resolve(ctx); return(type.IsVoid() || otherType.IsVoid() ? typeof(UnitType) : new[] { type, otherType }.GetMostCommonType()); }