Added tests for stdlib stack functions. Fixed some small bugs.
[vvhitespace] / stdlib / stack.pvvs
CommitLineData
23d17247
AT
1#ifndef VVS_STDLIB_STACK
2#define VVS_STDLIB_STACK
3
4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
5@ Name:
6@ stackrotate
7@ Description:
6cb31a3e 8@ Maximum rotation depth is 14. Stomps on heap[1]-heap[15].
d8954ff0 9@ Assumes rotation depth is at least 2.
23d17247
AT
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.
d8954ff0 26SSSTTTTN | PUSH 15
23d17247
AT
27TSTT | MODULO
28
6cb31a3e 29@ Use heap[15] for generating register addresses.
d8954ff0 30@ TODO: Switch to using heap[1] so number of registers is limited only by user.
6cb31a3e 31SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
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
6cb31a3e
AT
38SSSTN | PUSH 1 (starting register)
39SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
40TTT | LOAD
41TSSS | ADD
42SNT | SWAP
43TTS | STORE
44
45@ See if the loop is complete.
46SNS | DUP
6cb31a3e 47SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
48TTT | LOAD
49SSSTN | PUSH 1
50TSSS | ADD
51TSST | SUBTRACT
52NTSSSSSTSTSSSSSSSSTN | BRZ > 00001010 00000001
53
54@ Increment the loop counter
6cb31a3e 55SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
56TTT | LOAD
57SSSTN | PUSH 1
58TSSS | ADD
6cb31a3e 59SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
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
6cb31a3e 67@ First, prepare the counter in heap[15] again.
23d17247
AT
68@ This consumes 'rd' from the stack.
69NSSVSSSSTSTSSSSSSSSTN | Mark: 00001010 00000001
70SSSTN | PUSH 1
71TSST | SUBTRACT
6cb31a3e 72SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
73SNT | SWAP
74TTS | STORE
75
76@ Second, read in the old TOS manually.
6cb31a3e 77SSSTN | PUSH 1 (starting register)
23d17247
AT
78TTT | LOAD
79
80@ Read one word per pass through this loop.
81NSSVSSSSTSTSSSSSSSTSN | Mark: 00001010 00000010
6cb31a3e
AT
82SSSTN | PUSH 1 (starting register)
83SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
84TTT | LOAD
85TSSS | ADD
86TTT | LOAD
87
88@ See if the loop is complete.
6cb31a3e 89SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
90TTT | LOAD
91SSSTN | PUSH 1
92TSST | SUBTRACT
93NTSSSSSTSTSSSSSSSTTN | BRZ > 00001010 00000011
94
95@ Decrement the loop counter and loop again.
6cb31a3e 96SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
97TTT | LOAD
98SSSTN | PUSH 1
99TSST | SUBTRACT
6cb31a3e 100SSSTTTTN | PUSH 15 (ptr)
23d17247
AT
101SNT | SWAP
102TTS | STORE
103NSNSSSSTSTSSSSSSSTSN | JMP > 00001010 00000010
104
105@ Return
106NSSVSSSSTSTSSSSSSSTTN | Mark: 00001010 00000011
107NTN | RTS
108
a67867ae
AT
109@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
110@ Name:
111@ stackrotatereverse
112@ Description:
6cb31a3e 113@ Maximum rotation depth is 14. Stomps on heap[1]-heap[15].
d8954ff0 114@ Assumes rotation depth is at least 2.
a67867ae
AT
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.
d8954ff0 131SSSTTTTN | PUSH 15
a67867ae
AT
132TSTT | MODULO
133
6cb31a3e 134@ Use heap[15] for generating register addresses.
d8954ff0 135@ TODO: Switch to using heap[1] so number of registers is limited only by user.
6cb31a3e 136SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
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
6cb31a3e
AT
143SSSTN | PUSH 1 (starting register)
144SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
145TTT | LOAD
146TSSS | ADD
147SNT | SWAP
148TTS | STORE
149
150@ See if the loop is complete.
151SNS | DUP
6cb31a3e 152SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
153TTT | LOAD
154SSSTN | PUSH 1
155TSSS | ADD
156TSST | SUBTRACT
157NTSSSSSTSTTSSSSSSSTN | BRZ > 00001011 00000001
158
159@ Increment the loop counter
6cb31a3e 160SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
161TTT | LOAD
162SSSTN | PUSH 1
163TSSS | ADD
6cb31a3e 164SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
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
6cb31a3e 172@ First, prepare the counter in heap[15] again.
a67867ae
AT
173NSSVSSSSTSTTSSSSSSSTN | Mark: 00001011 00000001
174SSSTN | PUSH 1
175TSST | SUBTRACT
176SNS | DUP
177SSSTN | PUSH 1
178TSST | SUBTRACT
6cb31a3e 179SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
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
6cb31a3e
AT
186SSSTN | PUSH 1 (starting register)
187SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
188TTT | LOAD
189TSSS | ADD
190TTT | LOAD
191SNT | SWAP
192
193@ See if the loop is complete.
6cb31a3e 194SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
195TTT | LOAD
196NTSSSSSTSTTSSSSSSTTN | BRZ > 00001011 00000011
197
198@ Decrement the loop counter and loop again.
6cb31a3e 199SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
200TTT | LOAD
201SSSTN | PUSH 1
202TSST | SUBTRACT
6cb31a3e 203SSSTTTTN | PUSH 15 (ptr)
a67867ae
AT
204SNT | SWAP
205TTS | STORE
206NSNSSSSTSTTSSSSSSTSN | JMP > 00001011 00000010
207
208@ Read in the final value manually and return.
209NSSVSSSSTSTTSSSSSSTTN | Mark: 00001011 00000011
6cb31a3e 210SSSTN | PUSH 1 (starting register)
a67867ae
AT
211TSSS | ADD
212TTT | LOAD
213NTN | RTS
214
f0499c77
AT
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
23d17247 250#endif
a67867ae 251