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, 0/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 ]