@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.
@@ -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: ["let", [[name, value], ...], body]
239
- * Creates local bindings for use in body.
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, ["fn", varName, body]]
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, ["fn", varName, predicate]]
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, ["fn", varName, predicate]]
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, ["fn", varName, mapper]]
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-DBM7Xkm3.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-DBM7Xkm3.js';
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 bindings = args[0];
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 binding of bindings) {
262
- const name = binding[0];
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 fnExpr = args[1];
304
- const params = fnExpr[1];
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 fnExpr = args[1];
317
- const params = fnExpr[1];
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 fnExpr = args[1];
330
- const params = fnExpr[1];
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 fnExpr = args[1];
350
- const params = fnExpr[1];
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(varName, item);
334
+ locals.set("item", item);
335
+ locals.set("index", i);
356
336
  const childCtx = createChildContext(ctx, locals);
357
- return sum + toNumber2(evaluate2(body, childCtx));
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 evalLambda(lambdaExpr, evaluate2, ctx, ...values) {
829
- if (!isSExpr(lambdaExpr) || getOperator(lambdaExpr) !== "fn") {
830
- return evaluate2(lambdaExpr, ctx);
831
- }
832
- const args = getArgs(lambdaExpr);
833
- const params = args[0];
834
- const body = args[1];
835
- const newLocals = /* @__PURE__ */ new Map();
836
- if (Array.isArray(params)) {
837
- const paramNames = params;
838
- values.forEach((v, i) => {
839
- if (paramNames[i]) {
840
- const paramName = paramNames[i];
841
- const key = paramName.startsWith("@") ? paramName.slice(1) : paramName;
842
- newLocals.set(key, v);
843
- }
844
- });
845
- } else if (typeof params === "string") {
846
- const paramName = params.startsWith("@") ? params.slice(1) : params;
847
- newLocals.set(paramName, values[0]);
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
- const childCtx = createChildContext(ctx, newLocals);
850
- return evaluate2(body, childCtx);
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 lambda = args[1];
985
- return (arr ?? []).find((item) => evalLambda(lambda, evaluate2, ctx, 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 lambda = args[1];
990
- return (arr ?? []).findIndex((item) => evalLambda(lambda, evaluate2, ctx, 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 lambda = args[1];
995
- return (arr ?? []).filter((item) => evalLambda(lambda, evaluate2, ctx, 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 lambda = args[1];
1000
- return (arr ?? []).filter((item) => !evalLambda(lambda, evaluate2, ctx, 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 lambda = args[1];
1005
- return (arr ?? []).map((item) => evalLambda(lambda, evaluate2, ctx, 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 lambda = args[1];
1010
- const init = evaluate2(args[2], ctx);
997
+ const init = evaluate2(args[1], ctx);
998
+ const reducerExpr = args[2];
1011
999
  return (arr ?? []).reduce(
1012
- (acc, item) => evalLambda(lambda, evaluate2, ctx, 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 lambda = args[1];
1019
- return (arr ?? []).every((item) => Boolean(evalLambda(lambda, evaluate2, ctx, item)));
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 lambda = args[1];
1024
- return (arr ?? []).some((item) => Boolean(evalLambda(lambda, evaluate2, ctx, item)));
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 lambda = args[1];
1030
- return (arr ?? []).filter((item) => evalLambda(lambda, evaluate2, ctx, item)).length;
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 lambda = args[1];
1075
+ const predExpr = args[1];
1088
1076
  const matches = [];
1089
1077
  const nonMatches = [];
1090
- for (const item of arr ?? []) {
1091
- if (evalLambda(lambda, evaluate2, ctx, item)) {
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 evalLambda2(lambdaExpr, evaluate2, ctx, ...values) {
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] = evalLambda2(lambda, evaluate2, ctx, value);
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(evalLambda2(lambda, evaluate2, ctx, key));
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 (evalLambda2(lambda, evaluate2, ctx, key, value)) {
1268
+ if (evalLambda(lambda, evaluate2, ctx, key, value)) {
1281
1269
  result[key] = value;
1282
1270
  }
1283
1271
  }