Example #1
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            //Optimize condition
            _OptimizeNode(target, ref Condition);

            // Invert condition when unary logical not
            AstIndirectCall unaryCond;
            while (Condition.IsCommandCall(Commands.Core.Operators.LogicalNot.DefaultAlias, out unaryCond))
            {
                Condition = unaryCond.Arguments[0];
                IsNegative = !IsNegative;
            }

            //Constant conditions
            if (Condition is AstConstant)
            {
                var constCond = (AstConstant) Condition;
                PValue condValue;
                if (
                    !constCond.ToPValue(target).TryConvertTo(
                        target.Loader, PType.Bool, out condValue))
                    goto continueFull;
                else if (((bool) condValue.Value) ^ IsNegative)
                    IfBlock.EmitEffectCode(target);
                else
                    ElseBlock.EmitEffectCode(target);
                return;
            }
            //Conditions with empty blocks
            if (IfBlock.IsEmpty && ElseBlock.IsEmpty)
            {
                Condition.EmitEffectCode(target);
                return;
            }
            continueFull:
            ;

            //Switch If and Else block in case the if-block is empty
            if (IfBlock.IsEmpty)
            {
                IsNegative = !IsNegative;
                var tmp = IfBlock;
                IfBlock = ElseBlock;
                ElseBlock = tmp;
            }

            var elseLabel = "else\\" + _depth + "\\assembler";
            var endLabel = "endif\\" + _depth + "\\assembler";
            _depth++;

            //Emit
            var ifGoto = IfBlock.IsSingleStatement
                ? IfBlock[0] as AstExplicitGoTo
                : null;
            var elseGoto = ElseBlock.IsSingleStatement
                ? ElseBlock[0] as AstExplicitGoTo
                : null;
            ;

            var ifIsGoto = ifGoto != null;
            var elseIsGoto = elseGoto != null;

            if (ifIsGoto && elseIsGoto)
            {
                //only jumps
                AstLazyLogical.EmitJumpCondition(
                    target,
                    Condition,
                    ifGoto.Destination,
                    elseGoto.Destination,
                    !IsNegative);
            }
            else if (ifIsGoto)
            {
                //if => jump / else => block
                AstLazyLogical.EmitJumpCondition(target, Condition, ifGoto.Destination, !IsNegative);
                ElseBlock.EmitEffectCode(target);
            }
            else if (elseIsGoto)
            {
                //if => block / else => jump
                AstLazyLogical.EmitJumpCondition(
                    target, Condition, elseGoto.Destination, IsNegative); //inverted
                IfBlock.EmitEffectCode(target);
            }
            else
            {
                //if => block / else => block
                AstLazyLogical.EmitJumpCondition(target, Condition, elseLabel, IsNegative);
                IfBlock.EmitEffectCode(target);
                target.EmitJump(Position, endLabel);
                target.EmitLabel(Position, elseLabel);
                ElseBlock.EmitEffectCode(target);
                target.EmitLabel(Position, endLabel);
            }

            target.FreeLabel(elseLabel);
            target.FreeLabel(endLabel);
        }
Example #2
0
 protected override void DoEmitCode(CompilerTarget target, string trueLabel,
     string falseLabel)
 {
     var labelNs = @"Or\" + Guid.NewGuid().ToString("N");
     var nextLabel = @"Next\" + labelNs;
     foreach (var expr in Conditions)
     {
         var and = expr as AstLogicalAnd;
         if (and != null)
         {
             and.EmitCode(target, trueLabel, nextLabel);
             //ResolveOperator pending jumps to Next
             target.EmitLabel(Position, nextLabel);
             target.FreeLabel(nextLabel);
             //Future references of to nextLabel will be resolved in the next iteration
         }
         else
         {
             expr.EmitValueCode(target);
             target.EmitJumpIfTrue(Position, trueLabel);
         }
     }
     target.EmitJump(Position, falseLabel);
 }
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            //Optimize condition
            _OptimizeNode(target, ref Condition);
            _OptimizeNode(target, ref IfExpression);
            _OptimizeNode(target, ref ElseExpression);

            var elseLabel = "elsei\\" + _depth + "\\assembler";
            var endLabel = "endifi\\" + _depth + "\\assembler";
            _depth++;

            //Emit
            //if => block / else => block
            AstLazyLogical.EmitJumpCondition(target, Condition, elseLabel, IsNegative);
            IfExpression.EmitCode(target, stackSemantics);
            target.EmitJump(Position, endLabel);
            target.EmitLabel(Position, elseLabel);
            ElseExpression.EmitCode(target, stackSemantics);
            target.EmitLabel(Position, endLabel);

            target.FreeLabel(elseLabel);
            target.FreeLabel(endLabel);
        }