porffor 0.55.15 → 0.55.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,233 @@
1
+ import type {} from './porffor.d.ts';
2
+
3
+ // digits is an array of u32s as digits in base 2^32
4
+ export const __Porffor_bigint_fromDigits = (negative: boolean, digits: i32[]): bigint => {
5
+ const len: i32 = digits.length;
6
+ if (len > 16383) throw new RangeError('Maximum BigInt size exceeded'); // (65536 - 4) / 4
7
+
8
+ // const ptr: i32 = Porffor.allocate();
9
+ const ptr: i32 = Porffor.wasm`local.get ${digits}`;
10
+
11
+ Porffor.wasm.i32.store8(ptr, negative ? 1 : 0, 0, 0);
12
+ Porffor.wasm.i32.store16(ptr, len, 0, 2);
13
+
14
+ for (let i: i32 = 0; i < len; i++) {
15
+ Porffor.wasm.i32.store(ptr + i * 4, digits[i], 0, 4);
16
+ }
17
+
18
+ const out: bigint = ptr;
19
+ return out;
20
+ };
21
+
22
+ export const __Porffor_bigint_fromNumber = (n: number): bigint => {
23
+ if (!Number.isInteger(n) || !Number.isFinite(n)) throw new RangeError('Cannot convert non-integer to BigInt');
24
+
25
+ const negative: boolean = n < 0;
26
+ n = Math.abs(n);
27
+
28
+ const digits: i32[] = Porffor.allocate();
29
+ while (n > 0) {
30
+ digits.unshift(n % 0x100000000);
31
+ n = Math.trunc(n / 0x100000000);
32
+ }
33
+
34
+ return __Porffor_bigint_fromDigits(negative, digits);
35
+ };
36
+
37
+ export const __Porffor_bigint_toNumber = (ptr: i32): number => {
38
+ const negative: boolean = Porffor.wasm.i32.load8_u(ptr, 0, 0) != 0;
39
+ const len: i32 = Porffor.wasm.i32.load16_u(ptr, 0, 2);
40
+
41
+ let out: number = 0;
42
+ for (let i: i32 = 0; i < len; i++) {
43
+ const d: i32 = Porffor.wasm.i32.load(ptr + i * 4, 0, 4);
44
+ out = out * 0x100000000 + d;
45
+ }
46
+
47
+ if (negative) out = -out;
48
+ return out;
49
+ };
50
+
51
+ export const __Porffor_bigint_fromString = (n: string|bytestring): bigint => {
52
+ const len: i32 = n.length;
53
+
54
+ let negative: boolean = false;
55
+ let end: i32 = 0;
56
+ if (n[0] === '-') {
57
+ negative = true;
58
+ end = 1;
59
+ } else if (n[0] === '+') {
60
+ end = 1;
61
+ }
62
+
63
+ // n -> digits (base 2^32) (most to least significant)
64
+ // 4294967294 -> [ 4294967294 ]
65
+ // 4294967295 -> [ 4294967295 ]
66
+ // 4294967296 -> [ 1, 0 ]
67
+ // 4294967297 -> [ 1, 1 ]
68
+ // 4294967298 -> [ 1, 2 ]
69
+ // 9007199254740992 -> [ 2097152 ]
70
+ // 9007199254740993 -> [ 2097152, 1 ]
71
+ // 9007199254740994 -> [ 2097152, 2 ]
72
+ // 9007199254740995 -> [ 2097152, 3 ]
73
+
74
+ const digits: i32[] = Porffor.allocate();
75
+
76
+ const base = 0x100000000; // 2^32
77
+
78
+ for (let i: i32 = end; i < len; i++) {
79
+ const char: i32 = n.charCodeAt(i);
80
+ const digit: i32 = char - 48;
81
+ if (digit < 0 || digit > 9) throw new SyntaxError('Invalid characters in BigInt string');
82
+
83
+ // Multiply current digits by 10 and add the new digit
84
+ let carry: i32 = digit;
85
+ for (let j: i32 = 0; j < digits.length; j++) {
86
+ const value: i32 = digits[j] * 10 + carry;
87
+ digits[j] = value % base;
88
+ carry = Math.trunc(value / base);
89
+ }
90
+
91
+ // If there's a carry left, push it as a new digit
92
+ if (carry > 0) {
93
+ digits.push(carry);
94
+ }
95
+ }
96
+
97
+ return __Porffor_bigint_fromDigits(negative, digits);
98
+ };
99
+
100
+ export const __Porffor_bigint_toString = (ptr: i32, radix: number): string => {
101
+ // todo
102
+ // return '';
103
+ };
104
+
105
+ export const __Porffor_bigint_add = (a: i32, b: i32, sub: boolean): bigint => {
106
+ const aNegative: boolean = Porffor.wasm.i32.load8_u(a, 0, 0) != 0;
107
+ const aLen: i32 = Porffor.wasm.i32.load16_u(a, 0, 2);
108
+
109
+ let bNegative: boolean = Porffor.wasm.i32.load8_u(b, 0, 0) != 0;
110
+ if (sub) bNegative = !bNegative;
111
+ const bLen: i32 = Porffor.wasm.i32.load16_u(b, 0, 2);
112
+
113
+ const maxLen: i32 = Math.max(aLen, bLen);
114
+ const digits: i32[] = Porffor.allocate();
115
+
116
+ // fast path: same sign
117
+ let negative: boolean = false;
118
+ let carry: i32 = 0;
119
+ if (aNegative == bNegative) {
120
+ negative = aNegative;
121
+
122
+ for (let i: i32 = 0; i < maxLen; i++) {
123
+ let aDigit: i32 = 0;
124
+ const aOffset: i32 = aLen - i;
125
+ if (aOffset > 0) aDigit = Porffor.wasm.i32.load(a + aOffset * 4, 0, 0);
126
+
127
+ let bDigit: i32 = 0;
128
+ const bOffset: i32 = bLen - i;
129
+ if (bOffset > 0) bDigit = Porffor.wasm.i32.load(b + bOffset * 4, 0, 0);
130
+
131
+ let sum: i32 = aDigit + bDigit + carry;
132
+ if (sum >= 0x100000000) {
133
+ sum -= 0x100000000;
134
+ carry = 1;
135
+ } else if (sum < 0) {
136
+ sum += 0x100000000;
137
+ carry = 1;
138
+ } else {
139
+ carry = 0;
140
+ }
141
+
142
+ digits.unshift(sum);
143
+ }
144
+ } else {
145
+ let aLarger: i32 = 0;
146
+ for (let i: i32 = 0; i < maxLen; i++) {
147
+ let aDigit: i32 = 0;
148
+ const aOffset: i32 = aLen - i;
149
+ if (aOffset > 0) aDigit = Porffor.wasm.i32.load(a + aOffset * 4, 0, 0);
150
+
151
+ let bDigit: i32 = 0;
152
+ const bOffset: i32 = bLen - i;
153
+ if (bOffset > 0) bDigit = Porffor.wasm.i32.load(b + bOffset * 4, 0, 0);
154
+
155
+ let sum: i32 = carry;
156
+ if (aNegative) sum -= aDigit;
157
+ else sum += aDigit;
158
+ if (bNegative) sum -= bDigit;
159
+ else sum += bDigit;
160
+
161
+ if (aDigit != bDigit) aLarger = aDigit > bDigit ? 1 : -1;
162
+
163
+ if (sum >= 0x100000000) {
164
+ sum -= 0x100000000;
165
+ carry = 1;
166
+ } else if (sum < 0) {
167
+ sum += 0x100000000;
168
+ carry = -1;
169
+ } else {
170
+ carry = 0;
171
+ }
172
+
173
+ digits.unshift(sum);
174
+ }
175
+
176
+ if (aLarger == 1) negative = aNegative;
177
+ else if (aLarger == -1) negative = bNegative;
178
+ }
179
+
180
+ if (carry != 0) {
181
+ digits.unshift(Math.abs(carry));
182
+ if (carry < 0) negative = !negative;
183
+ }
184
+
185
+ return __Porffor_bigint_fromDigits(negative, digits);
186
+ };
187
+
188
+ export const __Porffor_bigint_sub = (a: i32, b: i32): bigint => {
189
+ return __Porffor_bigint_add(a, b, true);
190
+ };
191
+
192
+ export const __Porffor_bigint_mul = (a: i32, b: i32): bigint => {
193
+ // todo
194
+ // return 0n;
195
+ };
196
+
197
+ export const __Porffor_bigint_div = (a: i32, b: i32): bigint => {
198
+ // todo
199
+ // return 0n;
200
+ };
201
+
202
+ export const __Porffor_bigint_rem = (a: i32, b: i32): bigint => {
203
+ // todo
204
+ // return 0n;
205
+ };
206
+
207
+ export const __Porffor_bigint_eq = (a: i32, b: i32): boolean => {
208
+ // todo
209
+ // return false;
210
+ };
211
+
212
+ export const __Porffor_bigint_ne = (a: i32, b: i32): boolean => {
213
+ return !__Porffor_bigint_eq(a, b);
214
+ };
215
+
216
+ export const __Porffor_bigint_gt = (a: i32, b: i32): boolean => {
217
+ // todo
218
+ // return false;
219
+ };
220
+
221
+ export const __Porffor_bigint_ge = (a: i32, b: i32): boolean => {
222
+ // todo
223
+ // return false;
224
+ };
225
+
226
+ export const __Porffor_bigint_lt = (a: i32, b: i32): boolean => {
227
+ return !__Porffor_bigint_ge(a, b);
228
+ };
229
+
230
+ export const __Porffor_bigint_le = (a: i32, b: i32): boolean => {
231
+ return !__Porffor_bigint_gt(a, b);
232
+ };
233
+