4
4
"bytes"
5
5
"fmt"
6
6
"go/format"
7
+ "os"
7
8
"strings"
8
9
"text/template"
9
10
)
@@ -13,11 +14,14 @@ func main() {
13
14
err := template .Must (
14
15
template .New ("helpers" ).
15
16
Funcs (template.FuncMap {
16
- "cases" : func (op string ) string { return cases (op , false ) },
17
- "cases_int_only" : func (op string ) string { return cases (op , true ) },
17
+ "cases" : func (op string ) string { return cases (op , uints , ints , floats ) },
18
+ "cases_int_only" : func (op string ) string { return cases (op , uints , ints ) },
19
+ "cases_with_duration" : func (op string ) string {
20
+ return cases (op , uints , ints , floats , []string {"time.Duration" })
21
+ },
18
22
}).
19
23
Parse (helpers ),
20
- ).Execute (& b , types )
24
+ ).Execute (& b , nil )
21
25
if err != nil {
22
26
panic (err )
23
27
}
@@ -29,40 +33,48 @@ func main() {
29
33
fmt .Print (string (formatted ))
30
34
}
31
35
32
- var types = []string {
33
- "uint" ,
34
- "uint8" ,
35
- "uint16" ,
36
- "uint32" ,
37
- "uint64" ,
36
+ var ints = []string {
38
37
"int" ,
39
38
"int8" ,
40
39
"int16" ,
41
40
"int32" ,
42
41
"int64" ,
42
+ }
43
+
44
+ var uints = []string {
45
+ "uint" ,
46
+ "uint8" ,
47
+ "uint16" ,
48
+ "uint32" ,
49
+ "uint64" ,
50
+ }
51
+
52
+ var floats = []string {
43
53
"float32" ,
44
54
"float64" ,
45
55
}
46
56
47
- func cases (op string , noFloat bool ) string {
57
+ func cases (op string , xs ... []string ) string {
58
+ var types []string
59
+ for _ , x := range xs {
60
+ types = append (types , x ... )
61
+ }
62
+
63
+ _ , _ = fmt .Fprintf (os .Stderr , "Generating %s cases for %v\n " , op , types )
64
+
48
65
var out string
49
66
echo := func (s string , xs ... any ) {
50
67
out += fmt .Sprintf (s , xs ... ) + "\n "
51
68
}
52
69
for _ , a := range types {
53
- aIsFloat := strings .HasPrefix (a , "float" )
54
- if noFloat && aIsFloat {
55
- continue
56
- }
57
70
echo (`case %v:` , a )
58
71
echo (`switch y := b.(type) {` )
59
72
for _ , b := range types {
60
- bIsFloat := strings .HasPrefix (b , "float" )
61
- if noFloat && bIsFloat {
62
- continue
63
- }
64
73
t := "int"
65
- if aIsFloat || bIsFloat {
74
+ if isDuration (a ) || isDuration (b ) {
75
+ t = "time.Duration"
76
+ }
77
+ if isFloat (a ) || isFloat (b ) {
66
78
t = "float64"
67
79
}
68
80
echo (`case %v:` , b )
@@ -77,6 +89,18 @@ func cases(op string, noFloat bool) string {
77
89
return strings .TrimRight (out , "\n " )
78
90
}
79
91
92
+ func isFloat (t string ) bool {
93
+ return strings .HasPrefix (t , "float" )
94
+ }
95
+
96
+ func isInt (t string ) bool {
97
+ return strings .HasPrefix (t , "int" )
98
+ }
99
+
100
+ func isDuration (t string ) bool {
101
+ return t == "time.Duration"
102
+ }
103
+
80
104
const helpers = `// Code generated by vm/runtime/helpers/main.go. DO NOT EDIT.
81
105
82
106
package runtime
@@ -245,7 +269,7 @@ func Subtract(a, b interface{}) interface{} {
245
269
246
270
func Multiply(a, b interface{}) interface{} {
247
271
switch x := a.(type) {
248
- {{ cases "*" }}
272
+ {{ cases_with_duration "*" }}
249
273
}
250
274
panic(fmt.Sprintf("invalid operation: %T * %T", a, b))
251
275
}
0 commit comments