public StaticStack<MathOperation> Convert(string expression) { StaticStack<MathOperation> Output = new StaticStack<MathOperation>(); Stack<MathOperation> OperatorStack = new Stack<MathOperation>(); NumberState NumberState = NumberState.None; float CommaMultiplier = 0; float minus = 1; bool useMinus = true; for (int i = 0; i < expression.Length; i++) { char token = expression[i]; if (char.IsWhiteSpace(token)) { //fixes 5 2 = 52 //new bug: 5 2 + = 7 (infix) NumberState = NumberState.None; continue; } if(token == '-') { if (useMinus) { minus = -1; continue; } } if (char.IsDigit(token)) { float numeric = (float)char.GetNumericValue(token); switch (NumberState) { case NumberState.None: Output.Push((Number)(numeric * minus)); NumberState = NumberState.Number; break; case NumberState.Number: float num = (Number)Output.PopReal(); Output.Push((Number)(num * 10.0 + numeric * NonNullSign(num))); break; case NumberState.Comma: float num2 = (Number)Output.PopReal(); Output.Push((Number)(num2 + numeric * CommaMultiplier * NonNullSign(num2))); CommaMultiplier *= 0.1f; break; default: throw new NotImplementedException(); } minus = 1; useMinus = false; } else if (token == '.') { minus = 1; NumberState = NumberState.Comma; CommaMultiplier = 0.1f; } else if (token == ',') { NumberState = NumberState.None; if (OperatorStack.Count == 0) throw new MismatchedParenthesisException("\"" + expression.Substring(i) + "\": Can't find opening parenthesis"); while (OperatorStack.Count > 0) { if (OperatorStack.Peek() is Parenthesis) break; Output.Push(OperatorStack.Pop()); } if (OperatorStack.Count == 0 || !(OperatorStack.Peek() is Parenthesis)) throw new MismatchedParenthesisException("\"" + expression.Substring(i) + "\": Can't find opening parenthesis"); } else if (token == ')') { if (OperatorStack.Count == 0) throw new MismatchedParenthesisException("\"" + expression.Substring(i) + "\": Can't find opening parenthesis"); while (OperatorStack.Count > 0) { MathOperation TopOperator = OperatorStack.Pop(); if (TopOperator is Parenthesis) break; else Output.Push(TopOperator); if (OperatorStack.Count == 0) throw new MismatchedParenthesisException("\"" + expression.Substring(i) + "\": Can't find opening parenthesis"); } if (OperatorStack.Count > 0 && OperatorStack.Peek() is Function) Output.Push(OperatorStack.Pop()); useMinus = false; } else if (char.IsSymbol(token) || char.IsPunctuation(token)) { string fullname = ""; for (; i < expression.Length; i++) { char letter = expression[i]; if ((char.IsSymbol(letter) || char.IsPunctuation(letter))) //we cant use letters or 5 + sin(x) is going to break fullname += char.ToLower(letter); else { --i; break; } if (m_Operators.ContainsKey(fullname)) break; } if (m_Operators.ContainsKey(fullname)) { MathOperation TokenOperator = m_Operators[fullname]; if (NumberState != MathState.NumberState.None) { NumberState = NumberState.None; if (TokenOperator is Parenthesis) { // makes 5(x) possible OperatorStack.Push(new MathOperations.Operators.Multiplication()); } } while (OperatorStack.Count > 0) { MathOperation TopOperator = OperatorStack.Peek(); if (TokenOperator.Association == Association.Left && TokenOperator.Precedence <= TopOperator.Precedence) Output.Push(OperatorStack.Pop()); else if (TokenOperator.Association == Association.Right && TokenOperator.Precedence < TopOperator.Precedence) Output.Push(OperatorStack.Pop()); else break; } OperatorStack.Push(TokenOperator); } useMinus = true; } else if (char.IsLetter(token)) { minus = 1; string fullname = ""; for (; i < expression.Length; i++) { char letter = expression[i]; if (char.IsLetter(letter)) fullname += char.ToLower(letter); else { --i; break; } } if (NumberState != MathState.NumberState.None) { NumberState = NumberState.None; OperatorStack.Push(new MathOperations.Operators.Multiplication()); } if (m_Functions.ContainsKey(fullname)) OperatorStack.Push(m_Functions[fullname]); else if (m_Variables.ContainsKey(fullname)) { Output.Push(new Variable(fullname, m_Variables)); } else if (m_Constants.ContainsKey(fullname)) { Output.Push(new Constant(fullname, m_Constants[fullname])); } else if (DefineUnknownVariables) Output.Push(new Variable(fullname,m_Variables)); else throw new UndefinedFunctionException("Function \"" + fullname + "\" not defined"); useMinus = false; } else { throw new NotSupportedException(); } } while (OperatorStack.Count > 0) { if (OperatorStack.Peek() is Parenthesis) throw new MismatchedParenthesisException("Can't find closing parenthesis"); Output.Push(OperatorStack.Pop()); } return Output; }