/// <summary> /// Sets a variable name and value for dictionary of ExpressionTree /// </summary> /// <param name="expressionTree">ExpressionTree being evaluated</param> /// <param name="varName">Name of the variable</param> private void SetCellVariable(SpreadsheetEngine.ExpressionTree expressionTree, string varName) { SpreadsheetCell cell = this.GetCell(varName); if (double.TryParse(cell.CellValue, out double cellValue)) { expressionTree.SetVariable(varName, cellValue); } else { expressionTree.SetVariable(varName, 0.0); } }
/// <summary> /// Runs the ExpressionTree Demo /// </summary> public void MainMenu() { // Local Variables string userExpression = "A1+B1+C1"; string userInput = ""; string varName = ""; double varValue = 0; do { // Show Menu Console.WriteLine("Menu (current expression = \"" + userExpression + "\")"); Console.WriteLine("1. Enter a new expression"); Console.WriteLine("2. Set a variable value"); Console.WriteLine("3. Evaluate tree"); Console.WriteLine("4. Quit"); // Get User Option userInput = Console.ReadLine().ToString(); switch (userInput) { case "1": Console.WriteLine("Enter a new expression: "); userExpression = Console.ReadLine(); userExpressionTree = new SpreadsheetEngine.ExpressionTree(userExpression); break; case "2": Console.WriteLine("Enter a variable name: "); varName = Console.ReadLine(); Console.WriteLine("Enter a variable value: "); varValue = Convert.ToDouble(Console.ReadLine()); userExpressionTree.SetVariable(varName, varValue); break; case "3": Console.WriteLine(userExpressionTree.Evaluate()); break; default: break; } } while (userInput != "4"); // Exit if User enters "4" }
/// <summary> /// Evaluates Cell's Value based on Entered Text /// </summary> /// <param name="cell"></param> private void EvaluateSpreadsheetCell(SpreadsheetCell cell) { if (cell is SpreadsheetCell currentCell && currentCell != null) { // Empty Cell if (string.IsNullOrEmpty(currentCell.CellText)) { currentCell.CellValue = string.Empty; this.OnPropertyChanged(cell, "CellChanged"); } // Non-Formula else if (currentCell.CellText[0] != '=') { currentCell.CellValue = currentCell.CellText; this.OnPropertyChanged(cell, "CellChanged"); } // Formula else { // Build the Expression Tree Based on Cell Text SpreadsheetEngine.ExpressionTree expressionTree = new SpreadsheetEngine.ExpressionTree(currentCell.CellText.Substring(1)); // Get the Variable Names from the Expression Tree string[] variableNames = expressionTree.GetVariableNames(); foreach (string variable in variableNames) { SpreadsheetCell variableCell = this.GetCell(variable); // Check for Bad / Self References if (!CheckValidReference(currentCell, variableCell) || CheckSelfReference(currentCell, variableCell)) { return; } // Adjust Variable Values if (variableCell.CellValue != string.Empty && !variableCell.CellValue.Contains(" ")) { expressionTree.SetVariable(variable, Convert.ToDouble(variableCell.CellValue)); } else { // Set Default Variable Value to 0.0 expressionTree.SetVariable(variable, 0.0); } } // Mark Cells Dependent on the One Being Changed AddCellDependency(currentCell, variableNames); // Check Dependent Cells for Circular References foreach (string variable in variableNames) { SpreadsheetCell variableCell = this.GetCell(variable); if (CheckCircularReference(variableCell, currentCell)) { currentCell.CellValue = "!(circular reference)"; this.OnPropertyChanged(currentCell, "CellChanged"); return; } } // If no Errors, Evaluate the Formula and Update the Value currentCell.CellValue = expressionTree.Evaluate().ToString(); this.OnPropertyChanged(cell, "CellChanged"); } // Update the Dependent Cells of Cell Being Changed if (dependentCells.ContainsKey(currentCell)) { foreach (SpreadsheetCell dependentCell in dependentCells[currentCell]) { EvaluateSpreadsheetCell(dependentCell); } } } }
public void TestSetVariable() { SpreadsheetEngine.ExpressionTree expressionTree = new SpreadsheetEngine.ExpressionTree("5+4"); expressionTree.SetVariable("A1", 42); var fieldInfo = expressionTree.GetType().GetField("root", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); }