-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstack.shen
60 lines (50 loc) · 1.57 KB
/
stack.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
\\ TODO: replace with (ref _) containing a list
(datatype stack
N : number;
S : (list A);
______________________________
(@v stack N S <>) : (stack A);)
(define stack
doc "Creates a new mutable stack."
-> (@v stack 0 [] <>))
(define stack?
doc "Returns true if argument is a mutable stack."
X -> (trap-error (= stack (<-vector X 1)) (/. _ false)))
(define stack-empty?
doc "Returns true if given stack is empty."
Stack -> (= (<-vector Stack 2) 0))
(define stack-size
doc "Returns size of mutable stack."
Stack -> (<-vector Stack 2))
(define stack-push
doc "Pushes a value onto mutable stack, returns stack."
Stack Value ->
(do
(vector-update Stack 2 (+ 1))
(vector-update Stack 3 (cons Value))
Stack))
(define stack-peek
doc "Returns the top value of mutable stack, raises error if empty."
Stack ->
(if (stack-empty? Stack)
(error "mutable stack is empty")
(hd (<-vector Stack 3))))
(define stack-pop
doc "Pops value off of mutable stack, raises error if empty."
Stack ->
(let Value (stack-peek Stack)
(do
(vector-update Stack 2 #'decrement)
(vector-update Stack 3 #'tl)
Value)))
(declare stack [--> [stack A]])
(declare stack? [A --> boolean])
(declare stack-empty? [[stack A] --> boolean])
(declare stack-size [[stack A] --> number])
(declare stack-push [[stack A] --> [A --> [stack A]]])
(declare stack-peek [[stack A] --> A])
(declare stack-pop [[stack A] --> A])
(defmacro stack-of-macro
[stack-of | Xs] ->
(fold-right (/. X S [stack-push S X]) [stack] Xs)
where (cons? Xs))