formula: support for more math/trig formulas

- EVEN
- EXP
- FACT
- FACTDOUBLE
- FLOOR.MATH
- FLOOR.PRECISE
- GCD
- INT
- ISO.CEILING
- LCM
- LN
- LOG
- LOG10
This commit is contained in:
Todd 2017-09-16 09:37:11 -05:00
parent 341c2ef03e
commit e0786dae4a
4 changed files with 459 additions and 117 deletions

View File

@ -41,6 +41,20 @@ func init() {
//RegisterFunction("CSCH" //RegisterFunction("CSCH"
RegisterFunction("_xlfn.DECIMAL", Decimal) RegisterFunction("_xlfn.DECIMAL", Decimal)
RegisterFunction("DEGREES", Degrees) RegisterFunction("DEGREES", Degrees)
RegisterFunction("EVEN", Even)
RegisterFunction("EXP", makeMathWrapper("EXP", math.Exp))
RegisterFunction("FACT", Fact)
RegisterFunction("FACTDOUBLE", FactDouble)
//RegisterFunction("FLOOR", )
RegisterFunction("_xlfn.FLOOR.MATH", FloorMath)
RegisterFunction("_xlfn.FLOOR.PRECISE", FloorPrecise)
RegisterFunction("GCD", GCD)
RegisterFunction("INT", Int)
RegisterFunction("ISO.CEILING", CeilingPrecise) // appears to be the same from what I can tell
RegisterFunction("LCM", LCM)
RegisterFunction("LN", makeMathWrapper("LN", math.Log))
RegisterFunction("LOG", Log)
RegisterFunction("LOG10", makeMathWrapper("LOG10", math.Log10))
RegisterFunction("PI", Pi) RegisterFunction("PI", Pi)
} }
@ -56,9 +70,12 @@ func makeMathWrapper(name string, fn func(x float64) float64) Function {
switch arg.Type { switch arg.Type {
case ResultTypeNumber: case ResultTypeNumber:
v := fn(arg.ValueNumber) v := fn(arg.ValueNumber)
if v != v { if math.IsNaN(v) {
return MakeErrorResult(name + " returned NaN") return MakeErrorResult(name + " returned NaN")
} }
if math.IsInf(v, 0) {
return MakeErrorResult(name + " returned infinity")
}
return MakeNumberResult(v) return MakeNumberResult(v)
case ResultTypeList, ResultTypeString: case ResultTypeList, ResultTypeString:
return MakeErrorResult(name + " requires a numeric argument") return MakeErrorResult(name + " requires a numeric argument")
@ -169,7 +186,7 @@ func CeilingMath(args []Result) Result {
// number to round // number to round
number := args[0].AsNumber() number := args[0].AsNumber()
if number.Type != ResultTypeNumber { if number.Type != ResultTypeNumber {
return MakeErrorResult("first arugment to CEILING.MATH() must be a number") return MakeErrorResult("first argument to CEILING.MATH() must be a number")
} }
// significance // significance
@ -180,7 +197,7 @@ func CeilingMath(args []Result) Result {
if len(args) > 1 { if len(args) > 1 {
sigArg := args[1].AsNumber() sigArg := args[1].AsNumber()
if sigArg.Type != ResultTypeNumber { if sigArg.Type != ResultTypeNumber {
return MakeErrorResult("second arugment to CEILING.MATH() must be a number") return MakeErrorResult("second argument to CEILING.MATH() must be a number")
} }
significance = sigArg.ValueNumber significance = sigArg.ValueNumber
} }
@ -190,7 +207,7 @@ func CeilingMath(args []Result) Result {
if len(args) > 2 { if len(args) > 2 {
dirArg := args[2].AsNumber() dirArg := args[2].AsNumber()
if dirArg.Type != ResultTypeNumber { if dirArg.Type != ResultTypeNumber {
return MakeErrorResult("third arugment to CEILING.MATH() must be a number") return MakeErrorResult("third argument to CEILING.MATH() must be a number")
} }
direction = dirArg.ValueNumber direction = dirArg.ValueNumber
} }
@ -211,6 +228,8 @@ func CeilingMath(args []Result) Result {
return MakeNumberResult(v * significance) return MakeNumberResult(v * significance)
} }
// CeilingPrecise is an implementation of the CEILING.PRECISE function which
// returns the ceiling of a number.
func CeilingPrecise(args []Result) Result { func CeilingPrecise(args []Result) Result {
if len(args) == 0 { if len(args) == 0 {
return MakeErrorResult("CEILING.PRECISE() requires at least one argument") return MakeErrorResult("CEILING.PRECISE() requires at least one argument")
@ -221,7 +240,7 @@ func CeilingPrecise(args []Result) Result {
// number to round // number to round
number := args[0].AsNumber() number := args[0].AsNumber()
if number.Type != ResultTypeNumber { if number.Type != ResultTypeNumber {
return MakeErrorResult("first arugment to CEILING.PRECISE() must be a number") return MakeErrorResult("first argument to CEILING.PRECISE() must be a number")
} }
// significance // significance
@ -232,7 +251,7 @@ func CeilingPrecise(args []Result) Result {
if len(args) > 1 { if len(args) > 1 {
sigArg := args[1].AsNumber() sigArg := args[1].AsNumber()
if sigArg.Type != ResultTypeNumber { if sigArg.Type != ResultTypeNumber {
return MakeErrorResult("second arugment to CEILING.MATH() must be a number") return MakeErrorResult("second argument to CEILING.MATH() must be a number")
} }
// don't care about sign of significance // don't care about sign of significance
significance = math.Abs(sigArg.ValueNumber) significance = math.Abs(sigArg.ValueNumber)
@ -265,12 +284,12 @@ func Base(args []Result) Result {
// number to convert // number to convert
number := args[0].AsNumber() number := args[0].AsNumber()
if number.Type != ResultTypeNumber { if number.Type != ResultTypeNumber {
return MakeErrorResult("first arugment to BASE() must be a number") return MakeErrorResult("first argument to BASE() must be a number")
} }
radixArg := args[1].AsNumber() radixArg := args[1].AsNumber()
if radixArg.Type != ResultTypeNumber { if radixArg.Type != ResultTypeNumber {
return MakeErrorResult("second arugment to BASE() must be a number") return MakeErrorResult("second argument to BASE() must be a number")
} }
radix := int(radixArg.ValueNumber) radix := int(radixArg.ValueNumber)
if radix < 0 || radix > 36 { if radix < 0 || radix > 36 {
@ -282,7 +301,7 @@ func Base(args []Result) Result {
if len(args) > 2 { if len(args) > 2 {
lenArg := args[2].AsNumber() lenArg := args[2].AsNumber()
if lenArg.Type != ResultTypeNumber { if lenArg.Type != ResultTypeNumber {
return MakeErrorResult("third arugment to BASE() must be a number") return MakeErrorResult("third argument to BASE() must be a number")
} }
minLength = int(lenArg.ValueNumber) minLength = int(lenArg.ValueNumber)
} }
@ -346,14 +365,6 @@ func Combina(args []Result) Result {
return Combin(args) return Combin(args)
} }
func fact(f float64) float64 {
res := float64(1)
for i := float64(2); i <= f; i++ {
res *= i
}
return res
}
// Decimal is an implementation of the Excel function DECIMAL() that parses a string // Decimal is an implementation of the Excel function DECIMAL() that parses a string
// in a given base and returns the numeric result. // in a given base and returns the numeric result.
func Decimal(args []Result) Result { func Decimal(args []Result) Result {
@ -394,6 +405,337 @@ func Degrees(args []Result) Result {
return MakeNumberResult(180.0 / math.Pi * vArg.ValueNumber) return MakeNumberResult(180.0 / math.Pi * vArg.ValueNumber)
} }
// Even is an implementation of the Excel EVEN() that rounds a number to the
// nearest even integer.
func Even(args []Result) Result {
if len(args) != 1 {
return MakeErrorResult("EVEN() requires one argument")
}
vArg := args[0].AsNumber()
if vArg.Type != ResultTypeNumber {
return MakeErrorResult("EVEN() requires number argument")
}
sign := math.Signbit(vArg.ValueNumber)
m, r := math.Modf(vArg.ValueNumber / 2)
v := m * 2
if r != 0 {
if !sign {
v += 2
} else {
v -= 2
}
}
return MakeNumberResult(v)
}
func fact(f float64) float64 {
res := float64(1)
for i := float64(2); i <= f; i++ {
res *= i
}
return res
}
// Fact is an implementation of the excel FACT function which returns the
// factorial of a positive numeric input.
func Fact(args []Result) Result {
if len(args) != 1 {
return MakeErrorResult("FACT() accepts a single numeric argument")
}
vArg := args[0].AsNumber()
if vArg.Type != ResultTypeNumber {
return MakeErrorResult("FACT() accepts a single numeric argument")
}
if vArg.ValueNumber < 0 {
return MakeErrorResult("FACT() accepts only positive arguments")
}
return MakeNumberResult(fact(vArg.ValueNumber))
}
// FactDouble is an implementation of the excel FACTDOUBLE function which
// returns the double factorial of a positive numeric input.
func FactDouble(args []Result) Result {
if len(args) != 1 {
return MakeErrorResult("FACTDOUBLE() accepts a single numeric argument")
}
vArg := args[0].AsNumber()
if vArg.Type != ResultTypeNumber {
return MakeErrorResult("FACTDOUBLE() accepts a single numeric argument")
}
if vArg.ValueNumber < 0 {
return MakeErrorResult("FACTDOUBLE() accepts only positive arguments")
}
res := float64(1)
v := math.Trunc(vArg.ValueNumber)
for i := v; i > 1; i -= 2 {
res *= i
}
return MakeNumberResult(res)
}
// FloorMath implements _xlfn.FLOOR.MATH which rounds numbers down to the
// nearest multiple of the second argument, toward or away from zero as
// specified by the third argument.
func FloorMath(args []Result) Result {
if len(args) == 0 {
return MakeErrorResult("FLOOR.MATH() requires at least one argument")
}
if len(args) > 3 {
return MakeErrorResult("FLOOR.MATH() allows at most three arguments")
}
// number to round
number := args[0].AsNumber()
if number.Type != ResultTypeNumber {
return MakeErrorResult("first argument to FLOOR.MATH() must be a number")
}
// significance
significance := float64(1)
if number.ValueNumber < 0 {
significance = -1
}
if len(args) > 1 {
sigArg := args[1].AsNumber()
if sigArg.Type != ResultTypeNumber {
return MakeErrorResult("second argument to FLOOR.MATH() must be a number")
}
significance = sigArg.ValueNumber
}
// round direction
direction := float64(1)
if len(args) > 2 {
dirArg := args[2].AsNumber()
if dirArg.Type != ResultTypeNumber {
return MakeErrorResult("third argument to FLOOR.MATH() must be a number")
}
direction = dirArg.ValueNumber
}
if len(args) == 1 {
return MakeNumberResult(math.Floor(number.ValueNumber))
}
v := number.ValueNumber
v, res := math.Modf(v / significance)
if res != 0 && number.ValueNumber < 0 && direction > 0 {
v++
}
return MakeNumberResult(v * significance)
}
// FloorPrecise is an implementation of the FlOOR.PRECISE function.
func FloorPrecise(args []Result) Result {
if len(args) == 0 {
return MakeErrorResult("FLOOR.PRECISE() requires at least one argument")
}
if len(args) > 2 {
return MakeErrorResult("FLOOR.PRECISE() allows at most two arguments")
}
// number to round
number := args[0].AsNumber()
if number.Type != ResultTypeNumber {
return MakeErrorResult("first argument to FLOOR.PRECISE() must be a number")
}
// significance
significance := float64(1)
if number.ValueNumber < 0 {
significance = -1
}
if len(args) > 1 {
sigArg := args[1].AsNumber()
if sigArg.Type != ResultTypeNumber {
return MakeErrorResult("second argument to FLOOR.MATH() must be a number")
}
// don't care about sign of significance
significance = math.Abs(sigArg.ValueNumber)
}
if len(args) == 1 {
return MakeNumberResult(math.Floor(number.ValueNumber))
}
v := number.ValueNumber
v, res := math.Modf(v / significance)
if res != 0 {
if number.ValueNumber < 0 {
v--
}
}
return MakeNumberResult(v * significance)
}
func gcd(a, b float64) float64 {
a = math.Trunc(a)
b = math.Trunc(b)
if a == 0 {
return b
}
if b == 0 {
return a
}
for a != b {
if a > b {
a = a - b
} else {
b = b - a
}
}
return a
}
// GCD implements the Excel GCD() function which returns the greatest common
// divisor of a range of numbers.
func GCD(args []Result) Result {
if len(args) == 0 {
return MakeErrorResult("GCD() requires at least one argument")
}
numbers := []float64{}
for _, arg := range args {
switch arg.Type {
case ResultTypeString:
na := arg.AsNumber()
if na.Type != ResultTypeNumber {
return MakeErrorResult("GCD() only accepts numeric arguments")
}
numbers = append(numbers, na.ValueNumber)
case ResultTypeList:
res := GCD(arg.ValueList)
if res.Type != ResultTypeNumber {
return res
}
numbers = append(numbers, res.ValueNumber)
case ResultTypeNumber:
numbers = append(numbers, arg.ValueNumber)
case ResultTypeError:
return arg
}
}
if numbers[0] < 0 {
return MakeErrorResult("GCD() only accepts positive arguments")
}
if len(numbers) == 1 {
return MakeNumberResult(numbers[0])
}
res := numbers[0]
for i := 1; i < len(numbers); i++ {
if numbers[i] < 0 {
return MakeErrorResult("GCD() only accepts positive arguments")
}
res = gcd(res, numbers[i])
}
return MakeNumberResult(res)
}
func lcm(a, b float64) float64 {
a = math.Trunc(a)
b = math.Trunc(b)
if a == 0 && b == 0 {
return 0
}
return a * b / gcd(a, b)
}
// LCM implements the Excel LCM() function which returns the least common
// multiple of a range of numbers.
func LCM(args []Result) Result {
if len(args) == 0 {
return MakeErrorResult("LCM() requires at least one argument")
}
numbers := []float64{}
for _, arg := range args {
switch arg.Type {
case ResultTypeString:
na := arg.AsNumber()
if na.Type != ResultTypeNumber {
return MakeErrorResult("LCM() only accepts numeric arguments")
}
numbers = append(numbers, na.ValueNumber)
case ResultTypeList:
res := LCM(arg.ValueList)
if res.Type != ResultTypeNumber {
return res
}
numbers = append(numbers, res.ValueNumber)
case ResultTypeNumber:
numbers = append(numbers, arg.ValueNumber)
case ResultTypeError:
return arg
}
}
if numbers[0] < 0 {
return MakeErrorResult("LCM() only accepts positive arguments")
}
if len(numbers) == 1 {
return MakeNumberResult(numbers[0])
}
res := numbers[0]
for i := 1; i < len(numbers); i++ {
if numbers[i] < 0 {
return MakeErrorResult("LCM() only accepts positive arguments")
}
res = lcm(res, numbers[i])
}
return MakeNumberResult(res)
}
// Int is an implementation of the Excel INT() function that rounds a number
// down to an integer.
func Int(args []Result) Result {
if len(args) != 1 {
return MakeErrorResult("INT() requires a single numeric argument")
}
nArg := args[0].AsNumber()
if nArg.Type != ResultTypeNumber {
return MakeErrorResult("INT() requires a single numeric argument")
}
trunc, rem := math.Modf(nArg.ValueNumber)
if rem < 0 {
trunc--
}
return MakeNumberResult(trunc)
}
// Log implements the Excel LOG function which returns the log of a number. By
// default the result is base 10, however the second argument to the function
// can specify a different base.
func Log(args []Result) Result {
if len(args) == 0 {
return MakeErrorResult("LOG() requires at least one numeric argument")
}
if len(args) > 2 {
return MakeErrorResult("LOG() accepts a maximum of two arguments")
}
nArg := args[0].AsNumber()
if nArg.Type != ResultTypeNumber {
return MakeErrorResult("LOG() requires at least one numeric argument")
}
base := 10.0
if len(args) > 1 {
bArg := args[1].AsNumber()
if bArg.Type != ResultTypeNumber {
return MakeErrorResult("LOG() requires second argument to be numeric")
}
base = args[1].ValueNumber
}
if nArg.ValueNumber == 0 {
return MakeErrorResult("LOG() requires first argument to be non-zero")
}
if base == 0 {
return MakeErrorResult("LOG() requires second argument to be non-zero")
}
return MakeNumberResult(math.Log(nArg.ValueNumber) / math.Log(base))
}
// Pi is an implementation of the Excel Pi() function that just returns the Pi // Pi is an implementation of the Excel Pi() function that just returns the Pi
// constant. // constant.
func Pi(args []Result) Result { func Pi(args []Result) Result {

View File

@ -596,8 +596,8 @@ func (l *Lexer) lex(r io.Reader) {
switch data[p] { switch data[p] {
case 36: case 36:
goto tr61 goto tr61
case 47: case 46:
goto tr55 goto tr72
case 123: case 123:
goto tr55 goto tr55
case 125: case 125:
@ -606,9 +606,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -620,7 +620,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -630,35 +630,35 @@ func (l *Lexer) lex(r io.Reader) {
switch data[p] { switch data[p] {
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr74 goto tr72
case 123: case 123:
goto tr74 goto tr55
case 125: case 125:
goto tr74 goto tr55
} }
switch { switch {
case data[p] < 48: case data[p] < 48:
switch { switch {
case data[p] > 35: case data[p] > 35:
if 37 <= data[p] && data[p] <= 45 { if 37 <= data[p] && data[p] <= 47 {
goto tr74 goto tr55
} }
case data[p] >= 34: case data[p] >= 34:
goto tr74 goto tr55
} }
case data[p] > 57: case data[p] > 57:
switch { switch {
case data[p] < 65: case data[p] < 65:
if 58 <= data[p] && data[p] <= 63 { if 58 <= data[p] && data[p] <= 63 {
goto tr74 goto tr55
} }
case data[p] > 90: case data[p] > 90:
if 91 <= data[p] && data[p] <= 95 { if 91 <= data[p] && data[p] <= 95 {
goto tr74 goto tr55
} }
default: default:
goto tr76 goto tr72
} }
default: default:
goto tr72 goto tr72
@ -668,38 +668,38 @@ func (l *Lexer) lex(r io.Reader) {
switch data[p] { switch data[p] {
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr55 goto tr72
case 123: case 123:
goto tr55 goto tr76
case 125: case 125:
goto tr55 goto tr76
} }
switch { switch {
case data[p] < 48: case data[p] < 48:
switch { switch {
case data[p] > 35: case data[p] > 35:
if 37 <= data[p] && data[p] <= 45 { if 37 <= data[p] && data[p] <= 47 {
goto tr55 goto tr76
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr76
} }
case data[p] > 57: case data[p] > 57:
switch { switch {
case data[p] < 65: case data[p] < 65:
if 58 <= data[p] && data[p] <= 63 { if 58 <= data[p] && data[p] <= 63 {
goto tr55 goto tr76
} }
case data[p] > 90: case data[p] > 90:
if 91 <= data[p] && data[p] <= 95 { if 91 <= data[p] && data[p] <= 95 {
goto tr55
}
default:
goto tr76 goto tr76
} }
default: default:
goto tr76 goto tr72
}
default:
goto tr73
} }
goto tr31 goto tr31
case 43: case 43:
@ -708,8 +708,8 @@ func (l *Lexer) lex(r io.Reader) {
goto tr61 goto tr61
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr0 goto tr72
case 123: case 123:
goto tr0 goto tr0
case 125: case 125:
@ -718,9 +718,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr0 goto tr0
@ -732,7 +732,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr0 goto tr0
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr0 goto tr0
@ -742,8 +742,8 @@ func (l *Lexer) lex(r io.Reader) {
switch data[p] { switch data[p] {
case 36: case 36:
goto tr61 goto tr61
case 47: case 46:
goto tr55 goto tr72
case 65: case 65:
goto tr77 goto tr77
case 123: case 123:
@ -754,9 +754,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -768,7 +768,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 66: case data[p] >= 66:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -780,8 +780,8 @@ func (l *Lexer) lex(r io.Reader) {
goto tr61 goto tr61
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr55 goto tr72
case 76: case 76:
goto tr78 goto tr78
case 123: case 123:
@ -792,9 +792,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -806,7 +806,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -818,8 +818,8 @@ func (l *Lexer) lex(r io.Reader) {
goto tr61 goto tr61
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr55 goto tr72
case 83: case 83:
goto tr79 goto tr79
case 123: case 123:
@ -830,9 +830,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -844,7 +844,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -856,8 +856,8 @@ func (l *Lexer) lex(r io.Reader) {
goto tr61 goto tr61
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr55 goto tr72
case 69: case 69:
goto tr80 goto tr80
case 123: case 123:
@ -868,9 +868,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -882,7 +882,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -892,8 +892,8 @@ func (l *Lexer) lex(r io.Reader) {
switch data[p] { switch data[p] {
case 36: case 36:
goto tr61 goto tr61
case 47: case 46:
goto tr55 goto tr72
case 79: case 79:
goto tr81 goto tr81
case 82: case 82:
@ -906,9 +906,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -920,7 +920,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -932,8 +932,8 @@ func (l *Lexer) lex(r io.Reader) {
goto tr61 goto tr61
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr55 goto tr72
case 68: case 68:
goto tr83 goto tr83
case 123: case 123:
@ -944,9 +944,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -958,7 +958,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -970,8 +970,8 @@ func (l *Lexer) lex(r io.Reader) {
goto tr61 goto tr61
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr55 goto tr72
case 79: case 79:
goto tr84 goto tr84
case 123: case 123:
@ -982,9 +982,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -996,7 +996,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -1008,8 +1008,8 @@ func (l *Lexer) lex(r io.Reader) {
goto tr61 goto tr61
case 40: case 40:
goto tr75 goto tr75
case 47: case 46:
goto tr55 goto tr72
case 85: case 85:
goto tr79 goto tr79
case 123: case 123:
@ -1020,9 +1020,9 @@ func (l *Lexer) lex(r io.Reader) {
switch { switch {
case data[p] < 58: case data[p] < 58:
switch { switch {
case data[p] > 45: case data[p] > 47:
if 48 <= data[p] && data[p] <= 57 { if 48 <= data[p] && data[p] <= 57 {
goto tr72 goto tr73
} }
case data[p] >= 34: case data[p] >= 34:
goto tr55 goto tr55
@ -1034,7 +1034,7 @@ func (l *Lexer) lex(r io.Reader) {
goto tr55 goto tr55
} }
case data[p] >= 65: case data[p] >= 65:
goto tr73 goto tr74
} }
default: default:
goto tr55 goto tr55
@ -1295,10 +1295,10 @@ func (l *Lexer) lex(r io.Reader) {
tr71: tr71:
cs = 27 cs = 27
goto f32 goto f32
tr74: tr75:
cs = 27 cs = 27
goto f33 goto f33
tr75: tr76:
cs = 27 cs = 27
goto f34 goto f34
tr85: tr85:
@ -1352,10 +1352,10 @@ func (l *Lexer) lex(r io.Reader) {
tr72: tr72:
cs = 41 cs = 41
goto _again goto _again
tr76: tr73:
cs = 42 cs = 42
goto _again goto _again
tr73: tr74:
cs = 43 cs = 43
goto f24 goto f24
tr80: tr80:
@ -1401,7 +1401,7 @@ func (l *Lexer) lex(r io.Reader) {
f4: f4:
_acts = 7 _acts = 7
goto execFuncs goto execFuncs
f34: f33:
_acts = 9 _acts = 9
goto execFuncs goto execFuncs
f5: f5:
@ -1458,7 +1458,7 @@ func (l *Lexer) lex(r io.Reader) {
f27: f27:
_acts = 45 _acts = 45
goto execFuncs goto execFuncs
f33: f34:
_acts = 47 _acts = 47
goto execFuncs goto execFuncs
f25: f25:
@ -1858,9 +1858,9 @@ func (l *Lexer) lex(r io.Reader) {
case 40: case 40:
goto tr55 goto tr55
case 41: case 41:
goto tr74
case 42:
goto tr55 goto tr55
case 42:
goto tr76
case 43: case 43:
goto tr0 goto tr0
case 44: case 44:

View File

@ -34,7 +34,7 @@ import (
horizontalRange = '$'? [0-9]+ ':' '$'? [0-9]+; horizontalRange = '$'? [0-9]+ ':' '$'? [0-9]+;
# there is a function list at https://msdn.microsoft.com/en-us/library/dd906358(v=office.12).aspx # there is a function list at https://msdn.microsoft.com/en-us/library/dd906358(v=office.12).aspx
builtinFunction = [A-Z] [A-Z0-9]+ '('; builtinFunction = [A-Z] [A-Z0-9.]+ '(';
excelFn = '_xlfn.' [A-Z_] [A-Z0-9.]+ '('; excelFn = '_xlfn.' [A-Z_] [A-Z0-9.]+ '(';
sheetChar = ^['%\[\]\\:/?();{}#"=<>&+\-*/^%,_]; sheetChar = ^['%\[\]\\:/?();{}#"=<>&+\-*/^%,_];