Skip to content

Commit 979a20c

Browse files
alex-snezhkophated
andauthored
feat(stdlib)!: Make queue and stack mutable & provide Immutable submodules (#1479)
* feat(stdlib): Mutable queue and stack * moved mutable impls to root of modules * generate submodule docs with graindoc submodule support * updated history * update docs with graindoc fixes * formatting * update names as per review --------- Co-authored-by: Blaine Bublitz <blaine.bublitz@gmail.com>
1 parent 7ab7ddc commit 979a20c

File tree

6 files changed

+1145
-223
lines changed

6 files changed

+1145
-223
lines changed

compiler/test/stdlib/queue.test.gr

Lines changed: 102 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,118 @@
11
module QueueTest
22

33
include "queue"
4+
from Queue use { Immutable as ImmQ }
5+
include "list"
6+
7+
// Mutable queue tests
48

59
let empty = Queue.make()
10+
assert Queue.isEmpty(empty)
11+
assert Queue.size(empty) == 0
12+
assert Queue.peek(empty) == None
13+
assert Queue.pop(empty) == None
14+
assert Queue.size(empty) == 0
15+
16+
let queue = Queue.make()
17+
Queue.push(1, queue)
18+
Queue.push(2, queue)
19+
Queue.push(3, queue)
20+
21+
assert !Queue.isEmpty(queue)
22+
assert Queue.size(queue) == 3
23+
assert Queue.peek(queue) == Some(1)
24+
25+
assert Queue.pop(queue) == Some(1)
26+
assert Queue.peek(queue) == Some(2)
27+
assert Queue.size(queue) == 2
28+
29+
Queue.push(4, queue)
30+
assert Queue.size(queue) == 3
31+
assert Queue.peek(queue) == Some(2)
32+
let copy = Queue.copy(queue)
33+
Queue.pop(copy)
34+
assert Queue.size(copy) == 2
35+
assert Queue.size(queue) == 3
36+
Queue.clear(queue)
37+
assert Queue.size(queue) == 0
38+
assert Queue.peek(queue) == None
39+
40+
// test that expansion works
41+
let queue = Queue.makeSized(3)
42+
Queue.push(0, queue)
43+
Queue.push(1, queue)
44+
Queue.push(2, queue)
45+
Queue.push(3, queue)
46+
assert Queue.pop(queue) == Some(0)
47+
assert Queue.pop(queue) == Some(1)
48+
assert Queue.pop(queue) == Some(2)
49+
assert Queue.pop(queue) == Some(3)
50+
assert Queue.pop(queue) == None
51+
52+
// test that the "circular" behavior of the circular queue works as expected
53+
let queue = Queue.makeSized(4)
54+
let push = x => () => Queue.push(x, queue)
55+
let pop = () => ignore(Queue.pop(queue))
56+
let actions = [
57+
push(1),
58+
push(2),
59+
push(3),
60+
push(4),
61+
pop,
62+
pop,
63+
pop,
64+
push(5),
65+
push(6),
66+
pop,
67+
pop,
68+
push(7),
69+
push(8),
70+
push(9),
71+
]
72+
List.forEach(action => action(), actions)
73+
74+
assert Queue.size(queue) == 4
75+
assert Queue.peek(queue) == Some(6)
76+
77+
Queue.push(10, queue)
78+
assert Queue.size(queue) == 5
79+
assert Queue.pop(queue) == Some(6)
80+
assert Queue.pop(queue) == Some(7)
81+
assert Queue.pop(queue) == Some(8)
82+
assert Queue.pop(queue) == Some(9)
83+
assert Queue.pop(queue) == Some(10)
84+
assert Queue.pop(queue) == None
85+
86+
// Immutable queue tests
87+
688
// 1 <- 2 <- 3
7-
let sampleQueue = Queue.push(3, Queue.push(2, Queue.push(1, empty)))
89+
let sampleQueue = ImmQ.push(3, ImmQ.push(2, ImmQ.push(1, ImmQ.empty)))
890

9-
// Queue.isEmpty
91+
// ImmQ.isEmpty
1092

11-
assert Queue.isEmpty(empty)
12-
assert !Queue.isEmpty(sampleQueue)
93+
assert ImmQ.isEmpty(ImmQ.empty)
94+
assert !ImmQ.isEmpty(sampleQueue)
1395

14-
// Queue.peek
96+
// ImmQ.peek
1597

16-
assert Queue.peek(empty) == None
17-
assert Queue.peek(sampleQueue) == Some(1)
98+
assert ImmQ.peek(ImmQ.empty) == None
99+
assert ImmQ.peek(sampleQueue) == Some(1)
18100

19-
// Queue.push
101+
// ImmQ.push
20102

21-
assert Queue.peek(Queue.push(1, empty)) == Some(1)
22-
assert Queue.peek(Queue.push(4, sampleQueue)) == Some(1)
103+
assert ImmQ.peek(ImmQ.push(1, ImmQ.empty)) == Some(1)
104+
assert ImmQ.peek(ImmQ.push(4, sampleQueue)) == Some(1)
23105

24-
// Queue.pop
106+
// ImmQ.pop
25107

26-
assert Queue.isEmpty(Queue.pop(empty))
27-
assert Queue.isEmpty(Queue.pop(Queue.push(1, empty)))
28-
assert Queue.isEmpty(Queue.pop(Queue.pop(Queue.pop(sampleQueue))))
29-
assert Queue.peek(Queue.pop(sampleQueue)) == Some(2)
30-
assert Queue.peek(Queue.pop(Queue.push(4, Queue.pop(sampleQueue)))) == Some(3)
108+
assert ImmQ.isEmpty(ImmQ.pop(ImmQ.empty))
109+
assert ImmQ.isEmpty(ImmQ.pop(ImmQ.push(1, ImmQ.empty)))
110+
assert ImmQ.isEmpty(ImmQ.pop(ImmQ.pop(ImmQ.pop(sampleQueue))))
111+
assert ImmQ.peek(ImmQ.pop(sampleQueue)) == Some(2)
112+
assert ImmQ.peek(ImmQ.pop(ImmQ.push(4, ImmQ.pop(sampleQueue)))) == Some(3)
31113

32-
// Queue.size
114+
// ImmQ.size
33115

34-
assert Queue.size(empty) == 0
35-
assert Queue.size(sampleQueue) == 3
36-
assert Queue.size(Queue.pop(Queue.pop(sampleQueue))) == 1
116+
assert ImmQ.size(ImmQ.empty) == 0
117+
assert ImmQ.size(sampleQueue) == 3
118+
assert ImmQ.size(ImmQ.pop(ImmQ.pop(sampleQueue))) == 1

compiler/test/stdlib/stack.test.gr

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,92 @@
11
module StackTest
22

33
include "stack"
4+
from Stack use { Immutable as ImmStack }
5+
6+
// Mutable stack tests
47

58
let empty = Stack.make()
9+
assert Stack.isEmpty(empty)
10+
assert Stack.size(empty) == 0
11+
assert Stack.peek(empty) == None
12+
assert Stack.pop(empty) == None
13+
assert Stack.size(empty) == 0
14+
15+
let stack = Stack.make()
16+
Stack.push(1, stack)
17+
Stack.push(2, stack)
18+
Stack.push(3, stack)
19+
20+
assert !Stack.isEmpty(stack)
21+
assert Stack.size(stack) == 3
22+
assert Stack.peek(stack) == Some(3)
23+
24+
assert Stack.pop(stack) == Some(3)
25+
assert Stack.peek(stack) == Some(2)
26+
assert Stack.size(stack) == 2
27+
28+
Stack.push(4, stack)
29+
assert Stack.size(stack) == 3
30+
assert Stack.peek(stack) == Some(4)
31+
let copy = Stack.copy(stack)
32+
Stack.pop(copy)
33+
assert Stack.size(copy) == 2
34+
assert Stack.size(stack) == 3
35+
Stack.clear(stack)
36+
assert Stack.size(stack) == 0
37+
assert Stack.peek(stack) == None
38+
39+
let stack = Stack.makeSized(4)
40+
41+
Stack.push(1, stack)
42+
Stack.push(2, stack)
43+
Stack.push(3, stack)
44+
Stack.push(4, stack)
45+
Stack.push(5, stack)
46+
assert Stack.size(stack) == 5
47+
assert Stack.pop(stack) == Some(5)
48+
assert Stack.pop(stack) == Some(4)
49+
assert Stack.pop(stack) == Some(3)
50+
assert Stack.pop(stack) == Some(2)
51+
assert Stack.pop(stack) == Some(1)
52+
assert Stack.pop(stack) == None
53+
54+
// Immutable Stack tests
55+
656
// 1 <- 2 <- 3
7-
let sampleStack = Stack.push(3, Stack.push(2, Stack.push(1, empty)))
57+
let sampleStack = ImmStack.push(
58+
3,
59+
ImmStack.push(2, ImmStack.push(1, ImmStack.empty))
60+
)
861

9-
// Stack.isEmpty
62+
// ImmStack.isEmpty
1063

11-
assert Stack.isEmpty(empty)
12-
assert !Stack.isEmpty(sampleStack)
64+
assert ImmStack.isEmpty(ImmStack.empty)
65+
assert !ImmStack.isEmpty(sampleStack)
1366

14-
// Stack.peek
67+
// ImmStack.peek
1568

16-
assert Stack.peek(empty) == None
17-
assert Stack.peek(sampleStack) == Some(3)
69+
assert ImmStack.peek(ImmStack.empty) == None
70+
assert ImmStack.peek(sampleStack) == Some(3)
1871

19-
// Stack.push
72+
// ImmStack.push
2073

21-
assert Stack.peek(Stack.push(1, empty)) == Some(1)
22-
assert Stack.peek(Stack.push(4, sampleStack)) == Some(4)
74+
assert ImmStack.peek(ImmStack.push(1, ImmStack.empty)) == Some(1)
75+
assert ImmStack.peek(ImmStack.push(4, sampleStack)) == Some(4)
2376

24-
// Stack.pop
77+
// ImmStack.pop
2578

26-
assert Stack.isEmpty(Stack.pop(empty))
27-
assert Stack.isEmpty(Stack.pop(Stack.push(1, empty)))
28-
assert Stack.isEmpty(Stack.pop(Stack.pop(Stack.pop(sampleStack))))
29-
assert Stack.peek(Stack.pop(sampleStack)) == Some(2)
30-
assert Stack.peek(Stack.pop(Stack.push(4, Stack.pop(sampleStack)))) == Some(2)
79+
assert ImmStack.isEmpty(ImmStack.pop(ImmStack.empty))
80+
assert ImmStack.isEmpty(ImmStack.pop(ImmStack.push(1, ImmStack.empty)))
81+
assert ImmStack.isEmpty(ImmStack.pop(ImmStack.pop(ImmStack.pop(sampleStack))))
82+
assert ImmStack.peek(ImmStack.pop(sampleStack)) == Some(2)
83+
assert ImmStack.peek(
84+
ImmStack.pop(ImmStack.push(4, ImmStack.pop(sampleStack)))
85+
) ==
86+
Some(2)
3187

32-
// Stack.size
88+
// ImmStack.size
3389

34-
assert Stack.size(empty) == 0
35-
assert Stack.size(sampleStack) == 3
36-
assert Stack.size(Stack.pop(Stack.pop(sampleStack))) == 1
90+
assert ImmStack.size(ImmStack.empty) == 0
91+
assert ImmStack.size(sampleStack) == 3
92+
assert ImmStack.size(ImmStack.pop(ImmStack.pop(sampleStack))) == 1

0 commit comments

Comments
 (0)