public void AddDependency(FormulaCell cell) { if (_dependencies == null) _dependencies = new List<FormulaCell>(); if (!_dependencies.Contains(cell)) _dependencies.Add(cell); }
/// <summary> /// Currently a fake loader /// </summary> public void Load() { // 3 + RC[-2] + RC[-1] RpnExpression expr1 = new RpnExpression(); expr1.Add(new RpnNodeConst(3.0)); expr1.Add(new RpnNodeCellRef(0, false, -2, false)); expr1.Add(new RpnNodeCellRef(0, false, -1, false)); expr1.Add(new RpnNodeAdd()); expr1.Add(new RpnNodeAdd()); _expressions.Add(expr1); // RC[-2] + RC[-1] RpnExpression expr2 = new RpnExpression(); expr2.Add(new RpnNodeCellRef(0, false, -2, false)); expr2.Add(new RpnNodeCellRef(0, false, -1, false)); expr2.Add(new RpnNodeAdd()); _expressions.Add(expr2); for (int row = 0; row < _numRows; row++) { for (int col = 0; col < _numCols; col++) { // current sheet is 5 columns, 0 to 4. switch (col) { case 3: { FormulaCell cell = new FormulaCell(); cell.Formula = expr1; Cells[row, col] = cell; break; } case 4: { FormulaCell cell = new FormulaCell(); cell.Formula = expr2; Cells[row, col] = cell; break; } default: Cells[row, col] = new ConstantCell(); Cells[row, col].Value = row + col; break; } } } }
/// <summary> /// Evaluate the expression relative to cell(row, col) /// </summary> /// <param name="row"></param> /// <param name="col"></param> /// <returns></returns> public double Evaluate(RpnExpression expr, int row, int col) { FormulaCell thisCell = (FormulaCell)_sheet.Cells[row, col]; if (!thisCell.IsDirty) { return(thisCell.Value); } RpnStack stack = new RpnStack(); foreach (RpnNode n in expr.Nodes) { if (n.IsValueType()) { stack.Add(n); } else if (n.GetType() == typeof(RpnNodeCellRef)) { RpnNodeCellRef n1 = (RpnNodeCellRef)n; int row1 = row + n1._row; int col1 = col + n1._col; _sheet.Cells[row1, col1].AddDependency(thisCell); // TODO - only needs to be done on first evaluate double x = this.Value(row1, col1); // here's the magic recursive call to evaluate upstream stack.Add(new RpnNodeConst(x)); } else { stack.Add(n.Evaluate(stack)); } } Debug.Assert(stack.Count == 1); Debug.Assert(stack[0].IsValueType()); double ret = stack[0].Value(); thisCell.Value = ret; return(ret); }