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