예제 #1
0
파일: Compiler.cs 프로젝트: 40a/PowerShell
        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));
        }
예제 #2
0
파일: Compiler.cs 프로젝트: nickchal/pash
 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;
 }