@temperlang/core 0.0.5 → 0.1.0
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.
- package/index.js +300 -121
- package/package.json +1 -1
- package/regex.js +16 -20
package/index.js
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
1
|
export * from "./interface-types.js";
|
|
2
2
|
export * from "./regex.js";
|
|
3
3
|
|
|
4
|
-
export const noResultException = new (class NoResultException extends Error {
|
|
5
|
-
constructor() {
|
|
6
|
-
super("NoResult");
|
|
7
|
-
}
|
|
8
|
-
})();
|
|
9
|
-
|
|
10
4
|
// Implements extension method String::isEmpty
|
|
11
5
|
export function stringIsEmpty(s) {
|
|
12
6
|
return s === "";
|
|
13
7
|
}
|
|
8
|
+
|
|
14
9
|
// Implements extension method String::split
|
|
15
10
|
export function stringSplit(s, separator) {
|
|
16
11
|
return s.split(separator).map((s) => s);
|
|
17
12
|
}
|
|
18
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Implements extension method String::toFloat64
|
|
16
|
+
* @param {string} s
|
|
17
|
+
*/
|
|
18
|
+
export function stringToFloat64(s) {
|
|
19
|
+
// TODO Consider JSON.parse + bonus constants instead? Faster or not?
|
|
20
|
+
if (!/^\s*-?(?:\d+(?:\.\d+)?(?:[eE][-+]?\d+)?|NaN|Infinity)\s*$/.test(s)) {
|
|
21
|
+
bubble();
|
|
22
|
+
}
|
|
23
|
+
return Number(s);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Implements extension method String::toInt
|
|
28
|
+
* @param {string} s
|
|
29
|
+
*/
|
|
30
|
+
export function stringToInt(s) {
|
|
31
|
+
// I'm not sure there's another simple reliable way to know if it's all used.
|
|
32
|
+
// This also checks against things like 2e0 -> 2.
|
|
33
|
+
if (!/^\s*-?\d+\s*$/.test(s)) {
|
|
34
|
+
bubble();
|
|
35
|
+
}
|
|
36
|
+
const result = parseInt(s, 10);
|
|
37
|
+
// TODO Could we use a more precise regex above to avoid this check here?
|
|
38
|
+
requireIsSafeInteger(result);
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
19
42
|
/** Specifically for utf8 and utf32, since utf16 is simpler in js. */
|
|
20
43
|
class TrickyStringSlice {
|
|
21
44
|
hasAtLeast(count) {
|
|
@@ -114,7 +137,7 @@ class Utf8StringSlice extends TrickyStringSlice {
|
|
|
114
137
|
let left = this.left;
|
|
115
138
|
let right = this.right;
|
|
116
139
|
if (left >= right) {
|
|
117
|
-
|
|
140
|
+
bubble();
|
|
118
141
|
}
|
|
119
142
|
|
|
120
143
|
let content = this.content;
|
|
@@ -131,32 +154,53 @@ class Utf8StringSlice extends TrickyStringSlice {
|
|
|
131
154
|
}
|
|
132
155
|
}
|
|
133
156
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
157
|
+
/**
|
|
158
|
+
* @param {number} count
|
|
159
|
+
* @return {number}
|
|
160
|
+
*/
|
|
161
|
+
_advanceLeft(count) {
|
|
162
|
+
let left = this.left;
|
|
163
|
+
let content = this.content;
|
|
164
|
+
let contentLen = content.length;
|
|
165
|
+
let idx = left >> 2;
|
|
166
|
+
let sub = left & 3;
|
|
167
|
+
|
|
168
|
+
while (count > 0 && idx < contentLen) {
|
|
169
|
+
let cp = content.codePointAt(idx);
|
|
170
|
+
let rem = nUtf8BytesInChar(cp) - sub;
|
|
171
|
+
if (rem > count) {
|
|
172
|
+
sub += count;
|
|
173
|
+
count = 0;
|
|
148
174
|
} else {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
byteOffset + 1 < nBytes
|
|
153
|
-
? left + 1
|
|
154
|
-
: (left & ~3) + ((nBytes + 4) & ~3);
|
|
175
|
+
count -= rem;
|
|
176
|
+
sub = 0;
|
|
177
|
+
idx += cp > 0x10000 ? 2 : 1;
|
|
155
178
|
}
|
|
156
|
-
return new Utf8StringSlice(content, newLeft, right);
|
|
157
|
-
} else {
|
|
158
|
-
throw new Error("TODO");
|
|
159
179
|
}
|
|
180
|
+
|
|
181
|
+
return count ? this.right : Math.min(idx << 2 | sub, this.right);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @param {number} count
|
|
186
|
+
* @return {Utf8StringSlice}
|
|
187
|
+
*/
|
|
188
|
+
advance(count) {
|
|
189
|
+
let newLeft = this._advanceLeft(count);
|
|
190
|
+
return (this.left === newLeft)
|
|
191
|
+
? this
|
|
192
|
+
: new Utf8StringSlice(this.content, newLeft, this.right);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @param {number} count
|
|
197
|
+
* @return {Utf8StringSlice}
|
|
198
|
+
*/
|
|
199
|
+
limit(count) {
|
|
200
|
+
let newRight = this._advanceLeft(count);
|
|
201
|
+
return (this.right === newRight)
|
|
202
|
+
? this
|
|
203
|
+
: new Utf8StringSlice(this.content, this.left, newRight);
|
|
160
204
|
}
|
|
161
205
|
|
|
162
206
|
[Symbol.iterator]() {
|
|
@@ -217,26 +261,39 @@ class Utf16StringSlice {
|
|
|
217
261
|
let left = this.left;
|
|
218
262
|
let right = this.right;
|
|
219
263
|
if (left >= right) {
|
|
220
|
-
|
|
264
|
+
bubble();
|
|
221
265
|
}
|
|
222
266
|
return this.content.charCodeAt(left);
|
|
223
267
|
}
|
|
224
268
|
|
|
269
|
+
/**
|
|
270
|
+
* @param {number} count
|
|
271
|
+
* @return {number}
|
|
272
|
+
*/
|
|
273
|
+
_advanceLeft(count) {
|
|
274
|
+
return Math.min(this.left + count, this.right);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* @param {number} count
|
|
279
|
+
* @return {Utf16StringSlice}
|
|
280
|
+
*/
|
|
225
281
|
advance(count) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
282
|
+
let newLeft = this._advanceLeft(count);
|
|
283
|
+
return this.left === newLeft
|
|
284
|
+
? this
|
|
285
|
+
: new Utf16StringSlice(this.content, newLeft, this.right);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* @param {number} count
|
|
290
|
+
* @return {Utf16StringSlice}
|
|
291
|
+
*/
|
|
292
|
+
limit(count) {
|
|
293
|
+
let newRight = this._advanceLeft(count);
|
|
294
|
+
return this.right === newRight
|
|
295
|
+
? this
|
|
296
|
+
: new Utf16StringSlice(this.content, this.left, newRight);
|
|
240
297
|
}
|
|
241
298
|
|
|
242
299
|
[Symbol.iterator]() {
|
|
@@ -295,35 +352,55 @@ class CodePointsStringSlice extends TrickyStringSlice {
|
|
|
295
352
|
|
|
296
353
|
read() {
|
|
297
354
|
if (this.left >= this.right) {
|
|
298
|
-
|
|
355
|
+
bubble();
|
|
299
356
|
}
|
|
300
357
|
return this.content.codePointAt(this.left);
|
|
301
358
|
}
|
|
302
359
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
newLeft += 1;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
if (newLeft >= right) {
|
|
323
|
-
newLeft = right;
|
|
360
|
+
/**
|
|
361
|
+
* @param {number} count
|
|
362
|
+
* @return {number}
|
|
363
|
+
*/
|
|
364
|
+
_advanceLeft(count) {
|
|
365
|
+
let left = this.left;
|
|
366
|
+
let right = this.right;
|
|
367
|
+
let content = this.content;
|
|
368
|
+
if (count <= 0) { return left }
|
|
369
|
+
let newLeft = left;
|
|
370
|
+
for (let i = count; i && newLeft < right; --i) {
|
|
371
|
+
let cp = content.codePointAt(newLeft);
|
|
372
|
+
if (cp > 0xffff) {
|
|
373
|
+
newLeft += 2;
|
|
374
|
+
} else {
|
|
375
|
+
newLeft += 1;
|
|
324
376
|
}
|
|
325
|
-
return new CodePointsStringSlice(this.content, newLeft, right);
|
|
326
377
|
}
|
|
378
|
+
if (newLeft >= right) {
|
|
379
|
+
newLeft = right;
|
|
380
|
+
}
|
|
381
|
+
return newLeft;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* @param {number} count
|
|
386
|
+
* @return {CodePointsStringSlice}
|
|
387
|
+
*/
|
|
388
|
+
advance(count) {
|
|
389
|
+
let newLeft = this._advanceLeft(count);
|
|
390
|
+
return (newLeft === this.left)
|
|
391
|
+
? this
|
|
392
|
+
: new CodePointsStringSlice(this.content, newLeft, this.right);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @param {number} count
|
|
397
|
+
* @return {CodePointsStringSlice}
|
|
398
|
+
*/
|
|
399
|
+
limit(count) {
|
|
400
|
+
let newRight = this._advanceLeft(count);
|
|
401
|
+
return (newRight === this.right)
|
|
402
|
+
? this
|
|
403
|
+
: new CodePointsStringSlice(this.content, this.left, newRight);
|
|
327
404
|
}
|
|
328
405
|
|
|
329
406
|
[Symbol.iterator]() {
|
|
@@ -363,13 +440,25 @@ export function intToString(i, radix) {
|
|
|
363
440
|
return i.toString(radix);
|
|
364
441
|
}
|
|
365
442
|
|
|
443
|
+
// Implements extension method Float64::near
|
|
444
|
+
export function float64Near(x, y, relTol, absTol) {
|
|
445
|
+
if (relTol === undefined) {
|
|
446
|
+
relTol = 1e-9;
|
|
447
|
+
}
|
|
448
|
+
if (absTol === undefined) {
|
|
449
|
+
absTol = 0;
|
|
450
|
+
}
|
|
451
|
+
const margin = Math.max(Math.max(Math.abs(x), Math.abs(y)) * relTol, absTol);
|
|
452
|
+
return Math.abs(x - y) < margin;
|
|
453
|
+
}
|
|
454
|
+
|
|
366
455
|
// Implements extension method Float64::toInt
|
|
367
456
|
export function float64ToInt(n) {
|
|
368
457
|
const i = float64ToIntUnsafe(n);
|
|
369
458
|
if (Math.abs(n - i) < 1) {
|
|
370
459
|
return i;
|
|
371
460
|
} else {
|
|
372
|
-
|
|
461
|
+
bubble();
|
|
373
462
|
}
|
|
374
463
|
}
|
|
375
464
|
|
|
@@ -388,27 +477,18 @@ export function float64ToIntUnsafe(n) {
|
|
|
388
477
|
export function float64ToString(n) {
|
|
389
478
|
// TODO(mikesamuel, issue#579): need functional test to nail down
|
|
390
479
|
// double formatting threshholds.
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
return "
|
|
402
|
-
|
|
403
|
-
let result = n.toString();
|
|
404
|
-
// Rely on eagerness and js number formatting rules here.
|
|
405
|
-
const groups = /(-?[0-9]+)(\.[0-9]+)?(.+)?/.exec(result);
|
|
406
|
-
if (groups === null) {
|
|
407
|
-
return result;
|
|
408
|
-
} else {
|
|
409
|
-
// Guarantee a decimal point for floats.
|
|
410
|
-
return `${groups[1]}${groups[2] || ".0"}${groups[3] || ""}`;
|
|
411
|
-
}
|
|
480
|
+
if (n == 0) {
|
|
481
|
+
return Object.is(n, -0) ? "-0.0" : "0.0";
|
|
482
|
+
} else {
|
|
483
|
+
let result = n.toString();
|
|
484
|
+
// Rely on eagerness and js number formatting rules here.
|
|
485
|
+
const groups = /(-?[0-9]+)(\.[0-9]+)?(.+)?/.exec(result);
|
|
486
|
+
if (groups === null) {
|
|
487
|
+
return result;
|
|
488
|
+
} else {
|
|
489
|
+
// Guarantee a decimal point for floats.
|
|
490
|
+
return `${groups[1]}${groups[2] || ".0"}${groups[3] || ""}`;
|
|
491
|
+
}
|
|
412
492
|
}
|
|
413
493
|
}
|
|
414
494
|
|
|
@@ -446,10 +526,6 @@ const byteInfos = [
|
|
|
446
526
|
{ andMask: 0b0011_1111, orMask: 0b1000_0000, shift: 0 },
|
|
447
527
|
];
|
|
448
528
|
|
|
449
|
-
function freeze(items) {
|
|
450
|
-
return Object.freeze(items);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
529
|
// Implements extension method ListBuilder::add
|
|
454
530
|
export function listBuilderAdd(ls, newItem, at) {
|
|
455
531
|
if (at === undefined) {
|
|
@@ -458,7 +534,7 @@ export function listBuilderAdd(ls, newItem, at) {
|
|
|
458
534
|
ls.push(newItem);
|
|
459
535
|
} else {
|
|
460
536
|
if (at < 0 || at > ls.length) {
|
|
461
|
-
|
|
537
|
+
bubble();
|
|
462
538
|
}
|
|
463
539
|
ls.splice(at, 0, newItem);
|
|
464
540
|
}
|
|
@@ -469,7 +545,7 @@ export function listBuilderAddAll(ls, newItems, at) {
|
|
|
469
545
|
ls.push(...newItems);
|
|
470
546
|
} else {
|
|
471
547
|
if (at < 0 || at > ls.length) {
|
|
472
|
-
|
|
548
|
+
bubble();
|
|
473
549
|
}
|
|
474
550
|
ls.splice(at, 0, ...newItems);
|
|
475
551
|
}
|
|
@@ -505,7 +581,7 @@ export function listGet(ls, i) {
|
|
|
505
581
|
if (0 <= i && i < length) {
|
|
506
582
|
return ls[i];
|
|
507
583
|
}
|
|
508
|
-
|
|
584
|
+
bubble();
|
|
509
585
|
}
|
|
510
586
|
// Implements extension method List::getOr
|
|
511
587
|
export function listGetOr(ls, i, fallback) {
|
|
@@ -548,12 +624,20 @@ export function listMap(ls, transform) {
|
|
|
548
624
|
}
|
|
549
625
|
return freeze(mapped);
|
|
550
626
|
}
|
|
627
|
+
// Implements extension method Listed::toList
|
|
628
|
+
export function listedToList(ls) {
|
|
629
|
+
if (Object.isFrozen(ls)) {
|
|
630
|
+
return ls;
|
|
631
|
+
} else {
|
|
632
|
+
return listBuilderToList(ls);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
551
635
|
// Implements extension method ListBuilder::removeLast
|
|
552
636
|
export function listBuilderRemoveLast(ls) {
|
|
553
637
|
if (ls.length) {
|
|
554
638
|
return ls.pop();
|
|
555
639
|
} else {
|
|
556
|
-
|
|
640
|
+
bubble();
|
|
557
641
|
}
|
|
558
642
|
}
|
|
559
643
|
// Implements extension method ListBuilder::reverse
|
|
@@ -616,7 +700,7 @@ class FreezeMap extends Map {
|
|
|
616
700
|
}
|
|
617
701
|
}
|
|
618
702
|
export function mapConstructor(entries) {
|
|
619
|
-
return
|
|
703
|
+
return freeze(new FreezeMap(entries));
|
|
620
704
|
}
|
|
621
705
|
// MapBuilder
|
|
622
706
|
export function mapBuilderConstructor(entries) {
|
|
@@ -627,14 +711,23 @@ export function mapBuilderRemove(builder, key) {
|
|
|
627
711
|
if (builder.delete(key)) {
|
|
628
712
|
return result;
|
|
629
713
|
} else {
|
|
630
|
-
|
|
714
|
+
bubble();
|
|
631
715
|
}
|
|
632
716
|
}
|
|
633
717
|
export function mapBuilderSet(builder, key, value) {
|
|
634
718
|
builder.set(key, value);
|
|
635
719
|
}
|
|
636
|
-
export function
|
|
637
|
-
|
|
720
|
+
export function mappedToMap(mapped) {
|
|
721
|
+
if (mapped instanceof FreezeMap) {
|
|
722
|
+
return mapped;
|
|
723
|
+
}
|
|
724
|
+
return freeze(new FreezeMap(mapped));
|
|
725
|
+
}
|
|
726
|
+
export function mapBuilderToMap(mapped) {
|
|
727
|
+
return freeze(new FreezeMap(mapped));
|
|
728
|
+
}
|
|
729
|
+
export function mappedToMapBuilder(mapped) {
|
|
730
|
+
return new Map(mapped);
|
|
638
731
|
}
|
|
639
732
|
// Pair
|
|
640
733
|
class Pair {
|
|
@@ -653,20 +746,88 @@ class Pair {
|
|
|
653
746
|
}
|
|
654
747
|
}
|
|
655
748
|
export function pairConstructor(key, value) {
|
|
656
|
-
return
|
|
749
|
+
return freeze(new Pair(key, value));
|
|
657
750
|
}
|
|
658
751
|
// Mapped
|
|
752
|
+
export function mappedLength(map) {
|
|
753
|
+
return map.size;
|
|
754
|
+
}
|
|
659
755
|
export function mappedGet(map, key) {
|
|
660
756
|
const result = map.get(key);
|
|
661
757
|
// TODO Under compiler-error-free Temper, could undefined values get set?
|
|
662
|
-
|
|
758
|
+
// TODO Would Map<?, Void> be impossible to feed once we get checks in place?
|
|
663
759
|
if (result === undefined) {
|
|
664
|
-
|
|
760
|
+
bubble();
|
|
665
761
|
}
|
|
666
762
|
return result;
|
|
667
763
|
}
|
|
764
|
+
export function mappedGetOr(map, key, fallback) {
|
|
765
|
+
return map.get(key) ?? fallback;
|
|
766
|
+
}
|
|
767
|
+
export function mappedHas(map, key) {
|
|
768
|
+
return map.has(key);
|
|
769
|
+
}
|
|
770
|
+
export function mappedKeys(map) {
|
|
771
|
+
return freeze(Array.prototype.slice.call(map.keys()));
|
|
772
|
+
}
|
|
773
|
+
export function mappedValues(map) {
|
|
774
|
+
return freeze(Array.prototype.slice.call(map.values()));
|
|
775
|
+
}
|
|
668
776
|
export function mappedToList(map) {
|
|
669
|
-
return Array.from(map, ([key, value]) => new Pair(key, value));
|
|
777
|
+
return freeze(Array.from(map, ([key, value]) => new Pair(key, value)));
|
|
778
|
+
}
|
|
779
|
+
export function mappedToListWith(map, func) {
|
|
780
|
+
return freeze(Array.from(map, ([key, value]) => func(key, value)));
|
|
781
|
+
}
|
|
782
|
+
export function mappedToListBuilder(map) {
|
|
783
|
+
return freeze(Array.from(map, ([key, value]) => new Pair(key, value)));
|
|
784
|
+
}
|
|
785
|
+
export function mappedToListBuilderWith(map, func) {
|
|
786
|
+
return freeze(Array.from(map, ([key, value]) => func(key, value)));
|
|
787
|
+
}
|
|
788
|
+
export function mappedForEach(map, func) {
|
|
789
|
+
map.forEach((v, k) => func(k, v));
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// Implements Date::constructor
|
|
793
|
+
export function dateConstructor(year, month, day) {
|
|
794
|
+
let d = new Date(0);
|
|
795
|
+
// If we were to pass year into `new Date`, then it would
|
|
796
|
+
// have 1900 added when in the range [0, 99].
|
|
797
|
+
// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#year
|
|
798
|
+
d.setUTCFullYear(year);
|
|
799
|
+
d.setUTCMonth(month - 1 /* JS months are zero indexed */);
|
|
800
|
+
d.setUTCDate(day); // UTCDay is day of the week
|
|
801
|
+
return d;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// Implements Date::today
|
|
805
|
+
/**
|
|
806
|
+
* @returns {Date}
|
|
807
|
+
*/
|
|
808
|
+
export function dateToday() {
|
|
809
|
+
let d = new Date(Date.now());
|
|
810
|
+
// Get rid of the time component.
|
|
811
|
+
d.setTime(
|
|
812
|
+
Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate())
|
|
813
|
+
);
|
|
814
|
+
return d;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// Implements Date::yearsBetween
|
|
818
|
+
/**
|
|
819
|
+
* @param {Date} start
|
|
820
|
+
* @param {Date} end
|
|
821
|
+
*
|
|
822
|
+
* @returns {number}
|
|
823
|
+
*/
|
|
824
|
+
export function dateYearsBetween(start, end) {
|
|
825
|
+
let yearDelta = end.getUTCFullYear() - start.getUTCFullYear();
|
|
826
|
+
let monthDelta = end.getUTCMonth() - start.getUTCMonth();
|
|
827
|
+
return yearDelta -
|
|
828
|
+
// If the end month/day is before the start's then we
|
|
829
|
+
// don't have a full year.
|
|
830
|
+
(monthDelta < 0 || monthDelta == 0 && end.getUTCDate() < start.getUTCDate());
|
|
670
831
|
}
|
|
671
832
|
|
|
672
833
|
// Implements extension method Deque::constructor
|
|
@@ -692,7 +853,7 @@ export function dequeRemoveFirst(deque) {
|
|
|
692
853
|
if (length === nTaken) {
|
|
693
854
|
deque[DEQUE_NTAKEN] = 0;
|
|
694
855
|
deque.length = 0;
|
|
695
|
-
|
|
856
|
+
bubble();
|
|
696
857
|
}
|
|
697
858
|
let item = deque[nTaken];
|
|
698
859
|
let nShiftThreshhold = (length / 2) | 0;
|
|
@@ -762,6 +923,7 @@ const String = "".constructor;
|
|
|
762
923
|
const { isArray } = Array;
|
|
763
924
|
const { isSafeInteger } = Number;
|
|
764
925
|
const { trunc } = Math;
|
|
926
|
+
const { freeze } = Object;
|
|
765
927
|
|
|
766
928
|
export {
|
|
767
929
|
// Export reliable paths to JS builtins, so they can import them
|
|
@@ -774,35 +936,35 @@ export {
|
|
|
774
936
|
|
|
775
937
|
export function requireIsArray(x) {
|
|
776
938
|
if (!isArray(x)) {
|
|
777
|
-
|
|
939
|
+
bubble();
|
|
778
940
|
}
|
|
779
941
|
return x;
|
|
780
942
|
}
|
|
781
943
|
|
|
782
944
|
export function requireInstanceOf(x, typeRequirement) {
|
|
783
945
|
if (!(x instanceof typeRequirement)) {
|
|
784
|
-
|
|
946
|
+
bubble();
|
|
785
947
|
}
|
|
786
948
|
return x;
|
|
787
949
|
}
|
|
788
950
|
|
|
789
951
|
export function requireIsSafeInteger(x) {
|
|
790
952
|
if (!isSafeInteger(x)) {
|
|
791
|
-
|
|
953
|
+
bubble();
|
|
792
954
|
}
|
|
793
955
|
return x;
|
|
794
956
|
}
|
|
795
957
|
|
|
796
958
|
export function requireSame(x, y) {
|
|
797
959
|
if (x !== y) {
|
|
798
|
-
|
|
960
|
+
bubble();
|
|
799
961
|
}
|
|
800
962
|
return x;
|
|
801
963
|
}
|
|
802
964
|
|
|
803
965
|
export function requireTypeOf(x, typeOfString) {
|
|
804
966
|
if (typeof x !== typeOfString) {
|
|
805
|
-
|
|
967
|
+
bubble();
|
|
806
968
|
}
|
|
807
969
|
return x;
|
|
808
970
|
}
|
|
@@ -823,7 +985,7 @@ export function divDubDub(x, y) {
|
|
|
823
985
|
export function divIntInt(x, y) {
|
|
824
986
|
const result = trunc(x / y);
|
|
825
987
|
if (!isSafeInteger(result)) {
|
|
826
|
-
|
|
988
|
+
bubble();
|
|
827
989
|
}
|
|
828
990
|
/* not NaN or infinite */
|
|
829
991
|
return result;
|
|
@@ -831,7 +993,7 @@ export function divIntInt(x, y) {
|
|
|
831
993
|
export function modIntInt(x, y) {
|
|
832
994
|
const result = trunc(x % y);
|
|
833
995
|
if (!isSafeInteger(result)) {
|
|
834
|
-
|
|
996
|
+
bubble();
|
|
835
997
|
}
|
|
836
998
|
/* not NaN or infinite */
|
|
837
999
|
return result;
|
|
@@ -902,16 +1064,23 @@ export function cmpGeneric(a, b) {
|
|
|
902
1064
|
if (a === b) {
|
|
903
1065
|
return Object.is(a, 0) - Object.is(b, 0);
|
|
904
1066
|
}
|
|
1067
|
+
if (isNaN(a) || isNaN(b)) {
|
|
1068
|
+
return isNaN(a) - isNaN(b);
|
|
1069
|
+
}
|
|
905
1070
|
return a - b;
|
|
906
1071
|
}
|
|
907
1072
|
if (typeof a === "boolean" && typeof b === "boolean") {
|
|
908
1073
|
return a - b;
|
|
909
1074
|
}
|
|
910
|
-
|
|
1075
|
+
bubble();
|
|
911
1076
|
};
|
|
912
1077
|
export function ltGeneric(a, b) {
|
|
913
1078
|
if (typeof a === "number" && typeof b === "number") {
|
|
914
|
-
return
|
|
1079
|
+
return (
|
|
1080
|
+
(isNaN(b) && !isNaN(a)) ||
|
|
1081
|
+
a < b ||
|
|
1082
|
+
(a === 0 && b === 0 && Object.is(a, 0) < Object.is(b, 0))
|
|
1083
|
+
);
|
|
915
1084
|
}
|
|
916
1085
|
if (typeof a == "boolean" && typeof b === "boolean") {
|
|
917
1086
|
return a < b;
|
|
@@ -920,7 +1089,10 @@ export function ltGeneric(a, b) {
|
|
|
920
1089
|
}
|
|
921
1090
|
export function leGeneric(a, b) {
|
|
922
1091
|
if (typeof a === "number" && typeof b === "number") {
|
|
923
|
-
return
|
|
1092
|
+
return (
|
|
1093
|
+
isNaN(b) ||
|
|
1094
|
+
(a <= b && (a !== 0 || b !== 0 || Object.is(a, 0) <= Object.is(b, 0)))
|
|
1095
|
+
);
|
|
924
1096
|
}
|
|
925
1097
|
if (typeof a == "boolean" && typeof b === "boolean") {
|
|
926
1098
|
return a <= b;
|
|
@@ -929,7 +1101,11 @@ export function leGeneric(a, b) {
|
|
|
929
1101
|
}
|
|
930
1102
|
export function gtGeneric(a, b) {
|
|
931
1103
|
if (typeof a === "number" && typeof b === "number") {
|
|
932
|
-
return
|
|
1104
|
+
return (
|
|
1105
|
+
(isNaN(a) && !isNaN(b)) ||
|
|
1106
|
+
a > b ||
|
|
1107
|
+
(a === 0 && b === 0 && Object.is(a, 0) > Object.is(b, 0))
|
|
1108
|
+
);
|
|
933
1109
|
}
|
|
934
1110
|
if (typeof a == "boolean" && typeof b === "boolean") {
|
|
935
1111
|
return a > b;
|
|
@@ -938,7 +1114,10 @@ export function gtGeneric(a, b) {
|
|
|
938
1114
|
}
|
|
939
1115
|
export function geGeneric(a, b) {
|
|
940
1116
|
if (typeof a === "number" && typeof b === "number") {
|
|
941
|
-
return
|
|
1117
|
+
return (
|
|
1118
|
+
isNaN(a) ||
|
|
1119
|
+
(a >= b && (a !== 0 || b !== 0 || Object.is(a, 0) >= Object.is(b, 0)))
|
|
1120
|
+
);
|
|
942
1121
|
}
|
|
943
1122
|
if (typeof a == "boolean" && typeof b === "boolean") {
|
|
944
1123
|
return a >= b;
|
|
@@ -951,8 +1130,8 @@ export function eqGeneric(a, b) {
|
|
|
951
1130
|
export function neGeneric(a, b) {
|
|
952
1131
|
return !Object.is(a, b);
|
|
953
1132
|
}
|
|
954
|
-
export function
|
|
955
|
-
throw
|
|
1133
|
+
export function bubble() {
|
|
1134
|
+
throw Error();
|
|
956
1135
|
}
|
|
957
1136
|
export function print(a) {
|
|
958
1137
|
console.log("%s", a);
|
package/package.json
CHANGED
package/regex.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import {noResultException} from "./index.js";
|
|
2
|
-
|
|
3
1
|
export function compiledRegexCompiledFound(_, compiled, text) {
|
|
4
2
|
return compiled.test(text);
|
|
5
3
|
}
|
|
6
4
|
|
|
7
5
|
export function compiledRegexCompiledFind(_, compiled, text, regexRefs) {
|
|
8
|
-
|
|
6
|
+
const match = compiledRegexCompiledFindEx(_, compiled, text, regexRefs);
|
|
7
|
+
if (match === undefined) {
|
|
8
|
+
// We could just fail on `undefined.groups`, but that seems accidental.
|
|
9
|
+
throw Error();
|
|
10
|
+
}
|
|
11
|
+
return match.groups;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
|
-
* @param {RegExp} compiled
|
|
13
|
-
* @param {string} text
|
|
15
|
+
* @param {RegExp} compiled
|
|
16
|
+
* @param {string} text
|
|
14
17
|
*/
|
|
15
18
|
function compiledRegexCompiledFindEx(_, compiled, text, regexRefs) {
|
|
16
19
|
const match = compiled.exec(text);
|
|
17
20
|
if (match === null) {
|
|
18
|
-
|
|
21
|
+
return undefined;
|
|
19
22
|
}
|
|
20
23
|
const { groups, indices: { groups: indexGroups } } = match;
|
|
21
24
|
// Find the begin indices in code points for all matched groups.
|
|
@@ -64,9 +67,9 @@ function codePointIndices(text, unitNameIndexArray) {
|
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
/**
|
|
67
|
-
* @param {RegExp} compiled
|
|
68
|
-
* @param {string} text
|
|
69
|
-
* @param {(groups: Map<string, any>) => string} format
|
|
70
|
+
* @param {RegExp} compiled
|
|
71
|
+
* @param {string} text
|
|
72
|
+
* @param {(groups: Map<string, any>) => string} format
|
|
70
73
|
* @returns {string}
|
|
71
74
|
*/
|
|
72
75
|
export function compiledRegexCompiledReplace(
|
|
@@ -80,17 +83,10 @@ export function compiledRegexCompiledReplace(
|
|
|
80
83
|
// make our interface consistent, so we have to do this manually here.
|
|
81
84
|
// The hope is that we can optimize a bunch out when we have compile-time
|
|
82
85
|
// contant patterns and customized match result types.
|
|
83
|
-
let match;
|
|
84
|
-
|
|
85
|
-
match
|
|
86
|
-
|
|
87
|
-
if (e === noResultException) {
|
|
88
|
-
// Manually handle no match case for our manual replace logic.
|
|
89
|
-
return text;
|
|
90
|
-
} else {
|
|
91
|
-
// This shouldn't happen if we don't have bugs, but forward it in case.
|
|
92
|
-
throw e;
|
|
93
|
-
}
|
|
86
|
+
let match = compiledRegexCompiledFindEx(_, compiled, text, regexRefs);
|
|
87
|
+
if (match === undefined) {
|
|
88
|
+
// Manually handle no match case for our manual replace logic.
|
|
89
|
+
return text;
|
|
94
90
|
}
|
|
95
91
|
// Index and length in js space should save some processing.
|
|
96
92
|
const { groups, index, length } = match;
|