Ejemplo n.º 1
0
        /// <summary>
        /// Read variable
        /// </summary>
        public static bool TryProceedSimpleVariable(List <BaseFormulaNode> nodes, ReadOnlySpan <char> formula, ref int index)
        {
            // Read unary minus
            var localIndex = UnaryMinusReader.ReadUnaryMinus(nodes, formula, index, out var isNegativeLocal);

            var numberBuilder = new IndexWatcher();

            for (int i = localIndex; i < formula.Length; i++)
            {
                var ch         = formula[i];
                var isLastChar = i + 1 == formula.Length;

                if (ch.IsSimpleVariable())
                {
                    numberBuilder.Remember(i);

                    if (isLastChar && TryAddSimpleVariable(nodes, formula, numberBuilder, isNegativeLocal))
                    {
                        index = i;
                        return(true);
                    }
                }
                else if (TryAddSimpleVariable(nodes, formula, numberBuilder, isNegativeLocal))
                {
                    index = i - 1;
                    return(true);
                }
                else
                {
                    break;
                }
            }

            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Read word
        /// </summary>
        public static bool TryProceedWord(List <BaseFormulaNode> nodes, ReadOnlySpan <char> formula, ref int index)
        {
            // Read unary minus
            var localIndex = UnaryMinusReader.ReadUnaryMinus(nodes, formula, index, out _);

            // Check out of range
            if (localIndex >= formula.Length)
            {
                return(false);
            }

            // Read word
            if (!_quotes.Contains(formula[localIndex]))
            {
                return(false);
            }

            // Skip start char
            localIndex++;

            var variableBuilder = new IndexWatcher();

            for (int i = localIndex; i < formula.Length; i++)
            {
                var ch = formula[i];

                if (_quotes.Contains(ch))
                {
                    var wordSpan = formula.Slice(variableBuilder.StartIndex.GetValueOrDefault(), variableBuilder.Length);
                    var word     = wordSpan.ToString();

                    var varNode = new WordNode(word);
                    nodes.Add(varNode);

                    index = i;
                    return(true);
                }

                variableBuilder.Remember(i);
            }

            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Read variable
        /// </summary>
        public static bool TryProceedBorderedVariable(List <BaseFormulaNode> nodes, ReadOnlySpan <char> formula, ref int index)
        {
            // Read unary minus
            var localIndex = UnaryMinusReader.ReadUnaryMinus(nodes, formula, index, out var isNegativeLocal);

            // Check out of range
            if (localIndex >= formula.Length)
            {
                return(false);
            }

            // Read variable
            if (formula[localIndex] != START_CHAR)
            {
                return(false);
            }

            // Skip start char
            localIndex++;

            var variableBuilder = new IndexWatcher();

            for (int i = localIndex; i < formula.Length; i++)
            {
                var ch = formula[i];

                if (ch == END_CHAR)
                {
                    var variableSpan = formula.Slice(variableBuilder.StartIndex.GetValueOrDefault(), variableBuilder.Length);
                    var variableName = variableSpan.ToString();
                    AddFormulaNode(nodes, variableName, isNegativeLocal);

                    index = i;
                    return(true);
                }

                variableBuilder.Remember(i);
            }

            return(false);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Read function name
        /// </summary>
        public bool TryProceedFunction(List <BaseFormulaNode> nodes, ReadOnlySpan <char> formula, ref int index)
        {
            // Read unary minus
            var localIndex = UnaryMinusReader.ReadUnaryMinus(nodes, formula, index, out var isNegativeLocal);

            // Read function
            var functionNameBuilder = new NameBuilder();

            for (int fInd = 0; fInd < _functions.Count; fInd++)
            {
                var function = _functions[fInd];

                // Set function name
                functionNameBuilder.Reset(function.Name);

                for (int i = localIndex; i < formula.Length; i++)
                {
                    var ch = formula[i];

                    if (functionNameBuilder.TryRemember(ch))
                    {
                        if (functionNameBuilder.IsFinished && IsBracketNext(formula, i + 1))
                        {
                            var functionNode = new FunctionNode(function, isNegativeLocal);
                            nodes.Add(functionNode);

                            index = i;
                            return(true);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Read open bracket
        /// </summary>
        public static bool TryProceedOpenBracket(List <BaseFormulaNode> nodes, ReadOnlySpan <char> formula, BracketCounters negativeBracketCounters, ref int index)
        {
            // Read unary minus
            var localIndex = UnaryMinusReader.ReadUnaryMinus(nodes, formula, index, out var isNegativeLocal);

            // Check out of range
            if (localIndex >= formula.Length)
            {
                return(false);
            }

            // Check open bracket
            if (formula[localIndex] == OPEN_BRACKET_CHAR)
            {
                if (isNegativeLocal)
                {
                    AddAdditionalNodesForUnaryMinus(nodes);
                }

                // Add bracket
                var bracket = AddOpenBracket(nodes);

                // Is unary minus
                if (isNegativeLocal)
                {
                    negativeBracketCounters.CreateNewCounter();
                }
                else
                {
                    negativeBracketCounters.Proceed(bracket);
                }

                index = localIndex;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Read list
        /// </summary>
        public static bool TryProceedList(List <BaseFormulaNode> nodes, ReadOnlySpan <char> formula, ref int index)
        {
            // Read unary minus
            var localIndex = UnaryMinusReader.ReadUnaryMinus(nodes, formula, index, out _);

            // Check out of range
            if (localIndex >= formula.Length)
            {
                return(false);
            }

            // Read list
            if (formula[localIndex] != OPEN_BRACKET)
            {
                return(false);
            }

            // Skip start char
            localIndex++;

            // List nodes buffer
            var listNodes = new List <BaseFormulaNode>();

            for (int i = localIndex; i < formula.Length; i++)
            {
                var ch = formula[i];

                if (ch == CLOSE_BRACKET)
                {
                    var wordNodesCount   = listNodes.Count(c => c.TypeKey == NodeTypeEnum.Word);
                    var numberNodesCount = listNodes.Count(c => c.TypeKey == NodeTypeEnum.Number);

                    if (numberNodesCount >= wordNodesCount)
                    {
                        var numberList = listNodes
                                         .Where(c => c.TypeKey == NodeTypeEnum.Number).Cast <NumberNode>()
                                         .Select(s => s.Number).ToList();

                        var listNode = new NumberListNode(numberList);
                        nodes.Add(listNode);
                    }
                    else
                    {
                        var wordList = listNodes
                                       .Where(c => c.TypeKey == NodeTypeEnum.Word).Cast <WordNode>()
                                       .Select(s => s.Word).ToList();

                        var listNode = new WordListNode(wordList);
                        nodes.Add(listNode);
                    }

                    index = i;
                    return(true);
                }

                if (NumberReader.TryProceedNumber(listNodes, formula, ref i))
                {
                    continue;
                }

                if (WordReader.TryProceedWord(listNodes, formula, ref i))
                {
                    continue;
                }
            }

            return(false);
        }