# Mu - 063array.mu

      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 ]