/// <summary>
        /// Gets or sets a context item.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public Token this[string key]
        {
            get
            {
                Token token = new NullToken();

                if (_values.ContainsKey(key))
                {
                    token = (Token)_values[key];
                }

                return(token);
            }
            set
            {
                if (!_values.ContainsKey(key))
                {
                    _values.Add(key, value);
                }
                else
                {
                    if (value == null)
                    {
                        _values.Remove(key);
                    }
                    else
                    {
                        _values[key] = value;
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Gets a Token of type AssignmentToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (AssignmentOperatorToken.__assignmentPattern.IsMatch(line))
            {
                token = new AssignmentOperatorToken();
            }

            return(token);
        }
        /// <summary>
        /// Gets a Token of type PerenthesisToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (RangeDelimiterToken.__rangeDelimiterTokenPattern.IsMatch(line))
            {
                string matchText = RangeDelimiterToken.__rangeDelimiterTokenPattern.Matches(line)[0].Value;

                token = new RangeDelimiterToken(matchText);
            }

            return(token);
        }
예제 #4
0
        /// <summary>
        /// Gets a Token of type OperatorToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (BooleanOperatorToken.__operatorPattern.IsMatch(line))
            {
                string matchText = BooleanOperatorToken.__operatorPattern.Matches(line)[0].Value;

                token = new BooleanOperatorToken(matchText);
            }

            return(token);
        }
예제 #5
0
        /// <summary>
        /// Gets a Token of type CommentToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (CommentToken.__commentPattern.IsMatch(line))
            {
                string matchText = CommentToken.__commentPattern.Matches(line)[0].Value;

                token = new CommentToken(matchText);
            }

            return(token);
        }
예제 #6
0
        /// <summary>
        /// Gets a Token of type NumberToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (VariableToken.__variablePattern.IsMatch(line))
            {
                string matchText = VariableToken.__variablePattern.Matches(line)[0].Value;

                token = new VariableToken(matchText);
            }

            return(token);
        }
예제 #7
0
        /// <summary>
        /// Attempts to parse a token and returns success or failure.
        /// </summary>
        /// <param name="line">String from which to take the next token.</param>
        /// <param name="token">Out parameter to send token to if successful.</param>
        /// <returns></returns>
        public new static bool TryParse(string line, out Token token)
        {
            bool parseSuccessful = false;

            token = new NullToken();

            if ((token = Parse(line)) is VariableToken)
            {
                parseSuccessful = true;
            }

            return(parseSuccessful);
        }
        /// <summary>
        /// Attempts to parse a token and returns success or failure.
        /// </summary>
        /// <param name="line">String from which to take the next token.</param>
        /// <param name="token">Out parameter to send token to if successful.</param>
        /// <returns></returns>
        public static bool TryParse(string line, out Token token)
        {
            bool parseSuccessful = false;

            token = new NullToken();

            if ((token = Parse(line)) is InfixFunctionToken)
            {
                parseSuccessful = true;
            }

            return(parseSuccessful);
        }
        /// <summary>
        /// Gets a Token of type InfixFunctionToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (InfixFunctionToken.__functionPattern.IsMatch(line))
            {
                string matchText = InfixFunctionToken.__functionPattern.Matches(line)[0].Value;

                token = new InfixFunctionToken(matchText);
            }

            return(token);
        }
        /// <summary>
        /// Attempts to parse a token and returns success or failure.
        /// </summary>
        /// <param name="line">String from which to take the next token.</param>
        /// <param name="token">Out parameter to send token to if successful.</param>
        /// <returns></returns>
        public static bool TryParse(string line, out Token token)
        {
            bool parseSuccessful = false;

            token = new NullToken();

            if ((token = Parse(line)) is RangeDelimiterToken)
            {
                parseSuccessful = true;
            }

            return(parseSuccessful);
        }
예제 #11
0
        /// <summary>
        /// Gets a Token of type NumberToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public static Token ParseAsConstant(string line)
        {
            Token token = new NullToken();

            if (NumberToken.__numberPattern.IsMatch(line))
            {
                string matchText = NumberToken.__numberPattern.Matches(line)[0].Value;

                token = new NumberToken(matchText, "$");
            }

            return(token);
        }
예제 #12
0
        /// <summary>
        /// Gets a Token of type NumberToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (NumberToken.__numberPattern.IsMatch(line))
            {
                string matchText = NumberToken.__numberPattern.Matches(line)[0].Value;
                string value     = AsDecimal(matchText);

                token = new NumberToken(value, matchText);
            }

            return(token);
        }
예제 #13
0
        /// <summary>
        /// Evaluates this expression.
        /// </summary>
        /// <returns></returns>
        public override Token Evaluate()
        {
            Token result = new NullToken();
            Token left   = Operands[1].Evaluate();
            Token right  = Operands[0].Evaluate();

            if (left is VariableToken)
            {
                result = right;

                CalculatorContext.GetInstance()[left.ToString()] = result;
            }

            return(result);
        }
예제 #14
0
        /// <summary>
        /// Evaluates this expression.
        /// </summary>
        /// <returns></returns>
        public override Token Evaluate()
        {
            Token  result = new NullToken();
            Token  left   = EvaluateOperand(1);
            Token  right  = EvaluateOperand(0);
            double dLeft  = 0.0;
            double dRight = 0.0;

            if (double.TryParse(left.ToString(), out dLeft) && double.TryParse(right.ToString(), out dRight))
            {
                switch (Precedence)
                {
                case ExpressionPrecedence.Add:
                    result = new NumberToken((dLeft + dRight).ToString());
                    break;

                case ExpressionPrecedence.Subtract:
                    result = new NumberToken((dLeft - dRight).ToString());
                    break;

                case ExpressionPrecedence.MultiplyOrDivide:
                    if (Operation.ToString().Equals("/", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (right.ToString().Equals("0", StringComparison.InvariantCultureIgnoreCase))
                        {
                            throw new DivideByZeroException();
                        }
                        else
                        {
                            result = new NumberToken((dLeft / dRight).ToString());
                        }
                    }
                    else if (Operation.ToString().Equals("*"))
                    {
                        result = new NumberToken((dLeft * dRight).ToString());
                    }
                    break;
                }
            }
            else
            {
                throw new FormatException(String.Format("Could not parse double value from {0} for arithmetic expression.", left.ToString()));
            }

            return(result);
        }
        /// <summary>
        /// Gets a Token of type PrefixFunctionToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (PrefixFunctionToken.__functionPattern.IsMatch(line))
            {
                string matchText = PrefixFunctionToken.__functionPattern.Matches(line)[0].Value;

                if (matchText.Equals("-(", StringComparison.InvariantCultureIgnoreCase))
                {
                    matchText = "-";
                }

                token = new PrefixFunctionToken(matchText);
            }

            return(token);
        }
예제 #16
0
        /// <summary>
        /// Gets a Token of type SetContainerToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (SetContainerToken.__setContainerPattern.IsMatch(line))
            {
                string matchText = SetContainerToken.__setContainerPattern.Matches(line)[0].Value;

                token = new SetContainerToken(matchText);

                if (matchText.Equals("[", StringComparison.InvariantCultureIgnoreCase))
                {
                    ((SetContainerToken)token)._setContainerType = SetContainerTokenType.Open;
                }
                else
                {
                    ((SetContainerToken)token)._setContainerType = SetContainerTokenType.Closed;
                }
            }

            return(token);
        }
예제 #17
0
        /// <summary>
        /// Gets a Token of type PerenthesisToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (PerenthesisToken.__perenPattern.IsMatch(line))
            {
                string matchText = PerenthesisToken.__perenPattern.Matches(line)[0].Value;

                token = new PerenthesisToken(matchText);

                if (matchText.Equals("(", StringComparison.InvariantCultureIgnoreCase))
                {
                    ((PerenthesisToken)token)._perenthesisType = PerenthesisTokenType.Open;
                }
                else
                {
                    ((PerenthesisToken)token)._perenthesisType = PerenthesisTokenType.Closed;
                }
            }

            return(token);
        }
예제 #18
0
        /// <summary>
        /// Gets a Token of type ConstantToken from the beginning of a line of text.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (ConstantToken.__constantPattern.IsMatch(line))
            {
                string matchText = ConstantToken.__constantPattern.Matches(line)[0].Value;

                if (matchText.Equals("e", StringComparison.InvariantCultureIgnoreCase))
                {
                    token = new ConstantToken(Math.E.ToString(), matchText);
                }
                else if (matchText.Equals("pi", StringComparison.InvariantCultureIgnoreCase))
                {
                    token = new ConstantToken(Math.PI.ToString(), matchText);
                }
                else if (matchText.Equals("phi", StringComparison.InvariantCultureIgnoreCase))
                {
                    token = new ConstantToken("1.61803398874989", matchText);
                }
            }

            return(token);
        }
        /// <summary>
        /// Gets a Token of type LastResultToken from the beginning of a line of text. The resulting token
        /// needs to be a value token, like BooleanToken or NumberToken.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public new static Token Parse(string line)
        {
            Token token = new NullToken();

            if (LastResultToken.__constantPattern.IsMatch(line))
            {
                string matchText = LastResultToken.__constantPattern.Matches(line)[0].Value;

                if (matchText.Equals("$", StringComparison.InvariantCultureIgnoreCase))
                {
                    token = new LastResultToken(CalculatorContext.GetInstance().GetLastResult(), matchText);

                    Token intermediateToken = new NullToken();

                    if (NumberToken.TryParse(token.ToString(), out intermediateToken, true) ||
                        BooleanToken.TryParse(token.ToString(), out intermediateToken, true))
                    {
                        token = intermediateToken;
                    }
                }
            }

            return(token);
        }
예제 #20
0
        /// <summary>
        /// Evaluates this expression.
        /// </summary>
        /// <returns></returns>
        public override Token Evaluate()
        {
            Token result = new NullToken();
            Token left   = EvaluateOperand(1);
            Token right  = EvaluateOperand(0);

            if (left is NumberToken && right is NumberToken)
            {
                double dLeft  = 0.0;
                double dRight = 0.0;

                if (double.TryParse(left.ToString(), out dLeft) && double.TryParse(right.ToString(), out dRight))
                {
                    if (Operation.ToString().Equals("==", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((dLeft == dRight).ToString());
                    }
                    else if (Operation.ToString().Equals("<=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((dLeft <= dRight).ToString());
                    }
                    else if (Operation.ToString().Equals(">=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((dLeft >= dRight).ToString());
                    }
                    else if (Operation.ToString().Equals("<", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((dLeft < dRight).ToString());
                    }
                    else if (Operation.ToString().Equals(">", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((dLeft > dRight).ToString());
                    }
                    else if (Operation.ToString().Equals("!=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((dLeft != dRight).ToString());
                    }
                    else
                    {
                        throw new MalformedExpressionException(String.Format("Unknown boolean operator {0}.", Operation));
                    }
                }
                else
                {
                    throw new FormatException(String.Format("Could not parse double value from {0} for boolean expression.", left.ToString()));
                }
            }
            else if (left is BooleanToken && right is BooleanToken)
            {
                bool bLeft  = false;
                bool bRight = false;

                if (bool.TryParse(left.ToString(), out bLeft) && bool.TryParse(right.ToString(), out bRight))
                {
                    if (Operation.ToString().Equals("==", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((bLeft == bRight).ToString());
                    }
                    else if (Operation.ToString().Equals("!=", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((bLeft != bRight).ToString());
                    }
                    else
                    {
                        throw new MalformedExpressionException("Booleans cannot be less than or greater than each other.");
                    }
                }
                else
                {
                    throw new FormatException(String.Format("Could not parse bool value from {0} for boolean expression.", left.ToString()));
                }
            }
            else
            {
                throw new MalformedExpressionException(String.Concat(ToString(), " is not a valid boolean expression."));
            }

            return(result);
        }
예제 #21
0
        /// <summary>
        /// Parses tokens out of the string given.
        /// </summary>
        /// <param name="line"></param>
        private void ParseTokens(string line)
        {
            string          internalLine    = line;
            Regex           spaceRegex      = new Regex("^[\\s]+", RegexOptions.Compiled | RegexOptions.CultureInvariant);
            TokenParseState tokenParseState = new NullTokenParseState();

            while (!String.IsNullOrEmpty(internalLine))
            {
                Token token        = new NullToken();
                bool  tokenIsValid = false;

                if (spaceRegex.IsMatch(internalLine))
                {
                    int length = spaceRegex.Matches(internalLine)[0].Value.Length;

                    internalLine = RemoveToken(length, internalLine);
                }
                else
                {
                    tokenIsValid = tokenParseState.GetNextToken(internalLine, out token, out tokenParseState);

                    #region Old Conditional Code
                    //    if (lastToken is NullToken)
                    //    {
                    //        if (GetFirstToken(internalLine, out token))
                    //        {
                    //            tokenIsValid = true;
                    //        }
                    //        else if (InfixFunctionToken.TryParse(internalLine, out token)
                    //            || ArithmeticOperatorToken.TryParse(internalLine, out token)
                    //            || BinaryOperatorToken.TryParse(internalLine, out token)
                    //            || BooleanOperatorToken.TryParse(internalLine, out token)
                    //            || PostfixFunctionToken.TryParse(internalLine, out token))
                    //        {
                    //            _tokens.Add(CalculatorContext.GetInstance()[CalculatorContext.LastResult]);

                    //            lastToken = _tokens[0];
                    //        }
                    //        else
                    //        {
                    //            throw new InvalidTokenException(String.Format("Invalid or unrecognized token at {0}.", internalLine));
                    //        }
                    //    }
                    //    else if (lastToken is VariableToken)
                    //    {
                    //        if ((PerenthesisToken.TryParse(internalLine, out token) && ((PerenthesisToken)token).PerenthesisType == PerenthesisType.Closed)
                    //            || InfixFunctionToken.TryParse(internalLine, out token)
                    //            || ArithmeticOperatorToken.TryParse(internalLine, out token)
                    //            || BinaryOperatorToken.TryParse(internalLine, out token)
                    //            || BooleanOperatorToken.TryParse(internalLine, out token)
                    //            || PostfixFunctionToken.TryParse(internalLine, out token)
                    //            || AssignmentOperatorToken.TryParse(internalLine, out token)
                    //            || CommentToken.TryParse(internalLine, out token))
                    //        {
                    //            tokenIsValid = true;
                    //        }
                    //    }
                    //    else if (lastToken is NumberToken || lastToken is BooleanToken)
                    //    {
                    //        if ((PerenthesisToken.TryParse(internalLine, out token) && ((PerenthesisToken)token).PerenthesisType == PerenthesisType.Closed)
                    //            || InfixFunctionToken.TryParse(internalLine, out token)
                    //            || ArithmeticOperatorToken.TryParse(internalLine, out token)
                    //            || BinaryOperatorToken.TryParse(internalLine, out token)
                    //            || BooleanOperatorToken.TryParse(internalLine, out token)
                    //            || PostfixFunctionToken.TryParse(internalLine, out token)
                    //            || CommentToken.TryParse(internalLine, out token))
                    //        {
                    //            tokenIsValid = true;
                    //        }
                    //    }
                    //    else if (lastToken is PerenthesisToken)
                    //    {
                    //        if (PerenthesisToken.TryParse(internalLine, out token) && ((PerenthesisToken)token).PerenthesisType == ((PerenthesisToken)lastToken).PerenthesisType
                    //            || CommentToken.TryParse(internalLine, out token))
                    //        {
                    //            tokenIsValid = true;
                    //        }
                    //        else if (((PerenthesisToken)lastToken).PerenthesisType == PerenthesisType.Open)
                    //        {
                    //            if (PrefixFunctionToken.TryParse(internalLine, out token)
                    //                || BooleanToken.TryParse(internalLine, out token)
                    //                || VariableToken.TryParse(internalLine, out token)
                    //                || ConstantToken.TryParse(internalLine, out token)
                    //                || NumberToken.TryParse(internalLine, out token)
                    //                || LastResultToken.TryParse(internalLine, out token))
                    //            {
                    //                tokenIsValid = true;
                    //            }
                    //        }
                    //        else
                    //        {
                    //            if (InfixFunctionToken.TryParse(internalLine, out token)
                    //                || ArithmeticOperatorToken.TryParse(internalLine, out token)
                    //                || BinaryOperatorToken.TryParse(internalLine, out token)
                    //                || BooleanOperatorToken.TryParse(internalLine, out token)
                    //                || PostfixFunctionToken.TryParse(internalLine, out token))
                    //            {
                    //                tokenIsValid = true;
                    //            }
                    //        }
                    //    }
                    //    else if (lastToken is PrefixFunctionToken
                    //        && ((PerenthesisToken.TryParse(internalLine, out token) && ((PerenthesisToken)token).PerenthesisType == PerenthesisType.Open)
                    //            || lastToken.ToString().Equals("!", StringComparison.InvariantCultureIgnoreCase)
                    //                && (BooleanToken.TryParse(internalLine, out token)
                    //                || VariableToken.TryParse(internalLine, out token)
                    //                || ConstantToken.TryParse(internalLine, out token)
                    //                || NumberToken.TryParse(internalLine, out token))))
                    //    {
                    //        tokenIsValid = true;
                    //    }
                    //    else if (lastToken is InfixFunctionToken || lastToken is OperatorToken)
                    //    {
                    //        if (PrefixFunctionToken.TryParse(internalLine, out token)
                    //            || BooleanToken.TryParse(internalLine, out token)
                    //            || VariableToken.TryParse(internalLine, out token)
                    //            || ConstantToken.TryParse(internalLine, out token)
                    //            || NumberToken.TryParse(internalLine, out token)
                    //            || LastResultToken.TryParse(internalLine, out token)
                    //            || (PerenthesisToken.TryParse(internalLine, out token) && ((PerenthesisToken)token).PerenthesisType == PerenthesisType.Open)
                    //            || CommentToken.TryParse(internalLine, out token))
                    //        {
                    //            tokenIsValid = true;
                    //        }
                    //    }
                    //    else if (lastToken is PostfixFunctionToken)
                    //    {
                    //        if ((PerenthesisToken.TryParse(internalLine, out token) && ((PerenthesisToken)token).PerenthesisType == PerenthesisType.Closed)
                    //            || InfixFunctionToken.TryParse(internalLine, out token)
                    //            || ArithmeticOperatorToken.TryParse(internalLine, out token)
                    //            || BinaryOperatorToken.TryParse(internalLine, out token)
                    //            || BooleanOperatorToken.TryParse(internalLine, out token)
                    //            || PostfixFunctionToken.TryParse(internalLine, out token)
                    //            || CommentToken.TryParse(internalLine, out token))
                    //        {
                    //            tokenIsValid = true;
                    //        }
                    //    }
                    //    else
                    //    {
                    //        throw new InvalidTokenException(String.Format("Invalid or unrecognized token at {0}.", internalLine));
                    //    }
                    #endregion

                    if (tokenIsValid)
                    {
                        internalLine = AddTokenToCollection(token, internalLine);
                        _context[CalculatorContext.LastToken] = token;
                    }

                    CheckForLastResultImplication();
                }
            }
        }
예제 #22
0
        /// <summary>
        /// Evaluates this expression.
        /// </summary>
        /// <returns></returns>
        public override Token Evaluate()
        {
            Token  result        = new NullToken();
            string op            = Operation.ToString();
            bool   modeIsDegrees = CalculatorContext.GetInstance()[CalculatorContext.Mode].ToString().Equals("deg", StringComparison.InvariantCultureIgnoreCase);

            if (Operation is PrefixFunctionToken)
            {
                Token  val = EvaluateOperand(0);
                double res = 0.0;

                if (double.TryParse(val.ToString(), out res))
                {
                    if (op.Equals("abs", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((Math.Abs(res)).ToString());
                    }
                    else if (op.Equals("cosh", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (modeIsDegrees)
                        {
                            res = ToRadians(res);
                        }

                        res = Math.Cosh(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("sinh", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (modeIsDegrees)
                        {
                            res = ToRadians(res);
                        }

                        res = Math.Sinh(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("tanh", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (modeIsDegrees)
                        {
                            res = ToRadians(res);
                        }

                        res = Math.Tanh(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("cos", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (modeIsDegrees)
                        {
                            res = ToRadians(res);
                        }

                        res = Math.Cos(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("sin", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (modeIsDegrees)
                        {
                            res = ToRadians(res);
                        }

                        res = Math.Sin(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("tan", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (modeIsDegrees)
                        {
                            res = ToRadians(res);
                        }

                        res = Math.Tan(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("acos", StringComparison.InvariantCultureIgnoreCase))
                    {
                        res = modeIsDegrees ? ToDegrees(Math.Acos(res)) : Math.Acos(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("asin", StringComparison.InvariantCultureIgnoreCase))
                    {
                        res = modeIsDegrees ? ToDegrees(Math.Asin(res)) : Math.Acos(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("atan", StringComparison.InvariantCultureIgnoreCase))
                    {
                        res = modeIsDegrees ? ToDegrees(Math.Atan(res)) : Math.Acos(res);

                        result = new NumberToken(res.ToString());
                    }
                    else if (op.Equals("log", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((Math.Log10(res)).ToString());
                    }
                    else if (op.Equals("ln", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((Math.Log(res)).ToString());
                    }
                    else if (op.Equals("lb", StringComparison.InvariantCultureIgnoreCase) || op.Equals("ld", StringComparison.InvariantCultureIgnoreCase) || op.Equals("lg", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((Math.Log(res) / Math.Log(2.0)).ToString());
                    }
                    else if (op.Equals("deg", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((ToDegrees(res)).ToString());
                    }
                    else if (op.Equals("rad", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((ToRadians(res)).ToString());
                    }
                    else if (op.Equals("sqrt", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((Math.Sqrt(res)).ToString());
                    }
                    else if (op.Equals("too", StringComparison.InvariantCultureIgnoreCase))
                    {
                        CalculatorContext.GetInstance()[CalculatorContext.DisplayBase] = new NumberToken("8");

                        result = new NumberToken(val);
                    }
                    else if (op.Equals("tod", StringComparison.InvariantCultureIgnoreCase))
                    {
                        CalculatorContext.GetInstance()[CalculatorContext.DisplayBase] = new NumberToken("10");

                        result = new NumberToken(val);
                    }
                    else if (op.Equals("toh", StringComparison.InvariantCultureIgnoreCase))
                    {
                        CalculatorContext.GetInstance()[CalculatorContext.DisplayBase] = new NumberToken("16");

                        result = new NumberToken(val);
                    }
                    else if (op.Equals("tob", StringComparison.InvariantCultureIgnoreCase))
                    {
                        CalculatorContext.GetInstance()[CalculatorContext.DisplayBase] = new NumberToken("2");

                        result = new NumberToken(val);
                    }
                    else if (op.Equals("-", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((res * (-1)).ToString());
                    }
                    else if (op.Equals("!", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (val is BooleanToken)
                        {
                            result = ((BooleanToken)val).Not();
                        }
                        else if (val is NumberToken)
                        {
                            result = ((NumberToken)val).Negate();
                        }
                    }
                }
                else
                {
                    throw new FormatException(String.Format("Could not parse double value from {0}", val));
                }
            }
            else if (Operation is InfixFunctionToken)
            {
                Token  left   = EvaluateOperand(1);
                Token  right  = EvaluateOperand(0);
                double dLeft  = 0.0;
                double dRight = 0.0;

                if (double.TryParse(left.ToString(), out dLeft) && double.TryParse(right.ToString(), out dRight))
                {
                    if (op.Equals("**", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((Math.Pow(dLeft, dRight)).ToString());
                    }
                    else if (op.Equals("%", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((dLeft % dRight).ToString());
                    }
                    else if (op.Equals("//", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if ((left is NumberToken && right is NumberToken))
                        {
                            long lLeft  = 0;
                            long lRight = 0;

                            if ((long.TryParse(((NumberToken)left).WholePart(), out lLeft) && long.TryParse(((NumberToken)right).WholePart(), out lRight)))
                            {
                                long rem   = 0;
                                long whole = Math.DivRem(lLeft, lRight, out rem);

                                result = new NumberToken(whole.ToString());
                            }
                        }
                        else
                        {
                            throw new FormatException(String.Format("Could not parse long values from {0} or {1}.", left, right));
                        }
                    }
                }
                else
                {
                    throw new FormatException(String.Format("Could not parse double values from {0} or {1}.", left, right));
                }
            }
            else if (Operation is PostfixFunctionToken)
            {
                Token  val = EvaluateOperand(0);
                double res = 0.0;

                if (double.TryParse(val.ToString(), out res))
                {
                    if (op.Equals("!", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (Operation is PostfixFunctionToken)
                        {
                            double counter = res;
                            double total   = counter;

                            while (counter > 1)
                            {
                                counter--;

                                total *= counter;
                            }

                            result = new NumberToken(total.ToString());
                        }
                    }
                }
                else
                {
                    throw new FormatException(String.Format("Could not parse double value from {0}", val));
                }
            }
            else
            {
                throw new InvalidTokenException(String.Format("Operation {0} not currently supported. Please submit a feature request.", Operation));
            }

            return(result);
        }
예제 #23
0
        /// <summary>
        /// Evaluates this expression.
        /// </summary>
        /// <returns></returns>
        public override Token Evaluate()
        {
            Token result = new NullToken();
            Token left   = EvaluateOperand(1);
            Token right  = EvaluateOperand(0);

            if (left is NumberToken && right is NumberToken)
            {
                long lLeft  = 0;;
                long lRight = 0;;

                if (long.TryParse(((NumberToken)left).WholePart(), out lLeft) && long.TryParse(((NumberToken)right).WholePart(), out lRight))
                {
                    if (Operation.ToString().Equals("&", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((lLeft & lRight).ToString());
                    }
                    else if (Operation.ToString().Equals("|", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((lLeft | lRight).ToString());
                    }
                    else if (Operation.ToString().Equals("^", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new NumberToken((lLeft ^ lRight).ToString());
                    }
                    else
                    {
                        throw new FormatException(String.Format("Could not parse long value from {0} for binary expression.", left.ToString()));
                    }
                }
            }
            else if (left is BooleanToken && right is BooleanToken)
            {
                bool bLeft  = false;
                bool bRight = false;

                if (bool.TryParse(left.ToString(), out bLeft) && bool.TryParse(right.ToString(), out bRight))
                {
                    if (Operation.ToString().Equals("&", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((bLeft & bRight).ToString());
                    }
                    else if (Operation.ToString().Equals("|", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((bLeft | bRight).ToString());
                    }
                    else if (Operation.ToString().Equals("^", StringComparison.InvariantCultureIgnoreCase))
                    {
                        result = new BooleanToken((bLeft ^ bRight).ToString());
                    }
                    else
                    {
                        throw new FormatException(String.Format("Could not parse bool value from {0} for binary expression.", left.ToString()));
                    }
                }
            }
            else
            {
                throw new MalformedExpressionException(String.Concat(ToString(), " is not a valid binary expression."));
            }

            return(result);
        }