/// <summary> /// This function evaluates an expression returning the result. /// </summary> /// <returns> /// The double representing the evaluated expression. /// </returns> private double CalculateTree(Node calculatedNode) { ConstantNode constantNode = calculatedNode as ConstantNode; if (constantNode != null) { return(constantNode.Value); } VariableNode variableNode = calculatedNode as VariableNode; if (variableNode != null) { if (this.variables.ContainsKey(variableNode.VariableName)) { return(this.variables[variableNode.VariableName]); } else { return(0.0); } } OperatorNode operatorNode = calculatedNode as OperatorNode; if (operatorNode != null) { switch (operatorNode.OperatorValue) { case '+': return(this.CalculateTree(operatorNode.Left) + this.CalculateTree(operatorNode.Right)); case '-': return(this.CalculateTree(operatorNode.Left) - this.CalculateTree(operatorNode.Right)); case '*': return(this.CalculateTree(operatorNode.Left) * this.CalculateTree(operatorNode.Right)); case '/': return(this.CalculateTree(operatorNode.Left) / this.CalculateTree(operatorNode.Right)); default: // if it is not any of the operators that we support, throw an exception: throw new NotSupportedException( "Operator " + operatorNode.OperatorValue.ToString() + " not supported."); } } throw new NotSupportedException(); }
/// <summary> /// This is the comile algorithm that creates the expression tree. /// </summary> /// <param name="equation"> /// The entered expression. /// </param> /// <returns> /// The expression Tree. /// </returns> private Node Compile(string equation) { List <string> yardInputs = new List <string>(); Stack <Node> buildingStack = new Stack <Node>(); Factory nodeCreator = new Factory(); if (string.IsNullOrEmpty(equation)) { return(null); } yardInputs = this.ShuntingYard(equation); foreach (string yardIndex in yardInputs) { switch (yardIndex) { case "+": OperatorNode operatorNodeAdd = nodeCreator.CreateOperatorNode('+'); operatorNodeAdd.Right = buildingStack.Pop(); operatorNodeAdd.Left = buildingStack.Pop(); buildingStack.Push(operatorNodeAdd); break; case "-": OperatorNode operatorNodeSub = nodeCreator.CreateOperatorNode('-'); operatorNodeSub.Right = buildingStack.Pop(); operatorNodeSub.Left = buildingStack.Pop(); buildingStack.Push(operatorNodeSub); break; case "*": OperatorNode operatorNodeMult = nodeCreator.CreateOperatorNode('*'); operatorNodeMult.Right = buildingStack.Pop(); operatorNodeMult.Left = buildingStack.Pop(); buildingStack.Push(operatorNodeMult); break; case "/": OperatorNode operatorNodeDiv = nodeCreator.CreateOperatorNode('/'); operatorNodeDiv.Right = buildingStack.Pop(); operatorNodeDiv.Left = buildingStack.Pop(); buildingStack.Push(operatorNodeDiv); break; default: double nodeValue; if (double.TryParse(yardIndex, out nodeValue)) { // We need a ConstantNode buildingStack.Push(new ConstantNode() { Value = nodeValue }); } else { this.variables.Add(yardIndex, 0.0); buildingStack.Push(new VariableNode() { VariableName = yardIndex }); } break; } } return(buildingStack.Pop()); }