예제 #1
0
 /// <summary>
 /// Evaluates the specified script node by calling <see cref="ScriptNode.Evaluate"/>
 /// </summary>
 /// <param name="scriptNode">The script node (might be null but should not throw an error)</param>
 /// <returns>The result of the evaluation</returns>
 /// <remarks>The purpose of this method is to allow to hook during the evaluation of all ScriptNode. By default calls <see cref="ScriptNode.Evaluate"/></remarks>
 protected virtual object EvaluateImpl(ScriptNode scriptNode)
 {
     try
     {
         return(scriptNode != null?scriptNode.Evaluate(this) : null);
     }
     catch (ScriptRuntimeException ex) when(this.RenderRuntimeException != null)
     {
         return(this.RenderRuntimeException(ex));
     }
 }
예제 #2
0
        /// <summary>
        /// Evaluates a script node to a string.
        /// </summary>
        /// <param name="Node">Node to evaluate.</param>
        /// <param name="Variables">Variables.</param>
        /// <returns>String result.</returns>
        protected static string EvaluateString(ScriptNode Node, Variables Variables)
        {
            IElement Element = Node.Evaluate(Variables);

            if (Element is StringValue S)
            {
                return(S.Value);
            }
            else
            {
                return(Expression.ToString(Element.AssociatedObjectValue));
            }
        }
예제 #3
0
        public virtual object Evaluate(ScriptNode scriptNode, bool aliasReturnedFunction)
        {
            if (scriptNode == null)
            {
                return(null);
            }

            var previousFunctionCallState = _isFunctionCallDisabled;
            var previousLevel             = _getOrSetValueLevel;
            var previousNode = CurrentNode;

            try
            {
                CurrentNode             = scriptNode;
                _getOrSetValueLevel     = 0;
                _isFunctionCallDisabled = aliasReturnedFunction;
                var result = scriptNode.Evaluate(this);

                // If we are at a top-level evaluation and the result is an enumeration
                // force its evaluation within the current context
                if (previousNode == null &&
                    result is IEnumerable it &&
                    !(result is string)
                    )
                {
                    result = new ScriptArray(it);
                }

                return(result);
            }
            catch (ScriptRuntimeException ex) when(this.RenderRuntimeException != null)
            {
                return(this.RenderRuntimeException(ex));
            }
            catch (Exception ex) when(!(ex is ScriptRuntimeException))
            {
                var toThrow = new ScriptRuntimeException(scriptNode.Span, ex.Message, ex);

                if (RenderRuntimeException != null)
                {
                    return(RenderRuntimeException(toThrow));
                }
                throw toThrow;
            }
            finally
            {
                CurrentNode             = previousNode;
                _getOrSetValueLevel     = previousLevel;
                _isFunctionCallDisabled = previousFunctionCallState;
            }
        }
예제 #4
0
        /// <summary>
        /// Evaluates the specified script node.
        /// </summary>
        /// <param name="scriptNode">The script node.</param>
        /// <param name="aliasReturnedFunction">if set to <c>true</c> and a function would be evaluated as part of this node, return the object function without evaluating it.</param>
        /// <returns>The result of the evaluation.</returns>
        /// <remarks>
        /// <see cref="Result"/> is set to null when calling directly this method.
        /// </remarks>
        public object Evaluate(ScriptNode scriptNode, bool aliasReturnedFunction)
        {
            var previousFunctionCallState = isFunctionCallDisabled;

            try
            {
                isFunctionCallDisabled = aliasReturnedFunction;
                scriptNode?.Evaluate(this);
                var result = Result;
                Result = null;
                return(result);
            }
            finally
            {
                isFunctionCallDisabled = previousFunctionCallState;
            }
        }
예제 #5
0
 /// <summary>
 /// Gets a name from a script node, either by using the name of a variable reference, or evaluating the node to a string.
 /// </summary>
 /// <param name="Node">Node</param>
 /// <param name="Variables">Variables</param>
 /// <returns>Name</returns>
 /// <exception cref="ScriptRuntimeException">If node is not a variable reference, or does not evaluate to a string value.</exception>
 public static string GetName(ScriptNode Node, Variables Variables)
 {
     if (Node is VariableReference Ref)
     {
         return(Ref.VariableName);
     }
     else
     {
         IElement E = Node.Evaluate(Variables);
         if (E.AssociatedObjectValue is string s)
         {
             return(s);
         }
         else
         {
             throw new ScriptRuntimeException("Exepected variable reference or string value.", Node);
         }
     }
 }
예제 #6
0
        /// <summary>
        /// Evaluates the specified script node.
        /// </summary>
        /// <param name="scriptNode">The script node.</param>
        /// <param name="aliasReturnedFunction">if set to <c>true</c> and a function would be evaluated as part of this node, return the object function without evaluating it.</param>
        /// <returns>The result of the evaluation.</returns>
        public virtual object Evaluate(ScriptNode scriptNode, bool aliasReturnedFunction)
        {
            if (scriptNode == null)
            {
                return(null);
            }

            var previousFunctionCallState = _isFunctionCallDisabled;
            var previousLevel             = _getOrSetValueLevel;
            var previousNode = CurrentNode;

            try
            {
                CurrentNode             = scriptNode;
                _getOrSetValueLevel     = 0;
                _isFunctionCallDisabled = aliasReturnedFunction;
                return(scriptNode.Evaluate(this));
            }
            catch (ScriptRuntimeException ex) when(this.RenderRuntimeException != null)
            {
                return(this.RenderRuntimeException(ex));
            }
            catch (Exception ex) when(!(ex is ScriptRuntimeException))
            {
                var toThrow = new ScriptRuntimeException(scriptNode.Span, ex.Message, ex);

                if (RenderRuntimeException != null)
                {
                    return(RenderRuntimeException(toThrow));
                }
                throw toThrow;
            }
            finally
            {
                CurrentNode             = previousNode;
                _getOrSetValueLevel     = previousLevel;
                _isFunctionCallDisabled = previousFunctionCallState;
            }
        }
예제 #7
0
 /// <summary>
 /// Evaluates the specified script node by calling <see cref="ScriptNode.Evaluate"/>
 /// </summary>
 /// <param name="scriptNode">The script node (might be null but should not throw an error)</param>
 /// <returns>The result of the evaluation</returns>
 /// <remarks>The purpose of this method is to allow to hook during the evaluation of all ScriptNode. By default calls <see cref="ScriptNode.Evaluate"/></remarks>
 protected virtual object EvaluateImpl(ScriptNode scriptNode)
 {
     return(scriptNode?.Evaluate(this));
 }
예제 #8
0
 /// <summary>
 /// Evaluates the specified script node by calling <see cref="ScriptNode.Evaluate"/>
 /// </summary>
 /// <param name="scriptNode">The script node (might be null but should not throw an error)</param>
 /// <returns>The result of the evaluation</returns>
 /// <remarks>The purpose of this method is to allow to hook during the evaluation of all ScriptNode. By default calls <see cref="ScriptNode.Evaluate"/></remarks>
 protected virtual object EvaluateImpl(ScriptNode scriptNode)
 {
     return(scriptNode != null?scriptNode.Evaluate(this) : null);
 }
예제 #9
0
        internal static Filter Convert(ScriptNode Conditions, Variables Variables, string Name)
        {
            if (Conditions is null)
            {
                return(null);
            }

            if (Conditions is TernaryOperator Tercery)
            {
                if (Conditions is Operators.Comparisons.Range Range &&
                    Range.MiddleOperand is VariableReference Ref)
                {
                    ScriptNode LO        = Reduce(Range.LeftOperand, Name);
                    ScriptNode RO        = Reduce(Range.RightOperand, Name);
                    string     FieldName = Ref.VariableName;
                    object     Min       = LO.Evaluate(Variables)?.AssociatedObjectValue ?? null;
                    object     Max       = RO.Evaluate(Variables)?.AssociatedObjectValue ?? null;

                    Filter[] Filters = new Filter[2];

                    if (Range.LeftInclusive)
                    {
                        Filters[0] = new FilterFieldGreaterOrEqualTo(Ref.VariableName, Min);
                    }
                    else
                    {
                        Filters[0] = new FilterFieldGreaterThan(Ref.VariableName, Min);
                    }

                    if (Range.RightInclusive)
                    {
                        Filters[1] = new FilterFieldLesserOrEqualTo(Ref.VariableName, Max);
                    }
                    else
                    {
                        Filters[1] = new FilterFieldLesserThan(Ref.VariableName, Max);
                    }

                    return(new FilterAnd(Filters));
                }
            }
            else if (Conditions is BinaryOperator Bin)
            {
                ScriptNode LO = Reduce(Bin.LeftOperand, Name);
                ScriptNode RO = Reduce(Bin.RightOperand, Name);

                if (Conditions is Operators.Logical.And || Conditions is Operators.Dual.And)
                {
                    Filter L = Convert(LO, Variables, Name);
                    Filter R = Convert(RO, Variables, Name);

                    List <Filter> Filters = new List <Filter>();

                    if (L is FilterAnd L2)
                    {
                        Filters.AddRange(L2.ChildFilters);
                    }
                    else
                    {
                        Filters.Add(L);
                    }

                    if (R is FilterAnd R2)
                    {
                        Filters.AddRange(R2.ChildFilters);
                    }
                    else
                    {
                        Filters.Add(R);
                    }

                    return(new FilterAnd(Filters.ToArray()));
                }

                if (Conditions is Operators.Logical.Or || Conditions is Operators.Dual.Or)
                {
                    Filter L = Convert(LO, Variables, Name);
                    Filter R = Convert(RO, Variables, Name);

                    List <Filter> Filters = new List <Filter>();

                    if (L is FilterOr L2)
                    {
                        Filters.AddRange(L2.ChildFilters);
                    }
                    else
                    {
                        Filters.Add(L);
                    }

                    if (R is FilterOr R2)
                    {
                        Filters.AddRange(R2.ChildFilters);
                    }
                    else
                    {
                        Filters.Add(R);
                    }

                    return(new FilterOr(Filters.ToArray()));
                }

                if (LO is VariableReference LVar)
                {
                    string FieldName = LVar.VariableName;
                    object Value     = RO.Evaluate(Variables)?.AssociatedObjectValue ?? null;

                    if (Conditions is Operators.Comparisons.EqualTo ||
                        Conditions is Operators.Comparisons.EqualToElementWise ||
                        Conditions is Operators.Comparisons.IdenticalTo ||
                        Conditions is Operators.Comparisons.IdenticalToElementWise)
                    {
                        return(new FilterFieldEqualTo(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.NotEqualTo ||
                             Conditions is Operators.Comparisons.NotEqualToElementWise)
                    {
                        return(new FilterFieldNotEqualTo(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.GreaterThan)
                    {
                        return(new FilterFieldGreaterThan(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.GreaterThanOrEqualTo)
                    {
                        return(new FilterFieldGreaterOrEqualTo(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.LesserThan)
                    {
                        return(new FilterFieldLesserThan(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.LesserThanOrEqualTo)
                    {
                        return(new FilterFieldLesserOrEqualTo(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.Like Like)
                    {
                        string RegEx = WildcardToRegex(Value is string s ? s : Expression.ToString(Value), "%");
                        Like.TransformExpression += (Expression) => WildcardToRegex(Expression, "%");
                        return(new FilterFieldLikeRegEx(FieldName, RegEx));
                    }
                    else if (Conditions is Operators.Comparisons.NotLike NotLike)
                    {
                        string RegEx = WildcardToRegex(Value is string s ? s : Expression.ToString(Value), "%");
                        NotLike.TransformExpression += (Expression) => WildcardToRegex(Expression, "%");
                        return(new FilterNot(new FilterFieldLikeRegEx(FieldName, RegEx)));
                    }
                }
                else if (RO is VariableReference RVar)
                {
                    string FieldName = RVar.VariableName;
                    object Value     = LO.Evaluate(Variables)?.AssociatedObjectValue ?? null;

                    if (Conditions is Operators.Comparisons.EqualTo ||
                        Conditions is Operators.Comparisons.EqualToElementWise ||
                        Conditions is Operators.Comparisons.IdenticalTo ||
                        Conditions is Operators.Comparisons.IdenticalToElementWise)
                    {
                        return(new FilterFieldEqualTo(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.NotEqualTo ||
                             Conditions is Operators.Comparisons.NotEqualToElementWise)
                    {
                        return(new FilterFieldNotEqualTo(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.GreaterThan)
                    {
                        return(new FilterFieldLesserThan(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.GreaterThanOrEqualTo)
                    {
                        return(new FilterFieldLesserOrEqualTo(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.LesserThan)
                    {
                        return(new FilterFieldGreaterThan(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.LesserThanOrEqualTo)
                    {
                        return(new FilterFieldGreaterOrEqualTo(FieldName, Value));
                    }
                    else if (Conditions is Operators.Comparisons.Like Like)
                    {
                        string RegEx = WildcardToRegex(Value is string s ? s : Expression.ToString(Value), "%");
                        Like.TransformExpression += (Expression) => WildcardToRegex(Expression, "%");
                        return(new FilterFieldLikeRegEx(FieldName, RegEx));
                    }
                    else if (Conditions is Operators.Comparisons.NotLike NotLike)
                    {
                        string RegEx = WildcardToRegex(Value is string s ? s : Expression.ToString(Value), "%");
                        NotLike.TransformExpression += (Expression) => WildcardToRegex(Expression, "%");
                        return(new FilterNot(new FilterFieldLikeRegEx(FieldName, RegEx)));
                    }
                }
            }
            else if (Conditions is UnaryOperator UnOp)
            {
                if (Conditions is Operators.Logical.Not Not)
                {
                    Filter F = Convert(Reduce(Not.Operand, Name), Variables, Name);
                    if (F is FilterNot Not2)
                    {
                        return(Not2.ChildFilter);
                    }
                    else
                    {
                        return(new FilterNot(F));
                    }
                }
            }
            else if (Conditions is VariableReference Ref)
            {
                return(new FilterFieldEqualTo(Ref.VariableName, true));
            }

            return(new FilterCustom <object>(new ScriptNodeFilter(Conditions, Variables).Passes));
        }