yukigo-ast 0.1.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.
- package/CHANGELOG.md +19 -0
- package/dist/globals/generics.d.ts +740 -0
- package/dist/globals/generics.js +1128 -0
- package/dist/globals/helpers.d.ts +4 -0
- package/dist/globals/helpers.js +76 -0
- package/dist/globals/operators.d.ts +251 -0
- package/dist/globals/operators.js +336 -0
- package/dist/globals/patterns.d.ts +170 -0
- package/dist/globals/patterns.js +261 -0
- package/dist/globals/runtime.d.ts +22 -0
- package/dist/globals/runtime.js +6 -0
- package/dist/globals/types.d.ts +185 -0
- package/dist/globals/types.js +329 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/paradigms/data.d.ts +246 -0
- package/dist/paradigms/data.js +348 -0
- package/dist/paradigms/functional.d.ts +59 -0
- package/dist/paradigms/functional.js +103 -0
- package/dist/paradigms/imperative.d.ts +124 -0
- package/dist/paradigms/imperative.js +188 -0
- package/dist/paradigms/logic.d.ts +163 -0
- package/dist/paradigms/logic.js +240 -0
- package/dist/paradigms/object.d.ts +201 -0
- package/dist/paradigms/object.js +308 -0
- package/dist/visitor.d.ts +254 -0
- package/dist/visitor.js +426 -0
- package/package.json +25 -0
- package/src/globals/generics.ts +1421 -0
- package/src/globals/helpers.ts +107 -0
- package/src/globals/operators.ts +515 -0
- package/src/globals/patterns.ts +321 -0
- package/src/globals/runtime.ts +33 -0
- package/src/globals/types.ts +375 -0
- package/src/index.ts +12 -0
- package/src/paradigms/data.ts +393 -0
- package/src/paradigms/functional.ts +129 -0
- package/src/paradigms/imperative.ts +232 -0
- package/src/paradigms/logic.ts +314 -0
- package/src/paradigms/object.ts +366 -0
- package/src/visitor.ts +692 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { Visitor } from "../visitor.js";
|
|
2
|
+
import {
|
|
3
|
+
ASTNode,
|
|
4
|
+
Primitive,
|
|
5
|
+
SourceLocation,
|
|
6
|
+
SymbolPrimitive,
|
|
7
|
+
} from "./generics.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Represents a pattern that matches any value and binds it to a variable.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* map (\x -> x + 1)
|
|
14
|
+
* @category Patterns
|
|
15
|
+
*/
|
|
16
|
+
export class VariablePattern extends ASTNode {
|
|
17
|
+
/** @hidden */
|
|
18
|
+
public name: SymbolPrimitive;
|
|
19
|
+
|
|
20
|
+
constructor(name: SymbolPrimitive, loc?: SourceLocation) {
|
|
21
|
+
super(loc);
|
|
22
|
+
this.name = name;
|
|
23
|
+
}
|
|
24
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
25
|
+
return visitor.visitVariablePattern?.(this);
|
|
26
|
+
}
|
|
27
|
+
public toJSON() {
|
|
28
|
+
return {
|
|
29
|
+
type: "VariablePattern",
|
|
30
|
+
name: this.name.toJSON(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Represents a pattern that matches an exact literal value.
|
|
37
|
+
* @category Patterns
|
|
38
|
+
*/
|
|
39
|
+
export class LiteralPattern extends ASTNode {
|
|
40
|
+
/** @hidden */
|
|
41
|
+
public name: Primitive;
|
|
42
|
+
|
|
43
|
+
constructor(name: Primitive, loc?: SourceLocation) {
|
|
44
|
+
super(loc);
|
|
45
|
+
this.name = name;
|
|
46
|
+
}
|
|
47
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
48
|
+
return visitor.visitLiteralPattern?.(this);
|
|
49
|
+
}
|
|
50
|
+
public toJSON() {
|
|
51
|
+
return {
|
|
52
|
+
type: "LiteralPattern",
|
|
53
|
+
name: this.name.toJSON(),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Represents a pattern matching a function application or constructor with arguments.
|
|
59
|
+
* @category Patterns
|
|
60
|
+
*/
|
|
61
|
+
export class ApplicationPattern extends ASTNode {
|
|
62
|
+
/** @hidden */
|
|
63
|
+
public args: Pattern[];
|
|
64
|
+
/** @hidden */
|
|
65
|
+
public symbol: SymbolPrimitive;
|
|
66
|
+
|
|
67
|
+
constructor(
|
|
68
|
+
symbol: SymbolPrimitive,
|
|
69
|
+
args: Pattern[],
|
|
70
|
+
loc?: SourceLocation
|
|
71
|
+
) {
|
|
72
|
+
super(loc);
|
|
73
|
+
this.symbol = symbol;
|
|
74
|
+
this.args = args;
|
|
75
|
+
}
|
|
76
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
77
|
+
return visitor.visitApplicationPattern?.(this);
|
|
78
|
+
}
|
|
79
|
+
public toJSON() {
|
|
80
|
+
return {
|
|
81
|
+
type: "ApplicationPattern",
|
|
82
|
+
symbol: this.symbol.toJSON(),
|
|
83
|
+
args: this.args.map((arg) => arg.toJSON()),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Represents a pattern matching a tuple structure.
|
|
90
|
+
* @category Patterns
|
|
91
|
+
*/
|
|
92
|
+
export class TuplePattern extends ASTNode {
|
|
93
|
+
/** @hidden */
|
|
94
|
+
public elements: Pattern[];
|
|
95
|
+
|
|
96
|
+
constructor(elements: Pattern[], loc?: SourceLocation) {
|
|
97
|
+
super(loc);
|
|
98
|
+
this.elements = elements;
|
|
99
|
+
}
|
|
100
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
101
|
+
return visitor.visitTuplePattern?.(this);
|
|
102
|
+
}
|
|
103
|
+
public toJSON() {
|
|
104
|
+
return {
|
|
105
|
+
type: "TuplePattern",
|
|
106
|
+
elements: this.elements.map((elem) => elem.toJSON()),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Represents a pattern matching a list structure.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* sum (x:xs) = x + sum xs
|
|
116
|
+
* @category Patterns
|
|
117
|
+
*/
|
|
118
|
+
export class ListPattern extends ASTNode {
|
|
119
|
+
/** @hidden */
|
|
120
|
+
public elements: Pattern[];
|
|
121
|
+
|
|
122
|
+
constructor(elements: Pattern[], loc?: SourceLocation) {
|
|
123
|
+
super(loc);
|
|
124
|
+
this.elements = elements;
|
|
125
|
+
}
|
|
126
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
127
|
+
return visitor.visitListPattern?.(this);
|
|
128
|
+
}
|
|
129
|
+
public toJSON() {
|
|
130
|
+
return {
|
|
131
|
+
type: "ListPattern",
|
|
132
|
+
elements: this.elements.map((elem) => elem.toJSON()),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Represents a pattern matching a functor or compound term.
|
|
139
|
+
* @category Patterns
|
|
140
|
+
*/
|
|
141
|
+
export class FunctorPattern extends ASTNode {
|
|
142
|
+
/** @hidden */
|
|
143
|
+
public args: Pattern[];
|
|
144
|
+
/** @hidden */
|
|
145
|
+
public identifier: SymbolPrimitive;
|
|
146
|
+
|
|
147
|
+
constructor(
|
|
148
|
+
identifier: SymbolPrimitive,
|
|
149
|
+
args: Pattern[],
|
|
150
|
+
loc?: SourceLocation
|
|
151
|
+
) {
|
|
152
|
+
super(loc);
|
|
153
|
+
this.identifier = identifier;
|
|
154
|
+
this.args = args;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
158
|
+
return visitor.visitFunctorPattern?.(this);
|
|
159
|
+
}
|
|
160
|
+
public toJSON() {
|
|
161
|
+
return {
|
|
162
|
+
type: "FunctorPattern",
|
|
163
|
+
identifier: this.identifier.toJSON(),
|
|
164
|
+
args: this.args.map((arg) => arg.toJSON()),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Represents an alias pattern (e.g., x@pat), binding the whole value to a name while matching inner patterns.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* f p@(x, y) = ...
|
|
174
|
+
* @category Patterns
|
|
175
|
+
*/
|
|
176
|
+
export class AsPattern extends ASTNode {
|
|
177
|
+
/** @hidden */
|
|
178
|
+
public pattern: Pattern;
|
|
179
|
+
/** @hidden */
|
|
180
|
+
public alias: VariablePattern | WildcardPattern;
|
|
181
|
+
|
|
182
|
+
constructor(
|
|
183
|
+
alias: VariablePattern | WildcardPattern,
|
|
184
|
+
pattern: Pattern,
|
|
185
|
+
loc?: SourceLocation
|
|
186
|
+
) {
|
|
187
|
+
super(loc);
|
|
188
|
+
this.alias = alias;
|
|
189
|
+
this.pattern = pattern;
|
|
190
|
+
}
|
|
191
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
192
|
+
return visitor.visitAsPattern?.(this);
|
|
193
|
+
}
|
|
194
|
+
public toJSON() {
|
|
195
|
+
return {
|
|
196
|
+
type: "AsPattern",
|
|
197
|
+
alias: this.alias.toJSON(),
|
|
198
|
+
pattern: this.pattern.toJSON(),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Represents a wildcard pattern (_), which matches anything and discards the value.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* const _ x = x
|
|
208
|
+
* @category Patterns
|
|
209
|
+
*/
|
|
210
|
+
export class WildcardPattern extends ASTNode {
|
|
211
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
212
|
+
return visitor.visitWildcardPattern?.(this);
|
|
213
|
+
}
|
|
214
|
+
public toJSON() {
|
|
215
|
+
return {
|
|
216
|
+
type: "WildcardPattern",
|
|
217
|
+
name: "_",
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Represents a union of patterns, matching if any of the sub-patterns match.
|
|
224
|
+
* @category Patterns
|
|
225
|
+
*/
|
|
226
|
+
export class UnionPattern extends ASTNode {
|
|
227
|
+
/** @hidden */
|
|
228
|
+
public patterns: Pattern[];
|
|
229
|
+
|
|
230
|
+
constructor(patterns: Pattern[], loc?: SourceLocation) {
|
|
231
|
+
super(loc);
|
|
232
|
+
this.patterns = patterns;
|
|
233
|
+
}
|
|
234
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
235
|
+
return visitor.visitUnionPattern?.(this);
|
|
236
|
+
}
|
|
237
|
+
public toJSON() {
|
|
238
|
+
return {
|
|
239
|
+
type: "UnionPattern",
|
|
240
|
+
patterns: this.patterns.map((pattern) => pattern.toJSON()),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Represents a pattern matching a specific data constructor.
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* safeDiv (Just x) y = x / y
|
|
250
|
+
* @category Patterns
|
|
251
|
+
*/
|
|
252
|
+
export class ConstructorPattern extends ASTNode {
|
|
253
|
+
/** @hidden */
|
|
254
|
+
public patterns: Pattern[];
|
|
255
|
+
/** @hidden */
|
|
256
|
+
public constr: string;
|
|
257
|
+
|
|
258
|
+
constructor(
|
|
259
|
+
constr: string,
|
|
260
|
+
patterns: Pattern[],
|
|
261
|
+
loc?: SourceLocation
|
|
262
|
+
) {
|
|
263
|
+
super(loc);
|
|
264
|
+
this.constr = constr;
|
|
265
|
+
this.patterns = patterns;
|
|
266
|
+
}
|
|
267
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
268
|
+
return visitor.visitConstructorPattern?.(this);
|
|
269
|
+
}
|
|
270
|
+
public toJSON() {
|
|
271
|
+
return {
|
|
272
|
+
type: "ConstructorPattern",
|
|
273
|
+
constructor: this.constr,
|
|
274
|
+
patterns: this.patterns.map((pattern) => pattern.toJSON()),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Represents a pattern matching the head and tail of a list (x:xs).
|
|
281
|
+
* @category Patterns
|
|
282
|
+
*/
|
|
283
|
+
export class ConsPattern extends ASTNode {
|
|
284
|
+
/** @hidden */
|
|
285
|
+
public tail: Pattern;
|
|
286
|
+
/** @hidden */
|
|
287
|
+
public head: Pattern;
|
|
288
|
+
|
|
289
|
+
constructor(
|
|
290
|
+
head: Pattern,
|
|
291
|
+
tail: Pattern,
|
|
292
|
+
loc?: SourceLocation
|
|
293
|
+
) {
|
|
294
|
+
super(loc);
|
|
295
|
+
this.head = head;
|
|
296
|
+
this.tail = tail;
|
|
297
|
+
}
|
|
298
|
+
public accept<R>(visitor: Visitor<R>): R {
|
|
299
|
+
return visitor.visitConsPattern?.(this);
|
|
300
|
+
}
|
|
301
|
+
public toJSON() {
|
|
302
|
+
return {
|
|
303
|
+
type: "ConsPattern",
|
|
304
|
+
head: this.head.toJSON(),
|
|
305
|
+
tail: this.tail.toJSON(),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export type Pattern =
|
|
311
|
+
| VariablePattern
|
|
312
|
+
| LiteralPattern
|
|
313
|
+
| ApplicationPattern
|
|
314
|
+
| TuplePattern
|
|
315
|
+
| ListPattern
|
|
316
|
+
| FunctorPattern
|
|
317
|
+
| AsPattern
|
|
318
|
+
| WildcardPattern
|
|
319
|
+
| ConstructorPattern
|
|
320
|
+
| UnionPattern
|
|
321
|
+
| ConsPattern;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { GuardedBody, PrimitiveValue, UnguardedBody } from "./generics.js";
|
|
2
|
+
import { Pattern } from "./patterns.js";
|
|
3
|
+
|
|
4
|
+
export interface EquationRuntime {
|
|
5
|
+
patterns: Pattern[];
|
|
6
|
+
body: GuardedBody[] | UnguardedBody;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type PrimitiveThunk = () => PrimitiveValue;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Runtime Function used in the Interpreter
|
|
13
|
+
*/
|
|
14
|
+
export interface RuntimeFunction {
|
|
15
|
+
arity: number;
|
|
16
|
+
identifier?: string;
|
|
17
|
+
equations: EquationRuntime[];
|
|
18
|
+
pendingArgs?: (PrimitiveValue | PrimitiveThunk)[]; // for partial application
|
|
19
|
+
closure?: Map<string, PrimitiveValue>[];
|
|
20
|
+
}
|
|
21
|
+
export interface LazyList {
|
|
22
|
+
readonly type: "LazyList";
|
|
23
|
+
readonly generator: () => Generator<PrimitiveValue, void, unknown>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function isLazyList(prim: PrimitiveValue): prim is LazyList {
|
|
27
|
+
return (
|
|
28
|
+
prim &&
|
|
29
|
+
typeof prim === "object" &&
|
|
30
|
+
"type" in prim &&
|
|
31
|
+
prim.type === "LazyList"
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { Visitor } from "../visitor.js";
|
|
2
|
+
import {
|
|
3
|
+
ASTNode,
|
|
4
|
+
Expression,
|
|
5
|
+
SourceLocation,
|
|
6
|
+
SymbolPrimitive,
|
|
7
|
+
} from "./generics.js";
|
|
8
|
+
|
|
9
|
+
export type Type =
|
|
10
|
+
| SimpleType
|
|
11
|
+
| TypeVar
|
|
12
|
+
| ListType
|
|
13
|
+
| TypeApplication
|
|
14
|
+
| TupleType
|
|
15
|
+
| ParameterizedType
|
|
16
|
+
| ConstrainedType;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Represents a basic named type (e.g., Int, Bool).
|
|
20
|
+
* @category Types
|
|
21
|
+
*/
|
|
22
|
+
export class SimpleType extends ASTNode {
|
|
23
|
+
/** @hidden */
|
|
24
|
+
public constraints: Constraint[];
|
|
25
|
+
/** @hidden */
|
|
26
|
+
public value: string;
|
|
27
|
+
|
|
28
|
+
constructor(value: string, constraints: Constraint[], loc?: SourceLocation) {
|
|
29
|
+
super(loc);
|
|
30
|
+
this.value = value;
|
|
31
|
+
this.constraints = constraints;
|
|
32
|
+
}
|
|
33
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
34
|
+
return visitor.visitSimpleType?.(this);
|
|
35
|
+
}
|
|
36
|
+
toString() {
|
|
37
|
+
return this.value;
|
|
38
|
+
}
|
|
39
|
+
toJSON() {
|
|
40
|
+
return {
|
|
41
|
+
type: "SimpleType",
|
|
42
|
+
value: this.value,
|
|
43
|
+
constraints: this.constraints.map((c) => c.toJSON()),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Represents a type variable (e.g., 'a), used in polymorphic types.
|
|
49
|
+
* @category Types
|
|
50
|
+
*/
|
|
51
|
+
export class TypeVar extends ASTNode {
|
|
52
|
+
/** @hidden */
|
|
53
|
+
public constraints: Constraint[];
|
|
54
|
+
/** @hidden */
|
|
55
|
+
public value: string;
|
|
56
|
+
|
|
57
|
+
constructor(value: string, constraints: Constraint[], loc?: SourceLocation) {
|
|
58
|
+
super(loc);
|
|
59
|
+
this.value = value;
|
|
60
|
+
this.constraints = constraints;
|
|
61
|
+
}
|
|
62
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
63
|
+
return visitor.visitTypeVar?.(this);
|
|
64
|
+
}
|
|
65
|
+
toString(): string {
|
|
66
|
+
return this.value;
|
|
67
|
+
}
|
|
68
|
+
toJSON() {
|
|
69
|
+
return {
|
|
70
|
+
type: "TypeVar",
|
|
71
|
+
value: this.value,
|
|
72
|
+
constraints: this.constraints.map((c) => c.toJSON()),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Represents the application of a type constructor to arguments (e.g., List Int).
|
|
78
|
+
* @category Types
|
|
79
|
+
*/
|
|
80
|
+
export class TypeApplication extends ASTNode {
|
|
81
|
+
/** @hidden */
|
|
82
|
+
public argument: Type;
|
|
83
|
+
/** @hidden */
|
|
84
|
+
public functionType: Type;
|
|
85
|
+
|
|
86
|
+
constructor(functionType: Type, argument: Type, loc?: SourceLocation) {
|
|
87
|
+
super(loc);
|
|
88
|
+
this.functionType = functionType;
|
|
89
|
+
this.argument = argument;
|
|
90
|
+
}
|
|
91
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
92
|
+
return visitor.visitTypeApplication?.(this);
|
|
93
|
+
}
|
|
94
|
+
toString(): string {
|
|
95
|
+
const func = this.functionType.toString();
|
|
96
|
+
let arg = this.argument.toString();
|
|
97
|
+
if (
|
|
98
|
+
this.argument instanceof TypeApplication ||
|
|
99
|
+
this.argument instanceof ParameterizedType
|
|
100
|
+
) {
|
|
101
|
+
arg = `(${arg})`;
|
|
102
|
+
}
|
|
103
|
+
return `${func} ${arg}`;
|
|
104
|
+
}
|
|
105
|
+
toJSON() {
|
|
106
|
+
return {
|
|
107
|
+
type: "TypeApplication",
|
|
108
|
+
function: this.functionType.toJSON(),
|
|
109
|
+
argument: this.argument.toJSON(),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Represents a list type (e.g., [Int]).
|
|
115
|
+
* @category Types
|
|
116
|
+
*/
|
|
117
|
+
export class ListType extends ASTNode {
|
|
118
|
+
/** @hidden */
|
|
119
|
+
public constraints: Constraint[];
|
|
120
|
+
/** @hidden */
|
|
121
|
+
public values: Type;
|
|
122
|
+
|
|
123
|
+
constructor(values: Type, constraints: Constraint[], loc?: SourceLocation) {
|
|
124
|
+
super(loc);
|
|
125
|
+
this.values = values;
|
|
126
|
+
this.constraints = constraints;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
130
|
+
return visitor.visitListType?.(this);
|
|
131
|
+
}
|
|
132
|
+
toString() {
|
|
133
|
+
return `[${this.values.toString()}]`;
|
|
134
|
+
}
|
|
135
|
+
toJSON() {
|
|
136
|
+
return {
|
|
137
|
+
type: "ListType",
|
|
138
|
+
values: this.values.toJSON(),
|
|
139
|
+
constraints: this.constraints.map((c) => c.toJSON()),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Represents a tuple type (e.g., (Int, Bool)).
|
|
145
|
+
* @category Types
|
|
146
|
+
*/
|
|
147
|
+
export class TupleType extends ASTNode {
|
|
148
|
+
/** @hidden */
|
|
149
|
+
public constraints: Constraint[];
|
|
150
|
+
/** @hidden */
|
|
151
|
+
public values: Type[];
|
|
152
|
+
|
|
153
|
+
constructor(values: Type[], constraints: Constraint[], loc?: SourceLocation) {
|
|
154
|
+
super(loc);
|
|
155
|
+
this.values = values;
|
|
156
|
+
this.constraints = constraints;
|
|
157
|
+
}
|
|
158
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
159
|
+
return visitor.visitTupleType?.(this);
|
|
160
|
+
}
|
|
161
|
+
toString() {
|
|
162
|
+
return `(${this.values.map((t) => t.toString()).join(", ")})`;
|
|
163
|
+
}
|
|
164
|
+
toJSON() {
|
|
165
|
+
return {
|
|
166
|
+
type: "TupleType",
|
|
167
|
+
values: this.values.map((val) => val.toJSON()),
|
|
168
|
+
constraints: this.constraints.map((c) => c.toJSON()),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Represents a type constraint or class constraint (e.g., Eq a).
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* (Eq a) => a -> a -> Bool
|
|
178
|
+
* @category Types
|
|
179
|
+
*/
|
|
180
|
+
export class Constraint extends ASTNode {
|
|
181
|
+
/** @hidden */
|
|
182
|
+
public parameters: Type[];
|
|
183
|
+
/** @hidden */
|
|
184
|
+
public name: string;
|
|
185
|
+
|
|
186
|
+
constructor(name: string, parameters: Type[], loc?: SourceLocation) {
|
|
187
|
+
super(loc);
|
|
188
|
+
this.name = name;
|
|
189
|
+
this.parameters = parameters;
|
|
190
|
+
}
|
|
191
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
192
|
+
return visitor.visitConstraint?.(this);
|
|
193
|
+
}
|
|
194
|
+
toJSON() {
|
|
195
|
+
return {
|
|
196
|
+
type: "Constraint",
|
|
197
|
+
name: this.name,
|
|
198
|
+
parameters: this.parameters.map((p) => p.toJSON()),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Represents a type that accepts type parameters.
|
|
205
|
+
* @category Types
|
|
206
|
+
*/
|
|
207
|
+
export class ParameterizedType extends ASTNode {
|
|
208
|
+
/** @hidden */
|
|
209
|
+
public constraints: Constraint[];
|
|
210
|
+
/** @hidden */
|
|
211
|
+
public returnType: Type;
|
|
212
|
+
/** @hidden */
|
|
213
|
+
public inputs: Type[];
|
|
214
|
+
|
|
215
|
+
constructor(
|
|
216
|
+
inputs: Type[],
|
|
217
|
+
returnType: Type,
|
|
218
|
+
constraints: Constraint[],
|
|
219
|
+
loc?: SourceLocation
|
|
220
|
+
) {
|
|
221
|
+
super(loc);
|
|
222
|
+
this.inputs = inputs;
|
|
223
|
+
this.returnType = returnType;
|
|
224
|
+
this.constraints = constraints;
|
|
225
|
+
}
|
|
226
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
227
|
+
return visitor.visitParameterizedType?.(this);
|
|
228
|
+
}
|
|
229
|
+
toString() {
|
|
230
|
+
const inputs = this.inputs.map((t) => {
|
|
231
|
+
const str = t.toString();
|
|
232
|
+
return t instanceof ParameterizedType ? `(${str})` : str;
|
|
233
|
+
});
|
|
234
|
+
const ret = this.returnType.toString();
|
|
235
|
+
const signature = [...inputs, ret].join(" -> ");
|
|
236
|
+
|
|
237
|
+
if (this.constraints.length > 0) {
|
|
238
|
+
const constraints = this.constraints
|
|
239
|
+
.map((c) => {
|
|
240
|
+
const params = c.parameters.map((p) => p.toString()).join(" ");
|
|
241
|
+
return params ? `${c.name} ${params}` : c.name;
|
|
242
|
+
})
|
|
243
|
+
.join(", ");
|
|
244
|
+
const context =
|
|
245
|
+
this.constraints.length > 1 ? `(${constraints})` : constraints;
|
|
246
|
+
return `${context} => ${signature}`;
|
|
247
|
+
}
|
|
248
|
+
return signature;
|
|
249
|
+
}
|
|
250
|
+
toJSON() {
|
|
251
|
+
return {
|
|
252
|
+
type: "ParameterizedType",
|
|
253
|
+
inputs: this.inputs.map((p) => p.toJSON()),
|
|
254
|
+
return: this.returnType.toJSON(),
|
|
255
|
+
constraints: this.constraints.map((p) => p.toJSON()),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Represents a type qualified by a context of constraints.
|
|
261
|
+
* @category Types
|
|
262
|
+
*/
|
|
263
|
+
export class ConstrainedType extends ASTNode {
|
|
264
|
+
/** @hidden */
|
|
265
|
+
public constraints: Constraint[];
|
|
266
|
+
|
|
267
|
+
constructor(constraints: Constraint[], loc?: SourceLocation) {
|
|
268
|
+
super(loc);
|
|
269
|
+
this.constraints = constraints;
|
|
270
|
+
}
|
|
271
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
272
|
+
return visitor.visitConstrainedType?.(this);
|
|
273
|
+
}
|
|
274
|
+
toJSON() {
|
|
275
|
+
return {
|
|
276
|
+
type: "ConstrainedType",
|
|
277
|
+
constraints: this.constraints.map((p) => p.toJSON()),
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Represents a type alias definition, giving a new name to an existing type.
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* type String = [Char]
|
|
287
|
+
* @category Types
|
|
288
|
+
*/
|
|
289
|
+
export class TypeAlias extends ASTNode {
|
|
290
|
+
/** @hidden */
|
|
291
|
+
public value: Type;
|
|
292
|
+
/** @hidden */
|
|
293
|
+
public variables: string[];
|
|
294
|
+
/** @hidden */
|
|
295
|
+
public identifier: SymbolPrimitive;
|
|
296
|
+
|
|
297
|
+
constructor(
|
|
298
|
+
identifier: SymbolPrimitive,
|
|
299
|
+
variables: string[],
|
|
300
|
+
value: Type,
|
|
301
|
+
loc?: SourceLocation
|
|
302
|
+
) {
|
|
303
|
+
super(loc);
|
|
304
|
+
this.identifier = identifier;
|
|
305
|
+
this.variables = variables;
|
|
306
|
+
this.value = value;
|
|
307
|
+
}
|
|
308
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
309
|
+
return visitor.visitTypeAlias?.(this);
|
|
310
|
+
}
|
|
311
|
+
toJSON() {
|
|
312
|
+
return {
|
|
313
|
+
type: "TypeAlias",
|
|
314
|
+
identifier: this.identifier.toJSON(),
|
|
315
|
+
variables: this.variables,
|
|
316
|
+
value: this.value.toJSON(),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Represents an explicit type signature declaration for a function or variable.
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* add :: Int -> Int -> Int
|
|
326
|
+
* @category Types
|
|
327
|
+
*/
|
|
328
|
+
export class TypeSignature extends ASTNode {
|
|
329
|
+
/** @hidden */
|
|
330
|
+
public body: Type;
|
|
331
|
+
/** @hidden */
|
|
332
|
+
public identifier: SymbolPrimitive;
|
|
333
|
+
|
|
334
|
+
constructor(identifier: SymbolPrimitive, body: Type, loc?: SourceLocation) {
|
|
335
|
+
super(loc);
|
|
336
|
+
this.identifier = identifier;
|
|
337
|
+
this.body = body;
|
|
338
|
+
}
|
|
339
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
340
|
+
return visitor.visitTypeSignature?.(this);
|
|
341
|
+
}
|
|
342
|
+
toJSON() {
|
|
343
|
+
return {
|
|
344
|
+
type: "TypeSignature",
|
|
345
|
+
identifier: this.identifier.toJSON(),
|
|
346
|
+
body: this.body.toJSON(),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Represents an explicit type casting or annotation expression.
|
|
352
|
+
* @category Types
|
|
353
|
+
*/
|
|
354
|
+
export class TypeCast extends ASTNode {
|
|
355
|
+
/** @hidden */
|
|
356
|
+
public body: Type;
|
|
357
|
+
/** @hidden */
|
|
358
|
+
public expression: Expression;
|
|
359
|
+
|
|
360
|
+
constructor(expression: Expression, body: Type, loc?: SourceLocation) {
|
|
361
|
+
super(loc);
|
|
362
|
+
this.expression = expression;
|
|
363
|
+
this.body = body;
|
|
364
|
+
}
|
|
365
|
+
accept<R>(visitor: Visitor<R>): R {
|
|
366
|
+
return visitor.visitTypeCast?.(this);
|
|
367
|
+
}
|
|
368
|
+
toJSON() {
|
|
369
|
+
return {
|
|
370
|
+
type: "TypeCast",
|
|
371
|
+
expression: this.expression.toJSON(),
|
|
372
|
+
body: this.body.toJSON(),
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
}
|