Skip to content

Commit 867f71f

Browse files
committed
pkg/list: add builtins for list concatenation and repetition
These will be used to rewrite from the current use of list operators. Change-Id: I2a6461ac7d45649950160bb835cecf2c408593b4 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/8064 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent 172f006 commit 867f71f

File tree

3 files changed

+184
-0
lines changed

3 files changed

+184
-0
lines changed

pkg/list/list.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,47 @@ func FlattenN(xs cue.Value, depth int) ([]cue.Value, error) {
123123
return flattenN(xs, depth)
124124
}
125125

126+
// Repeat returns a new list consisting of count copies of list x.
127+
//
128+
// For instance:
129+
//
130+
// Repeat([1, 2], 2)
131+
//
132+
// results in
133+
//
134+
// [1, 2, 1, 2]
135+
//
136+
func Repeat(x []cue.Value, count int) ([]cue.Value, error) {
137+
if count < 0 {
138+
return nil, fmt.Errorf("negative count")
139+
}
140+
var a []cue.Value
141+
for i := 0; i < count; i++ {
142+
a = append(a, x...)
143+
}
144+
return a, nil
145+
}
146+
147+
// Concat takes a list of lists and concatenates them.
148+
//
149+
// Concat([a, b, c]) is equivalent to
150+
//
151+
// [ for x in a {x}, for x in b {x}, for x in c {x} ]
152+
//
153+
func Concat(a []cue.Value) ([]cue.Value, error) {
154+
var res []cue.Value
155+
for _, e := range a {
156+
iter, err := e.List()
157+
if err != nil {
158+
return nil, err
159+
}
160+
for iter.Next() {
161+
res = append(res, iter.Value())
162+
}
163+
}
164+
return res, nil
165+
}
166+
126167
// Take reports the prefix of length n of list x, or x itself if n > len(x).
127168
//
128169
// For instance:

pkg/list/pkg.go

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/list/testdata/list.txtar

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
-- in.cue --
2+
import "list"
3+
4+
repeat: {
5+
[string]: {x: _, n: int, v: list.Repeat(x, n)}
6+
7+
t1: {x: [], n: 0}
8+
t2: {x: [1], n: 0}
9+
10+
t3: {x: [1], n: 1}
11+
t4: {x: [1, 2], n: 1}
12+
13+
t5: {x: [], n: 3}
14+
t6: {x: [1, 2], n: 3}
15+
t7: {x: [1, 2, 3, 4], n: 3}
16+
17+
t8: {x: [1], n: -1}
18+
}
19+
concat: {
20+
[string]: {x: _, v: list.Concat(x)}
21+
22+
t1: x: []
23+
t2: x: [[]]
24+
25+
t3: x: [[1]]
26+
t4: x: [[1, 2]]
27+
t5: x: [[1], [2]]
28+
29+
t6: x: [[1, 2], [3, 4]]
30+
31+
t7: x: 1
32+
t8: x: [1, [2]]
33+
}
34+
-- out/list --
35+
Errors:
36+
error in call to list.Concat: cannot use value 1 (type int) as list
37+
error in call to list.Repeat: negative count
38+
concat.t7.v: cannot use 1 (type int) as list in argument 1 to list.Concat:
39+
./in.cue:30:12
40+
41+
Result:
42+
repeat: {
43+
t1: {
44+
x: []
45+
n: 0
46+
v: []
47+
}
48+
t2: {
49+
x: [1]
50+
n: 0
51+
v: []
52+
}
53+
t3: {
54+
x: [1]
55+
n: 1
56+
v: [1]
57+
}
58+
t4: {
59+
x: [1, 2]
60+
n: 1
61+
v: [1, 2]
62+
}
63+
t5: {
64+
x: []
65+
n: 3
66+
v: []
67+
}
68+
t6: {
69+
x: [1, 2]
70+
n: 3
71+
v: [1, 2, 1, 2, 1, 2]
72+
}
73+
t7: {
74+
x: [1, 2, 3, 4]
75+
n: 3
76+
v: [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
77+
}
78+
t8: {
79+
x: [1]
80+
n: -1
81+
v: _|_ // error in call to list.Repeat: negative count (and 1 more errors)
82+
}
83+
}
84+
concat: {
85+
t1: {
86+
x: []
87+
v: []
88+
}
89+
t2: {
90+
x: [[]]
91+
v: []
92+
}
93+
t3: {
94+
x: [[1]]
95+
v: [1]
96+
}
97+
t4: {
98+
x: [[1, 2]]
99+
v: [1, 2]
100+
}
101+
t5: {
102+
x: [[1], [2]]
103+
v: [1, 2]
104+
}
105+
t6: {
106+
x: [[1, 2], [3, 4]]
107+
v: [1, 2, 3, 4]
108+
}
109+
t7: {
110+
x: 1
111+
v: _|_ // concat.t7.v: cannot use 1 (type int) as list in argument 1 to list.Concat
112+
}
113+
t8: {
114+
x: [1, [2]]
115+
v: _|_ // error in call to list.Concat: cannot use value 1 (type int) as list (and 1 more errors)
116+
}
117+
}
118+

0 commit comments

Comments
 (0)