/// <summary> /// Gets the next token while within an infix operation parse state. /// </summary> /// <param name="internalLine"></param> /// <param name="token"></param> /// <param name="state"></param> /// <returns></returns> public override bool GetNextToken(string internalLine, out Token token, out TokenParseState state) { bool result = false; if ((result = PrefixFunctionToken.TryParse(internalLine, out token))) { state = new PrefixFunctionTokenParseState(); } else if ((result = BooleanToken.TryParse(internalLine, out token) || ConstantToken.TryParse(internalLine, out token) || NumberToken.TryParse(internalLine, out token) || LastResultToken.TryParse(internalLine, out token))) { state = new ValueTokenParseState(); } else if ((result = VariableToken.TryParse(internalLine, out token))) { state = new VariableTokenParseState(); } else if ((result = (PerenthesisToken.TryParse(internalLine, out token) && ((PerenthesisToken)token).PerenthesisType == PerenthesisTokenType.Open))) { state = new PerenthesisTokenParseState(); } else if ((result = CommentToken.TryParse(internalLine, out token))) { state = new NullTokenParseState(); } else { state = new InvalidTokenParseState(); } return(result); }
/// <summary> /// Gets the next token while within ta prefix function token parse state. /// </summary> /// <param name="internalLine"></param> /// <param name="token"></param> /// <param name="state"></param> /// <returns></returns> public override bool GetNextToken(string internalLine, out Token token, out TokenParseState state) { bool result = false; Token lastToken = CalculatorContext.GetInstance()[CalculatorContext.LastToken]; if ((result = (PerenthesisToken.TryParse(internalLine, out token) && ((PerenthesisToken)token).PerenthesisType == PerenthesisTokenType.Open))) { state = new PerenthesisTokenParseState(); } else if (lastToken.ToString().Equals("!", StringComparison.InvariantCultureIgnoreCase)) { if ((result = BooleanToken.TryParse(internalLine, out token) || ConstantToken.TryParse(internalLine, out token) || NumberToken.TryParse(internalLine, out token))) { state = new ValueTokenParseState(); } else if ((result = VariableToken.TryParse(internalLine, out token))) { state = new VariableTokenParseState(); } else { state = new InvalidTokenParseState(); } } else { state = new InvalidTokenParseState(); } return(result); }
/// <summary> /// Gets a Token of type BooleanToken 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 (BooleanToken.__booleanPattern.IsMatch(line)) { string matchText = BooleanToken.__booleanPattern.Matches(line)[0].Value; token = new BooleanToken(matchText, "$"); } return(token); }
/// <summary> /// Returns the inverse of this BooleanToken. /// </summary> /// <returns></returns> public Token Not() { Token result = this; if (ToString().Equals("true", StringComparison.InvariantCultureIgnoreCase)) { result = new BooleanToken("false"); } else { result = new BooleanToken("true"); } return(result); }
/// <summary> /// Gets the next token while in the set container token parse state. /// </summary> /// <param name="internalLine"></param> /// <param name="token"></param> /// <param name="state"></param> /// <returns></returns> public override bool GetNextToken(string internalLine, out Token token, out TokenParseState state) { bool result = false; Token lastToken = CalculatorContext.GetInstance()[CalculatorContext.LastToken]; if ((result = SetContainerToken.TryParse(internalLine, out token) && ((SetContainerToken)token).SetContainerType == ((SetContainerToken)lastToken).SetContainerType)) { state = new SetContainerTokenParseState(); } else if ((result = CommentToken.TryParse(internalLine, out token))) { state = new NullTokenParseState(); } else if (((SetContainerToken)lastToken).SetContainerType == SetContainerTokenType.Open) { if ((result = PrefixFunctionToken.TryParse(internalLine, out token))) { state = new PrefixFunctionTokenParseState(); } else if ((result = BooleanToken.TryParse(internalLine, out token) || ConstantToken.TryParse(internalLine, out token) || NumberToken.TryParse(internalLine, out token) || LastResultToken.TryParse(internalLine, out token))) { state = new ValueTokenParseState(); } else if ((result = VariableToken.TryParse(internalLine, out token))) { state = new VariableTokenParseState(); } else { state = new InvalidTokenParseState(); } } else if ((result = InfixFunctionToken.TryParse(internalLine, out token) || ArithmeticOperatorToken.TryParse(internalLine, out token) || BinaryOperatorToken.TryParse(internalLine, out token) || BooleanOperatorToken.TryParse(internalLine, out token))) { state = new InfixOperationParseState(); } else if ((result = PostfixFunctionToken.TryParse(internalLine, out token))) { state = new PostfixFunctionParseState(); } else { state = new InvalidTokenParseState(); } return(result); }
/// <summary> /// Gets the next Token if the last token was a NullToken. It first tries to get a normal, /// valid first token. If that fails, then it checks for a normal secondary token, and if /// that passes then the context LastResultIsImplied is set to true. /// </summary> /// <param name="internalLine"></param> /// <param name="token"></param> /// <returns></returns> public override bool GetNextToken(string internalLine, out Token token, out TokenParseState state) { bool result = false; if ((result = PerenthesisToken.TryParse(internalLine, out token))) { state = new PerenthesisTokenParseState(); } else if ((result = PrefixFunctionToken.TryParse(internalLine, out token))) { state = new PrefixFunctionTokenParseState(); } else if ((result = BooleanToken.TryParse(internalLine, out token) || ConstantToken.TryParse(internalLine, out token) || NumberToken.TryParse(internalLine, out token) || LastResultToken.TryParse(internalLine, out token))) { state = new ValueTokenParseState(); } else if ((result = VariableToken.TryParse(internalLine, out token))) { state = new VariableTokenParseState(); } else if ((result = InfixFunctionToken.TryParse(internalLine, out token) || ArithmeticOperatorToken.TryParse(internalLine, out token) || BinaryOperatorToken.TryParse(internalLine, out token) || BooleanOperatorToken.TryParse(internalLine, out token))) { state = new InfixOperationParseState(); CalculatorContext.GetInstance().LastResultIsImplied = true; } else if ((result = PostfixFunctionToken.TryParse(internalLine, out token))) { state = new PostfixFunctionParseState(); CalculatorContext.GetInstance().LastResultIsImplied = true; } else { state = new InvalidTokenParseState(); } return(result); }
/// <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); }
/// <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); }
/// <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); }