Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 20 additions & 32 deletions calc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1150,15 +1150,15 @@ func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.T
for optStack.Len() != 0 {
topOpt := optStack.Peek().(efp.Token)
if err = calculate(opdStack, topOpt); err != nil {
return newEmptyFormulaArg(), err
return newErrorFormulaArg(err.Error(), err.Error()), err
}
optStack.Pop()
}
if opdStack.Len() == 0 {
return newEmptyFormulaArg(), ErrInvalidFormula
}
if result := opdStack.Peek().(formulaArg); result.Type == ArgError {
return newEmptyFormulaArg(), errors.New(result.Error)
return result, errors.New(result.Error)
}
return opdStack.Peek().(formulaArg), err
}
Expand Down Expand Up @@ -1241,11 +1241,11 @@ func prepareEvalInfixExp(opfStack, opftStack, opfdStack, argsStack *Stack) {
func calcPow(rOpd, lOpd formulaArg, opdStack *Stack) error {
lOpdVal := lOpd.ToNumber()
if lOpdVal.Type != ArgNumber {
return errors.New(lOpdVal.Value())
return errors.New(lOpdVal.String)
}
rOpdVal := rOpd.ToNumber()
if rOpdVal.Type != ArgNumber {
return errors.New(rOpdVal.Value())
return errors.New(rOpdVal.String)
}
opdStack.Push(newNumberFormulaArg(math.Pow(lOpdVal.Number, rOpdVal.Number)))
return nil
Expand Down Expand Up @@ -1349,31 +1349,31 @@ func calcSplice(rOpd, lOpd formulaArg, opdStack *Stack) error {
func calcAdd(rOpd, lOpd formulaArg, opdStack *Stack) error {
lOpdVal := lOpd.ToNumber()
if lOpdVal.Type != ArgNumber {
return errors.New(lOpdVal.Value())
return errors.New(lOpdVal.String)
}
rOpdVal := rOpd.ToNumber()
if rOpdVal.Type != ArgNumber {
return errors.New(rOpdVal.Value())
return errors.New(rOpdVal.String)
}
opdStack.Push(newNumberFormulaArg(lOpdVal.Number + rOpdVal.Number))
return nil
}

// calcSubtract evaluate subtraction arithmetic operations.
func calcSubtract(rOpd, lOpd formulaArg, opdStack *Stack) error {
if rOpd.Value() == "" {
if rOpd.Type == ArgEmpty {
rOpd = newNumberFormulaArg(0)
}
if lOpd.Value() == "" {
if lOpd.Type == ArgEmpty {
lOpd = newNumberFormulaArg(0)
}
lOpdVal := lOpd.ToNumber()
if lOpdVal.Type != ArgNumber {
return errors.New(lOpdVal.Value())
return errors.New(lOpdVal.String)
}
rOpdVal := rOpd.ToNumber()
if rOpdVal.Type != ArgNumber {
return errors.New(rOpdVal.Value())
return errors.New(rOpdVal.String)
}
opdStack.Push(newNumberFormulaArg(lOpdVal.Number - rOpdVal.Number))
return nil
Expand All @@ -1383,11 +1383,11 @@ func calcSubtract(rOpd, lOpd formulaArg, opdStack *Stack) error {
func calcMultiply(rOpd, lOpd formulaArg, opdStack *Stack) error {
lOpdVal := lOpd.ToNumber()
if lOpdVal.Type != ArgNumber {
return errors.New(lOpdVal.Value())
return errors.New(lOpdVal.String)
}
rOpdVal := rOpd.ToNumber()
if rOpdVal.Type != ArgNumber {
return errors.New(rOpdVal.Value())
return errors.New(rOpdVal.String)
}
opdStack.Push(newNumberFormulaArg(lOpdVal.Number * rOpdVal.Number))
return nil
Expand All @@ -1397,11 +1397,11 @@ func calcMultiply(rOpd, lOpd formulaArg, opdStack *Stack) error {
func calcDiv(rOpd, lOpd formulaArg, opdStack *Stack) error {
lOpdVal := lOpd.ToNumber()
if lOpdVal.Type != ArgNumber {
return errors.New(lOpdVal.Value())
return errors.New(lOpdVal.String)
}
rOpdVal := rOpd.ToNumber()
if rOpdVal.Type != ArgNumber {
return errors.New(rOpdVal.Value())
return errors.New(rOpdVal.String)
}
if rOpdVal.Number == 0 {
return errors.New(formulaErrorDIV)
Expand Down Expand Up @@ -1449,18 +1449,18 @@ func calculate(opdStack *Stack, opt efp.Token) error {
rOpd := opdStack.Pop().(formulaArg)
lOpd := opdStack.Pop().(formulaArg)
if opt.TValue != "&" {
if rOpd.Value() == "" {
if rOpd.Type == ArgEmpty {
rOpd = newNumberFormulaArg(0)
}
if lOpd.Value() == "" {
if lOpd.Type == ArgEmpty {
lOpd = newNumberFormulaArg(0)
}
}
if rOpd.Type == ArgError {
return errors.New(rOpd.Value())
return errors.New(rOpd.String)
}
if lOpd.Type == ArgError {
return errors.New(lOpd.Value())
return errors.New(lOpd.String)
}
return fn(rOpd, lOpd, opdStack)
}
Expand Down Expand Up @@ -1545,19 +1545,6 @@ func tokenToFormulaArg(token efp.Token) formulaArg {
}
}

// formulaArgToToken create a token by given formula argument.
func formulaArgToToken(arg formulaArg) efp.Token {
switch arg.Type {
case ArgNumber:
if arg.Boolean {
return efp.Token{TValue: arg.Value(), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeLogical}
}
return efp.Token{TValue: arg.Value(), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber}
default:
return efp.Token{TValue: arg.Value(), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeText}
}
}

// parseToken parse basic arithmetic operator priority and evaluate based on
// operators and operands.
func (f *File) parseToken(ctx *calcContext, sheet string, token efp.Token, opdStack, optStack *Stack) error {
Expand All @@ -1571,7 +1558,8 @@ func (f *File) parseToken(ctx *calcContext, sheet string, token efp.Token, opdSt
if err != nil {
return errors.New(formulaErrorNAME)
}
token = formulaArgToToken(result)
opdStack.Push(result)
return nil
}
if isOperatorPrefixToken(token) {
f.parseOperatorPrefixToken(optStack, opdStack, token)
Expand Down
45 changes: 21 additions & 24 deletions calc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2325,19 +2325,27 @@ func TestCalcCellValue(t *testing.T) {
assert.Equal(t, expected, result, formula)
}
mathCalcError := map[string][]string{
"1/0": {"", "#DIV/0!"},
"(1/0)": {"", "#DIV/0!"},
"(A1/0+B1/0)": {"", "#DIV/0!"},
"1^\"text\"": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"\"text\"^1": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"1+\"text\"": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"\"text\"+1": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"1-\"text\"": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"\"text\"-1": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"1*\"text\"": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"\"text\"*1": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"1/\"text\"": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"\"text\"/1": {"", "strconv.ParseFloat: parsing \"text\": invalid syntax"},
"1/0": {"#DIV/0!", "#DIV/0!"},
"(1/0)": {"#DIV/0!", "#DIV/0!"},
"(A1/0+B1/0)": {"#DIV/0!", "#DIV/0!"},
"1^\"text\"": {"#VALUE!", "#VALUE!"},
"\"text\"^1": {"#VALUE!", "#VALUE!"},
"1+\"text\"": {"#VALUE!", "#VALUE!"},
"\"text\"+1": {"#VALUE!", "#VALUE!"},
"1-\"text\"": {"#VALUE!", "#VALUE!"},
"\"text\"-1": {"#VALUE!", "#VALUE!"},
"1*\"text\"": {"#VALUE!", "#VALUE!"},
"\"text\"*1": {"#VALUE!", "#VALUE!"},
"1/\"text\"": {"#VALUE!", "#VALUE!"},
"\"text\"/1": {"#VALUE!", "#VALUE!"},
"\"\"+1": {"#VALUE!", "#VALUE!"},
"1+\"\"": {"#VALUE!", "#VALUE!"},
"\"\"-1": {"#VALUE!", "#VALUE!"},
"1-\"\"": {"#VALUE!", "#VALUE!"},
"\"\"*1": {"#VALUE!", "#VALUE!"},
"1*\"\"": {"#VALUE!", "#VALUE!"},
"\"\"^1": {"#VALUE!", "#VALUE!"},
"1/\"\"": {"#VALUE!", "#VALUE!"},
// Engineering Functions
// BESSELI
"BESSELI()": {"#VALUE!", "BESSELI requires 2 numeric arguments"},
Expand Down Expand Up @@ -6673,17 +6681,6 @@ func TestFormulaRawCellValueOption(t *testing.T) {
}
}

func TestFormulaArgToToken(t *testing.T) {
assert.Equal(t,
efp.Token{
TType: efp.TokenTypeOperand,
TSubType: efp.TokenSubTypeLogical,
TValue: "TRUE",
},
formulaArgToToken(newBoolFormulaArg(true)),
)
}

func TestPrepareTrendGrowth(t *testing.T) {
assert.Equal(t, [][]float64(nil), prepareTrendGrowthMtxX([][]float64{{0, 0}, {0, 0}}))
assert.Equal(t, [][]float64(nil), prepareTrendGrowthMtxY(false, [][]float64{{0, 0}, {0, 0}}))
Expand Down