@dallaylaen/ski-interpreter 2.5.2 → 2.6.1
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/CHANGELOG.md +23 -2
- package/lib/ski-interpreter.cjs.js +34 -20
- package/lib/ski-interpreter.cjs.js.map +2 -2
- package/lib/ski-interpreter.min.js +8 -8
- package/lib/ski-interpreter.min.js.map +3 -3
- package/lib/{ski-interpreter.esm.js → ski-interpreter.mjs} +35 -21
- package/lib/{ski-interpreter.esm.js.map → ski-interpreter.mjs.map} +2 -2
- package/lib/ski-quest.min.js +8 -8
- package/lib/ski-quest.min.js.map +3 -3
- package/lib/types/expr.d.ts +29 -16
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.6.1] - 2026-03-29
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- renames `ski-interpreter.esm.js` -> `ski-interpreter.mjs`
|
|
13
|
+
and fixed types location in package.json
|
|
14
|
+
because ESM was not recognizing the package correctly.
|
|
15
|
+
|
|
16
|
+
## [2.6.0] - 2026-03-28
|
|
17
|
+
|
|
18
|
+
### BREAKING CHANGES
|
|
19
|
+
|
|
20
|
+
- `Alias`: `outdated` and `terminal` properties replaced by
|
|
21
|
+
`inline`: boolean.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Experimental `Alias.makeInline()` that sets the inline property
|
|
26
|
+
and adjusts the invocation accordingly
|
|
27
|
+
- (don't wait for more args if inline).
|
|
28
|
+
|
|
8
29
|
## [2.5.2] - 2026-03-27
|
|
9
30
|
|
|
10
31
|
### Changed
|
|
@@ -26,7 +47,7 @@ and mark its abstract/final/protected methods appropriately.
|
|
|
26
47
|
|
|
27
48
|
### BREAKING CHANGES
|
|
28
49
|
|
|
29
|
-
- `affine: true` in quests now means "has no duplicating subterms" rather than "non-duplicating as a whole."
|
|
50
|
+
- `affine: true` in quests now means "has no duplicating subterms" rather than "non-duplicating as a whole."
|
|
30
51
|
Aliases are exempted from this check, so a solution `SK`
|
|
31
52
|
will not pass as S is duplicating, but `false=SK; false`
|
|
32
53
|
will because `false` (as a whole term) _is_ affine.
|
|
@@ -81,7 +102,7 @@ will because `false` (as a whole term) _is_ affine.
|
|
|
81
102
|
### Changed
|
|
82
103
|
|
|
83
104
|
- `SKI.extras.foldr` is now removed in favor of
|
|
84
|
-
`Expr.foldBottomUp<T>(fun: (expr: Expr, args: T[]) => T): T`
|
|
105
|
+
`Expr.foldBottomUp<T>(fun: (expr: Expr, args: T[]) => T): T`
|
|
85
106
|
with the same semantics but more descriptive name
|
|
86
107
|
and simpler signature.
|
|
87
108
|
_Was experimental (and still is), so not considered a breaking change._
|
|
@@ -14830,8 +14830,8 @@ var Church = class _Church extends Expr {
|
|
|
14830
14830
|
return nargs >= 2 ? options.redex[0] + this.n + options.redex[1] : this.n + "";
|
|
14831
14831
|
}
|
|
14832
14832
|
};
|
|
14833
|
-
function waitn(
|
|
14834
|
-
return
|
|
14833
|
+
function waitn(n) {
|
|
14834
|
+
return n <= 1 ? (e) => (arg) => e.apply(arg) : (e) => (arg) => waitn(n - 1)(e.apply(arg));
|
|
14835
14835
|
}
|
|
14836
14836
|
var Alias = class extends Named {
|
|
14837
14837
|
constructor(name, impl, options = {}) {
|
|
@@ -14840,17 +14840,28 @@ var Alias = class extends Named {
|
|
|
14840
14840
|
throw new Error("Attempt to create an alias for a non-expression: " + impl);
|
|
14841
14841
|
this.impl = impl;
|
|
14842
14842
|
this._setup(options);
|
|
14843
|
-
this.
|
|
14844
|
-
this.invoke = waitn(impl, this.arity ?? 0);
|
|
14843
|
+
this.invoke = waitn(options.inline ? 0 : this.arity ?? 0)(impl);
|
|
14845
14844
|
this.size = impl.size;
|
|
14846
|
-
if (options.
|
|
14847
|
-
this.
|
|
14845
|
+
if (options.inline)
|
|
14846
|
+
this.inline = true;
|
|
14847
|
+
}
|
|
14848
|
+
/**
|
|
14849
|
+
* @desc Make the alias inline, i.e. replace it with its implementation everywhere.
|
|
14850
|
+
*
|
|
14851
|
+
* Replaces the old `outdated` attribute.
|
|
14852
|
+
* Used by the parser when a term definition is removed or updated.
|
|
14853
|
+
*
|
|
14854
|
+
* May change in future versions, use with caution.
|
|
14855
|
+
*
|
|
14856
|
+
* @experimental
|
|
14857
|
+
* @returns {this}
|
|
14858
|
+
*/
|
|
14859
|
+
makeInline() {
|
|
14860
|
+
this.invoke = waitn(0)(this.impl);
|
|
14861
|
+
this.inline = true;
|
|
14862
|
+
return this;
|
|
14848
14863
|
}
|
|
14849
14864
|
/**
|
|
14850
|
-
* @property {boolean} [outdated] - whether the alias is outdated
|
|
14851
|
-
* and should be replaced with its definition when encountered.
|
|
14852
|
-
* @property {boolean} [terminal] - whether the alias should behave like a standalone term
|
|
14853
|
-
* // TODO better name?
|
|
14854
14865
|
* @property {boolean} [proper] - whether the alias is a proper combinator (i.e. contains no free variables or constants)
|
|
14855
14866
|
* @property {number} [arity] - the number of arguments the alias waits for before expanding
|
|
14856
14867
|
* @property {Expr} [canonical] - equivalent lambda term.
|
|
@@ -14893,11 +14904,11 @@ var Alias = class extends Named {
|
|
|
14893
14904
|
return other.diff(this.impl, !swap);
|
|
14894
14905
|
}
|
|
14895
14906
|
_braced(first) {
|
|
14896
|
-
return this.
|
|
14907
|
+
return this.inline ? this.impl._braced(first) : false;
|
|
14897
14908
|
}
|
|
14898
14909
|
formatImpl(options, nargs) {
|
|
14899
|
-
const
|
|
14900
|
-
return
|
|
14910
|
+
const inline = options.inventory ? options.inventory[this.name] !== this : this.inline;
|
|
14911
|
+
return inline ? this.impl.formatImpl(options, nargs) : super.formatImpl(options, nargs);
|
|
14901
14912
|
}
|
|
14902
14913
|
diag(indent = "") {
|
|
14903
14914
|
return `${indent}Alias (${this.name}): \\
|
|
@@ -15109,8 +15120,9 @@ var Parser = class {
|
|
|
15109
15120
|
const named = this._named(term, impl);
|
|
15110
15121
|
const opts = typeof options === "string" ? { note: options, canonize: false } : options ?? {};
|
|
15111
15122
|
named._setup({ canonize: this.annotate, ...opts });
|
|
15112
|
-
|
|
15113
|
-
|
|
15123
|
+
const old = this.known[named.name];
|
|
15124
|
+
if (old instanceof Alias)
|
|
15125
|
+
old.makeInline();
|
|
15114
15126
|
this.known[named.name] = named;
|
|
15115
15127
|
this.allow.add(named.name);
|
|
15116
15128
|
return this;
|
|
@@ -15210,7 +15222,9 @@ var Parser = class {
|
|
|
15210
15222
|
* @return {SKI}
|
|
15211
15223
|
*/
|
|
15212
15224
|
remove(name) {
|
|
15213
|
-
this.known[name]
|
|
15225
|
+
const old = this.known[name];
|
|
15226
|
+
if (old instanceof Alias)
|
|
15227
|
+
old.makeInline();
|
|
15214
15228
|
delete this.known[name];
|
|
15215
15229
|
this.allow.delete(name);
|
|
15216
15230
|
return this;
|
|
@@ -15295,7 +15309,7 @@ var Parser = class {
|
|
|
15295
15309
|
let expr = new Empty();
|
|
15296
15310
|
for (const item of lines) {
|
|
15297
15311
|
if (expr instanceof Alias)
|
|
15298
|
-
expr.
|
|
15312
|
+
expr.makeInline();
|
|
15299
15313
|
const def = item.match(/^([A-Z]|[a-z][a-z_0-9]*)\s*=(.*)$/s);
|
|
15300
15314
|
if (def && def[2] === "")
|
|
15301
15315
|
expr = new FreeVar(def[1], options.scope ?? FreeVar.global);
|
|
@@ -15309,7 +15323,7 @@ var Parser = class {
|
|
|
15309
15323
|
}
|
|
15310
15324
|
if (this.addContext) {
|
|
15311
15325
|
if (expr instanceof Named)
|
|
15312
|
-
expr = new Alias(expr.name, expr, {
|
|
15326
|
+
expr = new Alias(expr.name, expr, { inline: true });
|
|
15313
15327
|
expr.context = {
|
|
15314
15328
|
env: { ...this.getTerms(), ...jar },
|
|
15315
15329
|
// also contains pre-parsed terms
|
|
@@ -15417,7 +15431,7 @@ var Quest = class {
|
|
|
15417
15431
|
for (const term of env ?? []) {
|
|
15418
15432
|
const expr = this.engineFull.parse(term, { env: jar, scope: this });
|
|
15419
15433
|
if (expr instanceof Alias)
|
|
15420
|
-
this.env[expr.name] = new Alias(expr.name, expr.impl, {
|
|
15434
|
+
this.env[expr.name] = new Alias(expr.name, expr.impl, { canonize: false });
|
|
15421
15435
|
else if (expr instanceof FreeVar)
|
|
15422
15436
|
this.env[expr.name] = expr;
|
|
15423
15437
|
else
|
|
@@ -15506,7 +15520,7 @@ var Quest = class {
|
|
|
15506
15520
|
if (e instanceof Named && arsenal[e.name] === e)
|
|
15507
15521
|
return control.prune(a + 1);
|
|
15508
15522
|
});
|
|
15509
|
-
const expr = impl instanceof FreeVar ? impl : new Alias(spec.fancy ?? spec.name, impl, {
|
|
15523
|
+
const expr = impl instanceof FreeVar ? impl : new Alias(spec.fancy ?? spec.name, impl, { canonize: false });
|
|
15510
15524
|
jar[spec.name] = expr;
|
|
15511
15525
|
prepared.push(expr);
|
|
15512
15526
|
}
|