Exemplo n.º 1
0
        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());
        }