<commit_before>﻿using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq.Expressions;
using LinqToTTreeInterfacesLib;
using Remotion.Linq;
using Remotion.Linq.Clauses;
using Remotion.Linq.Clauses.ResultOperators;

namespace LINQToTTreeLib.ResultOperators
{
    /// <summary>
    /// The aggragate operator - implement everything!
    /// </summary>
    [Export(typeof(IQVScalarResultOperator))]
    public class ROAggregate : IQVScalarResultOperator
    {
        /// <summary>
        /// We deal only with the aggregate operator here.
        /// </summary>
        /// <param name="resultOperatorType"></param>
        /// <returns></returns>
        public bool CanHandle(Type resultOperatorType)
        {
            return resultOperatorType == typeof(AggregateFromSeedResultOperator);
        }

        /// <summary>
        /// Deal with the aggregate operator coming in here.
        /// </summary>
        /// <param name="resultOperator"></param>
        /// <param name="queryModel"></param>
        /// <param name="_codeEnv"></param>
        /// <returns></returns>
        public Expression ProcessResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, IGeneratedQueryCode _codeEnv, ICodeContext context, CompositionContainer container)
        {
            ///
            /// Basic code checks
            /// 

            AggregateFromSeedResultOperator a = resultOperator as AggregateFromSeedResultOperator;
            if (a == null)
            {
                throw new ArgumentNullException("result Operator must not be null and must be of type AggregateFromSeedResultOperator!");
            }

            if (a.Func.Parameters.Count != 1)
            {
                throw new InvalidOperationException("Aggregate only allows for a function with one parameters!");
            }

            if (a.OptionalResultSelector != null)
            {
                throw new NotImplementedException("Can't do a selector function yet");
            }

            ///
            /// We need to declare a variable to hold the seed and its updates - the accumulator
            /// We then need to write the code that does the update to the seed.
            /// Finally, if there is a final funciton, we need to call that after the loop is done!
            ///

            throw new NotImplementedException();
#if false
            IVariable accumulator = null;
            if (a.Seed.Type.IsPointerType())
            {
                accumulator = new Variables.VarObject(a.Seed.Type);
            }
            else
            {
                accumulator = new Variables.VarSimple(a.Seed.Type);
            }
            accumulator.InitialValue = ExpressionToCPP.GetExpression(a.Seed, _codeEnv, context, container);
            accumulator.Declare = true;

            ///
            /// Now, parse the lambda expression, doing a substitution with this guy! Note that the only argument is our
            /// accumulator - the other arguments have all been replaced with subqueryexpressions and the like!
            /// 

            var p1 = context.Add(a.Func.Parameters[0].Name, accumulator.AsExpression());
            var funcResolved = ExpressionToCPP.GetExpression(a.Func.Body, _codeEnv, context, container);
            p1.Pop();

            _codeEnv.Add(new Statements.StatementAggregate(accumulator, funcResolved));

            return Expression.Variable(accumulator.Type, accumulator.RawValue);
#endif

        }
    }
}<commit_msg>Convert to correctly use expressions.<commit_after>﻿using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq.Expressions;
using LinqToTTreeInterfacesLib;
using LINQToTTreeLib.Expressions;
using Remotion.Linq;
using Remotion.Linq.Clauses;
using Remotion.Linq.Clauses.ResultOperators;

namespace LINQToTTreeLib.ResultOperators
{
    /// <summary>
    /// The aggragate operator - implement everything!
    /// </summary>
    [Export(typeof(IQVScalarResultOperator))]
    public class ROAggregate : IQVScalarResultOperator
    {
        /// <summary>
        /// We deal only with the aggregate operator here.
        /// </summary>
        /// <param name="resultOperatorType"></param>
        /// <returns></returns>
        public bool CanHandle(Type resultOperatorType)
        {
            return resultOperatorType == typeof(AggregateFromSeedResultOperator);
        }

        /// <summary>
        /// Deal with the aggregate operator coming in here.
        /// </summary>
        /// <param name="resultOperator"></param>
        /// <param name="queryModel"></param>
        /// <param name="_codeEnv"></param>
        /// <returns></returns>
        public Expression ProcessResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, IGeneratedQueryCode _codeEnv, ICodeContext context, CompositionContainer container)
        {
            ///
            /// Basic code checks
            /// 

            AggregateFromSeedResultOperator a = resultOperator as AggregateFromSeedResultOperator;
            if (a == null)
            {
                throw new ArgumentNullException("result Operator must not be null and must be of type AggregateFromSeedResultOperator!");
            }

            if (a.Func.Parameters.Count != 1)
            {
                throw new InvalidOperationException("Aggregate only allows for a function with one parameters!");
            }

            if (a.OptionalResultSelector != null)
            {
                throw new NotImplementedException("Can't do a selector function yet");
            }

            ///
            /// We need to declare a variable to hold the seed and its updates - the accumulator
            /// We then need to write the code that does the update to the seed.
            /// Finally, if there is a final funciton, we need to call that after the loop is done!
            ///

            var accumulator = DeclarableParameter.DeclarableParameterExpression(a.Seed.Type);
            accumulator.InitialValue = ExpressionToCPP.GetExpression(a.Seed, _codeEnv, context, container).RawValue;

            ///
            /// Now, parse the lambda expression, doing a substitution with this guy! Note that the only argument is our
            /// accumulator - the other arguments have all been replaced with subqueryexpressions and the like!
            /// 

            var p1 = context.Add(a.Func.Parameters[0].Name, accumulator);
            var funcResolved = ExpressionToCPP.GetExpression(a.Func.Body, _codeEnv, context, container);
            p1.Pop();

            _codeEnv.Add(new Statements.StatementAggregate(accumulator, funcResolved));

            return accumulator;
        }
    }
}
{'fraction_non_alphanumeric': 0.09354413702239789, 'fraction_numerical': 0.0011711316059142146, 'mean_word_length': 2.123914037494284, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6611223', 'n_tokens_mistral': 1689, 'n_tokens_neox': 1654, 'n_words': 484}