@mojir/lits 2.2.4 → 2.3.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/README.md +1 -0
- package/dist/cli/cli.js +1264 -909
- package/dist/cli/src/Lits/Lits.d.ts +8 -2
- package/dist/cli/src/builtin/bindingNode.d.ts +2 -1
- package/dist/cli/src/builtin/interface.d.ts +3 -2
- package/dist/cli/src/builtin/modules/number-theory/sequences/index.d.ts +2 -1
- package/dist/cli/src/evaluator/functionExecutors.d.ts +2 -1
- package/dist/cli/src/evaluator/index.d.ts +3 -2
- package/dist/cli/src/evaluator/interface.d.ts +3 -2
- package/dist/cli/src/utils/maybePromise.d.ts +54 -0
- package/dist/full.esm.js +1 -1
- package/dist/full.esm.js.map +1 -1
- package/dist/full.js +1 -1
- package/dist/full.js.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lits.iife.js +1 -1
- package/dist/lits.iife.js.map +1 -1
- package/dist/modules/assert.esm.js +1 -1
- package/dist/modules/assert.esm.js.map +1 -1
- package/dist/modules/assert.js +1 -1
- package/dist/modules/assert.js.map +1 -1
- package/dist/modules/collection.esm.js +1 -1
- package/dist/modules/collection.esm.js.map +1 -1
- package/dist/modules/collection.js +1 -1
- package/dist/modules/collection.js.map +1 -1
- package/dist/modules/grid.esm.js +1 -1
- package/dist/modules/grid.esm.js.map +1 -1
- package/dist/modules/grid.js +1 -1
- package/dist/modules/grid.js.map +1 -1
- package/dist/modules/number-theory.esm.js +1 -1
- package/dist/modules/number-theory.esm.js.map +1 -1
- package/dist/modules/number-theory.js +1 -1
- package/dist/modules/number-theory.js.map +1 -1
- package/dist/modules/sequence.esm.js +1 -1
- package/dist/modules/sequence.esm.js.map +1 -1
- package/dist/modules/sequence.js +1 -1
- package/dist/modules/sequence.js.map +1 -1
- package/dist/modules/src/Lits/Lits.d.ts +8 -2
- package/dist/modules/src/builtin/bindingNode.d.ts +2 -1
- package/dist/modules/src/builtin/interface.d.ts +3 -2
- package/dist/modules/src/builtin/modules/number-theory/sequences/index.d.ts +2 -1
- package/dist/modules/src/evaluator/functionExecutors.d.ts +2 -1
- package/dist/modules/src/evaluator/index.d.ts +3 -2
- package/dist/modules/src/evaluator/interface.d.ts +3 -2
- package/dist/modules/src/utils/maybePromise.d.ts +54 -0
- package/dist/modules/vector.esm.js +1 -1
- package/dist/modules/vector.esm.js.map +1 -1
- package/dist/modules/vector.js +1 -1
- package/dist/modules/vector.js.map +1 -1
- package/dist/src/Lits/Lits.d.ts +8 -2
- package/dist/src/builtin/bindingNode.d.ts +2 -1
- package/dist/src/builtin/interface.d.ts +3 -2
- package/dist/src/builtin/modules/number-theory/sequences/index.d.ts +2 -1
- package/dist/src/evaluator/functionExecutors.d.ts +2 -1
- package/dist/src/evaluator/index.d.ts +3 -2
- package/dist/src/evaluator/interface.d.ts +3 -2
- package/dist/src/utils/maybePromise.d.ts +54 -0
- package/dist/testFramework.esm.js +1 -1
- package/dist/testFramework.esm.js.map +1 -1
- package/dist/testFramework.js +1 -1
- package/dist/testFramework.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ var readline = require('node:readline');
|
|
|
7
7
|
var os = require('node:os');
|
|
8
8
|
var process$1 = require('node:process');
|
|
9
9
|
|
|
10
|
-
var version = "2.
|
|
10
|
+
var version = "2.3.0";
|
|
11
11
|
|
|
12
12
|
function getCodeMarker(sourceCodeInfo) {
|
|
13
13
|
if (!sourceCodeInfo.position || !sourceCodeInfo.code)
|
|
@@ -858,6 +858,200 @@ function assertCharArray(value, sourceCodeInfo) {
|
|
|
858
858
|
throw getAssertionError('array of strings', value, sourceCodeInfo);
|
|
859
859
|
}
|
|
860
860
|
|
|
861
|
+
/**
|
|
862
|
+
* MaybePromise utilities for transparent async support.
|
|
863
|
+
*
|
|
864
|
+
* The sync path stays zero-overhead — when no async JS functions are involved,
|
|
865
|
+
* everything runs synchronously with only `instanceof Promise` checks as overhead.
|
|
866
|
+
* When an async value is detected, the evaluation chain switches to Promise-based
|
|
867
|
+
* execution for the remainder.
|
|
868
|
+
*/
|
|
869
|
+
/**
|
|
870
|
+
* Chain a value that might be a Promise. If the value is sync, calls fn synchronously.
|
|
871
|
+
* If it's a Promise, chains with .then().
|
|
872
|
+
*/
|
|
873
|
+
function chain(value, fn) {
|
|
874
|
+
if (value instanceof Promise) {
|
|
875
|
+
return value.then(fn);
|
|
876
|
+
}
|
|
877
|
+
return fn(value);
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Like Array.map but handles MaybePromise callbacks sequentially.
|
|
881
|
+
* In the sync case, runs as a simple loop. Switches to async only when needed.
|
|
882
|
+
*/
|
|
883
|
+
function mapSequential(arr, fn) {
|
|
884
|
+
const results = [];
|
|
885
|
+
for (let i = 0; i < arr.length; i++) {
|
|
886
|
+
const result = fn(arr[i], i);
|
|
887
|
+
if (result instanceof Promise) {
|
|
888
|
+
return chainRemainingMap(result, results, arr, fn, i);
|
|
889
|
+
}
|
|
890
|
+
results.push(result);
|
|
891
|
+
}
|
|
892
|
+
return results;
|
|
893
|
+
}
|
|
894
|
+
async function chainRemainingMap(currentPromise, results, arr, fn, startIndex) {
|
|
895
|
+
results.push(await currentPromise);
|
|
896
|
+
for (let i = startIndex + 1; i < arr.length; i++) {
|
|
897
|
+
results.push(await fn(arr[i], i));
|
|
898
|
+
}
|
|
899
|
+
return results;
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Like Array.reduce but handles MaybePromise callbacks sequentially.
|
|
903
|
+
* In the sync case, runs as a simple loop. Switches to async only when needed.
|
|
904
|
+
*/
|
|
905
|
+
function reduceSequential(arr, fn, initial) {
|
|
906
|
+
let result = initial;
|
|
907
|
+
for (let i = 0; i < arr.length; i++) {
|
|
908
|
+
const next = fn(result, arr[i], i);
|
|
909
|
+
if (next instanceof Promise) {
|
|
910
|
+
return chainRemainingReduce(next, arr, fn, i);
|
|
911
|
+
}
|
|
912
|
+
result = next;
|
|
913
|
+
}
|
|
914
|
+
return result;
|
|
915
|
+
}
|
|
916
|
+
async function chainRemainingReduce(currentPromise, arr, fn, startIndex) {
|
|
917
|
+
let result = await currentPromise;
|
|
918
|
+
for (let i = startIndex + 1; i < arr.length; i++) {
|
|
919
|
+
result = await fn(result, arr[i], i);
|
|
920
|
+
}
|
|
921
|
+
return result;
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Like Array.forEach but handles MaybePromise callbacks sequentially.
|
|
925
|
+
* In the sync case, runs as a simple loop. Switches to async only when needed.
|
|
926
|
+
*/
|
|
927
|
+
function forEachSequential(arr, fn) {
|
|
928
|
+
for (let i = 0; i < arr.length; i++) {
|
|
929
|
+
const result = fn(arr[i], i);
|
|
930
|
+
if (result instanceof Promise) {
|
|
931
|
+
return chainRemainingForEach(result, arr, fn, i);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
async function chainRemainingForEach(currentPromise, arr, fn, startIndex) {
|
|
936
|
+
await currentPromise;
|
|
937
|
+
for (let i = startIndex + 1; i < arr.length; i++) {
|
|
938
|
+
await fn(arr[i], i);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Try/catch that handles MaybePromise values correctly.
|
|
943
|
+
* If tryFn returns a Promise, catches both sync throws and Promise rejections.
|
|
944
|
+
*/
|
|
945
|
+
function tryCatch(tryFn, catchFn) {
|
|
946
|
+
try {
|
|
947
|
+
const result = tryFn();
|
|
948
|
+
if (result instanceof Promise) {
|
|
949
|
+
return result.catch(catchFn);
|
|
950
|
+
}
|
|
951
|
+
return result;
|
|
952
|
+
}
|
|
953
|
+
catch (error) {
|
|
954
|
+
return catchFn(error);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Like Array.some but handles MaybePromise callbacks sequentially.
|
|
959
|
+
* Returns the first truthy MaybePromise result, or false.
|
|
960
|
+
*/
|
|
961
|
+
function someSequential(arr, fn) {
|
|
962
|
+
for (let i = 0; i < arr.length; i++) {
|
|
963
|
+
const result = fn(arr[i], i);
|
|
964
|
+
if (result instanceof Promise) {
|
|
965
|
+
return chainRemainingSome(result, arr, fn, i);
|
|
966
|
+
}
|
|
967
|
+
if (result)
|
|
968
|
+
return true;
|
|
969
|
+
}
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
async function chainRemainingSome(currentPromise, arr, fn, startIndex) {
|
|
973
|
+
if (await currentPromise)
|
|
974
|
+
return true;
|
|
975
|
+
for (let i = startIndex + 1; i < arr.length; i++) {
|
|
976
|
+
if (await fn(arr[i], i))
|
|
977
|
+
return true;
|
|
978
|
+
}
|
|
979
|
+
return false;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Like Array.every but handles MaybePromise callbacks sequentially.
|
|
983
|
+
* Returns false as soon as a falsy result is found.
|
|
984
|
+
*/
|
|
985
|
+
function everySequential(arr, fn) {
|
|
986
|
+
for (let i = 0; i < arr.length; i++) {
|
|
987
|
+
const result = fn(arr[i], i);
|
|
988
|
+
if (result instanceof Promise) {
|
|
989
|
+
return chainRemainingEvery(result, arr, fn, i);
|
|
990
|
+
}
|
|
991
|
+
if (!result)
|
|
992
|
+
return false;
|
|
993
|
+
}
|
|
994
|
+
return true;
|
|
995
|
+
}
|
|
996
|
+
async function chainRemainingEvery(currentPromise, arr, fn, startIndex) {
|
|
997
|
+
if (!await currentPromise)
|
|
998
|
+
return false;
|
|
999
|
+
for (let i = startIndex + 1; i < arr.length; i++) {
|
|
1000
|
+
if (!await fn(arr[i], i))
|
|
1001
|
+
return false;
|
|
1002
|
+
}
|
|
1003
|
+
return true;
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Like Array.filter but handles MaybePromise callbacks sequentially.
|
|
1007
|
+
* Returns the filtered array.
|
|
1008
|
+
*/
|
|
1009
|
+
function filterSequential(arr, fn) {
|
|
1010
|
+
const results = [];
|
|
1011
|
+
for (let i = 0; i < arr.length; i++) {
|
|
1012
|
+
const result = fn(arr[i], i);
|
|
1013
|
+
if (result instanceof Promise) {
|
|
1014
|
+
return chainRemainingFilter(result, results, arr, fn, i);
|
|
1015
|
+
}
|
|
1016
|
+
if (result)
|
|
1017
|
+
results.push(arr[i]);
|
|
1018
|
+
}
|
|
1019
|
+
return results;
|
|
1020
|
+
}
|
|
1021
|
+
async function chainRemainingFilter(currentPromise, results, arr, fn, startIndex) {
|
|
1022
|
+
if (await currentPromise)
|
|
1023
|
+
results.push(arr[startIndex]);
|
|
1024
|
+
for (let i = startIndex + 1; i < arr.length; i++) {
|
|
1025
|
+
if (await fn(arr[i], i))
|
|
1026
|
+
results.push(arr[i]);
|
|
1027
|
+
}
|
|
1028
|
+
return results;
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* Like Array.findIndex but handles MaybePromise callbacks sequentially.
|
|
1032
|
+
* Returns -1 if no element matches.
|
|
1033
|
+
*/
|
|
1034
|
+
function findIndexSequential(arr, fn) {
|
|
1035
|
+
for (let i = 0; i < arr.length; i++) {
|
|
1036
|
+
const result = fn(arr[i], i);
|
|
1037
|
+
if (result instanceof Promise) {
|
|
1038
|
+
return chainRemainingFindIndex(result, arr, fn, i);
|
|
1039
|
+
}
|
|
1040
|
+
if (result)
|
|
1041
|
+
return i;
|
|
1042
|
+
}
|
|
1043
|
+
return -1;
|
|
1044
|
+
}
|
|
1045
|
+
async function chainRemainingFindIndex(currentPromise, arr, fn, startIndex) {
|
|
1046
|
+
if (await currentPromise)
|
|
1047
|
+
return startIndex;
|
|
1048
|
+
for (let i = startIndex + 1; i < arr.length; i++) {
|
|
1049
|
+
if (await fn(arr[i], i))
|
|
1050
|
+
return i;
|
|
1051
|
+
}
|
|
1052
|
+
return -1;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
861
1055
|
function mapObjects({ colls, contextStack, executeFunction, fn, sourceCodeInfo, }) {
|
|
862
1056
|
assertObj(colls[0], sourceCodeInfo);
|
|
863
1057
|
const keys = Object.keys(colls[0]);
|
|
@@ -877,10 +1071,13 @@ function mapObjects({ colls, contextStack, executeFunction, fn, sourceCodeInfo,
|
|
|
877
1071
|
params[key].push(value);
|
|
878
1072
|
});
|
|
879
1073
|
});
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
return
|
|
883
|
-
|
|
1074
|
+
const initialObj = {};
|
|
1075
|
+
return reduceSequential(keys, (result, key) => {
|
|
1076
|
+
return chain(executeFunction(fn, params[key], contextStack, sourceCodeInfo), (value) => {
|
|
1077
|
+
result[key] = value;
|
|
1078
|
+
return result;
|
|
1079
|
+
});
|
|
1080
|
+
}, initialObj);
|
|
884
1081
|
}
|
|
885
1082
|
function get$1(coll, key) {
|
|
886
1083
|
if (isObj(coll)) {
|
|
@@ -919,21 +1116,33 @@ const collectionNormalExpression = {
|
|
|
919
1116
|
assertColl(coll, sourceCodeInfo);
|
|
920
1117
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
921
1118
|
if (Array.isArray(coll)) {
|
|
922
|
-
|
|
923
|
-
|
|
1119
|
+
return reduceSequential(coll, (result, elem) => {
|
|
1120
|
+
return chain(executeFunction(fn, [elem], contextStack, sourceCodeInfo), (keep) => {
|
|
1121
|
+
if (keep)
|
|
1122
|
+
result.push(elem);
|
|
1123
|
+
return result;
|
|
1124
|
+
});
|
|
1125
|
+
}, []);
|
|
924
1126
|
}
|
|
925
1127
|
if (isString(coll)) {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1128
|
+
const chars = coll.split('');
|
|
1129
|
+
return chain(reduceSequential(chars, (result, elem) => {
|
|
1130
|
+
return chain(executeFunction(fn, [elem], contextStack, sourceCodeInfo), (keep) => {
|
|
1131
|
+
if (keep)
|
|
1132
|
+
result.push(elem);
|
|
1133
|
+
return result;
|
|
1134
|
+
});
|
|
1135
|
+
}, []), filtered => filtered.join(''));
|
|
1136
|
+
}
|
|
1137
|
+
const entries = Object.entries(coll);
|
|
1138
|
+
const initialObj = {};
|
|
1139
|
+
return reduceSequential(entries, (result, [key, value]) => {
|
|
1140
|
+
return chain(executeFunction(fn, [value], contextStack, sourceCodeInfo), (keep) => {
|
|
1141
|
+
if (keep)
|
|
1142
|
+
result[key] = value;
|
|
1143
|
+
return result;
|
|
1144
|
+
});
|
|
1145
|
+
}, initialObj);
|
|
937
1146
|
},
|
|
938
1147
|
arity: toFixedArity(2),
|
|
939
1148
|
docs: {
|
|
@@ -996,12 +1205,14 @@ filter(
|
|
|
996
1205
|
for (let i = 0; i < len; i++) {
|
|
997
1206
|
paramArray.push(seqs.map(seq => seq[i]));
|
|
998
1207
|
}
|
|
999
|
-
const mapped = paramArray
|
|
1208
|
+
const mapped = mapSequential(paramArray, p => executeFunction(fn, p, contextStack, sourceCodeInfo));
|
|
1000
1209
|
if (!isStr) {
|
|
1001
1210
|
return mapped;
|
|
1002
1211
|
}
|
|
1003
|
-
mapped
|
|
1004
|
-
|
|
1212
|
+
return chain(mapped, (resolvedMapped) => {
|
|
1213
|
+
resolvedMapped.forEach(char => assertString(char, sourceCodeInfo));
|
|
1214
|
+
return resolvedMapped.join('');
|
|
1215
|
+
});
|
|
1005
1216
|
},
|
|
1006
1217
|
arity: { min: 2 },
|
|
1007
1218
|
docs: {
|
|
@@ -1036,21 +1247,21 @@ filter(
|
|
|
1036
1247
|
assertString(initial, sourceCodeInfo);
|
|
1037
1248
|
if (coll.length === 0)
|
|
1038
1249
|
return initial;
|
|
1039
|
-
return coll.split('')
|
|
1250
|
+
return reduceSequential(coll.split(''), (result, elem) => {
|
|
1040
1251
|
return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo);
|
|
1041
1252
|
}, initial);
|
|
1042
1253
|
}
|
|
1043
1254
|
else if (Array.isArray(coll)) {
|
|
1044
1255
|
if (coll.length === 0)
|
|
1045
1256
|
return initial;
|
|
1046
|
-
return coll
|
|
1257
|
+
return reduceSequential(coll, (result, elem) => {
|
|
1047
1258
|
return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo);
|
|
1048
1259
|
}, initial);
|
|
1049
1260
|
}
|
|
1050
1261
|
else {
|
|
1051
1262
|
if (Object.keys(coll).length === 0)
|
|
1052
1263
|
return initial;
|
|
1053
|
-
return Object.entries(coll)
|
|
1264
|
+
return reduceSequential(Object.entries(coll), (result, [, elem]) => {
|
|
1054
1265
|
return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo);
|
|
1055
1266
|
}, initial);
|
|
1056
1267
|
}
|
|
@@ -1490,7 +1701,7 @@ flatten([
|
|
|
1490
1701
|
evaluate: ([arr, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
1491
1702
|
assertArray(arr, sourceCodeInfo);
|
|
1492
1703
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
1493
|
-
return arr
|
|
1704
|
+
return chain(mapSequential(arr, elem => executeFunction(fn, [elem], contextStack, sourceCodeInfo)), mapped => mapped.flat(1));
|
|
1494
1705
|
},
|
|
1495
1706
|
arity: toFixedArity(2),
|
|
1496
1707
|
docs: {
|
|
@@ -1527,13 +1738,11 @@ mapcat(
|
|
|
1527
1738
|
assertArray(arr, sourceCodeInfo);
|
|
1528
1739
|
assertNumber(windowSize, sourceCodeInfo, { integer: true, lte: arr.length });
|
|
1529
1740
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
1530
|
-
const
|
|
1741
|
+
const windows = [];
|
|
1531
1742
|
for (let i = 0; i <= arr.length - windowSize; i++) {
|
|
1532
|
-
|
|
1533
|
-
const value = executeFunction(fn, [window], contextStack, sourceCodeInfo);
|
|
1534
|
-
result.push(value);
|
|
1743
|
+
windows.push(arr.slice(i, i + windowSize));
|
|
1535
1744
|
}
|
|
1536
|
-
return
|
|
1745
|
+
return mapSequential(windows, window => executeFunction(fn, [window], contextStack, sourceCodeInfo));
|
|
1537
1746
|
},
|
|
1538
1747
|
arity: toFixedArity(3),
|
|
1539
1748
|
docs: {
|
|
@@ -1558,12 +1767,11 @@ mapcat(
|
|
|
1558
1767
|
evaluate: ([arr, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
1559
1768
|
assertArray(arr, sourceCodeInfo);
|
|
1560
1769
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
1561
|
-
const
|
|
1770
|
+
const subArrays = [];
|
|
1562
1771
|
for (let i = 0; i < arr.length; i += 1) {
|
|
1563
|
-
|
|
1564
|
-
result.push(executeFunction(fn, [subArr], contextStack, sourceCodeInfo));
|
|
1772
|
+
subArrays.push(arr.slice(0, i + 1));
|
|
1565
1773
|
}
|
|
1566
|
-
return
|
|
1774
|
+
return mapSequential(subArrays, subArr => executeFunction(fn, [subArr], contextStack, sourceCodeInfo));
|
|
1567
1775
|
},
|
|
1568
1776
|
arity: toFixedArity(2),
|
|
1569
1777
|
docs: {
|
|
@@ -1938,9 +2146,14 @@ For string $seq returns all but the first characters in $seq.`,
|
|
|
1938
2146
|
assertSeq(seq, sourceCodeInfo);
|
|
1939
2147
|
if (seq.length === 0)
|
|
1940
2148
|
return null;
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
2149
|
+
const items = typeof seq === 'string' ? seq.split('') : seq;
|
|
2150
|
+
return reduceSequential(items, (found, elem) => {
|
|
2151
|
+
if (found !== null)
|
|
2152
|
+
return found;
|
|
2153
|
+
return chain(executeFunction(fn, [elem], contextStack, sourceCodeInfo), (result) => {
|
|
2154
|
+
return result ? toAny(elem) : null;
|
|
2155
|
+
});
|
|
2156
|
+
}, null);
|
|
1944
2157
|
},
|
|
1945
2158
|
arity: toFixedArity(2),
|
|
1946
2159
|
docs: {
|
|
@@ -1985,7 +2198,7 @@ some(
|
|
|
1985
2198
|
},
|
|
1986
2199
|
},
|
|
1987
2200
|
'sort': {
|
|
1988
|
-
evaluate: (params, sourceCodeInfo,
|
|
2201
|
+
evaluate: (params, sourceCodeInfo, _contextStack, { executeFunction: _executeFunction }) => {
|
|
1989
2202
|
const [seq] = params;
|
|
1990
2203
|
const defaultComparer = params.length === 1;
|
|
1991
2204
|
const comparer = defaultComparer ? null : params[1];
|
|
@@ -1997,8 +2210,12 @@ some(
|
|
|
1997
2210
|
}
|
|
1998
2211
|
else {
|
|
1999
2212
|
assertFunctionLike(comparer, sourceCodeInfo);
|
|
2213
|
+
// Note: sort comparator must be synchronous — async comparators would need a different approach
|
|
2000
2214
|
result.sort((a, b) => {
|
|
2001
|
-
const compareValue =
|
|
2215
|
+
const compareValue = _executeFunction(comparer, [a, b], _contextStack, sourceCodeInfo);
|
|
2216
|
+
if (compareValue instanceof Promise) {
|
|
2217
|
+
throw new TypeError('Async functions cannot be used as sort comparators');
|
|
2218
|
+
}
|
|
2002
2219
|
assertNumber(compareValue, sourceCodeInfo, { finite: true });
|
|
2003
2220
|
return compareValue;
|
|
2004
2221
|
});
|
|
@@ -2016,7 +2233,11 @@ some(
|
|
|
2016
2233
|
else {
|
|
2017
2234
|
result.sort((a, b) => {
|
|
2018
2235
|
assertFunctionLike(comparer, sourceCodeInfo);
|
|
2019
|
-
|
|
2236
|
+
// Note: sort comparator must be synchronous
|
|
2237
|
+
const compareValue = _executeFunction(comparer, [a, b], _contextStack, sourceCodeInfo);
|
|
2238
|
+
if (compareValue instanceof Promise) {
|
|
2239
|
+
throw new TypeError('Async functions cannot be used as sort comparators');
|
|
2240
|
+
}
|
|
2020
2241
|
assertNumber(compareValue, sourceCodeInfo, { finite: true });
|
|
2021
2242
|
return compareValue;
|
|
2022
2243
|
});
|
|
@@ -3611,17 +3832,23 @@ If no arguments are provided \`null\` is returned.`,
|
|
|
3611
3832
|
const rest = params.slice(1, -1);
|
|
3612
3833
|
assertObj(first, sourceCodeInfo);
|
|
3613
3834
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
3614
|
-
return rest
|
|
3835
|
+
return reduceSequential(rest, (result, obj) => {
|
|
3615
3836
|
assertObj(obj, sourceCodeInfo);
|
|
3616
|
-
Object.entries(obj)
|
|
3837
|
+
const entries = Object.entries(obj);
|
|
3838
|
+
return chain(reduceSequential(entries, (res, entry) => {
|
|
3617
3839
|
const key = asString(entry[0], sourceCodeInfo);
|
|
3618
3840
|
const val = toAny(entry[1]);
|
|
3619
|
-
if (collHasKey(
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3841
|
+
if (collHasKey(res, key)) {
|
|
3842
|
+
return chain(executeFunction(fn, [res[key], val], contextStack, sourceCodeInfo), (merged) => {
|
|
3843
|
+
res[key] = merged;
|
|
3844
|
+
return res;
|
|
3845
|
+
});
|
|
3846
|
+
}
|
|
3847
|
+
else {
|
|
3848
|
+
res[key] = val;
|
|
3849
|
+
return res;
|
|
3850
|
+
}
|
|
3851
|
+
}, result), r => r);
|
|
3625
3852
|
}, { ...first });
|
|
3626
3853
|
},
|
|
3627
3854
|
arity: { min: 2 },
|
|
@@ -5043,13 +5270,11 @@ const andSpecialExpression = {
|
|
|
5043
5270
|
arity: {},
|
|
5044
5271
|
docs: docs$f,
|
|
5045
5272
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
}
|
|
5052
|
-
return value;
|
|
5273
|
+
return reduceSequential(node[1][1], (acc, param) => {
|
|
5274
|
+
if (!acc)
|
|
5275
|
+
return acc;
|
|
5276
|
+
return evaluateNode(param, contextStack);
|
|
5277
|
+
}, true);
|
|
5053
5278
|
},
|
|
5054
5279
|
evaluateAsNormalExpression: (params, sourceCodeInfo) => {
|
|
5055
5280
|
let value = true;
|
|
@@ -5095,13 +5320,17 @@ const condSpecialExpression = {
|
|
|
5095
5320
|
docs: docs$e,
|
|
5096
5321
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5097
5322
|
const params = node[1][1];
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
return evaluateNode(
|
|
5323
|
+
function processCase(index) {
|
|
5324
|
+
if (index >= params.length)
|
|
5325
|
+
return null;
|
|
5326
|
+
const [test, form] = params[index];
|
|
5327
|
+
return chain(evaluateNode(test, contextStack), (value) => {
|
|
5328
|
+
if (!value)
|
|
5329
|
+
return processCase(index + 1);
|
|
5330
|
+
return evaluateNode(form, contextStack);
|
|
5331
|
+
});
|
|
5103
5332
|
}
|
|
5104
|
-
return
|
|
5333
|
+
return processCase(0);
|
|
5105
5334
|
},
|
|
5106
5335
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => getUndefinedSymbols(node[1][1].flat(), contextStack, builtin, evaluateNode),
|
|
5107
5336
|
};
|
|
@@ -5139,14 +5368,20 @@ const switchSpecialExpression = {
|
|
|
5139
5368
|
docs: docs$d,
|
|
5140
5369
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5141
5370
|
const [, switchValueNode, cases] = node[1];
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5371
|
+
return chain(evaluateNode(switchValueNode, contextStack), (switchValue) => {
|
|
5372
|
+
function processCase(index) {
|
|
5373
|
+
if (index >= cases.length)
|
|
5374
|
+
return null;
|
|
5375
|
+
const [test, form] = cases[index];
|
|
5376
|
+
return chain(evaluateNode(test, contextStack), (value) => {
|
|
5377
|
+
if (value === switchValue) {
|
|
5378
|
+
return evaluateNode(form, contextStack);
|
|
5379
|
+
}
|
|
5380
|
+
return processCase(index + 1);
|
|
5381
|
+
});
|
|
5147
5382
|
}
|
|
5148
|
-
|
|
5149
|
-
|
|
5383
|
+
return processCase(0);
|
|
5384
|
+
});
|
|
5150
5385
|
},
|
|
5151
5386
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => getUndefinedSymbols([node[1][1], ...node[1][2].flat()], contextStack, builtin, evaluateNode),
|
|
5152
5387
|
};
|
|
@@ -5226,37 +5461,47 @@ function walkDefaults(bindingTarget, onDefault) {
|
|
|
5226
5461
|
function evaluateBindingNodeValues(target, value, evaluate) {
|
|
5227
5462
|
const sourceCodeInfo = target[2];
|
|
5228
5463
|
const record = {};
|
|
5229
|
-
createRecord(target, value, evaluate, sourceCodeInfo, record);
|
|
5230
|
-
return record;
|
|
5464
|
+
return chain(createRecord(target, value, evaluate, sourceCodeInfo, record), () => record);
|
|
5231
5465
|
}
|
|
5232
5466
|
function createRecord(bindingTarget, value, evaluate, sourceCodeInfo, record) {
|
|
5233
5467
|
if (bindingTarget[0] === bindingTargetTypes.object) {
|
|
5234
5468
|
assertUnknownRecord(value, sourceCodeInfo);
|
|
5235
5469
|
const capturedKeys = new Set();
|
|
5236
5470
|
let restElement;
|
|
5237
|
-
Object.entries(bindingTarget[1][0])
|
|
5471
|
+
const entries = Object.entries(bindingTarget[1][0]);
|
|
5472
|
+
return chain(forEachSequential(entries, ([key, element]) => {
|
|
5238
5473
|
if (element[0] === bindingTargetTypes.rest) {
|
|
5239
5474
|
restElement = element;
|
|
5240
5475
|
return;
|
|
5241
5476
|
}
|
|
5242
5477
|
capturedKeys.add(key);
|
|
5243
|
-
const
|
|
5244
|
-
|
|
5245
|
-
|
|
5478
|
+
const existingVal = value[key];
|
|
5479
|
+
const maybeVal = existingVal !== undefined
|
|
5480
|
+
? existingVal
|
|
5481
|
+
: element[1][1]
|
|
5482
|
+
? evaluate(element[1][1])
|
|
5483
|
+
: null;
|
|
5484
|
+
return chain(maybeVal, (resolvedVal) => {
|
|
5485
|
+
const val = resolvedVal ?? null;
|
|
5486
|
+
assertAny(val, sourceCodeInfo);
|
|
5487
|
+
return createRecord(element, val, evaluate, sourceCodeInfo, record);
|
|
5488
|
+
});
|
|
5489
|
+
}), () => {
|
|
5490
|
+
if (restElement) {
|
|
5491
|
+
const restValues = Object.entries(value)
|
|
5492
|
+
.filter(([key]) => !capturedKeys.has(key))
|
|
5493
|
+
.reduce((acc, [key, val]) => {
|
|
5494
|
+
acc[key] = asAny(val);
|
|
5495
|
+
return acc;
|
|
5496
|
+
}, {});
|
|
5497
|
+
record[restElement[1][0]] = restValues;
|
|
5498
|
+
}
|
|
5246
5499
|
});
|
|
5247
|
-
if (restElement) {
|
|
5248
|
-
const restValues = Object.entries(value)
|
|
5249
|
-
.filter(([key]) => !capturedKeys.has(key))
|
|
5250
|
-
.reduce((acc, [key, val]) => {
|
|
5251
|
-
acc[key] = asAny(val);
|
|
5252
|
-
return acc;
|
|
5253
|
-
}, {});
|
|
5254
|
-
record[restElement[1][0]] = restValues;
|
|
5255
|
-
}
|
|
5256
5500
|
}
|
|
5257
5501
|
else if (bindingTarget[0] === bindingTargetTypes.array) {
|
|
5258
5502
|
let restIndex = null;
|
|
5259
5503
|
assertArray(value, sourceCodeInfo);
|
|
5504
|
+
const elements = [];
|
|
5260
5505
|
for (let index = 0; index < bindingTarget[1][0].length; index += 1) {
|
|
5261
5506
|
const element = bindingTarget[1][0][index] ?? null;
|
|
5262
5507
|
if (element === null) {
|
|
@@ -5266,15 +5511,27 @@ function createRecord(bindingTarget, value, evaluate, sourceCodeInfo, record) {
|
|
|
5266
5511
|
restIndex = index;
|
|
5267
5512
|
break;
|
|
5268
5513
|
}
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5514
|
+
elements.push({ element, index });
|
|
5515
|
+
}
|
|
5516
|
+
return chain(forEachSequential(elements, ({ element, index }) => {
|
|
5517
|
+
const existingVal = value[index];
|
|
5518
|
+
const maybeVal = existingVal !== undefined
|
|
5519
|
+
? existingVal
|
|
5520
|
+
: element[1][1]
|
|
5521
|
+
? evaluate(element[1][1])
|
|
5522
|
+
: null;
|
|
5523
|
+
return chain(maybeVal, (resolvedVal) => {
|
|
5524
|
+
const val = resolvedVal ?? null;
|
|
5525
|
+
assertAny(val, sourceCodeInfo);
|
|
5526
|
+
return createRecord(element, val, evaluate, sourceCodeInfo, record);
|
|
5527
|
+
});
|
|
5528
|
+
}), () => {
|
|
5529
|
+
if (restIndex !== null) {
|
|
5530
|
+
const restValues = value.slice(restIndex);
|
|
5531
|
+
const restElement = bindingTarget[1][0][restIndex];
|
|
5532
|
+
record[restElement[1][0]] = restValues;
|
|
5533
|
+
}
|
|
5534
|
+
});
|
|
5278
5535
|
}
|
|
5279
5536
|
else if (bindingTarget[0] === bindingTargetTypes.rest) {
|
|
5280
5537
|
record[bindingTarget[1][0]] = asAny(value);
|
|
@@ -5322,10 +5579,12 @@ const defSpecialExpression = {
|
|
|
5322
5579
|
const bindingNode = node[1][1];
|
|
5323
5580
|
const target = bindingNode[1][0];
|
|
5324
5581
|
const value = bindingNode[1][1];
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5582
|
+
return chain(evaluateNode(value, contextStack), (bindingValue) => {
|
|
5583
|
+
return chain(evaluateBindingNodeValues(target, bindingValue, Node => evaluateNode(Node, contextStack)), (values) => {
|
|
5584
|
+
contextStack.exportValues(values, target[2]);
|
|
5585
|
+
return bindingValue;
|
|
5586
|
+
});
|
|
5587
|
+
});
|
|
5329
5588
|
},
|
|
5330
5589
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => {
|
|
5331
5590
|
const bindingNode = node[1][1];
|
|
@@ -5362,10 +5621,7 @@ const doSpecialExpression = {
|
|
|
5362
5621
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5363
5622
|
const newContext = {};
|
|
5364
5623
|
const newContextStack = contextStack.create(newContext);
|
|
5365
|
-
|
|
5366
|
-
for (const form of node[1][1])
|
|
5367
|
-
result = evaluateNode(form, newContextStack);
|
|
5368
|
-
return result;
|
|
5624
|
+
return reduceSequential(node[1][1], (_acc, form) => evaluateNode(form, newContextStack), null);
|
|
5369
5625
|
},
|
|
5370
5626
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => {
|
|
5371
5627
|
return getUndefinedSymbols(node[1][1], contextStack.create({}), builtin, evaluateNode);
|
|
@@ -5460,13 +5716,15 @@ const ifSpecialExpression = {
|
|
|
5460
5716
|
docs: docs$a,
|
|
5461
5717
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5462
5718
|
const [conditionNode, trueNode, falseNode] = node[1][1];
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5719
|
+
return chain(evaluateNode(conditionNode, contextStack), (condition) => {
|
|
5720
|
+
if (condition) {
|
|
5721
|
+
return evaluateNode(trueNode, contextStack);
|
|
5722
|
+
}
|
|
5723
|
+
else if (falseNode) {
|
|
5724
|
+
return evaluateNode(falseNode, contextStack);
|
|
5725
|
+
}
|
|
5726
|
+
return null;
|
|
5727
|
+
});
|
|
5470
5728
|
},
|
|
5471
5729
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => getUndefinedSymbols(node[1][1].filter(n => !!n), contextStack, builtin, evaluateNode),
|
|
5472
5730
|
};
|
|
@@ -5497,13 +5755,15 @@ const unlessSpecialExpression = {
|
|
|
5497
5755
|
docs: docs$9,
|
|
5498
5756
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5499
5757
|
const [conditionNode, trueNode, falseNode] = node[1][1];
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5758
|
+
return chain(evaluateNode(conditionNode, contextStack), (condition) => {
|
|
5759
|
+
if (!condition) {
|
|
5760
|
+
return evaluateNode(trueNode, contextStack);
|
|
5761
|
+
}
|
|
5762
|
+
else if (falseNode) {
|
|
5763
|
+
return evaluateNode(falseNode, contextStack);
|
|
5764
|
+
}
|
|
5765
|
+
return null;
|
|
5766
|
+
});
|
|
5507
5767
|
},
|
|
5508
5768
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => getUndefinedSymbols(node[1][1].filter(n => !!n), contextStack, builtin, evaluateNode),
|
|
5509
5769
|
};
|
|
@@ -5529,10 +5789,12 @@ const letSpecialExpression = {
|
|
|
5529
5789
|
const bindingNode = node[1][1];
|
|
5530
5790
|
const target = bindingNode[1][0];
|
|
5531
5791
|
const value = bindingNode[1][1];
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5792
|
+
return chain(evaluateNode(value, contextStack), (bindingValue) => {
|
|
5793
|
+
return chain(evaluateBindingNodeValues(target, bindingValue, Node => evaluateNode(Node, contextStack)), (values) => {
|
|
5794
|
+
contextStack.addValues(values, target[2]);
|
|
5795
|
+
return bindingValue;
|
|
5796
|
+
});
|
|
5797
|
+
});
|
|
5536
5798
|
},
|
|
5537
5799
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => {
|
|
5538
5800
|
const bindingNode = node[1][1];
|
|
@@ -5579,39 +5841,93 @@ const loopSpecialExpression = {
|
|
|
5579
5841
|
docs: docs$7,
|
|
5580
5842
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5581
5843
|
const bindingNodes = node[1][1];
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5844
|
+
// Set up initial binding context sequentially (bindings may depend on each other)
|
|
5845
|
+
const initialContext = {};
|
|
5846
|
+
const setupBindings = reduceSequential(bindingNodes, (result, bindingNode) => {
|
|
5847
|
+
return chain(evaluateNode(bindingNode[1][1], contextStack.create(result)), (val) => {
|
|
5848
|
+
return chain(evaluateBindingNodeValues(bindingNode[1][0], val, Node => evaluateNode(Node, contextStack)), (valueRecord) => {
|
|
5849
|
+
Object.entries(valueRecord).forEach(([name, value]) => {
|
|
5850
|
+
result[name] = { value };
|
|
5851
|
+
});
|
|
5852
|
+
return result;
|
|
5853
|
+
});
|
|
5587
5854
|
});
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
if (error instanceof RecurSignal) {
|
|
5599
|
-
const params = error.params;
|
|
5600
|
-
if (params.length !== bindingNodes.length) {
|
|
5601
|
-
throw new LitsError(`recur expected ${bindingNodes.length} parameters, got ${valueToString(params.length)}`, node[2]);
|
|
5602
|
-
}
|
|
5603
|
-
bindingNodes.forEach((bindingNode, index) => {
|
|
5604
|
-
const valueRecord = evaluateBindingNodeValues(bindingNode[1][0], asAny(params[index]), Node => evaluateNode(Node, contextStack));
|
|
5855
|
+
}, initialContext);
|
|
5856
|
+
return chain(setupBindings, (bindingContext) => {
|
|
5857
|
+
const newContextStack = contextStack.create(bindingContext);
|
|
5858
|
+
const body = node[1][2];
|
|
5859
|
+
function rebindAndIterate(params) {
|
|
5860
|
+
if (params.length !== bindingNodes.length) {
|
|
5861
|
+
throw new LitsError(`recur expected ${bindingNodes.length} parameters, got ${valueToString(params.length)}`, node[2]);
|
|
5862
|
+
}
|
|
5863
|
+
return chain(forEachSequential(bindingNodes, (bindingNode, index) => {
|
|
5864
|
+
return chain(evaluateBindingNodeValues(bindingNode[1][0], asAny(params[index]), Node => evaluateNode(Node, contextStack)), (valueRecord) => {
|
|
5605
5865
|
for (const [name, value] of Object.entries(valueRecord)) {
|
|
5606
5866
|
bindingContext[name].value = value;
|
|
5607
5867
|
}
|
|
5608
5868
|
});
|
|
5609
|
-
|
|
5869
|
+
}), () => iterate());
|
|
5870
|
+
}
|
|
5871
|
+
function iterate() {
|
|
5872
|
+
return tryCatch(() => evaluateNode(body, newContextStack), (error) => {
|
|
5873
|
+
if (error instanceof RecurSignal) {
|
|
5874
|
+
return rebindAndIterate(error.params);
|
|
5875
|
+
}
|
|
5876
|
+
throw error;
|
|
5877
|
+
});
|
|
5878
|
+
}
|
|
5879
|
+
// Use sync for(;;) loop for the sync case to avoid stack overflow
|
|
5880
|
+
for (;;) {
|
|
5881
|
+
try {
|
|
5882
|
+
const result = evaluateNode(body, newContextStack);
|
|
5883
|
+
if (result instanceof Promise) {
|
|
5884
|
+
// Async path: handle recur via promise chain
|
|
5885
|
+
return result.catch((error) => {
|
|
5886
|
+
if (error instanceof RecurSignal) {
|
|
5887
|
+
return rebindAndIterate(error.params);
|
|
5888
|
+
}
|
|
5889
|
+
throw error;
|
|
5890
|
+
});
|
|
5891
|
+
}
|
|
5892
|
+
return result;
|
|
5893
|
+
}
|
|
5894
|
+
catch (error) {
|
|
5895
|
+
if (error instanceof RecurSignal) {
|
|
5896
|
+
const params = error.params;
|
|
5897
|
+
if (params.length !== bindingNodes.length) {
|
|
5898
|
+
throw new LitsError(`recur expected ${bindingNodes.length} parameters, got ${valueToString(params.length)}`, node[2]);
|
|
5899
|
+
}
|
|
5900
|
+
// rebindAndIterate returns MaybePromise — if any binding default is async,
|
|
5901
|
+
// we must switch to the async iterate path
|
|
5902
|
+
for (let index = 0; index < bindingNodes.length; index += 1) {
|
|
5903
|
+
const bindingNode = bindingNodes[index];
|
|
5904
|
+
const valueRecord = evaluateBindingNodeValues(bindingNode[1][0], asAny(params[index]), Node => evaluateNode(Node, contextStack));
|
|
5905
|
+
if (valueRecord instanceof Promise) {
|
|
5906
|
+
// Switch to fully async path
|
|
5907
|
+
return valueRecord.then((resolved) => {
|
|
5908
|
+
for (const [name, value] of Object.entries(resolved)) {
|
|
5909
|
+
bindingContext[name].value = value;
|
|
5910
|
+
}
|
|
5911
|
+
// Handle remaining bindings then iterate
|
|
5912
|
+
return chain(forEachSequential(bindingNodes.slice(index + 1), (bn, subIndex) => {
|
|
5913
|
+
return chain(evaluateBindingNodeValues(bn[1][0], asAny(params[index + 1 + subIndex]), Node => evaluateNode(Node, contextStack)), (vr) => {
|
|
5914
|
+
for (const [name, value] of Object.entries(vr)) {
|
|
5915
|
+
bindingContext[name].value = value;
|
|
5916
|
+
}
|
|
5917
|
+
});
|
|
5918
|
+
}), () => iterate());
|
|
5919
|
+
});
|
|
5920
|
+
}
|
|
5921
|
+
for (const [name, value] of Object.entries(valueRecord)) {
|
|
5922
|
+
bindingContext[name].value = value;
|
|
5923
|
+
}
|
|
5924
|
+
}
|
|
5925
|
+
continue;
|
|
5926
|
+
}
|
|
5927
|
+
throw error;
|
|
5610
5928
|
}
|
|
5611
|
-
throw error;
|
|
5612
5929
|
}
|
|
5613
|
-
|
|
5614
|
-
}
|
|
5930
|
+
});
|
|
5615
5931
|
},
|
|
5616
5932
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => {
|
|
5617
5933
|
const bindingNodes = node[1][1];
|
|
@@ -5631,74 +5947,107 @@ const loopSpecialExpression = {
|
|
|
5631
5947
|
};
|
|
5632
5948
|
|
|
5633
5949
|
function addToContext(bindings, context, contextStack, evaluateNode) {
|
|
5950
|
+
let bindingChain = undefined;
|
|
5634
5951
|
for (const bindingNode of bindings) {
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5952
|
+
bindingChain = chain(bindingChain, () => {
|
|
5953
|
+
const [target, bindingValue] = bindingNode[1];
|
|
5954
|
+
return chain(evaluateNode(bindingValue, contextStack), (val) => {
|
|
5955
|
+
return chain(evaluateBindingNodeValues(target, val, Node => evaluateNode(Node, contextStack)), (valueRecord) => {
|
|
5956
|
+
Object.entries(valueRecord).forEach(([name, value]) => {
|
|
5957
|
+
context[name] = { value };
|
|
5958
|
+
});
|
|
5959
|
+
});
|
|
5960
|
+
});
|
|
5640
5961
|
});
|
|
5641
5962
|
}
|
|
5963
|
+
return bindingChain;
|
|
5642
5964
|
}
|
|
5643
5965
|
function evaluateLoop(returnResult, loopNode, contextStack, evaluateNode) {
|
|
5644
5966
|
const sourceCodeInfo = loopNode[2];
|
|
5645
5967
|
const [, loopBindings, body] = loopNode[1];
|
|
5646
5968
|
const result = [];
|
|
5647
5969
|
const bindingIndices = loopBindings.map(() => 0);
|
|
5648
|
-
|
|
5649
|
-
while (!abort) {
|
|
5970
|
+
function processIteration() {
|
|
5650
5971
|
const context = {};
|
|
5651
5972
|
const newContextStack = contextStack.create(context);
|
|
5652
|
-
|
|
5653
|
-
|
|
5973
|
+
function processBinding(bindingIndex) {
|
|
5974
|
+
if (bindingIndex >= loopBindings.length)
|
|
5975
|
+
return 'continue';
|
|
5654
5976
|
const [bindingNode, letBindings, whenNode, whileNode] = loopBindings[bindingIndex];
|
|
5655
5977
|
const [targetNode, valueNode] = bindingNode[1];
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
break;
|
|
5662
|
-
}
|
|
5663
|
-
const index = asNonUndefined(bindingIndices[bindingIndex], sourceCodeInfo);
|
|
5664
|
-
if (index >= seq.length) {
|
|
5665
|
-
skip = true;
|
|
5666
|
-
if (bindingIndex === 0) {
|
|
5667
|
-
abort = true;
|
|
5668
|
-
break;
|
|
5978
|
+
return chain(evaluateNode(valueNode, newContextStack), (rawColl) => {
|
|
5979
|
+
const coll = asColl(rawColl, sourceCodeInfo);
|
|
5980
|
+
const seq = isSeq(coll) ? coll : Object.entries(coll);
|
|
5981
|
+
if (seq.length === 0) {
|
|
5982
|
+
return 'abort';
|
|
5669
5983
|
}
|
|
5670
|
-
bindingIndices[bindingIndex]
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5984
|
+
const index = asNonUndefined(bindingIndices[bindingIndex], sourceCodeInfo);
|
|
5985
|
+
if (index >= seq.length) {
|
|
5986
|
+
if (bindingIndex === 0) {
|
|
5987
|
+
return 'abort';
|
|
5988
|
+
}
|
|
5989
|
+
bindingIndices[bindingIndex] = 0;
|
|
5990
|
+
bindingIndices[bindingIndex - 1] = asNonUndefined(bindingIndices[bindingIndex - 1], sourceCodeInfo) + 1;
|
|
5991
|
+
return 'skip';
|
|
5992
|
+
}
|
|
5993
|
+
const val = asAny(seq[index], sourceCodeInfo);
|
|
5994
|
+
return chain(evaluateBindingNodeValues(targetNode, val, Node => evaluateNode(Node, newContextStack)), (valueRecord) => {
|
|
5995
|
+
Object.entries(valueRecord).forEach(([name, value]) => {
|
|
5996
|
+
context[name] = { value };
|
|
5997
|
+
});
|
|
5998
|
+
return chain(letBindings.length > 0
|
|
5999
|
+
? addToContext(letBindings, context, newContextStack, evaluateNode)
|
|
6000
|
+
: undefined, () => {
|
|
6001
|
+
if (whenNode) {
|
|
6002
|
+
return chain(evaluateNode(whenNode, newContextStack), (whenResult) => {
|
|
6003
|
+
if (!whenResult) {
|
|
6004
|
+
bindingIndices[bindingIndex] = asNonUndefined(bindingIndices[bindingIndex], sourceCodeInfo) + 1;
|
|
6005
|
+
return 'skip';
|
|
6006
|
+
}
|
|
6007
|
+
if (whileNode) {
|
|
6008
|
+
return chain(evaluateNode(whileNode, newContextStack), (whileResult) => {
|
|
6009
|
+
if (!whileResult) {
|
|
6010
|
+
bindingIndices[bindingIndex] = Number.POSITIVE_INFINITY;
|
|
6011
|
+
return 'skip';
|
|
6012
|
+
}
|
|
6013
|
+
return processBinding(bindingIndex + 1);
|
|
6014
|
+
});
|
|
6015
|
+
}
|
|
6016
|
+
return processBinding(bindingIndex + 1);
|
|
6017
|
+
});
|
|
6018
|
+
}
|
|
6019
|
+
if (whileNode) {
|
|
6020
|
+
return chain(evaluateNode(whileNode, newContextStack), (whileResult) => {
|
|
6021
|
+
if (!whileResult) {
|
|
6022
|
+
bindingIndices[bindingIndex] = Number.POSITIVE_INFINITY;
|
|
6023
|
+
return 'skip';
|
|
6024
|
+
}
|
|
6025
|
+
return processBinding(bindingIndex + 1);
|
|
6026
|
+
});
|
|
6027
|
+
}
|
|
6028
|
+
return processBinding(bindingIndex + 1);
|
|
6029
|
+
});
|
|
6030
|
+
});
|
|
5678
6031
|
});
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
bindingIndices[bindingIndex] = asNonUndefined(bindingIndices[bindingIndex], sourceCodeInfo) + 1;
|
|
5684
|
-
skip = true;
|
|
5685
|
-
break bindingsLoop;
|
|
6032
|
+
}
|
|
6033
|
+
return chain(processBinding(0), (status) => {
|
|
6034
|
+
if (status === 'abort') {
|
|
6035
|
+
return returnResult ? result : null;
|
|
5686
6036
|
}
|
|
5687
|
-
if (
|
|
5688
|
-
|
|
5689
|
-
skip = true;
|
|
5690
|
-
break bindingsLoop;
|
|
6037
|
+
if (status === 'skip') {
|
|
6038
|
+
return processIteration();
|
|
5691
6039
|
}
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
6040
|
+
// status === 'continue'
|
|
6041
|
+
return chain(evaluateNode(body, newContextStack), (value) => {
|
|
6042
|
+
if (returnResult)
|
|
6043
|
+
result.push(value);
|
|
6044
|
+
if (bindingIndices.length > 0)
|
|
6045
|
+
bindingIndices[bindingIndices.length - 1] += 1;
|
|
6046
|
+
return processIteration();
|
|
6047
|
+
});
|
|
6048
|
+
});
|
|
5700
6049
|
}
|
|
5701
|
-
return
|
|
6050
|
+
return processIteration();
|
|
5702
6051
|
}
|
|
5703
6052
|
function analyze(loopNode, contextStack, getUndefinedSymbols, builtin, evaluateNode) {
|
|
5704
6053
|
const result = new Set();
|
|
@@ -5787,8 +6136,7 @@ const doseqSpecialExpression = {
|
|
|
5787
6136
|
arity: toFixedArity(1),
|
|
5788
6137
|
docs: doseqDocs,
|
|
5789
6138
|
evaluate: (node, contextStack, helpers) => {
|
|
5790
|
-
evaluateLoop(false, node, contextStack, helpers.evaluateNode);
|
|
5791
|
-
return null;
|
|
6139
|
+
return chain(evaluateLoop(false, node, contextStack, helpers.evaluateNode), () => null);
|
|
5792
6140
|
},
|
|
5793
6141
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => analyze(node, contextStack, getUndefinedSymbols, builtin, evaluateNode),
|
|
5794
6142
|
};
|
|
@@ -5828,13 +6176,11 @@ const orSpecialExpression = {
|
|
|
5828
6176
|
arity: {},
|
|
5829
6177
|
docs: docs$6,
|
|
5830
6178
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
}
|
|
5837
|
-
return value;
|
|
6179
|
+
return reduceSequential(node[1][1], (acc, param) => {
|
|
6180
|
+
if (acc)
|
|
6181
|
+
return acc;
|
|
6182
|
+
return evaluateNode(param, contextStack);
|
|
6183
|
+
}, false);
|
|
5838
6184
|
},
|
|
5839
6185
|
evaluateAsNormalExpression: (params, sourceCodeInfo) => {
|
|
5840
6186
|
let value = false;
|
|
@@ -5887,16 +6233,21 @@ const qqSpecialExpression = {
|
|
|
5887
6233
|
arity: { min: 1 },
|
|
5888
6234
|
docs: docs$5,
|
|
5889
6235
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5890
|
-
|
|
6236
|
+
// Use a sentinel to know we haven't found a non-null value yet
|
|
6237
|
+
const SENTINEL = Symbol('qq-sentinel');
|
|
6238
|
+
return chain(reduceSequential(node[1][1], (acc, param) => {
|
|
6239
|
+
if (acc !== SENTINEL)
|
|
6240
|
+
return acc;
|
|
5891
6241
|
if (isUserDefinedSymbolNode(param) && contextStack.lookUp(param) === null) {
|
|
5892
|
-
|
|
5893
|
-
}
|
|
5894
|
-
const result = evaluateNode(param, contextStack);
|
|
5895
|
-
if (result !== null) {
|
|
5896
|
-
return result;
|
|
6242
|
+
return SENTINEL;
|
|
5897
6243
|
}
|
|
5898
|
-
|
|
5899
|
-
|
|
6244
|
+
return chain(evaluateNode(param, contextStack), (result) => {
|
|
6245
|
+
if (result !== null) {
|
|
6246
|
+
return result;
|
|
6247
|
+
}
|
|
6248
|
+
return SENTINEL;
|
|
6249
|
+
});
|
|
6250
|
+
}, SENTINEL), result => result === SENTINEL ? null : result);
|
|
5900
6251
|
},
|
|
5901
6252
|
evaluateAsNormalExpression: (params, sourceCodeInfo) => {
|
|
5902
6253
|
for (const param of params) {
|
|
@@ -5944,8 +6295,9 @@ const recurSpecialExpression = {
|
|
|
5944
6295
|
docs: docs$4,
|
|
5945
6296
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5946
6297
|
const params = node[1][1];
|
|
5947
|
-
|
|
5948
|
-
|
|
6298
|
+
return chain(mapSequential(params, paramNode => evaluateNode(paramNode, contextStack)), (evaluatedParams) => {
|
|
6299
|
+
throw new RecurSignal(evaluatedParams);
|
|
6300
|
+
});
|
|
5949
6301
|
},
|
|
5950
6302
|
evaluateAsNormalExpression: (params) => {
|
|
5951
6303
|
throw new RecurSignal(params);
|
|
@@ -5976,10 +6328,12 @@ const throwSpecialExpression = {
|
|
|
5976
6328
|
arity: toFixedArity(1),
|
|
5977
6329
|
docs: docs$3,
|
|
5978
6330
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
5979
|
-
|
|
5980
|
-
|
|
6331
|
+
return chain(evaluateNode(node[1][1], contextStack), (result) => {
|
|
6332
|
+
const message = asString(result, node[2], {
|
|
6333
|
+
nonEmpty: true,
|
|
6334
|
+
});
|
|
6335
|
+
throw new UserDefinedError(message, node[2]);
|
|
5981
6336
|
});
|
|
5982
|
-
throw new UserDefinedError(message, node[2]);
|
|
5983
6337
|
},
|
|
5984
6338
|
evaluateAsNormalExpression: (params, sourceCodeInfo) => {
|
|
5985
6339
|
const message = asString(params[0], sourceCodeInfo, {
|
|
@@ -6025,17 +6379,14 @@ const trySpecialExpression = {
|
|
|
6025
6379
|
docs: docs$2,
|
|
6026
6380
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
6027
6381
|
const [, tryExpression, errorSymbol, catchExpression] = node[1];
|
|
6028
|
-
|
|
6029
|
-
return evaluateNode(tryExpression, contextStack);
|
|
6030
|
-
}
|
|
6031
|
-
catch (error) {
|
|
6382
|
+
return tryCatch(() => evaluateNode(tryExpression, contextStack), (error) => {
|
|
6032
6383
|
const newContext = errorSymbol
|
|
6033
6384
|
? {
|
|
6034
6385
|
[errorSymbol[1]]: { value: error },
|
|
6035
6386
|
}
|
|
6036
6387
|
: {};
|
|
6037
6388
|
return evaluateNode(catchExpression, contextStack.create(newContext));
|
|
6038
|
-
}
|
|
6389
|
+
});
|
|
6039
6390
|
},
|
|
6040
6391
|
getUndefinedSymbols: (node, contextStack, { getUndefinedSymbols, builtin, evaluateNode }) => {
|
|
6041
6392
|
const [, tryExpression, errorSymbol, catchExpression] = node[1];
|
|
@@ -6082,19 +6433,21 @@ const arraySpecialExpression = {
|
|
|
6082
6433
|
docs: docs$1,
|
|
6083
6434
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
6084
6435
|
const result = [];
|
|
6085
|
-
|
|
6436
|
+
return chain(forEachSequential(node[1][1], (param) => {
|
|
6086
6437
|
if (isSpreadNode(param)) {
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6438
|
+
return chain(evaluateNode(param[1], contextStack), (spreadValue) => {
|
|
6439
|
+
if (!Array.isArray(spreadValue)) {
|
|
6440
|
+
throw new LitsError('Spread value is not an array', param[2]);
|
|
6441
|
+
}
|
|
6442
|
+
result.push(...spreadValue);
|
|
6443
|
+
});
|
|
6092
6444
|
}
|
|
6093
6445
|
else {
|
|
6094
|
-
|
|
6446
|
+
return chain(evaluateNode(param, contextStack), (value) => {
|
|
6447
|
+
result.push(value);
|
|
6448
|
+
});
|
|
6095
6449
|
}
|
|
6096
|
-
}
|
|
6097
|
-
return result;
|
|
6450
|
+
}), () => result);
|
|
6098
6451
|
},
|
|
6099
6452
|
evaluateAsNormalExpression: (params, sourceCodeInfo) => {
|
|
6100
6453
|
const result = [];
|
|
@@ -6147,28 +6500,34 @@ const objectSpecialExpression = {
|
|
|
6147
6500
|
evaluate: (node, contextStack, { evaluateNode }) => {
|
|
6148
6501
|
const result = {};
|
|
6149
6502
|
const params = node[1][1];
|
|
6150
|
-
|
|
6503
|
+
function processEntry(i) {
|
|
6504
|
+
if (i >= params.length)
|
|
6505
|
+
return result;
|
|
6151
6506
|
const keyNode = params[i];
|
|
6152
6507
|
if (isSpreadNode(keyNode)) {
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6508
|
+
return chain(evaluateNode(keyNode[1], contextStack), (spreadObject) => {
|
|
6509
|
+
if (!isUnknownRecord(spreadObject)) {
|
|
6510
|
+
throw new LitsError('Spread value is not an object', keyNode[2]);
|
|
6511
|
+
}
|
|
6512
|
+
Object.assign(result, spreadObject);
|
|
6513
|
+
return processEntry(i + 1);
|
|
6514
|
+
});
|
|
6159
6515
|
}
|
|
6160
6516
|
else {
|
|
6161
|
-
const key = evaluateNode(keyNode, contextStack);
|
|
6162
6517
|
const valueNode = params[i + 1];
|
|
6163
6518
|
if (valueNode === undefined) {
|
|
6164
6519
|
throw new LitsError('Missing value for key', keyNode[2]);
|
|
6165
6520
|
}
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6521
|
+
return chain(evaluateNode(keyNode, contextStack), (key) => {
|
|
6522
|
+
return chain(evaluateNode(valueNode, contextStack), (value) => {
|
|
6523
|
+
assertString(key, keyNode[2]);
|
|
6524
|
+
result[key] = value;
|
|
6525
|
+
return processEntry(i + 2);
|
|
6526
|
+
});
|
|
6527
|
+
});
|
|
6169
6528
|
}
|
|
6170
6529
|
}
|
|
6171
|
-
return
|
|
6530
|
+
return processEntry(0);
|
|
6172
6531
|
},
|
|
6173
6532
|
evaluateAsNormalExpression: (params, sourceCodeInfo) => {
|
|
6174
6533
|
const result = {};
|
|
@@ -6267,7 +6626,19 @@ function isNumberReservedSymbol(symbol) {
|
|
|
6267
6626
|
const functionExecutors = {
|
|
6268
6627
|
NativeJsFunction: (fn, params, sourceCodeInfo) => {
|
|
6269
6628
|
try {
|
|
6270
|
-
|
|
6629
|
+
const result = fn.nativeFn.fn(...params);
|
|
6630
|
+
// If the native function returns a Promise, await it transparently
|
|
6631
|
+
if (result instanceof Promise) {
|
|
6632
|
+
return result.then(resolved => toAny(resolved), (error) => {
|
|
6633
|
+
const message = typeof error === 'string'
|
|
6634
|
+
? error
|
|
6635
|
+
: isUnknownRecord(error) && typeof error.message === 'string'
|
|
6636
|
+
? error.message
|
|
6637
|
+
: '<no message>';
|
|
6638
|
+
throw new LitsError(`Native function threw: "${message}"`, sourceCodeInfo);
|
|
6639
|
+
});
|
|
6640
|
+
}
|
|
6641
|
+
return toAny(result);
|
|
6271
6642
|
}
|
|
6272
6643
|
catch (error) {
|
|
6273
6644
|
const message = typeof error === 'string'
|
|
@@ -6279,9 +6650,9 @@ const functionExecutors = {
|
|
|
6279
6650
|
}
|
|
6280
6651
|
},
|
|
6281
6652
|
UserDefined: (fn, params, sourceCodeInfo, contextStack, { evaluateNode }) => {
|
|
6282
|
-
|
|
6283
|
-
if (!arityAcceptsMin(fn.arity,
|
|
6284
|
-
throw new LitsError(`Expected ${fn.arity} arguments, got ${
|
|
6653
|
+
function setupAndExecute(currentParams) {
|
|
6654
|
+
if (!arityAcceptsMin(fn.arity, currentParams.length)) {
|
|
6655
|
+
throw new LitsError(`Expected ${fn.arity} arguments, got ${currentParams.length}.`, sourceCodeInfo);
|
|
6285
6656
|
}
|
|
6286
6657
|
const evaluatedFunction = fn.evaluatedfunction;
|
|
6287
6658
|
const args = evaluatedFunction[0];
|
|
@@ -6289,39 +6660,70 @@ const functionExecutors = {
|
|
|
6289
6660
|
const newContextStack = contextStack.create(fn.evaluatedfunction[2]);
|
|
6290
6661
|
const newContext = { self: { value: fn } };
|
|
6291
6662
|
const rest = [];
|
|
6292
|
-
|
|
6663
|
+
// Process non-rest params sequentially since binding evaluation may be async
|
|
6664
|
+
let paramSetup = undefined;
|
|
6665
|
+
for (let i = 0; i < currentParams.length; i += 1) {
|
|
6293
6666
|
if (i < nbrOfNonRestArgs) {
|
|
6294
|
-
const
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6667
|
+
const paramIndex = i;
|
|
6668
|
+
paramSetup = chain(paramSetup, () => {
|
|
6669
|
+
const param = toAny(currentParams[paramIndex]);
|
|
6670
|
+
return chain(evaluateBindingNodeValues(args[paramIndex], param, node => evaluateNode(node, newContextStack.create(newContext))), (valueRecord) => {
|
|
6671
|
+
Object.entries(valueRecord).forEach(([key, value]) => {
|
|
6672
|
+
newContext[key] = { value };
|
|
6673
|
+
});
|
|
6674
|
+
});
|
|
6298
6675
|
});
|
|
6299
6676
|
}
|
|
6300
6677
|
else {
|
|
6301
|
-
rest.push(toAny(
|
|
6678
|
+
rest.push(toAny(currentParams[i]));
|
|
6302
6679
|
}
|
|
6303
6680
|
}
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
const
|
|
6308
|
-
|
|
6309
|
-
|
|
6681
|
+
// Handle default values for optional params — chain sequentially since they may be async
|
|
6682
|
+
let defaultSetup = undefined;
|
|
6683
|
+
for (let i = currentParams.length; i < nbrOfNonRestArgs; i++) {
|
|
6684
|
+
const argIndex = i;
|
|
6685
|
+
defaultSetup = chain(defaultSetup, () => {
|
|
6686
|
+
const arg = args[argIndex];
|
|
6687
|
+
return chain(evaluateNode(arg[1][1], contextStack.create(newContext)), (defaultValue) => {
|
|
6688
|
+
return chain(evaluateBindingNodeValues(arg, defaultValue, node => evaluateNode(node, contextStack.create(newContext))), (valueRecord) => {
|
|
6689
|
+
Object.entries(valueRecord).forEach(([key, value]) => {
|
|
6690
|
+
newContext[key] = { value };
|
|
6691
|
+
});
|
|
6692
|
+
});
|
|
6693
|
+
});
|
|
6310
6694
|
});
|
|
6311
6695
|
}
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
const
|
|
6315
|
-
|
|
6316
|
-
|
|
6696
|
+
return chain(paramSetup, () => chain(defaultSetup, () => {
|
|
6697
|
+
const restArgument = args.find(arg => arg[0] === bindingTargetTypes.rest);
|
|
6698
|
+
const restSetup = restArgument !== undefined
|
|
6699
|
+
? chain(evaluateBindingNodeValues(restArgument, rest, node => evaluateNode(node, contextStack.create(newContext))), (valueRecord) => {
|
|
6700
|
+
Object.entries(valueRecord).forEach(([key, value]) => {
|
|
6701
|
+
newContext[key] = { value };
|
|
6702
|
+
});
|
|
6703
|
+
})
|
|
6704
|
+
: undefined;
|
|
6705
|
+
return chain(restSetup, () => {
|
|
6706
|
+
// Evaluate body nodes sequentially
|
|
6707
|
+
const newContextStack2 = newContextStack.create(newContext);
|
|
6708
|
+
const bodyResult = reduceSequential(evaluatedFunction[1], (_acc, node) => evaluateNode(node, newContextStack2), null);
|
|
6709
|
+
// Handle RecurSignal for async body results
|
|
6710
|
+
if (bodyResult instanceof Promise) {
|
|
6711
|
+
return bodyResult.catch((error) => {
|
|
6712
|
+
if (error instanceof RecurSignal) {
|
|
6713
|
+
return setupAndExecute(error.params);
|
|
6714
|
+
}
|
|
6715
|
+
throw error;
|
|
6716
|
+
});
|
|
6717
|
+
}
|
|
6718
|
+
return bodyResult;
|
|
6317
6719
|
});
|
|
6318
|
-
}
|
|
6720
|
+
}));
|
|
6721
|
+
}
|
|
6722
|
+
// Sync recur loop: use for(;;) to avoid stack overflow for sync tail recursion
|
|
6723
|
+
for (;;) {
|
|
6319
6724
|
try {
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
for (const node of evaluatedFunction[1]) {
|
|
6323
|
-
result = evaluateNode(node, newContextStack2);
|
|
6324
|
-
}
|
|
6725
|
+
const result = setupAndExecute(params);
|
|
6726
|
+
// If result is async, the RecurSignal handling is inside the Promise chain
|
|
6325
6727
|
return result;
|
|
6326
6728
|
}
|
|
6327
6729
|
catch (error) {
|
|
@@ -6351,38 +6753,51 @@ const functionExecutors = {
|
|
|
6351
6753
|
throw new LitsError(`(comp) expects one argument, got ${valueToString(params.length)}.`, sourceCodeInfo);
|
|
6352
6754
|
return asAny(params[0], sourceCodeInfo);
|
|
6353
6755
|
}
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6756
|
+
// reduceRight with MaybePromise: each step wraps result in array, passes to next function
|
|
6757
|
+
let result = params;
|
|
6758
|
+
for (let i = f.length - 1; i >= 0; i--) {
|
|
6759
|
+
const fun = f[i];
|
|
6760
|
+
result = chain(result, (currentParams) => {
|
|
6761
|
+
return chain(executeFunction(asFunctionLike(fun, sourceCodeInfo), currentParams, contextStack, sourceCodeInfo), r => [r]);
|
|
6762
|
+
});
|
|
6763
|
+
}
|
|
6764
|
+
return chain(result, finalArr => asAny(finalArr[0], sourceCodeInfo));
|
|
6357
6765
|
},
|
|
6358
6766
|
Constantly: (fn) => {
|
|
6359
6767
|
return fn.value;
|
|
6360
6768
|
},
|
|
6361
6769
|
Juxt: (fn, params, sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
6362
|
-
return fn.params
|
|
6770
|
+
return mapSequential(fn.params, fun => executeFunction(asFunctionLike(fun, sourceCodeInfo), params, contextStack, sourceCodeInfo));
|
|
6363
6771
|
},
|
|
6364
6772
|
Complement: (fn, params, sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
6365
|
-
return
|
|
6773
|
+
return chain(executeFunction(fn.function, params, contextStack, sourceCodeInfo), result => !result);
|
|
6366
6774
|
},
|
|
6367
6775
|
EveryPred: (fn, params, sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
6776
|
+
// Flatten to sequential checks: for each predicate, for each param
|
|
6777
|
+
const checks = [];
|
|
6368
6778
|
for (const f of fn.params) {
|
|
6369
6779
|
for (const param of params) {
|
|
6370
|
-
|
|
6371
|
-
if (!result)
|
|
6372
|
-
return false;
|
|
6780
|
+
checks.push(() => executeFunction(asFunctionLike(f, sourceCodeInfo), [param], contextStack, sourceCodeInfo));
|
|
6373
6781
|
}
|
|
6374
6782
|
}
|
|
6375
|
-
return
|
|
6783
|
+
return reduceSequential(checks, (acc, check) => {
|
|
6784
|
+
if (!acc)
|
|
6785
|
+
return false;
|
|
6786
|
+
return chain(check(), result => !!result);
|
|
6787
|
+
}, true);
|
|
6376
6788
|
},
|
|
6377
6789
|
SomePred: (fn, params, sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
6790
|
+
const checks = [];
|
|
6378
6791
|
for (const f of fn.params) {
|
|
6379
6792
|
for (const param of params) {
|
|
6380
|
-
|
|
6381
|
-
if (result)
|
|
6382
|
-
return true;
|
|
6793
|
+
checks.push(() => executeFunction(asFunctionLike(f, sourceCodeInfo), [param], contextStack, sourceCodeInfo));
|
|
6383
6794
|
}
|
|
6384
6795
|
}
|
|
6385
|
-
return
|
|
6796
|
+
return reduceSequential(checks, (acc, check) => {
|
|
6797
|
+
if (acc)
|
|
6798
|
+
return true;
|
|
6799
|
+
return chain(check(), result => !!result);
|
|
6800
|
+
}, false);
|
|
6386
6801
|
},
|
|
6387
6802
|
Fnull: (fn, params, sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
6388
6803
|
const fnulledParams = params.map((param, index) => (param === null ? toAny(fn.params[index]) : param));
|
|
@@ -6416,11 +6831,7 @@ const functionExecutors = {
|
|
|
6416
6831
|
};
|
|
6417
6832
|
|
|
6418
6833
|
function evaluate(ast, contextStack) {
|
|
6419
|
-
|
|
6420
|
-
for (const node of ast.body) {
|
|
6421
|
-
result = evaluateNode(node, contextStack);
|
|
6422
|
-
}
|
|
6423
|
-
return result;
|
|
6834
|
+
return reduceSequential(ast.body, (_acc, node) => evaluateNode(node, contextStack), null);
|
|
6424
6835
|
}
|
|
6425
6836
|
function evaluateNode(node, contextStack) {
|
|
6426
6837
|
switch (node[0]) {
|
|
@@ -6436,13 +6847,15 @@ function evaluateNode(node, contextStack) {
|
|
|
6436
6847
|
return evaluateReservedSymbol(node);
|
|
6437
6848
|
case NodeTypes.NormalExpression: {
|
|
6438
6849
|
const result = evaluateNormalExpression(node, contextStack);
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6850
|
+
return chain(result, (resolved) => {
|
|
6851
|
+
if (typeof resolved === 'number' && Number.isNaN(resolved)) {
|
|
6852
|
+
throw new LitsError('Number is NaN', node[2]);
|
|
6853
|
+
}
|
|
6854
|
+
return annotate(resolved);
|
|
6855
|
+
});
|
|
6443
6856
|
}
|
|
6444
6857
|
case NodeTypes.SpecialExpression:
|
|
6445
|
-
return
|
|
6858
|
+
return chain(evaluateSpecialExpression(node, contextStack), resolved => annotate(resolved));
|
|
6446
6859
|
/* v8 ignore next 2 */
|
|
6447
6860
|
default:
|
|
6448
6861
|
throw new LitsError(`${getNodeTypeName(node[0])}-node cannot be evaluated`, node[2]);
|
|
@@ -6462,73 +6875,84 @@ function evaluateReservedSymbol(node) {
|
|
|
6462
6875
|
const value = reservedSymbolRecord[reservedName];
|
|
6463
6876
|
return asNonUndefined(value, node[2]);
|
|
6464
6877
|
}
|
|
6465
|
-
function
|
|
6466
|
-
const sourceCodeInfo = node[2];
|
|
6467
|
-
const paramNodes = node[1][1];
|
|
6878
|
+
function evaluateParams(paramNodes, contextStack) {
|
|
6468
6879
|
const params = [];
|
|
6469
6880
|
const placeholders = [];
|
|
6470
|
-
paramNodes
|
|
6881
|
+
const result = forEachSequential(paramNodes, (paramNode, index) => {
|
|
6471
6882
|
if (isSpreadNode(paramNode)) {
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6883
|
+
return chain(evaluateNode(paramNode[1], contextStack), (spreadValue) => {
|
|
6884
|
+
if (Array.isArray(spreadValue)) {
|
|
6885
|
+
params.push(...spreadValue);
|
|
6886
|
+
}
|
|
6887
|
+
else {
|
|
6888
|
+
throw new LitsError(`Spread operator requires an array, got ${valueToString(paramNode)}`, paramNode[2]);
|
|
6889
|
+
}
|
|
6890
|
+
});
|
|
6479
6891
|
}
|
|
6480
6892
|
else if (paramNode[0] === NodeTypes.ReservedSymbol && paramNode[1] === '_') {
|
|
6481
6893
|
placeholders.push(index);
|
|
6482
6894
|
}
|
|
6483
6895
|
else {
|
|
6484
|
-
|
|
6896
|
+
return chain(evaluateNode(paramNode, contextStack), (value) => {
|
|
6897
|
+
params.push(value);
|
|
6898
|
+
});
|
|
6485
6899
|
}
|
|
6486
6900
|
});
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
if (
|
|
6510
|
-
|
|
6901
|
+
return chain(result, () => ({ params, placeholders }));
|
|
6902
|
+
}
|
|
6903
|
+
function evaluateNormalExpression(node, contextStack) {
|
|
6904
|
+
const sourceCodeInfo = node[2];
|
|
6905
|
+
return chain(evaluateParams(node[1][1], contextStack), ({ params, placeholders }) => {
|
|
6906
|
+
if (isNormalExpressionNodeWithName(node)) {
|
|
6907
|
+
const nameSymbol = node[1][0];
|
|
6908
|
+
if (placeholders.length > 0) {
|
|
6909
|
+
const fn = evaluateNode(nameSymbol, contextStack);
|
|
6910
|
+
return chain(fn, (resolvedFn) => {
|
|
6911
|
+
const partialFunction = {
|
|
6912
|
+
[FUNCTION_SYMBOL]: true,
|
|
6913
|
+
function: asFunctionLike(resolvedFn, sourceCodeInfo),
|
|
6914
|
+
functionType: 'Partial',
|
|
6915
|
+
params,
|
|
6916
|
+
placeholders,
|
|
6917
|
+
sourceCodeInfo,
|
|
6918
|
+
arity: toFixedArity(placeholders.length),
|
|
6919
|
+
};
|
|
6920
|
+
return partialFunction;
|
|
6921
|
+
});
|
|
6922
|
+
}
|
|
6923
|
+
if (isNormalBuiltinSymbolNode(nameSymbol)) {
|
|
6924
|
+
const type = nameSymbol[1];
|
|
6925
|
+
const normalExpression = builtin.allNormalExpressions[type];
|
|
6926
|
+
return normalExpression.evaluate(params, node[2], contextStack, { executeFunction });
|
|
6927
|
+
}
|
|
6928
|
+
else {
|
|
6929
|
+
const fn = contextStack.getValue(nameSymbol[1]);
|
|
6930
|
+
if (fn !== undefined) {
|
|
6931
|
+
return executeFunction(asFunctionLike(fn, sourceCodeInfo), params, contextStack, sourceCodeInfo);
|
|
6932
|
+
}
|
|
6933
|
+
throw new UndefinedSymbolError(nameSymbol[1], node[2]);
|
|
6511
6934
|
}
|
|
6512
|
-
throw new UndefinedSymbolError(nameSymbol[1], node[2]);
|
|
6513
6935
|
}
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6936
|
+
else {
|
|
6937
|
+
const fnNode = node[1][0];
|
|
6938
|
+
return chain(evaluateNode(fnNode, contextStack), (resolvedFn) => {
|
|
6939
|
+
const fn = asFunctionLike(resolvedFn, sourceCodeInfo);
|
|
6940
|
+
if (placeholders.length > 0) {
|
|
6941
|
+
const partialFunction = {
|
|
6942
|
+
[FUNCTION_SYMBOL]: true,
|
|
6943
|
+
function: fn,
|
|
6944
|
+
functionType: 'Partial',
|
|
6945
|
+
params,
|
|
6946
|
+
placeholders,
|
|
6947
|
+
sourceCodeInfo,
|
|
6948
|
+
arity: toFixedArity(placeholders.length),
|
|
6949
|
+
};
|
|
6950
|
+
return partialFunction;
|
|
6951
|
+
}
|
|
6952
|
+
return executeFunction(fn, params, contextStack, sourceCodeInfo);
|
|
6953
|
+
});
|
|
6529
6954
|
}
|
|
6530
|
-
|
|
6531
|
-
}
|
|
6955
|
+
});
|
|
6532
6956
|
}
|
|
6533
6957
|
function executeFunction(fn, params, contextStack, sourceCodeInfo) {
|
|
6534
6958
|
if (isLitsFunction(fn))
|
|
@@ -7587,6 +8011,7 @@ class ParserContext {
|
|
|
7587
8011
|
const token = this.tokens[this.position];
|
|
7588
8012
|
if (!token) {
|
|
7589
8013
|
const lastToken = this.tokens.at(-1);
|
|
8014
|
+
/* v8 ignore next */
|
|
7590
8015
|
const sourceCodeInfo = lastToken ? lastToken[2] : undefined;
|
|
7591
8016
|
throw new LitsError('Unexpected end of input', sourceCodeInfo);
|
|
7592
8017
|
}
|
|
@@ -8863,15 +9288,36 @@ class Lits {
|
|
|
8863
9288
|
debug: this.debug,
|
|
8864
9289
|
};
|
|
8865
9290
|
}
|
|
9291
|
+
async = {
|
|
9292
|
+
run: async (program, params = {}) => {
|
|
9293
|
+
const ast = this.generateAst(program, params);
|
|
9294
|
+
return this.evaluate(ast, params);
|
|
9295
|
+
},
|
|
9296
|
+
context: async (programOrAst, params = {}) => {
|
|
9297
|
+
const ast = typeof programOrAst === 'string' ? this.generateAst(programOrAst, params) : programOrAst;
|
|
9298
|
+
const contextStack = createContextStack(params, this.modules);
|
|
9299
|
+
await evaluate(ast, contextStack);
|
|
9300
|
+
return contextStack.globalContext;
|
|
9301
|
+
},
|
|
9302
|
+
apply: async (fn, fnParams, params = {}) => {
|
|
9303
|
+
return this.apply(fn, fnParams, params);
|
|
9304
|
+
},
|
|
9305
|
+
};
|
|
8866
9306
|
run(program, params = {}) {
|
|
8867
9307
|
const ast = this.generateAst(program, params);
|
|
8868
9308
|
const result = this.evaluate(ast, params);
|
|
9309
|
+
if (result instanceof Promise) {
|
|
9310
|
+
throw new TypeError('Unexpected async result in synchronous run(). Use lits.async.run() for async operations.');
|
|
9311
|
+
}
|
|
8869
9312
|
return result;
|
|
8870
9313
|
}
|
|
8871
9314
|
context(programOrAst, params = {}) {
|
|
8872
9315
|
const ast = typeof programOrAst === 'string' ? this.generateAst(programOrAst, params) : programOrAst;
|
|
8873
9316
|
const contextStack = createContextStack(params, this.modules);
|
|
8874
|
-
evaluate(ast, contextStack);
|
|
9317
|
+
const result = evaluate(ast, contextStack);
|
|
9318
|
+
if (result instanceof Promise) {
|
|
9319
|
+
throw new TypeError('Unexpected async result in synchronous context(). Use lits.async.context() for async operations.');
|
|
9320
|
+
}
|
|
8875
9321
|
return contextStack.globalContext;
|
|
8876
9322
|
}
|
|
8877
9323
|
getUndefinedSymbols(programOrAst, params = {}) {
|
|
@@ -10137,13 +10583,9 @@ const assertNormalExpression = {
|
|
|
10137
10583
|
}
|
|
10138
10584
|
message ??= '';
|
|
10139
10585
|
assertFunctionLike(func, sourceCodeInfo);
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
}
|
|
10143
|
-
catch {
|
|
10144
|
-
return null;
|
|
10145
|
-
}
|
|
10146
|
-
throw new AssertionError(`Expected function to throw.${message}`, sourceCodeInfo);
|
|
10586
|
+
return tryCatch(() => chain(executeFunction(func, [], contextStack, sourceCodeInfo), () => {
|
|
10587
|
+
throw new AssertionError(`Expected function to throw.${message}`, sourceCodeInfo);
|
|
10588
|
+
}), () => null);
|
|
10147
10589
|
},
|
|
10148
10590
|
arity: { min: 1, max: 2 },
|
|
10149
10591
|
},
|
|
@@ -10156,17 +10598,15 @@ const assertNormalExpression = {
|
|
|
10156
10598
|
message ??= '';
|
|
10157
10599
|
assertString(throwMessage, sourceCodeInfo);
|
|
10158
10600
|
assertFunctionLike(func, sourceCodeInfo);
|
|
10159
|
-
|
|
10160
|
-
|
|
10161
|
-
}
|
|
10162
|
-
catch (error) {
|
|
10601
|
+
return tryCatch(() => chain(executeFunction(func, [], contextStack, sourceCodeInfo), () => {
|
|
10602
|
+
throw new AssertionError(`Expected function to throw "${throwMessage}".${message}`, sourceCodeInfo);
|
|
10603
|
+
}), (error) => {
|
|
10163
10604
|
const errorMessage = error.shortMessage;
|
|
10164
10605
|
if (errorMessage !== throwMessage) {
|
|
10165
10606
|
throw new AssertionError(`Expected function to throw "${throwMessage}", but thrown "${errorMessage}".${message}`, sourceCodeInfo);
|
|
10166
10607
|
}
|
|
10167
10608
|
return null;
|
|
10168
|
-
}
|
|
10169
|
-
throw new AssertionError(`Expected function to throw "${throwMessage}".${message}`, sourceCodeInfo);
|
|
10609
|
+
});
|
|
10170
10610
|
},
|
|
10171
10611
|
arity: { min: 2, max: 3 },
|
|
10172
10612
|
},
|
|
@@ -10178,13 +10618,9 @@ const assertNormalExpression = {
|
|
|
10178
10618
|
}
|
|
10179
10619
|
message ??= '';
|
|
10180
10620
|
assertFunctionLike(func, sourceCodeInfo);
|
|
10181
|
-
|
|
10182
|
-
executeFunction(func, [], contextStack, sourceCodeInfo);
|
|
10183
|
-
}
|
|
10184
|
-
catch {
|
|
10621
|
+
return tryCatch(() => chain(executeFunction(func, [], contextStack, sourceCodeInfo), () => null), () => {
|
|
10185
10622
|
throw new AssertionError(`Expected function not to throw.${message}`, sourceCodeInfo);
|
|
10186
|
-
}
|
|
10187
|
-
return null;
|
|
10623
|
+
});
|
|
10188
10624
|
},
|
|
10189
10625
|
arity: { min: 1, max: 2 },
|
|
10190
10626
|
},
|
|
@@ -11572,14 +12008,13 @@ const gridFunctions = {
|
|
|
11572
12008
|
evaluate: ([grid, predicate], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
11573
12009
|
assertGrid(grid, sourceCodeInfo);
|
|
11574
12010
|
assertFunctionLike(predicate, sourceCodeInfo);
|
|
12011
|
+
const cells = [];
|
|
11575
12012
|
for (const row of grid) {
|
|
11576
12013
|
for (const cell of row) {
|
|
11577
|
-
|
|
11578
|
-
return false;
|
|
11579
|
-
}
|
|
12014
|
+
cells.push(cell);
|
|
11580
12015
|
}
|
|
11581
12016
|
}
|
|
11582
|
-
return
|
|
12017
|
+
return everySequential(cells, cell => executeFunction(predicate, [cell], contextStack, sourceCodeInfo));
|
|
11583
12018
|
},
|
|
11584
12019
|
arity: toFixedArity(2),
|
|
11585
12020
|
},
|
|
@@ -11587,14 +12022,13 @@ const gridFunctions = {
|
|
|
11587
12022
|
evaluate: ([grid, predicate], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
11588
12023
|
assertGrid(grid, sourceCodeInfo);
|
|
11589
12024
|
assertFunctionLike(predicate, sourceCodeInfo);
|
|
12025
|
+
const cells = [];
|
|
11590
12026
|
for (const row of grid) {
|
|
11591
12027
|
for (const cell of row) {
|
|
11592
|
-
|
|
11593
|
-
return true;
|
|
11594
|
-
}
|
|
12028
|
+
cells.push(cell);
|
|
11595
12029
|
}
|
|
11596
12030
|
}
|
|
11597
|
-
return
|
|
12031
|
+
return someSequential(cells, cell => executeFunction(predicate, [cell], contextStack, sourceCodeInfo));
|
|
11598
12032
|
},
|
|
11599
12033
|
arity: toFixedArity(2),
|
|
11600
12034
|
},
|
|
@@ -11602,12 +12036,7 @@ const gridFunctions = {
|
|
|
11602
12036
|
evaluate: ([grid, predicate], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
11603
12037
|
assertGrid(grid, sourceCodeInfo);
|
|
11604
12038
|
assertFunctionLike(predicate, sourceCodeInfo);
|
|
11605
|
-
|
|
11606
|
-
if (!executeFunction(predicate, [row], contextStack, sourceCodeInfo)) {
|
|
11607
|
-
return false;
|
|
11608
|
-
}
|
|
11609
|
-
}
|
|
11610
|
-
return true;
|
|
12039
|
+
return everySequential(Array.from(grid), row => executeFunction(predicate, [row], contextStack, sourceCodeInfo));
|
|
11611
12040
|
},
|
|
11612
12041
|
arity: toFixedArity(2),
|
|
11613
12042
|
},
|
|
@@ -11615,12 +12044,7 @@ const gridFunctions = {
|
|
|
11615
12044
|
evaluate: ([grid, predicate], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
11616
12045
|
assertGrid(grid, sourceCodeInfo);
|
|
11617
12046
|
assertFunctionLike(predicate, sourceCodeInfo);
|
|
11618
|
-
|
|
11619
|
-
if (executeFunction(predicate, [row], contextStack, sourceCodeInfo)) {
|
|
11620
|
-
return true;
|
|
11621
|
-
}
|
|
11622
|
-
}
|
|
11623
|
-
return false;
|
|
12047
|
+
return someSequential(Array.from(grid), row => executeFunction(predicate, [row], contextStack, sourceCodeInfo));
|
|
11624
12048
|
},
|
|
11625
12049
|
arity: toFixedArity(2),
|
|
11626
12050
|
},
|
|
@@ -11629,12 +12053,7 @@ const gridFunctions = {
|
|
|
11629
12053
|
assertGrid(grid, sourceCodeInfo);
|
|
11630
12054
|
assertFunctionLike(predicate, sourceCodeInfo);
|
|
11631
12055
|
const transposed = transpose(grid);
|
|
11632
|
-
|
|
11633
|
-
if (!executeFunction(predicate, [row], contextStack, sourceCodeInfo)) {
|
|
11634
|
-
return false;
|
|
11635
|
-
}
|
|
11636
|
-
}
|
|
11637
|
-
return true;
|
|
12056
|
+
return everySequential(Array.from(transposed), row => executeFunction(predicate, [row], contextStack, sourceCodeInfo));
|
|
11638
12057
|
},
|
|
11639
12058
|
arity: toFixedArity(2),
|
|
11640
12059
|
},
|
|
@@ -11643,12 +12062,7 @@ const gridFunctions = {
|
|
|
11643
12062
|
assertGrid(grid, sourceCodeInfo);
|
|
11644
12063
|
assertFunctionLike(predicate, sourceCodeInfo);
|
|
11645
12064
|
const transposed = transpose(grid);
|
|
11646
|
-
|
|
11647
|
-
if (executeFunction(predicate, [row], contextStack, sourceCodeInfo)) {
|
|
11648
|
-
return true;
|
|
11649
|
-
}
|
|
11650
|
-
}
|
|
11651
|
-
return false;
|
|
12065
|
+
return someSequential(Array.from(transposed), row => executeFunction(predicate, [row], contextStack, sourceCodeInfo));
|
|
11652
12066
|
},
|
|
11653
12067
|
arity: toFixedArity(2),
|
|
11654
12068
|
},
|
|
@@ -11697,17 +12111,14 @@ const gridFunctions = {
|
|
|
11697
12111
|
assertNumber(rows, sourceCodeInfo, { integer: true, positive: true });
|
|
11698
12112
|
assertNumber(cols, sourceCodeInfo, { integer: true, positive: true });
|
|
11699
12113
|
assertFunctionLike(generator, sourceCodeInfo);
|
|
11700
|
-
|
|
11701
|
-
|
|
11702
|
-
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
|
|
11706
|
-
|
|
11707
|
-
|
|
11708
|
-
result.push(row);
|
|
11709
|
-
}
|
|
11710
|
-
return result;
|
|
12114
|
+
return mapSequential(Array.from({ length: rows }), (_, i) => {
|
|
12115
|
+
return mapSequential(Array.from({ length: cols }), (__, j) => {
|
|
12116
|
+
return chain(executeFunction(generator, [i, j], contextStack, sourceCodeInfo), (value) => {
|
|
12117
|
+
assertAny(value, sourceCodeInfo);
|
|
12118
|
+
return value;
|
|
12119
|
+
});
|
|
12120
|
+
});
|
|
12121
|
+
});
|
|
11711
12122
|
},
|
|
11712
12123
|
arity: toFixedArity(3),
|
|
11713
12124
|
},
|
|
@@ -11994,16 +12405,12 @@ const gridFunctions = {
|
|
|
11994
12405
|
throw new LitsError(`All grids must have the same number of columns, but got ${cols} and ${grid[0].length}`, sourceCodeInfo);
|
|
11995
12406
|
}
|
|
11996
12407
|
});
|
|
11997
|
-
|
|
11998
|
-
|
|
11999
|
-
const row = [];
|
|
12000
|
-
for (let j = 0; j < cols; j += 1) {
|
|
12408
|
+
return mapSequential(Array.from({ length: rows }), (_, i) => {
|
|
12409
|
+
return mapSequential(Array.from({ length: cols }), (__, j) => {
|
|
12001
12410
|
const args = grids.map(grid => grid[i][j]);
|
|
12002
|
-
|
|
12003
|
-
}
|
|
12004
|
-
|
|
12005
|
-
}
|
|
12006
|
-
return result;
|
|
12411
|
+
return chain(executeFunction(fn, args, contextStack, sourceCodeInfo), val => asAny(val));
|
|
12412
|
+
});
|
|
12413
|
+
});
|
|
12007
12414
|
},
|
|
12008
12415
|
arity: { min: 2 },
|
|
12009
12416
|
},
|
|
@@ -12013,15 +12420,11 @@ const gridFunctions = {
|
|
|
12013
12420
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
12014
12421
|
const rows = grid.length;
|
|
12015
12422
|
const cols = grid[0].length;
|
|
12016
|
-
|
|
12017
|
-
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
}
|
|
12022
|
-
result.push(row);
|
|
12023
|
-
}
|
|
12024
|
-
return result;
|
|
12423
|
+
return mapSequential(Array.from({ length: rows }), (_, i) => {
|
|
12424
|
+
return mapSequential(Array.from({ length: cols }), (__, j) => {
|
|
12425
|
+
return chain(executeFunction(fn, [grid[i][j], i, j], contextStack, sourceCodeInfo), val => asAny(val));
|
|
12426
|
+
});
|
|
12427
|
+
});
|
|
12025
12428
|
},
|
|
12026
12429
|
arity: toFixedArity(2),
|
|
12027
12430
|
},
|
|
@@ -12029,13 +12432,13 @@ const gridFunctions = {
|
|
|
12029
12432
|
evaluate: ([grid, fn, initialValue], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
12030
12433
|
assertGrid(grid, sourceCodeInfo);
|
|
12031
12434
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
12032
|
-
|
|
12435
|
+
const cells = [];
|
|
12033
12436
|
for (const row of grid) {
|
|
12034
12437
|
for (const cell of row) {
|
|
12035
|
-
|
|
12438
|
+
cells.push(cell);
|
|
12036
12439
|
}
|
|
12037
12440
|
}
|
|
12038
|
-
return accumulator;
|
|
12441
|
+
return reduceSequential(cells, (accumulator, cell) => executeFunction(fn, [accumulator, cell], contextStack, sourceCodeInfo), asAny(initialValue));
|
|
12039
12442
|
},
|
|
12040
12443
|
arity: toFixedArity(3),
|
|
12041
12444
|
},
|
|
@@ -12043,13 +12446,13 @@ const gridFunctions = {
|
|
|
12043
12446
|
evaluate: ([grid, fn, initialValue], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
12044
12447
|
assertGrid(grid, sourceCodeInfo);
|
|
12045
12448
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
12046
|
-
|
|
12449
|
+
const cells = [];
|
|
12047
12450
|
for (let i = 0; i < grid.length; i += 1) {
|
|
12048
12451
|
for (let j = 0; j < grid[i].length; j += 1) {
|
|
12049
|
-
|
|
12452
|
+
cells.push({ cell: grid[i][j], i, j });
|
|
12050
12453
|
}
|
|
12051
12454
|
}
|
|
12052
|
-
return accumulator;
|
|
12455
|
+
return reduceSequential(cells, (accumulator, { cell, i, j }) => executeFunction(fn, [accumulator, cell, i, j], contextStack, sourceCodeInfo), asAny(initialValue));
|
|
12053
12456
|
},
|
|
12054
12457
|
arity: toFixedArity(3),
|
|
12055
12458
|
},
|
|
@@ -18165,10 +18568,11 @@ const vectorFunctions = {
|
|
|
18165
18568
|
evaluate: ([length, generator], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
18166
18569
|
assertNumber(length, sourceCodeInfo, { integer: true, nonNegative: true });
|
|
18167
18570
|
assertFunctionLike(generator, sourceCodeInfo);
|
|
18168
|
-
return Array.from({ length }, (_, i) => {
|
|
18169
|
-
|
|
18170
|
-
|
|
18171
|
-
|
|
18571
|
+
return mapSequential(Array.from({ length }), (_, i) => {
|
|
18572
|
+
return chain(executeFunction(generator, [i], contextStack, sourceCodeInfo), (value) => {
|
|
18573
|
+
assertNumber(value, sourceCodeInfo, { finite: true });
|
|
18574
|
+
return value;
|
|
18575
|
+
});
|
|
18172
18576
|
});
|
|
18173
18577
|
},
|
|
18174
18578
|
arity: toFixedArity(2),
|
|
@@ -26799,16 +27203,17 @@ const abundantSequence = {
|
|
|
26799
27203
|
'abundant?': n => isAbundant(n),
|
|
26800
27204
|
'abundant-take-while': (takeWhile) => {
|
|
26801
27205
|
const abundants = [];
|
|
26802
|
-
|
|
26803
|
-
if (!isAbundant(i))
|
|
26804
|
-
|
|
26805
|
-
|
|
26806
|
-
|
|
26807
|
-
|
|
26808
|
-
|
|
26809
|
-
|
|
27206
|
+
function loop(i) {
|
|
27207
|
+
if (!isAbundant(i))
|
|
27208
|
+
return loop(i + 1);
|
|
27209
|
+
return chain(takeWhile(i, abundants.length), (keep) => {
|
|
27210
|
+
if (!keep)
|
|
27211
|
+
return abundants;
|
|
27212
|
+
abundants.push(i);
|
|
27213
|
+
return loop(i + 1);
|
|
27214
|
+
});
|
|
26810
27215
|
}
|
|
26811
|
-
return
|
|
27216
|
+
return loop(2);
|
|
26812
27217
|
},
|
|
26813
27218
|
};
|
|
26814
27219
|
|
|
@@ -26853,15 +27258,20 @@ const arithmeticNormalExpressions = {
|
|
|
26853
27258
|
assertNumber(start, sourceCodeInfo, { finite: true });
|
|
26854
27259
|
assertNumber(step, sourceCodeInfo, { finite: true });
|
|
26855
27260
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
27261
|
+
const s = start;
|
|
27262
|
+
const d = step;
|
|
27263
|
+
const f = fn;
|
|
26856
27264
|
const arithmetic = [];
|
|
26857
|
-
|
|
26858
|
-
const value =
|
|
26859
|
-
|
|
26860
|
-
|
|
26861
|
-
|
|
26862
|
-
|
|
27265
|
+
function loop(i) {
|
|
27266
|
+
const value = s + i * d;
|
|
27267
|
+
return chain(executeFunction(f, [value, i], contextStack, sourceCodeInfo), (keep) => {
|
|
27268
|
+
if (!keep)
|
|
27269
|
+
return arithmetic;
|
|
27270
|
+
arithmetic.push(value);
|
|
27271
|
+
return loop(i + 1);
|
|
27272
|
+
});
|
|
26863
27273
|
}
|
|
26864
|
-
return
|
|
27274
|
+
return loop(0);
|
|
26865
27275
|
},
|
|
26866
27276
|
arity: toFixedArity(3),
|
|
26867
27277
|
},
|
|
@@ -26927,28 +27337,21 @@ function getBernoulliSeq(length) {
|
|
|
26927
27337
|
* @returns Array of Bernoulli numbers generated until predicate returns false
|
|
26928
27338
|
*/
|
|
26929
27339
|
function generateBernoulli(predicate) {
|
|
26930
|
-
const batchSize = 100;
|
|
26931
|
-
// Start with computing the Bernoulli numbers
|
|
26932
27340
|
const bernoulli = [1];
|
|
26933
|
-
|
|
26934
|
-
|
|
26935
|
-
|
|
26936
|
-
|
|
26937
|
-
|
|
26938
|
-
|
|
26939
|
-
|
|
26940
|
-
|
|
26941
|
-
sum += binomialCoefficient(n + 1, k) * bernoulli[k];
|
|
26942
|
-
}
|
|
26943
|
-
const newValue = n > 1 && n % 2 === 1 ? 0 : -sum / (n + 1);
|
|
26944
|
-
// Check if we should continue
|
|
26945
|
-
if (!predicate(newValue, n)) {
|
|
26946
|
-
// We're done, return the generated sequence (including the last value)
|
|
27341
|
+
function loop(n) {
|
|
27342
|
+
let sum = 0;
|
|
27343
|
+
for (let k = 0; k < n; k++) {
|
|
27344
|
+
sum += binomialCoefficient(n + 1, k) * bernoulli[k];
|
|
27345
|
+
}
|
|
27346
|
+
const newValue = n > 1 && n % 2 === 1 ? 0 : -sum / (n + 1);
|
|
27347
|
+
return chain(predicate(newValue, n), (keep) => {
|
|
27348
|
+
if (!keep)
|
|
26947
27349
|
return bernoulli;
|
|
26948
|
-
}
|
|
26949
27350
|
bernoulli.push(newValue);
|
|
26950
|
-
|
|
27351
|
+
return loop(n + 1);
|
|
27352
|
+
});
|
|
26951
27353
|
}
|
|
27354
|
+
return loop(1);
|
|
26952
27355
|
}
|
|
26953
27356
|
const bernoulliNormalExpressions = {
|
|
26954
27357
|
'bernoulli-seq': {
|
|
@@ -26969,8 +27372,8 @@ const bernoulliNormalExpressions = {
|
|
|
26969
27372
|
'bernoulli-take-while': {
|
|
26970
27373
|
evaluate: ([fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
26971
27374
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
26972
|
-
const
|
|
26973
|
-
return
|
|
27375
|
+
const f = fn;
|
|
27376
|
+
return generateBernoulli((value, index) => chain(executeFunction(f, [value, index], contextStack), val => !!val));
|
|
26974
27377
|
},
|
|
26975
27378
|
arity: toFixedArity(1),
|
|
26976
27379
|
},
|
|
@@ -27059,16 +27462,17 @@ const primeSequence = {
|
|
|
27059
27462
|
'prime?': n => isPrime(n),
|
|
27060
27463
|
'prime-take-while': (takeWhile) => {
|
|
27061
27464
|
const primes = [];
|
|
27062
|
-
|
|
27063
|
-
if (!isPrime(i))
|
|
27064
|
-
|
|
27065
|
-
|
|
27066
|
-
|
|
27067
|
-
|
|
27068
|
-
|
|
27069
|
-
|
|
27465
|
+
function loop(i) {
|
|
27466
|
+
if (!isPrime(i))
|
|
27467
|
+
return loop(i + 1);
|
|
27468
|
+
return chain(takeWhile(i, primes.length), (keep) => {
|
|
27469
|
+
if (!keep)
|
|
27470
|
+
return primes;
|
|
27471
|
+
primes.push(i);
|
|
27472
|
+
return loop(i + 1);
|
|
27473
|
+
});
|
|
27070
27474
|
}
|
|
27071
|
-
return
|
|
27475
|
+
return loop(2);
|
|
27072
27476
|
},
|
|
27073
27477
|
};
|
|
27074
27478
|
|
|
@@ -27093,16 +27497,17 @@ const compositeSequence = {
|
|
|
27093
27497
|
'composite?': n => isComposite(n),
|
|
27094
27498
|
'composite-take-while': (takeWhile) => {
|
|
27095
27499
|
const composites = [];
|
|
27096
|
-
|
|
27097
|
-
if (!isComposite(i))
|
|
27098
|
-
|
|
27099
|
-
|
|
27100
|
-
|
|
27101
|
-
|
|
27102
|
-
|
|
27103
|
-
|
|
27500
|
+
function loop(i) {
|
|
27501
|
+
if (!isComposite(i))
|
|
27502
|
+
return loop(i + 1);
|
|
27503
|
+
return chain(takeWhile(i, composites.length), (keep) => {
|
|
27504
|
+
if (!keep)
|
|
27505
|
+
return composites;
|
|
27506
|
+
composites.push(i);
|
|
27507
|
+
return loop(i + 1);
|
|
27508
|
+
});
|
|
27104
27509
|
}
|
|
27105
|
-
return
|
|
27510
|
+
return loop(4);
|
|
27106
27511
|
},
|
|
27107
27512
|
};
|
|
27108
27513
|
|
|
@@ -27126,16 +27531,17 @@ const deficientSequence = {
|
|
|
27126
27531
|
'deficient?': n => isDeficient(n),
|
|
27127
27532
|
'deficient-take-while': (takeWhile) => {
|
|
27128
27533
|
const deficients = [];
|
|
27129
|
-
|
|
27130
|
-
if (!isDeficient(i))
|
|
27131
|
-
|
|
27132
|
-
|
|
27133
|
-
|
|
27134
|
-
|
|
27135
|
-
|
|
27136
|
-
|
|
27534
|
+
function loop(i) {
|
|
27535
|
+
if (!isDeficient(i))
|
|
27536
|
+
return loop(i + 1);
|
|
27537
|
+
return chain(takeWhile(i, deficients.length), (keep) => {
|
|
27538
|
+
if (!keep)
|
|
27539
|
+
return deficients;
|
|
27540
|
+
deficients.push(i);
|
|
27541
|
+
return loop(i + 1);
|
|
27542
|
+
});
|
|
27137
27543
|
}
|
|
27138
|
-
return
|
|
27544
|
+
return loop(1);
|
|
27139
27545
|
},
|
|
27140
27546
|
};
|
|
27141
27547
|
|
|
@@ -27295,15 +27701,20 @@ const geometricNormalExpressions = {
|
|
|
27295
27701
|
assertNumber(start, sourceCodeInfo, { finite: true });
|
|
27296
27702
|
assertNumber(ratio, sourceCodeInfo, { finite: true });
|
|
27297
27703
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
27704
|
+
const s = start;
|
|
27705
|
+
const r = ratio;
|
|
27706
|
+
const f = fn;
|
|
27298
27707
|
const geometric = [];
|
|
27299
|
-
|
|
27300
|
-
const value =
|
|
27301
|
-
|
|
27302
|
-
|
|
27303
|
-
|
|
27304
|
-
|
|
27708
|
+
function loop(i) {
|
|
27709
|
+
const value = s * r ** i;
|
|
27710
|
+
return chain(executeFunction(f, [value, i], contextStack, sourceCodeInfo), (keep) => {
|
|
27711
|
+
if (!keep)
|
|
27712
|
+
return geometric;
|
|
27713
|
+
geometric.push(value);
|
|
27714
|
+
return loop(i + 1);
|
|
27715
|
+
});
|
|
27305
27716
|
}
|
|
27306
|
-
return
|
|
27717
|
+
return loop(0);
|
|
27307
27718
|
},
|
|
27308
27719
|
arity: toFixedArity(3),
|
|
27309
27720
|
},
|
|
@@ -27335,18 +27746,21 @@ function getGolombSeq(n) {
|
|
|
27335
27746
|
return golomb.slice(1);
|
|
27336
27747
|
}
|
|
27337
27748
|
function generateGolombSeq(pred) {
|
|
27338
|
-
if (!pred(1, 0)) {
|
|
27339
|
-
return [];
|
|
27340
|
-
}
|
|
27341
27749
|
const golomb = [0, 1];
|
|
27342
|
-
|
|
27343
|
-
|
|
27344
|
-
|
|
27345
|
-
|
|
27750
|
+
return chain(pred(1, 0), (keepFirst) => {
|
|
27751
|
+
if (!keepFirst)
|
|
27752
|
+
return [];
|
|
27753
|
+
function loop(i) {
|
|
27754
|
+
const golombNumber = 1 + golomb[i - golomb[golomb[i - 1]]];
|
|
27755
|
+
return chain(pred(golombNumber, i - 1), (keep) => {
|
|
27756
|
+
if (!keep)
|
|
27757
|
+
return golomb.slice(1);
|
|
27758
|
+
golomb.push(golombNumber);
|
|
27759
|
+
return loop(i + 1);
|
|
27760
|
+
});
|
|
27346
27761
|
}
|
|
27347
|
-
|
|
27348
|
-
}
|
|
27349
|
-
return golomb.slice(1);
|
|
27762
|
+
return loop(2);
|
|
27763
|
+
});
|
|
27350
27764
|
}
|
|
27351
27765
|
const golombSequence = {
|
|
27352
27766
|
'golomb-seq': length => getGolombSeq(length),
|
|
@@ -27401,23 +27815,17 @@ const happySequence = {
|
|
|
27401
27815
|
'happy?': n => isHappyNumber(n),
|
|
27402
27816
|
'happy-take-while': (takeWhile) => {
|
|
27403
27817
|
const happyNumbers = [];
|
|
27404
|
-
|
|
27405
|
-
|
|
27406
|
-
|
|
27407
|
-
|
|
27408
|
-
|
|
27409
|
-
|
|
27410
|
-
.split('')
|
|
27411
|
-
.reduce((sum, digit) => sum + Number(digit) ** 2, 0);
|
|
27412
|
-
}
|
|
27413
|
-
if (n === 1) {
|
|
27414
|
-
if (!takeWhile(i, happyNumbers.length)) {
|
|
27415
|
-
break;
|
|
27416
|
-
}
|
|
27818
|
+
function loop(i) {
|
|
27819
|
+
if (!isHappyNumber(i))
|
|
27820
|
+
return loop(i + 1);
|
|
27821
|
+
return chain(takeWhile(i, happyNumbers.length), (keep) => {
|
|
27822
|
+
if (!keep)
|
|
27823
|
+
return happyNumbers;
|
|
27417
27824
|
happyNumbers.push(i);
|
|
27418
|
-
|
|
27825
|
+
return loop(i + 1);
|
|
27826
|
+
});
|
|
27419
27827
|
}
|
|
27420
|
-
return
|
|
27828
|
+
return loop(1);
|
|
27421
27829
|
},
|
|
27422
27830
|
};
|
|
27423
27831
|
|
|
@@ -27500,19 +27908,23 @@ const lookAndSaySequence = {
|
|
|
27500
27908
|
return lookAndSay;
|
|
27501
27909
|
},
|
|
27502
27910
|
'look-and-say-take-while': (takeWhile) => {
|
|
27503
|
-
|
|
27504
|
-
|
|
27505
|
-
|
|
27506
|
-
|
|
27507
|
-
|
|
27508
|
-
|
|
27509
|
-
|
|
27510
|
-
|
|
27511
|
-
|
|
27911
|
+
const lookAndSay = [];
|
|
27912
|
+
return chain(takeWhile('1', 0), (keepFirst) => {
|
|
27913
|
+
if (!keepFirst)
|
|
27914
|
+
return lookAndSay;
|
|
27915
|
+
lookAndSay.push('1');
|
|
27916
|
+
function loop(i) {
|
|
27917
|
+
const prev = lookAndSay[i - 1];
|
|
27918
|
+
const next = prev.replace(/(\d)\1*/g, match => `${match.length}${match[0]}`);
|
|
27919
|
+
return chain(takeWhile(next, i), (keep) => {
|
|
27920
|
+
if (!keep)
|
|
27921
|
+
return lookAndSay;
|
|
27922
|
+
lookAndSay.push(next);
|
|
27923
|
+
return loop(i + 1);
|
|
27924
|
+
});
|
|
27512
27925
|
}
|
|
27513
|
-
|
|
27514
|
-
}
|
|
27515
|
-
return lookAndSay;
|
|
27926
|
+
return loop(1);
|
|
27927
|
+
});
|
|
27516
27928
|
},
|
|
27517
27929
|
'look-and-say?': n => isLookAndSay(n),
|
|
27518
27930
|
};
|
|
@@ -27620,42 +28032,45 @@ function generateLuckyNumbers(predicate) {
|
|
|
27620
28032
|
const luckyNumbers = [1]; // 1 is always the first lucky number
|
|
27621
28033
|
let count = 1;
|
|
27622
28034
|
// Check if we should continue after the first number
|
|
27623
|
-
|
|
27624
|
-
|
|
27625
|
-
|
|
27626
|
-
|
|
27627
|
-
|
|
27628
|
-
|
|
27629
|
-
|
|
27630
|
-
|
|
27631
|
-
|
|
27632
|
-
|
|
27633
|
-
|
|
27634
|
-
|
|
27635
|
-
|
|
27636
|
-
|
|
27637
|
-
|
|
27638
|
-
|
|
27639
|
-
|
|
27640
|
-
|
|
27641
|
-
|
|
27642
|
-
|
|
27643
|
-
|
|
27644
|
-
|
|
27645
|
-
|
|
27646
|
-
|
|
27647
|
-
|
|
27648
|
-
|
|
27649
|
-
|
|
27650
|
-
|
|
27651
|
-
|
|
27652
|
-
|
|
27653
|
-
|
|
27654
|
-
|
|
27655
|
-
|
|
28035
|
+
return chain(predicate(1, 0), (keepFirst) => {
|
|
28036
|
+
if (!keepFirst)
|
|
28037
|
+
return [];
|
|
28038
|
+
// Continue the sieve process
|
|
28039
|
+
let index = 1; // Start with the second element (index 1, which is 3)
|
|
28040
|
+
function loop() {
|
|
28041
|
+
// Get the current lucky number
|
|
28042
|
+
const luckyNumber = filteredNumbers[index];
|
|
28043
|
+
// Check if we should continue
|
|
28044
|
+
return chain(predicate(luckyNumber, count), (keep) => {
|
|
28045
|
+
if (!keep)
|
|
28046
|
+
return luckyNumbers;
|
|
28047
|
+
// Add to result
|
|
28048
|
+
luckyNumbers.push(luckyNumber);
|
|
28049
|
+
count++;
|
|
28050
|
+
// Apply the sieve
|
|
28051
|
+
const step = luckyNumber;
|
|
28052
|
+
const newFiltered = [];
|
|
28053
|
+
for (let i = 0; i < filteredNumbers.length; i++) {
|
|
28054
|
+
if ((i + 1) % step !== 0) { // Keep numbers not at positions divisible by step
|
|
28055
|
+
newFiltered.push(filteredNumbers[i]);
|
|
28056
|
+
}
|
|
28057
|
+
}
|
|
28058
|
+
filteredNumbers = newFiltered;
|
|
28059
|
+
index++;
|
|
28060
|
+
// If we're running low on numbers, extend the sequence
|
|
28061
|
+
if (index >= filteredNumbers.length - 5) {
|
|
28062
|
+
const lastNum = filteredNumbers[filteredNumbers.length - 1];
|
|
28063
|
+
let next = lastNum + 2;
|
|
28064
|
+
while (filteredNumbers.length < index + 1000) {
|
|
28065
|
+
filteredNumbers.push(next);
|
|
28066
|
+
next += 2;
|
|
28067
|
+
}
|
|
28068
|
+
}
|
|
28069
|
+
return loop();
|
|
28070
|
+
});
|
|
27656
28071
|
}
|
|
27657
|
-
|
|
27658
|
-
|
|
28072
|
+
return loop();
|
|
28073
|
+
});
|
|
27659
28074
|
}
|
|
27660
28075
|
/**
|
|
27661
28076
|
* Generates lucky numbers up to a specified length or count
|
|
@@ -27818,32 +28233,37 @@ const padovanSequence = {
|
|
|
27818
28233
|
'padovan?': n => isPadovan(n),
|
|
27819
28234
|
'padovan-take-while': (takeWhile) => {
|
|
27820
28235
|
const padovan = [];
|
|
27821
|
-
|
|
27822
|
-
|
|
27823
|
-
|
|
27824
|
-
|
|
27825
|
-
|
|
27826
|
-
|
|
27827
|
-
|
|
27828
|
-
|
|
27829
|
-
|
|
27830
|
-
|
|
27831
|
-
|
|
27832
|
-
|
|
27833
|
-
|
|
27834
|
-
|
|
27835
|
-
|
|
27836
|
-
|
|
27837
|
-
|
|
27838
|
-
|
|
27839
|
-
|
|
27840
|
-
|
|
27841
|
-
|
|
27842
|
-
|
|
27843
|
-
|
|
27844
|
-
|
|
27845
|
-
|
|
27846
|
-
|
|
28236
|
+
return chain(takeWhile(1, 0), (keep0) => {
|
|
28237
|
+
if (!keep0)
|
|
28238
|
+
return padovan;
|
|
28239
|
+
padovan.push(1);
|
|
28240
|
+
return chain(takeWhile(1, 1), (keep1) => {
|
|
28241
|
+
if (!keep1)
|
|
28242
|
+
return padovan;
|
|
28243
|
+
padovan.push(1);
|
|
28244
|
+
return chain(takeWhile(1, 2), (keep2) => {
|
|
28245
|
+
if (!keep2)
|
|
28246
|
+
return padovan;
|
|
28247
|
+
padovan.push(1);
|
|
28248
|
+
let a = 1;
|
|
28249
|
+
let b = 1;
|
|
28250
|
+
let c = 1;
|
|
28251
|
+
function loop(i) {
|
|
28252
|
+
const temp = a + b;
|
|
28253
|
+
a = b;
|
|
28254
|
+
b = c;
|
|
28255
|
+
c = temp;
|
|
28256
|
+
return chain(takeWhile(c, i), (keep) => {
|
|
28257
|
+
if (!keep)
|
|
28258
|
+
return padovan;
|
|
28259
|
+
padovan.push(c);
|
|
28260
|
+
return loop(i + 1);
|
|
28261
|
+
});
|
|
28262
|
+
}
|
|
28263
|
+
return loop(4);
|
|
28264
|
+
});
|
|
28265
|
+
});
|
|
28266
|
+
});
|
|
27847
28267
|
},
|
|
27848
28268
|
};
|
|
27849
28269
|
|
|
@@ -27905,14 +28325,16 @@ const perfectCubeSequence = {
|
|
|
27905
28325
|
'perfect-cube?': n => n > 0 && Number.isInteger(Math.cbrt(n)),
|
|
27906
28326
|
'perfect-cube-take-while': (takeWhile) => {
|
|
27907
28327
|
const perfectcubes = [];
|
|
27908
|
-
|
|
28328
|
+
function loop(i) {
|
|
27909
28329
|
const value = i ** 3;
|
|
27910
|
-
|
|
27911
|
-
|
|
27912
|
-
|
|
27913
|
-
|
|
28330
|
+
return chain(takeWhile(value, i), (keep) => {
|
|
28331
|
+
if (!keep)
|
|
28332
|
+
return perfectcubes;
|
|
28333
|
+
perfectcubes.push(value);
|
|
28334
|
+
return loop(i + 1);
|
|
28335
|
+
});
|
|
27914
28336
|
}
|
|
27915
|
-
return
|
|
28337
|
+
return loop(1);
|
|
27916
28338
|
},
|
|
27917
28339
|
};
|
|
27918
28340
|
|
|
@@ -27957,15 +28379,17 @@ const perfectPowerSequence = {
|
|
|
27957
28379
|
'perfect-power?': n => perfectPower(n) !== null,
|
|
27958
28380
|
'perfect-power-take-while': (takeWhile) => {
|
|
27959
28381
|
const perfectPowers = [];
|
|
27960
|
-
|
|
27961
|
-
if (perfectPower(i))
|
|
27962
|
-
|
|
27963
|
-
|
|
27964
|
-
|
|
28382
|
+
function loop(i) {
|
|
28383
|
+
if (!perfectPower(i))
|
|
28384
|
+
return loop(i + 1);
|
|
28385
|
+
return chain(takeWhile(i, perfectPowers.length), (keep) => {
|
|
28386
|
+
if (!keep)
|
|
28387
|
+
return perfectPowers;
|
|
27965
28388
|
perfectPowers.push(i);
|
|
27966
|
-
|
|
28389
|
+
return loop(i + 1);
|
|
28390
|
+
});
|
|
27967
28391
|
}
|
|
27968
|
-
return
|
|
28392
|
+
return loop(1);
|
|
27969
28393
|
},
|
|
27970
28394
|
};
|
|
27971
28395
|
|
|
@@ -27980,14 +28404,16 @@ const perfectSquareSequence = {
|
|
|
27980
28404
|
'perfect-square?': n => n > 0 && Number.isInteger(Math.sqrt(n)),
|
|
27981
28405
|
'perfect-square-take-while': (takeWhile) => {
|
|
27982
28406
|
const perfectSquares = [];
|
|
27983
|
-
|
|
28407
|
+
function loop(i) {
|
|
27984
28408
|
const value = i ** 2;
|
|
27985
|
-
|
|
27986
|
-
|
|
27987
|
-
|
|
27988
|
-
|
|
28409
|
+
return chain(takeWhile(value, i), (keep) => {
|
|
28410
|
+
if (!keep)
|
|
28411
|
+
return perfectSquares;
|
|
28412
|
+
perfectSquares.push(value);
|
|
28413
|
+
return loop(i + 1);
|
|
28414
|
+
});
|
|
27989
28415
|
}
|
|
27990
|
-
return
|
|
28416
|
+
return loop(1);
|
|
27991
28417
|
},
|
|
27992
28418
|
};
|
|
27993
28419
|
|
|
@@ -28008,15 +28434,19 @@ const poligonalNormalExpressions = {
|
|
|
28008
28434
|
evaluate: ([sides, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
28009
28435
|
assertNumber(sides, sourceCodeInfo, { integer: true, gte: 3 });
|
|
28010
28436
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
28437
|
+
const s = sides;
|
|
28438
|
+
const f = fn;
|
|
28011
28439
|
const polygonal = [];
|
|
28012
|
-
|
|
28013
|
-
const value = (i * i * (
|
|
28014
|
-
|
|
28015
|
-
|
|
28016
|
-
|
|
28017
|
-
|
|
28440
|
+
function loop(i) {
|
|
28441
|
+
const value = (i * i * (s - 2) - i * (s - 4)) / 2;
|
|
28442
|
+
return chain(executeFunction(f, [value, i], contextStack, sourceCodeInfo), (keep) => {
|
|
28443
|
+
if (!keep)
|
|
28444
|
+
return polygonal;
|
|
28445
|
+
polygonal.push(value);
|
|
28446
|
+
return loop(i + 1);
|
|
28447
|
+
});
|
|
28018
28448
|
}
|
|
28019
|
-
return
|
|
28449
|
+
return loop(1);
|
|
28020
28450
|
},
|
|
28021
28451
|
arity: toFixedArity(2),
|
|
28022
28452
|
},
|
|
@@ -28080,23 +28510,29 @@ function generateRecamanSequence(n) {
|
|
|
28080
28510
|
const recamanSequence = {
|
|
28081
28511
|
'recaman-seq': length => generateRecamanSequence(length),
|
|
28082
28512
|
'recaman-take-while': (takeWhile) => {
|
|
28083
|
-
|
|
28084
|
-
return [];
|
|
28085
|
-
const sequence = [0];
|
|
28513
|
+
const sequence = [];
|
|
28086
28514
|
const seen = new Set([0]);
|
|
28087
|
-
|
|
28088
|
-
|
|
28089
|
-
|
|
28090
|
-
|
|
28091
|
-
|
|
28092
|
-
|
|
28093
|
-
|
|
28094
|
-
|
|
28095
|
-
|
|
28096
|
-
|
|
28097
|
-
|
|
28098
|
-
|
|
28099
|
-
|
|
28515
|
+
return chain(takeWhile(0, 0), (keepFirst) => {
|
|
28516
|
+
if (!keepFirst)
|
|
28517
|
+
return sequence;
|
|
28518
|
+
sequence.push(0);
|
|
28519
|
+
function loop(i) {
|
|
28520
|
+
// Try to go backward
|
|
28521
|
+
let next = sequence[i - 1] - i;
|
|
28522
|
+
// If that's not positive or already seen, go forward
|
|
28523
|
+
if (next <= 0 || seen.has(next)) {
|
|
28524
|
+
next = sequence[i - 1] + i;
|
|
28525
|
+
}
|
|
28526
|
+
return chain(takeWhile(next, i), (keep) => {
|
|
28527
|
+
if (!keep)
|
|
28528
|
+
return sequence;
|
|
28529
|
+
sequence.push(next);
|
|
28530
|
+
seen.add(next);
|
|
28531
|
+
return loop(i + 1);
|
|
28532
|
+
});
|
|
28533
|
+
}
|
|
28534
|
+
return loop(1);
|
|
28535
|
+
});
|
|
28100
28536
|
},
|
|
28101
28537
|
'recaman?': () => true,
|
|
28102
28538
|
};
|
|
@@ -28120,14 +28556,16 @@ const thueMorseSequence = {
|
|
|
28120
28556
|
},
|
|
28121
28557
|
'thue-morse-take-while': (takeWhile) => {
|
|
28122
28558
|
const thueMorse = [];
|
|
28123
|
-
|
|
28559
|
+
function loop(i) {
|
|
28124
28560
|
const value = countSetBits(i) % 2;
|
|
28125
|
-
|
|
28126
|
-
|
|
28127
|
-
|
|
28128
|
-
|
|
28561
|
+
return chain(takeWhile(value, i), (keep) => {
|
|
28562
|
+
if (!keep)
|
|
28563
|
+
return thueMorse;
|
|
28564
|
+
thueMorse.push(value);
|
|
28565
|
+
return loop(i + 1);
|
|
28566
|
+
});
|
|
28129
28567
|
}
|
|
28130
|
-
return
|
|
28568
|
+
return loop(0);
|
|
28131
28569
|
},
|
|
28132
28570
|
'thue-morse?': n => n === 1 || n === 0,
|
|
28133
28571
|
};
|
|
@@ -28251,16 +28689,16 @@ function getFiniteNumberSequence(name, sequence) {
|
|
|
28251
28689
|
return {
|
|
28252
28690
|
[`${name}-seq`]: createSeqNormalExpression(length => sequence.slice(0, length), sequence.length),
|
|
28253
28691
|
[`${name}-take-while`]: createTakeWhileNormalExpression((takeWhile) => {
|
|
28254
|
-
|
|
28255
|
-
|
|
28256
|
-
|
|
28257
|
-
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
28261
|
-
}
|
|
28692
|
+
function loop(i) {
|
|
28693
|
+
if (i >= sequence.length)
|
|
28694
|
+
return sequence.slice(0, i);
|
|
28695
|
+
return chain(takeWhile(sequence[i], i), (keep) => {
|
|
28696
|
+
if (!keep)
|
|
28697
|
+
return sequence.slice(0, i);
|
|
28698
|
+
return loop(i + 1);
|
|
28699
|
+
});
|
|
28262
28700
|
}
|
|
28263
|
-
return
|
|
28701
|
+
return loop(0);
|
|
28264
28702
|
}, sequence.length),
|
|
28265
28703
|
[`${name}-nth`]: createNthNormalExpression(() => sequence, sequence.length),
|
|
28266
28704
|
[`${name}?`]: createNumberPredNormalExpression(n => sequence.includes(n)),
|
|
@@ -28313,14 +28751,16 @@ function createTakeWhileNormalExpression(takeWhileFunction, maxLength) {
|
|
|
28313
28751
|
evaluate: (params, sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
28314
28752
|
const fn = params[0];
|
|
28315
28753
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
28316
|
-
const result = takeWhileFunction((value, index) =>
|
|
28317
|
-
|
|
28318
|
-
|
|
28319
|
-
|
|
28320
|
-
|
|
28754
|
+
const result = takeWhileFunction((value, index) => chain(executeFunction(fn, [value, index], contextStack), val => !!val), sourceCodeInfo);
|
|
28755
|
+
return chain(result, (resolved) => {
|
|
28756
|
+
if (typeof resolved[0] === 'number') {
|
|
28757
|
+
/* v8 ignore next 3 */
|
|
28758
|
+
if (resolved.some(n => n > Number.MAX_SAFE_INTEGER)) {
|
|
28759
|
+
throw new LitsError('Result exceeds maximum safe integer', sourceCodeInfo);
|
|
28760
|
+
}
|
|
28321
28761
|
}
|
|
28322
|
-
|
|
28323
|
-
|
|
28762
|
+
return resolved;
|
|
28763
|
+
});
|
|
28324
28764
|
},
|
|
28325
28765
|
arity: typeof maxLength === 'number' ? { max: 1 } : toFixedArity(1),
|
|
28326
28766
|
};
|
|
@@ -29789,38 +30229,30 @@ function update(coll, key, fn, params, contextStack, executeFunction, sourceCode
|
|
|
29789
30229
|
if (isObj(coll)) {
|
|
29790
30230
|
assertString(key, sourceCodeInfo);
|
|
29791
30231
|
const result = { ...coll };
|
|
29792
|
-
|
|
29793
|
-
|
|
30232
|
+
return chain(executeFunction(fn, [result[key], ...params], contextStack, sourceCodeInfo), (val) => {
|
|
30233
|
+
result[key] = val;
|
|
30234
|
+
return result;
|
|
30235
|
+
});
|
|
29794
30236
|
}
|
|
29795
30237
|
else {
|
|
29796
30238
|
assertNumber(key, sourceCodeInfo);
|
|
29797
30239
|
const intKey = toNonNegativeInteger(key);
|
|
29798
30240
|
assertNumber(intKey, sourceCodeInfo, { lte: coll.length });
|
|
29799
30241
|
if (Array.isArray(coll)) {
|
|
29800
|
-
|
|
30242
|
+
return chain(mapSequential(Array.from({ length: coll.length + (intKey === coll.length ? 1 : 0) }), (_, index) => {
|
|
29801
30243
|
if (intKey === index)
|
|
29802
|
-
return executeFunction(fn, [
|
|
29803
|
-
return
|
|
29804
|
-
});
|
|
29805
|
-
if (intKey === coll.length)
|
|
29806
|
-
result[intKey] = executeFunction(fn, [undefined, ...params], contextStack, sourceCodeInfo);
|
|
29807
|
-
return result;
|
|
30244
|
+
return executeFunction(fn, [coll[index], ...params], contextStack, sourceCodeInfo);
|
|
30245
|
+
return coll[index];
|
|
30246
|
+
}), result => result);
|
|
29808
30247
|
}
|
|
29809
30248
|
else {
|
|
29810
|
-
const
|
|
30249
|
+
const chars = coll.split('');
|
|
30250
|
+
return chain(mapSequential(Array.from({ length: chars.length + (intKey === chars.length ? 1 : 0) }), (_, index) => {
|
|
29811
30251
|
if (intKey === index) {
|
|
29812
|
-
return
|
|
29813
|
-
char: true,
|
|
29814
|
-
});
|
|
30252
|
+
return chain(executeFunction(fn, [chars[index], ...params], contextStack, sourceCodeInfo), val => asString(val, sourceCodeInfo, { char: true }));
|
|
29815
30253
|
}
|
|
29816
|
-
return
|
|
29817
|
-
});
|
|
29818
|
-
if (intKey === coll.length) {
|
|
29819
|
-
result[intKey] = asString(executeFunction(fn, [undefined, ...params], contextStack, sourceCodeInfo), sourceCodeInfo, {
|
|
29820
|
-
char: true,
|
|
29821
|
-
});
|
|
29822
|
-
}
|
|
29823
|
-
return result.join('');
|
|
30254
|
+
return chars[index];
|
|
30255
|
+
}), result => result.join(''));
|
|
29824
30256
|
}
|
|
29825
30257
|
}
|
|
29826
30258
|
}
|
|
@@ -30025,13 +30457,18 @@ cu.update(
|
|
|
30025
30457
|
const parentKey = asStringOrNumber(keys[keys.length - 2], sourceCodeInfo);
|
|
30026
30458
|
if (Array.isArray(innerCollMeta.parent)) {
|
|
30027
30459
|
assertNumber(parentKey, sourceCodeInfo);
|
|
30028
|
-
|
|
30460
|
+
return chain(update(innerCollMeta.coll, lastKey, fn, params, contextStack, executeFunction, sourceCodeInfo), (updated) => {
|
|
30461
|
+
innerCollMeta.parent[parentKey] = updated;
|
|
30462
|
+
return coll;
|
|
30463
|
+
});
|
|
30029
30464
|
}
|
|
30030
30465
|
else {
|
|
30031
30466
|
assertString(parentKey, sourceCodeInfo);
|
|
30032
|
-
|
|
30467
|
+
return chain(update(innerCollMeta.coll, lastKey, fn, params, contextStack, executeFunction, sourceCodeInfo), (updated) => {
|
|
30468
|
+
innerCollMeta.parent[parentKey] = updated;
|
|
30469
|
+
return coll;
|
|
30470
|
+
});
|
|
30033
30471
|
}
|
|
30034
|
-
return coll;
|
|
30035
30472
|
},
|
|
30036
30473
|
arity: { min: 3 },
|
|
30037
30474
|
docs: {
|
|
@@ -30092,21 +30529,15 @@ cu.update-in(
|
|
|
30092
30529
|
assertColl(coll, sourceCodeInfo);
|
|
30093
30530
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30094
30531
|
if (Array.isArray(coll)) {
|
|
30095
|
-
|
|
30096
|
-
return result;
|
|
30532
|
+
return filterSequential(coll, (elem, index) => executeFunction(fn, [elem, index], contextStack, sourceCodeInfo));
|
|
30097
30533
|
}
|
|
30098
30534
|
if (typeof coll === 'string') {
|
|
30099
|
-
return coll
|
|
30100
|
-
.split('')
|
|
30101
|
-
.filter((elem, index) => executeFunction(fn, [elem, index], contextStack, sourceCodeInfo))
|
|
30102
|
-
.join('');
|
|
30535
|
+
return chain(filterSequential(coll.split(''), (elem, index) => executeFunction(fn, [elem, index], contextStack, sourceCodeInfo)), filtered => filtered.join(''));
|
|
30103
30536
|
}
|
|
30104
|
-
return Object.entries(coll)
|
|
30105
|
-
.filter(([key, value]) => executeFunction(fn, [value, key], contextStack, sourceCodeInfo))
|
|
30106
|
-
.reduce((result, [key, value]) => {
|
|
30537
|
+
return chain(filterSequential(Object.entries(coll), ([key, value]) => executeFunction(fn, [value, key], contextStack, sourceCodeInfo)), filtered => filtered.reduce((result, [key, value]) => {
|
|
30107
30538
|
result[key] = value;
|
|
30108
30539
|
return result;
|
|
30109
|
-
}, {});
|
|
30540
|
+
}, {}));
|
|
30110
30541
|
},
|
|
30111
30542
|
arity: toFixedArity(2),
|
|
30112
30543
|
docs: {
|
|
@@ -30134,18 +30565,17 @@ cu.update-in(
|
|
|
30134
30565
|
assertColl(coll, sourceCodeInfo);
|
|
30135
30566
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30136
30567
|
if (Array.isArray(coll)) {
|
|
30137
|
-
return coll
|
|
30568
|
+
return mapSequential(coll, (elem, index) => executeFunction(fn, [elem, index], contextStack, sourceCodeInfo));
|
|
30138
30569
|
}
|
|
30139
30570
|
if (typeof coll === 'string') {
|
|
30140
|
-
return coll
|
|
30141
|
-
.split('')
|
|
30142
|
-
.map((elem, index) => executeFunction(fn, [elem, index], contextStack, sourceCodeInfo))
|
|
30143
|
-
.join('');
|
|
30571
|
+
return chain(mapSequential(coll.split(''), (elem, index) => executeFunction(fn, [elem, index], contextStack, sourceCodeInfo)), mapped => mapped.join(''));
|
|
30144
30572
|
}
|
|
30145
|
-
|
|
30146
|
-
|
|
30147
|
-
|
|
30148
|
-
|
|
30573
|
+
const entries = Object.entries(coll);
|
|
30574
|
+
return reduceSequential(entries, (acc, [key, value]) => {
|
|
30575
|
+
return chain(executeFunction(fn, [value, key], contextStack, sourceCodeInfo), (result) => {
|
|
30576
|
+
acc[key] = result;
|
|
30577
|
+
return acc;
|
|
30578
|
+
});
|
|
30149
30579
|
}, {});
|
|
30150
30580
|
},
|
|
30151
30581
|
arity: toFixedArity(2),
|
|
@@ -30180,23 +30610,17 @@ cu.update-in(
|
|
|
30180
30610
|
assertString(initial, sourceCodeInfo);
|
|
30181
30611
|
if (coll.length === 0)
|
|
30182
30612
|
return initial;
|
|
30183
|
-
return coll.split('').
|
|
30184
|
-
return executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo);
|
|
30185
|
-
}, initial);
|
|
30613
|
+
return reduceSequential(coll.split('').map((elem, index) => ({ elem, index })), (result, { elem, index }) => executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo), initial);
|
|
30186
30614
|
}
|
|
30187
30615
|
else if (Array.isArray(coll)) {
|
|
30188
30616
|
if (coll.length === 0)
|
|
30189
30617
|
return initial;
|
|
30190
|
-
return coll.
|
|
30191
|
-
return executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo);
|
|
30192
|
-
}, initial);
|
|
30618
|
+
return reduceSequential(coll.map((elem, index) => ({ elem, index })), (result, { elem, index }) => executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo), initial);
|
|
30193
30619
|
}
|
|
30194
30620
|
else {
|
|
30195
30621
|
if (Object.keys(coll).length === 0)
|
|
30196
30622
|
return initial;
|
|
30197
|
-
return Object.entries(coll)
|
|
30198
|
-
return executeFunction(fn, [result, elem, key], contextStack, sourceCodeInfo);
|
|
30199
|
-
}, initial);
|
|
30623
|
+
return reduceSequential(Object.entries(coll), (result, [key, elem]) => executeFunction(fn, [result, elem, key], contextStack, sourceCodeInfo), initial);
|
|
30200
30624
|
}
|
|
30201
30625
|
},
|
|
30202
30626
|
arity: toFixedArity(3),
|
|
@@ -30232,23 +30656,17 @@ cu.update-in(
|
|
|
30232
30656
|
if (typeof coll === 'string') {
|
|
30233
30657
|
if (coll.length === 0)
|
|
30234
30658
|
return initial;
|
|
30235
|
-
return coll.split('').
|
|
30236
|
-
return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo);
|
|
30237
|
-
}, initial);
|
|
30659
|
+
return reduceSequential(Array.from(coll.split('')).reverse(), (result, elem) => executeFunction(fn, [result, elem], contextStack, sourceCodeInfo), initial);
|
|
30238
30660
|
}
|
|
30239
30661
|
else if (Array.isArray(coll)) {
|
|
30240
30662
|
if (coll.length === 0)
|
|
30241
30663
|
return initial;
|
|
30242
|
-
return coll.
|
|
30243
|
-
return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo);
|
|
30244
|
-
}, initial);
|
|
30664
|
+
return reduceSequential(Array.from(coll).reverse(), (result, elem) => executeFunction(fn, [result, elem], contextStack, sourceCodeInfo), initial);
|
|
30245
30665
|
}
|
|
30246
30666
|
else {
|
|
30247
30667
|
if (Object.keys(coll).length === 0)
|
|
30248
30668
|
return initial;
|
|
30249
|
-
return Object.entries(coll).
|
|
30250
|
-
return executeFunction(fn, [result, elem], contextStack, sourceCodeInfo);
|
|
30251
|
-
}, initial);
|
|
30669
|
+
return reduceSequential(Object.entries(coll).reverse(), (result, [, elem]) => executeFunction(fn, [result, elem], contextStack, sourceCodeInfo), initial);
|
|
30252
30670
|
}
|
|
30253
30671
|
},
|
|
30254
30672
|
arity: toFixedArity(3),
|
|
@@ -30277,23 +30695,17 @@ cu.update-in(
|
|
|
30277
30695
|
if (typeof coll === 'string') {
|
|
30278
30696
|
if (coll.length === 0)
|
|
30279
30697
|
return initial;
|
|
30280
|
-
return coll.split('').
|
|
30281
|
-
return executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo);
|
|
30282
|
-
}, initial);
|
|
30698
|
+
return reduceSequential(Array.from(coll.split('')).reverse().map((elem, _, arr) => ({ elem, index: arr.length - 1 - _ })), (result, { elem, index }) => executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo), initial);
|
|
30283
30699
|
}
|
|
30284
30700
|
else if (Array.isArray(coll)) {
|
|
30285
30701
|
if (coll.length === 0)
|
|
30286
30702
|
return initial;
|
|
30287
|
-
return coll.
|
|
30288
|
-
return executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo);
|
|
30289
|
-
}, initial);
|
|
30703
|
+
return reduceSequential(Array.from(coll).reverse().map((elem, _, arr) => ({ elem, index: arr.length - 1 - _ })), (result, { elem, index }) => executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo), initial);
|
|
30290
30704
|
}
|
|
30291
30705
|
else {
|
|
30292
30706
|
if (Object.keys(coll).length === 0)
|
|
30293
30707
|
return initial;
|
|
30294
|
-
return Object.entries(coll).
|
|
30295
|
-
return executeFunction(fn, [result, elem, key], contextStack, sourceCodeInfo);
|
|
30296
|
-
}, initial);
|
|
30708
|
+
return reduceSequential(Object.entries(coll).reverse(), (result, [key, elem]) => executeFunction(fn, [result, elem, key], contextStack, sourceCodeInfo), initial);
|
|
30297
30709
|
}
|
|
30298
30710
|
},
|
|
30299
30711
|
arity: toFixedArity(3),
|
|
@@ -30327,40 +30739,20 @@ cu.update-in(
|
|
|
30327
30739
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30328
30740
|
assertAny(initial, sourceCodeInfo);
|
|
30329
30741
|
assertAny(initial, sourceCodeInfo);
|
|
30330
|
-
|
|
30331
|
-
assertString(initial, sourceCodeInfo)
|
|
30332
|
-
|
|
30333
|
-
|
|
30334
|
-
|
|
30335
|
-
|
|
30336
|
-
|
|
30742
|
+
const items = typeof coll === 'string'
|
|
30743
|
+
? (assertString(initial, sourceCodeInfo), coll.length === 0 ? [] : coll.split(''))
|
|
30744
|
+
: Array.isArray(coll)
|
|
30745
|
+
? (coll.length === 0 ? [] : Array.from(coll))
|
|
30746
|
+
: (Object.keys(coll).length === 0 ? [] : Object.entries(coll).map(([, v]) => v));
|
|
30747
|
+
if (items.length === 0)
|
|
30748
|
+
return [initial];
|
|
30749
|
+
const resultArray = [initial];
|
|
30750
|
+
return chain(reduceSequential(items, (result, elem) => {
|
|
30751
|
+
return chain(executeFunction(fn, [result, elem], contextStack, sourceCodeInfo), (newVal) => {
|
|
30337
30752
|
resultArray.push(newVal);
|
|
30338
30753
|
return newVal;
|
|
30339
|
-
}
|
|
30340
|
-
|
|
30341
|
-
}
|
|
30342
|
-
else if (Array.isArray(coll)) {
|
|
30343
|
-
if (coll.length === 0)
|
|
30344
|
-
return [initial];
|
|
30345
|
-
const resultArray = [initial];
|
|
30346
|
-
coll.reduce((result, elem) => {
|
|
30347
|
-
const newVal = executeFunction(fn, [result, elem], contextStack, sourceCodeInfo);
|
|
30348
|
-
resultArray.push(newVal);
|
|
30349
|
-
return newVal;
|
|
30350
|
-
}, initial);
|
|
30351
|
-
return resultArray;
|
|
30352
|
-
}
|
|
30353
|
-
else {
|
|
30354
|
-
if (Object.keys(coll).length === 0)
|
|
30355
|
-
return [initial];
|
|
30356
|
-
const resultArray = [initial];
|
|
30357
|
-
Object.entries(coll).reduce((result, [, elem]) => {
|
|
30358
|
-
const newVal = executeFunction(fn, [result, elem], contextStack, sourceCodeInfo);
|
|
30359
|
-
resultArray.push(newVal);
|
|
30360
|
-
return newVal;
|
|
30361
|
-
}, initial);
|
|
30362
|
-
return resultArray;
|
|
30363
|
-
}
|
|
30754
|
+
});
|
|
30755
|
+
}, initial), () => resultArray);
|
|
30364
30756
|
},
|
|
30365
30757
|
arity: toFixedArity(3),
|
|
30366
30758
|
docs: {
|
|
@@ -30395,40 +30787,21 @@ cu.reductions(
|
|
|
30395
30787
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30396
30788
|
assertAny(initial, sourceCodeInfo);
|
|
30397
30789
|
assertAny(initial, sourceCodeInfo);
|
|
30398
|
-
|
|
30399
|
-
|
|
30400
|
-
|
|
30401
|
-
|
|
30402
|
-
|
|
30403
|
-
|
|
30404
|
-
|
|
30405
|
-
|
|
30406
|
-
|
|
30407
|
-
|
|
30408
|
-
return
|
|
30409
|
-
}
|
|
30410
|
-
else if (Array.isArray(coll)) {
|
|
30411
|
-
if (coll.length === 0)
|
|
30412
|
-
return [initial];
|
|
30413
|
-
const resultArray = [initial];
|
|
30414
|
-
coll.reduce((result, elem, index) => {
|
|
30415
|
-
const newVal = executeFunction(fn, [result, elem, index], contextStack, sourceCodeInfo);
|
|
30416
|
-
resultArray.push(newVal);
|
|
30417
|
-
return newVal;
|
|
30418
|
-
}, initial);
|
|
30419
|
-
return resultArray;
|
|
30420
|
-
}
|
|
30421
|
-
else {
|
|
30422
|
-
if (Object.keys(coll).length === 0)
|
|
30423
|
-
return [initial];
|
|
30424
|
-
const resultArray = [initial];
|
|
30425
|
-
Object.entries(coll).reduce((result, [key, elem]) => {
|
|
30426
|
-
const newVal = executeFunction(fn, [result, elem, key], contextStack, sourceCodeInfo);
|
|
30790
|
+
const toIndexedItem = (elem, key) => ({ elem, key });
|
|
30791
|
+
const items = typeof coll === 'string'
|
|
30792
|
+
? (assertString(initial, sourceCodeInfo), coll.length === 0 ? [] : coll.split('').map((elem, index) => toIndexedItem(elem, index)))
|
|
30793
|
+
: Array.isArray(coll)
|
|
30794
|
+
? (coll.length === 0 ? [] : coll.map((elem, index) => toIndexedItem(elem, index)))
|
|
30795
|
+
: (Object.keys(coll).length === 0 ? [] : Object.entries(coll).map(([key, v]) => toIndexedItem(v, key)));
|
|
30796
|
+
if (items.length === 0)
|
|
30797
|
+
return [initial];
|
|
30798
|
+
const resultArray = [initial];
|
|
30799
|
+
return chain(reduceSequential(items, (result, { elem, key }) => {
|
|
30800
|
+
return chain(executeFunction(fn, [result, elem, key], contextStack, sourceCodeInfo), (newVal) => {
|
|
30427
30801
|
resultArray.push(newVal);
|
|
30428
30802
|
return newVal;
|
|
30429
|
-
}
|
|
30430
|
-
|
|
30431
|
-
}
|
|
30803
|
+
});
|
|
30804
|
+
}, initial), () => resultArray);
|
|
30432
30805
|
},
|
|
30433
30806
|
arity: toFixedArity(3),
|
|
30434
30807
|
docs: {
|
|
@@ -30491,11 +30864,12 @@ cu.reductions(
|
|
|
30491
30864
|
evaluate: ([coll, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
30492
30865
|
assertColl(coll, sourceCodeInfo);
|
|
30493
30866
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30494
|
-
|
|
30495
|
-
|
|
30496
|
-
|
|
30497
|
-
|
|
30498
|
-
|
|
30867
|
+
const arr = Array.isArray(coll)
|
|
30868
|
+
? coll
|
|
30869
|
+
: typeof coll === 'string'
|
|
30870
|
+
? coll.split('')
|
|
30871
|
+
: Object.entries(coll);
|
|
30872
|
+
return everySequential(arr, elem => executeFunction(fn, [elem], contextStack, sourceCodeInfo));
|
|
30499
30873
|
},
|
|
30500
30874
|
arity: toFixedArity(2),
|
|
30501
30875
|
docs: {
|
|
@@ -30545,11 +30919,12 @@ cu.every?(
|
|
|
30545
30919
|
evaluate: ([coll, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
30546
30920
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30547
30921
|
assertColl(coll, sourceCodeInfo);
|
|
30548
|
-
|
|
30549
|
-
|
|
30550
|
-
|
|
30551
|
-
|
|
30552
|
-
|
|
30922
|
+
const arr = Array.isArray(coll)
|
|
30923
|
+
? coll
|
|
30924
|
+
: typeof coll === 'string'
|
|
30925
|
+
? coll.split('')
|
|
30926
|
+
: Object.entries(coll);
|
|
30927
|
+
return someSequential(arr, elem => executeFunction(fn, [elem], contextStack, sourceCodeInfo));
|
|
30553
30928
|
},
|
|
30554
30929
|
arity: toFixedArity(2),
|
|
30555
30930
|
docs: {
|
|
@@ -30597,11 +30972,12 @@ cu.any?(
|
|
|
30597
30972
|
evaluate: ([coll, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
30598
30973
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30599
30974
|
assertColl(coll, sourceCodeInfo);
|
|
30600
|
-
|
|
30601
|
-
|
|
30602
|
-
|
|
30603
|
-
|
|
30604
|
-
|
|
30975
|
+
const arr = Array.isArray(coll)
|
|
30976
|
+
? coll
|
|
30977
|
+
: typeof coll === 'string'
|
|
30978
|
+
? coll.split('')
|
|
30979
|
+
: Object.entries(coll);
|
|
30980
|
+
return chain(someSequential(arr, elem => executeFunction(fn, [elem], contextStack, sourceCodeInfo)), result => !result);
|
|
30605
30981
|
},
|
|
30606
30982
|
arity: toFixedArity(2),
|
|
30607
30983
|
docs: {
|
|
@@ -30649,11 +31025,12 @@ cu.not-any?(
|
|
|
30649
31025
|
evaluate: ([coll, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
30650
31026
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30651
31027
|
assertColl(coll, sourceCodeInfo);
|
|
30652
|
-
|
|
30653
|
-
|
|
30654
|
-
|
|
30655
|
-
|
|
30656
|
-
|
|
31028
|
+
const arr = Array.isArray(coll)
|
|
31029
|
+
? coll
|
|
31030
|
+
: typeof coll === 'string'
|
|
31031
|
+
? coll.split('')
|
|
31032
|
+
: Object.entries(coll);
|
|
31033
|
+
return chain(everySequential(arr, elem => executeFunction(fn, [elem], contextStack, sourceCodeInfo)), result => !result);
|
|
30657
31034
|
},
|
|
30658
31035
|
arity: toFixedArity(2),
|
|
30659
31036
|
docs: {
|
|
@@ -30710,14 +31087,8 @@ const sequenceUtilsFunctions = {
|
|
|
30710
31087
|
if (seq === null)
|
|
30711
31088
|
return null;
|
|
30712
31089
|
assertSeq(seq, sourceCodeInfo);
|
|
30713
|
-
|
|
30714
|
-
|
|
30715
|
-
return index !== -1 ? index : null;
|
|
30716
|
-
}
|
|
30717
|
-
else {
|
|
30718
|
-
const index = seq.findIndex(elem => executeFunction(fn, [elem], contextStack, sourceCodeInfo));
|
|
30719
|
-
return index !== -1 ? index : null;
|
|
30720
|
-
}
|
|
31090
|
+
const arr = typeof seq === 'string' ? seq.split('') : seq;
|
|
31091
|
+
return chain(findIndexSequential(arr, elem => executeFunction(fn, [elem], contextStack, sourceCodeInfo)), index => index !== -1 ? index : null);
|
|
30721
31092
|
},
|
|
30722
31093
|
arity: toFixedArity(2),
|
|
30723
31094
|
docs: {
|
|
@@ -30864,50 +31235,39 @@ su.position(
|
|
|
30864
31235
|
assertSeq(seq, sourceCodeInfo);
|
|
30865
31236
|
assertFunctionLike(keyfn, sourceCodeInfo);
|
|
30866
31237
|
const comparer = defaultComparer ? null : params[2];
|
|
30867
|
-
|
|
30868
|
-
|
|
31238
|
+
const isString = typeof seq === 'string';
|
|
31239
|
+
const arr = isString ? seq.split('') : [...seq];
|
|
31240
|
+
// Pre-compute all keys using mapSequential (async-safe)
|
|
31241
|
+
return chain(mapSequential(arr, elem => executeFunction(keyfn, [elem], contextStack, sourceCodeInfo)), (keys) => {
|
|
30869
31242
|
if (defaultComparer) {
|
|
30870
|
-
|
|
30871
|
-
|
|
30872
|
-
|
|
30873
|
-
|
|
30874
|
-
assertStringOrNumber(
|
|
30875
|
-
return compare(
|
|
31243
|
+
// Create indexed pairs, sort by pre-computed keys
|
|
31244
|
+
const indexed = arr.map((elem, i) => ({ elem, key: keys[i] }));
|
|
31245
|
+
indexed.sort((a, b) => {
|
|
31246
|
+
assertStringOrNumber(a.key, sourceCodeInfo);
|
|
31247
|
+
assertStringOrNumber(b.key, sourceCodeInfo);
|
|
31248
|
+
return compare(a.key, b.key, sourceCodeInfo);
|
|
30876
31249
|
});
|
|
31250
|
+
const sorted = indexed.map(x => x.elem);
|
|
31251
|
+
return isString ? sorted.join('') : sorted;
|
|
30877
31252
|
}
|
|
30878
31253
|
else {
|
|
30879
31254
|
assertFunctionLike(comparer, sourceCodeInfo);
|
|
30880
|
-
|
|
30881
|
-
|
|
30882
|
-
|
|
30883
|
-
|
|
31255
|
+
// Pre-compute keys, then need pairwise comparisons — these may also be async
|
|
31256
|
+
// For sort-by with custom comparer, we must use a non-async sort since
|
|
31257
|
+
// Array.sort requires sync comparators
|
|
31258
|
+
const indexed = arr.map((elem, i) => ({ elem, key: keys[i] }));
|
|
31259
|
+
indexed.sort((a, b) => {
|
|
31260
|
+
const compareValue = executeFunction(comparer, [a.key, b.key], contextStack, sourceCodeInfo);
|
|
31261
|
+
if (compareValue instanceof Promise) {
|
|
31262
|
+
throw new TypeError('Async functions cannot be used as sort-by comparators');
|
|
31263
|
+
}
|
|
30884
31264
|
assertNumber(compareValue, sourceCodeInfo, { finite: true });
|
|
30885
31265
|
return compareValue;
|
|
30886
31266
|
});
|
|
31267
|
+
const sorted = indexed.map(x => x.elem);
|
|
31268
|
+
return isString ? sorted.join('') : sorted;
|
|
30887
31269
|
}
|
|
30888
|
-
|
|
30889
|
-
}
|
|
30890
|
-
const result = [...seq];
|
|
30891
|
-
if (defaultComparer) {
|
|
30892
|
-
result.sort((a, b) => {
|
|
30893
|
-
const aKey = executeFunction(keyfn, [a], contextStack, sourceCodeInfo);
|
|
30894
|
-
assertStringOrNumber(aKey, sourceCodeInfo);
|
|
30895
|
-
const bKey = executeFunction(keyfn, [b], contextStack, sourceCodeInfo);
|
|
30896
|
-
assertStringOrNumber(bKey, sourceCodeInfo);
|
|
30897
|
-
return compare(aKey, bKey, sourceCodeInfo);
|
|
30898
|
-
});
|
|
30899
|
-
}
|
|
30900
|
-
else {
|
|
30901
|
-
assertFunctionLike(comparer, sourceCodeInfo);
|
|
30902
|
-
result.sort((a, b) => {
|
|
30903
|
-
const aKey = executeFunction(keyfn, [a], contextStack, sourceCodeInfo);
|
|
30904
|
-
const bKey = executeFunction(keyfn, [b], contextStack, sourceCodeInfo);
|
|
30905
|
-
const compareValue = executeFunction(comparer, [aKey, bKey], contextStack, sourceCodeInfo);
|
|
30906
|
-
assertNumber(compareValue, sourceCodeInfo, { finite: true });
|
|
30907
|
-
return compareValue;
|
|
30908
|
-
});
|
|
30909
|
-
}
|
|
30910
|
-
return result;
|
|
31270
|
+
});
|
|
30911
31271
|
},
|
|
30912
31272
|
arity: { min: 2, max: 3 },
|
|
30913
31273
|
docs: {
|
|
@@ -30994,14 +31354,12 @@ su.position(
|
|
|
30994
31354
|
evaluate: ([seq, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
30995
31355
|
assertSeq(seq, sourceCodeInfo);
|
|
30996
31356
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
30997
|
-
const
|
|
30998
|
-
|
|
30999
|
-
|
|
31000
|
-
|
|
31001
|
-
|
|
31002
|
-
|
|
31003
|
-
}
|
|
31004
|
-
return typeof seq === 'string' ? result.join('') : result;
|
|
31357
|
+
const arr = typeof seq === 'string' ? seq.split('') : Array.from(seq);
|
|
31358
|
+
// Find the first index where the predicate is false
|
|
31359
|
+
return chain(findIndexSequential(arr, elem => chain(executeFunction(fn, [elem], contextStack, sourceCodeInfo), result => !result)), (index) => {
|
|
31360
|
+
const taken = index === -1 ? arr : arr.slice(0, index);
|
|
31361
|
+
return typeof seq === 'string' ? taken.join('') : taken;
|
|
31362
|
+
});
|
|
31005
31363
|
},
|
|
31006
31364
|
arity: toFixedArity(2),
|
|
31007
31365
|
docs: {
|
|
@@ -31092,13 +31450,12 @@ su.take-while(
|
|
|
31092
31450
|
evaluate: ([seq, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
31093
31451
|
assertSeq(seq, sourceCodeInfo);
|
|
31094
31452
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
31095
|
-
|
|
31096
|
-
|
|
31097
|
-
|
|
31098
|
-
|
|
31099
|
-
|
|
31100
|
-
|
|
31101
|
-
return charArray.slice(from).join('');
|
|
31453
|
+
const arr = Array.isArray(seq) ? seq : seq.split('');
|
|
31454
|
+
return chain(findIndexSequential(arr, elem => chain(executeFunction(fn, [elem], contextStack, sourceCodeInfo), result => !result)), (from) => {
|
|
31455
|
+
if (from === -1)
|
|
31456
|
+
return typeof seq === 'string' ? '' : [];
|
|
31457
|
+
return typeof seq === 'string' ? arr.slice(from).join('') : seq.slice(from);
|
|
31458
|
+
});
|
|
31102
31459
|
},
|
|
31103
31460
|
arity: toFixedArity(2),
|
|
31104
31461
|
docs: {
|
|
@@ -31201,12 +31558,8 @@ l`,
|
|
|
31201
31558
|
evaluate: ([input, fn], sourceCodeInfo, contextStack, { executeFunction }) => {
|
|
31202
31559
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
31203
31560
|
assertSeq(input, sourceCodeInfo);
|
|
31204
|
-
|
|
31205
|
-
|
|
31206
|
-
return input
|
|
31207
|
-
.split('')
|
|
31208
|
-
.filter(elem => !executeFunction(fn, [elem], contextStack, sourceCodeInfo))
|
|
31209
|
-
.join('');
|
|
31561
|
+
const arr = Array.isArray(input) ? input : input.split('');
|
|
31562
|
+
return chain(filterSequential(arr, elem => chain(executeFunction(fn, [elem], contextStack, sourceCodeInfo), result => !result)), filtered => typeof input === 'string' ? filtered.join('') : filtered);
|
|
31210
31563
|
},
|
|
31211
31564
|
arity: toFixedArity(2),
|
|
31212
31565
|
docs: {
|
|
@@ -31296,10 +31649,11 @@ l`,
|
|
|
31296
31649
|
assertSeq(seq, sourceCodeInfo);
|
|
31297
31650
|
const seqIsArray = Array.isArray(seq);
|
|
31298
31651
|
const arr = seqIsArray ? seq : seq.split('');
|
|
31299
|
-
|
|
31300
|
-
|
|
31301
|
-
|
|
31302
|
-
|
|
31652
|
+
return chain(findIndexSequential(arr, elem => chain(executeFunction(fn, [elem], contextStack, sourceCodeInfo), result => !result)), (index) => {
|
|
31653
|
+
if (index === -1)
|
|
31654
|
+
return [seq, seqIsArray ? [] : ''];
|
|
31655
|
+
return [seq.slice(0, index), seq.slice(index)];
|
|
31656
|
+
});
|
|
31303
31657
|
},
|
|
31304
31658
|
arity: toFixedArity(2),
|
|
31305
31659
|
docs: {
|
|
@@ -31353,13 +31707,14 @@ l`,
|
|
|
31353
31707
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
31354
31708
|
assertSeq(seq, sourceCodeInfo);
|
|
31355
31709
|
const arr = Array.isArray(seq) ? seq : seq.split('');
|
|
31356
|
-
return arr
|
|
31357
|
-
|
|
31358
|
-
|
|
31359
|
-
|
|
31360
|
-
|
|
31361
|
-
|
|
31362
|
-
|
|
31710
|
+
return reduceSequential(arr, (result, val) => {
|
|
31711
|
+
return chain(executeFunction(fn, [val], contextStack, sourceCodeInfo), (key) => {
|
|
31712
|
+
assertString(key, sourceCodeInfo);
|
|
31713
|
+
if (!collHasKey(result, key))
|
|
31714
|
+
result[key] = [];
|
|
31715
|
+
result[key].push(val);
|
|
31716
|
+
return result;
|
|
31717
|
+
});
|
|
31363
31718
|
}, {});
|
|
31364
31719
|
},
|
|
31365
31720
|
arity: toFixedArity(2),
|
|
@@ -31468,17 +31823,17 @@ l`,
|
|
|
31468
31823
|
assertFunctionLike(fn, sourceCodeInfo);
|
|
31469
31824
|
assertSeq(seq, sourceCodeInfo);
|
|
31470
31825
|
const isStringSeq = typeof seq === 'string';
|
|
31471
|
-
|
|
31472
|
-
|
|
31473
|
-
|
|
31474
|
-
|
|
31475
|
-
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
|
|
31479
|
-
|
|
31480
|
-
|
|
31481
|
-
|
|
31826
|
+
const arr = isStringSeq ? seq.split('') : seq;
|
|
31827
|
+
return chain(reduceSequential(arr, (acc, elem) => {
|
|
31828
|
+
return chain(executeFunction(fn, [elem], contextStack, sourceCodeInfo), (value) => {
|
|
31829
|
+
if (value !== acc.oldValue) {
|
|
31830
|
+
acc.result.push([]);
|
|
31831
|
+
acc.oldValue = value;
|
|
31832
|
+
}
|
|
31833
|
+
acc.result[acc.result.length - 1].push(elem);
|
|
31834
|
+
return acc;
|
|
31835
|
+
});
|
|
31836
|
+
}, { result: [], oldValue: undefined }), ({ result }) => isStringSeq ? result.map(elem => elem.join('')) : result);
|
|
31482
31837
|
},
|
|
31483
31838
|
arity: toFixedArity(2),
|
|
31484
31839
|
docs: {
|