# Mu - 068random.mu

     1 def random generator:&:stream:num -> result:num, fail?:bool, generator:&:stream:num [
     2   local-scope
     3   load-inputs
     4   {
     5     break-if generator
     6     # generator is 0? use real random-number generator
     7     result <- real-random
     8     return result, false
     9   }
    10   result, fail?, generator <- read generator
    11 ]
    12
    13 # helper for tests
    14 def assume-random-numbers -> result:&:stream:num [
    15   local-scope
    16   load-inputs
    17   # compute result-len, space to allocate in result
    18   result-len:num <- copy 0
    19   {
    20     _, arg-received?:bool <- next-input
    21     break-unless arg-received?
    22     result-len <- add result-len, 1
    23     loop
    24   }
    25   rewind-inputs
    26   result-data:&:@:num <- new number:type, result-len
    27   idx:num <- copy 0
    28   {
    29     curr:num, arg-received?:bool <- next-input
    30     break-unless arg-received?
    31     *result-data <- put-index *result-data, idx, curr
    32     idx <- add idx, 1
    33     loop
    34   }
    35   result <- new-stream result-data
    36 ]
    37
    38 scenario random-numbers-in-scenario [
    39   local-scope
    40   source:&:stream:num <- assume-random-numbers 34, 35, 37
    41   1:num/raw, 2:bool/raw <- random source
    42   3:num/raw, 4:bool/raw <- random source
    43   5:num/raw, 6:bool/raw <- random source
    44   7:num/raw, 8:bool/raw <- random source
    45   memory-should-contain [
    46     1 <- 34
    47     2 <- 0  # everything went well
    48     3 <- 35
    49     4 <- 0  # everything went well
    50     5 <- 37
    51     6 <- 0  # everything went well
    52     7 <- 0  # empty result
    53     8 <- 1  # end of stream
    54   ]
    55 ]
    56
    57 # generate a random integer in the semi-open interval [start, end)
    58 def random-in-range generator:&:stream:num, start:num, end:num -> result:num, fail?:bool, generator:&:stream:num [
    59   local-scope
    60   load-inputs
    61   result, fail?, generator <- random generator
    62   return-if fail?
    63   delta:num <- subtract end, start
    64   _, result <- divide-with-remainder result, delta
    65   result <- add result, start
    66 ]
    67
    68 scenario random-in-range [
    69   local-scope
    70   source:&:stream:num <- assume-random-numbers 91
    71   1:num/raw <- random-in-range source, 40, 50
    72   memory-should-contain [
    73     1 <- 41
    74   ]
    75 ]