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); } }
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); }
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; }
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)); }
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)); }