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-input
 22     break-unless exists?
 23     capacity <- add capacity, 1
 24     loop
 25   }
 26   result <- new _elem:type, capacity
 27   rewind-inputs
 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-input
 34     assert exists?, [error in rewinding inputs 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-inputs
 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-input
 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-inputs [
 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-inputs
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-inputs
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 ]