X-Git-Url: http://git.subgeniuskitty.com/vvhitespace/.git/blobdiff_plain/23d1724712fae7dc9645d862d57d030cf3e2e764..48f884892a9cb24c1be8bb0d8f5f5f6851c03bd5:/stdlib/stack.pvvs diff --git a/stdlib/stack.pvvs b/stdlib/stack.pvvs index a5115ac..8ed5e9d 100644 --- a/stdlib/stack.pvvs +++ b/stdlib/stack.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_STACK #define VVS_STDLIB_STACK @@ -5,8 +8,8 @@ @ 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 @ ... @@ -23,19 +26,20 @@ NSSVTSTSN | Mark: 1010 (stackrotate) @ For the convenience of other functions, modulo the @ rotation depth by the available registers. -SSSTSTN | PUSH 5 +SSSTTTTN | PUSH 15 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 -SSSTSSTN | PUSH 9 (starting register) -SSSTTTSN | PUSH 14 (ptr) +SSSTN | PUSH 1 (starting register) +SSSTTTTN | PUSH 15 (ptr) TTT | LOAD TSSS | ADD SNT | SWAP @@ -43,7 +47,7 @@ TTS | STORE @ See if the loop is complete. SNS | DUP -SSSTTTSN | PUSH 14 (ptr) +SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSSS | ADD @@ -51,11 +55,11 @@ TSST | SUBTRACT NTSSSSSTSTSSSSSSSSTN | BRZ > 00001010 00000001 @ Increment the loop counter -SSSTTTSN | PUSH 14 (ptr) +SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSSS | ADD -SSSTTTSN | PUSH 14 (ptr) +SSSTTTTN | PUSH 15 (ptr) 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. -@ 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 -SSSTTTSN | PUSH 14 (ptr) +SSSTTTTN | PUSH 15 (ptr) 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 -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. -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. -SSSTTTSN | PUSH 14 (ptr) +SSSTTTTN | PUSH 15 (ptr) TTT | LOAD SSSTN | PUSH 1 TSST | SUBTRACT -SSSTTTSN | PUSH 14 (ptr) +SSSTTTTN | PUSH 15 (ptr) SNT | SWAP TTS | STORE NSNSSSSTSTSSSSSSSTSN | JMP > 00001010 00000010 @@ -105,4 +109,146 @@ NSNSSSSTSTSSSSSSSTSN | JMP > 00001010 00000010 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 +