@almadar/evaluator 2.1.1 → 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/dist/{index-DBM7Xkm3.d.ts → index-C-vYm4zW.d.ts} +11 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +78 -90
- package/dist/index.js.map +1 -1
- package/dist/operators/index.d.ts +1 -1
- package/dist/operators/index.js +21 -41
- package/dist/operators/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -235,8 +235,10 @@ declare function evalIf(args: SExpr[], evaluate: Evaluator$3, ctx: EvaluationCon
|
|
|
235
235
|
|
|
236
236
|
type Evaluator$2 = (expr: SExpr, ctx: EvaluationContext) => unknown;
|
|
237
237
|
/**
|
|
238
|
-
* Evaluate let binding
|
|
239
|
-
*
|
|
238
|
+
* Evaluate let binding.
|
|
239
|
+
* Supports two formats:
|
|
240
|
+
* - Array of pairs: ["let", [["x", 10], ["y", 20]], body]
|
|
241
|
+
* - Object style: ["let", {"x": 10, "y": 20}, body]
|
|
240
242
|
*/
|
|
241
243
|
declare function evalLet(args: SExpr[], evaluate: Evaluator$2, ctx: EvaluationContext): unknown;
|
|
242
244
|
/**
|
|
@@ -259,19 +261,22 @@ declare function evalFn(args: SExpr[], _evaluate: Evaluator$2, _ctx: EvaluationC
|
|
|
259
261
|
* Collection Operator Implementations
|
|
260
262
|
*
|
|
261
263
|
* Implements: map, filter, find, count, sum, first, last, nth, concat, includes, empty
|
|
264
|
+
*
|
|
265
|
+
* These short-form operators (map, filter, find) use @item/@index bindings,
|
|
266
|
+
* matching the Rust evaluator's approach.
|
|
262
267
|
*/
|
|
263
268
|
|
|
264
269
|
type Evaluator$1 = (expr: SExpr, ctx: EvaluationContext) => unknown;
|
|
265
270
|
/**
|
|
266
|
-
* Evaluate map: ["map", collection,
|
|
271
|
+
* Evaluate map: ["map", collection, expr_using_@item]
|
|
267
272
|
*/
|
|
268
273
|
declare function evalMap(args: SExpr[], evaluate: Evaluator$1, ctx: EvaluationContext): unknown[];
|
|
269
274
|
/**
|
|
270
|
-
* Evaluate filter: ["filter", collection,
|
|
275
|
+
* Evaluate filter: ["filter", collection, expr_using_@item]
|
|
271
276
|
*/
|
|
272
277
|
declare function evalFilter(args: SExpr[], evaluate: Evaluator$1, ctx: EvaluationContext): unknown[];
|
|
273
278
|
/**
|
|
274
|
-
* Evaluate find: ["find", collection,
|
|
279
|
+
* Evaluate find: ["find", collection, expr_using_@item]
|
|
275
280
|
*/
|
|
276
281
|
declare function evalFind(args: SExpr[], evaluate: Evaluator$1, ctx: EvaluationContext): unknown;
|
|
277
282
|
/**
|
|
@@ -279,7 +284,7 @@ declare function evalFind(args: SExpr[], evaluate: Evaluator$1, ctx: EvaluationC
|
|
|
279
284
|
*/
|
|
280
285
|
declare function evalCount(args: SExpr[], evaluate: Evaluator$1, ctx: EvaluationContext): number;
|
|
281
286
|
/**
|
|
282
|
-
* Evaluate sum: ["sum", collection] or ["sum", collection,
|
|
287
|
+
* Evaluate sum: ["sum", collection] or ["sum", collection, mapExpr_using_@item]
|
|
283
288
|
*/
|
|
284
289
|
declare function evalSum(args: SExpr[], evaluate: Evaluator$1, ctx: EvaluationContext): number;
|
|
285
290
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SExpr } from '@almadar/core';
|
|
2
2
|
export { CORE_BINDINGS, CoreBinding, Expression, ExpressionSchema, ParsedBinding, SExpr, SExprAtom, SExprSchema, collectBindings, getArgs, getOperator, isBinding, isSExpr, isSExprAtom, isSExprCall, isValidBinding, parseBinding, sexpr, walkSExpr } from '@almadar/core';
|
|
3
|
-
import { E as EvaluationContext } from './index-
|
|
4
|
-
export { c as createChildContext, a as createEffectContext, b as createMinimalContext, e as evalAbs, d as evalAdd, f as evalAnd, g as evalCallService, h as evalCeil, i as evalClamp, j as evalConcat, k as evalCount, l as evalDecrement, m as evalDespawn, n as evalDivide, o as evalDo, p as evalEmit, q as evalEmpty, r as evalEqual, s as evalFilter, t as evalFind, u as evalFirst, v as evalFloor, w as evalFn, x as evalGreaterThan, y as evalGreaterThanOrEqual, z as evalIf, A as evalIncludes, B as evalIncrement, C as evalLast, D as evalLessThan, F as evalLessThanOrEqual, G as evalLet, H as evalMap, I as evalMatches, J as evalMax, K as evalMin, L as evalModulo, M as evalMultiply, N as evalNavigate, O as evalNot, P as evalNotEqual, Q as evalNotify, R as evalNth, S as evalOr, T as evalPersist, U as evalRenderUI, V as evalRound, W as evalSet, X as evalSetDynamic, Y as evalSpawn, Z as evalSubtract, _ as evalSum, $ as evalWhen, a0 as resolveBinding } from './index-
|
|
3
|
+
import { E as EvaluationContext } from './index-C-vYm4zW.js';
|
|
4
|
+
export { c as createChildContext, a as createEffectContext, b as createMinimalContext, e as evalAbs, d as evalAdd, f as evalAnd, g as evalCallService, h as evalCeil, i as evalClamp, j as evalConcat, k as evalCount, l as evalDecrement, m as evalDespawn, n as evalDivide, o as evalDo, p as evalEmit, q as evalEmpty, r as evalEqual, s as evalFilter, t as evalFind, u as evalFirst, v as evalFloor, w as evalFn, x as evalGreaterThan, y as evalGreaterThanOrEqual, z as evalIf, A as evalIncludes, B as evalIncrement, C as evalLast, D as evalLessThan, F as evalLessThanOrEqual, G as evalLet, H as evalMap, I as evalMatches, J as evalMax, K as evalMin, L as evalModulo, M as evalMultiply, N as evalNavigate, O as evalNot, P as evalNotEqual, Q as evalNotify, R as evalNth, S as evalOr, T as evalPersist, U as evalRenderUI, V as evalRound, W as evalSet, X as evalSetDynamic, Y as evalSpawn, Z as evalSubtract, _ as evalSum, $ as evalWhen, a0 as resolveBinding } from './index-C-vYm4zW.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* S-Expression Evaluator
|
package/dist/index.js
CHANGED
|
@@ -255,12 +255,12 @@ function toBoolean(value) {
|
|
|
255
255
|
|
|
256
256
|
// operators/control.ts
|
|
257
257
|
function evalLet(args, evaluate2, ctx) {
|
|
258
|
-
const
|
|
258
|
+
const rawBindings = args[0];
|
|
259
259
|
const body = args[1];
|
|
260
|
+
const bindingPairs = Array.isArray(rawBindings) ? rawBindings.map((b) => [b[0], b[1]]) : Object.entries(rawBindings);
|
|
260
261
|
const locals = /* @__PURE__ */ new Map();
|
|
261
|
-
for (const
|
|
262
|
-
const
|
|
263
|
-
const value = evaluate2(binding[1], ctx);
|
|
262
|
+
for (const [name, valueExpr] of bindingPairs) {
|
|
263
|
+
const value = evaluate2(valueExpr, ctx);
|
|
264
264
|
locals.set(name, value);
|
|
265
265
|
}
|
|
266
266
|
const childCtx = createChildContext(ctx, locals);
|
|
@@ -298,44 +298,26 @@ function evalFn(args, _evaluate, _ctx) {
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
// operators/collections.ts
|
|
301
|
+
function withItem(expr, evaluate2, ctx, item, index) {
|
|
302
|
+
const locals = /* @__PURE__ */ new Map();
|
|
303
|
+
locals.set("item", item);
|
|
304
|
+
locals.set("index", index);
|
|
305
|
+
return evaluate2(expr, createChildContext(ctx, locals));
|
|
306
|
+
}
|
|
301
307
|
function evalMap(args, evaluate2, ctx) {
|
|
302
308
|
const collection = toArray(evaluate2(args[0], ctx));
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
const body = fnExpr[2];
|
|
306
|
-
const varName = typeof params === "string" ? params : params[0];
|
|
307
|
-
return collection.map((item) => {
|
|
308
|
-
const locals = /* @__PURE__ */ new Map();
|
|
309
|
-
locals.set(varName, item);
|
|
310
|
-
const childCtx = createChildContext(ctx, locals);
|
|
311
|
-
return evaluate2(body, childCtx);
|
|
312
|
-
});
|
|
309
|
+
const mapExpr = args[1];
|
|
310
|
+
return collection.map((item, i) => withItem(mapExpr, evaluate2, ctx, item, i));
|
|
313
311
|
}
|
|
314
312
|
function evalFilter(args, evaluate2, ctx) {
|
|
315
313
|
const collection = toArray(evaluate2(args[0], ctx));
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
const body = fnExpr[2];
|
|
319
|
-
const varName = typeof params === "string" ? params : params[0];
|
|
320
|
-
return collection.filter((item) => {
|
|
321
|
-
const locals = /* @__PURE__ */ new Map();
|
|
322
|
-
locals.set(varName, item);
|
|
323
|
-
const childCtx = createChildContext(ctx, locals);
|
|
324
|
-
return Boolean(evaluate2(body, childCtx));
|
|
325
|
-
});
|
|
314
|
+
const predExpr = args[1];
|
|
315
|
+
return collection.filter((item, i) => Boolean(withItem(predExpr, evaluate2, ctx, item, i)));
|
|
326
316
|
}
|
|
327
317
|
function evalFind(args, evaluate2, ctx) {
|
|
328
318
|
const collection = toArray(evaluate2(args[0], ctx));
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
const body = fnExpr[2];
|
|
332
|
-
const varName = typeof params === "string" ? params : params[0];
|
|
333
|
-
return collection.find((item) => {
|
|
334
|
-
const locals = /* @__PURE__ */ new Map();
|
|
335
|
-
locals.set(varName, item);
|
|
336
|
-
const childCtx = createChildContext(ctx, locals);
|
|
337
|
-
return Boolean(evaluate2(body, childCtx));
|
|
338
|
-
});
|
|
319
|
+
const predExpr = args[1];
|
|
320
|
+
return collection.find((item, i) => Boolean(withItem(predExpr, evaluate2, ctx, item, i)));
|
|
339
321
|
}
|
|
340
322
|
function evalCount(args, evaluate2, ctx) {
|
|
341
323
|
const collection = toArray(evaluate2(args[0], ctx));
|
|
@@ -346,15 +328,13 @@ function evalSum(args, evaluate2, ctx) {
|
|
|
346
328
|
if (args.length === 1) {
|
|
347
329
|
return collection.reduce((sum, item) => sum + toNumber2(item), 0);
|
|
348
330
|
}
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
const body = fnExpr[2];
|
|
352
|
-
const varName = typeof params === "string" ? params : params[0];
|
|
353
|
-
return collection.reduce((sum, item) => {
|
|
331
|
+
const mapExpr = args[1];
|
|
332
|
+
return collection.reduce((sum, item, i) => {
|
|
354
333
|
const locals = /* @__PURE__ */ new Map();
|
|
355
|
-
locals.set(
|
|
334
|
+
locals.set("item", item);
|
|
335
|
+
locals.set("index", i);
|
|
356
336
|
const childCtx = createChildContext(ctx, locals);
|
|
357
|
-
return sum + toNumber2(evaluate2(
|
|
337
|
+
return sum + toNumber2(evaluate2(mapExpr, childCtx));
|
|
358
338
|
}, 0);
|
|
359
339
|
}
|
|
360
340
|
function evalFirst(args, evaluate2, ctx) {
|
|
@@ -825,29 +805,37 @@ function evalStrTruncate(args, evaluate2, ctx) {
|
|
|
825
805
|
}
|
|
826
806
|
|
|
827
807
|
// std/array.ts
|
|
828
|
-
function
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
808
|
+
function evalWithItem(expr, evaluate2, ctx, item, index) {
|
|
809
|
+
const locals = /* @__PURE__ */ new Map();
|
|
810
|
+
locals.set("item", item);
|
|
811
|
+
locals.set("index", index);
|
|
812
|
+
const childCtx = createChildContext(ctx, locals);
|
|
813
|
+
return evaluate2(expr, childCtx);
|
|
814
|
+
}
|
|
815
|
+
function evalReduceLambda(lambdaExpr, evaluate2, ctx, acc, item) {
|
|
816
|
+
const locals = /* @__PURE__ */ new Map();
|
|
817
|
+
if (isSExpr(lambdaExpr) && getOperator(lambdaExpr) === "fn") {
|
|
818
|
+
const fnArgs = getArgs(lambdaExpr);
|
|
819
|
+
const params = fnArgs[0];
|
|
820
|
+
const body = fnArgs[1];
|
|
821
|
+
if (Array.isArray(params)) {
|
|
822
|
+
const paramNames = params;
|
|
823
|
+
const values = [acc, item];
|
|
824
|
+
paramNames.forEach((p, i) => {
|
|
825
|
+
const key = p.startsWith("@") ? p.slice(1) : p;
|
|
826
|
+
locals.set(key, values[i]);
|
|
827
|
+
});
|
|
828
|
+
} else if (typeof params === "string") {
|
|
829
|
+
const key = params.startsWith("@") ? params.slice(1) : params;
|
|
830
|
+
locals.set(key, acc);
|
|
831
|
+
}
|
|
832
|
+
const childCtx2 = createChildContext(ctx, locals);
|
|
833
|
+
return evaluate2(body, childCtx2);
|
|
848
834
|
}
|
|
849
|
-
|
|
850
|
-
|
|
835
|
+
locals.set("acc", acc);
|
|
836
|
+
locals.set("item", item);
|
|
837
|
+
const childCtx = createChildContext(ctx, locals);
|
|
838
|
+
return evaluate2(lambdaExpr, childCtx);
|
|
851
839
|
}
|
|
852
840
|
function evalArrayLen(args, evaluate2, ctx) {
|
|
853
841
|
const arr = evaluate2(args[0], ctx);
|
|
@@ -981,53 +969,53 @@ function evalArrayIndexOf(args, evaluate2, ctx) {
|
|
|
981
969
|
}
|
|
982
970
|
function evalArrayFind(args, evaluate2, ctx) {
|
|
983
971
|
const arr = evaluate2(args[0], ctx);
|
|
984
|
-
const
|
|
985
|
-
return (arr ?? []).find((item) =>
|
|
972
|
+
const predExpr = args[1];
|
|
973
|
+
return (arr ?? []).find((item, i) => evalWithItem(predExpr, evaluate2, ctx, item, i));
|
|
986
974
|
}
|
|
987
975
|
function evalArrayFindIndex(args, evaluate2, ctx) {
|
|
988
976
|
const arr = evaluate2(args[0], ctx);
|
|
989
|
-
const
|
|
990
|
-
return (arr ?? []).findIndex((item) =>
|
|
977
|
+
const predExpr = args[1];
|
|
978
|
+
return (arr ?? []).findIndex((item, i) => evalWithItem(predExpr, evaluate2, ctx, item, i));
|
|
991
979
|
}
|
|
992
980
|
function evalArrayFilter(args, evaluate2, ctx) {
|
|
993
981
|
const arr = evaluate2(args[0], ctx);
|
|
994
|
-
const
|
|
995
|
-
return (arr ?? []).filter((item) =>
|
|
982
|
+
const predExpr = args[1];
|
|
983
|
+
return (arr ?? []).filter((item, i) => evalWithItem(predExpr, evaluate2, ctx, item, i));
|
|
996
984
|
}
|
|
997
985
|
function evalArrayReject(args, evaluate2, ctx) {
|
|
998
986
|
const arr = evaluate2(args[0], ctx);
|
|
999
|
-
const
|
|
1000
|
-
return (arr ?? []).filter((item) => !
|
|
987
|
+
const predExpr = args[1];
|
|
988
|
+
return (arr ?? []).filter((item, i) => !evalWithItem(predExpr, evaluate2, ctx, item, i));
|
|
1001
989
|
}
|
|
1002
990
|
function evalArrayMap(args, evaluate2, ctx) {
|
|
1003
991
|
const arr = evaluate2(args[0], ctx);
|
|
1004
|
-
const
|
|
1005
|
-
return (arr ?? []).map((item) =>
|
|
992
|
+
const mapExpr = args[1];
|
|
993
|
+
return (arr ?? []).map((item, i) => evalWithItem(mapExpr, evaluate2, ctx, item, i));
|
|
1006
994
|
}
|
|
1007
995
|
function evalArrayReduce(args, evaluate2, ctx) {
|
|
1008
996
|
const arr = evaluate2(args[0], ctx);
|
|
1009
|
-
const
|
|
1010
|
-
const
|
|
997
|
+
const init = evaluate2(args[1], ctx);
|
|
998
|
+
const reducerExpr = args[2];
|
|
1011
999
|
return (arr ?? []).reduce(
|
|
1012
|
-
(acc, item) =>
|
|
1000
|
+
(acc, item) => evalReduceLambda(reducerExpr, evaluate2, ctx, acc, item),
|
|
1013
1001
|
init
|
|
1014
1002
|
);
|
|
1015
1003
|
}
|
|
1016
1004
|
function evalArrayEvery(args, evaluate2, ctx) {
|
|
1017
1005
|
const arr = evaluate2(args[0], ctx);
|
|
1018
|
-
const
|
|
1019
|
-
return (arr ?? []).every((item) => Boolean(
|
|
1006
|
+
const predExpr = args[1];
|
|
1007
|
+
return (arr ?? []).every((item, i) => Boolean(evalWithItem(predExpr, evaluate2, ctx, item, i)));
|
|
1020
1008
|
}
|
|
1021
1009
|
function evalArraySome(args, evaluate2, ctx) {
|
|
1022
1010
|
const arr = evaluate2(args[0], ctx);
|
|
1023
|
-
const
|
|
1024
|
-
return (arr ?? []).some((item) => Boolean(
|
|
1011
|
+
const predExpr = args[1];
|
|
1012
|
+
return (arr ?? []).some((item, i) => Boolean(evalWithItem(predExpr, evaluate2, ctx, item, i)));
|
|
1025
1013
|
}
|
|
1026
1014
|
function evalArrayCount(args, evaluate2, ctx) {
|
|
1027
1015
|
const arr = evaluate2(args[0], ctx);
|
|
1028
1016
|
if (args.length > 1) {
|
|
1029
|
-
const
|
|
1030
|
-
return (arr ?? []).filter((item) =>
|
|
1017
|
+
const predExpr = args[1];
|
|
1018
|
+
return (arr ?? []).filter((item, i) => evalWithItem(predExpr, evaluate2, ctx, item, i)).length;
|
|
1031
1019
|
}
|
|
1032
1020
|
return arr?.length ?? 0;
|
|
1033
1021
|
}
|
|
@@ -1084,16 +1072,16 @@ function evalArrayGroupBy(args, evaluate2, ctx) {
|
|
|
1084
1072
|
}
|
|
1085
1073
|
function evalArrayPartition(args, evaluate2, ctx) {
|
|
1086
1074
|
const arr = evaluate2(args[0], ctx);
|
|
1087
|
-
const
|
|
1075
|
+
const predExpr = args[1];
|
|
1088
1076
|
const matches = [];
|
|
1089
1077
|
const nonMatches = [];
|
|
1090
|
-
|
|
1091
|
-
if (
|
|
1078
|
+
(arr ?? []).forEach((item, i) => {
|
|
1079
|
+
if (evalWithItem(predExpr, evaluate2, ctx, item, i)) {
|
|
1092
1080
|
matches.push(item);
|
|
1093
1081
|
} else {
|
|
1094
1082
|
nonMatches.push(item);
|
|
1095
1083
|
}
|
|
1096
|
-
}
|
|
1084
|
+
});
|
|
1097
1085
|
return [matches, nonMatches];
|
|
1098
1086
|
}
|
|
1099
1087
|
function evalArrayTake(args, evaluate2, ctx) {
|
|
@@ -1118,7 +1106,7 @@ function evalArrayDropLast(args, evaluate2, ctx) {
|
|
|
1118
1106
|
}
|
|
1119
1107
|
|
|
1120
1108
|
// std/object.ts
|
|
1121
|
-
function
|
|
1109
|
+
function evalLambda(lambdaExpr, evaluate2, ctx, ...values) {
|
|
1122
1110
|
if (!isSExpr(lambdaExpr) || getOperator(lambdaExpr) !== "fn") {
|
|
1123
1111
|
return evaluate2(lambdaExpr, ctx);
|
|
1124
1112
|
}
|
|
@@ -1258,7 +1246,7 @@ function evalObjectMapValues(args, evaluate2, ctx) {
|
|
|
1258
1246
|
const lambda = args[1];
|
|
1259
1247
|
const result = {};
|
|
1260
1248
|
for (const [key, value] of Object.entries(obj ?? {})) {
|
|
1261
|
-
result[key] =
|
|
1249
|
+
result[key] = evalLambda(lambda, evaluate2, ctx, value);
|
|
1262
1250
|
}
|
|
1263
1251
|
return result;
|
|
1264
1252
|
}
|
|
@@ -1267,7 +1255,7 @@ function evalObjectMapKeys(args, evaluate2, ctx) {
|
|
|
1267
1255
|
const lambda = args[1];
|
|
1268
1256
|
const result = {};
|
|
1269
1257
|
for (const [key, value] of Object.entries(obj ?? {})) {
|
|
1270
|
-
const newKey = String(
|
|
1258
|
+
const newKey = String(evalLambda(lambda, evaluate2, ctx, key));
|
|
1271
1259
|
result[newKey] = value;
|
|
1272
1260
|
}
|
|
1273
1261
|
return result;
|
|
@@ -1277,7 +1265,7 @@ function evalObjectFilter(args, evaluate2, ctx) {
|
|
|
1277
1265
|
const lambda = args[1];
|
|
1278
1266
|
const result = {};
|
|
1279
1267
|
for (const [key, value] of Object.entries(obj ?? {})) {
|
|
1280
|
-
if (
|
|
1268
|
+
if (evalLambda(lambda, evaluate2, ctx, key, value)) {
|
|
1281
1269
|
result[key] = value;
|
|
1282
1270
|
}
|
|
1283
1271
|
}
|