public void NumberAddition() { var exp = new QueryExpressionNode( new QueryExpressionNode(4.AsJsonElement()), Operators.Addition, new QueryExpressionNode(5.AsJsonElement()) ); Assert.AreEqual(QueryExpressionType.Number, exp.OutputType); Assert.IsTrue(9.AsJsonElement().IsEquivalentTo(exp.Evaluate(default)));
public static string MaybeAddParentheses(this QueryExpressionNode node, int operationOrder, bool overrideIfSame = false) { var asString = node.ToString(); if (operationOrder < node.Operator?.OrderOfOperation) { asString = $"({asString})"; } if (overrideIfSame && operationOrder == node.Operator?.OrderOfOperation) { asString = $"({asString})"; } return(asString); }
// expects the full expression, including the () public static bool TryParseExpression(this ReadOnlySpan <char> span, ref int i, out QueryExpressionNode expression) { var index = i; if (span[index] != '(') { expression = null; return(false); } index++; if (!QueryExpressionNode.TryParseSingleValue(span, ref index, out var left)) { expression = null; return(false); } var followingNodes = new List <(IQueryExpressionOperator, QueryExpressionNode)>(); while (index < span.Length && span[index] != ')') { if (!Operators.TryParse(span, ref index, out var op)) { expression = null; return(false); } QueryExpressionNode right; if (span[index] == '(') { if (!span.TryParseExpression(ref index, out right)) { expression = null; return(false); } } else if (!QueryExpressionNode.TryParseSingleValue(span, ref index, out right)) { expression = null; return(false); } followingNodes.Add((op, right)); } if (!followingNodes.Any()) { i = index; expression = new QueryExpressionNode(left, Operators.Exists, null); return(true); } var current = new Stack <QueryExpressionNode>(); QueryExpressionNode root = null; foreach (var(op, node) in followingNodes) { if (root == null) { root = new QueryExpressionNode(left, op, node); current.Push(root); continue; } while (current.Any() && current.Peek().Operator.OrderOfOperation < op.OrderOfOperation) { current.Pop(); } if (current.Any()) { current.Peek().InsertRight(op, node); continue; } root = new QueryExpressionNode(root, op, node); current.Push(root); } i = index; expression = root; return(true); }
public ItemQueryIndex(QueryExpressionNode expression) { _expression = expression; }
internal ContainerQueryIndex(QueryExpressionNode expression) { _expression = expression; }
private ItemQueryIndex(QueryExpressionNode expression) { _expression = expression; }
private ContainerQueryIndex(QueryExpressionNode expression) { _expression = expression; }
// expects the full expression, including the () public static bool TryParseExpression(this ReadOnlySpan <char> span, ref int i, [NotNullWhen(true)] out QueryExpressionNode?expression) { if (span[i] != '(') { expression = null; return(false); } i++; span.ConsumeWhitespace(ref i); if (!QueryExpressionNode.TryParseSingleValue(span, ref i, out var left)) { expression = null; return(false); } var followingNodes = new List <(IQueryExpressionOperator, QueryExpressionNode)>(); while (i < span.Length && span[i] != ')') { span.ConsumeWhitespace(ref i); if (!Operators.TryParse(span, ref i, out var op)) { expression = null; return(false); } QueryExpressionNode?right; span.ConsumeWhitespace(ref i); if (span[i] == '(') { span.ConsumeWhitespace(ref i); if (!span.TryParseExpression(ref i, out right)) { expression = null; return(false); } } else { span.ConsumeWhitespace(ref i); if (!QueryExpressionNode.TryParseSingleValue(span, ref i, out right)) { expression = null; return(false); } } followingNodes.Add((op, right)); } i++; // consume ')' if (!followingNodes.Any()) { expression = left.Operator is NotOperator ? left : new QueryExpressionNode(left, Operators.Exists, null !); return(true); } var current = new Stack <QueryExpressionNode>(); QueryExpressionNode?root = null; foreach (var(op, node) in followingNodes) { if (root == null) { root = new QueryExpressionNode(left, op, node); current.Push(root); continue; } while (current.Any() && current.Peek().Operator?.OrderOfOperation < op.OrderOfOperation) { current.Pop(); } if (current.Any()) { current.Peek().InsertRight(op, node); continue; } root = new QueryExpressionNode(root, op, node); current.Push(root); } expression = root; return(expression != null); }