예제 #1
0
 // IfStatementTest
 private void DefaultWalk(IfStatementTest node)
 {
     if (Walk(node))
     {
         WalkNode(node.Test);
         WalkNode(node.Body);
     }
     PostWalk(node);
 }
예제 #2
0
        // 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);
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        // 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);
        }
예제 #6
0
        // 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);
            }
        }
예제 #7
0
 public static Expression If(IfStatementTest[] tests, Expression @else) {
     ContractUtils.RequiresNotNullItems(tests, "tests");
     return IfStatementBuilder.BuildConditions(tests, @else);
 }
예제 #8
0
파일: Body.cs 프로젝트: jcteague/ironruby
        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;
        }
예제 #9
0
 public static IfStatement If(SourceSpan span, IfStatementTest[] tests, Statement @else)
 {
     Contract.RequiresNotNullItems(tests, "tests");
     return new IfStatement(span, CollectionUtils.ToReadOnlyCollection(tests), @else);
 }
예제 #10
0
 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];
                      }
                    }
                      }
                }
예제 #12
0
 // IfStatementTest
 private void DefaultWalk(IfStatementTest node)
 {
     if (Walk(node)) {
         WalkNode(node.Test);
         WalkNode(node.Body);
     }
     PostWalk(node);
 }