1
2
3
4
5
6 container list:_elem [
7 value:_elem
8 next:&:list:_elem
9 ]
10
11 def push x:_elem, l:&:list:_elem -> l:&:list:_elem [
12 local-scope
13 load-ingredients
14 result:&:list:_elem <- new {(list _elem): type}
15 *result <- merge x, l
16 return result
17 ]
18
19 def first in:&:list:_elem -> result:_elem [
20 local-scope
21 load-ingredients
22 result <- get *in, value:offset
23 ]
24
25 def rest in:&:list:_elem -> result:&:list:_elem/contained-in:in [
26 local-scope
27 load-ingredients
28 result <- get *in, next:offset
29 ]
30
31 scenario list-handling [
32 run [
33 ¦ local-scope
34 ¦ x:&:list:num <- push 3, 0
35 ¦ x <- push 4, x
36 ¦ x <- push 5, x
37 ¦ 10:num/raw <- first x
38 ¦ x <- rest x
39 ¦ 11:num/raw <- first x
40 ¦ x <- rest x
41 ¦ 12:num/raw <- first x
42 ¦ 20:&:list:num/raw <- rest x
43 ]
44 memory-should-contain [
45 ¦ 10 <- 5
46 ¦ 11 <- 4
47 ¦ 12 <- 3
48 ¦ 20 <- 0
49 ]
50 ]
51
52 def length l:&:list:_elem -> result:num [
53 local-scope
54 load-ingredients
55 return-unless l, 0
56 rest:&:list:_elem <- rest l
57 length-of-rest:num <- length rest
58 result <- add length-of-rest, 1
59 ]
60
61
62 def insert x:_elem, in:&:list:_elem -> in:&:list:_elem [
63 local-scope
64 load-ingredients
65 new-node:&:list:_elem <- new {(list _elem): type}
66 *new-node <- put *new-node, value:offset, x
67 next-node:&:list:_elem <- get *in, next:offset
68 *in <- put *in, next:offset, new-node
69 *new-node <- put *new-node, next:offset, next-node
70 ]
71
72 scenario inserting-into-list [
73 local-scope
74 list:&:list:char <- push 3, 0
75 list <- push 4, list
76 list <- push 5, list
77 run [
78 ¦ list2:&:list:char <- rest list
79 ¦ list2 <- insert 6, list2
80 ¦
81 ¦ list2 <- copy list
82 ¦ 10:char/raw <- first list2
83 ¦ list2 <- rest list2
84 ¦ 11:char/raw <- first list2
85 ¦ list2 <- rest list2
86 ¦ 12:char/raw <- first list2
87 ¦ list2 <- rest list2
88 ¦ 13:char/raw <- first list2
89 ]
90 memory-should-contain [
91 ¦ 10 <- 5
92 ¦ 11 <- 4
93 ¦ 12 <- 6
94 ¦ 13 <- 3
95 ]
96 ]
97
98 scenario inserting-at-end-of-list [
99 local-scope
100 list:&:list:char <- push 3, 0
101 list <- push 4, list
102 list <- push 5, list
103 run [
104 ¦ list2:&:list:char <- rest list
105 ¦ list2 <- rest list2
106 ¦ list2 <- insert 6, list2
107 ¦
108 ¦ list2 <- copy list
109 ¦ 10:char/raw <- first list2
110 ¦ list2 <- rest list2
111 ¦ 11:char/raw <- first list2
112 ¦ list2 <- rest list2
113 ¦ 12:char/raw <- first list2
114 ¦ list2 <- rest list2
115 ¦ 13:char/raw <- first list2
116 ]
117 memory-should-contain [
118 ¦ 10 <- 5
119 ¦ 11 <- 4
120 ¦ 12 <- 3
121 ¦ 13 <- 6
122 ]
123 ]
124
125 scenario inserting-after-start-of-list [
126 local-scope
127 list:&:list:char <- push 3, 0
128 list <- push 4, list
129 list <- push 5, list
130 run [
131 ¦ list <- insert 6, list
132 ¦
133 ¦ list2:&:list:char <- copy list
134 ¦ 10:char/raw <- first list2
135 ¦ list2 <- rest list2
136 ¦ 11:char/raw <- first list2
137 ¦ list2 <- rest list2
138 ¦ 12:char/raw <- first list2
139 ¦ list2 <- rest list2
140 ¦ 13:char/raw <- first list2
141 ]
142 memory-should-contain [
143 ¦ 10 <- 5
144 ¦ 11 <- 6
145 ¦ 12 <- 4
146 ¦ 13 <- 3
147 ]
148 ]
149
150
151
152
153
154 def remove x:&:list:_elem/contained-in:in, in:&:list:_elem -> in:&:list:_elem [
155 local-scope
156 load-ingredients
157
158 return-unless x
159 next-node:&:list:_elem <- rest x
160
161 *x <- put *x, next:offset, 0
162
163 at-head?:bool <- equal x, in
164 return-if at-head?, next-node
165
166 prev-node:&:list:_elem <- copy in
167 curr:&:list:_elem <- rest prev-node
168 {
169 ¦ return-unless curr
170 ¦ found?:bool <- equal curr, x
171 ¦ break-if found?
172 ¦ prev-node <- copy curr
173 ¦ curr <- rest curr
174 }
175
176 *prev-node <- put *prev-node, next:offset, next-node
177 ]
178
179 scenario removing-from-list [
180 local-scope
181 list:&:list:char <- push 3, 0
182 list <- push 4, list
183 list <- push 5, list
184 run [
185 ¦ list2:&:list:char <- rest list
186 ¦ list <- remove list2, list
187 ¦ 10:bool/raw <- equal list2, 0
188 ¦
189 ¦ list2 <- copy list
190 ¦ 11:char/raw <- first list2
191 ¦ list2 <- rest list2
192 ¦ 12:char/raw <- first list2
193 ¦ 20:&:list:char/raw <- rest list2
194 ]
195 memory-should-contain [
196 ¦ 10 <- 0
197 ¦ 11 <- 5
198 ¦ 12 <- 3
199 ¦ 20 <- 0
200 ]
201 ]
202
203 scenario removing-from-start-of-list [
204 local-scope
205 list:&:list:char <- push 3, 0
206 list <- push 4, list
207 list <- push 5, list
208 run [
209 ¦ list <- remove list, list
210 ¦
211 ¦ list2:&:list:char <- copy list
212 ¦ 10:char/raw <- first list2
213 ¦ list2 <- rest list2
214 ¦ 11:char/raw <- first list2
215 ¦ 20:&:list:char/raw <- rest list2
216 ]
217 memory-should-contain [
218 ¦ 10 <- 4
219 ¦ 11 <- 3
220 ¦ 20 <- 0
221 ]
222 ]
223
224 scenario removing-from-end-of-list [
225 local-scope
226 list:&:list:char <- push 3, 0
227 list <- push 4, list
228 list <- push 5, list
229 run [
230 ¦
231 ¦ list2:&:list:char <- rest list
232 ¦ list2 <- rest list2
233 ¦ list <- remove list2, list
234 ¦ 10:bool/raw <- equal list2, 0
235 ¦
236 ¦ list2 <- copy list
237 ¦ 11:char/raw <- first list2
238 ¦ list2 <- rest list2
239 ¦ 12:char/raw <- first list2
240 ¦ 20:&:list:char/raw <- rest list2
241 ]
242 memory-should-contain [
243 ¦ 10 <- 0
244 ¦ 11 <- 5
245 ¦ 12 <- 4
246 ¦ 20 <- 0
247 ]
248 ]
249
250 scenario removing-from-singleton-list [
251 local-scope
252 list:&:list:char <- push 3, 0
253 run [
254 ¦ list <- remove list, list
255 ¦ 1:num/raw <- copy list
256 ]
257 memory-should-contain [
258 ¦ 1 <- 0
259 ]
260 ]
261
262
263
264 def reverse list:&:list:_elem temp:&:list:_elem/contained-in:result -> result:&:list:_elem [
265 local-scope
266 load-ingredients
267 return-unless list, temp
268 object:_elem <- first, list
269 list <- rest list
270 temp <- push object, temp
271 result <- reverse list, temp
272 ]
273
274 scenario reverse-list [
275 local-scope
276 list:&:list:number <- push 1, 0
277 list <- push 2, list
278 list <- push 3, list
279 run [
280 ¦ stash [list:], list
281 ¦ list <- reverse list
282 ¦ stash [reversed:], list
283 ]
284 trace-should-contain [
285 ¦ app: list: 3 -> 2 -> 1
286 ¦ app: reversed: 1 -> 2 -> 3
287 ]
288 ]
289
290 def to-text in:&:list:_elem -> result:text [
291 local-scope
292 load-ingredients
293 buf:&:buffer <- new-buffer 80
294 buf <- to-buffer in, buf
295 result <- buffer-to-array buf
296 ]
297
298
299 def to-text-line in:&:list:_elem -> result:text [
300 local-scope
301 load-ingredients
302 buf:&:buffer <- new-buffer 80
303 buf <- to-buffer in, buf, 6
304 result <- buffer-to-array buf
305 ]
306
307 def to-buffer in:&:list:_elem, buf:&:buffer -> buf:&:buffer [
308 local-scope
309 load-ingredients
310 {
311 ¦ break-if in
312 ¦ buf <- append buf, [[]]
313 ¦ return
314 }
315
316 val:_elem <- get *in, value:offset
317 buf <- append buf, val
318
319 next:&:list:_elem <- rest in
320 nextn:num <- copy next
321 return-unless next
322 buf <- append buf, [ -> ]
323
324 remaining:num, optional-ingredient-found?:bool <- next-ingredient
325 {
326 ¦ break-if optional-ingredient-found?
327 ¦
328 ¦ buf <- to-buffer next, buf
329 ¦ return
330 }
331 {
332 ¦ break-unless remaining
333 ¦
334 ¦ remaining <- subtract remaining, 1
335 ¦ buf <- to-buffer next, buf, remaining
336 ¦ return
337 }
338
339 append buf, [...]
340 ]
341
342 scenario stash-empty-list [
343 local-scope
344 x:&:list:num <- copy 0
345 run [
346 ¦ stash x
347 ]
348 trace-should-contain [
349 ¦ app: []
350 ]
351 ]