summaryrefslogtreecommitdiff
path: root/calc.go
diff options
context:
space:
mode:
Diffstat (limited to 'calc.go')
-rw-r--r--calc.go70
1 files changed, 65 insertions, 5 deletions
diff --git a/calc.go b/calc.go
index d2bab1d..5b975f5 100644
--- a/calc.go
+++ b/calc.go
@@ -110,6 +110,7 @@ var tokenPriority = map[string]int{
"+": 3,
"-": 3,
"=": 2,
+ "<>": 2,
"<": 2,
"<=": 2,
">": 2,
@@ -151,11 +152,9 @@ func (f *File) CalcCellValue(sheet, cell string) (result string, err error) {
return
}
result = token.TValue
- if len(result) > 16 {
- num, e := roundPrecision(result)
- if e != nil {
- return result, err
- }
+ isNum, precision := isNumeric(result)
+ if isNum && precision > 15 {
+ num, _ := roundPrecision(result)
result = strings.ToUpper(num)
}
return
@@ -353,6 +352,12 @@ func calcEq(rOpd, lOpd string, opdStack *Stack) error {
return nil
}
+// calcNEq evaluate not equal arithmetic operations.
+func calcNEq(rOpd, lOpd string, opdStack *Stack) error {
+ opdStack.Push(efp.Token{TValue: strings.ToUpper(strconv.FormatBool(rOpd != lOpd)), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
+ return nil
+}
+
// calcL evaluate less than arithmetic operations.
func calcL(rOpd, lOpd string, opdStack *Stack) error {
lOpdVal, err := strconv.ParseFloat(lOpd, 64)
@@ -498,6 +503,7 @@ func calculate(opdStack *Stack, opt efp.Token) error {
"/": calcDiv,
"+": calcAdd,
"=": calcEq,
+ "<>": calcNEq,
"<": calcL,
"<=": calcLe,
">": calcG,
@@ -3400,6 +3406,20 @@ func (fn *formulaFuncs) CLEAN(argsList *list.List) (result string, err error) {
return
}
+// LEN returns the length of a supplied text string. The syntax of the
+// function is:
+//
+// LEN(text)
+//
+func (fn *formulaFuncs) LEN(argsList *list.List) (result string, err error) {
+ if argsList.Len() != 1 {
+ err = errors.New("LEN requires 1 string argument")
+ return
+ }
+ result = strconv.Itoa(len(argsList.Front().Value.(formulaArg).String))
+ return
+}
+
// TRIM removes extra spaces (i.e. all spaces except for single spaces between
// words or characters) from a supplied text string. The syntax of the
// function is:
@@ -3469,3 +3489,43 @@ func (fn *formulaFuncs) UPPER(argsList *list.List) (result string, err error) {
result = strings.ToUpper(argsList.Front().Value.(formulaArg).String)
return
}
+
+// Conditional Functions
+
+// IF function tests a supplied condition and returns one result if the
+// condition evaluates to TRUE, and another result if the condition evaluates
+// to FALSE. The syntax of the function is:
+//
+// IF( logical_test, value_if_true, value_if_false )
+//
+func (fn *formulaFuncs) IF(argsList *list.List) (result string, err error) {
+ if argsList.Len() == 0 {
+ err = errors.New("IF requires at least 1 argument")
+ return
+ }
+ if argsList.Len() > 3 {
+ err = errors.New("IF accepts at most 3 arguments")
+ return
+ }
+ token := argsList.Front().Value.(formulaArg)
+ var cond bool
+ switch token.Type {
+ case ArgString:
+ if cond, err = strconv.ParseBool(token.String); err != nil {
+ err = errors.New(formulaErrorVALUE)
+ return
+ }
+ if argsList.Len() == 1 {
+ result = strings.ToUpper(strconv.FormatBool(cond))
+ return
+ }
+ if cond {
+ result = argsList.Front().Next().Value.(formulaArg).String
+ return
+ }
+ if argsList.Len() == 3 {
+ result = argsList.Back().Value.(formulaArg).String
+ }
+ }
+ return
+}