Beispiel #1
0
        // when [<expr>, ...] *<array>
        //
        // generates this code:
        //
        // IEnumerator<object>/*!*/ enumVar = RubyOps.Unsplat(<array>).GetEnumerator();
        // bool result = false;
        // while (enumVar.MoveNext()) {
        //     if (<MakeTest>(enumVar.Current)) {
        //         result = true;
        //         break;
        //     }
        // }
        private static MSA.Expression /*!*/ MakeArrayTest(AstGenerator /*!*/ gen, MSA.Expression /*!*/ array, MSA.Expression value)
        {
            MSA.Expression enumVariable   = gen.CurrentScope.DefineHiddenVariable("#case-enumerator", typeof(IEnumerator <object>));
            MSA.Expression resultVariable = gen.CurrentScope.DefineHiddenVariable("#case-compare-result", typeof(bool));

            MSA.LabelTarget label = Ast.Label();
            return(AstFactory.Block(
                       Ast.Assign(enumVariable, Ast.Call(
                                      Methods.Unsplat.OpCall(AstFactory.Box(array)),
                                      Methods.IEnumerable_Of_Object_GetEnumerator
                                      )),

                       Ast.Assign(resultVariable, Ast.Constant(false)),

                       AstUtils.While(
                           Ast.Call(enumVariable, Methods.IEnumerator_MoveNext),
                           AstUtils.If(
                               MakeTest(gen, Ast.Call(enumVariable, Methods.IEnumerator_get_Current), value),
                               Ast.Block(
                                   Ast.Assign(resultVariable, Ast.Constant(true)),
                                   Ast.Break(label),
                                   Ast.Empty()
                                   )
                               ),
                           null,
                           label,
                           null
                           ),
                       resultVariable
                       ));
        }
Beispiel #2
0
        private MSAst.Expression ReduceWorker(bool optimizeDynamicConvert)
        {
            // Only the body is "in the loop" for the purposes of break/continue
            // The "else" clause is outside

            ConstantExpression constTest = _test as ConstantExpression;

            if (constTest != null && constTest.Value is int)
            {
                // while 0: / while 1:
                int val = (int)constTest.Value;
                if (val == 0)
                {
                    // completely optimize the loop away
                    if (_else == null)
                    {
                        return(MSAst.Expression.Empty());
                    }
                    else
                    {
                        return(_else);
                    }
                }

                MSAst.Expression test = MSAst.Expression.Constant(true);
                MSAst.Expression res  = AstUtils.While(
                    test,
                    _body,
                    _else,
                    _break,
                    _continue
                    );

                if (GlobalParent.IndexToLocation(_test.StartIndex).Line != GlobalParent.IndexToLocation(_body.StartIndex).Line)
                {
                    res = GlobalParent.AddDebugInfoAndVoid(res, _test.Span);
                }

                return(res);
            }

            return(AstUtils.While(
                       GlobalParent.AddDebugInfo(
                           optimizeDynamicConvert ?
                           TransformAndDynamicConvert(_test, typeof(bool)) :
                           GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, _test),
                           Header
                           ),
                       _body,
                       _else,
                       _break,
                       _continue
                       ));
        }