/// <summary>
        /// Calculates value of the expression of many variables.
        /// </summary>
        /// <param name="variables">Variables</param>
        /// <returns>Value of the expression</returns>
        public double Calculate(params Var[] variables)
        {
            Stack stack = new Stack();

            foreach (Token t in reversePolishNotation)
            {
                if (t.Type == TokenType.Number)
                {
                    stack.Push(t);
                }
                else if (t.Type == TokenType.Operator)
                {
                    string operand1Str = stack.Pop().Lexeme.Replace(',', '.');
                    string operand2Str = stack.Pop().Lexeme.Replace(',', '.');
                    double operand1 = double.Parse(operand1Str, CultureInfo.InvariantCulture);
                    double operand2 = double.Parse(operand2Str, CultureInfo.InvariantCulture);
                    double smallResult = operators[t.Lexeme](operand1, operand2);
                    stack.Push(new Token(smallResult.ToString(CultureInfo.InvariantCulture), TokenType.Number));
                }
                else if (t.Type == TokenType.Function)
                {
                    string operandStr = stack.Pop().Lexeme.Replace(',', '.');
                    double operand = double.Parse(operandStr, CultureInfo.InvariantCulture);
                    double smallResult = functions[t.Lexeme](operand);
                    stack.Push(new Token(smallResult.ToString(CultureInfo.InvariantCulture), TokenType.Number));
                }
                else if (t.Type == TokenType.Constant)
                {
                    double constant = constants[t.Lexeme];
                    stack.Push(new Token(constant.ToString(CultureInfo.InvariantCulture), TokenType.Number));
                }
                else if (t.Type == TokenType.Variable)
                {
                    Token smallToken = new Token();

                    foreach (Var variable in variables)
                    {
                        if (t.Lexeme == variable.Name)
                        {
                            smallToken = new Token(variable.Value.ToString(CultureInfo.InvariantCulture), TokenType.Number);
                            break;
                        }
                    }

                    stack.Push(smallToken);
                }
                else
                {
                    throw new ArgumentException("Bad expression string.");
                }
            }

            double result = double.Parse(stack.Pop().Lexeme, CultureInfo.InvariantCulture);

            return result;
        }
Exemple #2
0
 /// <summary>
 /// Adds a token to the top of stack.
 /// </summary>
 /// <param name="t">Token to add</param>
 public void Push(Token t)
 {
     tokens.Add(t);
 }
        /// <summary>
        /// Parses a string of characters and converts it to sequence of tokens.
        /// </summary>
        /// <returns>Sequence of tokens</returns>
        private List<Token> GetTokens(string expression)
        {
            List<Token> tokens = new List<Token>();

            bool isError;
            bool success;
            for (int i = 0; i < expression.Length; ++i)
            {
                isError = true;
                success = false;

                string number = "";
                double num;
                while (double.TryParse(expression[i].ToString(CultureInfo.InvariantCulture), System.Globalization.NumberStyles.Number, CultureInfo.InvariantCulture, out num) || expression[i] == '.')
                {
                    if (expression[i] == '.')
                    {
                        number += ".";
                    }
                    else
                    {
                        number += num.ToString(CultureInfo.InvariantCulture);
                    }

                    if (i < expression.Length - 1)
                    {
                        ++i;
                    }
                    else break;
                }
                if (number != "")
                {
                    Token t = new Token(number, TokenType.Number);
                    tokens.Add(t);
                    success = true;
                    isError = false;
                    number = "";
                }

                foreach (string s in operators.Keys)
                {
                    if (expression[i].ToString(CultureInfo.InvariantCulture) == s)
                    {
                        if (isUnaryOparator(tokens))
                        {      
                            expression = expression.Insert(i, "0");
                            --i;
                        }
                        else
                        {
                            Token t = new Token(expression[i].ToString(CultureInfo.InvariantCulture), TokenType.Operator);
                            tokens.Add(t);
                        }
                        success = true;
                        isError = false;                        
                        break;
                    }
                }

                foreach (string s in functions.Keys)
                {
                    if (success)
                    {
                        break;
                    }

                    string function = "";

                    int k = i;
                    for (int j = 0; j < s.Length; ++j)
                    {
                        if (s[j] == expression[k])
                        {
                            function += expression[k];
                        }
                        if (k < expression.Length - 1)
                        {
                            ++k;
                        }
                        else break;
                    }
                    if (function == s)
                    {
                        Token t = new Token(function, TokenType.Function);
                        tokens.Add(t);
                        isError = false;
                        success = true;
                        i += function.Length - 1;
                        break;
                    }
                }

                foreach (string s in constants.Keys)
                {
                    if (success)
                    {
                        break;
                    }

                    string constant = "";

                    int k = i;
                    for (int j = 0; j < s.Length; ++j)
                    {
                        if (s[j] == expression[k])
                        {
                            constant += expression[k];
                        }
                        if (k < expression.Length - 1)
                        {
                            ++k;
                        }
                        else break;
                    }
                    if (constant == s)
                    {
                        Token t = new Token(constant, TokenType.Constant);
                        tokens.Add(t);
                        isError = false;
                        success = true;
                        i += constant.Length - 1;
                        break;
                    }
                }

                foreach (char c in variables)
                {
                    if (success)
                    {
                        break;
                    }

                    if (expression[i] == c)
                    {
                        Token t = new Token(expression[i].ToString(CultureInfo.InvariantCulture), TokenType.Variable);
                        tokens.Add(t);
                        isError = false;
                        success = true;
                        break;
                    }
                }

                if (isError)
                {
                    throw new ArgumentException("Bad expression string.");
                }
            }

            return tokens;
        }