public static double ProcessArithmetic(List<PhoenixCAS.Token> expression) { int lpcount = 0; int rpcount = 0; foreach (Token t in expression) { if (t.Type == Token.TokenType.RParen) rpcount++; if (t.Type == Token.TokenType.LParen) lpcount++; } if (rpcount != lpcount) throw new MismatchedParenthesisException(); if (expression.Count == 1) if (expression[0].Type != Token.TokenType.Number) if (expression[0].Type == Token.TokenType.Symbol) { if (Token.Symbols.ContainsKey(expression[0].Data)) return Token.Symbols[expression[0].Data]; else throw new NullSymbolException(); } else throw new MalformedExpressionException(); else return Convert.ToDouble(expression[0].Data); else if (expression.Count == 2 && expression[0].Type != Token.TokenType.Function) if (expression[0].Type != Token.TokenType.Add && expression[0].Type != Token.TokenType.Sub && expression[1].Type != Token.TokenType.Number ) throw new MalformedExpressionException(); else return ((expression[0].Type == Token.TokenType.Add ? 1 : -1) * Convert.ToDouble(expression[1].Data)); else { if (rpcount > 0) { int innermostLparen= -1; for (int i = 0; i < expression.Count(); i++) { if (expression[i].Type == Token.TokenType.LParen) innermostLparen = i; } int innermostRparen = innermostLparen; for (int i = innermostLparen; i < expression.Count(); i++) { if (expression[i].Type != Token.TokenType.RParen) continue; innermostRparen = i; break; } Token innerExpressionResult = new Token(Token.TokenType.Number, ProcessArithmetic(expression.GetRange(innermostLparen+1, innermostRparen-innermostLparen-1)).ToString()); expression.RemoveRange(innermostLparen, innermostRparen - innermostLparen+1); expression.Insert(innermostLparen, innerExpressionResult); return ProcessArithmetic(expression); } for (int i = 0; i < expression.Count; i++) { Token t = expression[i]; if (t.Type == Token.TokenType.Symbol) if (Token.Symbols.ContainsKey(t.Data)) expression[i] = new Token(Token.TokenType.Number, Token.Symbols[t.Data].ToString()); else throw new NullSymbolException(); } for (int i = expression.Count - 1; i > -1; i--) { if (expression[i].Type == Token.TokenType.Function) { string[] sa = expression[i].Data.Split("\n".ToCharArray()); int args = Convert.ToInt32(sa[0]); string name = sa[1]; if (expression.Count() < i + args) throw new NullFunctionException(); double result = 0; switch (args) { case 1: result = Token.SingleFunctions[name](Convert.ToDouble(expression[i + 1].Data)); break; case 2: result = Token.DoubleFunctions[name](Convert.ToDouble(expression[i + 1].Data), Convert.ToDouble(expression[i + 2].Data)); break; default: throw new NullFunctionException(); } expression.Insert(i, new Token(Token.TokenType.Number, result.ToString())); expression.RemoveRange(i+1, args + 1); return ProcessArithmetic(expression); } } int index = 0; int maxPriority = -2; for (int i = 0; i < expression.Count; i++) { /*if ((t1.type == Token.TokenType.ADD || t1.type == Token.TokenType.SUB) && (t2.type == Token.TokenType.ADD || t2.type == Token.TokenType.SUB) || (t2.type == Token.TokenType.NUMBER && t2.type == Token.TokenType.NUMBER) || t1.type == Token.TokenType.NULL || t2.type == Token.TokenType.NULL) throw new PhoenixCAS.Exceptions.MalformedExpressionException();*/ if (expression[i].Priority > maxPriority) { maxPriority = expression[i].Priority; index = i; } } Token t1 = expression[index]; Token t2 = expression[index - 1]; List<Token> l = new List<Token>(expression); switch (t1.Type) { case Token.TokenType.Add: return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) + Convert.ToDouble(expression[index + 1].Data)).ToString()))); case Token.TokenType.Sub: return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) - Convert.ToDouble(expression[index + 1].Data)).ToString()))); case Token.TokenType.Multi: return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) * Convert.ToDouble(expression[index + 1].Data)).ToString()))); case Token.TokenType.Div: return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) / Convert.ToDouble(expression[index + 1].Data)).ToString()))); case Token.TokenType.Caret: return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, Math.Pow(Convert.ToDouble(t2.Data), Convert.ToDouble(expression[index + 1].Data)).ToString()))); case Token.TokenType.Modulo: return ProcessArithmetic(ProcessArithmeticHelper(l, index, new Token(Token.TokenType.Number, (Convert.ToDouble(t2.Data) % Convert.ToDouble(expression[index + 1].Data)).ToString()))); } } throw new MalformedExpressionException(); }
private static List<Token> ProcessArithmeticHelper(List<Token> l, int index, Token t) { List<Token> r = new List<Token>(l); r.RemoveRange(index - 1, 3); /*if (index - 2 == 1) { r.Insert(index - 1, Token.TokenType.ADD); r.Insert(index, t); } else*/ r.Insert(index - 1, t); return r; }