public void AddInstructions(LightCompiler compiler)
        {
            EnterLoopInstruction enterLoopInstruction = null;

            compiler.PushLabelBlock(LabelScopeKind.Statement);
            foreach (Expression expression in this._exprs)
            {
                compiler.CompileAsVoid(expression);
                EnterLoopExpression expression2 = expression as EnterLoopExpression;
                if (expression2 != null)
                {
                    enterLoopInstruction = expression2.EnterLoopInstruction;
                }
            }
            compiler.PopLabelBlock(LabelScopeKind.Statement);
            if (enterLoopInstruction != null)
            {
                enterLoopInstruction.FinishLoop(compiler.Instructions.Count);
            }
        }
Пример #2
0
        private Expression GenerateDoLoop(LoopStatementAst loopStatement)
        {
            // Generate code like:
            //    :RepeatTarget
            //    try {
            //       loop body
            //       // break -> goto BreakTarget
            //       // continue -> goto TestBlock
            //    } catch (BreakException be) {
            //        if (be.MatchLabel(loopLabel))
            //             goto BreakTarget;
            //        throw;
            //    } catch (ContinueException ce) {
            //        if (ce.MatchLabel(loopLabel))
            //            goto ContinueTarget;
            //        throw;
            //    }
            //    :ContinueTarget
            //    if (condition)
            //    {
            //        goto RepeatTarget
            //    }
            //    :BreakTarget

            int preStmtCount = _stmtCount;

            string loopLabel = loopStatement.Label;
            var exprs = new List<Expression>();
            var repeatLabel = Expression.Label(!string.IsNullOrEmpty(loopLabel) ? loopLabel : null);
            var continueLabel = Expression.Label(!string.IsNullOrEmpty(loopLabel) ? loopLabel + "Continue" : "continue");
            var breakLabel = Expression.Label(!string.IsNullOrEmpty(loopLabel) ? loopLabel + "Break" : "break");
            var enterLoopExpression = new EnterLoopExpression();

            exprs.Add(Expression.Label(repeatLabel));
            exprs.Add(enterLoopExpression);

            _loopTargets.Add(new LoopGotoTargets(loopLabel ?? "", breakLabel, continueLabel));
            _generatingWhileOrDoLoop = true;
            var loopBodyExprs = new List<Expression>
                                    {
                                    s_callCheckForInterrupts,
                                    Compile(loopStatement.Body),
                                    ExpressionCache.Empty
                                };
            _generatingWhileOrDoLoop = false;
            _loopTargets.RemoveAt(_loopTargets.Count - 1);

            exprs.Add(Expression.TryCatch(Expression.Block(loopBodyExprs),
                                          GenerateLoopBreakContinueCatchBlocks(loopLabel, breakLabel, continueLabel)));
            exprs.Add(Expression.Label(continueLabel));
            var test = CaptureStatementResults(loopStatement.Condition, CaptureAstContext.Condition).Convert(typeof(bool));
            if (loopStatement is DoUntilStatementAst)
            {
                test = Expression.Not(test);
            }
            exprs.Add(Expression.IfThen(test, Expression.Goto(repeatLabel)));
            exprs.Add(Expression.Label(breakLabel));

            enterLoopExpression.LoopStatementCount = _stmtCount - preStmtCount;
            return enterLoopExpression.Loop = new PowerShellLoopExpression(exprs);
        }
Пример #3
0
 private Expression GenerateWhileLoop(string loopLabel, Func<Expression> generateCondition, Action<List<Expression>, LabelTarget, LabelTarget> generateLoopBody, PipelineBaseAst continueAst = null)
 {
     string str;
     string str1;
     string str2;
     LabelTarget labelTarget;
     int num = this._stmtCount;
     List<Expression> expressions = new List<Expression>();
     if (!string.IsNullOrEmpty(loopLabel))
     {
         str = string.Concat(loopLabel, "Continue");
     }
     else
     {
         str = "continue";
     }
     LabelTarget labelTarget1 = Expression.Label(str);
     if (!string.IsNullOrEmpty(loopLabel))
     {
         str1 = string.Concat(loopLabel, "Break");
     }
     else
     {
         str1 = "break";
     }
     LabelTarget labelTarget2 = Expression.Label(str1);
     EnterLoopExpression enterLoopExpression = new EnterLoopExpression();
     if (continueAst != null)
     {
         if (!string.IsNullOrEmpty(loopLabel))
         {
             str2 = string.Concat(loopLabel, "LoopTop");
         }
         else
         {
             str2 = "looptop";
         }
         labelTarget = Expression.Label(str2);
     }
     else
     {
         labelTarget = labelTarget1;
     }
     LabelTarget labelTarget3 = labelTarget;
     expressions.Add(Expression.Label(labelTarget3));
     expressions.Add(enterLoopExpression);
     List<Expression> expressions1 = new List<Expression>();
     expressions1.Add(Compiler._callCheckForInterrupts);
     List<Compiler.LoopGotoTargets> loopGotoTargets = this._loopTargets;
     string str3 = loopLabel;
     string str4 = str3;
     if (str3 == null)
     {
         str4 = "";
     }
     loopGotoTargets.Add(new Compiler.LoopGotoTargets(str4, labelTarget2, labelTarget1));
     generateLoopBody(expressions1, labelTarget2, labelTarget1);
     if (continueAst == null)
     {
         expressions1.Add(Expression.Goto(labelTarget3));
     }
     this._loopTargets.RemoveAt(this._loopTargets.Count - 1);
     Expression expression = Expression.TryCatch(Expression.Block(expressions1), Compiler.GenerateLoopBreakContinueCatchBlocks(loopLabel, labelTarget2, labelTarget1));
     if (continueAst != null)
     {
         List<Expression> expressions2 = new List<Expression>();
         expressions2.Add(expression);
         expressions2.Add(Expression.Label(labelTarget1));
         if (continueAst.GetPureExpression() != null)
         {
             expressions2.Add(this.UpdatePosition(continueAst));
         }
         expressions2.Add(this.CaptureStatementResults(continueAst, Compiler.CaptureAstContext.Assignment, null));
         expressions2.Add(Expression.Goto(labelTarget3));
         expression = Expression.Block(expressions2);
     }
     if (generateCondition == null)
     {
         expressions.Add(expression);
     }
     else
     {
         expressions.Add(Expression.IfThen(generateCondition().Convert(typeof(bool)), expression));
     }
     expressions.Add(Expression.Label(labelTarget2));
     enterLoopExpression.LoopStatementCount = this._stmtCount - num;
     PowerShellLoopExpression powerShellLoopExpression = new PowerShellLoopExpression(expressions);
     PowerShellLoopExpression powerShellLoopExpression1 = powerShellLoopExpression;
     enterLoopExpression.Loop = powerShellLoopExpression;
     return powerShellLoopExpression1;
 }
Пример #4
0
        private Expression GenerateWhileLoop(string loopLabel,
                                             Func<Expression> generateCondition,
                                             Action<List<Expression>, LabelTarget, LabelTarget> generateLoopBody,
                                             PipelineBaseAst continueAst = null)
        {
            // If continueAst is not null, generate:
            //    LoopTop:
            //    if (condition)
            //    {
            //        try {
            //            loop body
            //            // break -> goto BreakTarget
            //            // continue -> goto ContinueTarget
            //        } catch (BreakException be) {
            //            if (be.MatchLabel(loopLabel)) goto BreakTarget;
            //            throw;
            //        } catch (ContinueException ce) {
            //            if (ce.MatchLabel(loopLabel)) goto ContinueTarget;
            //            throw;
            //        }
            //    ContinueTarget:
            //            continueAction
            //            goto LoopTop:
            //    }
            //    :BreakTarget
            //
            // If continueAst is null, generate:
            //    ContinueTarget:
            //    if (condition)
            //    {
            //        try {
            //            loop body
            //            // break -> goto BreakTarget
            //            // continue -> goto ContinueTarget
            //            goto ContinueTarget
            //        } catch (BreakException be) {
            //            if (be.MatchLabel(loopLabel)) goto BreakTarget;
            //            throw;
            //        } catch (ContinueException ce) {
            //            if (ce.MatchLabel(loopLabel)) goto ContinueTarget;
            //            throw;
            //        }
            //    }
            //    :BreakTarget

            int preStmtCount = _stmtCount;

            var exprs = new List<Expression>();
            var continueLabel = Expression.Label(!string.IsNullOrEmpty(loopLabel) ? loopLabel + "Continue" : "continue");
            var breakLabel = Expression.Label(!string.IsNullOrEmpty(loopLabel) ? loopLabel + "Break" : "break");
            var enterLoop = new EnterLoopExpression();

            var loopTop = (continueAst != null)
                              ? Expression.Label(!string.IsNullOrEmpty(loopLabel) ? loopLabel + "LoopTop" : "looptop")
                              : continueLabel;

            exprs.Add(Expression.Label(loopTop));
            exprs.Add(enterLoop);

            var loopBodyExprs = new List<Expression>();
            loopBodyExprs.Add(s_callCheckForInterrupts);

            _loopTargets.Add(new LoopGotoTargets(loopLabel ?? "", breakLabel, continueLabel));
            _generatingWhileOrDoLoop = true;
            generateLoopBody(loopBodyExprs, breakLabel, continueLabel);
            _generatingWhileOrDoLoop = false;
            if (continueAst == null)
            {
                loopBodyExprs.Add(Expression.Goto(loopTop));
            }
            _loopTargets.RemoveAt(_loopTargets.Count - 1);

            Expression loopBody =
                Expression.TryCatch(Expression.Block(loopBodyExprs),
                                    GenerateLoopBreakContinueCatchBlocks(loopLabel, breakLabel, continueLabel));
            if (continueAst != null)
            {
                var x = new List<Expression>();
                x.Add(loopBody);
                x.Add(Expression.Label(continueLabel));
                if (continueAst.GetPureExpression() != null)
                {
                    // Assignments generate the code to update the position automatically,
                    // but pre/post increments don't, so we add it here explicitly.
                    x.Add(UpdatePosition(continueAst));
                }
                // We should not preserve the partial output if exception is thrown when evaluating the continueAst.
                x.Add(CaptureStatementResults(continueAst, CaptureAstContext.AssignmentWithoutResultPreservation));
                x.Add(Expression.Goto(loopTop));
                loopBody = Expression.Block(x);
            }

            if (generateCondition != null)
            {
                exprs.Add(Expression.IfThen(generateCondition().Convert(typeof(bool)), loopBody));
            }
            else
            {
                exprs.Add(loopBody);
            }
            exprs.Add(Expression.Label(breakLabel));
            enterLoop.LoopStatementCount = _stmtCount - preStmtCount;
            return (enterLoop.Loop = new PowerShellLoopExpression(exprs));
        }
Пример #5
0
 private Expression GenerateDoLoop(LoopStatementAst loopStatement)
 {
     int num = this._stmtCount;
     string label = loopStatement.Label;
     List<Expression> exprs = new List<Expression>();
     LabelTarget target = Expression.Label(!string.IsNullOrEmpty(label) ? label : null);
     LabelTarget continueLabel = Expression.Label(!string.IsNullOrEmpty(label) ? (label + "Continue") : "continue");
     LabelTarget breakLabel = Expression.Label(!string.IsNullOrEmpty(label) ? (label + "Break") : "break");
     EnterLoopExpression item = new EnterLoopExpression();
     exprs.Add(Expression.Label(target));
     exprs.Add(item);
     this._loopTargets.Add(new LoopGotoTargets(label ?? "", breakLabel, continueLabel));
     List<Expression> expressions = new List<Expression> {
         _callCheckForInterrupts,
         this.Compile(loopStatement.Body),
         ExpressionCache.Empty
     };
     this._loopTargets.RemoveAt(this._loopTargets.Count - 1);
     exprs.Add(Expression.TryCatch(Expression.Block(expressions), GenerateLoopBreakContinueCatchBlocks(label, breakLabel, continueLabel)));
     exprs.Add(Expression.Label(continueLabel));
     Expression expression = this.CaptureStatementResults(loopStatement.Condition, CaptureAstContext.Condition, null).Convert(typeof(bool));
     if (loopStatement is DoUntilStatementAst)
     {
         expression = Expression.Not(expression);
     }
     exprs.Add(Expression.IfThen(expression, Expression.Goto(target)));
     exprs.Add(Expression.Label(breakLabel));
     item.LoopStatementCount = this._stmtCount - num;
     return (item.Loop = new PowerShellLoopExpression(exprs));
 }