toilscript 0.1.2 → 0.1.5

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,413 @@
1
+ import { u128 } from './u128';
2
+ import { i256 } from './i256';
3
+ import { u256 } from './u256';
4
+
5
+ import { __clz128, __ctz128, } from '../globals';
6
+
7
+ import { atou128 } from '../utils';
8
+
9
+ /**
10
+ * 128-bit signed integer in two's complement representation.
11
+ * The `hi` field is signed, storing sign bits for negative values.
12
+ */
13
+ export class i128 {
14
+
15
+ constructor(public lo: u64 = 0, public hi: i64 = 0) {
16
+ }
17
+
18
+ @inline static get Zero(): i128 {
19
+ return new i128();
20
+ }
21
+
22
+ @inline static get One(): i128 {
23
+ return new i128(1, 0);
24
+ }
25
+
26
+ @inline static get Min(): i128 {
27
+ return new i128(0, 0x8000000000000000);
28
+ }
29
+
30
+ @inline static get Max(): i128 {
31
+ return new i128(u64.MAX_VALUE, 0x7FFFFFFFFFFFFFFF);
32
+ }
33
+
34
+ // Construct from decimal or hex string
35
+ @inline
36
+ static fromString(value: string, radix: i32 = 10): i128 {
37
+ // If the string is prefixed with "-" we rely on atou128 + two’s complement wrap
38
+ // in the final reinterpret.
39
+ return changetype<i128>(atou128(value, radix));
40
+ }
41
+
42
+ @inline
43
+ static fromI256(value: i256): i128 {
44
+ // Truncates top bits (value.hi1, value.hi2)
45
+ return new i128(value.lo1, value.lo2);
46
+ }
47
+
48
+ @inline
49
+ static fromU256(value: u256): i128 {
50
+ // Also truncation
51
+ return new i128(value.lo1, <i64>value.lo2);
52
+ }
53
+
54
+ @inline
55
+ static fromI128(value: i128): i128 {
56
+ return new i128(value.lo, value.hi);
57
+ }
58
+
59
+ @inline
60
+ static fromU128(value: u128): i128 {
61
+ return new i128(value.lo, <i64>value.hi);
62
+ }
63
+
64
+ @inline
65
+ static fromI64(value: i64): i128 {
66
+ return new i128(<u64>value, value >> 63);
67
+ }
68
+
69
+ @inline
70
+ static fromU64(value: u64): i128 {
71
+ return new i128(value, 0);
72
+ }
73
+
74
+ @inline
75
+ static fromF64(value: f64): i128 {
76
+ let i = <i64>value; // convert f64 -> i64 (round/truncate)
77
+ return new i128(<u64>i, i >> 63);
78
+ }
79
+
80
+ @inline
81
+ static fromF32(value: f32): i128 {
82
+ let i = <i64>value; // or <i32> then sign-extend
83
+ return new i128(<u64>i, i >> 63);
84
+ }
85
+
86
+ @inline
87
+ static fromI32(value: i32): i128 {
88
+ return new i128(<u64>value, <i64>(value >> 31));
89
+ }
90
+
91
+ @inline
92
+ static fromU32(value: u32): i128 {
93
+ return new i128(<u64>value, 0);
94
+ }
95
+
96
+ @inline
97
+ static fromBits(lo1: i32, lo2: i32, hi1: i32, hi2: i32): i128 {
98
+ let lo = ((<u64>lo2) << 32) | (<u64>(lo1) & 0xffffffff);
99
+ let hi = ((<i64>hi2) << 32) | (<i64>(hi1) & 0xffffffff);
100
+ return new i128(lo, hi);
101
+ }
102
+
103
+ @inline
104
+ static fromBytes<T>(array: T, bigEndian: bool = false): i128 {
105
+ if (array instanceof u8[]) {
106
+ return bigEndian
107
+ // @ts-ignore
108
+ ? i128.fromBytesBE(<u8[]>array)
109
+ : i128.fromBytesLE(<u8[]>array);
110
+ } else if (array instanceof Uint8Array) {
111
+ return bigEndian
112
+ ? i128.fromUint8ArrayBE(<Uint8Array>array)
113
+ : i128.fromUint8ArrayLE(<Uint8Array>array);
114
+ } else {
115
+ throw new TypeError("Unsupported generic type");
116
+ }
117
+ }
118
+
119
+ @inline
120
+ static fromBytesLE(array: u8[]): i128 {
121
+ return i128.fromUint8ArrayLE(changetype<Uint8Array>(array));
122
+ }
123
+
124
+ @inline
125
+ static fromBytesBE(array: u8[]): i128 {
126
+ return i128.fromUint8ArrayBE(changetype<Uint8Array>(array));
127
+ }
128
+
129
+ @inline
130
+ static fromUint8ArrayLE(array: Uint8Array): i128 {
131
+ assert(array.length && (array.length & 15) == 0);
132
+ let buffer = array.dataStart;
133
+ return new i128(
134
+ load<u64>(buffer, 0 * sizeof<u64>()),
135
+ load<u64>(buffer, 1 * sizeof<u64>())
136
+ );
137
+ }
138
+
139
+ static fromUint8ArrayBE(array: Uint8Array): i128 {
140
+ assert(array.length && (array.length & 15) == 0);
141
+ let buffer = array.dataStart;
142
+ return new i128(
143
+ bswap<u64>(load<u64>(buffer, 1 * sizeof<u64>())),
144
+ bswap<u64>(load<u64>(buffer, 0 * sizeof<u64>()))
145
+ );
146
+ }
147
+
148
+ /**
149
+ * Create 128-bit signed integer from a generic type T
150
+ * @param value
151
+ * @return 128-bit signed integer
152
+ */
153
+ @inline
154
+ static from<T>(value: T): i128 {
155
+ if (value instanceof bool) return i128.fromU64(<u64>value);
156
+ else if (value instanceof i8) return i128.fromI64(<i64>value);
157
+ else if (value instanceof u8) return i128.fromU64(<u64>value);
158
+ else if (value instanceof i16) return i128.fromI64(<i64>value);
159
+ else if (value instanceof u16) return i128.fromU64(<u64>value);
160
+ else if (value instanceof i32) return i128.fromI64(<i64>value);
161
+ else if (value instanceof u32) return i128.fromU64(<u64>value);
162
+ else if (value instanceof i64) return i128.fromI64(<i64>value);
163
+ else if (value instanceof u64) return i128.fromU64(<u64>value);
164
+ else if (value instanceof f32) return i128.fromF64(<f64>value);
165
+ else if (value instanceof f64) return i128.fromF64(<f64>value);
166
+ else if (value instanceof i128) return i128.fromI128(<i128>value);
167
+ else if (value instanceof u128) return i128.fromU128(<u128>value);
168
+ else if (value instanceof i256) return i128.fromI256(<i256>value);
169
+ else if (value instanceof u256) return i128.fromU256(<u256>value);
170
+ else if (value instanceof u8[]) return i128.fromBytes(<u8[]>value);
171
+ else throw new TypeError("Unsupported generic type");
172
+ }
173
+
174
+ @inline @operator.prefix('!')
175
+ static isEmpty(value: i128): bool {
176
+ return value.isZero();
177
+ }
178
+
179
+ @inline @operator('|')
180
+ static or(a: i128, b: i128): i128 {
181
+ return new i128(a.lo | b.lo, a.hi | b.hi);
182
+ }
183
+
184
+ @inline @operator('^')
185
+ static xor(a: i128, b: i128): i128 {
186
+ return new i128(a.lo ^ b.lo, a.hi ^ b.hi);
187
+ }
188
+
189
+ @inline @operator('&')
190
+ static and(a: i128, b: i128): i128 {
191
+ return new i128(a.lo & b.lo, a.hi & b.hi);
192
+ }
193
+
194
+ @inline @operator('<<')
195
+ static shl(value: i128, shift: i32): i128 {
196
+ shift &= 127;
197
+ 0xFFFFFFFFFFFFFFFF
198
+ if (!shift) return value;
199
+
200
+ let lo = value.lo;
201
+ let hi = value.hi;
202
+ if (shift < 64) {
203
+ let newLo = lo << shift;
204
+ let newHi = (hi << shift) | i64(lo >>> (64 - shift));
205
+ return new i128(newLo, newHi);
206
+ } else {
207
+ // shift >= 64
208
+ let s = shift - 64;
209
+ if (s == 0) {
210
+ // exactly 64
211
+ return new i128(0, lo as i64);
212
+ } else {
213
+ // 1..63
214
+ return new i128(0, (lo << s) as i64);
215
+ }
216
+ }
217
+ }
218
+
219
+ @inline @operator('>>>')
220
+ static shr_u(value: i128, shift: i32): i128 {
221
+ // an unsigned right shift of a *signed* 128
222
+ shift &= 127;
223
+ if (!shift) return value;
224
+
225
+ let lo = value.lo;
226
+ let hi = u64(value.hi); // reinterpret sign as high bits
227
+
228
+ if (shift < 64) {
229
+ let newLo = (lo >>> shift) | (hi << (64 - shift));
230
+ let newHi = hi >>> shift;
231
+ return new i128(newLo, newHi as i64);
232
+ } else {
233
+ // shift >= 64
234
+ let s = shift - 64;
235
+ if (s == 0) {
236
+ return new i128(hi, 0);
237
+ } else {
238
+ // 1..63
239
+ return new i128(hi >>> s, 0);
240
+ }
241
+ }
242
+ }
243
+
244
+ @inline @operator('+')
245
+ static add(a: i128, b: i128): i128 {
246
+ let lo = a.lo + b.lo;
247
+ let carry = (lo < a.lo) ? 1 : 0;
248
+ let hi = a.hi + b.hi + (carry as i64);
249
+ return new i128(lo, hi);
250
+ }
251
+
252
+ @inline @operator('-')
253
+ static sub(a: i128, b: i128): i128 {
254
+ let lo = a.lo - b.lo;
255
+ let borrow = (lo > a.lo) ? 1 : 0;
256
+ let hi = a.hi - b.hi - (borrow as i64);
257
+ return new i128(lo, hi);
258
+ }
259
+
260
+ @inline @operator('==')
261
+ static eq(a: i128, b: i128): bool {
262
+ return a.hi == b.hi && a.lo == b.lo;
263
+ }
264
+
265
+ @inline @operator('!=')
266
+ static ne(a: i128, b: i128): bool {
267
+ return !i128.eq(a, b);
268
+ }
269
+
270
+ @inline @operator('<')
271
+ static lt(a: i128, b: i128): bool {
272
+ let ah = a.hi, bh = b.hi;
273
+ // If hi parts differ, that decides the sign. Otherwise compare lo.
274
+ return ah == bh ? a.lo < b.lo : ah < bh;
275
+ }
276
+
277
+ @inline @operator('>')
278
+ static gt(a: i128, b: i128): bool {
279
+ return b < a;
280
+ }
281
+
282
+ @inline @operator('<=')
283
+ static le(a: i128, b: i128): bool {
284
+ return !i128.gt(a, b);
285
+ }
286
+
287
+ @inline @operator('>=')
288
+ static ge(a: i128, b: i128): bool {
289
+ return !i128.lt(a, b);
290
+ }
291
+
292
+ @inline
293
+ static ord(a: i128, b: i128): i32 {
294
+ // Return -1, 0, 1
295
+ if (a == b) return 0;
296
+ return i128.lt(a, b) ? -1 : 1;
297
+ }
298
+
299
+ @inline
300
+ static popcnt(value: i128): i32 {
301
+ return <i32>(popcnt(value.lo) + popcnt(value.hi));
302
+ }
303
+
304
+ @inline
305
+ static clz(value: i128): i32 {
306
+ return __clz128(value.lo, value.hi);
307
+ }
308
+
309
+ @inline
310
+ static ctz(value: i128): i32 {
311
+ return __ctz128(value.lo, value.hi);
312
+ }
313
+
314
+ @inline
315
+ static abs(value: i128): i128 {
316
+ // if negative, return -value
317
+ return value.isNeg() ? value.neg() : value;
318
+ }
319
+
320
+ @inline
321
+ isPos(): bool {
322
+ return this.hi >= 0;
323
+ }
324
+
325
+ @inline
326
+ isNeg(): bool {
327
+ return this.hi < 0;
328
+ }
329
+
330
+ @inline
331
+ isZero(): bool {
332
+ return !(this.lo | this.hi);
333
+ }
334
+
335
+ @inline @operator.prefix('~')
336
+ not(): i128 {
337
+ return new i128(~this.lo, ~this.hi);
338
+ }
339
+
340
+ @inline @operator.prefix('+')
341
+ pos(): i128 {
342
+ return this;
343
+ }
344
+
345
+ @inline @operator.prefix('-')
346
+ neg(): i128 {
347
+ // two's complement: ~x + 1
348
+ let nlo = ~this.lo;
349
+ let nhi = ~this.hi;
350
+
351
+ let sum = nlo + 1;
352
+ let carry = (sum < nlo) ? 1 : 0;
353
+ let hi2 = nhi + (carry as i64);
354
+
355
+ return new i128(sum, hi2);
356
+ }
357
+
358
+ /**
359
+ * Convert to a normal array of bytes (16 bytes for 128 bits).
360
+ * @param bigEndian If true, the highest bytes come first.
361
+ */
362
+ @inline
363
+ toBytes(bigEndian: bool = false): u8[] {
364
+ let result = new Array<u8>(16);
365
+ this.toArrayBuffer(result.dataStart, bigEndian);
366
+ return result;
367
+ }
368
+
369
+ /**
370
+ * Convert to a StaticArray<u8> of length 16.
371
+ * @param bigEndian If true, the highest bytes come first.
372
+ * @returns StaticArray<u8>
373
+ */
374
+ @inline
375
+ toStaticBytes(bigEndian: bool = false): StaticArray<u8> {
376
+ let result = new StaticArray<u8>(16);
377
+ this.toArrayBuffer(changetype<usize>(result), bigEndian);
378
+ return result;
379
+ }
380
+
381
+ /**
382
+ * Convert to Uint8Array
383
+ * @param bigEndian Little or Big Endian? Default: false
384
+ * @returns Uint8Array
385
+ */
386
+ @inline
387
+ toUint8Array(bigEndian: bool = false): Uint8Array {
388
+ let result = new Uint8Array(16);
389
+ this.toArrayBuffer(result.dataStart, bigEndian);
390
+ return result;
391
+ }
392
+
393
+ @inline
394
+ private toArrayBufferLE(buffer: usize): void {
395
+ store<u64>(buffer, this.lo, 0 * sizeof<u64>());
396
+ store<u64>(buffer, this.hi, 1 * sizeof<u64>());
397
+ }
398
+
399
+ @inline
400
+ private toArrayBufferBE(buffer: usize): void {
401
+ store<u64>(buffer, bswap<u64>(this.hi), 0 * sizeof<u64>());
402
+ store<u64>(buffer, bswap<u64>(this.lo), 1 * sizeof<u64>());
403
+ }
404
+
405
+ @inline
406
+ private toArrayBuffer(buffer: usize, bigEndian: bool = false): void {
407
+ if (bigEndian) {
408
+ this.toArrayBufferBE(buffer);
409
+ } else {
410
+ this.toArrayBufferLE(buffer);
411
+ }
412
+ }
413
+ }
@@ -0,0 +1,50 @@
1
+ export class i256 {
2
+
3
+ constructor(
4
+ public lo1: i64 = 0,
5
+ public lo2: i64 = 0,
6
+ public hi1: i64 = 0,
7
+ public hi2: i64 = 0,
8
+ ) {
9
+ }
10
+
11
+ @inline static get Zero(): i256 {
12
+ return new i256();
13
+ }
14
+
15
+ @inline static get One(): i256 {
16
+ return new i256(1);
17
+ }
18
+
19
+ @inline static get Min(): i256 {
20
+ return new i256(0, 0, 0, 0x8000000000000000);
21
+ }
22
+
23
+ @inline static get Max(): i256 {
24
+ return new i256(u64.MAX_VALUE, u64.MAX_VALUE, u64.MAX_VALUE, 0x7FFFFFFFFFFFFFFF);
25
+ }
26
+
27
+ @inline @operator.prefix('!')
28
+ static isEmpty(value: i256): bool {
29
+ return value.isZero();
30
+ }
31
+
32
+ @inline
33
+ isNeg(): bool {
34
+ return <bool>(this.hi2 >>> 63);
35
+ }
36
+
37
+ @inline
38
+ isZero(): bool {
39
+ return !(this.lo1 | this.lo2 | this.hi1 | this.hi2);
40
+ }
41
+
42
+ /*
43
+ @inline
44
+ static abs(value: i128): i128 {
45
+ return value < 0 ? value.neg() : value;
46
+ }
47
+ */
48
+
49
+ // TODO
50
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./i128";
2
+ export * from "./u128";
3
+ export * from "./u256";