More minor updates to `rationale.md`.
[vvhitespace] / stdlib / math.pvvs
CommitLineData
3625ff3a
AT
1#ifndef VVS_STDLIB_MATH
2#define VVS_STDLIB_MATH
3
2612f47f 4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
bb21580a
AT
5@ Name:
6@ random (10000)
2612f47f 7@ Description:
f969012f
DNR
8@ Returns a pseudo-random number.
9@ Before using for the first time, seed heap[0] with a non-zero value.
10@ This PRNG was taken from: https://en.wikipedia.org/wiki/Xorshift
2612f47f
AT
11@ Call Stack:
12@ empty
13@ Return Stack:
14@ random number <-- TOS
15@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
f969012f 16#include <logic.pvvs>
2612f47f 17NSSVTSSSSN | Mark: 10000 (random)
b15f1da5 18
f969012f 19@ Fetch seed from heap[0].
b15f1da5
AT
20SSSSN | PUSH 0 (ptr)
21TTT | LOAD
b15f1da5 22
f969012f
DNR
23@ Set TOS ^= TOS << 13
24SNS | DUP
25SSSTTSTN | PUSH +13
26NSTTSTTSTN | JSR > 101101 (lshift)
27NSTTSTSTTN | JSR > 101011 (xor)
28
29@ Set TOS ^= TOS >> 7
30SNS | DUP
31SSSTTTN | PUSH +7
32NSTTSTTSSN | JSR > 101100 (rshift)
33NSTTSTSTTN | JSR > 101011 (xor)
34
35@ Set TOS ^= TOS << 17
36SNS | DUP
37SSSTSSSTN | PUSH +17
38NSTTSTTSTN | JSR > 101101 (lshift)
39NSTTSTSTTN | JSR > 101011 (xor)
40
41@ Store a copy of the new seed at heap[0] and return.
b15f1da5
AT
42SNS | DUP
43SSSSN | PUSH 0 (ptr)
44SNT | SWAP
45TTS | STORE
2612f47f
AT
46NTN | RTS
47
3625ff3a 48@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
bb21580a
AT
49@ Name:
50@ abs (10001)
3625ff3a 51@ Description:
bb21580a 52@ Returns the absolute value of its argument
3625ff3a
AT
53@ Call Stack:
54@ signed number <-- TOS
55@ Return Stack:
56@ abs(signed number) <-- TOS
57@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
58NSSVTSSSTN | Mark: 10001 (absolute value)
7359501c
AT
59
60@ Catch -(2^63) as a special case since its absolute value will overflow
61@ a twos-complement 64-bit word. Return zero as though the absolute value
62@ overflowed to the bottom of the non-negative integers rather than
63@ overflowing back to the most negative integer.
64SNS | DUP
65SSTTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSN | -(2^63)
66TSST | SUBTRACT
67NTSSSSTSSSTSSSSSSTSN | BRZ > 00010001 00000010
68
69@ Handle all the other numbers.
3625ff3a
AT
70SNS | DUP
71NTTSSSTSSSTSSSSSSSSN | BMI > 00010001 00000000
72NSNSSSTSSSTSSSSSSSTN | JMP > 00010001 00000001
73NSSVSSSTSSSTSSSSSSSSN | Mark: 00010001 00000000
74SSTTN | PUSH -1
75TSSN | MULTIPLY
76NSSVSSSTSSSTSSSSSSSTN | Mark: 00010001 00000001
77NTN | RTS
78
7359501c
AT
79@ Special case: Push 0 and return.
80NSSVSSSTSSSTSSSSSSTSN | Mark: 00010001 00000010
81SNN | DROP
82SSSSN | PUSH 0
83NTN | RTS
84
37372ed0
AT
85@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
86@ Name:
87@ gcd (10010)
88@ Description:
89@ Returns greatest common divisor of X and Y.
90@ Call Stack:
91@ Y
92@ X <-- TOS
93@ Return Stack:
94@ gcd(X,Y) <-- TOS
95@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
96#include <stack.pvvs>
97NSSVTSSTSN | Mark: 10010 (gcd)
98
99@ Since 1 > -1, transform problem into gcd(abs(X),abs(Y)).
100SNT | SWAP
101NSTTSSSTN | JSR > 10001 (abs)
102SNT | SWAP
103NSTTSSSTN | JSR > 10001 (abs)
104
105@ Verify neither operand is zero.
106SNT | SWAP
107SNS | DUP
108NTSSSSTSSTSSSSSSSSSN | BRZ > 00010010 00000000 (gcd:zero input)
109SNT | SWAP
110SNS | DUP
111NTSSSSTSSTSSSSSSSSSN | BRZ > 00010010 00000000 (gcd:zero input)
112
113@ Verify X != Y and sort X,Y so the smaller is TOS.
114SNS | DUP
115SSSTTN | PUSH 3
116NSTTTSSN | JSR > 1100 (deepdup)
117SNT | SWAP
118TSST | SUBTRACT
119@ TOS> Y-X, X, Y
120NTTSSSTSSTSSSSSSSSTN | BMI > 00010010 00000001 (gcd:swap inputs)
121NSNSSSTSSTSSSSSSSTSN | JMP > 00010010 00000010 (gcd:main loop)
122NSSVSSSTSSTSSSSSSSSTN | MARK: 00010010 00000001 (gcd:swap inputs)
123SNT | SWAP
124
125@ Main gcd loop.
126@ Euclidean algorithm.
127NSSVSSSTSSTSSSSSSSTSN | MARK: 00010010 00000010 (gcd:main loop)
128SNS | DUP
129SSSTTN | PUSH 3
130NSTTSTSN | JSR > 1010 (stackrotate)
131TSTT | MODULO
132SNS | DUP
133NTSSSSTSSTSSSSSSSTTN | BRZ > 00010010 00000011 (gcd:loop termination)
134NSNSSSTSSTSSSSSSSTSN | JMP > 00010010 00000010 (gcd:main loop)
135NSSVSSSTSSTSSSSSSSTTN | MARK: 00010010 00000011 (gcd:loop termination)
136SNN | DROP
137NTN | RTS
138
139@ At least one operand was zero.
140@ Since we define gcd(a,0) = a, return the other operand.
141NSSVSSSTSSTSSSSSSSSSN | MARK: 00010010 00000000 (gcd:zero input)
142SNN | DROP
143NTN | RTS
144
3625ff3a 145#endif