Added tests for stdlib stack functions. Fixed some small bugs.
[vvhitespace] / stdlib / stack.pvvs
... / ...
CommitLineData
1#ifndef VVS_STDLIB_STACK
2#define VVS_STDLIB_STACK
3
4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
5@ Name:
6@ stackrotate
7@ Description:
8@ Maximum rotation depth is 14. Stomps on heap[1]-heap[15].
9@ Assumes rotation depth is at least 2.
10@ Call Stack:
11@ stack word n
12@ ...
13@ stack word 1
14@ rotation depth (rd) <-- TOS
15@ Return Stack (n>rd=3):
16@ stack word n
17@ ...
18@ stack word 1
19@ stack word 3
20@ stack word 2 <-- TOS
21@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
22NSSVTSTSN | Mark: 1010 (stackrotate)
23
24@ For the convenience of other functions, modulo the
25@ rotation depth by the available registers.
26SSSTTTTN | PUSH 15
27TSTT | MODULO
28
29@ Use heap[15] for generating register addresses.
30@ TODO: Switch to using heap[1] so number of registers is limited only by user.
31SSSTTTTN | PUSH 15 (ptr)
32SSSSN | PUSH 0
33TTS | STORE
34
35@ Dump one word from stack to heap each pass through the loop.
36NSSVSSSSTSTSSSSSSSSSN | Mark: 00001010 00000000
37SNT | SWAP
38SSSTN | PUSH 1 (starting register)
39SSSTTTTN | PUSH 15 (ptr)
40TTT | LOAD
41TSSS | ADD
42SNT | SWAP
43TTS | STORE
44
45@ See if the loop is complete.
46SNS | DUP
47SSSTTTTN | PUSH 15 (ptr)
48TTT | LOAD
49SSSTN | PUSH 1
50TSSS | ADD
51TSST | SUBTRACT
52NTSSSSSTSTSSSSSSSSTN | BRZ > 00001010 00000001
53
54@ Increment the loop counter
55SSSTTTTN | PUSH 15 (ptr)
56TTT | LOAD
57SSSTN | PUSH 1
58TSSS | ADD
59SSSTTTTN | PUSH 15 (ptr)
60SNT | SWAP
61TTS | STORE
62NSNSSSSTSTSSSSSSSSSN | JMP > 00001010 00000000
63
64@ The correct number of words have been stored to registers.
65@ Time to read them back in rotated order.
66
67@ First, prepare the counter in heap[15] again.
68@ This consumes 'rd' from the stack.
69NSSVSSSSTSTSSSSSSSSTN | Mark: 00001010 00000001
70SSSTN | PUSH 1
71TSST | SUBTRACT
72SSSTTTTN | PUSH 15 (ptr)
73SNT | SWAP
74TTS | STORE
75
76@ Second, read in the old TOS manually.
77SSSTN | PUSH 1 (starting register)
78TTT | LOAD
79
80@ Read one word per pass through this loop.
81NSSVSSSSTSTSSSSSSSTSN | Mark: 00001010 00000010
82SSSTN | PUSH 1 (starting register)
83SSSTTTTN | PUSH 15 (ptr)
84TTT | LOAD
85TSSS | ADD
86TTT | LOAD
87
88@ See if the loop is complete.
89SSSTTTTN | PUSH 15 (ptr)
90TTT | LOAD
91SSSTN | PUSH 1
92TSST | SUBTRACT
93NTSSSSSTSTSSSSSSSTTN | BRZ > 00001010 00000011
94
95@ Decrement the loop counter and loop again.
96SSSTTTTN | PUSH 15 (ptr)
97TTT | LOAD
98SSSTN | PUSH 1
99TSST | SUBTRACT
100SSSTTTTN | PUSH 15 (ptr)
101SNT | SWAP
102TTS | STORE
103NSNSSSSTSTSSSSSSSTSN | JMP > 00001010 00000010
104
105@ Return
106NSSVSSSSTSTSSSSSSSTTN | Mark: 00001010 00000011
107NTN | RTS
108
109@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
110@ Name:
111@ stackrotatereverse
112@ Description:
113@ Maximum rotation depth is 14. Stomps on heap[1]-heap[15].
114@ Assumes rotation depth is at least 2.
115@ Call Stack:
116@ stack word n
117@ ...
118@ stack word 1
119@ rotation depth (rd) <-- TOS
120@ Return Stack (n>rd=3):
121@ stack word n
122@ ...
123@ stack word 2
124@ stack word 1
125@ stack word 3 <-- TOS
126@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
127NSSVTSTTN | Mark: 1011 (stackrotatereverse)
128
129@ For the convenience of other functions, modulo the
130@ rotation depth by the available registers.
131SSSTTTTN | PUSH 15
132TSTT | MODULO
133
134@ Use heap[15] for generating register addresses.
135@ TODO: Switch to using heap[1] so number of registers is limited only by user.
136SSSTTTTN | PUSH 15 (ptr)
137SSSSN | PUSH 0
138TTS | STORE
139
140@ Dump one word from stack to heap each pass through the loop.
141NSSVSSSSTSTTSSSSSSSSN | Mark: 00001011 00000000
142SNT | SWAP
143SSSTN | PUSH 1 (starting register)
144SSSTTTTN | PUSH 15 (ptr)
145TTT | LOAD
146TSSS | ADD
147SNT | SWAP
148TTS | STORE
149
150@ See if the loop is complete.
151SNS | DUP
152SSSTTTTN | PUSH 15 (ptr)
153TTT | LOAD
154SSSTN | PUSH 1
155TSSS | ADD
156TSST | SUBTRACT
157NTSSSSSTSTTSSSSSSSTN | BRZ > 00001011 00000001
158
159@ Increment the loop counter
160SSSTTTTN | PUSH 15 (ptr)
161TTT | LOAD
162SSSTN | PUSH 1
163TSSS | ADD
164SSSTTTTN | PUSH 15 (ptr)
165SNT | SWAP
166TTS | STORE
167NSNSSSSTSTTSSSSSSSSN | JMP > 00001011 00000000
168
169@ The correct number of words have been stored to registers.
170@ Time to read them back in rotated order.
171
172@ First, prepare the counter in heap[15] again.
173NSSVSSSSTSTTSSSSSSSTN | Mark: 00001011 00000001
174SSSTN | PUSH 1
175TSST | SUBTRACT
176SNS | DUP
177SSSTN | PUSH 1
178TSST | SUBTRACT
179SSSTTTTN | PUSH 15 (ptr)
180SNT | SWAP
181TTS | STORE
182
183@ Read one word per pass through this loop.
184@ Store it behind 'rd' on the stack.
185NSSVSSSSTSTTSSSSSSTSN | Mark: 00001011 00000010
186SSSTN | PUSH 1 (starting register)
187SSSTTTTN | PUSH 15 (ptr)
188TTT | LOAD
189TSSS | ADD
190TTT | LOAD
191SNT | SWAP
192
193@ See if the loop is complete.
194SSSTTTTN | PUSH 15 (ptr)
195TTT | LOAD
196NTSSSSSTSTTSSSSSSTTN | BRZ > 00001011 00000011
197
198@ Decrement the loop counter and loop again.
199SSSTTTTN | PUSH 15 (ptr)
200TTT | LOAD
201SSSTN | PUSH 1
202TSST | SUBTRACT
203SSSTTTTN | PUSH 15 (ptr)
204SNT | SWAP
205TTS | STORE
206NSNSSSSTSTTSSSSSSTSN | JMP > 00001011 00000010
207
208@ Read in the final value manually and return.
209NSSVSSSSTSTTSSSSSSTTN | Mark: 00001011 00000011
210SSSTN | PUSH 1 (starting register)
211TSSS | ADD
212TTT | LOAD
213NTN | RTS
214
215@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
216@ Name:
217@ deepdup
218@ Description:
219@ Duplicates an item deep on the stack, placing the duplicate on TOS.
220@ By default, maximum depth is 11.
221@ True maximum depth is (max depth of stackrotate & stackrotatereverse)-3.
222@ Call Stack:
223@ stack word n
224@ ...
225@ stack word 1
226@ dupdepth <-- TOS
227@ Return Stack:
228@ stack word n
229@ ...
230@ stack word 1
231@ copy of stack word 3 <-- TOS
232@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
233NSSVTTSSN | Mark: 1100 (deepdup)
234
235@ Copy 'dupdepth' and use it to bring forth the desired stack word.
236SNS | DUP
237SSSTN | PUSH 1
238TSSS | ADD
239NSTTSTTN | JSR > 1011 (stackrotatereverse)
240
241@ Copy the desired stack word and return it back into the stack.
242SNS | DUP
243SSSTTN | PUSH 3
244NSTTSTTN | JSR > 1011 (stackrotatereverse)
245SSSTN | PUSH 1
246TSSS | ADD
247NSTTSTSN | JSR > 1010 (stackrotate)
248NTN | RTS
249
250#endif
251