First draft of a real README for the VVS stdlib.
[vvhitespace] / stdlib / logic.pvvs
index eccc68b..a69cd3a 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_LOGIC
 #define VVS_STDLIB_LOGIC
 
 #ifndef VVS_STDLIB_LOGIC
 #define VVS_STDLIB_LOGIC
 
@@ -20,8 +23,110 @@ NSSVTSTSSSN             | Mark: 101000 (not)
 @ In twos-complement, NOT(X) = (-X)-1
 SSTTN                   | PUSH -1
 TSSN                    | MULTIPLY
 @ In twos-complement, NOT(X) = (-X)-1
 SSTTN                   | PUSH -1
 TSSN                    | MULTIPLY
-SSTTN                   | PUSH -1
+SSSTN                   | PUSH 1
+TSST                    | SUBTRACT
+NTN                     | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   and (101001)
+@ Description:
+@   Performs a bitwise AND on the TOS word.
+@ Call Stack:
+@   X
+@   Y
+@ Return Stack:
+@   X ^ Y
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSTSSTN             | Mark: 101001 (and)
+
+@ Prepare the stack for computation.
+SSSSN                   | PUSH 0 (result)
+SSSTTTTTTN              | PUSH 63 (shift counter)
+
+@ Loop through the bits one at a time.
+NSSVSSTSTSSTSSSSSSSSN   | Mark: 00101001 00000000
+@ Prepare copy of X for the AND
+SNS                     | DUP
+SSSTSTN                 | PUSH 5
+NSTTTSSN                | JSR > 1100 (deepdup)
+SNT                     | SWAP
+NSTTSTTSSN              | JSR > 101100 (rshift)
+@ Prepare copy of Y for the AND
+SSSTSSN                 | PUSH 4
+NSTTTSSN                | JSR > 1100 (deepdup)
+SSSTTN                  | PUSH 3
+NSTTTSSN                | JSR > 1100 (deepdup)
+NSTTSTTSSN              | JSR > 101100 (rshift)
+@ Do the AND and store in result.
+NSTTSSSSSSN             | JSR > 1000000 (lowbitand)
+SSSTTN                  | PUSH 3
+NSTTSTTN                | JSR > 1011 (stackrotatereverse)
+SSSTN                   | PUSH 1
+NSTTSTTSTN              | JSR > 101101 (lshift)
+TSSS                    | ADD
+SSSTSN                  | PUSH 2
+NSTTSTSN                | JSR > 1010 (stackrotate)
+@ Test for end of loop.
+SNS                     | DUP
+NTSSSTSTSSTSSSSSSSTN    | BRZ > 00101001 00000001
+@ Decrement the counter and loop again.
+SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
 TSST                    | SUBTRACT
+NSNSSTSTSSTSSSSSSSSN    | JMP > 00101001 00000000
+
+@ Clean up and return.
+NSSVSSTSTSSTSSSSSSSTN   | Mark: 00101001 00000001
+SNN                     | DROP
+SNT                     | SWAP
+SNN                     | DROP
+SNT                     | SWAP
+SNN                     | DROP
+NTN                     | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   or (101010)
+@ Description:
+@   Performs a bitwise OR on the TOS word.
+@ Call Stack:
+@   X
+@   Y
+@ Return Stack:
+@   X v Y
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSTSTSN             | Mark: 101010 (or)
+NSTTSTSSSN              | JSR > 101000 (not)
+SNT                     | SWAP
+NSTTSTSSSN              | JSR > 101000 (not)
+NSTTSTSSTN              | JSR > 101001 (and)
+NSTTSTSSSN              | JSR > 101000 (not)
+NTN                     | RTS
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   xor (101011)
+@ Description:
+@   Performs a bitwise XOR on the TOS word.
+@ Call Stack:
+@   X
+@   Y
+@ Return Stack:
+@   X xor Y
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+#include <stack.pvvs>
+NSSVTSTSTTN             | Mark: 101011 (xor)
+SNS                     | DUP
+SSSTTN                  | PUSH 3
+NSTTTSSN                | JSR > 1100 (deepdup)
+NSTTSTSTSN              | JSR > 101010 (or)
+SNT                     | SWAP
+SSSTTN                  | PUSH 3
+NSTTSTTN                | JSR > 1011 (stackrotatereverse)
+NSTTSTSSTN              | JSR > 101001 (and)
+NSTTSTSSSN              | JSR > 101000 (not)
+NSTTSTSSTN              | JSR > 101001 (and)
 NTN                     | RTS
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 NTN                     | RTS
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -36,13 +141,17 @@ NTN                     | RTS
 @   X >> shiftcount
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 NSSVTSTTSSN             | Mark: 101100 (rshift)
 @   X >> shiftcount
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 NSSVTSTTSSN             | Mark: 101100 (rshift)
-
-@ Test for loop completion first since it's allowable to shift by zero.
-NSSVSSTSTTSSSSSSSSSTN   | Mark: 00101100 00000001
+@ Test for loop completion first since it is allowable to shift by zero.
 SNS                     | DUP
 NTSSSTSTTSSSSSSSSSSN    | BRZ > 00101100 00000000
 SNS                     | DUP
 NTSSSTSTTSSSSSSSSSSN    | BRZ > 00101100 00000000
-@ Shift by one bit on each pass.
+
+@ Negative numbers need special handling.
 SNT                     | SWAP
 SNT                     | SWAP
+SNS                     | DUP
+NTTSSTSTTSSSSSSSTSTN    | BMI > 00101100 00000101
+
+@ Shift by one bit on each pass.
+NSSVSSTSTTSSSSSSSTSSN   | Mark: 00101100 00000100
 SSSTSN                  | PUSH 2
 TSTS                    | DIVIDE
 @ Decrement the counter.
 SSSTSN                  | PUSH 2
 TSTS                    | DIVIDE
 @ Decrement the counter.
@@ -50,13 +159,23 @@ SNT                     | SWAP
 SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
 @ Loop again.
 SSSTN                   | PUSH 1
 TSST                    | SUBTRACT
 @ Loop again.
-NSNSSTSTTSSSSSSSSSTN    | JMP > 00101100 00000001
+NSNTSTTSSN              | JMP > 101100 (rshift)
 
 
-@ Clean up and return.
+@ Clean up
 NSSVSSTSTTSSSSSSSSSSN   | Mark: 00101100 00000000
 SNN                     | DROP
 NTN                     | RTS
 
 NSSVSSTSTTSSSSSSSSSSN   | Mark: 00101100 00000000
 SNN                     | DROP
 NTN                     | RTS
 
+@ Found a negative number. Subtract one before proceeding if odd.
+NSSVSSTSTTSSSSSSSTSTN   | Mark: 00101100 00000101
+SNS                     | DUP
+SSSTSN                  | PUSH 2
+TSTT                    | MODULO
+NTSSSTSTTSSSSSSSTSSN    | BRZ > 00101100 00000100
+SSSTN                   | PUSH 1
+TSST                    | SUBTRACT
+NSNSSTSTTSSSSSSSTSSN    | JMP > 00101100 00000100
+
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @ Name:
 @   lshift (101101)
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @ Name:
 @   lshift (101101)
@@ -70,7 +189,7 @@ NTN                     | RTS
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 NSSVTSTTSTN             | Mark: 101101 (lshift)
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 NSSVTSTTSTN             | Mark: 101101 (lshift)
 
-@ Test for loop completion first since it's allowable to shift by zero.
+@ Test for loop completion first since it is allowable to shift by zero.
 NSSVSSTSTTSTSSSSSSSTN   | Mark: 00101101 00000001
 SNS                     | DUP
 NTSSSTSTTSTSSSSSSSSN    | BRZ > 00101101 00000000
 NSSVSSTSTTSTSSSSSSSTN   | Mark: 00101101 00000001
 SNS                     | DUP
 NTSSSTSTTSTSSSSSSSSN    | BRZ > 00101101 00000000
@@ -90,4 +209,27 @@ NSSVSSTSTTSTSSSSSSSSN   | Mark: 00101101 00000000
 SNN                     | DROP
 NTN                     | RTS
 
 SNN                     | DROP
 NTN                     | RTS
 
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@ Name:
+@   lowbitand (1000000)
+@ Description:
+@   Performs logical AND on the least-significant bit of 'X' and 'Y'.
+@   Returns either 1 or 0, no other values.
+@ Call Stack:
+@   X
+@   Y
+@ Return Stack:
+@   lsb(X) AND lsb(Y)
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+NSSVTSSSSSSN            | Mark: 1000000 (lowbitand)
+SSSTSN                  | PUSH 2
+TSTT                    | MODULO
+SNT                     | SWAP
+SSSTSN                  | PUSH 2
+TSTT                    | MODULO
+TSSS                    | ADD
+SSSTSN                  | PUSH 2
+TSTS                    | DIVIDE
+NTN                     | RTS
+
 #endif
 #endif