Beispiel #1
0
 private void ValidateNumberFormatter(INumberBoxNumberFormatter value)
 {
     if (value is null)
     {
         throw new ArgumentNullException(nameof(value));
     }
 }
Beispiel #2
0
        public static double?Compute(string expr, INumberBoxNumberFormatter numberParser)
        {
            // Tokenize the input string
            var tokens = GetTokens(expr, numberParser);

            if (tokens.Count > 0)
            {
                // Rearrange to postfix notation
                var postfixTokens = ConvertInfixToPostfix(tokens);
                if (postfixTokens.Count > 0)
                {
                    // Compute expression
                    return(ComputePostfixExpression(postfixTokens));
                }
            }

            return(null);
        }
Beispiel #3
0
        static (double, int) GetNextNumber(string input, INumberBoxNumberFormatter numberParser)
        {
            // Attempt to parse anything before an operator or space as a number
            Regex regex = new Regex("^-?([^-+/*\\(\\)\\^\\s]+)");
            Match match = regex.Match(input);

            if (match.Success)
            {
                // Might be a number
                var matchLength = match.Value.Length;
                var parsedNum   = numberParser.ParseDouble(input.Substring(0, matchLength));

                if (parsedNum.HasValue)
                {
                    // Parsing was successful
                    return(parsedNum.Value, matchLength);
                }
            }

            return(double.NaN, 0);
        }
Beispiel #4
0
        static IList <MathToken> GetTokens(string input, INumberBoxNumberFormatter numberParser)
        {
            var tokens = new List <MathToken>();

            bool expectNumber = true;

            while (input.Length > 0)
            {
                // Skip spaces
                var nextChar = input[0];
                if (nextChar != ' ')
                {
                    if (expectNumber)
                    {
                        if (nextChar == '(')
                        {
                            // Open parens are also acceptable, but don't change the next expected token type.
                            tokens.Add(new MathToken(MathTokenType.Parenthesis, nextChar));
                        }
                        else
                        {
                            var(value, charLength) = GetNextNumber(input, numberParser);

                            if (charLength > 0)
                            {
                                tokens.Add(new MathToken(MathTokenType.Numeric, value));
                                input        = input.SafeSubstring(charLength - 1); // advance the end of the token
                                expectNumber = false;                               // next token should be an operator
                            }
                            else
                            {
                                // Error case -- next token is not a number
                                return(s_emptyTokens);
                            }
                        }
                    }
                    else
                    {
                        if (c_numberBoxOperators.IndexOf(nextChar) >= 0)
                        {
                            tokens.Add(new MathToken(MathTokenType.Operator, nextChar));
                            expectNumber = true; // next token should be a number
                        }
                        else if (nextChar == ')')
                        {
                            // Closed parens are also acceptable, but don't change the next expected token type.
                            tokens.Add(new MathToken(MathTokenType.Parenthesis, nextChar));
                        }
                        else
                        {
                            // Error case -- could not evaluate part of the expression
                            return(s_emptyTokens);
                        }
                    }
                }

                input = input.SafeSubstring(1);
            }

            return(tokens);
        }