First draft of a real README for the VVS stdlib.
[vvhitespace] / stdlib / stack.pvvs
index a5115ac..8ed5e9d 100644 (file)
@@ -1,3 +1,6 @@
+@ (c) 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
+@ See LICENSE.txt file for copyright and license details.
+
 #ifndef VVS_STDLIB_STACK
 #define VVS_STDLIB_STACK
 
 #ifndef VVS_STDLIB_STACK
 #define VVS_STDLIB_STACK
 
@@ -5,8 +8,8 @@
 @ Name:
 @   stackrotate
 @ Description:
 @ Name:
 @   stackrotate
 @ Description:
-@   Maximum rotation depth is five. Stomps on heap[9]-heap[14].
-@   Assumes rotation depth greater than two, otherwise use SWAP.
+@   Maximum rotation depth is 14. Stomps on heap[1]-heap[15].
+@   Assumes rotation depth is at least 2.
 @ Call Stack:
 @   stack word n
 @   ...
 @ Call Stack:
 @   stack word n
 @   ...
@@ -23,19 +26,20 @@ NSSVTSTSN               | Mark: 1010 (stackrotate)
 
 @ For the convenience of other functions, modulo the
 @ rotation depth by the available registers.
 
 @ For the convenience of other functions, modulo the
 @ rotation depth by the available registers.
-SSSTSTN                 | PUSH 5
+SSSTTTTN                | PUSH 15
 TSTT                    | MODULO
 
 TSTT                    | MODULO
 
-@ Use heap[14] for generating register addresses.
-SSSTTTSN                | PUSH 14 (ptr)
+@ Use heap[15] for generating register addresses.
+@ TODO: Switch to using heap[1] so number of registers is limited only by user.
+SSSTTTTN                | PUSH 15 (ptr)
 SSSSN                   | PUSH 0
 TTS                     | STORE
 
 @ Dump one word from stack to heap each pass through the loop.
 NSSVSSSSTSTSSSSSSSSSN   | Mark: 00001010 00000000
 SNT                     | SWAP
 SSSSN                   | PUSH 0
 TTS                     | STORE
 
 @ Dump one word from stack to heap each pass through the loop.
 NSSVSSSSTSTSSSSSSSSSN   | Mark: 00001010 00000000
 SNT                     | SWAP
-SSSTSSTN                | PUSH 9 (starting register)
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTN                   | PUSH 1 (starting register)
+SSSTTTTN                | PUSH 15 (ptr)
 TTT                     | LOAD
 TSSS                    | ADD
 SNT                     | SWAP
 TTT                     | LOAD
 TSSS                    | ADD
 SNT                     | SWAP
@@ -43,7 +47,7 @@ TTS                     | STORE
 
 @ See if the loop is complete.
 SNS                     | DUP
 
 @ See if the loop is complete.
 SNS                     | DUP
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTTTTN                | PUSH 15 (ptr)
 TTT                     | LOAD
 SSSTN                   | PUSH 1
 TSSS                    | ADD
 TTT                     | LOAD
 SSSTN                   | PUSH 1
 TSSS                    | ADD
@@ -51,11 +55,11 @@ TSST                    | SUBTRACT
 NTSSSSSTSTSSSSSSSSTN    | BRZ > 00001010 00000001
 
 @ Increment the loop counter
 NTSSSSSTSTSSSSSSSSTN    | BRZ > 00001010 00000001
 
 @ Increment the loop counter
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTTTTN                | PUSH 15 (ptr)
 TTT                     | LOAD
 SSSTN                   | PUSH 1
 TSSS                    | ADD
 TTT                     | LOAD
 SSSTN                   | PUSH 1
 TSSS                    | ADD
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTTTTN                | PUSH 15 (ptr)
 SNT                     | SWAP
 TTS                     | STORE
 NSNSSSSTSTSSSSSSSSSN    | JMP > 00001010 00000000
 SNT                     | SWAP
 TTS                     | STORE
 NSNSSSSTSTSSSSSSSSSN    | JMP > 00001010 00000000
@@ -63,40 +67,40 @@ NSNSSSSTSTSSSSSSSSSN    | JMP > 00001010 00000000
 @ The correct number of words have been stored to registers.
 @ Time to read them back in rotated order.
 
 @ The correct number of words have been stored to registers.
 @ Time to read them back in rotated order.
 
-@ First, prepare the counter in heap[14] again.
+@ First, prepare the counter in heap[15] again.
 @ This consumes 'rd' from the stack.
 NSSVSSSSTSTSSSSSSSSTN   | Mark: 00001010 00000001
 SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
 @ This consumes 'rd' from the stack.
 NSSVSSSSTSTSSSSSSSSTN   | Mark: 00001010 00000001
 SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTTTTN                | PUSH 15 (ptr)
 SNT                     | SWAP
 TTS                     | STORE
 
 @ Second, read in the old TOS manually.
 SNT                     | SWAP
 TTS                     | STORE
 
 @ Second, read in the old TOS manually.
-SSSTSSTN                | PUSH 9 (starting register)
+SSSTN                   | PUSH 1 (starting register)
 TTT                     | LOAD
 
 @ Read one word per pass through this loop.
 NSSVSSSSTSTSSSSSSSTSN   | Mark: 00001010 00000010
 TTT                     | LOAD
 
 @ Read one word per pass through this loop.
 NSSVSSSSTSTSSSSSSSTSN   | Mark: 00001010 00000010
-SSSTSSTN                | PUSH 9 (starting register)
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTN                   | PUSH 1 (starting register)
+SSSTTTTN                | PUSH 15 (ptr)
 TTT                     | LOAD
 TSSS                    | ADD
 TTT                     | LOAD
 
 @ See if the loop is complete.
 TTT                     | LOAD
 TSSS                    | ADD
 TTT                     | LOAD
 
 @ See if the loop is complete.
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTTTTN                | PUSH 15 (ptr)
 TTT                     | LOAD
 SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
 NTSSSSSTSTSSSSSSSTTN    | BRZ > 00001010 00000011
 
 @ Decrement the loop counter and loop again.
 TTT                     | LOAD
 SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
 NTSSSSSTSTSSSSSSSTTN    | BRZ > 00001010 00000011
 
 @ Decrement the loop counter and loop again.
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTTTTN                | PUSH 15 (ptr)
 TTT                     | LOAD
 SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
 TTT                     | LOAD
 SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
-SSSTTTSN                | PUSH 14 (ptr)
+SSSTTTTN                | PUSH 15 (ptr)
 SNT                     | SWAP
 TTS                     | STORE
 NSNSSSSTSTSSSSSSSTSN    | JMP > 00001010 00000010
 SNT                     | SWAP
 TTS                     | STORE
 NSNSSSSTSTSSSSSSSTSN    | JMP > 00001010 00000010
@@ -105,4 +109,146 @@ NSNSSSSTSTSSSSSSSTSN    | JMP > 00001010 00000010
 NSSVSSSSTSTSSSSSSSTTN   | Mark: 00001010 00000011
 NTN                     | RTS
 
 NSSVSSSSTSTSSSSSSSTTN   | Mark: 00001010 00000011
 NTN                     | RTS
 
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   stackrotatereverse
+@ Description:
+@   Maximum rotation depth is 14. Stomps on heap[1]-heap[15].
+@   Assumes rotation depth is at least 2.
+@ Call Stack:
+@   stack word n
+@   ...
+@   stack word 1
+@   rotation depth (rd)  <-- TOS
+@ Return Stack (n>rd=3):
+@   stack word n
+@   ...
+@   stack word 2
+@   stack word 1
+@   stack word 3   <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSTTN               | Mark: 1011 (stackrotatereverse)
+
+@ For the convenience of other functions, modulo the
+@ rotation depth by the available registers.
+SSSTTTTN                | PUSH 15
+TSTT                    | MODULO
+
+@ Use heap[15] for generating register addresses.
+@ TODO: Switch to using heap[1] so number of registers is limited only by user.
+SSSTTTTN                | PUSH 15 (ptr)
+SSSSN                   | PUSH 0
+TTS                     | STORE
+
+@ Dump one word from stack to heap each pass through the loop.
+NSSVSSSSTSTTSSSSSSSSN   | Mark: 00001011 00000000
+SNT                     | SWAP
+SSSTN                   | PUSH 1 (starting register)
+SSSTTTTN                | PUSH 15 (ptr)
+TTT                     | LOAD
+TSSS                    | ADD
+SNT                     | SWAP
+TTS                     | STORE
+
+@ See if the loop is complete.
+SNS                     | DUP
+SSSTTTTN                | PUSH 15 (ptr)
+TTT                     | LOAD
+SSSTN                   | PUSH 1
+TSSS                    | ADD
+TSST                    | SUBTRACT
+NTSSSSSTSTTSSSSSSSTN    | BRZ > 00001011 00000001
+
+@ Increment the loop counter
+SSSTTTTN                | PUSH 15 (ptr)
+TTT                     | LOAD
+SSSTN                   | PUSH 1
+TSSS                    | ADD
+SSSTTTTN                | PUSH 15 (ptr)
+SNT                     | SWAP
+TTS                     | STORE
+NSNSSSSTSTTSSSSSSSSN    | JMP > 00001011 00000000
+
+@ The correct number of words have been stored to registers.
+@ Time to read them back in rotated order.
+
+@ First, prepare the counter in heap[15] again.
+NSSVSSSSTSTTSSSSSSSTN   | Mark: 00001011 00000001
+SSSTN                   | PUSH 1
+TSST                    | SUBTRACT
+SNS                     | DUP
+SSSTN                   | PUSH 1
+TSST                    | SUBTRACT
+SSSTTTTN                | PUSH 15 (ptr)
+SNT                     | SWAP
+TTS                     | STORE
+
+@ Read one word per pass through this loop.
+@ Store it behind 'rd' on the stack.
+NSSVSSSSTSTTSSSSSSTSN   | Mark: 00001011 00000010
+SSSTN                   | PUSH 1 (starting register)
+SSSTTTTN                | PUSH 15 (ptr)
+TTT                     | LOAD
+TSSS                    | ADD
+TTT                     | LOAD
+SNT                     | SWAP
+
+@ See if the loop is complete.
+SSSTTTTN                | PUSH 15 (ptr)
+TTT                     | LOAD
+NTSSSSSTSTTSSSSSSTTN    | BRZ > 00001011 00000011
+
+@ Decrement the loop counter and loop again.
+SSSTTTTN                | PUSH 15 (ptr)
+TTT                     | LOAD
+SSSTN                   | PUSH 1
+TSST                    | SUBTRACT
+SSSTTTTN                | PUSH 15 (ptr)
+SNT                     | SWAP
+TTS                     | STORE
+NSNSSSSTSTTSSSSSSTSN    | JMP > 00001011 00000010
+
+@ Read in the final value manually and return.
+NSSVSSSSTSTTSSSSSSTTN   | Mark: 00001011 00000011
+SSSTN                   | PUSH 1 (starting register)
+TSSS                    | ADD
+TTT                     | LOAD
+NTN                     | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   deepdup
+@ Description:
+@   Duplicates an item deep on the stack, placing the duplicate on TOS.
+@   By default, maximum depth is 13.
+@   True maximum depth is (max depth of stackrotate & stackrotatereverse)-1.
+@ Call Stack:
+@   stack word n
+@   ...
+@   stack word 1
+@   dupdepth   <-- TOS
+@ Return Stack: (dupdepth=3)
+@   stack word n
+@   ...
+@   stack word 1
+@   copy of stack word 3   <-- TOS
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTTSSN               | Mark: 1100 (deepdup)
+
+@ Copy 'dupdepth' and use it to bring forth the desired stack word.
+SNS                     | DUP
+SSSTN                   | PUSH 1
+TSSS                    | ADD
+NSTTSTTN                | JSR > 1011 (stackrotatereverse)
+
+@ Copy the desired stack word and return it back into the stack.
+SNS                     | DUP
+SSSTTN                  | PUSH 3
+NSTTSTTN                | JSR > 1011 (stackrotatereverse)
+SSSTN                   | PUSH 1
+TSSS                    | ADD
+NSTTSTSN                | JSR > 1010 (stackrotate)
+NTN                     | RTS
+
 #endif
 #endif
+