@dallaylaen/ski-interpreter 2.5.0 → 2.5.2

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.
@@ -13869,18 +13869,11 @@ var FormatOptionsSchema = external_exports.object({
13869
13869
  inventory: external_exports.record(external_exports.string(), external_exports.custom((v) => v instanceof Expr)).optional()
13870
13870
  });
13871
13871
  var Expr = class _Expr {
13872
- static {
13873
- this.control = control;
13874
- }
13875
- static {
13876
- this.native = native;
13877
- }
13878
- // rough estimate of the number of nodes in the tree
13879
13872
  /**
13880
13873
  *
13881
13874
  * @desc Define properties of the term based on user supplied options and/or inference results.
13882
13875
  * Typically useful for declaring Native and Alias terms.
13883
- * @private
13876
+ * @protected
13884
13877
  * @param {Object} options
13885
13878
  * @param {string} [options.note] - a brief description what the term does
13886
13879
  * @param {number} [options.arity] - number of arguments the term is waiting for (if known)
@@ -13955,6 +13948,7 @@ var Expr = class _Expr {
13955
13948
  * }} [options]
13956
13949
  * @param {(e:Expr) => TraverseValue<Expr>} change
13957
13950
  * @returns {Expr|null}
13951
+ * @final
13958
13952
  */
13959
13953
  traverse(options, change) {
13960
13954
  if (typeof options === "function") {
@@ -13968,7 +13962,8 @@ var Expr = class _Expr {
13968
13962
  return expr ?? null;
13969
13963
  }
13970
13964
  /**
13971
- * @private
13965
+ * @protected
13966
+ * @final
13972
13967
  * @param {Object} options
13973
13968
  * @param {(e:Expr) => TraverseValue<Expr>} change
13974
13969
  * @returns {TraverseValue<Expr>}
@@ -13987,7 +13982,7 @@ var Expr = class _Expr {
13987
13982
  return action ? action(expr) : expr;
13988
13983
  }
13989
13984
  /**
13990
- * @private
13985
+ * @protected
13991
13986
  * @param {Object} options
13992
13987
  * @param {(e:Expr) => TraverseValue<Expr>} change
13993
13988
  * @returns {TraverseValue<Expr>}
@@ -14017,7 +14012,11 @@ var Expr = class _Expr {
14017
14012
  *
14018
14013
  * This method is experimental and may change in the future.
14019
14014
  *
14015
+ * @example // count the number of nodes in the expression tree
14016
+ * expr.fold(0, (acc, e) => acc + 1);
14017
+ *
14020
14018
  * @experimental
14019
+ * @final
14021
14020
  * @template T
14022
14021
  * @param {T} initial
14023
14022
  * @param {(acc: T, expr: Expr) => TraverseValue<T>} combine
@@ -14027,6 +14026,14 @@ var Expr = class _Expr {
14027
14026
  const [value] = unwrap(this._fold(initial, combine));
14028
14027
  return value ?? initial;
14029
14028
  }
14029
+ /**
14030
+ * @desc Internal method for fold(), which performs the actual folding.
14031
+ * Should be implemented in subclasses having any internal structure.
14032
+ *
14033
+ * @protected
14034
+ * @param initial
14035
+ * @param combine
14036
+ */
14030
14037
  _fold(initial, combine) {
14031
14038
  return combine(initial, this);
14032
14039
  }
@@ -14070,6 +14077,7 @@ var Expr = class _Expr {
14070
14077
  *
14071
14078
  * Use toLambda() if you want to get a lambda term in any case.
14072
14079
  *
14080
+ * @final
14073
14081
  * @param {{max?: number, maxArgs?: number}} options
14074
14082
  * @return {TermInfo}
14075
14083
  */
@@ -14162,6 +14170,7 @@ var Expr = class _Expr {
14162
14170
  *
14163
14171
  * See also Expr.walk() and Expr.toSKI().
14164
14172
  *
14173
+ * @final
14165
14174
  * @param {{
14166
14175
  * max?: number,
14167
14176
  * maxArgs?: number,
@@ -14208,6 +14217,7 @@ var Expr = class _Expr {
14208
14217
  *
14209
14218
  * See also Expr.walk() and Expr.toLambda().
14210
14219
  *
14220
+ * @final
14211
14221
  * @param {{max?: number}} [options]
14212
14222
  * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
14213
14223
  */
@@ -14238,12 +14248,15 @@ var Expr = class _Expr {
14238
14248
  }
14239
14249
  }
14240
14250
  /**
14241
- * Replace all instances of plug in the expression with value and return the resulting expression,
14251
+ * Replace all instances of `search` in the expression with `replace` and return the resulting expression,
14242
14252
  * or null if no changes could be made.
14253
+ *
14243
14254
  * Lambda terms and applications will never match if used as plug
14244
- * as they are impossible co compare without extensive computations.
14255
+ * as they are impossible to compare without extensive computations.
14256
+ *
14245
14257
  * Typically used on variables but can also be applied to other terms, e.g. aliases.
14246
- * See also Expr.traverse().
14258
+ * See also Expr.traverse() for more flexible replacement of subterms.
14259
+ *
14247
14260
  * @param {Expr} search
14248
14261
  * @param {Expr} replace
14249
14262
  * @return {Expr|null}
@@ -14284,6 +14297,7 @@ var Expr = class _Expr {
14284
14297
  * @desc Run uninterrupted sequence of step() applications
14285
14298
  * until the expression is irreducible, or max number of steps is reached.
14286
14299
  * Default number of steps = 1000.
14300
+ * @final
14287
14301
  * @param {{max?: number, steps?: number, throw?: boolean}|Expr} [opt]
14288
14302
  * @param {Expr} args
14289
14303
  * @return {{expr: Expr, steps: number, final: boolean}}
@@ -14314,7 +14328,9 @@ var Expr = class _Expr {
14314
14328
  }
14315
14329
  /**
14316
14330
  * Execute step() while possible, yielding a brief description of events after each step.
14331
+ *
14317
14332
  * Mnemonics: like run() but slower.
14333
+ * @final
14318
14334
  * @param {{max?: number}} options
14319
14335
  * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
14320
14336
  */
@@ -14344,6 +14360,7 @@ var Expr = class _Expr {
14344
14360
  *
14345
14361
  * @param {Expr} other
14346
14362
  * @return {boolean}
14363
+ * @final
14347
14364
  */
14348
14365
  equals(other) {
14349
14366
  return !this.diff(other);
@@ -14362,6 +14379,8 @@ var Expr = class _Expr {
14362
14379
  * To somewhat alleviate confusion, the output will include
14363
14380
  * the internal id of the variable in square brackets.
14364
14381
  *
14382
+ * Do not rely on the exact format of the output as it may change in the future.
14383
+ *
14365
14384
  * @example "K(S != I)" is the result of comparing "KS" and "KI"
14366
14385
  * @example "S(K([x[13] != x[14]]))K"
14367
14386
  *
@@ -14382,6 +14401,11 @@ var Expr = class _Expr {
14382
14401
  * `this` is the expected value and the argument is the actual one.
14383
14402
  * Mnemonic: the expected value is always a combinator, the actual one may be anything.
14384
14403
  *
14404
+ * In case of failure, an error is thrown with a message describing the first point of difference
14405
+ * and `expected` and `actual` properties like in AssertionError.
14406
+ * AssertionError is not used directly to because browsers don't recognize it.
14407
+ *
14408
+ * @final
14385
14409
  * @param {Expr} actual
14386
14410
  * @param {string} comment
14387
14411
  */
@@ -14401,7 +14425,10 @@ var Expr = class _Expr {
14401
14425
  /**
14402
14426
  * @desc Returns string representation of the expression.
14403
14427
  * Same as format() without options.
14428
+ *
14429
+ * Use formatImpl() to override in subclasses.
14404
14430
  * @return {string}
14431
+ * @final
14405
14432
  */
14406
14433
  toString() {
14407
14434
  return this.format();
@@ -14410,6 +14437,7 @@ var Expr = class _Expr {
14410
14437
  * @desc Whether the expression needs parentheses when printed.
14411
14438
  * @param {boolean} [first] - whether this is the first term in a sequence
14412
14439
  * @return {boolean}
14440
+ * @protected
14413
14441
  */
14414
14442
  _braced(_first) {
14415
14443
  return false;
@@ -14418,7 +14446,7 @@ var Expr = class _Expr {
14418
14446
  * @desc Whether the expression can be printed without a space when followed by arg.
14419
14447
  * @param {Expr} arg
14420
14448
  * @returns {boolean}
14421
- * @private
14449
+ * @protected
14422
14450
  */
14423
14451
  _unspaced(arg) {
14424
14452
  return this._braced(true);
@@ -14426,8 +14454,9 @@ var Expr = class _Expr {
14426
14454
  /**
14427
14455
  * @desc Stringify the expression with fancy formatting options.
14428
14456
  * Said options mostly include wrappers around various constructs in form of ['(', ')'],
14429
- * as well as terse and html flags that set up the defaults.
14457
+ * as well as `terse` and `html` flags that fill in appropriate defaults.
14430
14458
  * Format without options is equivalent to toString() and can be parsed back.
14459
+ * @final
14431
14460
  *
14432
14461
  * @param {Object} [options] - formatting options
14433
14462
  * @param {boolean} [options.terse] - whether to use terse formatting (omitting unnecessary spaces and parentheses)
@@ -14472,7 +14501,7 @@ var Expr = class _Expr {
14472
14501
  around: ["", ""],
14473
14502
  redex: ["", ""]
14474
14503
  };
14475
- return this._format({
14504
+ return this.formatImpl({
14476
14505
  terse: options.terse ?? true,
14477
14506
  brackets: options.brackets ?? fallback.brackets,
14478
14507
  space: options.space ?? fallback.space,
@@ -14485,16 +14514,6 @@ var Expr = class _Expr {
14485
14514
  html: options.html ?? false
14486
14515
  }, 0);
14487
14516
  }
14488
- /**
14489
- * @desc Internal method for format(), which performs the actual formatting.
14490
- * @param {Object} options
14491
- * @param {number} nargs
14492
- * @returns {string}
14493
- * @private
14494
- */
14495
- _format(options, nargs) {
14496
- throw new Error("No _format() method defined in class " + this.constructor.name);
14497
- }
14498
14517
  /**
14499
14518
  * @desc Returns a string representation of the expression tree, with indentation to show structure.
14500
14519
  *
@@ -14516,24 +14535,13 @@ var Expr = class _Expr {
14516
14535
  * FreeVar: x[54]
14517
14536
  * FreeVar: x[54]
14518
14537
  */
14519
- diag() {
14520
- const rec = (e, indent) => {
14521
- if (e instanceof App)
14522
- return [indent + "App:", ...e.unroll().flatMap((s) => rec(s, indent + " "))];
14523
- if (e instanceof Lambda)
14524
- return [`${indent}Lambda (${e.arg}[${e.arg.id}]):`, ...rec(e.impl, indent + " ")];
14525
- if (e instanceof Alias)
14526
- return [`${indent}Alias (${e.name}): \\`, ...rec(e.impl, indent)];
14527
- if (e instanceof FreeVar)
14528
- return [`${indent}FreeVar: ${e.name}[${e.id}]`];
14529
- return [`${indent}${e.constructor.name}: ${e}`];
14530
- };
14531
- const out = rec(this, "");
14532
- return out.join("\n");
14538
+ diag(indent = "") {
14539
+ return indent + this.constructor.name + ": " + this;
14533
14540
  }
14534
14541
  /**
14535
14542
  * @desc Convert the expression to a JSON-serializable format.
14536
14543
  * @returns {string}
14544
+ * @final
14537
14545
  */
14538
14546
  toJSON() {
14539
14547
  return this.format();
@@ -14628,15 +14636,18 @@ var App = class _App extends Expr {
14628
14636
  _braced(first) {
14629
14637
  return !first;
14630
14638
  }
14631
- _format(options, nargs) {
14632
- const fun = this.fun._format(options, nargs + 1);
14633
- const arg = this.arg._format(options, 0);
14639
+ formatImpl(options, nargs) {
14640
+ const fun = this.fun.formatImpl(options, nargs + 1);
14641
+ const arg = this.arg.formatImpl(options, 0);
14634
14642
  const wrap = nargs ? ["", ""] : options.around;
14635
14643
  if (options.terse && !this.arg._braced(false))
14636
14644
  return wrap[0] + fun + (this.fun._unspaced(this.arg) ? "" : options.space) + arg + wrap[1];
14637
14645
  else
14638
14646
  return wrap[0] + fun + options.brackets[0] + arg + options.brackets[1] + wrap[1];
14639
14647
  }
14648
+ diag(indent = "") {
14649
+ return indent + "App:\n" + this.unroll().map((e) => e.diag(indent + " ")).join("\n");
14650
+ }
14640
14651
  _unspaced(arg) {
14641
14652
  return this.arg._braced(false) ? true : this.arg._unspaced(arg);
14642
14653
  }
@@ -14651,7 +14662,7 @@ var Named = class _Named extends Expr {
14651
14662
  _unspaced(arg) {
14652
14663
  return !!(arg instanceof _Named && (this.name.match(/^[A-Z+]$/) && arg.name.match(/^[a-z+]/i) || this.name.match(/^[a-z+]/i) && arg.name.match(/^[A-Z+]$/)));
14653
14664
  }
14654
- _format(options, nargs) {
14665
+ formatImpl(options, nargs) {
14655
14666
  const name = options.html ? this.fancyName ?? this.name : this.name;
14656
14667
  return this.arity !== void 0 && this.arity > 0 && this.arity <= nargs ? options.redex[0] + name + options.redex[1] : name;
14657
14668
  }
@@ -14677,10 +14688,13 @@ var FreeVar = class _FreeVar extends Named {
14677
14688
  return replace;
14678
14689
  return null;
14679
14690
  }
14680
- _format(options, nargs) {
14691
+ formatImpl(options, nargs) {
14681
14692
  const name = options.html ? this.fancyName ?? this.name : this.name;
14682
14693
  return options.var[0] + name + options.var[1];
14683
14694
  }
14695
+ diag(indent = "") {
14696
+ return `${indent}FreeVar: ${this.name}[${this.id}]`;
14697
+ }
14684
14698
  static {
14685
14699
  this.global = ["global"];
14686
14700
  }
@@ -14756,8 +14770,12 @@ var Lambda = class _Lambda extends Expr {
14756
14770
  return "(t->" + diff + ")";
14757
14771
  return null;
14758
14772
  }
14759
- _format(options, nargs) {
14760
- return (nargs > 0 ? options.brackets[0] : "") + options.lambda[0] + this.arg._format(options, 0) + options.lambda[1] + this.impl._format(options, 0) + options.lambda[2] + (nargs > 0 ? options.brackets[1] : "");
14773
+ formatImpl(options, nargs) {
14774
+ return (nargs > 0 ? options.brackets[0] : "") + options.lambda[0] + this.arg.formatImpl(options, 0) + options.lambda[1] + this.impl.formatImpl(options, 0) + options.lambda[2] + (nargs > 0 ? options.brackets[1] : "");
14775
+ }
14776
+ diag(indent = "") {
14777
+ return `${indent}Lambda (${this.arg.name}[${this.arg.id}]):
14778
+ ` + this.impl.diag(indent + " ");
14761
14779
  }
14762
14780
  _braced(first) {
14763
14781
  return true;
@@ -14788,7 +14806,7 @@ var Church = class _Church extends Expr {
14788
14806
  _unspaced(arg) {
14789
14807
  return false;
14790
14808
  }
14791
- _format(options, nargs) {
14809
+ formatImpl(options, nargs) {
14792
14810
  return nargs >= 2 ? options.redex[0] + this.n + options.redex[1] : this.n + "";
14793
14811
  }
14794
14812
  };
@@ -14857,9 +14875,13 @@ var Alias = class extends Named {
14857
14875
  _braced(first) {
14858
14876
  return this.outdated ? this.impl._braced(first) : false;
14859
14877
  }
14860
- _format(options, nargs) {
14878
+ formatImpl(options, nargs) {
14861
14879
  const outdated = options.inventory ? options.inventory[this.name] !== this : this.outdated;
14862
- return outdated ? this.impl._format(options, nargs) : super._format(options, nargs);
14880
+ return outdated ? this.impl.formatImpl(options, nargs) : super.formatImpl(options, nargs);
14881
+ }
14882
+ diag(indent = "") {
14883
+ return `${indent}Alias (${this.name}): \\
14884
+ ` + this.impl.diag(indent);
14863
14885
  }
14864
14886
  };
14865
14887
  function addNative(name, impl, opt = {}) {
@@ -14973,6 +14995,9 @@ var Empty = class extends Expr {
14973
14995
  postParse() {
14974
14996
  throw new Error("Attempt to use empty expression () as a term");
14975
14997
  }
14998
+ formatImpl(options, nargs) {
14999
+ return "()";
15000
+ }
14976
15001
  };
14977
15002
  var PartialLambda = class _PartialLambda extends Empty {
14978
15003
  // TODO mutable! rewrite ro when have time
@@ -15222,9 +15247,7 @@ var Parser = class {
15222
15247
  list[j] = rework(list[j]);
15223
15248
  detour.set(needDetour[list[j].name], list[j]);
15224
15249
  env[list[j].name] = list[j];
15225
- console.log(`list[${j}] = ${list[j].name}=${list[j].impl};`);
15226
15250
  }
15227
- console.log("detour:", detour);
15228
15251
  }
15229
15252
  const out = list.map(
15230
15253
  (e) => needDetour[e.name] ? e.name + "=" + needDetour[e.name].name + "=" + e.impl.format({ inventory: env }) : e.name + "=" + e.impl.format({ inventory: env })
@@ -15352,22 +15375,6 @@ var Parser = class {
15352
15375
  /**
15353
15376
  * Public static shortcuts to common functions (see also ./extras.js)
15354
15377
  */
15355
- /**
15356
- * @desc Create a proxy object that generates variables on demand,
15357
- * with names corresponding to the property accessed.
15358
- * Different invocations will return distinct variables,
15359
- * even if with the same name.
15360
- *
15361
- *
15362
- * @example const {x, y, z} = SKI.vars();
15363
- * x.name; // 'x'
15364
- * x instanceof FreeVar; // true
15365
- * x.apply(y).apply(z); // x(y)(z)
15366
- *
15367
- * @template T
15368
- * @param {T} [scope] - optional context to bind the generated variables to
15369
- * @return {{[key: string]: FreeVar}}
15370
- */
15371
15378
  };
15372
15379
  function maybeAlias(name, impl) {
15373
15380
  while (impl instanceof Alias && impl.name === name)
@@ -15911,7 +15918,17 @@ var SKI = class extends Parser {
15911
15918
  static {
15912
15919
  this.W = native.W;
15913
15920
  }
15914
- // variable generator shortcut
15921
+ /**
15922
+ * @desc Create a proxy object that generates variables on demand,
15923
+ * with names corresponding to the property accessed.
15924
+ * Different invocations will return distinct variables,
15925
+ * even if with the same name.
15926
+ *
15927
+ * @example const {x, y, z} = SKI.vars();
15928
+ * x.name; // 'x'
15929
+ * x instanceof FreeVar; // true
15930
+ * x.apply(y).apply(z); // x(y)(z)
15931
+ */
15915
15932
  static vars(scope = {}) {
15916
15933
  const vars = {};
15917
15934
  return new Proxy(vars, {