public string Build(string className, Sheet sheet) { var cells = sheet.Rows.SelectMany(row => row.Cells.Select(cell => cell)).ToList(); var code = new StringBuilder(); code.AppendLine($"public class {className} : ISheet"); code.AppendLine("{"); code.AppendLine(string.Empty); code.AppendLine(CellsClassBuilder.Build(cells)); code.AppendLine(FormulasClassBuilder.Build(cells.Where(cell => cell.Type == CellType.Formula))); code.AppendLine(string.Empty); code.AppendLine($"\tpublic string Name {{ get {{ return \"{sheet.Name.Replace("\"", "\\\"")}\"; }} }}"); code.AppendLine("\tprivate readonly Cells cells;"); code.AppendLine("\tprivate readonly Formulas formulas;"); code.AppendLine($"\tpublic {className}()"); code.AppendLine("\t{"); code.AppendLine("\t\tcells = new Cells();"); code.AppendLine("\t\tformulas = new Formulas(cells);"); code.AppendLine("\t}"); code.AppendLine("\tpublic void Evaluate()"); code.AppendLine("\t{"); code.AppendLine("\t\tformulas.Evaluate();"); code.AppendLine("\t}"); code.AppendLine("\tpublic string GetString(string cellReference)"); code.AppendLine("\t{"); code.AppendLine("\t\treturn cells[cellReference].Value.AsString();"); code.AppendLine("\t}"); code.AppendLine("\tpublic double GetNumeric(string cellReference)"); code.AppendLine("\t{"); code.AppendLine("\t\treturn cells[cellReference].Value.AsNumeric();"); code.AppendLine("\t}"); code.AppendLine("\tpublic void SetString(string cellReference, string value)"); code.AppendLine("\t{"); code.AppendLine("\t\tcells[cellReference] = new ComparableValue(new StringValue(value));"); code.AppendLine("\t}"); code.AppendLine("\tpublic void SetNumeric(string cellReference, double value)"); code.AppendLine("\t{"); code.AppendLine("\t\tcells[cellReference] = new ComparableValue(new NumericValue(value));"); code.AppendLine("\t}"); code.AppendLine("}"); return(code.ToString()); }
public static string FormatFormula(Formula formula) { var stack = new Stack <string>(); foreach (var token in formula.Tokens.Where(token => token.GetType() != typeof(SkipToken))) { switch (token) { case AddToken _: var add1 = stack.Pop(); var add2 = stack.Pop(); stack.Push($"{add2} + {add1}"); break; case SubtractToken _: var sub1 = stack.Pop(); var sub2 = stack.Pop(); stack.Push($"{sub2} - {sub1}"); break; case MultiplyToken _: var mul1 = stack.Pop(); var mul2 = stack.Pop(); stack.Push($"{mul2} * {mul1}"); break; case DivideToken _: var div1 = stack.Pop(); var div2 = stack.Pop(); stack.Push($"{div2} / {div1}"); break; case EqualToken _: var eq1 = stack.Pop(); var eq2 = stack.Pop(); stack.Push($"{eq2} == {eq1}"); break; case NotEqualToken _: var neq1 = stack.Pop(); var neq2 = stack.Pop(); stack.Push($"{neq2} != {neq1}"); break; case GreaterEqualToken _: var ge1 = stack.Pop(); var ge2 = stack.Pop(); stack.Push($"{ge2} >= {ge1}"); break; case GreaterThanToken _: var gt1 = stack.Pop(); var gt2 = stack.Pop(); stack.Push($"{gt2} > {gt1}"); break; case LessEqualToken _: var le1 = stack.Pop(); var le2 = stack.Pop(); stack.Push($"{le2} <= {le1}"); break; case LessThanToken _: var lt1 = stack.Pop(); var lt2 = stack.Pop(); stack.Push($"{lt2} < {lt1}"); break; case ParenthesisToken _: stack.Push($"({stack.Pop()})"); break; case RefToken refToken: stack.Push($"cells[\"{refToken.CellReference}\"]"); break; case IntegerToken integerToken: stack.Push(CellsClassBuilder.NewComparableValue(CellType.Numeric, string.Empty, integerToken.Value)); break; case StringToken stringToken: stack.Push(CellsClassBuilder.NewComparableValue(CellType.String, stringToken.Value, 0)); break; case FuncVarToken funcVarToken: stack.Push( $"{FormatFuncName(funcVarToken.Name)}({string.Join(", ", GetOperands(stack, funcVarToken.Operands))})"); break; case FuncToken funcToken: stack.Push( $"{FormatFuncName(funcToken.Name)}({string.Join(", ", GetOperands(stack, funcToken.Operands))})"); break; case AreaToken areaToken: stack.Push($"new []{{{string.Join(", ", areaToken.CellReferences.Select(x => $"cells[\"{x}\"]"))}}}"); break; case SumToken _: stack.Push($"Sum({stack.Pop()})"); break; case NumberToken numberToken: stack.Push(CellsClassBuilder.NewComparableValue(CellType.Numeric, string.Empty, numberToken.Value)); break; default: throw new Exception($"Token type '{token.GetType()}' is not supported"); } } return(stack.Pop()); }