/// <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)); } }
/// <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)); } }
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; } }
/// <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; } }
/// <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); } } }
/// <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; } }
/// <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)); }
/// <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); }
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)); }