1 scenario array-from-args [
  2   run [
  3   ¦ local-scope
  4   ¦ x:&:@:num <- new-array 0, 1, 2
  5   ¦ 10:@:num/raw <- copy *x
  6   ]
  7   memory-should-contain [
  8   ¦ 10 <- 3  # array length
  9   ¦ 11 <- 0
 10   ¦ 12 <- 1
 11   ¦ 13 <- 2
 12   ]
 13 ]
 14 
 15 # create an array out of a list of args
 16 def new-array -> result:&:@:_elem [
 17   local-scope
 18   capacity:num <- copy 0
 19   {
 20   ¦ # while read curr-value
 21   ¦ curr-value:_elem, exists?:bool <- next-ingredient
 22   ¦ break-unless exists?
 23   ¦ capacity <- add capacity, 1
 24   ¦ loop
 25   }
 26   result <- new _elem:type, capacity
 27   rewind-ingredients
 28   i:num <- copy 0
 29   {
 30   ¦ # while read curr-value
 31   ¦ done?:bool <- greater-or-equal i, capacity
 32   ¦ break-if done?
 33   ¦ curr-value:_elem, exists?:bool <- next-ingredient
 34   ¦ assert exists?, [error in rewinding ingredients to new-array]
 35   ¦ *result <- put-index *result, i, curr-value
 36   ¦ i <- add i, 1
 37   ¦ loop
 38   }
 39   return result
 40 ]
 41 
 42 # fill an existing array with a set of numbers
 43 # (contributed by Caleb Couch)
 44 def fill array:&:@:num -> array:&:@:num [
 45   local-scope
 46   load-ingredients
 47   loopn:num <- copy 0
 48   length:num <- length *array
 49   {
 50   ¦ length?:bool <- equal loopn, length
 51   ¦ break-if length?
 52   ¦ object:num, arg-received?:bool <- next-ingredient
 53   ¦ break-unless arg-received?
 54   ¦ *array <- put-index *array, loopn, object
 55   ¦ loopn <- add loopn, 1
 56   ¦ loop
 57   }
 58 ]
 59 
 60 scenario fill-on-an-empty-array [
 61   local-scope
 62   array:&:@:num <- new number:type, 3
 63   run [
 64   ¦ array <- fill array, 1 2 3
 65   ¦ 10:@:num/raw <- copy *array
 66   ]
 67   memory-should-contain [
 68   ¦ 10 <- 3
 69   ¦ 11 <- 1
 70   ¦ 12 <- 2
 71   ¦ 13 <- 3
 72   ]
 73 ]
 74 
 75 scenario fill-overwrites-existing-values [
 76   local-scope
 77   array:&:@:num <- new number:type, 3
 78   *array <- put-index *array, 0, 4
 79   run [
 80   ¦ array <- fill array, 1 2 3
 81   ¦ 10:@:num/raw <- copy *array
 82   ]
 83   memory-should-contain [
 84   ¦ 10 <- 3
 85   ¦ 11 <- 1
 86   ¦ 12 <- 2
 87   ¦ 13 <- 3
 88   ]
 89 ]
 90 
 91 scenario fill-exits-gracefully-when-given-no-ingredients [
 92   local-scope
 93   array:&:@:num <- new number:type, 3
 94   run [
 95   ¦ array <- fill array
 96   ¦ 10:@:num/raw <- copy *array
 97   ]
 98   memory-should-contain [
 99   ¦ 10 <- 3
100   ¦ 11 <- 0
101   ¦ 12 <- 0
102   ¦ 13 <- 0
103   ]
104 ]
105 
106 # swap two elements of an array
107 # (contributed by Caleb Couch)
108 def swap array:&:@:num, index1:num, index2:num -> array:&:@:num [
109   local-scope
110   load-ingredients
111   object1:num <- index *array, index1
112   object2:num <- index *array, index2
113   *array <- put-index *array, index1, object2
114   *array <- put-index *array, index2, object1
115 ]
116 
117 scenario swap-works [
118   local-scope
119   array:&:@:num <- new number:type, 4
120   array <- fill array, 4 3 2 1
121   run [
122   ¦ array <- swap array, 0, 2
123   ¦ 10:num/raw <- index *array, 0
124   ¦ 11:num/raw <- index *array, 2
125   ]
126   memory-should-contain [
127   ¦ 10 <- 2
128   ¦ 11 <- 4
129   ]
130 ]
131 
132 # reverse the elements of an array
133 # (contributed by Caleb Couch)
134 def reverse array:&:@:_elem -> array:&:@:_elem [
135   local-scope
136   load-ingredients
137   start:num <- copy 0
138   length:num <- length *array
139   end:num <- subtract length, 1
140   {
141   ¦ done?:bool <- greater-or-equal start, end
142   ¦ break-if done?
143   ¦ array <- swap array, start, end
144   ¦ start <- add start, 1
145   ¦ end <- subtract end, 1
146   ¦ loop
147   }
148 ]
149 
150 scenario reverse-array-odd-length [
151   local-scope
152   array:&:@:num <- new number:type, 3
153   array <- fill array, 3 2 1
154   run [
155   ¦ array <- reverse array
156   ¦ 10:@:num/raw <- copy *array
157   ]
158   memory-should-contain [
159   ¦ 10 <- 3
160   ¦ 11 <- 1
161   ¦ 12 <- 2
162   ¦ 13 <- 3
163   ]
164 ]
165 
166 scenario reverse-array-even-length [
167   local-scope
168   array:&:@:num <- new number:type, 4
169   array <- fill array, 4 3 2 1
170   run [
171   ¦ array <- reverse array
172   ¦ 10:@:num/raw <- copy *array
173   ]
174   memory-should-contain [
175   ¦ 10 <- 4
176   ¦ 11 <- 1
177   ¦ 12 <- 2
178   ¦ 13 <- 3
179   ¦ 14 <- 4
180   ]
181 ]