/// <summary> /// Evaluate expression children and return them. /// </summary> /// <param name="expression">Expression with children.</param> /// <param name="state">Global state.</param> /// <param name="options">Options used in evaluation. </param> /// <param name="verify">Optional function to verify each child's result.</param> /// <returns>List of child values or error message.</returns> public static (IReadOnlyList <object>, string error) EvaluateChildren(Expression expression, IMemory state, Options options, VerifyExpression verify = null) { var args = new List <object>(); object value; string error = null; var pos = 0; foreach (var child in expression.Children) { (value, error) = child.TryEvaluate(state, options); if (error != null) { break; } if (verify != null) { error = verify(value, child, pos); } if (error != null) { break; } args.Add(value); ++pos; } return(args, error); }
// Apply -- these are helpers for adding functions to the expression library. /// <summary> /// Generate an expression delegate that applies function after verifying all children. /// </summary> /// <param name="function">Function to apply.</param> /// <param name="verify">Function to check each arg for validity.</param> /// <returns>Delegate for evaluating an expression.</returns> public static EvaluateExpressionDelegate Apply(Func <IReadOnlyList <object>, object> function, VerifyExpression verify = null) => (expression, state, options) => { object value = null; string error = null; IReadOnlyList <object> args; (args, error) = EvaluateChildren(expression, state, options, verify); if (error == null) { try { value = function(args); } #pragma warning disable CA1031 // Do not catch general exception types (capture any exception and return it in the error) catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { error = e.Message; } } value = ResolveValue(value); return(value, error); };
// Apply -- these are helpers for adding functions to the expression library. /// <summary> /// Generate an expression delegate that applies function after verifying all children. /// </summary> /// <param name="function">Function to apply.</param> /// <param name="verify">Function to check each arg for validity.</param> /// <returns>Delegate for evaluating an expression.</returns> public static EvaluateExpressionDelegate Apply(Func <IReadOnlyList <object>, object> function, VerifyExpression verify = null) => (expression, state, options) => { object value = null; string error = null; IReadOnlyList <object> args; (args, error) = EvaluateChildren(expression, state, options, verify); if (error == null) { try { value = function(args); } catch (Exception e) { error = e.Message; } } value = ResolveValue(value); return(value, error); };