// IfStatementTest private void DefaultWalk(IfStatementTest node) { if (Walk(node)) { WalkNode(node.Test); WalkNode(node.Body); } PostWalk(node); }
// IfStatementTest private IfStatementTest Rewrite(IfStatementTest node) { Expression test = RewriteExpressionFreeTemps(node.Test); Statement body = RewriteStatement(node.Body); if (((object)test != (object)node.Test) || ((object)body != (object)node.Body)) { return(new IfStatementTest(node.Span, node.Header, test, body)); } else { return(node); } }
internal static Expression BuildConditions(IList <IfStatementTest> clauses, Expression @else) { Expression result = @else ?? Utils.Empty(); // This should probably be using SwitchExpression to avoid stack // overflow if we have lots of "else" clauses. int index = clauses.Count; while (index-- > 0) { IfStatementTest ist = clauses[index]; result = Expression.IfThenElse(ist.Test, ist.Body, result); } return(result); }
internal static Expression BuildConditions(IList <IfStatementTest> clauses, Expression @else) { Expression result = @else != null?Expression.Void(@else) : Expression.Empty(); int index = clauses.Count; while (index-- > 0) { IfStatementTest ist = clauses[index]; result = Expression.Condition( ist.Test, Expression.Void(ist.Body), result ); } return(result); }
// IfStatement private void Dump(IfStatement node) { for (int i = 0; i < node.Tests.Count; i++) { IfStatementTest test = node.Tests[i]; Out(i == 0 ? ".if (" : "} .elif ("); WalkNode(test.Test); Out(") {", Flow.NewLine); Indent(); WalkNode(test.Body); Dedent(); } if (node.ElseStatement != null) { Out("} .else {", Flow.NewLine); Indent(); WalkNode(node.ElseStatement); Dedent(); } Out("}", Flow.NewLine); }
// IfStatement private Statement Rewrite(IfStatement node) { ReadOnlyCollection <IfStatementTest> tests = node.Tests; IfStatementTest[] clone = null; for (int i = 0; i < tests.Count; i++) { IfStatementTest test = tests[i]; IfStatementTest rtest = Rewrite(test); if (((object)test != (object)rtest) && (clone == null)) { clone = Clone(tests, i); } if (clone != null) { clone[i] = rtest; } } Statement @else = RewriteStatement(node.ElseStatement); // Did we rewrite anything? if (clone != null) { return(new IfStatement(node.Span, CollectionUtils.ToReadOnlyCollection(clone), @else)); } else if ((object)@else != (object)node.ElseStatement) { return(new IfStatement(node.Span, CollectionUtils.ToReadOnlyCollection(tests), @else)); } else { return(node); } }
public static Expression If(IfStatementTest[] tests, Expression @else) { ContractUtils.RequiresNotNullItems(tests, "tests"); return IfStatementBuilder.BuildConditions(tests, @else); }
private MSA.Expression/*!*/ TransformExceptionHandling(AstGenerator/*!*/ gen, ResultOperation resultOperation) { Assert.NotNull(gen); MSA.Expression exceptionThrownVariable = gen.CurrentScope.DefineHiddenVariable("#exception-thrown", typeof(bool)); MSA.ParameterExpression exceptionVariable = gen.CurrentScope.DefineHiddenVariable("#exception", typeof(Exception)); MSA.Expression exceptionRethrowVariable = gen.CurrentScope.DefineHiddenVariable("#exception-rethrow", typeof(bool)); MSA.Expression retryingVariable = gen.CurrentScope.DefineHiddenVariable("#retrying", typeof(bool)); MSA.ParameterExpression evalUnwinder = gen.CurrentScope.DefineHiddenVariable("#unwinder", typeof(EvalUnwinder)); MSA.Expression oldExceptionVariable = gen.CurrentScope.DefineHiddenVariable("#old-exception", typeof(Exception)); MSA.Expression transformedBody; MSA.Expression transformedEnsure; MSA.Expression transformedElse; if (_ensureStatements != null) { transformedEnsure = Ast.Block( // ensure: Ast.Assign(oldExceptionVariable, Methods.GetCurrentException.OpCall(gen.CurrentScopeVariable)), gen.TransformStatements(_ensureStatements, ResultOperation.Ignore), Methods.SetCurrentException.OpCall(gen.CurrentScopeVariable, oldExceptionVariable), // rethrow: AstUtils.IfThen( Ast.AndAlso( exceptionRethrowVariable, Ast.NotEqual(oldExceptionVariable, AstUtils.Constant(null)) ), Ast.Throw(oldExceptionVariable) ), AstUtils.Empty() ); } else { // rethrow: transformedEnsure = AstUtils.IfThen( Ast.AndAlso( exceptionRethrowVariable, Ast.NotEqual( Ast.Assign(oldExceptionVariable, Methods.GetCurrentException.OpCall(gen.CurrentScopeVariable)), AstUtils.Constant(null, typeof(Exception))) ), Ast.Throw(oldExceptionVariable) ); } if (_elseStatements != null) { transformedElse = gen.TransformStatements(_elseStatements, resultOperation); } else { transformedElse = AstUtils.Empty(); } // body should do return, but else-clause is present => we cannot do return from the guarded statements: // (the value of the last expression in the body cannot be the last executed expression statement => we can ignore it): transformedBody = gen.TransformStatements(_statements, (_elseStatements != null) ? ResultOperation.Ignore : resultOperation); MSA.Expression setInRescueFlag = null, clearInRescueFlag = null; var breakLabel = Ast.Label(); var continueLabel = Ast.Label(); // make rescue clause: MSA.Expression transformedRescue; if (_rescueClauses != null) { // outer-most EH blocks sets and clears runtime flag RuntimeFlowControl.InTryRescue: if (gen.CurrentRescue == null) { setInRescueFlag = Ast.Assign(Ast.Field(gen.CurrentRfcVariable, RuntimeFlowControl.InRescueField), AstUtils.Constant(true)); clearInRescueFlag = Ast.Assign(Ast.Field(gen.CurrentRfcVariable, RuntimeFlowControl.InRescueField), AstUtils.Constant(false)); } else { setInRescueFlag = clearInRescueFlag = AstUtils.Empty(); } gen.EnterRescueClause(retryingVariable, breakLabel, continueLabel); var handlers = new IfStatementTest[_rescueClauses.Count]; for (int i = 0; i < handlers.Length; i++) { handlers[i] = _rescueClauses[i].Transform(gen, resultOperation); } transformedRescue = Ast.Block( setInRescueFlag, AstUtils.Try( AstUtils.If(handlers, Ast.Assign(exceptionRethrowVariable, AstUtils.Constant(true))) ).Filter(evalUnwinder, Ast.Equal(Ast.Field(evalUnwinder, EvalUnwinder.ReasonField), AstUtils.Constant(BlockReturnReason.Retry)), Ast.Block( Ast.Assign(retryingVariable, AstUtils.Constant(true)), Ast.Continue(continueLabel), AstUtils.Empty() ) ) ); gen.LeaveRescueClause(); } else { transformedRescue = Ast.Assign(exceptionRethrowVariable, AstUtils.Constant(true)); } if (_elseStatements != null) { transformedElse = AstUtils.Unless(exceptionThrownVariable, transformedElse); } var result = AstFactory.Infinite(breakLabel, continueLabel, Ast.Assign(exceptionThrownVariable, AstUtils.Constant(false)), Ast.Assign(exceptionRethrowVariable, AstUtils.Constant(false)), Ast.Assign(retryingVariable, AstUtils.Constant(false)), AstUtils.Try( // save exception (old_$! is not used unless there is a rescue clause): Ast.Block( (_rescueClauses == null) ? (MSA.Expression)AstUtils.Empty() : Ast.Assign(oldExceptionVariable, Methods.GetCurrentException.OpCall(gen.CurrentScopeVariable)), AstUtils.Try( Ast.Block(transformedBody, AstUtils.Empty()) ).Filter(exceptionVariable, Methods.CanRescue.OpCall(gen.CurrentRfcVariable, exceptionVariable), Ast.Assign(exceptionThrownVariable, AstUtils.Constant(true)), Methods.SetCurrentExceptionAndStackTrace.OpCall(gen.CurrentScopeVariable, exceptionVariable), transformedRescue, AstUtils.Empty() ).FinallyIf((_rescueClauses != null), // restore previous exception if the current one has been handled: AstUtils.Unless(exceptionRethrowVariable, Methods.SetCurrentException.OpCall(gen.CurrentScopeVariable, oldExceptionVariable) ), clearInRescueFlag ), // unless (exception_thrown) do <else-statements> end transformedElse, AstUtils.Empty() ) ).FilterIf((_rescueClauses != null || _elseStatements != null), exceptionVariable, Methods.CanRescue.OpCall(gen.CurrentRfcVariable, exceptionVariable), Ast.Block( Methods.SetCurrentExceptionAndStackTrace.OpCall(gen.CurrentScopeVariable, exceptionVariable), Ast.Assign(exceptionRethrowVariable, AstUtils.Constant(true)), AstUtils.Empty() ) ).Finally( AstUtils.Unless(retryingVariable, transformedEnsure) ), Ast.Break(breakLabel) ); return result; }
public static IfStatement If(SourceSpan span, IfStatementTest[] tests, Statement @else) { Contract.RequiresNotNullItems(tests, "tests"); return new IfStatement(span, CollectionUtils.ToReadOnlyCollection(tests), @else); }
public static IfStatement If(IfStatementTest[] tests, Statement @else) { return If(SourceSpan.None, tests, @else); }
protected override void PostWalk(IfStatementTest node) { base.PostWalk(node); if (node.Test is MethodCallExpression) { var mce = (MethodCallExpression)node.Test; if (mce.Method == typeof(IronScheme.Runtime.Builtins).GetMethod("IsTrue")) { if (mce.Arguments[0].Type == typeof(bool)) { node.Test = mce.Arguments[0]; } } } }