First draft of a real README for the VVS stdlib.
[vvhitespace] / stdlib / logic.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
0c56152e
AT
4#ifndef VVS_STDLIB_LOGIC
5#define VVS_STDLIB_LOGIC
6
7@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
8@ These subroutines assume they are running on the official VVS interpreter
9@ which internally uses a twos-complement representation.
10@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
11
12@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
13@ Name:
14@ not (101000)
15@ Description:
16@ Performs a bitwise NOT on the TOS word.
17@ Call Stack:
18@ X
19@ Return Stack:
20@ NOT(X)
21@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
22NSSVTSTSSSN | Mark: 101000 (not)
23@ In twos-complement, NOT(X) = (-X)-1
24SSTTN | PUSH -1
25TSSN | MULTIPLY
76974914 26SSSTN | PUSH 1
0c56152e
AT
27TSST | SUBTRACT
28NTN | RTS
29
3eaa958a
AT
30@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
31@ Name:
32@ and (101001)
33@ Description:
34@ Performs a bitwise AND on the TOS word.
35@ Call Stack:
36@ X
37@ Y
38@ Return Stack:
39@ X ^ Y
40@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
149f16fd 41#include <stack.pvvs>
3eaa958a
AT
42NSSVTSTSSTN | Mark: 101001 (and)
43
44@ Prepare the stack for computation.
45SSSSN | PUSH 0 (result)
46SSSTTTTTTN | PUSH 63 (shift counter)
47
48@ Loop through the bits one at a time.
49NSSVSSTSTSSTSSSSSSSSN | Mark: 00101001 00000000
76974914 50@ Prepare copy of X for the AND
3eaa958a
AT
51SNS | DUP
52SSSTSTN | PUSH 5
53NSTTTSSN | JSR > 1100 (deepdup)
54SNT | SWAP
55NSTTSTTSSN | JSR > 101100 (rshift)
76974914 56@ Prepare copy of Y for the AND
3eaa958a
AT
57SSSTSSN | PUSH 4
58NSTTTSSN | JSR > 1100 (deepdup)
59SSSTTN | PUSH 3
60NSTTTSSN | JSR > 1100 (deepdup)
61NSTTSTTSSN | JSR > 101100 (rshift)
62@ Do the AND and store in result.
63NSTTSSSSSSN | JSR > 1000000 (lowbitand)
64SSSTTN | PUSH 3
65NSTTSTTN | JSR > 1011 (stackrotatereverse)
66SSSTN | PUSH 1
67NSTTSTTSTN | JSR > 101101 (lshift)
68TSSS | ADD
69SSSTSN | PUSH 2
70NSTTSTSN | JSR > 1010 (stackrotate)
71@ Test for end of loop.
72SNS | DUP
73NTSSSTSTSSTSSSSSSSTN | BRZ > 00101001 00000001
74@ Decrement the counter and loop again.
75SSSTN | PUSH 1
76TSST | SUBTRACT
77NSNSSTSTSSTSSSSSSSSN | JMP > 00101001 00000000
78
79@ Clean up and return.
80NSSVSSTSTSSTSSSSSSSTN | Mark: 00101001 00000001
81SNN | DROP
82SNT | SWAP
83SNN | DROP
84SNT | SWAP
85SNN | DROP
86NTN | RTS
87
76974914
AT
88@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
89@ Name:
90@ or (101010)
91@ Description:
92@ Performs a bitwise OR on the TOS word.
93@ Call Stack:
94@ X
95@ Y
96@ Return Stack:
97@ X v Y
98@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
99NSSVTSTSTSN | Mark: 101010 (or)
100NSTTSTSSSN | JSR > 101000 (not)
101SNT | SWAP
102NSTTSTSSSN | JSR > 101000 (not)
103NSTTSTSSTN | JSR > 101001 (and)
104NSTTSTSSSN | JSR > 101000 (not)
105NTN | RTS
106
107@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
108@ Name:
109@ xor (101011)
110@ Description:
111@ Performs a bitwise XOR on the TOS word.
112@ Call Stack:
113@ X
114@ Y
115@ Return Stack:
116@ X xor Y
117@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
149f16fd 118#include <stack.pvvs>
76974914
AT
119NSSVTSTSTTN | Mark: 101011 (xor)
120SNS | DUP
121SSSTTN | PUSH 3
122NSTTTSSN | JSR > 1100 (deepdup)
123NSTTSTSTSN | JSR > 101010 (or)
124SNT | SWAP
125SSSTTN | PUSH 3
126NSTTSTTN | JSR > 1011 (stackrotatereverse)
127NSTTSTSSTN | JSR > 101001 (and)
128NSTTSTSSSN | JSR > 101000 (not)
129NSTTSTSSTN | JSR > 101001 (and)
130NTN | RTS
131
0c56152e
AT
132@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
133@ Name:
134@ rshift (101100)
135@ Description:
136@ Shifts 'X' right by 'shiftcount' bits with sign extension.
137@ Call Stack:
138@ X
139@ shiftcount
140@ Return Stack:
141@ X >> shiftcount
142@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
143NSSVTSTTSSN | Mark: 101100 (rshift)
3eaa958a 144@ Test for loop completion first since it is allowable to shift by zero.
0c56152e
AT
145SNS | DUP
146NTSSSTSTTSSSSSSSSSSN | BRZ > 00101100 00000000
0750ec76
AT
147
148@ Negative numbers need special handling.
0c56152e 149SNT | SWAP
0750ec76
AT
150SNS | DUP
151NTTSSTSTTSSSSSSSTSTN | BMI > 00101100 00000101
152
153@ Shift by one bit on each pass.
154NSSVSSTSTTSSSSSSSTSSN | Mark: 00101100 00000100
0c56152e
AT
155SSSTSN | PUSH 2
156TSTS | DIVIDE
157@ Decrement the counter.
158SNT | SWAP
159SSSTN | PUSH 1
160TSST | SUBTRACT
161@ Loop again.
0750ec76 162NSNTSTTSSN | JMP > 101100 (rshift)
0c56152e 163
0750ec76 164@ Clean up
0c56152e
AT
165NSSVSSTSTTSSSSSSSSSSN | Mark: 00101100 00000000
166SNN | DROP
167NTN | RTS
168
0750ec76
AT
169@ Found a negative number. Subtract one before proceeding if odd.
170NSSVSSTSTTSSSSSSSTSTN | Mark: 00101100 00000101
171SNS | DUP
172SSSTSN | PUSH 2
173TSTT | MODULO
174NTSSSTSTTSSSSSSSTSSN | BRZ > 00101100 00000100
175SSSTN | PUSH 1
176TSST | SUBTRACT
177NSNSSTSTTSSSSSSSTSSN | JMP > 00101100 00000100
178
0c56152e
AT
179@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
180@ Name:
181@ lshift (101101)
182@ Description:
183@ Shifts 'X' left by 'shiftcount' bits with zero filling.
184@ Call Stack:
185@ X
186@ shiftcount
187@ Return Stack:
188@ X << shiftcount
189@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
190NSSVTSTTSTN | Mark: 101101 (lshift)
191
3eaa958a 192@ Test for loop completion first since it is allowable to shift by zero.
0c56152e
AT
193NSSVSSTSTTSTSSSSSSSTN | Mark: 00101101 00000001
194SNS | DUP
195NTSSSTSTTSTSSSSSSSSN | BRZ > 00101101 00000000
196@ Shift by one bit on each pass.
197SNT | SWAP
198SSSTSN | PUSH 2
199TSSN | MULTIPLY
200@ Decrement the counter.
201SNT | SWAP
202SSSTN | PUSH 1
203TSST | SUBTRACT
204@ Loop again.
205NSNSSTSTTSTSSSSSSSTN | JMP > 00101101 00000001
206
207@ Clean up and return.
208NSSVSSTSTTSTSSSSSSSSN | Mark: 00101101 00000000
209SNN | DROP
210NTN | RTS
211
e0d5136c
AT
212@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
213@ Name:
214@ lowbitand (1000000)
215@ Description:
216@ Performs logical AND on the least-significant bit of 'X' and 'Y'.
217@ Returns either 1 or 0, no other values.
218@ Call Stack:
219@ X
220@ Y
221@ Return Stack:
222@ lsb(X) AND lsb(Y)
223@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
224NSSVTSSSSSSN | Mark: 1000000 (lowbitand)
225SSSTSN | PUSH 2
226TSTT | MODULO
227SNT | SWAP
228SSSTSN | PUSH 2
229TSTT | MODULO
230TSSS | ADD
231SSSTSN | PUSH 2
232TSTS | DIVIDE
233NTN | RTS
234
0c56152e 235#endif