예제 #1
0
        /// <summary>
        /// Generate a function with no arguments that returns an int given that name. The
        /// actual statement is a very simple constant.
        /// </summary>
        /// <param name="fname"></param>
        /// <returns></returns>
        public static QMFuncSource GenerateFunction()
        {
            int[] ints = new int[10];
            var   qmb  = new QueryModelBuilder();

            qmb.AddClause(new MainFromClause("i", typeof(int), Expression.Constant(ints)));
            qmb.AddClause(new SelectClause(Expression.Constant(1)));
            qmb.AddResultOperator(new Remotion.Linq.Clauses.ResultOperators.CountResultOperator());

            var h = new QMFuncHeader()
            {
                Arguments = new object[] { }, QM = qmb.Build()
            };

            h.QMText = h.QM.ToString();
            var f = new QMFuncSource(h);

            var p           = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var st          = new StatementAssign(p, new ValSimple("5", typeof(int)));
            var inlineblock = new StatementInlineBlock();

            inlineblock.Add(st);
            inlineblock.Add(new StatementReturn(p));
            f.SetCodeBody(inlineblock);

            return(f);
        }
예제 #2
0
        public void TestObjectInitalizerInInnerBlock()
        {
            CPPTranslator target = new CPPTranslator();
            var           vInt   = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));

            vInt.SetInitialValue("2");
            GeneratedCode code = new GeneratedCode();

            code.SetResult(vInt);

            var innerBlock = new StatementInlineBlock();
            var vInt2      = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));

            vInt2.SetInitialValue("5");
            innerBlock.Add(vInt2);
            innerBlock.Add(new StatementSimpleStatement("fork = dork"));
            code.Add(innerBlock);

            var r = TranslateGeneratedCode(target, code);

            var st = (r["QueryFunctionBlocks"] as IEnumerable <IEnumerable <string> >).First().ToArray();

            Assert.AreEqual(6, st.Length, "incorrect number of statements");
            Assert.AreEqual("int " + vInt2.RawValue + " = 5;", st[2].Trim(), "incorrect initialization");
        }
예제 #3
0
        public void DeclaredVariablesLocalOnly()
        {
            var outter = new StatementInlineBlock();

            outter.Add(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)));

            var s = new StatementForLoop(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)), new ValSimple("5", typeof(int)));

            s.Add(DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)));

            outter.Add(s);

            Assert.AreEqual(2, s.DeclaredVariables.Count());
            Assert.AreEqual(3, s.AllDeclaredVariables.Count());
        }
예제 #4
0
        public void TestCombineNestedForLoopOnOneSide()
        {
            var base1  = new StatementInlineBlock();
            var limit  = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int));
            var loopP1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var loop1  = new StatementForLoop(loopP1, limit);

            base1.Add(loop1);

            var base2   = new StatementInlineBlock();
            var limit2  = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int));
            var loopP12 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var loop12  = new StatementForLoop(loopP12, limit);

            base2.Add(loop12);
            var loopP22 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var loop22  = new StatementForLoop(loopP22, limit);

            loop12.Add(loop22);

            var r = base1.TryCombineStatement(base2, new dummyOpt());

            Assert.IsTrue(r, "combination should work");
            Assert.AreEqual(base1, loop1.Parent, "loop 1 parent");
            Assert.AreEqual(loop1, loop22.Parent, "Loop 2 parent");
        }
예제 #5
0
        public void TestForFunctionNumber()
        {
            CPPTranslator target = new CPPTranslator();
            var           vInt   = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));

            vInt.SetInitialValue("2");
            GeneratedCode code = new GeneratedCode();

            code.SetResult(vInt);

            var innerBlock = new StatementInlineBlock();
            var vInt2      = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));

            vInt2.SetInitialValue("5");
            innerBlock.Add(vInt2);
            code.Add(innerBlock);

            var r = TranslateGeneratedCode(target, code);

            Assert.IsTrue(r.ContainsKey("NumberOfQueryFunctions"), "Number of functions isn't here");
            Assert.IsInstanceOfType(r["NumberOfQueryFunctions"], typeof(int), "# function type");
            Assert.AreEqual(1, r["NumberOfQueryFunctions"], "# of functions");

            Assert.IsTrue(r.ContainsKey("QueryFunctionBlocks"), "Missing query function blocks");
            Assert.IsInstanceOfType(r["QueryFunctionBlocks"], typeof(IEnumerable <IEnumerable <string> >), "Type is incorrect");
            var codeBlocks = r["QueryFunctionBlocks"] as IEnumerable <IEnumerable <string> >;

            Assert.AreEqual(1, codeBlocks.Count(), "Wrong number of code blocks");
        }
예제 #6
0
 public IEnumerable <IStatementCompound> QueryCode()
 {
     for (int i = 0; i < 300; i++)
     {
         var innerBlock = new StatementInlineBlock();
         var vInt2      = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
         vInt2.SetInitialValue("5");
         innerBlock.Add(vInt2);
         yield return(innerBlock);
     }
 }
예제 #7
0
        private QMFuncSource[] GenerateFunction2()
        {
            var fsub = QMFuncUtils.GenerateFunction();

            int[] ints = new int[10];
            var   h    = new QMFuncHeader()
            {
                Arguments = new object[] { }, QM = new QueryModel(new MainFromClause("i", typeof(int), Expression.Constant(ints)), new SelectClause(Expression.Constant(10)))
            };

            h.QMText = h.QM.ToString();
            var f = new QMFuncSource(h);

            var p           = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var st          = new StatementAssign(p, new ValSimple(fsub.Name + "()", typeof(int)));
            var inlineblock = new StatementInlineBlock();

            inlineblock.Add(st);
            inlineblock.Add(new StatementReturn(p));
            f.SetCodeBody(inlineblock);

            return(new QMFuncSource[] { fsub, f });
        }
예제 #8
0
        /// <summary>
        /// Cache the result of a query model into a function.
        /// </summary>
        /// <param name="queryModel"></param>
        /// <param name="qmSource"></param>
        private void VisitQueryModelCache(QueryModel queryModel, IQMFunctionSource qmSource)
        {
            // If we already have the answer for this cache, then we should just re-call the routine.
            if (qmSource.StatementBlock != null)
            {
                Debug.WriteLine("Using previously cached QM result");
                GenerateQMFunctionCall(qmSource);
                return;
            }
            Debug.WriteLine("Cache: Gathering Data");
            Debug.Indent();

            // Since we don't have it cached, we need to re-run things, and carefully watch for
            // everything new that shows up. What shows up will be what we declare as the function
            // body.
            var currentScope      = _codeEnv.CurrentScope;
            var topLevelStatement = new StatementInlineBlock();

            _codeEnv.Add(topLevelStatement);
            _codeEnv.SetCurrentScopeAsResultScope();

            // If this variable has been cached, then return it. Otherwise, mark the cache as filled.
            _codeEnv.Add(new StatementFilter(qmSource.CacheVariableGood));
            _codeEnv.Add(new StatementReturn(qmSource.CacheVariable));
            _codeEnv.Pop();
            _codeEnv.Add(new StatementAssign(qmSource.CacheVariableGood, new ValSimple("true", typeof(bool), null)));

            // Now, run the code to process the query model!

            VisitQueryModelNoCache(queryModel);

            // The result is treated differently depending on it being a sequence or a single value.
            if (qmSource.IsSequence)
            {
                // Push the good values into our cache object.
                if (!(_codeContext.LoopIndexVariable is IDeclaredParameter))
                {
                    throw new InvalidOperationException("Can't deal with anythign that isn't a loop var");
                }
                _codeEnv.Add(new StatementRecordIndicies(ExpressionToCPP.GetExpression(_codeContext.LoopVariable, _codeEnv, _codeContext, MEFContainer), qmSource.CacheVariable));

                // Remember what the loop index variable is, as we are going to need it when we generate the return function!
                qmSource.SequenceVariable(_codeContext.LoopIndexVariable, _codeContext.LoopVariable);
            }
            else
            {
                // This is a specific result. Save just the result and return it.
                // Grab the result, cache it, and return it.
                var rtnExpr = ExpressionToCPP.GetExpression(_codeEnv.ResultValue, _codeEnv, _codeContext, MEFContainer);
                topLevelStatement.Add(new StatementAssign(qmSource.CacheVariable, rtnExpr));

                // If the return is a declared parameter, then it must be actually defined somewhere (we normally don't).
                var declParam = _codeEnv.ResultValue as IDeclaredParameter;
                if (declParam != null)
                {
                    topLevelStatement.Add(declParam, false);
                }
            }

            // Always return the proper value...
            topLevelStatement.Add(new StatementReturn(qmSource.CacheVariable));

            // Now extract the block of code and put it in the function block.
            _codeEnv.CurrentScope = currentScope;
            qmSource.SetCodeBody(topLevelStatement);

            // Reset our state and remove the function code. And put in the function call in its place.
            _codeEnv.Remove(topLevelStatement);
            GenerateQMFunctionCall(qmSource);

            Debug.Unindent();
        }