@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.
- package/CHANGELOG.md +17 -0
- package/README.md +13 -7
- package/lib/ski-interpreter.cjs.js +86 -69
- package/lib/ski-interpreter.cjs.js.map +2 -2
- package/lib/ski-interpreter.esm.js +86 -69
- package/lib/ski-interpreter.esm.js.map +2 -2
- package/lib/ski-interpreter.min.js +10 -7
- package/lib/ski-interpreter.min.js.map +3 -3
- package/lib/ski-quest.min.js +10 -7
- package/lib/ski-quest.min.js.map +3 -3
- package/lib/types/expr.d.ts +84 -45
- package/lib/types/index.d.ts +12 -1
- package/lib/types/internal.d.ts +1 -4
- package/lib/types/quest.d.ts +1 -1
- package/package.json +1 -1
|
@@ -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
|
-
* @
|
|
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
|
-
* @
|
|
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
|
-
* @
|
|
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
|
|
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
|
|
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
|
-
* @
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
14632
|
-
const fun = this.fun.
|
|
14633
|
-
const arg = this.arg.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
14760
|
-
return (nargs > 0 ? options.brackets[0] : "") + options.lambda[0] + this.arg.
|
|
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
|
-
|
|
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
|
-
|
|
14878
|
+
formatImpl(options, nargs) {
|
|
14861
14879
|
const outdated = options.inventory ? options.inventory[this.name] !== this : this.outdated;
|
|
14862
|
-
return outdated ? this.impl.
|
|
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
|
-
|
|
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, {
|