diff options
-rw-r--r-- | calc.go | 10 | ||||
-rw-r--r-- | calc_test.go | 20 |
2 files changed, 26 insertions, 4 deletions
@@ -726,6 +726,7 @@ func (f *File) evalInfixExp(sheet, cell string, tokens []efp.Token) (efp.Token, if isFunctionStartToken(token) { opfStack.Push(token) argsStack.Push(list.New().Init()) + opftStack.Push(token) // to know which operators belong to a function use the function as a separator continue } @@ -738,7 +739,7 @@ func (f *File) evalInfixExp(sheet, cell string, tokens []efp.Token) (efp.Token, // current token is args or range, skip next token, order required: parse reference first if token.TSubType == efp.TokenSubTypeRange { - if !opftStack.Empty() { + if opftStack.Peek().(efp.Token) != opfStack.Peek().(efp.Token) { refTo := f.getDefinedNameRefTo(token.TValue, sheet) if refTo != "" { token.TValue = refTo @@ -783,7 +784,7 @@ func (f *File) evalInfixExp(sheet, cell string, tokens []efp.Token) (efp.Token, // current token is arg if token.TType == efp.TokenTypeArgument { - for !opftStack.Empty() { + for opftStack.Peek().(efp.Token) != opfStack.Peek().(efp.Token) { // calculate trigger topOpt := opftStack.Peek().(efp.Token) if err := calculate(opfdStack, topOpt); err != nil { @@ -826,7 +827,7 @@ func (f *File) evalInfixExpFunc(sheet, cell string, token, nextToken efp.Token, return nil } // current token is function stop - for !opftStack.Empty() { + for opftStack.Peek().(efp.Token) != opfStack.Peek().(efp.Token) { // calculate trigger topOpt := opftStack.Peek().(efp.Token) if err := calculate(opfdStack, topOpt); err != nil { @@ -847,9 +848,10 @@ func (f *File) evalInfixExpFunc(sheet, cell string, token, nextToken efp.Token, return errors.New(arg.Value()) } argsStack.Pop() + opftStack.Pop() // remove current function separator opfStack.Pop() if opfStack.Len() > 0 { // still in function stack - if nextToken.TType == efp.TokenTypeOperatorInfix { + if nextToken.TType == efp.TokenTypeOperatorInfix || opftStack.Len() > 1 { // mathematics calculate in formula function opfdStack.Push(efp.Token{TValue: arg.Value(), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber}) } else { diff --git a/calc_test.go b/calc_test.go index 50f8023..a2b1294 100644 --- a/calc_test.go +++ b/calc_test.go @@ -3787,3 +3787,23 @@ func TestGetYearDays(t *testing.T) { assert.Equal(t, data[2], getYearDays(data[0], data[1])) } } + +func TestNestedFunctionsWithOperators(t *testing.T) { + f := NewFile() + formulaList := map[string]string{ + `=LEN("KEEP")`: "4", + `=LEN("REMOVEKEEP") - LEN("REMOVE")`: "4", + `=RIGHT("REMOVEKEEP", 4)`: "KEEP", + `=RIGHT("REMOVEKEEP", 10 - 6))`: "KEEP", + `=RIGHT("REMOVEKEEP", LEN("REMOVEKEEP") - 6)`: "KEEP", + `=RIGHT("REMOVEKEEP", LEN("REMOVEKEEP") - LEN("REMOV") - 1)`: "KEEP", + `=RIGHT("REMOVEKEEP", 10 - LEN("REMOVE"))`: "KEEP", + `=RIGHT("REMOVEKEEP", LEN("REMOVEKEEP") - LEN("REMOVE"))`: "KEEP", + } + for formula, expected := range formulaList { + assert.NoError(t, f.SetCellFormula("Sheet1", "E1", formula)) + result, err := f.CalcCellValue("Sheet1", "E1") + assert.NoError(t, err, formula) + assert.Equal(t, expected, result, formula) + } +} |