Example #1
0
        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);
            }
        }
Example #2
0
        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());
        }