cue: support multiplication of strings and bytes
Change-Id: I5df8c4449843a2623e9854ab9b1fc625f98b8821
Reviewed-on: https://cue-review.googlesource.com/c/1543
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cue/binop.go b/cue/binop.go
index c534fc9..ada9cc9 100644
--- a/cue/binop.go
+++ b/cue/binop.go
@@ -605,7 +605,7 @@
}
func (x *stringLit) binOp(ctx *context, src source, op op, other evaluated) evaluated {
- switch other.(type) {
+ switch y := other.(type) {
// case *basicType:
// return x
@@ -624,7 +624,8 @@
case opLss, opLeq, opEql, opNeq, opGeq, opGtr:
return cmpTonode(src, op, strings.Compare(x.str, str))
case opAdd:
- return &stringLit{binSrc(src.Pos(), op, x, other), x.str + str}
+ src := binSrc(src.Pos(), op, x, other)
+ return &stringLit{src, x.str + str}
case opMat:
b, err := regexp.MatchString(str, x.str)
if err != nil {
@@ -638,6 +639,12 @@
}
return boolTonode(src, !b)
}
+ case *numLit:
+ switch op {
+ case opMul:
+ src := binSrc(src.Pos(), op, x, other)
+ return &stringLit{src, strings.Repeat(x.str, y.intValue(ctx))}
+ }
}
return ctx.mkIncompatible(src, op, x, other)
}
@@ -664,6 +671,13 @@
copy = append(copy, b...)
return &bytesLit{binSrc(src.Pos(), op, x, other), copy}
}
+
+ case *numLit:
+ switch op {
+ case opMul:
+ src := binSrc(src.Pos(), op, x, other)
+ return &bytesLit{src, bytes.Repeat(x.b, y.intValue(ctx))}
+ }
}
return ctx.mkIncompatible(src, op, x, other)
}
diff --git a/cue/kind.go b/cue/kind.go
index 7355965..8cf7772 100644
--- a/cue/kind.go
+++ b/cue/kind.go
@@ -201,11 +201,13 @@
}
return bottomKind, false
}
- if a.isAnyOf(listKind) && b.isAnyOf(intKind) {
- return a, false
- }
- if b.isAnyOf(listKind) && a.isAnyOf(intKind) {
- return b, true
+ if op == opMul {
+ if a.isAnyOf(listKind|stringKind|bytesKind) && b.isAnyOf(intKind) {
+ return a, false
+ }
+ if b.isAnyOf(listKind|stringKind|bytesKind) && a.isAnyOf(intKind) {
+ return b, true
+ }
}
// non-overlapping types
if a&scalarKinds == 0 || b&scalarKinds == 0 {
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index 7b5a09d..256177d 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -147,7 +147,6 @@
i2: 2 & int
sum: -1 + +2 // 1
- str: "foo" + "bar" // "foobar"
div1: 2.0 / 3 * 6 // 4
div2: 2 / 3 * 6 // 4
rem: 2 % 3 // 2
@@ -171,7 +170,6 @@
`,
out: `<0>{i1: 1, i2: 2, ` +
`sum: 1, ` +
- `str: "foobar", ` +
`div1: 4.00000000000000000000000, ` +
`div2: 4.00000000000000000000000, ` +
`rem: 2, ` +
@@ -272,6 +270,25 @@
`,
out: `<0>{a: 1, b: 1, c: 1.0, d: _|_((int & float):unsupported op &((int)*, (float)*)), e: "4", f: true}`,
}, {
+ desc: "strings and bytes",
+ in: `
+ s0: "foo" + "bar"
+ s1: 3 * "abc"
+ s2: "abc" * 2
+
+ b0: 'foo' + 'bar'
+ b1: 3 * 'abc'
+ b2: 'abc' * 2
+ `,
+ out: `<0>{` +
+ `s0: "foobar", ` +
+ `s1: "abcabcabc", ` +
+ `s2: "abcabc", ` +
+ `b0: 'foobar', ` +
+ `b1: 'abcabcabc', ` +
+ `b2: 'abcabc'` +
+ `}`,
+ }, {
desc: "escaping",
in: `