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);
        }
Example #3
0
        // 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;
		}
Example #8
0
        // 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);
        }