Skip to content

Commit d1712c8

Browse files
committed
Don't create two function maps
1 parent 5d20467 commit d1712c8

2 files changed

Lines changed: 79 additions & 107 deletions

File tree

calculator.go

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,62 @@ import (
55
"math"
66
)
77

8+
var functions = map[string]interface{}{
9+
"abs": math.Abs,
10+
"acos": math.Acos,
11+
"acosh": math.Acosh,
12+
"asin": math.Asin,
13+
"asinh": math.Asinh,
14+
"atan": math.Atan,
15+
"atan2": math.Atan2,
16+
"atanh": math.Atanh,
17+
"cbrt": math.Cbrt,
18+
"ceil": math.Ceil,
19+
"copysign": math.Copysign,
20+
"cos": math.Cos,
21+
"cosh": math.Cosh,
22+
"dim": math.Dim,
23+
"erf": math.Erf,
24+
"erfc": math.Erfc,
25+
"erfcinv": math.Erfcinv, // Go 1.10+
26+
"erfinv": math.Erfinv, // Go 1.10+
27+
"exp": math.Exp,
28+
"exp2": math.Exp2,
29+
"expm1": math.Expm1,
30+
"fma": math.FMA, // Go 1.14+
31+
"floor": math.Floor,
32+
"gamma": math.Gamma,
33+
"hypot": math.Hypot,
34+
"j0": math.J0,
35+
"j1": math.J1,
36+
"log": math.Log,
37+
"log10": math.Log10,
38+
"log1p": math.Log1p,
39+
"log2": math.Log2,
40+
"logb": math.Logb,
41+
"max": math.Max,
42+
"min": math.Min,
43+
"mod": math.Mod,
44+
"nan": math.NaN,
45+
"nextafter": math.Nextafter,
46+
"pow": math.Pow,
47+
"remainder": math.Remainder,
48+
"round": math.Round, // Go 1.10+
49+
"roundtoeven": math.RoundToEven, // Go 1.10+
50+
"sin": math.Sin,
51+
"sinh": math.Sinh,
52+
"sqrt": math.Sqrt,
53+
"tan": math.Tan,
54+
"tanh": math.Tanh,
55+
"trunc": math.Trunc,
56+
"y0": math.Y0,
57+
"y1": math.Y1,
58+
}
59+
860
func call(funcName string, args []float64) (float64, error) {
9-
functions := map[string]interface{}{
10-
"abs": math.Abs,
11-
"acos": math.Acos,
12-
"acosh": math.Acosh,
13-
"asin": math.Asin,
14-
"asinh": math.Asinh,
15-
"atan": math.Atan,
16-
"atan2": math.Atan2,
17-
"atanh": math.Atanh,
18-
"cbrt": math.Cbrt,
19-
"ceil": math.Ceil,
20-
"copysign": math.Copysign,
21-
"cos": math.Cos,
22-
"cosh": math.Cosh,
23-
"dim": math.Dim,
24-
"erf": math.Erf,
25-
"erfc": math.Erfc,
26-
"erfcinv": math.Erfcinv,
27-
"erfinv": math.Erfinv,
28-
"exp": math.Exp,
29-
"exp2": math.Exp2,
30-
"expm1": math.Expm1,
31-
"fma": math.FMA,
32-
"floor": math.Floor,
33-
"gamma": math.Gamma,
34-
"hypot": math.Hypot,
35-
"j0": math.J0,
36-
"j1": math.J1,
37-
"log": math.Log,
38-
"log10": math.Log10,
39-
"log1p": math.Log1p,
40-
"log2": math.Log2,
41-
"logb": math.Logb,
42-
"max": math.Max,
43-
"min": math.Min,
44-
"mod": math.Mod,
45-
"nan": math.NaN,
46-
"nextafter": math.Nextafter,
47-
"pow": math.Pow,
48-
"remainder": math.Remainder,
49-
"round": math.Round,
50-
"roundtoeven": math.RoundToEven,
51-
"sin": math.Sin,
52-
"sinh": math.Sinh,
53-
"sqrt": math.Sqrt,
54-
"tan": math.Tan,
55-
"tanh": math.Tanh,
56-
"trunc": math.Trunc,
57-
"y0": math.Y0,
58-
"y1": math.Y1,
59-
}
6061
f, ok := functions[funcName]
6162
if !ok {
62-
return 0, fmt.Errorf("function %s not found", funcName)
63+
return 0, fmt.Errorf("unknown function %s", funcName)
6364
}
6465
switch f := f.(type) {
6566
case func() float64:
@@ -70,8 +71,9 @@ func call(funcName string, args []float64) (float64, error) {
7071
return f(args[0], args[1]), nil
7172
case func(float64, float64, float64) float64:
7273
return f(args[0], args[1], args[2]), nil
74+
default:
75+
return 0, fmt.Errorf("invalid function %s", funcName)
7376
}
74-
return 0, fmt.Errorf("unknown function %s", funcName)
7577
}
7678

7779
func calculate(n *node) (float64, error) {

parser.go

Lines changed: 24 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -70,63 +70,33 @@ func (p *parser) constantNode(str string) (*node, error) {
7070
return &node{kind: numNode, val: val}, nil
7171
}
7272

73-
func (p *parser) functionNode(str string) (*node, error) {
74-
functions := map[string]int{
75-
"abs": 1,
76-
"acos": 1,
77-
"acosh": 1,
78-
"asin": 1,
79-
"asinh": 1,
80-
"atan": 1,
81-
"atan2": 2,
82-
"atanh": 1,
83-
"cbrt": 1,
84-
"ceil": 1,
85-
"copysign": 2,
86-
"cos": 1,
87-
"cosh": 1,
88-
"dim": 2,
89-
"erf": 1,
90-
"erfc": 1,
91-
"erfcinv": 1,
92-
"erfinv": 1,
93-
"exp": 1,
94-
"exp2": 1,
95-
"expm1": 1,
96-
"fma": 3,
97-
"floor": 1,
98-
"gamma": 1,
99-
"hypot": 2,
100-
"j0": 1,
101-
"j1": 1,
102-
"log": 1,
103-
"log10": 1,
104-
"log1p": 1,
105-
"log2": 1,
106-
"logb": 1,
107-
"max": 2,
108-
"min": 2,
109-
"mod": 2,
110-
"nan": 0,
111-
"nextafter": 2,
112-
"pow": 2,
113-
"remainder": 2,
114-
"round": 1,
115-
"roundtoeven": 1,
116-
"sin": 1,
117-
"sinh": 1,
118-
"sqrt": 1,
119-
"tan": 1,
120-
"tanh": 1,
121-
"trunc": 1,
122-
"y0": 1,
123-
"y1": 1,
73+
func argumentNumber(funcName string) (int, error) {
74+
f, ok := functions[funcName]
75+
if !ok {
76+
return 0, fmt.Errorf("unknown function: %s", funcName)
77+
}
78+
79+
switch f.(type) {
80+
case func() float64:
81+
return 0, nil
82+
case func(float64) float64:
83+
return 1, nil
84+
case func(float64, float64) float64:
85+
return 2, nil
86+
case func(float64, float64, float64) float64:
87+
return 3, nil
88+
default:
89+
return 0, fmt.Errorf("invalid function: %s", funcName)
12490
}
91+
}
92+
93+
func (p *parser) functionNode(str string) (*node, error) {
12594
funcName := strings.ToLower(str)
126-
num, ok := functions[funcName]
127-
if !ok {
128-
return nil, fmt.Errorf("unknown function: %s", funcName)
95+
num, err := argumentNumber(funcName)
96+
if err != nil {
97+
return nil, err
12998
}
99+
130100
if p.consume(")") {
131101
if num != 0 {
132102
return nil, fmt.Errorf("%s should have argument(s)", funcName)

0 commit comments

Comments
 (0)