@dallaylaen/ski-interpreter 2.2.0 → 2.3.0

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.
@@ -24,7 +24,8 @@ export class SKI {
24
24
  };
25
25
  hasNumbers: boolean;
26
26
  hasLambdas: boolean;
27
- allow: any;
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.
@@ -41,20 +42,41 @@ export class SKI {
41
42
  *
42
43
  * @param {Alias|String} term
43
44
  * @param {String|Expr|function(Expr):Partial} [impl]
44
- * @param {String} [note]
45
+ * @param {object|string} [options]
46
+ * @param {string} [options.note] - optional annotation for the term, default is auto-generated if this.annotate is true
47
+ * @param {boolean} [options.canonize] - whether to canonize the term's implementation, default is this.annotate
48
+ * @param {boolean} [options.fancy] - alternative HTML-friendly name for the term
49
+ * @param {number} [options.arity] - custom arity for the term, default is inferred from the implementation
45
50
  * @return {SKI} chainable
46
51
  */
47
- add(term: typeof classes.Alias | string, impl?: string | typeof classes.Expr | ((arg0: typeof classes.Expr) => Partial), note?: string): SKI;
48
- _named(term: any, impl: any): classes.Alias | classes.Native;
49
- maybeAdd(name: any, impl: any): this;
52
+ add(term: typeof classes.Alias | string, impl?: string | typeof classes.Expr | ((arg0: typeof classes.Expr) => Partial), options?: object | string): SKI;
53
+ /**
54
+ * @desc Internal helper for add() that creates an Alias or Native term from the given arguments.
55
+ * @param {Alias|string} term
56
+ * @param {string|Expr|function(Expr):Partial} impl
57
+ * @returns {Native|Alias}
58
+ * @private
59
+ */
60
+ private _named;
61
+ /**
62
+ * @desc Declare a new term if it is not known, otherwise just allow it.
63
+ * Currently only used by quests.
64
+ * Use with caution, this function may change its signature, behavior, or even be removed in the future.
65
+ *
66
+ * @experimental
67
+ * @param {string|Alias} name
68
+ * @param {string|Expr|function(Expr):Partial} impl
69
+ * @returns {SKI}
70
+ */
71
+ maybeAdd(name: string | typeof classes.Alias, impl: string | typeof classes.Expr | ((arg0: typeof classes.Expr) => Partial)): SKI;
50
72
  /**
51
73
  * @desc Declare and remove multiple terms at once
52
74
  * term=impl adds term
53
75
  * term= removes term
54
- * @param {string[]]} list
76
+ * @param {string[]} list
55
77
  * @return {SKI} chainable
56
78
  */
57
- bulkAdd(list: any): SKI;
79
+ bulkAdd(list: string[]): SKI;
58
80
  /**
59
81
  * Restrict the interpreter to given terms. Terms prepended with '+' will be added
60
82
  * and terms preceeded with '-' will be removed.
@@ -92,44 +114,46 @@ export class SKI {
92
114
  */
93
115
  declare(): string[];
94
116
  /**
95
- *
117
+ * @template T
96
118
  * @param {string} source
97
119
  * @param {Object} [options]
98
120
  * @param {{[keys: string]: Expr}} [options.env]
99
- * @param {any} [options.scope]
121
+ * @param {T} [options.scope]
100
122
  * @param {boolean} [options.numbers]
101
123
  * @param {boolean} [options.lambdas]
102
124
  * @param {string} [options.allow]
103
125
  * @return {Expr}
104
126
  */
105
- parse(source: string, options?: {
127
+ parse<T_1>(source: string, options?: {
106
128
  env?: {
107
129
  [keys: string]: typeof classes.Expr;
108
130
  };
109
- scope?: any;
131
+ scope?: T_1;
110
132
  numbers?: boolean;
111
133
  lambdas?: boolean;
112
134
  allow?: string;
113
135
  }): typeof classes.Expr;
114
136
  /**
115
- *
137
+ * @desc Parse a single line of source code, without splitting it into declarations.
138
+ * Internal, always use parse() instead.
139
+ * @template T
116
140
  * @param {String} source S(KI)I
117
141
  * @param {{[keys: string]: Expr}} env
118
142
  * @param {Object} [options]
119
143
  * @param {{[keys: string]: Expr}} [options.env] - unused, see 'env' argument
120
- * @param {any} [options.scope]
144
+ * @param {T} [options.scope]
121
145
  * @param {boolean} [options.numbers]
122
146
  * @param {boolean} [options.lambdas]
123
147
  * @param {string} [options.allow]
124
148
  * @return {Expr} parsed expression
125
149
  */
126
- parseLine(source: string, env?: {
150
+ parseLine<T_1>(source: string, env?: {
127
151
  [keys: string]: typeof classes.Expr;
128
152
  }, options?: {
129
153
  env?: {
130
154
  [keys: string]: typeof classes.Expr;
131
155
  };
132
- scope?: any;
156
+ scope?: T_1;
133
157
  numbers?: boolean;
134
158
  lambdas?: boolean;
135
159
  allow?: string;
@@ -159,9 +183,11 @@ export namespace SKI {
159
183
  * x instanceof FreeVar; // true
160
184
  * x.apply(y).apply(z); // x(y)(z)
161
185
  *
186
+ * @template T
187
+ * @param {T} [scope] - optional context to bind the generated variables to
162
188
  * @return {{[key: string]: FreeVar}}
163
189
  */
164
- export function vars(context?: {}): {
190
+ export function vars<T_1>(scope?: T_1): {
165
191
  [key: string]: typeof import("./expr").FreeVar;
166
192
  };
167
193
  /**
@@ -173,9 +199,10 @@ export namespace SKI {
173
199
  export { classes };
174
200
  export { native };
175
201
  export let control: {
176
- descend: (arg0: any) => any;
177
- prune: (arg0: any) => any;
178
- stop: (arg0: any) => any;
202
+ descend: (arg0: T) => TraverseControl<T>;
203
+ prune: (arg0: T) => TraverseControl<T>;
204
+ redo: (arg0: T) => TraverseControl<T>;
205
+ stop: (arg0: T) => TraverseControl<T>;
179
206
  };
180
207
  }
181
208
  import classes = require("./expr");
@@ -1,22 +1,22 @@
1
1
  export type CaseResult = {
2
2
  pass: boolean;
3
- reason: string | null;
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: string | null;
8
+ note?: string;
9
9
  args: typeof import("./expr").Expr[];
10
10
  case: Case;
11
11
  };
12
12
  export type Capability = {
13
- linear: boolean | null;
14
- affine: boolean | null;
15
- normal: boolean | null;
16
- proper: boolean | null;
17
- discard: boolean | null;
18
- duplicate: boolean | null;
19
- arity: number | null;
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;
@@ -34,35 +34,39 @@ export type QuestResult = {
34
34
  steps: number;
35
35
  weight?: number;
36
36
  };
37
+ export type SelfCheck = {
38
+ accepted?: string[][];
39
+ rejected?: string[][];
40
+ };
37
41
  /**
38
42
  * @typedef {{
39
43
  * pass: boolean,
40
- * reason: string?,
44
+ * reason?: string,
41
45
  * steps: number,
42
46
  * start: Expr,
43
47
  * found: Expr,
44
48
  * expected: Expr,
45
- * note: string?,
49
+ * note?: string,
46
50
  * args: Expr[],
47
51
  * case: Case
48
52
  * }} CaseResult
49
53
  */
50
54
  /**
51
55
  * @typedef {{
52
- * linear: boolean?,
53
- * affine: boolean?,
54
- * normal: boolean?,
55
- * proper: boolean?,
56
- * discard: boolean?,
57
- * duplicate: boolean?,
58
- * arity: number?,
56
+ * linear?: boolean,
57
+ * affine?: boolean,
58
+ * normal?: boolean,
59
+ * proper?: boolean,
60
+ * discard?: boolean,
61
+ * duplicate?: boolean,
62
+ * arity?: number,
59
63
  * }} Capability
60
64
  */
61
65
  /**
62
66
  * @typedef {
63
67
  * [string, string]
64
- * | [{max: number?}, string, string]
65
- * | [{caps: Capability, max: number?}, string]
68
+ * | [{max?: number}, string, string]
69
+ * | [{caps: Capability, max?: number}, string]
66
70
  * } TestCase
67
71
  */
68
72
  /**
@@ -79,27 +83,32 @@ export type QuestResult = {
79
83
  * weight?: number
80
84
  * }} QuestResult
81
85
  */
86
+ /**
87
+ * @typedef {{
88
+ * input: InputSpec | InputSpec[],
89
+ * cases: TestCase[],
90
+ *
91
+ * // the rest is optional
92
+ *
93
+ * allow?: string,
94
+ * numbers?: boolean,
95
+ * env?: string[],
96
+ * engine?: SKI,
97
+ * engineFull?: SKI,
98
+ *
99
+ * // metadata, also any fields not listed here will go to quest.meta.???
100
+ * id?: string|number,
101
+ * name?: string,
102
+ * intro?: string|string[], // multiple strings will be concatenated with spaces
103
+ * }} QuestSpec
104
+ */
105
+ /**
106
+ * @typedef {{ accepted?: string[][], rejected?: string[][] }} SelfCheck
107
+ */
82
108
  export class Quest {
83
109
  /**
84
110
  * @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
- *
111
+ * @param {QuestSpec} options
103
112
  * @example const quest = new Quest({
104
113
  * input: 'identity',
105
114
  * cases: [
@@ -114,11 +123,11 @@ export class Quest {
114
123
  * // despite having the same name.
115
124
  * quest.check('I'); // fail! I not in the allowed list.
116
125
  */
117
- constructor(options?: {});
126
+ constructor(options: QuestSpec);
118
127
  engine: any;
119
128
  engineFull: any;
120
129
  restrict: {
121
- allow: any;
130
+ allow: QuestSpec;
122
131
  numbers: any;
123
132
  lambdas: any;
124
133
  };
@@ -129,7 +138,7 @@ export class Quest {
129
138
  name: any;
130
139
  intro: any;
131
140
  id: any;
132
- meta: {};
141
+ meta: QuestSpec;
133
142
  /**
134
143
  * Display allowed terms based on what engine thinks of this.env + this.restrict.allow
135
144
  * @return {string}
@@ -158,12 +167,39 @@ export class Quest {
158
167
  * @return {QuestResult}
159
168
  */
160
169
  check(...input: string): QuestResult;
170
+ verify(options: any): {
171
+ date: string;
172
+ };
173
+ /**
174
+ * @desc Verify that solutions that are expected to pass/fail do so.
175
+ * @param {SelfCheck|{[key: string]: SelfCheck}} dataset
176
+ * @return {{shouldPass: {input: string[], result: QuestResult}[], shouldFail: {input: string[], result: QuestResult}[]} | null}
177
+ */
178
+ verifySolutions(dataset: SelfCheck | {
179
+ [key: string]: SelfCheck;
180
+ }): {
181
+ shouldPass: {
182
+ input: string[];
183
+ result: QuestResult;
184
+ }[];
185
+ shouldFail: {
186
+ input: string[];
187
+ result: QuestResult;
188
+ }[];
189
+ } | null;
190
+ verifyMeta(options?: {}): {
191
+ date: string;
192
+ };
161
193
  /**
162
194
  *
163
195
  * @return {TestCase[]}
164
196
  */
165
197
  show(): TestCase[];
166
198
  }
199
+ export namespace Quest {
200
+ export { Group };
201
+ export { Case };
202
+ }
167
203
  declare class Case {
168
204
  /**
169
205
  * @param {FreeVar[]} input
@@ -196,6 +232,16 @@ declare class Case {
196
232
  */
197
233
  check(...expr: typeof import("./expr").Expr): CaseResult;
198
234
  }
235
+ declare class Group {
236
+ constructor(options: any);
237
+ name: any;
238
+ intro: string;
239
+ id: any;
240
+ content: any;
241
+ verify(options: any): {
242
+ content: any;
243
+ };
244
+ }
199
245
  import { SKI } from "./parser";
200
246
  declare class Subst {
201
247
  /**