// Syntax analysis of reverse polish notation expression private Stack <double> SyntaxAnalysisRPN(Stack <double> stack, string token) { // if it's operand then just push to stack if (token[0] == NumberMarker[0]) { stack.Push(double.Parse(token.Remove(0, 1))); } // otherwise apply operator or funtion to elements in stack else if (NumberOfArguments(token) == 1) { double argument = stack.Pop(); NumExpression arg = new NumExpression(argument); if (!isRadians) { argument = argument * Math.PI / 180; // Convert value to degree } NumExpression trigArg = new NumExpression(argument); double result; switch (token) { case UnaryPlus: result = arg.evaluate(); break; case UnaryMinus: NegateExpresion neg = new NegateExpresion(arg); result = neg.evaluate(); break; case Sqrt: SqrtExpression sqrt = new SqrtExpression(arg); result = sqrt.evaluate(); break; case Log: LogarithmExpression log = new LogarithmExpression(arg); result = log.evaluate(); break; case Ln: LnExpression ln = new LnExpression(arg); result = ln.evaluate(); break; case Sin: SinExpression sin = new SinExpression(trigArg); result = sin.evaluate(); break; case Cos: CosExpression cos = new CosExpression(trigArg); result = cos.evaluate(); break; case Tan: TanExpression tan = new TanExpression(trigArg); result = tan.evaluate(); break; case Csc: CscExpression csc = new CscExpression(trigArg); result = csc.evaluate(); break; case Sec: SecExpression sec = new SecExpression(trigArg); result = sec.evaluate(); break; case Cot: CotExpression cot = new CotExpression(trigArg); result = cot.evaluate(); break; default: throw new ArgumentException("Unknown operator"); } stack.Push(result); } else { // otherwise operator's number of arguments equal to 2 double argument2 = stack.Pop(); double argument1 = stack.Pop(); NumExpression arg1 = new NumExpression(argument1); NumExpression arg2 = new NumExpression(argument2); double result; switch (token) { case Plus: AdditionExpression add = new AdditionExpression(arg1, arg2); result = add.evaluate(); break; case Minus: MinusExpression minus = new MinusExpression(arg1, arg2); result = minus.evaluate(); break; case Multiply: MultiplyExpression multiply = new MultiplyExpression(arg1, arg2); result = multiply.evaluate(); break; case Divide: if (argument2 == 0) { throw new DivideByZeroException("Second argument is zero"); } DivideExpression divide = new DivideExpression(arg1, arg2); result = divide.evaluate(); break; case Mod: ModExpression mod = new ModExpression(arg1, arg2); result = mod.evaluate(); break; case Exponent: ExpononetExpression exp = new ExpononetExpression(arg1, arg2); result = exp.evaluate(); break; default: throw new ArgumentException("Unknown operator"); } stack.Push(result); } return(stack); }
public override List <TestResult> run() { //Do some tests, make results, pass back a list List <TestResult> results = new List <TestResult>(); double expected = 5.0; Expression expr = new AtomicExpression(expected); double actual = expr.evaluate(); TestResult res = new TestResult("Atomic Positive Int", expected, actual, compare(expected, actual)); results.Add(res); expected = -5.0; expr = new AtomicExpression(expected); actual = expr.evaluate(); res = new TestResult("Atomic Negative Int", expected, actual, compare(expected, actual)); results.Add(res); expected = 0; expr = new AtomicExpression(expected); actual = expr.evaluate(); res = new TestResult("Atomic 0 Int", expected, actual, compare(expected, actual)); results.Add(res); expected = 5.0; expr = new ParenExpression(new AtomicExpression(expected)); actual = expr.evaluate(); res = new TestResult("Paren Positive Int", expected, actual, compare(expected, actual)); results.Add(res); expected = -5.0; expr = new ParenExpression(new AtomicExpression(expected)); actual = expr.evaluate(); res = new TestResult("Paren Positive Int", expected, actual, compare(expected, actual)); results.Add(res); expected = 0; expr = new ParenExpression(new AtomicExpression(expected)); actual = expr.evaluate(); res = new TestResult("Paren 0 Int", expected, actual, compare(expected, actual)); results.Add(res); expected = 7; expr = new AddExpression(new AtomicExpression(5), new AtomicExpression(2)); actual = expr.evaluate(); res = new TestResult("Add Positive Int", expected, actual, compare(expected, actual)); results.Add(res); expected = 3; expr = new SubtractExpression(new AtomicExpression(5), new AtomicExpression(2)); actual = expr.evaluate(); res = new TestResult("Subtract Postive Int", expected, actual, compare(expected, actual)); results.Add(res); expected = 10; expr = new MultiplyExpression(new AtomicExpression(5), new AtomicExpression(2)); actual = expr.evaluate(); res = new TestResult("Multiply Positive Int", expected, actual, compare(expected, actual)); results.Add(res); expected = 2.5; expr = new DivideExpression(new AtomicExpression(5), new AtomicExpression(2)); actual = expr.evaluate(); res = new TestResult("Divide Positive Float", expected, actual, compare(expected, actual)); results.Add(res); expected = 25; expr = new ExponentExpression(new AtomicExpression(5), new AtomicExpression(2)); actual = expr.evaluate(); res = new TestResult("Exponent Positive Float", expected, actual, compare(expected, actual)); results.Add(res); return(results); //I can be reasonably certain they won't mess up in different circumstances. It's just wrappers for primitive expressions. }