-
Notifications
You must be signed in to change notification settings - Fork 0
/
queue.shen
66 lines (56 loc) · 1.71 KB
/
queue.shen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
\\ TODO: replace with (ref _) containing a list
(datatype queue
N : number;
I : (list A);
O : (list A);
________________________________
(@v queue N I O <>) : (queue A);)
(define queue
doc "Creates a new queue."
-> (@v queue 0 [] [] <>))
(define queue?
doc "Returns true if argument is a queue."
X -> (trap-error (= queue (<-vector X 1)) (/. _ false)))
(define queue-empty?
doc "Returns true if given queue is empty."
Queue -> (= (<-vector Queue 2) 0))
(define queue-size
doc "Returns size of queue."
Queue -> (<-vector Queue 2))
(define queue-push
doc "Pushes a value onto queue, returns queue."
Queue Value ->
(do
(vector-update Queue 2 (+ 1))
(vector-update Queue 3 (cons Value))
Queue))
(define queue-peek
doc "Returns the head value of mutable queue, raises error if empty."
Queue ->
(do
(when (queue-empty? Queue)
(error "mutable queue is empty"))
(when (= [] (<-vector Queue 4))
(do
(vector-> Queue 4 (reverse (<-vector Queue 3)))
(vector-> Queue 3 [])))
(hd (<-vector Queue 4))))
(define queue-pop
doc "Pops value off of mutable queue, raises error if empty."
Queue ->
(let Value (queue-peek Queue)
(do
(vector-update Queue 2 #'decrement)
(vector-update Queue 4 #'tl)
Value)))
(declare queue [--> [queue A]])
(declare queue? [A --> boolean])
(declare queue-empty? [[queue A] --> boolean])
(declare queue-size [[queue A] --> number])
(declare queue-push [[queue A] --> [A --> [queue A]]])
(declare queue-peek [[queue A] --> A])
(declare queue-pop [[queue A] --> A])
(defmacro queue-of-macro
[queue-of | Xs] ->
(fold-left (/. X Q [queue-push Q X]) [queue] Xs)
where (cons? Xs))