Skip to content

Commit 5be37aa

Browse files
committed
Fix duration multiplication by integer
1 parent f32da1e commit 5be37aa

File tree

3 files changed

+109
-20
lines changed

3 files changed

+109
-20
lines changed

expr_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,18 @@ func TestExpr(t *testing.T) {
976976
`duration("1h") + duration("1m")`,
977977
time.Hour + time.Minute,
978978
},
979+
{
980+
`7 * duration("1h")`,
981+
7 * time.Hour,
982+
},
983+
{
984+
`duration("1h") * 7`,
985+
7 * time.Hour,
986+
},
987+
{
988+
`duration("1s") * .5`,
989+
5e8,
990+
},
979991
{
980992
`1 /* one */ + 2 // two`,
981993
3,

vm/runtime/generated.go

+53
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vm/runtime/helpers/main.go

+44-20
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
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+
80104
const helpers = `// Code generated by vm/runtime/helpers/main.go. DO NOT EDIT.
81105
82106
package runtime
@@ -245,7 +269,7 @@ func Subtract(a, b interface{}) interface{} {
245269
246270
func 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

Comments
 (0)