Added bitwise AND subroutine to VVS stdlib.
[vvhitespace] / stdlib / logic.pvvs
CommitLineData
0c56152e
AT
1#ifndef VVS_STDLIB_LOGIC
2#define VVS_STDLIB_LOGIC
3
4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
5@ These subroutines assume they are running on the official VVS interpreter
6@ which internally uses a twos-complement representation.
7@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
8
9@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
10@ Name:
11@ not (101000)
12@ Description:
13@ Performs a bitwise NOT on the TOS word.
14@ Call Stack:
15@ X
16@ Return Stack:
17@ NOT(X)
18@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
19NSSVTSTSSSN | Mark: 101000 (not)
20@ In twos-complement, NOT(X) = (-X)-1
21SSTTN | PUSH -1
22TSSN | MULTIPLY
23SSTTN | PUSH -1
24TSST | SUBTRACT
25NTN | RTS
26
3eaa958a
AT
27@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
28@ Name:
29@ and (101001)
30@ Description:
31@ Performs a bitwise AND on the TOS word.
32@ Call Stack:
33@ X
34@ Y
35@ Return Stack:
36@ X ^ Y
37@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
38NSSVTSTSSTN | Mark: 101001 (and)
39
40@ Prepare the stack for computation.
41SSSSN | PUSH 0 (result)
42SSSTTTTTTN | PUSH 63 (shift counter)
43
44@ Loop through the bits one at a time.
45NSSVSSTSTSSTSSSSSSSSN | Mark: 00101001 00000000
46@ Prepare X for the AND
47SNS | DUP
48SSSTSTN | PUSH 5
49NSTTTSSN | JSR > 1100 (deepdup)
50SNT | SWAP
51NSTTSTTSSN | JSR > 101100 (rshift)
52@ Prepare Y for the AND
53SSSTSSN | PUSH 4
54NSTTTSSN | JSR > 1100 (deepdup)
55SSSTTN | PUSH 3
56NSTTTSSN | JSR > 1100 (deepdup)
57NSTTSTTSSN | JSR > 101100 (rshift)
58@ Do the AND and store in result.
59NSTTSSSSSSN | JSR > 1000000 (lowbitand)
60SSSTTN | PUSH 3
61NSTTSTTN | JSR > 1011 (stackrotatereverse)
62SSSTN | PUSH 1
63NSTTSTTSTN | JSR > 101101 (lshift)
64TSSS | ADD
65SSSTSN | PUSH 2
66NSTTSTSN | JSR > 1010 (stackrotate)
67@ Test for end of loop.
68SNS | DUP
69NTSSSTSTSSTSSSSSSSTN | BRZ > 00101001 00000001
70@ Decrement the counter and loop again.
71SSSTN | PUSH 1
72TSST | SUBTRACT
73NSNSSTSTSSTSSSSSSSSN | JMP > 00101001 00000000
74
75@ Clean up and return.
76NSSVSSTSTSSTSSSSSSSTN | Mark: 00101001 00000001
77SNN | DROP
78SNT | SWAP
79SNN | DROP
80SNT | SWAP
81SNN | DROP
82NTN | RTS
83
0c56152e
AT
84@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
85@ Name:
86@ rshift (101100)
87@ Description:
88@ Shifts 'X' right by 'shiftcount' bits with sign extension.
89@ Call Stack:
90@ X
91@ shiftcount
92@ Return Stack:
93@ X >> shiftcount
94@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
95NSSVTSTTSSN | Mark: 101100 (rshift)
96
3eaa958a 97@ Test for loop completion first since it is allowable to shift by zero.
0c56152e
AT
98NSSVSSTSTTSSSSSSSSSTN | Mark: 00101100 00000001
99SNS | DUP
100NTSSSTSTTSSSSSSSSSSN | BRZ > 00101100 00000000
101@ Shift by one bit on each pass.
102SNT | SWAP
103SSSTSN | PUSH 2
104TSTS | DIVIDE
105@ Decrement the counter.
106SNT | SWAP
107SSSTN | PUSH 1
108TSST | SUBTRACT
109@ Loop again.
110NSNSSTSTTSSSSSSSSSTN | JMP > 00101100 00000001
111
112@ Clean up and return.
113NSSVSSTSTTSSSSSSSSSSN | Mark: 00101100 00000000
114SNN | DROP
115NTN | RTS
116
117@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
118@ Name:
119@ lshift (101101)
120@ Description:
121@ Shifts 'X' left by 'shiftcount' bits with zero filling.
122@ Call Stack:
123@ X
124@ shiftcount
125@ Return Stack:
126@ X << shiftcount
127@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
128NSSVTSTTSTN | Mark: 101101 (lshift)
129
3eaa958a 130@ Test for loop completion first since it is allowable to shift by zero.
0c56152e
AT
131NSSVSSTSTTSTSSSSSSSTN | Mark: 00101101 00000001
132SNS | DUP
133NTSSSTSTTSTSSSSSSSSN | BRZ > 00101101 00000000
134@ Shift by one bit on each pass.
135SNT | SWAP
136SSSTSN | PUSH 2
137TSSN | MULTIPLY
138@ Decrement the counter.
139SNT | SWAP
140SSSTN | PUSH 1
141TSST | SUBTRACT
142@ Loop again.
143NSNSSTSTTSTSSSSSSSTN | JMP > 00101101 00000001
144
145@ Clean up and return.
146NSSVSSTSTTSTSSSSSSSSN | Mark: 00101101 00000000
147SNN | DROP
148NTN | RTS
149
e0d5136c
AT
150@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
151@ Name:
152@ lowbitand (1000000)
153@ Description:
154@ Performs logical AND on the least-significant bit of 'X' and 'Y'.
155@ Returns either 1 or 0, no other values.
156@ Call Stack:
157@ X
158@ Y
159@ Return Stack:
160@ lsb(X) AND lsb(Y)
161@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
162NSSVTSSSSSSN | Mark: 1000000 (lowbitand)
163SSSTSN | PUSH 2
164TSTT | MODULO
165SNT | SWAP
166SSSTSN | PUSH 2
167TSTT | MODULO
168TSSS | ADD
169SSSTSN | PUSH 2
170TSTS | DIVIDE
171NTN | RTS
172
0c56152e 173#endif