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