@calcit/procs 0.29.0-alpha.27 → 0.29.0-alpha.28
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/lib/calcit-data.d.mts +1 -0
- package/lib/calcit-data.mjs +33 -1
- package/lib/calcit.procs.mjs +70 -47
- package/lib/package.json +1 -1
- package/package.json +1 -1
package/lib/calcit-data.d.mts
CHANGED
|
@@ -37,6 +37,7 @@ export declare let newTag: (content: string) => CalcitTag;
|
|
|
37
37
|
export declare let castTag: (x: CalcitValue) => CalcitTag;
|
|
38
38
|
export declare var refsRegistry: Map<string, CalcitRef>;
|
|
39
39
|
export declare let hashFunction: (x: CalcitValue) => Hash;
|
|
40
|
+
export declare let format_calcit_number: (x: number) => string;
|
|
40
41
|
export declare let toString: (x: CalcitValue, escaped: boolean, disableJsDataWarning?: boolean) => string;
|
|
41
42
|
export declare let to_js_data: (x: CalcitValue, options?: CalcitValue) => any;
|
|
42
43
|
export declare let _$n_map_$o_get: (xs: CalcitValue, k: CalcitValue) => CalcitValue;
|
package/lib/calcit-data.mjs
CHANGED
|
@@ -447,6 +447,38 @@ let hashCirru = (base, x) => {
|
|
|
447
447
|
};
|
|
448
448
|
// Dirty code to change ternary-tree behavior
|
|
449
449
|
overwriteHashGenerator(hashFunction);
|
|
450
|
+
// Calcit number text, shared by `turn-string`, `str` and printing (see docs/data/number.md).
|
|
451
|
+
export let format_calcit_number = (x) => {
|
|
452
|
+
// Match native f64 Display, which expands finite exponents into decimal notation.
|
|
453
|
+
if (Object.is(x, -0)) {
|
|
454
|
+
return "-0";
|
|
455
|
+
}
|
|
456
|
+
if (x === Infinity) {
|
|
457
|
+
return "inf";
|
|
458
|
+
}
|
|
459
|
+
if (x === -Infinity) {
|
|
460
|
+
return "-inf";
|
|
461
|
+
}
|
|
462
|
+
const text = x.toString();
|
|
463
|
+
const exponentIndex = text.indexOf("e");
|
|
464
|
+
if (exponentIndex < 0) {
|
|
465
|
+
return text;
|
|
466
|
+
}
|
|
467
|
+
const mantissa = text.slice(0, exponentIndex);
|
|
468
|
+
const exponent = Number(text.slice(exponentIndex + 1));
|
|
469
|
+
const sign = mantissa.startsWith("-") ? "-" : "";
|
|
470
|
+
const unsigned = sign ? mantissa.slice(1) : mantissa;
|
|
471
|
+
const decimalPoint = unsigned.indexOf(".");
|
|
472
|
+
const decimalIndex = (decimalPoint < 0 ? unsigned.length : decimalPoint) + exponent;
|
|
473
|
+
const digits = unsigned.replace(".", "");
|
|
474
|
+
if (decimalIndex <= 0) {
|
|
475
|
+
return `${sign}0.${"0".repeat(-decimalIndex)}${digits}`;
|
|
476
|
+
}
|
|
477
|
+
if (decimalIndex >= digits.length) {
|
|
478
|
+
return `${sign}${digits}${"0".repeat(decimalIndex - digits.length)}`;
|
|
479
|
+
}
|
|
480
|
+
return `${sign}${digits.slice(0, decimalIndex)}.${digits.slice(decimalIndex)}`;
|
|
481
|
+
};
|
|
450
482
|
export let toString = (x, escaped, disableJsDataWarning = false) => {
|
|
451
483
|
if (x === null) {
|
|
452
484
|
return "nil";
|
|
@@ -468,7 +500,7 @@ export let toString = (x, escaped, disableJsDataWarning = false) => {
|
|
|
468
500
|
}
|
|
469
501
|
}
|
|
470
502
|
if (typeof x === "number") {
|
|
471
|
-
return x
|
|
503
|
+
return format_calcit_number(x);
|
|
472
504
|
}
|
|
473
505
|
if (typeof x === "boolean") {
|
|
474
506
|
return x.toString();
|
package/lib/calcit.procs.mjs
CHANGED
|
@@ -3,7 +3,7 @@ export const calcit_version = pkg.version;
|
|
|
3
3
|
export const calcit_package_json = pkg;
|
|
4
4
|
import { parse } from "@cirru/parser.ts";
|
|
5
5
|
import { writeCirruCode } from "@cirru/writer.ts";
|
|
6
|
-
import { CalcitSymbol, CalcitTag, CalcitRecur, castTag, newTag, refsRegistry, toString, getStringName, compareTagNames, _$n__$e_, hashFunction, } from "./calcit-data.mjs";
|
|
6
|
+
import { CalcitSymbol, CalcitTag, CalcitRecur, castTag, newTag, refsRegistry, toString, format_calcit_number, getStringName, compareTagNames, _$n__$e_, hashFunction, } from "./calcit-data.mjs";
|
|
7
7
|
import { CalcitRef, atom } from "./js-ref.mjs";
|
|
8
8
|
import { CalcitStructValue } from "./js-struct-value.mjs";
|
|
9
9
|
import { CalcitImpl } from "./js-impl.mjs";
|
|
@@ -946,7 +946,9 @@ export let remove_watch = (a, k) => {
|
|
|
946
946
|
}
|
|
947
947
|
throw new Error(`remove-watch failed: listener with key \`${k.value}\` not found`);
|
|
948
948
|
};
|
|
949
|
-
|
|
949
|
+
// Same eager range limit as native `MAX_RANGE_LEN` and WASM, 2^24 elements (#1852).
|
|
950
|
+
const MAX_RANGE_LENGTH = 2 ** 24;
|
|
951
|
+
const rangeTooLarge = () => new Error(`&list:range result is too large: more than ${MAX_RANGE_LENGTH} elements`);
|
|
950
952
|
export let range = (n, m, step = 1) => {
|
|
951
953
|
const base = m == null ? 0 : n;
|
|
952
954
|
const bound = m == null ? n : m;
|
|
@@ -964,11 +966,13 @@ export let range = (n, m, step = 1) => {
|
|
|
964
966
|
? Math.ceil(Math.abs(base) / Math.abs(step) + Math.abs(bound) / Math.abs(step))
|
|
965
967
|
: Math.ceil((bound - base) / step);
|
|
966
968
|
if (!Number.isFinite(estimatedLength) || estimatedLength > MAX_RANGE_LENGTH) {
|
|
967
|
-
throw
|
|
969
|
+
throw rangeTooLarge();
|
|
968
970
|
}
|
|
969
971
|
const result = [];
|
|
970
972
|
if (step > 0) {
|
|
971
973
|
for (let value = base; value < bound;) {
|
|
974
|
+
if (result.length >= MAX_RANGE_LENGTH)
|
|
975
|
+
throw rangeTooLarge();
|
|
972
976
|
result.push(value);
|
|
973
977
|
const next = value + step;
|
|
974
978
|
if (next === value) {
|
|
@@ -979,6 +983,8 @@ export let range = (n, m, step = 1) => {
|
|
|
979
983
|
}
|
|
980
984
|
else {
|
|
981
985
|
for (let value = base; value > bound;) {
|
|
986
|
+
if (result.length >= MAX_RANGE_LENGTH)
|
|
987
|
+
throw rangeTooLarge();
|
|
982
988
|
result.push(value);
|
|
983
989
|
const next = value + step;
|
|
984
990
|
if (next === value) {
|
|
@@ -1158,11 +1164,12 @@ export let _$n_list_$o_slice = (xs, from, to) => {
|
|
|
1158
1164
|
if (to == null) {
|
|
1159
1165
|
to = size;
|
|
1160
1166
|
}
|
|
1161
|
-
|
|
1162
|
-
|
|
1167
|
+
// Bounds are integers with 0 <= from <= to <= size, as in native (docs/data/number.md).
|
|
1168
|
+
if (!Number.isInteger(from) || !Number.isInteger(to) || from < 0 || from > to || to > size) {
|
|
1169
|
+
throw new Error(`&list:slice expected integer bounds within 0..${size}, but received: ${from} ${to}`);
|
|
1163
1170
|
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1171
|
+
if (from === to) {
|
|
1172
|
+
return new CalcitSliceList([]);
|
|
1166
1173
|
}
|
|
1167
1174
|
return xs.slice(from, to);
|
|
1168
1175
|
};
|
|
@@ -1360,13 +1367,19 @@ export let cos = (n) => {
|
|
|
1360
1367
|
return Math.cos(n);
|
|
1361
1368
|
};
|
|
1362
1369
|
export let pow = (n, m) => {
|
|
1370
|
+
// IEEE 754 pow, which Math.pow breaks: pow(1, y) is 1 for any y, pow(-1, ±Infinity) is 1.
|
|
1371
|
+
if (n === 1 || (n === -1 && (m === Infinity || m === -Infinity))) {
|
|
1372
|
+
return 1;
|
|
1373
|
+
}
|
|
1363
1374
|
return Math.pow(n, m);
|
|
1364
1375
|
};
|
|
1365
1376
|
export let ceil = (n) => {
|
|
1366
1377
|
return Math.ceil(n);
|
|
1367
1378
|
};
|
|
1368
1379
|
export let round = (n) => {
|
|
1369
|
-
|
|
1380
|
+
// Ties round away from zero; `Math.round` alone rounds them toward +Infinity.
|
|
1381
|
+
// Negating keeps `-0` for inputs such as -0.4.
|
|
1382
|
+
return n < 0 ? -Math.round(-n) : Math.round(n);
|
|
1370
1383
|
};
|
|
1371
1384
|
export let _$n_number_$o_fract = (n) => {
|
|
1372
1385
|
return n - Math.floor(n);
|
|
@@ -1519,6 +1532,10 @@ export let _$n_number_$o_format = (x, n) => {
|
|
|
1519
1532
|
return x.toFixed(n);
|
|
1520
1533
|
};
|
|
1521
1534
|
export let _$n_number_$o_display_by = (x, n) => {
|
|
1535
|
+
// a non-negative safe integer, printed exactly (docs/data/number.md)
|
|
1536
|
+
if (typeof x !== "number" || !Number.isSafeInteger(x) || x < 0) {
|
|
1537
|
+
throw new Error(`&number:display-by expected a non-negative safe integer, but received: ${x}`);
|
|
1538
|
+
}
|
|
1522
1539
|
switch (n) {
|
|
1523
1540
|
case 2:
|
|
1524
1541
|
return `0b${x.toString(2)}`;
|
|
@@ -1690,37 +1707,6 @@ export let quit_$x_ = (code) => {
|
|
|
1690
1707
|
throw new Error(`quit!(${code})`);
|
|
1691
1708
|
}
|
|
1692
1709
|
};
|
|
1693
|
-
let format_calcit_number = (x) => {
|
|
1694
|
-
// Match native f64 Display, which expands finite exponents into decimal notation.
|
|
1695
|
-
if (Object.is(x, -0)) {
|
|
1696
|
-
return "-0";
|
|
1697
|
-
}
|
|
1698
|
-
if (x === Infinity) {
|
|
1699
|
-
return "inf";
|
|
1700
|
-
}
|
|
1701
|
-
if (x === -Infinity) {
|
|
1702
|
-
return "-inf";
|
|
1703
|
-
}
|
|
1704
|
-
const text = x.toString();
|
|
1705
|
-
const exponentIndex = text.indexOf("e");
|
|
1706
|
-
if (exponentIndex < 0) {
|
|
1707
|
-
return text;
|
|
1708
|
-
}
|
|
1709
|
-
const mantissa = text.slice(0, exponentIndex);
|
|
1710
|
-
const exponent = Number(text.slice(exponentIndex + 1));
|
|
1711
|
-
const sign = mantissa.startsWith("-") ? "-" : "";
|
|
1712
|
-
const unsigned = sign ? mantissa.slice(1) : mantissa;
|
|
1713
|
-
const decimalPoint = unsigned.indexOf(".");
|
|
1714
|
-
const decimalIndex = (decimalPoint < 0 ? unsigned.length : decimalPoint) + exponent;
|
|
1715
|
-
const digits = unsigned.replace(".", "");
|
|
1716
|
-
if (decimalIndex <= 0) {
|
|
1717
|
-
return `${sign}0.${"0".repeat(-decimalIndex)}${digits}`;
|
|
1718
|
-
}
|
|
1719
|
-
if (decimalIndex >= digits.length) {
|
|
1720
|
-
return `${sign}${digits}${"0".repeat(decimalIndex - digits.length)}`;
|
|
1721
|
-
}
|
|
1722
|
-
return `${sign}${digits.slice(0, decimalIndex)}.${digits.slice(decimalIndex)}`;
|
|
1723
|
-
};
|
|
1724
1710
|
export let turn_string = (x) => {
|
|
1725
1711
|
if (x === null) {
|
|
1726
1712
|
return "";
|
|
@@ -2980,23 +2966,30 @@ export let _$n_map_$o_diff_triple = (a, b) => {
|
|
|
2980
2966
|
throw new Error("&map:diff-triple expected 2 maps");
|
|
2981
2967
|
}
|
|
2982
2968
|
};
|
|
2969
|
+
// Bitwise operands are integers within i32 (docs/data/number.md); JS would otherwise wrap or truncate them.
|
|
2970
|
+
let bit_operand = (name, x) => {
|
|
2971
|
+
if (typeof x !== "number" || !Number.isInteger(x) || x < -2147483648 || x > 2147483647) {
|
|
2972
|
+
throw new Error(`&math:${name} operand expected an integer within i32, but got: ${x}`);
|
|
2973
|
+
}
|
|
2974
|
+
return x;
|
|
2975
|
+
};
|
|
2983
2976
|
export let bit_shr = (base, step) => {
|
|
2984
|
-
return base >> step;
|
|
2977
|
+
return bit_operand("bit-shr", base) >> bit_operand("bit-shr", step);
|
|
2985
2978
|
};
|
|
2986
2979
|
export let bit_shl = (base, step) => {
|
|
2987
|
-
return base << step;
|
|
2980
|
+
return bit_operand("bit-shl", base) << bit_operand("bit-shl", step);
|
|
2988
2981
|
};
|
|
2989
2982
|
export let bit_and = (a, b) => {
|
|
2990
|
-
return a & b;
|
|
2983
|
+
return bit_operand("bit-and", a) & bit_operand("bit-and", b);
|
|
2991
2984
|
};
|
|
2992
2985
|
export let bit_or = (a, b) => {
|
|
2993
|
-
return a | b;
|
|
2986
|
+
return bit_operand("bit-or", a) | bit_operand("bit-or", b);
|
|
2994
2987
|
};
|
|
2995
2988
|
export let bit_xor = (a, b) => {
|
|
2996
|
-
return a ^ b;
|
|
2989
|
+
return bit_operand("bit-xor", a) ^ bit_operand("bit-xor", b);
|
|
2997
2990
|
};
|
|
2998
2991
|
export let bit_not = (a) => {
|
|
2999
|
-
return ~a;
|
|
2992
|
+
return ~bit_operand("bit-not", a);
|
|
3000
2993
|
};
|
|
3001
2994
|
export let _$n_list_$o_to_set = (xs) => {
|
|
3002
2995
|
var result = [];
|
|
@@ -3019,11 +3012,41 @@ export let _$n_list_$o_distinct = (xs) => {
|
|
|
3019
3012
|
}
|
|
3020
3013
|
return new CalcitSliceList(result);
|
|
3021
3014
|
};
|
|
3015
|
+
// Longest padded string, the V8 string length limit, so every backend fails at the same size.
|
|
3016
|
+
const MAX_PADDED_LEN = 536870888;
|
|
3017
|
+
// Padding for `&str:pad-left` / `&str:pad-right`, measured in Unicode scalars like `&str:count`
|
|
3018
|
+
// (not UTF-16 units, so astral characters are never split). NaN and negative lengths pad nothing,
|
|
3019
|
+
// and so does an empty pattern.
|
|
3020
|
+
const strPadding = (procName, s, size, pattern) => {
|
|
3021
|
+
if (size > MAX_PADDED_LEN) {
|
|
3022
|
+
throw new Error(`${procName} expected a finite length up to ${MAX_PADDED_LEN}, but received: ${format_calcit_number(size)}`);
|
|
3023
|
+
}
|
|
3024
|
+
if (!(size > 0) || pattern === "")
|
|
3025
|
+
return "";
|
|
3026
|
+
let missing = Math.floor(size);
|
|
3027
|
+
for (const _scalar of s) {
|
|
3028
|
+
missing -= 1;
|
|
3029
|
+
if (missing <= 0)
|
|
3030
|
+
return "";
|
|
3031
|
+
}
|
|
3032
|
+
let patternCount = 0;
|
|
3033
|
+
for (const _scalar of pattern)
|
|
3034
|
+
patternCount += 1;
|
|
3035
|
+
let padding = pattern.repeat(Math.floor(missing / patternCount));
|
|
3036
|
+
let rest = missing % patternCount;
|
|
3037
|
+
for (const scalar of pattern) {
|
|
3038
|
+
if (rest <= 0)
|
|
3039
|
+
break;
|
|
3040
|
+
padding += scalar;
|
|
3041
|
+
rest -= 1;
|
|
3042
|
+
}
|
|
3043
|
+
return padding;
|
|
3044
|
+
};
|
|
3022
3045
|
export let _$n_str_$o_pad_left = (s, size, pattern) => {
|
|
3023
|
-
return s
|
|
3046
|
+
return strPadding("&str:pad-left", s, size, pattern) + s;
|
|
3024
3047
|
};
|
|
3025
3048
|
export let _$n_str_$o_pad_right = (s, size, pattern) => {
|
|
3026
|
-
return s
|
|
3049
|
+
return s + strPadding("&str:pad-right", s, size, pattern);
|
|
3027
3050
|
};
|
|
3028
3051
|
export let _$n_get_os = () => {
|
|
3029
3052
|
return newTag("js-engine");
|
package/lib/package.json
CHANGED