@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.
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { TraverseValue, Dict } from './internal';
2
+ import { TraverseValue } from './internal';
3
3
  /**
4
4
  * @desc Control primitives for fold() and traverse() methods.
5
5
  */
@@ -13,7 +13,7 @@ export declare const control: {
13
13
  * @desc List of predefined native combinators.
14
14
  * This is required for toSKI() to work, otherwise could as well have been in parser.js.
15
15
  */
16
- export declare const native: Dict<Native>;
16
+ export declare const native: Record<string, Native>;
17
17
  export type TermInfo = {
18
18
  normal: boolean;
19
19
  proper: boolean;
@@ -54,7 +54,11 @@ export declare const FormatOptionsSchema: z.ZodObject<{
54
54
  inventory: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<Expr, Expr>>>;
55
55
  }, z.core.$strip>;
56
56
  export type FormatOptions = z.infer<typeof FormatOptionsSchema>;
57
- type RefinedFormatOptions = {
57
+ /**
58
+ * @desc A version of FormatOptions with defaults plugged in,
59
+ * use for mandatory formatImpl implementation in Expr subclasses.
60
+ */
61
+ export type RefinedFormatOptions = {
58
62
  terse?: boolean;
59
63
  html?: boolean;
60
64
  brackets: [string, string];
@@ -63,54 +67,47 @@ type RefinedFormatOptions = {
63
67
  lambda: [string, string, string];
64
68
  around: [string, string];
65
69
  redex: [string, string];
66
- inventory?: Dict<Expr>;
70
+ inventory?: Record<string, Expr>;
67
71
  };
68
72
  type TraverseOptions = {
69
73
  order?: 'LO' | 'LI' | 'leftmost-outermost' | 'leftmost-innermost';
70
74
  };
71
75
  type TraverseCallback = (e: Expr) => TraverseValue<Expr>;
72
- export declare class Expr {
73
- static control: {
74
- descend: <T>(value?: T) => import("./internal").TraverseControl<T>;
75
- prune: <T>(value?: T) => import("./internal").TraverseControl<T>;
76
- redo: <T>(value?: T) => import("./internal").TraverseControl<T>;
77
- stop: <T>(value?: T) => import("./internal").TraverseControl<T>;
78
- };
79
- static native: Dict<Native>;
76
+ export declare abstract class Expr {
80
77
  /**
81
- * @descr A combinatory logic expression.
78
+ * @desc A combinatory logic expression.
82
79
  *
83
- * Applications, variables, and other terms like combinators per se
84
- * are subclasses of this class.
80
+ * Applications, variables, lambdas, combinators per se,
81
+ * and other expression subtypes all extend this class.
82
+ *
83
+ * Expr itself cannot (or at least should not) be instantiated.
85
84
  *
86
85
  * @abstract
87
- * @property {{
88
- * scope?: any,
89
- * env?: { [key: string]: Expr },
90
- * src?: string,
91
- * parser: object,
92
- * }} [context]
93
- * @property {number} [arity] - number of arguments the term is waiting for (if known)
94
- * @property {string} [note] - a brief description what the term does
95
- * @property {string} [fancyName] - how to display in html mode, e.g. &phi; instead of 'f'
96
- * Typically only applicable to descendants of Named.
97
- * @property {TermInfo} [props] - properties inferred from the term's behavior
98
86
  */
87
+ /** @desc optional context for the term. Is set by the parser with addContext: true */
99
88
  context?: {
100
89
  scope?: object;
101
- env?: Dict<Expr>;
90
+ env?: Record<string, Expr>;
102
91
  src?: string;
103
92
  parser: object;
104
93
  };
94
+ /** @desc number of arguments the term is waiting for (if known) */
105
95
  arity?: number;
96
+ /** @desc a brief description what the term does */
106
97
  note?: string;
98
+ /** @desc the properties of the term, typically inferred from its behavior.
99
+ * This is used internally when declaring Native / Alias terms.
100
+ */
107
101
  props?: TermInfo;
102
+ /** @desc An estimated number of nodes in the expression tree.
103
+ * Used to prevent runaway computations.
104
+ */
108
105
  size?: number;
109
106
  /**
110
107
  *
111
108
  * @desc Define properties of the term based on user supplied options and/or inference results.
112
109
  * Typically useful for declaring Native and Alias terms.
113
- * @private
110
+ * @protected
114
111
  * @param {Object} options
115
112
  * @param {string} [options.note] - a brief description what the term does
116
113
  * @param {number} [options.arity] - number of arguments the term is waiting for (if known)
@@ -165,17 +162,19 @@ export declare class Expr {
165
162
  * }} [options]
166
163
  * @param {(e:Expr) => TraverseValue<Expr>} change
167
164
  * @returns {Expr|null}
165
+ * @final
168
166
  */
169
167
  traverse(options: TraverseOptions | TraverseCallback, change?: TraverseCallback): Expr | null;
170
168
  /**
171
- * @private
169
+ * @protected
170
+ * @final
172
171
  * @param {Object} options
173
172
  * @param {(e:Expr) => TraverseValue<Expr>} change
174
173
  * @returns {TraverseValue<Expr>}
175
174
  */
176
175
  _traverse_redo(options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr>;
177
176
  /**
178
- * @private
177
+ * @protected
179
178
  * @param {Object} options
180
179
  * @param {(e:Expr) => TraverseValue<Expr>} change
181
180
  * @returns {TraverseValue<Expr>}
@@ -201,13 +200,25 @@ export declare class Expr {
201
200
  *
202
201
  * This method is experimental and may change in the future.
203
202
  *
203
+ * @example // count the number of nodes in the expression tree
204
+ * expr.fold(0, (acc, e) => acc + 1);
205
+ *
204
206
  * @experimental
207
+ * @final
205
208
  * @template T
206
209
  * @param {T} initial
207
210
  * @param {(acc: T, expr: Expr) => TraverseValue<T>} combine
208
211
  * @returns {T}
209
212
  */
210
213
  fold<T>(initial: T, combine: (acc: T, expr: Expr) => TraverseValue<T>): T;
214
+ /**
215
+ * @desc Internal method for fold(), which performs the actual folding.
216
+ * Should be implemented in subclasses having any internal structure.
217
+ *
218
+ * @protected
219
+ * @param initial
220
+ * @param combine
221
+ */
211
222
  _fold<T>(initial: T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T>;
212
223
  /**
213
224
  * @experimental
@@ -246,6 +257,7 @@ export declare class Expr {
246
257
  *
247
258
  * Use toLambda() if you want to get a lambda term in any case.
248
259
  *
260
+ * @final
249
261
  * @param {{max?: number, maxArgs?: number}} options
250
262
  * @return {TermInfo}
251
263
  */
@@ -265,7 +277,7 @@ export declare class Expr {
265
277
  max: number;
266
278
  maxArgs: number;
267
279
  maxSize: number;
268
- skipNames: Dict<boolean>;
280
+ skipNames: Record<string, boolean>;
269
281
  }, nargs: number): TermInfo;
270
282
  /**
271
283
  * @desc Expand an expression into a list of terms
@@ -288,6 +300,7 @@ export declare class Expr {
288
300
  *
289
301
  * See also Expr.walk() and Expr.toSKI().
290
302
  *
303
+ * @final
291
304
  * @param {{
292
305
  * max?: number,
293
306
  * maxArgs?: number,
@@ -312,6 +325,7 @@ export declare class Expr {
312
325
  *
313
326
  * See also Expr.walk() and Expr.toLambda().
314
327
  *
328
+ * @final
315
329
  * @param {{max?: number}} [options]
316
330
  * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
317
331
  */
@@ -321,12 +335,15 @@ export declare class Expr {
321
335
  final: boolean;
322
336
  }, void, unknown>;
323
337
  /**
324
- * Replace all instances of plug in the expression with value and return the resulting expression,
338
+ * Replace all instances of `search` in the expression with `replace` and return the resulting expression,
325
339
  * or null if no changes could be made.
340
+ *
326
341
  * Lambda terms and applications will never match if used as plug
327
- * as they are impossible co compare without extensive computations.
342
+ * as they are impossible to compare without extensive computations.
343
+ *
328
344
  * Typically used on variables but can also be applied to other terms, e.g. aliases.
329
- * See also Expr.traverse().
345
+ * See also Expr.traverse() for more flexible replacement of subterms.
346
+ *
330
347
  * @param {Expr} search
331
348
  * @param {Expr} replace
332
349
  * @return {Expr|null}
@@ -361,6 +378,7 @@ export declare class Expr {
361
378
  * @desc Run uninterrupted sequence of step() applications
362
379
  * until the expression is irreducible, or max number of steps is reached.
363
380
  * Default number of steps = 1000.
381
+ * @final
364
382
  * @param {{max?: number, steps?: number, throw?: boolean}|Expr} [opt]
365
383
  * @param {Expr} args
366
384
  * @return {{expr: Expr, steps: number, final: boolean}}
@@ -368,7 +386,9 @@ export declare class Expr {
368
386
  run(opt?: RunOptions | Expr, ...args: Expr[]): Run;
369
387
  /**
370
388
  * Execute step() while possible, yielding a brief description of events after each step.
389
+ *
371
390
  * Mnemonics: like run() but slower.
391
+ * @final
372
392
  * @param {{max?: number}} options
373
393
  * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
374
394
  */
@@ -386,6 +406,7 @@ export declare class Expr {
386
406
  *
387
407
  * @param {Expr} other
388
408
  * @return {boolean}
409
+ * @final
389
410
  */
390
411
  equals(other: Expr): boolean;
391
412
  /**
@@ -402,6 +423,8 @@ export declare class Expr {
402
423
  * To somewhat alleviate confusion, the output will include
403
424
  * the internal id of the variable in square brackets.
404
425
  *
426
+ * Do not rely on the exact format of the output as it may change in the future.
427
+ *
405
428
  * @example "K(S != I)" is the result of comparing "KS" and "KI"
406
429
  * @example "S(K([x[13] != x[14]]))K"
407
430
  *
@@ -416,6 +439,11 @@ export declare class Expr {
416
439
  * `this` is the expected value and the argument is the actual one.
417
440
  * Mnemonic: the expected value is always a combinator, the actual one may be anything.
418
441
  *
442
+ * In case of failure, an error is thrown with a message describing the first point of difference
443
+ * and `expected` and `actual` properties like in AssertionError.
444
+ * AssertionError is not used directly to because browsers don't recognize it.
445
+ *
446
+ * @final
419
447
  * @param {Expr} actual
420
448
  * @param {string} comment
421
449
  */
@@ -423,27 +451,32 @@ export declare class Expr {
423
451
  /**
424
452
  * @desc Returns string representation of the expression.
425
453
  * Same as format() without options.
454
+ *
455
+ * Use formatImpl() to override in subclasses.
426
456
  * @return {string}
457
+ * @final
427
458
  */
428
459
  toString(): string;
429
460
  /**
430
461
  * @desc Whether the expression needs parentheses when printed.
431
462
  * @param {boolean} [first] - whether this is the first term in a sequence
432
463
  * @return {boolean}
464
+ * @protected
433
465
  */
434
466
  _braced(_first?: boolean): boolean;
435
467
  /**
436
468
  * @desc Whether the expression can be printed without a space when followed by arg.
437
469
  * @param {Expr} arg
438
470
  * @returns {boolean}
439
- * @private
471
+ * @protected
440
472
  */
441
473
  _unspaced(arg: Expr): boolean;
442
474
  /**
443
475
  * @desc Stringify the expression with fancy formatting options.
444
476
  * Said options mostly include wrappers around various constructs in form of ['(', ')'],
445
- * as well as terse and html flags that set up the defaults.
477
+ * as well as `terse` and `html` flags that fill in appropriate defaults.
446
478
  * Format without options is equivalent to toString() and can be parsed back.
479
+ * @final
447
480
  *
448
481
  * @param {Object} [options] - formatting options
449
482
  * @param {boolean} [options.terse] - whether to use terse formatting (omitting unnecessary spaces and parentheses)
@@ -478,9 +511,10 @@ export declare class Expr {
478
511
  * @param {Object} options
479
512
  * @param {number} nargs
480
513
  * @returns {string}
481
- * @private
514
+ * @protected
515
+ * @abstract
482
516
  */
483
- _format(options: RefinedFormatOptions, nargs: number): string;
517
+ abstract formatImpl(options: RefinedFormatOptions, nargs: number): string;
484
518
  /**
485
519
  * @desc Returns a string representation of the expression tree, with indentation to show structure.
486
520
  *
@@ -502,10 +536,11 @@ export declare class Expr {
502
536
  * FreeVar: x[54]
503
537
  * FreeVar: x[54]
504
538
  */
505
- diag(): string;
539
+ diag(indent?: string): string;
506
540
  /**
507
541
  * @desc Convert the expression to a JSON-serializable format.
508
542
  * @returns {string}
543
+ * @final
509
544
  */
510
545
  toJSON(): string | object;
511
546
  }
@@ -533,7 +568,8 @@ export declare class App extends Expr {
533
568
  unroll(): Expr[];
534
569
  diff(other: Expr, swap?: boolean): string | null;
535
570
  _braced(first?: boolean): boolean;
536
- _format(options: RefinedFormatOptions, nargs: number): string;
571
+ formatImpl(options: RefinedFormatOptions, nargs: number): string;
572
+ diag(indent?: string): string;
537
573
  _unspaced(arg: Expr): boolean;
538
574
  }
539
575
  export declare class Named extends Expr {
@@ -546,7 +582,7 @@ export declare class Named extends Expr {
546
582
  fancyName?: string;
547
583
  constructor(name: string);
548
584
  _unspaced(arg: Expr): boolean;
549
- _format(options: RefinedFormatOptions, nargs: number): string;
585
+ formatImpl(options: RefinedFormatOptions, nargs: number): string;
550
586
  }
551
587
  export declare class FreeVar extends Named {
552
588
  /**
@@ -571,7 +607,8 @@ export declare class FreeVar extends Named {
571
607
  constructor(name: string, scope?: object);
572
608
  diff(other: Expr, swap?: boolean): string | null;
573
609
  subst(search: Expr, replace: Expr): Expr | null;
574
- _format(options: RefinedFormatOptions, nargs: number): string;
610
+ formatImpl(options: RefinedFormatOptions, nargs: number): string;
611
+ diag(indent?: string): string;
575
612
  static global: string[];
576
613
  }
577
614
  export declare class Native extends Named {
@@ -622,7 +659,8 @@ export declare class Lambda extends Expr {
622
659
  _fold<T>(initial: T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T>;
623
660
  subst(search: Expr, replace: Expr): Expr | null;
624
661
  diff(other: Expr, swap?: boolean): string | null;
625
- _format(options: RefinedFormatOptions, nargs: number): string;
662
+ formatImpl(options: RefinedFormatOptions, nargs: number): string;
663
+ diag(indent?: string): string;
626
664
  _braced(first: boolean): boolean;
627
665
  }
628
666
  export declare class Church extends Expr {
@@ -635,7 +673,7 @@ export declare class Church extends Expr {
635
673
  constructor(n: number);
636
674
  diff(other: Expr, swap?: boolean): string | null;
637
675
  _unspaced(arg: Expr): boolean;
638
- _format(options: RefinedFormatOptions, nargs: number): string;
676
+ formatImpl(options: RefinedFormatOptions, nargs: number): string;
639
677
  }
640
678
  export declare class Alias extends Named {
641
679
  /**
@@ -684,7 +722,8 @@ export declare class Alias extends Named {
684
722
  step(): Step;
685
723
  diff(other: Expr, swap?: boolean): string | null;
686
724
  _braced(first: boolean): boolean;
687
- _format(options: RefinedFormatOptions, nargs: number): string;
725
+ formatImpl(options: RefinedFormatOptions, nargs: number): string;
726
+ diag(indent?: string): string;
688
727
  }
689
728
  export declare const classes: {
690
729
  Expr: typeof Expr;
@@ -3,7 +3,7 @@ import { Parser } from './parser';
3
3
  import { Quest } from './quest';
4
4
  import { toposort } from './toposort';
5
5
  export declare class SKI extends Parser {
6
- static native: import("./internal").Dict<import("./expr").Native>;
6
+ static native: Record<string, import("./expr").Native>;
7
7
  static control: {
8
8
  descend: <T>(value?: T) => import("./internal").TraverseControl<T>;
9
9
  prune: <T>(value?: T) => import("./internal").TraverseControl<T>;
@@ -39,6 +39,17 @@ export declare class SKI extends Parser {
39
39
  static K: import("./expr").Native;
40
40
  static S: import("./expr").Native;
41
41
  static W: import("./expr").Native;
42
+ /**
43
+ * @desc Create a proxy object that generates variables on demand,
44
+ * with names corresponding to the property accessed.
45
+ * Different invocations will return distinct variables,
46
+ * even if with the same name.
47
+ *
48
+ * @example const {x, y, z} = SKI.vars();
49
+ * x.name; // 'x'
50
+ * x instanceof FreeVar; // true
51
+ * x.apply(y).apply(z); // x(y)(z)
52
+ */
42
53
  static vars(scope?: object): {
43
54
  [key: string]: FreeVar;
44
55
  };
@@ -1,6 +1,3 @@
1
- export type Dict<T> = {
2
- [key: string]: T;
3
- };
4
1
  export declare class Tokenizer {
5
2
  /**
6
3
  * @desc Create a tokenizer that splits strings into tokens according to the given terms.
@@ -28,7 +25,7 @@ export declare class Tokenizer {
28
25
  */
29
26
  export declare function restrict(set: Set<string>, spec?: string): Set<string>;
30
27
  export type TraverseDecorator = <T>(value?: T) => TraverseControl<T>;
31
- export type TraverseValue<T> = T | TraverseControl<T> | null | undefined | void;
28
+ export type TraverseValue<T> = TraverseControl<T | null | undefined | void> | T | null | undefined | void;
32
29
  export declare class TraverseControl<T> {
33
30
  /**
34
31
  * @desc A wrapper for values returned by fold/traverse callbacks
@@ -220,7 +220,7 @@ declare class Case {
220
220
  }
221
221
  declare class Subst {
222
222
  /**
223
- * @descr A placeholder object with exactly n free variables to be substituted later.
223
+ * @desc A placeholder object with exactly n free variables to be substituted later.
224
224
  * Basically a poor man's lambda.
225
225
  * @param {Expr} expr
226
226
  * @param {FreeVar[]} env
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dallaylaen/ski-interpreter",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "description": "Simple Kombinator Interpreter - a combinatory logic & lambda calculus parser and interpreter. Supports SKI, BCKW, Church numerals, and setting up assertions ('quests') involving all of the above.",
5
5
  "keywords": [
6
6
  "combinatory logic",