@dallaylaen/ski-interpreter 2.2.0 → 2.2.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 +14 -0
- package/README.md +25 -4
- package/lib/ski-interpreter.cjs.js +160 -80
- package/lib/ski-interpreter.cjs.js.map +2 -2
- package/lib/ski-interpreter.esm.js +160 -80
- package/lib/ski-interpreter.esm.js.map +2 -2
- package/lib/ski-interpreter.min.js +4 -0
- package/lib/ski-interpreter.min.js.map +7 -0
- package/lib/ski-quest.min.js +4 -0
- package/lib/ski-quest.min.js.map +7 -0
- package/package.json +8 -4
- package/types/src/expr.d.ts +134 -48
- package/types/src/extras.d.ts +17 -1
- package/types/src/internal.d.ts +23 -10
- package/types/src/parser.d.ts +40 -17
- package/types/src/quest.d.ts +43 -41
package/types/src/expr.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
export type
|
|
2
|
-
value: T | null;
|
|
3
|
-
action: string;
|
|
4
|
-
} | null;
|
|
1
|
+
export type TraverseValue<T_1> = T_1 | TraverseControl<T_1> | null;
|
|
5
2
|
export type Partial = Expr | ((arg0: Expr) => Partial);
|
|
6
3
|
/**
|
|
7
4
|
* @typedef {Expr | function(Expr): Partial} Partial
|
|
@@ -19,13 +16,19 @@ export class Expr {
|
|
|
19
16
|
* @return {Expr}
|
|
20
17
|
*/
|
|
21
18
|
expand(): Expr;
|
|
19
|
+
/**
|
|
20
|
+
* @desc Returns true if the expression contains only free variables and applications, false otherwise.
|
|
21
|
+
* @returns {boolean}
|
|
22
|
+
*/
|
|
22
23
|
freeOnly(): boolean;
|
|
23
24
|
/**
|
|
24
25
|
* @desc Traverse the expression tree, applying change() to each node.
|
|
25
26
|
* If change() returns an Expr, the node is replaced with that value.
|
|
26
|
-
* Otherwise, the node is
|
|
27
|
+
* Otherwise, the node is descended further (if applicable)
|
|
27
28
|
* or left unchanged.
|
|
28
29
|
*
|
|
30
|
+
* The traversal order is leftmost-outermost (LO), i.e. the same order as reduction steps are taken.
|
|
31
|
+
*
|
|
29
32
|
* Returns null if no changes were made, or the new expression otherwise.
|
|
30
33
|
*
|
|
31
34
|
* @param {(e:Expr) => (Expr|null)} change
|
|
@@ -55,13 +58,20 @@ export class Expr {
|
|
|
55
58
|
* @experimental
|
|
56
59
|
* @template T
|
|
57
60
|
* @param {T} initial
|
|
58
|
-
* @param {(acc: T, expr: Expr) =>
|
|
61
|
+
* @param {(acc: T, expr: Expr) => TraverseValue<T>} combine
|
|
59
62
|
* @returns {T}
|
|
60
63
|
*/
|
|
61
|
-
fold<
|
|
62
|
-
_fold(initial: any, combine: any): any;
|
|
64
|
+
fold<T_1>(initial: T_1, combine: (acc: T_1, expr: Expr) => TraverseValue<T_1>): T_1;
|
|
63
65
|
/**
|
|
64
|
-
* @
|
|
66
|
+
* @template T
|
|
67
|
+
* @param {T} initial
|
|
68
|
+
* @param {(acc: T, expr: Expr) => TraverseValue<T>} combine
|
|
69
|
+
* @returns {TraverseValue<T>}
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
private _fold;
|
|
73
|
+
/**
|
|
74
|
+
* @desc rough estimate of the term's complexity
|
|
65
75
|
* @return {number}
|
|
66
76
|
*/
|
|
67
77
|
weight(): number;
|
|
@@ -109,7 +119,15 @@ export class Expr {
|
|
|
109
119
|
* @param {{max: number, maxArgs: number, index: number}} options
|
|
110
120
|
* @param {FreeVar[]} preArgs
|
|
111
121
|
* @param {number} steps
|
|
112
|
-
* @returns {{
|
|
122
|
+
* @returns {{
|
|
123
|
+
* normal: boolean,
|
|
124
|
+
* steps: number,
|
|
125
|
+
* expr?: Expr,
|
|
126
|
+
* arity?: number,
|
|
127
|
+
* skip?: Set<number>,
|
|
128
|
+
* dup?: Set<number>,
|
|
129
|
+
* duplicate, discard, proper: boolean
|
|
130
|
+
* }
|
|
113
131
|
* @private
|
|
114
132
|
*/
|
|
115
133
|
private _infer;
|
|
@@ -144,7 +162,7 @@ export class Expr {
|
|
|
144
162
|
* latin?: number,
|
|
145
163
|
* }} options
|
|
146
164
|
* @param {number} [maxWeight] - maximum allowed weight of terms in the sequence
|
|
147
|
-
* @return {IterableIterator<{expr: Expr, steps
|
|
165
|
+
* @return {IterableIterator<{expr: Expr, steps?: number, comment?: string}>}
|
|
148
166
|
*/
|
|
149
167
|
toLambda(options?: {
|
|
150
168
|
max?: number;
|
|
@@ -155,8 +173,8 @@ export class Expr {
|
|
|
155
173
|
latin?: number;
|
|
156
174
|
}): IterableIterator<{
|
|
157
175
|
expr: Expr;
|
|
158
|
-
steps
|
|
159
|
-
comment
|
|
176
|
+
steps?: number;
|
|
177
|
+
comment?: string;
|
|
160
178
|
}>;
|
|
161
179
|
/**
|
|
162
180
|
* @desc Rewrite the expression into S, K, and I combinators step by step.
|
|
@@ -227,14 +245,14 @@ export class Expr {
|
|
|
227
245
|
* @desc Run uninterrupted sequence of step() applications
|
|
228
246
|
* until the expression is irreducible, or max number of steps is reached.
|
|
229
247
|
* Default number of steps = 1000.
|
|
230
|
-
* @param {{max
|
|
248
|
+
* @param {{max?: number, steps?: number, throw?: boolean}|Expr} [opt]
|
|
231
249
|
* @param {Expr} args
|
|
232
250
|
* @return {{expr: Expr, steps: number, final: boolean}}
|
|
233
251
|
*/
|
|
234
252
|
run(opt?: {
|
|
235
|
-
max
|
|
236
|
-
steps
|
|
237
|
-
throw
|
|
253
|
+
max?: number;
|
|
254
|
+
steps?: number;
|
|
255
|
+
throw?: boolean;
|
|
238
256
|
} | Expr, ...args: Expr): {
|
|
239
257
|
expr: Expr;
|
|
240
258
|
steps: number;
|
|
@@ -243,11 +261,11 @@ export class Expr {
|
|
|
243
261
|
/**
|
|
244
262
|
* Execute step() while possible, yielding a brief description of events after each step.
|
|
245
263
|
* Mnemonics: like run() but slower.
|
|
246
|
-
* @param {{max
|
|
264
|
+
* @param {{max?: number}} options
|
|
247
265
|
* @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
|
|
248
266
|
*/
|
|
249
267
|
walk(options?: {
|
|
250
|
-
max
|
|
268
|
+
max?: number;
|
|
251
269
|
}): IterableIterator<{
|
|
252
270
|
final: boolean;
|
|
253
271
|
expr: Expr;
|
|
@@ -365,6 +383,28 @@ export class Expr {
|
|
|
365
383
|
* @private
|
|
366
384
|
*/
|
|
367
385
|
private _format;
|
|
386
|
+
/**
|
|
387
|
+
* @desc Returns a string representation of the expression tree, with indentation to show structure.
|
|
388
|
+
*
|
|
389
|
+
* Applications are flattened to avoid excessive nesting.
|
|
390
|
+
* Variables include ids to distinguish different instances of the same variable name.
|
|
391
|
+
*
|
|
392
|
+
* May be useful for debugging.
|
|
393
|
+
*
|
|
394
|
+
* @returns {string}
|
|
395
|
+
*
|
|
396
|
+
* @example
|
|
397
|
+
* > console.log(ski.parse('C 5 x (x->x x)').diag())
|
|
398
|
+
* App:
|
|
399
|
+
* Native: C
|
|
400
|
+
* Church: 5
|
|
401
|
+
* FreeVar: x[53]
|
|
402
|
+
* Lambda (x[54]):
|
|
403
|
+
* App:
|
|
404
|
+
* FreeVar: x[54]
|
|
405
|
+
* FreeVar: x[54]
|
|
406
|
+
*/
|
|
407
|
+
diag(): string;
|
|
368
408
|
/**
|
|
369
409
|
* @desc Convert the expression to a JSON-serializable format.
|
|
370
410
|
* @returns {string}
|
|
@@ -390,9 +430,33 @@ export class App extends Expr {
|
|
|
390
430
|
fun: Expr;
|
|
391
431
|
final: boolean;
|
|
392
432
|
arity: number;
|
|
393
|
-
_infer(options: any, preArgs?: any[], steps?: number):
|
|
433
|
+
_infer(options: any, preArgs?: any[], steps?: number): {
|
|
434
|
+
normal: boolean;
|
|
435
|
+
steps: number;
|
|
436
|
+
expr?: Expr;
|
|
437
|
+
arity?: number;
|
|
438
|
+
skip?: Set<number>;
|
|
439
|
+
dup?: Set<number>;
|
|
440
|
+
duplicate: any;
|
|
441
|
+
discard: any;
|
|
442
|
+
proper: boolean;
|
|
443
|
+
} | {
|
|
444
|
+
normal: boolean;
|
|
445
|
+
steps: number;
|
|
446
|
+
} | {
|
|
447
|
+
expr: Expr;
|
|
448
|
+
arity?: number;
|
|
449
|
+
skip?: Set<number>;
|
|
450
|
+
dup?: Set<number>;
|
|
451
|
+
duplicate?: any;
|
|
452
|
+
discard?: any;
|
|
453
|
+
proper: boolean;
|
|
454
|
+
normal: boolean;
|
|
455
|
+
steps: number;
|
|
456
|
+
};
|
|
394
457
|
traverse(change: any): Expr;
|
|
395
458
|
any(predicate: any): any;
|
|
459
|
+
_fold(initial: any, combine: any): any;
|
|
396
460
|
subst(search: any, replace: any): Expr;
|
|
397
461
|
/**
|
|
398
462
|
* @return {{expr: Expr, steps: number}}
|
|
@@ -402,11 +466,7 @@ export class App extends Expr {
|
|
|
402
466
|
steps: number;
|
|
403
467
|
};
|
|
404
468
|
invoke(arg: any): Partial;
|
|
405
|
-
|
|
406
|
-
* @desc Convert the expression to SKI combinatory logic
|
|
407
|
-
* @return {Expr}
|
|
408
|
-
*/
|
|
409
|
-
_rski(options: any): Expr;
|
|
469
|
+
_rski(options: any): Expr | this;
|
|
410
470
|
diff(other: any, swap?: boolean): string;
|
|
411
471
|
_braced(first: any): boolean;
|
|
412
472
|
_format(options: any, nargs: any): string;
|
|
@@ -465,10 +525,24 @@ export class Lambda extends Expr {
|
|
|
465
525
|
arg: FreeVar;
|
|
466
526
|
impl: Expr;
|
|
467
527
|
arity: number;
|
|
468
|
-
_infer(options: any, preArgs?: any[], steps?: number):
|
|
528
|
+
_infer(options: any, preArgs?: any[], steps?: number): {
|
|
529
|
+
normal: boolean;
|
|
530
|
+
steps: number;
|
|
531
|
+
expr?: Expr;
|
|
532
|
+
arity?: number;
|
|
533
|
+
skip?: Set<number>;
|
|
534
|
+
dup?: Set<number>;
|
|
535
|
+
duplicate: any;
|
|
536
|
+
discard: any;
|
|
537
|
+
proper: boolean;
|
|
538
|
+
} | {
|
|
539
|
+
normal: boolean;
|
|
540
|
+
steps: number;
|
|
541
|
+
};
|
|
469
542
|
invoke(arg: any): Expr;
|
|
470
543
|
traverse(change: any): Expr | Lambda;
|
|
471
544
|
any(predicate: any): any;
|
|
545
|
+
_fold(initial: any, combine: any): any;
|
|
472
546
|
subst(search: any, replace: any): Lambda;
|
|
473
547
|
_rski(options: any): any;
|
|
474
548
|
diff(other: any, swap?: boolean): string;
|
|
@@ -499,8 +573,10 @@ export class Native extends Named {
|
|
|
499
573
|
apply?: (arg0: Expr) => (Expr | null);
|
|
500
574
|
});
|
|
501
575
|
invoke: Partial;
|
|
502
|
-
|
|
503
|
-
|
|
576
|
+
/** @type {number} */
|
|
577
|
+
arity: number;
|
|
578
|
+
/** @type {string} */
|
|
579
|
+
note: string;
|
|
504
580
|
_rski(options: any): Expr | this;
|
|
505
581
|
}
|
|
506
582
|
export class Alias extends Named {
|
|
@@ -518,14 +594,14 @@ export class Alias extends Named {
|
|
|
518
594
|
*
|
|
519
595
|
* @param {String} name
|
|
520
596
|
* @param {Expr} impl
|
|
521
|
-
* @param {{canonize
|
|
597
|
+
* @param {{canonize?: boolean, max?: number, maxArgs?: number, note?: string, terminal?: boolean}} [options]
|
|
522
598
|
*/
|
|
523
599
|
constructor(name: string, impl: Expr, options?: {
|
|
524
|
-
canonize
|
|
525
|
-
max
|
|
526
|
-
maxArgs
|
|
527
|
-
note
|
|
528
|
-
terminal
|
|
600
|
+
canonize?: boolean;
|
|
601
|
+
max?: number;
|
|
602
|
+
maxArgs?: number;
|
|
603
|
+
note?: string;
|
|
604
|
+
terminal?: boolean;
|
|
529
605
|
});
|
|
530
606
|
impl: Expr;
|
|
531
607
|
note: string;
|
|
@@ -536,15 +612,18 @@ export class Alias extends Named {
|
|
|
536
612
|
invoke: (arg: any) => any;
|
|
537
613
|
traverse(change: any): any;
|
|
538
614
|
any(predicate: any): any;
|
|
615
|
+
_fold(initial: any, combine: any): any;
|
|
539
616
|
subst(search: any, replace: any): any;
|
|
540
|
-
_infer(options: any, preArgs?: any[], steps?: number):
|
|
541
|
-
|
|
542
|
-
*
|
|
543
|
-
* @return {{expr: Expr, steps: number}}
|
|
544
|
-
*/
|
|
545
|
-
step(): {
|
|
546
|
-
expr: Expr;
|
|
617
|
+
_infer(options: any, preArgs?: any[], steps?: number): {
|
|
618
|
+
normal: boolean;
|
|
547
619
|
steps: number;
|
|
620
|
+
expr?: Expr;
|
|
621
|
+
arity?: number;
|
|
622
|
+
skip?: Set<number>;
|
|
623
|
+
dup?: Set<number>;
|
|
624
|
+
duplicate: any;
|
|
625
|
+
discard: any;
|
|
626
|
+
proper: boolean;
|
|
548
627
|
};
|
|
549
628
|
diff(other: any, swap?: boolean): any;
|
|
550
629
|
_rski(options: any): Expr;
|
|
@@ -557,8 +636,8 @@ export class Church extends Native {
|
|
|
557
636
|
* @param {number} n
|
|
558
637
|
*/
|
|
559
638
|
constructor(n: number);
|
|
560
|
-
|
|
561
|
-
|
|
639
|
+
/** @type {number} */
|
|
640
|
+
n: number;
|
|
562
641
|
diff(other: any, swap?: boolean): string;
|
|
563
642
|
}
|
|
564
643
|
/**
|
|
@@ -567,11 +646,18 @@ export class Church extends Native {
|
|
|
567
646
|
declare const native: {
|
|
568
647
|
[key: string]: Native;
|
|
569
648
|
};
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
649
|
+
/**
|
|
650
|
+
* @template T
|
|
651
|
+
* @typedef {T | TraverseControl<T> | null} TraverseValue
|
|
652
|
+
*/
|
|
653
|
+
/**
|
|
654
|
+
* @desc Control primitives for fold() and traverse() methods.
|
|
655
|
+
* @template T
|
|
656
|
+
* @type {{[name: string]: function(T): TraverseControl<T>}}
|
|
657
|
+
*/
|
|
658
|
+
declare const control: {
|
|
659
|
+
[name: string]: (arg0: T) => TraverseControl<T>;
|
|
660
|
+
};
|
|
575
661
|
/**
|
|
576
662
|
* @desc Sort a list in such a way that dependent terms come after the (named) terms they depend on.
|
|
577
663
|
* If env is given, only terms listed there are taken into account.
|
package/types/src/extras.d.ts
CHANGED
|
@@ -54,5 +54,21 @@ export function search(seed: Expr[], options: {
|
|
|
54
54
|
* @returns {any}
|
|
55
55
|
*/
|
|
56
56
|
export function deepFormat(obj: any, options?: object): any;
|
|
57
|
-
|
|
57
|
+
/**
|
|
58
|
+
* @desc Given an expression and a hash of named terms,
|
|
59
|
+
* return a semicolon-separated string that declares said expression
|
|
60
|
+
* unambiguously.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* var expr = ski.parse("T=CI; V=BCT; V x y");
|
|
64
|
+
* SKI.extras.declare(expr, expr.context.env);
|
|
65
|
+
* // 'B; C; I; T=CI; V=BC(T); x=; y=; Vx y'
|
|
66
|
+
*
|
|
67
|
+
* @param {Expr} expr
|
|
68
|
+
* @param {{[s: string]: Named}} [env]
|
|
69
|
+
* @returns {string}
|
|
70
|
+
*/
|
|
71
|
+
export function declare(expr: Expr, env?: {
|
|
72
|
+
[s: string]: Named;
|
|
73
|
+
}): string;
|
|
58
74
|
import { Expr } from "./expr";
|
package/types/src/internal.d.ts
CHANGED
|
@@ -27,26 +27,39 @@ export function restrict(set: Set<string>, spec?: string): Set<string>;
|
|
|
27
27
|
/**
|
|
28
28
|
* @private
|
|
29
29
|
* @template T
|
|
30
|
-
* @param {T|
|
|
31
|
-
* @returns {[T?,
|
|
30
|
+
* @param {T|TraverseControl<T>|null} value
|
|
31
|
+
* @returns {[T?, function|undefined]}
|
|
32
32
|
*/
|
|
33
|
-
export function unwrap<T>(value: T |
|
|
33
|
+
export function unwrap<T>(value: T | TraverseControl<T> | null): [T?, Function | undefined];
|
|
34
34
|
/**
|
|
35
|
+
* @desc Prepare a self-referencing wrapper function for use as a fold/traverse control decorator.
|
|
36
|
+
*
|
|
37
|
+
* If `fun` is created by `prepareWrapper`, then
|
|
38
|
+
* unwrap(fun(x)) will always return exactly [x, fun], and the second value can be checked with ===.
|
|
39
|
+
*
|
|
40
|
+
* An optional label can be provided for debugging purposes.
|
|
35
41
|
*
|
|
36
42
|
* @private
|
|
37
43
|
* @template T
|
|
38
|
-
* @param {string}
|
|
39
|
-
* @returns {function(T):
|
|
44
|
+
* @param {string} [label]
|
|
45
|
+
* @returns {function(T): TraverseControl<T>}
|
|
40
46
|
*/
|
|
41
|
-
export function prepareWrapper<T>(
|
|
42
|
-
declare class
|
|
47
|
+
export function prepareWrapper<T>(label?: string): (arg0: T) => TraverseControl<T>;
|
|
48
|
+
declare class TraverseControl {
|
|
43
49
|
/**
|
|
50
|
+
* @desc A wrapper for values returned by fold/traverse callbacks
|
|
51
|
+
* which instructs the traversal to alter its behavior while
|
|
52
|
+
* retaining the value in question.
|
|
53
|
+
*
|
|
54
|
+
* This class is instantiated internally be `SKI.control.*` functions,
|
|
55
|
+
* and is not intended to be used directly by client code.
|
|
56
|
+
*
|
|
44
57
|
* @template T
|
|
45
58
|
* @param {T} value
|
|
46
|
-
* @param {
|
|
59
|
+
* @param {function(T): TraverseControl<T>} decoration
|
|
47
60
|
*/
|
|
48
|
-
constructor(value: T,
|
|
61
|
+
constructor(value: T, decoration: (arg0: T) => TraverseControl<T>);
|
|
49
62
|
value: T;
|
|
50
|
-
|
|
63
|
+
decoration: (arg0: T) => TraverseControl<T>;
|
|
51
64
|
}
|
|
52
65
|
export {};
|
package/types/src/parser.d.ts
CHANGED
|
@@ -24,7 +24,8 @@ export class SKI {
|
|
|
24
24
|
};
|
|
25
25
|
hasNumbers: boolean;
|
|
26
26
|
hasLambdas: boolean;
|
|
27
|
-
|
|
27
|
+
/** @type {Set<string>} */
|
|
28
|
+
allow: Set<string>;
|
|
28
29
|
/**
|
|
29
30
|
* @desc Declare a new term
|
|
30
31
|
* If the first argument is an Alias, it is added as is.
|
|
@@ -45,16 +46,33 @@ export class SKI {
|
|
|
45
46
|
* @return {SKI} chainable
|
|
46
47
|
*/
|
|
47
48
|
add(term: typeof classes.Alias | string, impl?: string | typeof classes.Expr | ((arg0: typeof classes.Expr) => Partial), note?: string): SKI;
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
/**
|
|
50
|
+
* @desc Internal helper for add() that creates an Alias or Native term from the given arguments.
|
|
51
|
+
* @param {Alias|string} term
|
|
52
|
+
* @param {string|Expr|function(Expr):Partial} impl
|
|
53
|
+
* @returns {Native|Alias}
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
private _named;
|
|
57
|
+
/**
|
|
58
|
+
* @desc Declare a new term if it is not known, otherwise just allow it.
|
|
59
|
+
* Currently only used by quests.
|
|
60
|
+
* Use with caution, this function may change its signature, behavior, or even be removed in the future.
|
|
61
|
+
*
|
|
62
|
+
* @experimental
|
|
63
|
+
* @param {string|Alias} name
|
|
64
|
+
* @param {string|Expr|function(Expr):Partial} impl
|
|
65
|
+
* @returns {SKI}
|
|
66
|
+
*/
|
|
67
|
+
maybeAdd(name: string | typeof classes.Alias, impl: string | typeof classes.Expr | ((arg0: typeof classes.Expr) => Partial)): SKI;
|
|
50
68
|
/**
|
|
51
69
|
* @desc Declare and remove multiple terms at once
|
|
52
70
|
* term=impl adds term
|
|
53
71
|
* term= removes term
|
|
54
|
-
* @param {string[]
|
|
72
|
+
* @param {string[]} list
|
|
55
73
|
* @return {SKI} chainable
|
|
56
74
|
*/
|
|
57
|
-
bulkAdd(list:
|
|
75
|
+
bulkAdd(list: string[]): SKI;
|
|
58
76
|
/**
|
|
59
77
|
* Restrict the interpreter to given terms. Terms prepended with '+' will be added
|
|
60
78
|
* and terms preceeded with '-' will be removed.
|
|
@@ -92,44 +110,46 @@ export class SKI {
|
|
|
92
110
|
*/
|
|
93
111
|
declare(): string[];
|
|
94
112
|
/**
|
|
95
|
-
*
|
|
113
|
+
* @template T
|
|
96
114
|
* @param {string} source
|
|
97
115
|
* @param {Object} [options]
|
|
98
116
|
* @param {{[keys: string]: Expr}} [options.env]
|
|
99
|
-
* @param {
|
|
117
|
+
* @param {T} [options.scope]
|
|
100
118
|
* @param {boolean} [options.numbers]
|
|
101
119
|
* @param {boolean} [options.lambdas]
|
|
102
120
|
* @param {string} [options.allow]
|
|
103
121
|
* @return {Expr}
|
|
104
122
|
*/
|
|
105
|
-
parse(source: string, options?: {
|
|
123
|
+
parse<T_1>(source: string, options?: {
|
|
106
124
|
env?: {
|
|
107
125
|
[keys: string]: typeof classes.Expr;
|
|
108
126
|
};
|
|
109
|
-
scope?:
|
|
127
|
+
scope?: T_1;
|
|
110
128
|
numbers?: boolean;
|
|
111
129
|
lambdas?: boolean;
|
|
112
130
|
allow?: string;
|
|
113
131
|
}): typeof classes.Expr;
|
|
114
132
|
/**
|
|
115
|
-
*
|
|
133
|
+
* @desc Parse a single line of source code, without splitting it into declarations.
|
|
134
|
+
* Internal, always use parse() instead.
|
|
135
|
+
* @template T
|
|
116
136
|
* @param {String} source S(KI)I
|
|
117
137
|
* @param {{[keys: string]: Expr}} env
|
|
118
138
|
* @param {Object} [options]
|
|
119
139
|
* @param {{[keys: string]: Expr}} [options.env] - unused, see 'env' argument
|
|
120
|
-
* @param {
|
|
140
|
+
* @param {T} [options.scope]
|
|
121
141
|
* @param {boolean} [options.numbers]
|
|
122
142
|
* @param {boolean} [options.lambdas]
|
|
123
143
|
* @param {string} [options.allow]
|
|
124
144
|
* @return {Expr} parsed expression
|
|
125
145
|
*/
|
|
126
|
-
parseLine(source: string, env?: {
|
|
146
|
+
parseLine<T_1>(source: string, env?: {
|
|
127
147
|
[keys: string]: typeof classes.Expr;
|
|
128
148
|
}, options?: {
|
|
129
149
|
env?: {
|
|
130
150
|
[keys: string]: typeof classes.Expr;
|
|
131
151
|
};
|
|
132
|
-
scope?:
|
|
152
|
+
scope?: T_1;
|
|
133
153
|
numbers?: boolean;
|
|
134
154
|
lambdas?: boolean;
|
|
135
155
|
allow?: string;
|
|
@@ -159,9 +179,11 @@ export namespace SKI {
|
|
|
159
179
|
* x instanceof FreeVar; // true
|
|
160
180
|
* x.apply(y).apply(z); // x(y)(z)
|
|
161
181
|
*
|
|
182
|
+
* @template T
|
|
183
|
+
* @param {T} [scope] - optional context to bind the generated variables to
|
|
162
184
|
* @return {{[key: string]: FreeVar}}
|
|
163
185
|
*/
|
|
164
|
-
export function vars(
|
|
186
|
+
export function vars<T_1>(scope?: T_1): {
|
|
165
187
|
[key: string]: typeof import("./expr").FreeVar;
|
|
166
188
|
};
|
|
167
189
|
/**
|
|
@@ -173,9 +195,10 @@ export namespace SKI {
|
|
|
173
195
|
export { classes };
|
|
174
196
|
export { native };
|
|
175
197
|
export let control: {
|
|
176
|
-
descend: (arg0:
|
|
177
|
-
prune: (arg0:
|
|
178
|
-
|
|
198
|
+
descend: (arg0: T) => TraverseControl<T>;
|
|
199
|
+
prune: (arg0: T) => TraverseControl<T>;
|
|
200
|
+
redo: (arg0: T) => TraverseControl<T>;
|
|
201
|
+
stop: (arg0: T) => TraverseControl<T>;
|
|
179
202
|
};
|
|
180
203
|
}
|
|
181
204
|
import classes = require("./expr");
|
package/types/src/quest.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
export type CaseResult = {
|
|
2
2
|
pass: boolean;
|
|
3
|
-
reason
|
|
3
|
+
reason?: string;
|
|
4
4
|
steps: number;
|
|
5
5
|
start: typeof import("./expr").Expr;
|
|
6
6
|
found: typeof import("./expr").Expr;
|
|
7
7
|
expected: typeof import("./expr").Expr;
|
|
8
|
-
note
|
|
8
|
+
note?: string;
|
|
9
9
|
args: typeof import("./expr").Expr[];
|
|
10
10
|
case: Case;
|
|
11
11
|
};
|
|
12
12
|
export type Capability = {
|
|
13
|
-
linear
|
|
14
|
-
affine
|
|
15
|
-
normal
|
|
16
|
-
proper
|
|
17
|
-
discard
|
|
18
|
-
duplicate
|
|
19
|
-
arity
|
|
13
|
+
linear?: boolean;
|
|
14
|
+
affine?: boolean;
|
|
15
|
+
normal?: boolean;
|
|
16
|
+
proper?: boolean;
|
|
17
|
+
discard?: boolean;
|
|
18
|
+
duplicate?: boolean;
|
|
19
|
+
arity?: number;
|
|
20
20
|
};
|
|
21
21
|
export type InputSpec = string | {
|
|
22
22
|
name: string;
|
|
@@ -37,32 +37,32 @@ export type QuestResult = {
|
|
|
37
37
|
/**
|
|
38
38
|
* @typedef {{
|
|
39
39
|
* pass: boolean,
|
|
40
|
-
* reason
|
|
40
|
+
* reason?: string,
|
|
41
41
|
* steps: number,
|
|
42
42
|
* start: Expr,
|
|
43
43
|
* found: Expr,
|
|
44
44
|
* expected: Expr,
|
|
45
|
-
* note
|
|
45
|
+
* note?: string,
|
|
46
46
|
* args: Expr[],
|
|
47
47
|
* case: Case
|
|
48
48
|
* }} CaseResult
|
|
49
49
|
*/
|
|
50
50
|
/**
|
|
51
51
|
* @typedef {{
|
|
52
|
-
* linear
|
|
53
|
-
* affine
|
|
54
|
-
* normal
|
|
55
|
-
* proper
|
|
56
|
-
* discard
|
|
57
|
-
* duplicate
|
|
58
|
-
* arity
|
|
52
|
+
* linear?: boolean,
|
|
53
|
+
* affine?: boolean,
|
|
54
|
+
* normal?: boolean,
|
|
55
|
+
* proper?: boolean,
|
|
56
|
+
* discard?: boolean,
|
|
57
|
+
* duplicate?: boolean,
|
|
58
|
+
* arity?: number,
|
|
59
59
|
* }} Capability
|
|
60
60
|
*/
|
|
61
61
|
/**
|
|
62
62
|
* @typedef {
|
|
63
63
|
* [string, string]
|
|
64
|
-
* | [{max
|
|
65
|
-
* | [{caps: Capability, max
|
|
64
|
+
* | [{max?: number}, string, string]
|
|
65
|
+
* | [{caps: Capability, max?: number}, string]
|
|
66
66
|
* } TestCase
|
|
67
67
|
*/
|
|
68
68
|
/**
|
|
@@ -79,27 +79,29 @@ export type QuestResult = {
|
|
|
79
79
|
* weight?: number
|
|
80
80
|
* }} QuestResult
|
|
81
81
|
*/
|
|
82
|
+
/**
|
|
83
|
+
* @typedef {{
|
|
84
|
+
* input: InputSpec | InputSpec[],
|
|
85
|
+
* cases: TestCase[],
|
|
86
|
+
*
|
|
87
|
+
* // the rest is optional
|
|
88
|
+
*
|
|
89
|
+
* allow?: string,
|
|
90
|
+
* numbers?: boolean,
|
|
91
|
+
* env?: string[],
|
|
92
|
+
* engine?: SKI,
|
|
93
|
+
* engineFull?: SKI,
|
|
94
|
+
*
|
|
95
|
+
* // metadata, also any fields not listed here will go to quest.meta.???
|
|
96
|
+
* id?: string|number,
|
|
97
|
+
* name?: string,
|
|
98
|
+
* intro?: string|string[], // multiple strings will be concatenated with spaces
|
|
99
|
+
* }} QuestSpec
|
|
100
|
+
*/
|
|
82
101
|
export class Quest {
|
|
83
102
|
/**
|
|
84
103
|
* @description A combinator problem with a set of test cases for the proposed solution.
|
|
85
|
-
* @param {
|
|
86
|
-
* input: InputSpec | InputSpec[],
|
|
87
|
-
* cases: TestCase[],
|
|
88
|
-
*
|
|
89
|
-
* // the rest is optional
|
|
90
|
-
|
|
91
|
-
* allow?: string,
|
|
92
|
-
* numbers?: boolean,
|
|
93
|
-
* env?: string[],
|
|
94
|
-
* engine?: SKI,
|
|
95
|
-
* engineFull?: SKI,
|
|
96
|
-
*
|
|
97
|
-
* // metadata, also any fields not listed here will go to quest.meta.???
|
|
98
|
-
* id?: string|number,
|
|
99
|
-
* name?: string,
|
|
100
|
-
* intro?: string|string[], // multiple strings will be concatenated with spaces
|
|
101
|
-
* }} options
|
|
102
|
-
*
|
|
104
|
+
* @param {QuestSpec} options
|
|
103
105
|
* @example const quest = new Quest({
|
|
104
106
|
* input: 'identity',
|
|
105
107
|
* cases: [
|
|
@@ -114,11 +116,11 @@ export class Quest {
|
|
|
114
116
|
* // despite having the same name.
|
|
115
117
|
* quest.check('I'); // fail! I not in the allowed list.
|
|
116
118
|
*/
|
|
117
|
-
constructor(options
|
|
119
|
+
constructor(options: QuestSpec);
|
|
118
120
|
engine: any;
|
|
119
121
|
engineFull: any;
|
|
120
122
|
restrict: {
|
|
121
|
-
allow:
|
|
123
|
+
allow: QuestSpec;
|
|
122
124
|
numbers: any;
|
|
123
125
|
lambdas: any;
|
|
124
126
|
};
|
|
@@ -129,7 +131,7 @@ export class Quest {
|
|
|
129
131
|
name: any;
|
|
130
132
|
intro: any;
|
|
131
133
|
id: any;
|
|
132
|
-
meta:
|
|
134
|
+
meta: QuestSpec;
|
|
133
135
|
/**
|
|
134
136
|
* Display allowed terms based on what engine thinks of this.env + this.restrict.allow
|
|
135
137
|
* @return {string}
|