Ejemplo n.º 1
0
 /// <summary>
 /// Add to the current pattern a new pattern symbol that matches all elements
 /// </summary>
 /// <typeparam name="TKey">Key type</typeparam>
 /// <typeparam name="TPayload">Payload type</typeparam>
 /// <typeparam name="TRegister">Result type (output of matcher is the register at an accepting state of the AFA)</typeparam>
 /// <typeparam name="TAccumulator">Accumulator type</typeparam>
 /// <param name="source">Input pattern</param>
 /// <param name="accumulatorInitialization">Initializer function for the accumulator</param>
 /// <param name="accumulatorBoolField"></param>
 /// <param name="fence">Condition that must be true for the transition to occur</param>
 /// <returns>The newly constructed pattern</returns>
 public static IPattern <TKey, TPayload, TRegister, TAccumulator> AllElement <TKey, TPayload, TRegister, TAccumulator>(
     this IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator> source,
     Expression <Func <TAccumulator> > accumulatorInitialization,
     Expression <Func <TAccumulator, bool> > accumulatorBoolField,
     Expression <Func <long, TPayload, TRegister, bool> > fence)
 {
     return(CreateMultiElementFunctions(source, accumulatorInitialization, accumulatorBoolField, fence, true, b => !b));
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Add to the current pattern a new pattern symbol that matches any element
        /// </summary>
        /// <typeparam name="TKey">Key type</typeparam>
        /// <typeparam name="TPayload">Payload type</typeparam>
        /// <typeparam name="TRegister">Result type (output of matcher is the register at an accepting state of the AFA)</typeparam>
        /// <param name="source">Input pattern</param>
        /// <param name="fence">Condition that must be true for the transition to occur</param>
        /// <returns>The newly constructed pattern</returns>
        public static IPattern <TKey, TPayload, TRegister, bool> AnyElement <TKey, TPayload, TRegister>(
            this IAbstractPatternRoot <TKey, TPayload, TRegister, bool> source,
            Expression <Func <long, TPayload, TRegister, bool> > fence)
        {
            Expression <Func <long, TPayload, TRegister, bool, bool> > fenceTemplate = (ts, ev, reg, acc) => CallInliner.Call(fence, ts, ev, reg);

            return(source.MultiElement((ts, reg) => false, fenceTemplate.InlineCalls(), (ts, ev, acc) => acc, (ts, acc, reg) => acc, null, null));
        }
Ejemplo n.º 3
0
        private static IPattern <TKey, TPayload, TRegister, TAccumulator> CreateMultiElementFunctions <TKey, TPayload, TRegister, TAccumulator>(IAbstractPatternRoot <TKey, TPayload, TRegister, TAccumulator> source, Expression <Func <TAccumulator> > accumulatorInitialization, Expression <Func <TAccumulator, bool> > accumulatorboolField, Expression <Func <long, TPayload, TRegister, bool> > fence, bool initialValueForBooleanField, Expression <Func <bool, bool> > shortCircuitCondition)
        {
            if (!(accumulatorboolField.Body is MemberExpression memberExpression))
            {
                throw new InvalidOperationException("accumulatorboolField must be a lambda that picks out one field from its parameter");
            }
            if (!(memberExpression.Expression is ParameterExpression parameter))
            {
                throw new InvalidOperationException("accumulatorboolField must be a lambda that picks out one field from its parameter");
            }
            var memberInfo = memberExpression.Member;

            if (memberInfo is System.Reflection.PropertyInfo propertyInfo && !propertyInfo.CanWrite)
            {
                throw new InvalidOperationException("accumulatorboolField is specifying a property, " + propertyInfo.Name + "' that does not have a setter");
            }

            // "f" is the field specified by the accumulatorboolField lambda.
            // Create the Initialize function as (ts, reg) => { var acc = accumulatorInitialization(); acc.f = initialValueForBooleanField; return acc; }
            Expression <Func <long, TRegister, TAccumulator> > initializeTemplate = (ts, reg) => CallInliner.Call(accumulatorInitialization);
            var userInitializeFunction        = initializeTemplate.InlineCalls();
            var accumulatorLocalForInitialize = Expression.Parameter(typeof(TAccumulator), "acc");
            var initializeBody = new List <Expression>()
            {
                Expression.Assign(accumulatorLocalForInitialize, userInitializeFunction.Body),
                Expression.Assign(Expression.MakeMemberAccess(accumulatorLocalForInitialize, memberInfo), Expression.Constant(initialValueForBooleanField, typeof(bool))),
                accumulatorLocalForInitialize
            };
            var initializeFunction = (Expression <Func <long, TRegister, TAccumulator> >)Expression.Lambda(
                Expression.Block(new[] { accumulatorLocalForInitialize }, initializeBody),
                Expression.Parameter(typeof(long), "ts"), Expression.Parameter(typeof(TRegister), "reg"));

            // Create the Accumulate function as (ts, ev, reg, acc) => { acc.f = fence(ts, ev, reg); return acc; }
            Expression <Func <long, TPayload, TRegister, TAccumulator, bool> > userAccumulatorFunctionTemplate = (ts, ev, reg, acc) => CallInliner.Call(fence, ts, ev, reg);
            var userAccumulatorFunction = userAccumulatorFunctionTemplate.InlineCalls();
            var accParmeter             = userAccumulatorFunction.Parameters[3];
            var accumulateBody          = new List <Expression>()
            {
                Expression.Assign(Expression.MakeMemberAccess(accParmeter, memberInfo), userAccumulatorFunction.Body), accParmeter,
            };
            var parameters = new ParameterExpression[]
            {
                userAccumulatorFunction.Parameters[0],
                userAccumulatorFunction.Parameters[1],
                userAccumulatorFunction.Parameters[2],
                accParmeter,
            };
            var accumulateFunction = (Expression <Func <long, TPayload, TRegister, TAccumulator, TAccumulator> >)Expression.Lambda(Expression.Block(accumulateBody), parameters);

            // Create the SkipToEnd function as (ts, ev, acc) => acc.f
            Expression <Func <long, TPayload, TAccumulator, bool> > skipToEndTemplate = (ts, ev, acc) => CallInliner.Call(shortCircuitCondition, CallInliner.Call(accumulatorboolField, acc));
            var skipToEndFunction = skipToEndTemplate.InlineCalls();

            // Create the fence function as (ts, acc, reg) => acc.f
            Expression <Func <long, TAccumulator, TRegister, bool> > fenceTemplate = (ts, acc, reg) => CallInliner.Call(accumulatorboolField, acc);
            var fenceFunction = fenceTemplate.InlineCalls();

            return(source.MultiElement(initializeFunction, accumulateFunction, skipToEndFunction, fenceFunction, null, null));
        }