Пример #1
0
        /// <summary>
        /// Applies beta reduction on invocation expressions in the given expression, using the specified configuration flags.
        /// This is an advanced method which should be used with care when side-effects in expression trees are critical to maintain.
        /// Some configurations may lead to changes in timing and the arity of side-effects.
        /// </summary>
        /// <param name="expression">Expression to apply beta reductions on.</param>
        /// <param name="nodeTypes">Flags to restrict the argument expression node types that will be inlined during beta reduction. (Default: Atoms)</param>
        /// <param name="restrictions">Flags to restrict the number of uses of each argument expression during inlining. (Default: None)</param>
        /// <returns>Expression after applying beta reductions.</returns>
        public static Expression Reduce(Expression expression, BetaReductionNodeTypes nodeTypes, BetaReductionRestrictions restrictions)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            return(ReduceCore(expression, nodeTypes, restrictions));
        }
Пример #2
0
            public BetaReductionExpressionVisitor(BetaReductionNodeTypes nodeTypes, BetaReductionRestrictions restrictions)
            {
                _includeConstant    = (nodeTypes & BetaReductionNodeTypes.Constant) != 0;
                _includeDefault     = (nodeTypes & BetaReductionNodeTypes.Default) != 0;
                _includeParameter   = (nodeTypes & BetaReductionNodeTypes.Parameter) != 0;
                _includeQuote       = (nodeTypes & BetaReductionNodeTypes.Quote) != 0;
                _includeMolecules   = (nodeTypes & BetaReductionNodeTypes.Molecules) != 0;
                _inDangerOfCaptures = _includeParameter | _includeQuote | _includeMolecules;

                _disallowDiscard  = (restrictions & BetaReductionRestrictions.DisallowDiscard) != 0;
                _disallowMultiple = (restrictions & BetaReductionRestrictions.DisallowMultiple) != 0;
            }
Пример #3
0
        /// <summary>
        /// Applies beta reduction on invocation expressions in the given expression, using the specified configuration flags, until no further reductions are possible.
        /// This is an advanced method which should be used with care when side-effects in expression trees are critical to maintain.
        /// Some configurations may lead to changes in timing and the arity of side-effects.
        /// </summary>
        /// <param name="expression">Expression to apply beta reductions on.</param>
        /// <param name="nodeTypes">Flags to restrict the argument expression node types that will be inlined during beta reduction.</param>
        /// <param name="restrictions">Flags to restrict the number of uses of each argument expression during inlining.</param>
        /// <param name="throwOnCycle">Indicates whether to throw an exception if the reduction gets stuck in a cyclic reduction (e.g. for a recursive lambda expression). If set to false, the reduction stops and the current expression is returned.</param>
        /// <returns>Expression after applying beta reductions.</returns>
        public static Expression ReduceEager(Expression expression, BetaReductionNodeTypes nodeTypes, BetaReductionRestrictions restrictions, bool throwOnCycle)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            var history = new HashSet <Expression>(new ExpressionEqualityComparer());

            var current = expression;
            var reduced = default(Expression);

            var i = 0;

            while (current != reduced)
            {
                if (!history.Add(current))
                {
                    if (throwOnCycle)
                    {
                        throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Irreducible recursive lambda expression detected: '{0}'.", current));
                    }
                    else
                    {
                        break;
                    }
                }

                reduced = current;
                current = ReduceCore(current, nodeTypes, restrictions);

                i++;
            }

            return(current);
        }
Пример #4
0
 private static Expression ReduceCore(Expression expression, BetaReductionNodeTypes nodeTypes, BetaReductionRestrictions restrictions) => new BetaReductionExpressionVisitor(nodeTypes, restrictions).Visit(expression);