44 "bytes"
55 "fmt"
66 "go/format"
7+ "os"
78 "strings"
89 "text/template"
910)
@@ -13,11 +14,14 @@ func main() {
1314 err := template .Must (
1415 template .New ("helpers" ).
1516 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+ },
1822 }).
1923 Parse (helpers ),
20- ).Execute (& b , types )
24+ ).Execute (& b , nil )
2125 if err != nil {
2226 panic (err )
2327 }
@@ -29,40 +33,48 @@ func main() {
2933 fmt .Print (string (formatted ))
3034}
3135
32- var types = []string {
33- "uint" ,
34- "uint8" ,
35- "uint16" ,
36- "uint32" ,
37- "uint64" ,
36+ var ints = []string {
3837 "int" ,
3938 "int8" ,
4039 "int16" ,
4140 "int32" ,
4241 "int64" ,
42+ }
43+
44+ var uints = []string {
45+ "uint" ,
46+ "uint8" ,
47+ "uint16" ,
48+ "uint32" ,
49+ "uint64" ,
50+ }
51+
52+ var floats = []string {
4353 "float32" ,
4454 "float64" ,
4555}
4656
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+
4865 var out string
4966 echo := func (s string , xs ... any ) {
5067 out += fmt .Sprintf (s , xs ... ) + "\n "
5168 }
5269 for _ , a := range types {
53- aIsFloat := strings .HasPrefix (a , "float" )
54- if noFloat && aIsFloat {
55- continue
56- }
5770 echo (`case %v:` , a )
5871 echo (`switch y := b.(type) {` )
5972 for _ , b := range types {
60- bIsFloat := strings .HasPrefix (b , "float" )
61- if noFloat && bIsFloat {
62- continue
63- }
6473 t := "int"
65- if aIsFloat || bIsFloat {
74+ if isDuration (a ) || isDuration (b ) {
75+ t = "time.Duration"
76+ }
77+ if isFloat (a ) || isFloat (b ) {
6678 t = "float64"
6779 }
6880 echo (`case %v:` , b )
@@ -77,6 +89,18 @@ func cases(op string, noFloat bool) string {
7789 return strings .TrimRight (out , "\n " )
7890}
7991
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+
80104const helpers = `// Code generated by vm/runtime/helpers/main.go. DO NOT EDIT.
81105
82106package runtime
@@ -245,7 +269,7 @@ func Subtract(a, b interface{}) interface{} {
245269
246270func Multiply(a, b interface{}) interface{} {
247271 switch x := a.(type) {
248- {{ cases "*" }}
272+ {{ cases_with_duration "*" }}
249273 }
250274 panic(fmt.Sprintf("invalid operation: %T * %T", a, b))
251275}
0 commit comments