@rsconcept/domain 1.0.0 → 1.2.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/README.md +3 -3
- package/dist/analyzer-DlSq3Y3r.d.ts +39 -0
- package/dist/arguments-extractor-1acwjQNc.d.ts +38 -0
- package/dist/ast-C8sIpKdL.d.ts +51 -0
- package/dist/ast-annotations-BiMjkKvz.d.ts +16 -0
- package/dist/branded-ZlzIcxzu.d.ts +9 -0
- package/dist/calculator-C9W2jkSx.d.ts +39 -0
- package/dist/cctext/index.d.ts +2 -1
- package/dist/cctext/index.js +2 -42
- package/dist/cctext/language-api.d.ts +10 -12
- package/dist/cctext/language-api.js +157 -227
- package/dist/cctext/language-api.js.map +1 -1
- package/dist/cctext/language.d.ts +24 -22
- package/dist/cctext/language.js +43 -39
- package/dist/cctext/language.js.map +1 -1
- package/dist/error-E1LVq_3w.d.ts +87 -0
- package/dist/graph/graph.d.ts +2 -62
- package/dist/graph/graph.js +339 -382
- package/dist/graph/graph.js.map +1 -1
- package/dist/graph/index.d.ts +2 -1
- package/dist/graph/index.js +2 -384
- package/dist/graph-DR8rL2o3.d.ts +64 -0
- package/dist/hash-Y8I4c6Al.d.ts +8 -0
- package/dist/index-BKZ67WMa.d.ts +1 -0
- package/dist/index-BVVgDSdq.d.ts +1 -0
- package/dist/index-DmtQKWjk.d.ts +1 -0
- package/dist/index-_6s0AX1B.d.ts +1 -0
- package/dist/index.d.ts +27 -28
- package/dist/index.js +23 -5851
- package/dist/lezer-tree-iS7LpLBJ.d.ts +14 -0
- package/dist/library/folder-tree.d.ts +22 -20
- package/dist/library/folder-tree.js +108 -130
- package/dist/library/folder-tree.js.map +1 -1
- package/dist/library/index.d.ts +8 -17
- package/dist/library/index.js +7 -2800
- package/dist/library/library-api.d.ts +3 -1
- package/dist/library/library-api.js +9 -8
- package/dist/library/library-api.js.map +1 -1
- package/dist/library/library.d.ts +2 -56
- package/dist/library/library.js +23 -19
- package/dist/library/library.js.map +1 -1
- package/dist/library/oss-api.d.ts +26 -37
- package/dist/library/oss-api.js +258 -1096
- package/dist/library/oss-api.js.map +1 -1
- package/dist/library/oss-layout-api.d.ts +28 -28
- package/dist/library/oss-layout-api.js +239 -316
- package/dist/library/oss-layout-api.js.map +1 -1
- package/dist/library/oss-layout.d.ts +2 -25
- package/dist/library/oss-layout.js +1 -1
- package/dist/library/oss.d.ts +87 -89
- package/dist/library/oss.js +27 -26
- package/dist/library/oss.js.map +1 -1
- package/dist/library/rsengine.d.ts +100 -106
- package/dist/library/rsengine.js +439 -2599
- package/dist/library/rsengine.js.map +1 -1
- package/dist/library/rsform-api.d.ts +11 -16
- package/dist/library/rsform-api.js +313 -825
- package/dist/library/rsform-api.js.map +1 -1
- package/dist/library/rsform.d.ts +159 -167
- package/dist/library/rsform.js +29 -28
- package/dist/library/rsform.js.map +1 -1
- package/dist/library/rsmodel-api.d.ts +8 -15
- package/dist/library/rsmodel-api.js +172 -813
- package/dist/library/rsmodel-api.js.map +1 -1
- package/dist/library/rsmodel.d.ts +27 -33
- package/dist/library/rsmodel.js +16 -23
- package/dist/library/rsmodel.js.map +1 -1
- package/dist/library/structure-planner.d.ts +20 -26
- package/dist/library/structure-planner.js +106 -474
- package/dist/library/structure-planner.js.map +1 -1
- package/dist/library-CYun28Xz.d.ts +58 -0
- package/dist/oss-layout-3glgAqfn.d.ts +27 -0
- package/dist/parser-Bwd8LxJ1.d.ts +7 -0
- package/dist/parsing/ast.d.ts +2 -49
- package/dist/parsing/ast.js +68 -76
- package/dist/parsing/ast.js.map +1 -1
- package/dist/parsing/index.d.ts +3 -3
- package/dist/parsing/index.js +3 -141
- package/dist/parsing/lezer-tree.d.ts +2 -13
- package/dist/parsing/lezer-tree.js +50 -43
- package/dist/parsing/lezer-tree.js.map +1 -1
- package/dist/rslang/api.d.ts +9 -14
- package/dist/rslang/api.js +114 -827
- package/dist/rslang/api.js.map +1 -1
- package/dist/rslang/ast-annotations.d.ts +2 -18
- package/dist/rslang/ast-annotations.js +34 -45
- package/dist/rslang/ast-annotations.js.map +1 -1
- package/dist/rslang/error.d.ts +2 -85
- package/dist/rslang/error.js +88 -150
- package/dist/rslang/error.js.map +1 -1
- package/dist/rslang/eval/calculator.d.ts +2 -43
- package/dist/rslang/eval/calculator.js +81 -1636
- package/dist/rslang/eval/calculator.js.map +1 -1
- package/dist/rslang/eval/evaluation-cache.d.ts +22 -26
- package/dist/rslang/eval/evaluation-cache.js +168 -287
- package/dist/rslang/eval/evaluation-cache.js.map +1 -1
- package/dist/rslang/eval/evaluator.d.ts +59 -63
- package/dist/rslang/eval/evaluator.js +602 -1509
- package/dist/rslang/eval/evaluator.js.map +1 -1
- package/dist/rslang/eval/value-api.d.ts +2 -48
- package/dist/rslang/eval/value-api.js +2 -490
- package/dist/rslang/eval/value.d.ts +2 -36
- package/dist/rslang/eval/value.js +2 -118
- package/dist/rslang/index.d.ts +14 -17
- package/dist/rslang/index.js +12 -4314
- package/dist/rslang/labels.d.ts +6 -6
- package/dist/rslang/labels.js +139 -305
- package/dist/rslang/labels.js.map +1 -1
- package/dist/rslang/parser/expression-generator.d.ts +5 -5
- package/dist/rslang/parser/expression-generator.js +248 -446
- package/dist/rslang/parser/expression-generator.js.map +1 -1
- package/dist/rslang/parser/normalize.d.ts +4 -8
- package/dist/rslang/parser/normalize.js +286 -481
- package/dist/rslang/parser/normalize.js.map +1 -1
- package/dist/rslang/parser/parser.d.ts +2 -5
- package/dist/rslang/parser/parser.js +30 -21
- package/dist/rslang/parser/parser.js.map +1 -1
- package/dist/rslang/parser/parser.terms.d.ts +43 -41
- package/dist/rslang/parser/parser.terms.js +44 -83
- package/dist/rslang/parser/parser.terms.js.map +1 -1
- package/dist/rslang/parser/syntax-errors.d.ts +5 -8
- package/dist/rslang/parser/syntax-errors.js +113 -382
- package/dist/rslang/parser/syntax-errors.js.map +1 -1
- package/dist/rslang/parser/token.d.ts +2 -79
- package/dist/rslang/parser/token.js +81 -93
- package/dist/rslang/parser/token.js.map +1 -1
- package/dist/rslang/semantic/analyzer.d.ts +2 -39
- package/dist/rslang/semantic/analyzer.js +186 -2600
- package/dist/rslang/semantic/analyzer.js.map +1 -1
- package/dist/rslang/semantic/arguments-extractor.d.ts +2 -42
- package/dist/rslang/semantic/arguments-extractor.js +202 -361
- package/dist/rslang/semantic/arguments-extractor.js.map +1 -1
- package/dist/rslang/semantic/type-auditor.d.ts +64 -68
- package/dist/rslang/semantic/type-auditor.js +594 -1564
- package/dist/rslang/semantic/type-auditor.js.map +1 -1
- package/dist/rslang/semantic/typification-api.d.ts +4 -7
- package/dist/rslang/semantic/typification-api.js +162 -303
- package/dist/rslang/semantic/typification-api.js.map +1 -1
- package/dist/rslang/semantic/typification-parser.d.ts +2 -12
- package/dist/rslang/semantic/typification-parser.js +165 -219
- package/dist/rslang/semantic/typification-parser.js.map +1 -1
- package/dist/rslang/semantic/typification.d.ts +2 -119
- package/dist/rslang/semantic/typification.js +66 -52
- package/dist/rslang/semantic/typification.js.map +1 -1
- package/dist/rslang/semantic/value-auditor.d.ts +32 -38
- package/dist/rslang/semantic/value-auditor.js +206 -518
- package/dist/rslang/semantic/value-auditor.js.map +1 -1
- package/dist/rslang/semantic/value-class.d.ts +2 -10
- package/dist/rslang/semantic/value-class.js +8 -7
- package/dist/rslang/semantic/value-class.js.map +1 -1
- package/dist/rslang/typification-graph.d.ts +2 -33
- package/dist/rslang/typification-graph.js +94 -306
- package/dist/rslang/typification-graph.js.map +1 -1
- package/dist/shared/branded.d.ts +2 -7
- package/dist/shared/branded.js +1 -1
- package/dist/shared/hash.d.ts +2 -6
- package/dist/shared/hash.js +13 -13
- package/dist/shared/hash.js.map +1 -1
- package/dist/shared/index.d.ts +3 -2
- package/dist/shared/index.js +2 -18
- package/dist/token-DeXAmzwr.d.ts +81 -0
- package/dist/typification-Dk-fisgO.d.ts +120 -0
- package/dist/typification-graph-6HcZ-rKH.d.ts +30 -0
- package/dist/typification-parser-BBVx1RxP.d.ts +13 -0
- package/dist/value-B8UtCqaK.js +366 -0
- package/dist/value-B8UtCqaK.js.map +1 -0
- package/dist/value-CTjX6825.d.ts +33 -0
- package/dist/value-api-Bw-SgaYY.d.ts +49 -0
- package/dist/value-class-CNI-lqXJ.d.ts +12 -0
- package/package.json +8 -8
- package/src/library/oss-api.test.ts +76 -0
- package/src/library/oss-api.ts +4 -1
- package/src/library/rsform-api.test.ts +24 -0
- package/src/library/rsform-api.ts +12 -4
- package/dist/cctext/index.js.map +0 -1
- package/dist/graph/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/library/index.js.map +0 -1
- package/dist/library/oss-layout.js.map +0 -1
- package/dist/parsing/index.js.map +0 -1
- package/dist/rslang/eval/value-api.js.map +0 -1
- package/dist/rslang/eval/value.js.map +0 -1
- package/dist/rslang/index.js.map +0 -1
- package/dist/shared/branded.js.map +0 -1
- package/dist/shared/index.js.map +0 -1
|
@@ -1,1570 +1,600 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
return false;
|
|
520
|
-
}
|
|
521
|
-
for (let index = 0; index < type1.factors.length; ++index) {
|
|
522
|
-
if (!checkEquality(type1.factors[index], type2.factors[index])) {
|
|
523
|
-
return false;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return true;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
function mergeTypifications(type1, type2) {
|
|
531
|
-
if (type1 === type2) {
|
|
532
|
-
return type1;
|
|
533
|
-
}
|
|
534
|
-
if (type1.typeID === TypeID.anyTypification) {
|
|
535
|
-
return isTypification(type2) ? type2 : null;
|
|
536
|
-
}
|
|
537
|
-
if (type2.typeID === TypeID.anyTypification) {
|
|
538
|
-
return isTypification(type1) ? type1 : null;
|
|
539
|
-
}
|
|
540
|
-
switch (type1.typeID) {
|
|
541
|
-
case TypeID.integer:
|
|
542
|
-
case TypeID.basic:
|
|
543
|
-
return commonType(type1, type2);
|
|
544
|
-
case TypeID.collection:
|
|
545
|
-
if (type2.typeID !== TypeID.collection) {
|
|
546
|
-
return null;
|
|
547
|
-
}
|
|
548
|
-
const base = mergeTypifications(type1.base, type2.base);
|
|
549
|
-
return base ? bool(base) : null;
|
|
550
|
-
case TypeID.tuple:
|
|
551
|
-
if (type2.typeID !== TypeID.tuple) {
|
|
552
|
-
return null;
|
|
553
|
-
}
|
|
554
|
-
if (type1.factors.length !== type2.factors.length) {
|
|
555
|
-
return null;
|
|
556
|
-
}
|
|
557
|
-
const components = [];
|
|
558
|
-
for (let index = 0; index < type1.factors.length; ++index) {
|
|
559
|
-
const component2 = mergeTypifications(type1.factors[index], type2.factors[index]);
|
|
560
|
-
if (component2 === null) {
|
|
561
|
-
return null;
|
|
562
|
-
}
|
|
563
|
-
components.push(component2);
|
|
564
|
-
}
|
|
565
|
-
return tuple(components);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
function checkCompatibility(type1, type2) {
|
|
569
|
-
if (type1 === type2) {
|
|
570
|
-
return true;
|
|
571
|
-
}
|
|
572
|
-
if (type1.typeID === TypeID.anyTypification) {
|
|
573
|
-
return isTypification(type2);
|
|
574
|
-
}
|
|
575
|
-
if (type2.typeID === TypeID.anyTypification) {
|
|
576
|
-
return isTypification(type1);
|
|
577
|
-
}
|
|
578
|
-
if (isTypification(type1) !== isTypification(type2)) {
|
|
579
|
-
return false;
|
|
580
|
-
}
|
|
581
|
-
if (type1.typeID === TypeID.integer || type1.typeID === TypeID.basic || type2.typeID === TypeID.integer || type2.typeID === TypeID.basic) {
|
|
582
|
-
return commonType(type1, type2) !== null;
|
|
583
|
-
}
|
|
584
|
-
if (type1.typeID !== type2.typeID) {
|
|
585
|
-
return false;
|
|
586
|
-
}
|
|
587
|
-
switch (type1.typeID) {
|
|
588
|
-
case TypeID.collection:
|
|
589
|
-
return checkCompatibility(type1.base, type2.base);
|
|
590
|
-
case TypeID.tuple:
|
|
591
|
-
if (type1.factors.length !== type2.factors.length) {
|
|
592
|
-
return false;
|
|
593
|
-
}
|
|
594
|
-
for (let index = 0; index < type1.factors.length; ++index) {
|
|
595
|
-
if (!checkCompatibility(type1.factors[index], type2.factors[index])) {
|
|
596
|
-
return false;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
return true;
|
|
600
|
-
case TypeID.logic:
|
|
601
|
-
case TypeID.predicate:
|
|
602
|
-
case TypeID.function:
|
|
603
|
-
return false;
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
function compareTemplated(substitutes, arg, value) {
|
|
607
|
-
if (arg === value) {
|
|
608
|
-
return true;
|
|
609
|
-
}
|
|
610
|
-
if (arg.typeID === TypeID.basic && isRadical(arg.baseID)) {
|
|
611
|
-
if (!substitutes.has(arg.baseID)) {
|
|
612
|
-
substitutes.set(arg.baseID, value);
|
|
613
|
-
return true;
|
|
614
|
-
} else {
|
|
615
|
-
const mergeType = mergeTypifications(substitutes.get(arg.baseID), value);
|
|
616
|
-
if (mergeType === null) {
|
|
617
|
-
return false;
|
|
618
|
-
}
|
|
619
|
-
substitutes.set(arg.baseID, mergeType);
|
|
620
|
-
return true;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
if (value.typeID === TypeID.anyTypification) {
|
|
624
|
-
return true;
|
|
625
|
-
}
|
|
626
|
-
if (arg.typeID === TypeID.integer || arg.typeID === TypeID.basic || value.typeID === TypeID.integer || value.typeID === TypeID.basic) {
|
|
627
|
-
return commonType(arg, value) !== null;
|
|
628
|
-
}
|
|
629
|
-
if (arg.typeID !== value.typeID) {
|
|
630
|
-
return false;
|
|
631
|
-
}
|
|
632
|
-
switch (arg.typeID) {
|
|
633
|
-
case TypeID.collection:
|
|
634
|
-
return compareTemplated(substitutes, arg.base, value.base);
|
|
635
|
-
case TypeID.tuple: {
|
|
636
|
-
if (arg.factors.length !== value.factors.length) {
|
|
637
|
-
return false;
|
|
638
|
-
}
|
|
639
|
-
for (let index = 0; index < arg.factors.length; ++index) {
|
|
640
|
-
if (!compareTemplated(substitutes, arg.factors[index], value.factors[index])) {
|
|
641
|
-
return false;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
return true;
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
function substituteBase(target, substitutes) {
|
|
649
|
-
switch (target.typeID) {
|
|
650
|
-
case TypeID.basic: {
|
|
651
|
-
if (substitutes.has(target.baseID)) {
|
|
652
|
-
Object.assign(target, substitutes.get(target.baseID));
|
|
653
|
-
}
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
case TypeID.collection: {
|
|
657
|
-
substituteBase(target.base, substitutes);
|
|
658
|
-
return;
|
|
659
|
-
}
|
|
660
|
-
case TypeID.tuple: {
|
|
661
|
-
for (const factor of target.factors) {
|
|
662
|
-
substituteBase(factor, substitutes);
|
|
663
|
-
}
|
|
664
|
-
return;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
function commonType(type1, type2) {
|
|
669
|
-
if (type1 === type2) {
|
|
670
|
-
return type1;
|
|
671
|
-
}
|
|
672
|
-
const int1 = "isIntegerCompatible" in type1 && type1.isIntegerCompatible;
|
|
673
|
-
const int2 = "isIntegerCompatible" in type2 && type2.isIntegerCompatible;
|
|
674
|
-
if (!int1 || !int2) {
|
|
675
|
-
if (type1.typeID === TypeID.basic && type2.typeID === TypeID.basic) {
|
|
676
|
-
return type1.baseID === type2.baseID ? type1 : null;
|
|
677
|
-
}
|
|
678
|
-
return null;
|
|
679
|
-
}
|
|
680
|
-
if (type1.typeID === TypeID.integer) {
|
|
681
|
-
return type2;
|
|
682
|
-
} else if (type2.typeID === TypeID.integer) {
|
|
683
|
-
return type1;
|
|
684
|
-
} else {
|
|
685
|
-
return IntegerT;
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
// src/rslang/semantic/type-auditor.ts
|
|
690
|
-
var TypeAuditor = class _TypeAuditor {
|
|
691
|
-
static TYPE_DEDUCTION_DEPTH = 5;
|
|
692
|
-
context;
|
|
693
|
-
reporter;
|
|
694
|
-
locals;
|
|
695
|
-
annotateTypes;
|
|
696
|
-
annotateErrors;
|
|
697
|
-
constructor(context) {
|
|
698
|
-
this.annotateTypes = false;
|
|
699
|
-
this.annotateErrors = false;
|
|
700
|
-
this.context = context;
|
|
701
|
-
this.locals = new LocalContext(this.onError.bind(this));
|
|
702
|
-
}
|
|
703
|
-
run(ast, annotateTypes, reporter, annotateErrors = false) {
|
|
704
|
-
if (ast.hasError) {
|
|
705
|
-
return null;
|
|
706
|
-
}
|
|
707
|
-
this.annotateTypes = annotateTypes;
|
|
708
|
-
this.annotateErrors = annotateErrors;
|
|
709
|
-
this.reporter = reporter;
|
|
710
|
-
this.clear();
|
|
711
|
-
return this.dispatchVisit(ast);
|
|
712
|
-
}
|
|
713
|
-
clear() {
|
|
714
|
-
this.locals = new LocalContext(this.onError.bind(this));
|
|
715
|
-
}
|
|
716
|
-
dispatchDeclare(node, domain) {
|
|
717
|
-
const result = this.processDeclare(node, domain);
|
|
718
|
-
if (result === true && this.annotateTypes) {
|
|
719
|
-
annotateType(node, domain);
|
|
720
|
-
}
|
|
721
|
-
return result;
|
|
722
|
-
}
|
|
723
|
-
processDeclare(node, domain) {
|
|
724
|
-
switch (node.typeID) {
|
|
725
|
-
case TokenID.ID_LOCAL:
|
|
726
|
-
return this.declareLocal(node, domain);
|
|
727
|
-
case TokenID.NT_TUPLE_DECL:
|
|
728
|
-
return this.declareTuple(node, domain);
|
|
729
|
-
case TokenID.NT_ENUM_DECL:
|
|
730
|
-
return this.declareEnumeration(node, domain);
|
|
731
|
-
}
|
|
732
|
-
return false;
|
|
733
|
-
}
|
|
734
|
-
declareLocal(node, domain) {
|
|
735
|
-
return this.locals.pushLocal(node, domain);
|
|
736
|
-
}
|
|
737
|
-
declareTuple(node, domain) {
|
|
738
|
-
if (domain.typeID !== TypeID.tuple || domain.factors.length !== node.children.length) {
|
|
739
|
-
this.onError(RSErrorCode.invalidCortegeDeclare, node.children[0]);
|
|
740
|
-
return false;
|
|
741
|
-
}
|
|
742
|
-
for (let child = 0; child < node.children.length; child++) {
|
|
743
|
-
if (!this.visitChildDeclaration(node, child, component(domain, child + 1))) {
|
|
744
|
-
return false;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
return true;
|
|
748
|
-
}
|
|
749
|
-
declareEnumeration(node, domain) {
|
|
750
|
-
for (const child of node.children) {
|
|
751
|
-
if (!this.dispatchDeclare(child, domain)) {
|
|
752
|
-
return false;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
return true;
|
|
756
|
-
}
|
|
757
|
-
dispatchVisit(node) {
|
|
758
|
-
const result = this.processVisit(node);
|
|
759
|
-
if (result !== null && this.annotateTypes) {
|
|
760
|
-
annotateType(node, result);
|
|
761
|
-
}
|
|
762
|
-
return result;
|
|
763
|
-
}
|
|
764
|
-
processVisit(node) {
|
|
765
|
-
switch (node.typeID) {
|
|
766
|
-
case TokenID.ID_GLOBAL:
|
|
767
|
-
case TokenID.ID_FUNCTION:
|
|
768
|
-
case TokenID.ID_PREDICATE:
|
|
769
|
-
return this.visitGlobal(node);
|
|
770
|
-
case TokenID.ID_LOCAL:
|
|
771
|
-
return this.visitLocal(node);
|
|
772
|
-
case TokenID.ID_RADICAL:
|
|
773
|
-
return this.visitRadical(node);
|
|
774
|
-
case TokenID.LIT_INTEGER:
|
|
775
|
-
return IntegerT;
|
|
776
|
-
case TokenID.LIT_WHOLE_NUMBERS:
|
|
777
|
-
return bool(IntegerT);
|
|
778
|
-
case TokenID.LIT_EMPTYSET:
|
|
779
|
-
return this.visitEmptySet(node);
|
|
780
|
-
case TokenID.NT_ARGUMENTS:
|
|
781
|
-
return this.visitArgumentsEnum(node);
|
|
782
|
-
case TokenID.NT_ARG_DECL:
|
|
783
|
-
return this.visitArgument(node);
|
|
784
|
-
case TokenID.PLUS:
|
|
785
|
-
case TokenID.MINUS:
|
|
786
|
-
case TokenID.MULTIPLY:
|
|
787
|
-
return this.visitArithmetic(node);
|
|
788
|
-
case TokenID.QUANTOR_UNIVERSAL:
|
|
789
|
-
case TokenID.QUANTOR_EXISTS:
|
|
790
|
-
return this.visitQuantifier(node);
|
|
791
|
-
case TokenID.LOGIC_NOT:
|
|
792
|
-
return this.visitNegation(node);
|
|
793
|
-
case TokenID.LOGIC_AND:
|
|
794
|
-
case TokenID.LOGIC_OR:
|
|
795
|
-
case TokenID.LOGIC_IMPLICATION:
|
|
796
|
-
case TokenID.LOGIC_EQUIVALENT:
|
|
797
|
-
return this.visitLogicBinary(node);
|
|
798
|
-
case TokenID.EQUAL:
|
|
799
|
-
case TokenID.NOTEQUAL:
|
|
800
|
-
return this.visitEquals(node);
|
|
801
|
-
case TokenID.GREATER:
|
|
802
|
-
case TokenID.LESSER:
|
|
803
|
-
case TokenID.GREATER_OR_EQ:
|
|
804
|
-
case TokenID.LESSER_OR_EQ:
|
|
805
|
-
return this.visitIntegerPredicate(node);
|
|
806
|
-
case TokenID.SET_IN:
|
|
807
|
-
case TokenID.SET_NOT_IN:
|
|
808
|
-
case TokenID.SUBSET:
|
|
809
|
-
case TokenID.SUBSET_OR_EQ:
|
|
810
|
-
case TokenID.NOT_SUBSET:
|
|
811
|
-
return this.visitSetexprPredicate(node);
|
|
812
|
-
case TokenID.DECART:
|
|
813
|
-
return this.visitDecart(node);
|
|
814
|
-
case TokenID.BOOLEAN:
|
|
815
|
-
return this.visitBoolean(node);
|
|
816
|
-
case TokenID.NT_TUPLE:
|
|
817
|
-
return this.visitTuple(node);
|
|
818
|
-
case TokenID.NT_ENUMERATION:
|
|
819
|
-
return this.visitEnumeration(node);
|
|
820
|
-
case TokenID.BIGPR:
|
|
821
|
-
return this.visitProjectSet(node);
|
|
822
|
-
case TokenID.SMALLPR:
|
|
823
|
-
return this.visitProjectTuple(node);
|
|
824
|
-
case TokenID.FILTER:
|
|
825
|
-
return this.visitFilter(node);
|
|
826
|
-
case TokenID.CARD:
|
|
827
|
-
return this.visitCard(node);
|
|
828
|
-
case TokenID.REDUCE:
|
|
829
|
-
return this.visitReduce(node);
|
|
830
|
-
case TokenID.BOOL:
|
|
831
|
-
return this.visitBool(node);
|
|
832
|
-
case TokenID.DEBOOL:
|
|
833
|
-
return this.visitDebool(node);
|
|
834
|
-
case TokenID.SET_UNION:
|
|
835
|
-
case TokenID.SET_INTERSECTION:
|
|
836
|
-
case TokenID.SET_MINUS:
|
|
837
|
-
case TokenID.SET_SYMMETRIC_MINUS:
|
|
838
|
-
return this.visitSetexprBinary(node);
|
|
839
|
-
case TokenID.NT_FUNC_DEFINITION:
|
|
840
|
-
return this.visitFunctionDefinition(node);
|
|
841
|
-
case TokenID.NT_FUNC_CALL:
|
|
842
|
-
return this.visitFunctionCall(node);
|
|
843
|
-
case TokenID.ITERATE:
|
|
844
|
-
return this.visitIterate(node);
|
|
845
|
-
case TokenID.ASSIGN:
|
|
846
|
-
return this.visitAssign(node);
|
|
847
|
-
case TokenID.NT_DECLARATIVE_EXPR:
|
|
848
|
-
return this.visitDeclarative(node);
|
|
849
|
-
case TokenID.NT_IMPERATIVE_EXPR:
|
|
850
|
-
return this.visitImperative(node);
|
|
851
|
-
case TokenID.NT_RECURSIVE_FULL:
|
|
852
|
-
case TokenID.NT_RECURSIVE_SHORT:
|
|
853
|
-
return this.visitRecursion(node);
|
|
854
|
-
}
|
|
855
|
-
return null;
|
|
856
|
-
}
|
|
857
|
-
onError(code, node, params) {
|
|
858
|
-
this.reporter?.({ code, from: node.from, to: node.to, params });
|
|
859
|
-
if (this.annotateErrors) {
|
|
860
|
-
annotateError(node, code, params);
|
|
861
|
-
}
|
|
862
|
-
return null;
|
|
863
|
-
}
|
|
864
|
-
visitChild(node, index) {
|
|
865
|
-
if (index >= node.children.length) {
|
|
866
|
-
return null;
|
|
867
|
-
}
|
|
868
|
-
return this.dispatchVisit(node.children[index]);
|
|
869
|
-
}
|
|
870
|
-
visitChildDeclaration(node, index, domain) {
|
|
871
|
-
if (index >= node.children.length) {
|
|
872
|
-
return false;
|
|
873
|
-
}
|
|
874
|
-
if (!this.dispatchDeclare(node.children[index], domain)) {
|
|
875
|
-
return false;
|
|
876
|
-
}
|
|
877
|
-
return true;
|
|
878
|
-
}
|
|
879
|
-
visitAllAndReturn(node, type) {
|
|
880
|
-
for (const child of node.children) {
|
|
881
|
-
if (!this.dispatchVisit(child)) {
|
|
882
|
-
return null;
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
return type;
|
|
886
|
-
}
|
|
887
|
-
childTypification(node, index) {
|
|
888
|
-
const result = this.visitChild(node, index);
|
|
889
|
-
if (result === null) {
|
|
890
|
-
return null;
|
|
891
|
-
}
|
|
892
|
-
if (!isTypification(result)) {
|
|
893
|
-
this.onError(RSErrorCode.expectedSetexpr, node.children[index], [labelType(result)]);
|
|
894
|
-
return null;
|
|
895
|
-
}
|
|
896
|
-
return result;
|
|
897
|
-
}
|
|
898
|
-
childLogic(node, index) {
|
|
899
|
-
const result = this.visitChild(node, index);
|
|
900
|
-
if (result === null) {
|
|
901
|
-
return false;
|
|
902
|
-
}
|
|
903
|
-
if (result.typeID !== TypeID.logic) {
|
|
904
|
-
this.onError(RSErrorCode.expectedLogic, node.children[index], [labelType(result)]);
|
|
905
|
-
return false;
|
|
906
|
-
}
|
|
907
|
-
return true;
|
|
908
|
-
}
|
|
909
|
-
childTypeDebool(node, index, errorCode) {
|
|
910
|
-
const result = this.childTypification(node, index);
|
|
911
|
-
if (result === null) {
|
|
912
|
-
return null;
|
|
913
|
-
}
|
|
914
|
-
if (result.typeID === TypeID.anyTypification) {
|
|
915
|
-
return result;
|
|
916
|
-
}
|
|
917
|
-
if (result.typeID !== TypeID.collection) {
|
|
918
|
-
this.onError(errorCode, node.children[index], [labelType(result)]);
|
|
919
|
-
return null;
|
|
920
|
-
}
|
|
921
|
-
return debool(result);
|
|
922
|
-
}
|
|
923
|
-
visitLocal(node) {
|
|
924
|
-
return this.locals.getLocalType(node);
|
|
925
|
-
}
|
|
926
|
-
visitGlobal(node) {
|
|
927
|
-
const alias = getNodeText(node);
|
|
928
|
-
const type = this.context.get(alias);
|
|
929
|
-
if (!type) {
|
|
930
|
-
return this.onError(RSErrorCode.globalNotTyped, node, [alias]);
|
|
931
|
-
}
|
|
932
|
-
return type;
|
|
933
|
-
}
|
|
934
|
-
visitFunctionDefinition(node) {
|
|
935
|
-
this.locals.startScope();
|
|
936
|
-
if (!this.visitChild(node, 0)) {
|
|
937
|
-
return null;
|
|
938
|
-
}
|
|
939
|
-
const args = [];
|
|
940
|
-
for (const local of this.locals.data) {
|
|
941
|
-
if (local.level === 1) {
|
|
942
|
-
args.push({ alias: local.alias, type: local.type });
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
const result = this.visitChild(node, 1);
|
|
946
|
-
if (result === null || result.typeID === TypeID.function || result.typeID === TypeID.predicate) {
|
|
947
|
-
return null;
|
|
948
|
-
}
|
|
949
|
-
this.locals.endScope(node.children[1]);
|
|
950
|
-
if (result.typeID === TypeID.logic) {
|
|
951
|
-
return {
|
|
952
|
-
typeID: TypeID.predicate,
|
|
953
|
-
result,
|
|
954
|
-
args
|
|
955
|
-
};
|
|
956
|
-
} else {
|
|
957
|
-
return {
|
|
958
|
-
typeID: TypeID.function,
|
|
959
|
-
result,
|
|
960
|
-
args
|
|
961
|
-
};
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
visitFunctionCall(node) {
|
|
965
|
-
const funcName = getNodeText(node.children[0]);
|
|
966
|
-
const funcType = this.context.get(funcName);
|
|
967
|
-
if (funcType?.typeID !== TypeID.function && funcType?.typeID !== TypeID.predicate) {
|
|
968
|
-
return this.onError(RSErrorCode.globalNotTyped, node.children[0], [funcName]);
|
|
969
|
-
}
|
|
970
|
-
if (this.annotateTypes) {
|
|
971
|
-
annotateType(node.children[0], funcType);
|
|
972
|
-
}
|
|
973
|
-
const substitutes = this.checkFuncArguments(node, funcName, funcType);
|
|
974
|
-
if (substitutes === null) {
|
|
975
|
-
return null;
|
|
976
|
-
}
|
|
977
|
-
if (funcType.result.typeID === TypeID.logic) {
|
|
978
|
-
return funcType.result;
|
|
979
|
-
} else {
|
|
980
|
-
const result = mangleRadicals(funcName, funcType.result);
|
|
981
|
-
if (substitutes.size > 0) {
|
|
982
|
-
substituteBase(result, substitutes);
|
|
983
|
-
}
|
|
984
|
-
return result;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
visitRadical(node) {
|
|
988
|
-
const alias = getNodeText(node);
|
|
989
|
-
if (!this.isInsideFuncArgument(node)) {
|
|
990
|
-
return this.onError(RSErrorCode.radicalUsage, node, [alias]);
|
|
991
|
-
}
|
|
992
|
-
return bool({ typeID: TypeID.basic, baseID: alias });
|
|
993
|
-
}
|
|
994
|
-
visitEmptySet(node) {
|
|
995
|
-
const invalidParents = [
|
|
996
|
-
TokenID.CARD,
|
|
997
|
-
TokenID.DEBOOL,
|
|
998
|
-
TokenID.SET_UNION,
|
|
999
|
-
TokenID.SET_INTERSECTION,
|
|
1000
|
-
TokenID.SET_MINUS,
|
|
1001
|
-
TokenID.SET_SYMMETRIC_MINUS,
|
|
1002
|
-
TokenID.REDUCE,
|
|
1003
|
-
TokenID.BIGPR,
|
|
1004
|
-
TokenID.SMALLPR
|
|
1005
|
-
];
|
|
1006
|
-
if (invalidParents.includes(node.parent?.typeID)) {
|
|
1007
|
-
return this.onError(RSErrorCode.invalidEmptySetUsage, node);
|
|
1008
|
-
}
|
|
1009
|
-
return EmptySetT;
|
|
1010
|
-
}
|
|
1011
|
-
visitArgument(node) {
|
|
1012
|
-
const variable = node.children[0];
|
|
1013
|
-
if (variable.typeID === TokenID.NT_TUPLE_DECL) {
|
|
1014
|
-
return this.onError(RSErrorCode.invalidArgumentCortegeDeclare, variable);
|
|
1015
|
-
}
|
|
1016
|
-
const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
1017
|
-
if (domain === null) {
|
|
1018
|
-
return null;
|
|
1019
|
-
}
|
|
1020
|
-
if (!this.visitChildDeclaration(node, 0, domain)) {
|
|
1021
|
-
return null;
|
|
1022
|
-
}
|
|
1023
|
-
return domain;
|
|
1024
|
-
}
|
|
1025
|
-
visitCard(node) {
|
|
1026
|
-
if (!this.childTypeDebool(node, 0, RSErrorCode.invalidCard)) {
|
|
1027
|
-
return null;
|
|
1028
|
-
}
|
|
1029
|
-
return IntegerT;
|
|
1030
|
-
}
|
|
1031
|
-
visitArithmetic(node) {
|
|
1032
|
-
const type1 = this.childTypification(node, 0);
|
|
1033
|
-
if (type1 === null) {
|
|
1034
|
-
return null;
|
|
1035
|
-
}
|
|
1036
|
-
if (!("isArithmetic" in type1 && type1.isArithmetic)) {
|
|
1037
|
-
return this.onError(RSErrorCode.arithmeticNotSupported, node.children[0], [labelType(type1)]);
|
|
1038
|
-
}
|
|
1039
|
-
const type2 = this.childTypification(node, 1);
|
|
1040
|
-
if (type2 === null) {
|
|
1041
|
-
return null;
|
|
1042
|
-
}
|
|
1043
|
-
if (!("isArithmetic" in type2 && type2.isArithmetic)) {
|
|
1044
|
-
return this.onError(RSErrorCode.arithmeticNotSupported, node.children[1], [labelType(type2)]);
|
|
1045
|
-
}
|
|
1046
|
-
const result = mergeTypifications(type1, type2);
|
|
1047
|
-
if (result === null) {
|
|
1048
|
-
return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
|
|
1049
|
-
}
|
|
1050
|
-
return result;
|
|
1051
|
-
}
|
|
1052
|
-
visitIntegerPredicate(node) {
|
|
1053
|
-
const type1 = this.childTypification(node, 0);
|
|
1054
|
-
if (type1 === null) {
|
|
1055
|
-
return null;
|
|
1056
|
-
}
|
|
1057
|
-
if (!("isOrdered" in type1 && type1.isOrdered)) {
|
|
1058
|
-
return this.onError(RSErrorCode.orderingNotSupported, node.children[0], [labelType(type1)]);
|
|
1059
|
-
}
|
|
1060
|
-
const type2 = this.childTypification(node, 1);
|
|
1061
|
-
if (type2 === null) {
|
|
1062
|
-
return null;
|
|
1063
|
-
}
|
|
1064
|
-
if (!("isOrdered" in type2 && type2.isOrdered)) {
|
|
1065
|
-
return this.onError(RSErrorCode.orderingNotSupported, node.children[1], [labelType(type2)]);
|
|
1066
|
-
}
|
|
1067
|
-
if (!checkCompatibility(type1, type2)) {
|
|
1068
|
-
return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
|
|
1069
|
-
}
|
|
1070
|
-
return LogicT;
|
|
1071
|
-
}
|
|
1072
|
-
visitQuantifier(node) {
|
|
1073
|
-
this.locals.startScope();
|
|
1074
|
-
const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
1075
|
-
if (domain === null) {
|
|
1076
|
-
return null;
|
|
1077
|
-
} else if (!this.visitChildDeclaration(node, 0, domain)) {
|
|
1078
|
-
return null;
|
|
1079
|
-
} else if (!this.childLogic(node, 2)) {
|
|
1080
|
-
return null;
|
|
1081
|
-
}
|
|
1082
|
-
this.locals.endScope(node.children[2]);
|
|
1083
|
-
return LogicT;
|
|
1084
|
-
}
|
|
1085
|
-
visitNegation(node) {
|
|
1086
|
-
if (!this.childLogic(node, 0)) {
|
|
1087
|
-
return null;
|
|
1088
|
-
}
|
|
1089
|
-
return LogicT;
|
|
1090
|
-
}
|
|
1091
|
-
visitLogicBinary(node) {
|
|
1092
|
-
if (!this.childLogic(node, 0) || !this.childLogic(node, 1)) {
|
|
1093
|
-
return null;
|
|
1094
|
-
}
|
|
1095
|
-
return LogicT;
|
|
1096
|
-
}
|
|
1097
|
-
visitEquals(node) {
|
|
1098
|
-
const type1 = this.childTypification(node, 0);
|
|
1099
|
-
if (type1 === null) {
|
|
1100
|
-
return null;
|
|
1101
|
-
}
|
|
1102
|
-
const type2 = this.childTypification(node, 1);
|
|
1103
|
-
if (type2 === null) {
|
|
1104
|
-
return null;
|
|
1105
|
-
}
|
|
1106
|
-
if (!checkCompatibility(type1, type2)) {
|
|
1107
|
-
return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
|
|
1108
|
-
}
|
|
1109
|
-
return LogicT;
|
|
1110
|
-
}
|
|
1111
|
-
visitSetexprPredicate(node) {
|
|
1112
|
-
let type2 = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
1113
|
-
if (type2 === null) {
|
|
1114
|
-
return null;
|
|
1115
|
-
}
|
|
1116
|
-
const isSubset = this.isSubset(node.typeID);
|
|
1117
|
-
if (isSubset) {
|
|
1118
|
-
type2 = bool(type2);
|
|
1119
|
-
}
|
|
1120
|
-
const type1 = this.childTypification(node, 0);
|
|
1121
|
-
if (type1 === null) {
|
|
1122
|
-
return null;
|
|
1123
|
-
}
|
|
1124
|
-
if (!checkCompatibility(type1, type2)) {
|
|
1125
|
-
if (isSubset) {
|
|
1126
|
-
return this.onError(RSErrorCode.typesNotEqual, node, [labelType(type1), labelType(type2)]);
|
|
1127
|
-
} else {
|
|
1128
|
-
return this.onError(RSErrorCode.invalidElementPredicate, node, [
|
|
1129
|
-
labelType(type1),
|
|
1130
|
-
labelToken(node.typeID),
|
|
1131
|
-
labelType(bool(type2))
|
|
1132
|
-
]);
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
return LogicT;
|
|
1136
|
-
}
|
|
1137
|
-
visitDecart(node) {
|
|
1138
|
-
const factors = [];
|
|
1139
|
-
for (let child = 0; child < node.children.length; child++) {
|
|
1140
|
-
const type = this.childTypeDebool(node, child, RSErrorCode.invalidDecart);
|
|
1141
|
-
if (type === null) {
|
|
1142
|
-
return null;
|
|
1143
|
-
} else {
|
|
1144
|
-
factors.push(type);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
return bool(tuple(factors));
|
|
1148
|
-
}
|
|
1149
|
-
visitBoolean(node) {
|
|
1150
|
-
const type = this.childTypeDebool(node, 0, RSErrorCode.invalidBoolean);
|
|
1151
|
-
if (type === null) {
|
|
1152
|
-
return null;
|
|
1153
|
-
}
|
|
1154
|
-
return bool(bool(type));
|
|
1155
|
-
}
|
|
1156
|
-
visitTuple(node) {
|
|
1157
|
-
const components = [];
|
|
1158
|
-
for (let child = 0; child < node.children.length; child++) {
|
|
1159
|
-
const type = this.childTypification(node, child);
|
|
1160
|
-
if (type === null) {
|
|
1161
|
-
return null;
|
|
1162
|
-
}
|
|
1163
|
-
components.push(type);
|
|
1164
|
-
}
|
|
1165
|
-
return tuple(components);
|
|
1166
|
-
}
|
|
1167
|
-
visitEnumeration(node) {
|
|
1168
|
-
let type = this.childTypification(node, 0);
|
|
1169
|
-
if (type === null) {
|
|
1170
|
-
return null;
|
|
1171
|
-
}
|
|
1172
|
-
for (let child = 1; child < node.children.length; child++) {
|
|
1173
|
-
const childType = this.childTypification(node, child);
|
|
1174
|
-
if (childType === null) {
|
|
1175
|
-
return null;
|
|
1176
|
-
}
|
|
1177
|
-
const merge = mergeTypifications(type, childType);
|
|
1178
|
-
if (merge === null) {
|
|
1179
|
-
return this.onError(RSErrorCode.invalidEnumeration, node.children[child], [
|
|
1180
|
-
labelType(type),
|
|
1181
|
-
labelType(childType)
|
|
1182
|
-
]);
|
|
1183
|
-
}
|
|
1184
|
-
type = merge;
|
|
1185
|
-
}
|
|
1186
|
-
return bool(type);
|
|
1187
|
-
}
|
|
1188
|
-
visitBool(node) {
|
|
1189
|
-
return this.visitEnumeration(node);
|
|
1190
|
-
}
|
|
1191
|
-
visitDebool(node) {
|
|
1192
|
-
return this.childTypeDebool(node, 0, RSErrorCode.invalidDebool);
|
|
1193
|
-
}
|
|
1194
|
-
visitSetexprBinary(node) {
|
|
1195
|
-
const type1 = this.childTypeDebool(node, 0, RSErrorCode.invalidTypeOperation);
|
|
1196
|
-
if (type1 === null) {
|
|
1197
|
-
return null;
|
|
1198
|
-
}
|
|
1199
|
-
const type2 = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
1200
|
-
if (type2 === null) {
|
|
1201
|
-
return null;
|
|
1202
|
-
}
|
|
1203
|
-
const result = mergeTypifications(type1, type2);
|
|
1204
|
-
if (result === null) {
|
|
1205
|
-
return this.onError(RSErrorCode.typesNotEqual, node, [labelType(bool(type1)), labelType(bool(type2))]);
|
|
1206
|
-
}
|
|
1207
|
-
return bool(result);
|
|
1208
|
-
}
|
|
1209
|
-
visitProjectSet(node) {
|
|
1210
|
-
const argument = this.childTypeDebool(node, 0, RSErrorCode.invalidProjectionSet);
|
|
1211
|
-
if (argument === null) {
|
|
1212
|
-
return null;
|
|
1213
|
-
}
|
|
1214
|
-
if (argument.typeID === TypeID.anyTypification) {
|
|
1215
|
-
return EmptySetT;
|
|
1216
|
-
}
|
|
1217
|
-
if (argument.typeID !== TypeID.tuple) {
|
|
1218
|
-
return this.onError(RSErrorCode.invalidProjectionSet, node.children[0], [
|
|
1219
|
-
labelRSLangNode(node),
|
|
1220
|
-
labelType(bool(argument))
|
|
1221
|
-
]);
|
|
1222
|
-
}
|
|
1223
|
-
const indices = getNodeIndices(node);
|
|
1224
|
-
const components = [];
|
|
1225
|
-
for (const index of indices) {
|
|
1226
|
-
const newComponent = component(argument, index);
|
|
1227
|
-
if (newComponent === null) {
|
|
1228
|
-
return this.onError(RSErrorCode.invalidProjectionSet, node.children[0], [
|
|
1229
|
-
labelRSLangNode(node),
|
|
1230
|
-
labelType(bool(argument))
|
|
1231
|
-
]);
|
|
1232
|
-
} else {
|
|
1233
|
-
components.push(newComponent);
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
if (components.length === 1) {
|
|
1237
|
-
return bool(components[0]);
|
|
1238
|
-
} else {
|
|
1239
|
-
return bool(tuple(components));
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
visitProjectTuple(node) {
|
|
1243
|
-
const argument = this.childTypification(node, 0);
|
|
1244
|
-
if (argument === null) {
|
|
1245
|
-
return null;
|
|
1246
|
-
}
|
|
1247
|
-
if (argument.typeID === TypeID.anyTypification) {
|
|
1248
|
-
return argument;
|
|
1249
|
-
}
|
|
1250
|
-
if (argument.typeID !== TypeID.tuple) {
|
|
1251
|
-
return this.onError(RSErrorCode.invalidProjectionTuple, node.children[0], [
|
|
1252
|
-
labelRSLangNode(node),
|
|
1253
|
-
labelType(argument)
|
|
1254
|
-
]);
|
|
1255
|
-
}
|
|
1256
|
-
const indices = getNodeIndices(node);
|
|
1257
|
-
const components = [];
|
|
1258
|
-
for (const index of indices) {
|
|
1259
|
-
const newComponent = component(argument, index);
|
|
1260
|
-
if (newComponent === null) {
|
|
1261
|
-
return this.onError(RSErrorCode.invalidProjectionTuple, node.children[0], [
|
|
1262
|
-
labelRSLangNode(node),
|
|
1263
|
-
labelType(argument)
|
|
1264
|
-
]);
|
|
1265
|
-
} else {
|
|
1266
|
-
components.push(newComponent);
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
if (components.length === 1) {
|
|
1270
|
-
return components[0];
|
|
1271
|
-
} else {
|
|
1272
|
-
return tuple(components);
|
|
1273
|
-
}
|
|
1274
|
-
}
|
|
1275
|
-
visitFilter(node) {
|
|
1276
|
-
const indices = getNodeIndices(node);
|
|
1277
|
-
const tupleParam = indices.length === node.children.length - 1;
|
|
1278
|
-
if (!tupleParam && node.children.length > 2) {
|
|
1279
|
-
return this.onError(RSErrorCode.invalidFilterArity, node);
|
|
1280
|
-
}
|
|
1281
|
-
const argument = this.childTypification(node, node.children.length - 1);
|
|
1282
|
-
if (argument === null) {
|
|
1283
|
-
return null;
|
|
1284
|
-
}
|
|
1285
|
-
if (argument.typeID === TypeID.anyTypification || argument.typeID === TypeID.collection && argument.base.typeID === TypeID.anyTypification) {
|
|
1286
|
-
return EmptySetT;
|
|
1287
|
-
}
|
|
1288
|
-
if (argument.typeID !== TypeID.collection || argument.base.typeID !== TypeID.tuple) {
|
|
1289
|
-
return this.onError(RSErrorCode.invalidFilterArgumentType, node.children[node.children.length - 1], [
|
|
1290
|
-
labelRSLangNode(node),
|
|
1291
|
-
labelType(argument)
|
|
1292
|
-
]);
|
|
1293
|
-
}
|
|
1294
|
-
const argBase = debool(argument);
|
|
1295
|
-
const bases = [];
|
|
1296
|
-
for (const index of indices) {
|
|
1297
|
-
const newBase = component(argBase, index);
|
|
1298
|
-
if (newBase === null) {
|
|
1299
|
-
return this.onError(RSErrorCode.invalidFilterArgumentType, node.children[node.children.length - 1], [
|
|
1300
|
-
labelRSLangNode(node),
|
|
1301
|
-
labelType(argument)
|
|
1302
|
-
]);
|
|
1303
|
-
}
|
|
1304
|
-
bases.push(newBase);
|
|
1305
|
-
}
|
|
1306
|
-
if (tupleParam) {
|
|
1307
|
-
for (let child = 0; child + 1 < node.children.length; child++) {
|
|
1308
|
-
const param = this.childTypification(node, child);
|
|
1309
|
-
if (param === null) {
|
|
1310
|
-
return null;
|
|
1311
|
-
}
|
|
1312
|
-
if (param.typeID !== TypeID.collection || !checkCompatibility(bases[child], debool(param))) {
|
|
1313
|
-
return this.onError(RSErrorCode.typesNotEqual, node.children[child], [
|
|
1314
|
-
labelType(param),
|
|
1315
|
-
labelType(bool(bases[child]))
|
|
1316
|
-
]);
|
|
1317
|
-
}
|
|
1318
|
-
}
|
|
1319
|
-
} else {
|
|
1320
|
-
const param = this.childTypification(node, 0);
|
|
1321
|
-
if (param === null) {
|
|
1322
|
-
return null;
|
|
1323
|
-
}
|
|
1324
|
-
const paramType = param;
|
|
1325
|
-
const expected = bool(tuple(bases));
|
|
1326
|
-
if (paramType.typeID !== TypeID.collection || !checkCompatibility(expected, paramType)) {
|
|
1327
|
-
return this.onError(RSErrorCode.typesNotEqual, node.children[0], [labelType(paramType), labelType(expected)]);
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
return argument;
|
|
1331
|
-
}
|
|
1332
|
-
visitReduce(node) {
|
|
1333
|
-
const argument = this.childTypification(node, 0);
|
|
1334
|
-
if (argument === null) {
|
|
1335
|
-
return null;
|
|
1336
|
-
}
|
|
1337
|
-
if (argument.typeID === TypeID.anyTypification || argument.typeID === TypeID.collection && argument.base.typeID === TypeID.anyTypification) {
|
|
1338
|
-
return EmptySetT;
|
|
1339
|
-
}
|
|
1340
|
-
if (argument.typeID !== TypeID.collection || argument.base.typeID !== TypeID.collection) {
|
|
1341
|
-
return this.onError(RSErrorCode.invalidReduce, node.children[0], [labelType(argument)]);
|
|
1342
|
-
}
|
|
1343
|
-
return debool(argument);
|
|
1344
|
-
}
|
|
1345
|
-
visitArgumentsEnum(node) {
|
|
1346
|
-
return this.visitAllAndReturn(node, LogicT);
|
|
1347
|
-
}
|
|
1348
|
-
visitDeclarative(node) {
|
|
1349
|
-
this.locals.startScope();
|
|
1350
|
-
const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
1351
|
-
if (domain === null) {
|
|
1352
|
-
return null;
|
|
1353
|
-
} else if (!this.visitChildDeclaration(node, 0, domain)) {
|
|
1354
|
-
return null;
|
|
1355
|
-
} else if (!this.childLogic(node, 2)) {
|
|
1356
|
-
return null;
|
|
1357
|
-
}
|
|
1358
|
-
this.locals.endScope(node.children[2]);
|
|
1359
|
-
return bool(domain);
|
|
1360
|
-
}
|
|
1361
|
-
visitImperative(node) {
|
|
1362
|
-
this.locals.startScope();
|
|
1363
|
-
for (let child = 1; child < node.children.length; child++) {
|
|
1364
|
-
if (!this.childLogic(node, child)) {
|
|
1365
|
-
return null;
|
|
1366
|
-
}
|
|
1367
|
-
}
|
|
1368
|
-
const type = this.childTypification(node, 0);
|
|
1369
|
-
if (type === null) {
|
|
1370
|
-
return null;
|
|
1371
|
-
}
|
|
1372
|
-
this.locals.endScope(node);
|
|
1373
|
-
return bool(type);
|
|
1374
|
-
}
|
|
1375
|
-
visitIterate(node) {
|
|
1376
|
-
const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
1377
|
-
if (domain === null) {
|
|
1378
|
-
return null;
|
|
1379
|
-
}
|
|
1380
|
-
if (!this.visitChildDeclaration(node, 0, domain)) {
|
|
1381
|
-
return null;
|
|
1382
|
-
}
|
|
1383
|
-
return LogicT;
|
|
1384
|
-
}
|
|
1385
|
-
visitAssign(node) {
|
|
1386
|
-
const domain = this.childTypification(node, 1);
|
|
1387
|
-
if (domain === null) {
|
|
1388
|
-
return null;
|
|
1389
|
-
}
|
|
1390
|
-
if (!this.visitChildDeclaration(node, 0, domain)) {
|
|
1391
|
-
return null;
|
|
1392
|
-
}
|
|
1393
|
-
return LogicT;
|
|
1394
|
-
}
|
|
1395
|
-
visitRecursion(node) {
|
|
1396
|
-
this.locals.startScope();
|
|
1397
|
-
const initType = this.childTypification(node, 1);
|
|
1398
|
-
if (initType === null) {
|
|
1399
|
-
return null;
|
|
1400
|
-
}
|
|
1401
|
-
if (!this.visitChildDeclaration(node, 0, initType)) {
|
|
1402
|
-
return null;
|
|
1403
|
-
}
|
|
1404
|
-
const isFull = node.typeID === TokenID.NT_RECURSIVE_FULL;
|
|
1405
|
-
const iterationIndex = isFull ? 3 : 2;
|
|
1406
|
-
let iterationValue = this.childTypification(node, iterationIndex);
|
|
1407
|
-
if (iterationValue === null) {
|
|
1408
|
-
return null;
|
|
1409
|
-
}
|
|
1410
|
-
if (!checkCompatibility(iterationValue, initType)) {
|
|
1411
|
-
return this.onError(RSErrorCode.typesNotEqual, node.children[iterationIndex], [
|
|
1412
|
-
labelType(iterationValue),
|
|
1413
|
-
labelType(initType)
|
|
1414
|
-
]);
|
|
1415
|
-
}
|
|
1416
|
-
if (hasGenerics(initType)) {
|
|
1417
|
-
for (let retries = _TypeAuditor.TYPE_DEDUCTION_DEPTH; retries > 0; retries--) {
|
|
1418
|
-
this.locals.endScope(node);
|
|
1419
|
-
this.locals.clearUnused();
|
|
1420
|
-
this.locals.startScope();
|
|
1421
|
-
if (!this.visitChildDeclaration(node, 0, iterationValue)) {
|
|
1422
|
-
return null;
|
|
1423
|
-
}
|
|
1424
|
-
const newIteration = this.childTypification(node, iterationIndex);
|
|
1425
|
-
if (newIteration === null) {
|
|
1426
|
-
return null;
|
|
1427
|
-
}
|
|
1428
|
-
if (checkEquality(newIteration, iterationValue)) {
|
|
1429
|
-
break;
|
|
1430
|
-
}
|
|
1431
|
-
iterationValue = newIteration;
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
if (isFull) {
|
|
1435
|
-
if (!this.childLogic(node, 2)) {
|
|
1436
|
-
return null;
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
this.locals.endScope(node);
|
|
1440
|
-
return iterationValue;
|
|
1441
|
-
}
|
|
1442
|
-
isSubset(token) {
|
|
1443
|
-
return token === TokenID.SUBSET || token === TokenID.SUBSET_OR_EQ || token === TokenID.NOT_SUBSET;
|
|
1444
|
-
}
|
|
1445
|
-
isInsideFuncArgument(node) {
|
|
1446
|
-
while (node.parent && node.parent !== node) {
|
|
1447
|
-
if (node.typeID === TokenID.NT_ARGUMENTS) return true;
|
|
1448
|
-
node = node.parent;
|
|
1449
|
-
}
|
|
1450
|
-
return false;
|
|
1451
|
-
}
|
|
1452
|
-
checkFuncArguments(node, alias, type) {
|
|
1453
|
-
if (node.children.length - 1 !== type.args.length) {
|
|
1454
|
-
return this.onError(RSErrorCode.invalidArgsArity, node.children[1], [
|
|
1455
|
-
String(type.args.length),
|
|
1456
|
-
String(node.children.length - 1)
|
|
1457
|
-
]);
|
|
1458
|
-
}
|
|
1459
|
-
const substitutes = /* @__PURE__ */ new Map();
|
|
1460
|
-
for (let child = 1; child < node.children.length; child++) {
|
|
1461
|
-
const childType = this.childTypification(node, child);
|
|
1462
|
-
if (childType === null) {
|
|
1463
|
-
return null;
|
|
1464
|
-
}
|
|
1465
|
-
const argType = mangleRadicals(alias, type.args[child - 1].type);
|
|
1466
|
-
if (!compareTemplated(substitutes, argType, childType)) {
|
|
1467
|
-
this.onError(RSErrorCode.invalidArgumentType, node.children[child], [
|
|
1468
|
-
`${type.args[child - 1].alias}\u2208${labelType(argType)}`,
|
|
1469
|
-
labelType(childType)
|
|
1470
|
-
]);
|
|
1471
|
-
return null;
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
return substitutes;
|
|
1475
|
-
}
|
|
1
|
+
import { annotateError, annotateType } from "../ast-annotations.js";
|
|
2
|
+
import { RSErrorCode } from "../error.js";
|
|
3
|
+
import { getNodeIndices, getNodeText } from "../../parsing/ast.js";
|
|
4
|
+
import "../../parsing/index.js";
|
|
5
|
+
import { TokenID } from "../parser/token.js";
|
|
6
|
+
import { EmptySetT, IntegerT, LogicT, TypeID, bool, component, debool, isRadical, isTypification, tuple } from "./typification.js";
|
|
7
|
+
import { labelRSLangNode, labelToken, labelType } from "../labels.js";
|
|
8
|
+
import { checkCompatibility, checkEquality, compareTemplated, hasGenerics, mergeTypifications, substituteBase } from "./typification-api.js";
|
|
9
|
+
//#region src/rslang/semantic/type-auditor.ts
|
|
10
|
+
/**
|
|
11
|
+
* Module: Type auditor for AST type checking.
|
|
12
|
+
*/
|
|
13
|
+
/** Type auditor for AST type checking. */
|
|
14
|
+
var TypeAuditor = class TypeAuditor {
|
|
15
|
+
static TYPE_DEDUCTION_DEPTH = 5;
|
|
16
|
+
context;
|
|
17
|
+
reporter;
|
|
18
|
+
locals;
|
|
19
|
+
annotateTypes;
|
|
20
|
+
annotateErrors;
|
|
21
|
+
constructor(context) {
|
|
22
|
+
this.annotateTypes = false;
|
|
23
|
+
this.annotateErrors = false;
|
|
24
|
+
this.context = context;
|
|
25
|
+
this.locals = new LocalContext(this.onError.bind(this));
|
|
26
|
+
}
|
|
27
|
+
run(ast, annotateTypes, reporter, annotateErrors = false) {
|
|
28
|
+
if (ast.hasError) return null;
|
|
29
|
+
this.annotateTypes = annotateTypes;
|
|
30
|
+
this.annotateErrors = annotateErrors;
|
|
31
|
+
this.reporter = reporter;
|
|
32
|
+
this.clear();
|
|
33
|
+
return this.dispatchVisit(ast);
|
|
34
|
+
}
|
|
35
|
+
clear() {
|
|
36
|
+
this.locals = new LocalContext(this.onError.bind(this));
|
|
37
|
+
}
|
|
38
|
+
dispatchDeclare(node, domain) {
|
|
39
|
+
const result = this.processDeclare(node, domain);
|
|
40
|
+
if (result === true && this.annotateTypes) annotateType(node, domain);
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
processDeclare(node, domain) {
|
|
44
|
+
switch (node.typeID) {
|
|
45
|
+
case TokenID.ID_LOCAL: return this.declareLocal(node, domain);
|
|
46
|
+
case TokenID.NT_TUPLE_DECL: return this.declareTuple(node, domain);
|
|
47
|
+
case TokenID.NT_ENUM_DECL: return this.declareEnumeration(node, domain);
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
declareLocal(node, domain) {
|
|
52
|
+
return this.locals.pushLocal(node, domain);
|
|
53
|
+
}
|
|
54
|
+
declareTuple(node, domain) {
|
|
55
|
+
if (domain.typeID !== TypeID.tuple || domain.factors.length !== node.children.length) {
|
|
56
|
+
this.onError(RSErrorCode.invalidCortegeDeclare, node.children[0]);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
for (let child = 0; child < node.children.length; child++) if (!this.visitChildDeclaration(node, child, component(domain, child + 1))) return false;
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
declareEnumeration(node, domain) {
|
|
63
|
+
for (const child of node.children) if (!this.dispatchDeclare(child, domain)) return false;
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
dispatchVisit(node) {
|
|
67
|
+
const result = this.processVisit(node);
|
|
68
|
+
if (result !== null && this.annotateTypes) annotateType(node, result);
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
processVisit(node) {
|
|
72
|
+
switch (node.typeID) {
|
|
73
|
+
case TokenID.ID_GLOBAL:
|
|
74
|
+
case TokenID.ID_FUNCTION:
|
|
75
|
+
case TokenID.ID_PREDICATE: return this.visitGlobal(node);
|
|
76
|
+
case TokenID.ID_LOCAL: return this.visitLocal(node);
|
|
77
|
+
case TokenID.ID_RADICAL: return this.visitRadical(node);
|
|
78
|
+
case TokenID.LIT_INTEGER: return IntegerT;
|
|
79
|
+
case TokenID.LIT_WHOLE_NUMBERS: return bool(IntegerT);
|
|
80
|
+
case TokenID.LIT_EMPTYSET: return this.visitEmptySet(node);
|
|
81
|
+
case TokenID.NT_ARGUMENTS: return this.visitArgumentsEnum(node);
|
|
82
|
+
case TokenID.NT_ARG_DECL: return this.visitArgument(node);
|
|
83
|
+
case TokenID.PLUS:
|
|
84
|
+
case TokenID.MINUS:
|
|
85
|
+
case TokenID.MULTIPLY: return this.visitArithmetic(node);
|
|
86
|
+
case TokenID.QUANTOR_UNIVERSAL:
|
|
87
|
+
case TokenID.QUANTOR_EXISTS: return this.visitQuantifier(node);
|
|
88
|
+
case TokenID.LOGIC_NOT: return this.visitNegation(node);
|
|
89
|
+
case TokenID.LOGIC_AND:
|
|
90
|
+
case TokenID.LOGIC_OR:
|
|
91
|
+
case TokenID.LOGIC_IMPLICATION:
|
|
92
|
+
case TokenID.LOGIC_EQUIVALENT: return this.visitLogicBinary(node);
|
|
93
|
+
case TokenID.EQUAL:
|
|
94
|
+
case TokenID.NOTEQUAL: return this.visitEquals(node);
|
|
95
|
+
case TokenID.GREATER:
|
|
96
|
+
case TokenID.LESSER:
|
|
97
|
+
case TokenID.GREATER_OR_EQ:
|
|
98
|
+
case TokenID.LESSER_OR_EQ: return this.visitIntegerPredicate(node);
|
|
99
|
+
case TokenID.SET_IN:
|
|
100
|
+
case TokenID.SET_NOT_IN:
|
|
101
|
+
case TokenID.SUBSET:
|
|
102
|
+
case TokenID.SUBSET_OR_EQ:
|
|
103
|
+
case TokenID.NOT_SUBSET: return this.visitSetexprPredicate(node);
|
|
104
|
+
case TokenID.DECART: return this.visitDecart(node);
|
|
105
|
+
case TokenID.BOOLEAN: return this.visitBoolean(node);
|
|
106
|
+
case TokenID.NT_TUPLE: return this.visitTuple(node);
|
|
107
|
+
case TokenID.NT_ENUMERATION: return this.visitEnumeration(node);
|
|
108
|
+
case TokenID.BIGPR: return this.visitProjectSet(node);
|
|
109
|
+
case TokenID.SMALLPR: return this.visitProjectTuple(node);
|
|
110
|
+
case TokenID.FILTER: return this.visitFilter(node);
|
|
111
|
+
case TokenID.CARD: return this.visitCard(node);
|
|
112
|
+
case TokenID.REDUCE: return this.visitReduce(node);
|
|
113
|
+
case TokenID.BOOL: return this.visitBool(node);
|
|
114
|
+
case TokenID.DEBOOL: return this.visitDebool(node);
|
|
115
|
+
case TokenID.SET_UNION:
|
|
116
|
+
case TokenID.SET_INTERSECTION:
|
|
117
|
+
case TokenID.SET_MINUS:
|
|
118
|
+
case TokenID.SET_SYMMETRIC_MINUS: return this.visitSetexprBinary(node);
|
|
119
|
+
case TokenID.NT_FUNC_DEFINITION: return this.visitFunctionDefinition(node);
|
|
120
|
+
case TokenID.NT_FUNC_CALL: return this.visitFunctionCall(node);
|
|
121
|
+
case TokenID.ITERATE: return this.visitIterate(node);
|
|
122
|
+
case TokenID.ASSIGN: return this.visitAssign(node);
|
|
123
|
+
case TokenID.NT_DECLARATIVE_EXPR: return this.visitDeclarative(node);
|
|
124
|
+
case TokenID.NT_IMPERATIVE_EXPR: return this.visitImperative(node);
|
|
125
|
+
case TokenID.NT_RECURSIVE_FULL:
|
|
126
|
+
case TokenID.NT_RECURSIVE_SHORT: return this.visitRecursion(node);
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
onError(code, node, params) {
|
|
131
|
+
this.reporter?.({
|
|
132
|
+
code,
|
|
133
|
+
from: node.from,
|
|
134
|
+
to: node.to,
|
|
135
|
+
params
|
|
136
|
+
});
|
|
137
|
+
if (this.annotateErrors) annotateError(node, code, params);
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
visitChild(node, index) {
|
|
141
|
+
if (index >= node.children.length) return null;
|
|
142
|
+
return this.dispatchVisit(node.children[index]);
|
|
143
|
+
}
|
|
144
|
+
visitChildDeclaration(node, index, domain) {
|
|
145
|
+
if (index >= node.children.length) return false;
|
|
146
|
+
if (!this.dispatchDeclare(node.children[index], domain)) return false;
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
visitAllAndReturn(node, type) {
|
|
150
|
+
for (const child of node.children) if (!this.dispatchVisit(child)) return null;
|
|
151
|
+
return type;
|
|
152
|
+
}
|
|
153
|
+
childTypification(node, index) {
|
|
154
|
+
const result = this.visitChild(node, index);
|
|
155
|
+
if (result === null) return null;
|
|
156
|
+
if (!isTypification(result)) {
|
|
157
|
+
this.onError(RSErrorCode.expectedSetexpr, node.children[index], [labelType(result)]);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
childLogic(node, index) {
|
|
163
|
+
const result = this.visitChild(node, index);
|
|
164
|
+
if (result === null) return false;
|
|
165
|
+
if (result.typeID !== TypeID.logic) {
|
|
166
|
+
this.onError(RSErrorCode.expectedLogic, node.children[index], [labelType(result)]);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
childTypeDebool(node, index, errorCode) {
|
|
172
|
+
const result = this.childTypification(node, index);
|
|
173
|
+
if (result === null) return null;
|
|
174
|
+
if (result.typeID === TypeID.anyTypification) return result;
|
|
175
|
+
if (result.typeID !== TypeID.collection) {
|
|
176
|
+
this.onError(errorCode, node.children[index], [labelType(result)]);
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
return debool(result);
|
|
180
|
+
}
|
|
181
|
+
visitLocal(node) {
|
|
182
|
+
return this.locals.getLocalType(node);
|
|
183
|
+
}
|
|
184
|
+
visitGlobal(node) {
|
|
185
|
+
const alias = getNodeText(node);
|
|
186
|
+
const type = this.context.get(alias);
|
|
187
|
+
if (!type) return this.onError(RSErrorCode.globalNotTyped, node, [alias]);
|
|
188
|
+
return type;
|
|
189
|
+
}
|
|
190
|
+
visitFunctionDefinition(node) {
|
|
191
|
+
this.locals.startScope();
|
|
192
|
+
if (!this.visitChild(node, 0)) return null;
|
|
193
|
+
const args = [];
|
|
194
|
+
for (const local of this.locals.data) if (local.level === 1) args.push({
|
|
195
|
+
alias: local.alias,
|
|
196
|
+
type: local.type
|
|
197
|
+
});
|
|
198
|
+
const result = this.visitChild(node, 1);
|
|
199
|
+
if (result === null || result.typeID === TypeID.function || result.typeID === TypeID.predicate) return null;
|
|
200
|
+
this.locals.endScope(node.children[1]);
|
|
201
|
+
if (result.typeID === TypeID.logic) return {
|
|
202
|
+
typeID: TypeID.predicate,
|
|
203
|
+
result,
|
|
204
|
+
args
|
|
205
|
+
};
|
|
206
|
+
else return {
|
|
207
|
+
typeID: TypeID.function,
|
|
208
|
+
result,
|
|
209
|
+
args
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
visitFunctionCall(node) {
|
|
213
|
+
const funcName = getNodeText(node.children[0]);
|
|
214
|
+
const funcType = this.context.get(funcName);
|
|
215
|
+
if (funcType?.typeID !== TypeID.function && funcType?.typeID !== TypeID.predicate) return this.onError(RSErrorCode.globalNotTyped, node.children[0], [funcName]);
|
|
216
|
+
if (this.annotateTypes) annotateType(node.children[0], funcType);
|
|
217
|
+
const substitutes = this.checkFuncArguments(node, funcName, funcType);
|
|
218
|
+
if (substitutes === null) return null;
|
|
219
|
+
if (funcType.result.typeID === TypeID.logic) return funcType.result;
|
|
220
|
+
else {
|
|
221
|
+
const result = mangleRadicals(funcName, funcType.result);
|
|
222
|
+
if (substitutes.size > 0) substituteBase(result, substitutes);
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
visitRadical(node) {
|
|
227
|
+
const alias = getNodeText(node);
|
|
228
|
+
if (!this.isInsideFuncArgument(node)) return this.onError(RSErrorCode.radicalUsage, node, [alias]);
|
|
229
|
+
return bool({
|
|
230
|
+
typeID: TypeID.basic,
|
|
231
|
+
baseID: alias
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
visitEmptySet(node) {
|
|
235
|
+
if ([
|
|
236
|
+
TokenID.CARD,
|
|
237
|
+
TokenID.DEBOOL,
|
|
238
|
+
TokenID.SET_UNION,
|
|
239
|
+
TokenID.SET_INTERSECTION,
|
|
240
|
+
TokenID.SET_MINUS,
|
|
241
|
+
TokenID.SET_SYMMETRIC_MINUS,
|
|
242
|
+
TokenID.REDUCE,
|
|
243
|
+
TokenID.BIGPR,
|
|
244
|
+
TokenID.SMALLPR
|
|
245
|
+
].includes(node.parent?.typeID)) return this.onError(RSErrorCode.invalidEmptySetUsage, node);
|
|
246
|
+
return EmptySetT;
|
|
247
|
+
}
|
|
248
|
+
visitArgument(node) {
|
|
249
|
+
const variable = node.children[0];
|
|
250
|
+
if (variable.typeID === TokenID.NT_TUPLE_DECL) return this.onError(RSErrorCode.invalidArgumentCortegeDeclare, variable);
|
|
251
|
+
const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
252
|
+
if (domain === null) return null;
|
|
253
|
+
if (!this.visitChildDeclaration(node, 0, domain)) return null;
|
|
254
|
+
return domain;
|
|
255
|
+
}
|
|
256
|
+
visitCard(node) {
|
|
257
|
+
if (!this.childTypeDebool(node, 0, RSErrorCode.invalidCard)) return null;
|
|
258
|
+
return IntegerT;
|
|
259
|
+
}
|
|
260
|
+
visitArithmetic(node) {
|
|
261
|
+
const type1 = this.childTypification(node, 0);
|
|
262
|
+
if (type1 === null) return null;
|
|
263
|
+
if (!("isArithmetic" in type1 && type1.isArithmetic)) return this.onError(RSErrorCode.arithmeticNotSupported, node.children[0], [labelType(type1)]);
|
|
264
|
+
const type2 = this.childTypification(node, 1);
|
|
265
|
+
if (type2 === null) return null;
|
|
266
|
+
if (!("isArithmetic" in type2 && type2.isArithmetic)) return this.onError(RSErrorCode.arithmeticNotSupported, node.children[1], [labelType(type2)]);
|
|
267
|
+
const result = mergeTypifications(type1, type2);
|
|
268
|
+
if (result === null) return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
visitIntegerPredicate(node) {
|
|
272
|
+
const type1 = this.childTypification(node, 0);
|
|
273
|
+
if (type1 === null) return null;
|
|
274
|
+
if (!("isOrdered" in type1 && type1.isOrdered)) return this.onError(RSErrorCode.orderingNotSupported, node.children[0], [labelType(type1)]);
|
|
275
|
+
const type2 = this.childTypification(node, 1);
|
|
276
|
+
if (type2 === null) return null;
|
|
277
|
+
if (!("isOrdered" in type2 && type2.isOrdered)) return this.onError(RSErrorCode.orderingNotSupported, node.children[1], [labelType(type2)]);
|
|
278
|
+
if (!checkCompatibility(type1, type2)) return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
|
|
279
|
+
return LogicT;
|
|
280
|
+
}
|
|
281
|
+
visitQuantifier(node) {
|
|
282
|
+
this.locals.startScope();
|
|
283
|
+
const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
284
|
+
if (domain === null) return null;
|
|
285
|
+
else if (!this.visitChildDeclaration(node, 0, domain)) return null;
|
|
286
|
+
else if (!this.childLogic(node, 2)) return null;
|
|
287
|
+
this.locals.endScope(node.children[2]);
|
|
288
|
+
return LogicT;
|
|
289
|
+
}
|
|
290
|
+
visitNegation(node) {
|
|
291
|
+
if (!this.childLogic(node, 0)) return null;
|
|
292
|
+
return LogicT;
|
|
293
|
+
}
|
|
294
|
+
visitLogicBinary(node) {
|
|
295
|
+
if (!this.childLogic(node, 0) || !this.childLogic(node, 1)) return null;
|
|
296
|
+
return LogicT;
|
|
297
|
+
}
|
|
298
|
+
visitEquals(node) {
|
|
299
|
+
const type1 = this.childTypification(node, 0);
|
|
300
|
+
if (type1 === null) return null;
|
|
301
|
+
const type2 = this.childTypification(node, 1);
|
|
302
|
+
if (type2 === null) return null;
|
|
303
|
+
if (!checkCompatibility(type1, type2)) return this.onError(RSErrorCode.typesNotCompatible, node, [labelType(type1), labelType(type2)]);
|
|
304
|
+
return LogicT;
|
|
305
|
+
}
|
|
306
|
+
visitSetexprPredicate(node) {
|
|
307
|
+
let type2 = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
308
|
+
if (type2 === null) return null;
|
|
309
|
+
const isSubset = this.isSubset(node.typeID);
|
|
310
|
+
if (isSubset) type2 = bool(type2);
|
|
311
|
+
const type1 = this.childTypification(node, 0);
|
|
312
|
+
if (type1 === null) return null;
|
|
313
|
+
if (!checkCompatibility(type1, type2)) if (isSubset) return this.onError(RSErrorCode.typesNotEqual, node, [labelType(type1), labelType(type2)]);
|
|
314
|
+
else return this.onError(RSErrorCode.invalidElementPredicate, node, [
|
|
315
|
+
labelType(type1),
|
|
316
|
+
labelToken(node.typeID),
|
|
317
|
+
labelType(bool(type2))
|
|
318
|
+
]);
|
|
319
|
+
return LogicT;
|
|
320
|
+
}
|
|
321
|
+
visitDecart(node) {
|
|
322
|
+
const factors = [];
|
|
323
|
+
for (let child = 0; child < node.children.length; child++) {
|
|
324
|
+
const type = this.childTypeDebool(node, child, RSErrorCode.invalidDecart);
|
|
325
|
+
if (type === null) return null;
|
|
326
|
+
else factors.push(type);
|
|
327
|
+
}
|
|
328
|
+
return bool(tuple(factors));
|
|
329
|
+
}
|
|
330
|
+
visitBoolean(node) {
|
|
331
|
+
const type = this.childTypeDebool(node, 0, RSErrorCode.invalidBoolean);
|
|
332
|
+
if (type === null) return null;
|
|
333
|
+
return bool(bool(type));
|
|
334
|
+
}
|
|
335
|
+
visitTuple(node) {
|
|
336
|
+
const components = [];
|
|
337
|
+
for (let child = 0; child < node.children.length; child++) {
|
|
338
|
+
const type = this.childTypification(node, child);
|
|
339
|
+
if (type === null) return null;
|
|
340
|
+
components.push(type);
|
|
341
|
+
}
|
|
342
|
+
return tuple(components);
|
|
343
|
+
}
|
|
344
|
+
visitEnumeration(node) {
|
|
345
|
+
let type = this.childTypification(node, 0);
|
|
346
|
+
if (type === null) return null;
|
|
347
|
+
for (let child = 1; child < node.children.length; child++) {
|
|
348
|
+
const childType = this.childTypification(node, child);
|
|
349
|
+
if (childType === null) return null;
|
|
350
|
+
const merge = mergeTypifications(type, childType);
|
|
351
|
+
if (merge === null) return this.onError(RSErrorCode.invalidEnumeration, node.children[child], [labelType(type), labelType(childType)]);
|
|
352
|
+
type = merge;
|
|
353
|
+
}
|
|
354
|
+
return bool(type);
|
|
355
|
+
}
|
|
356
|
+
visitBool(node) {
|
|
357
|
+
return this.visitEnumeration(node);
|
|
358
|
+
}
|
|
359
|
+
visitDebool(node) {
|
|
360
|
+
return this.childTypeDebool(node, 0, RSErrorCode.invalidDebool);
|
|
361
|
+
}
|
|
362
|
+
visitSetexprBinary(node) {
|
|
363
|
+
const type1 = this.childTypeDebool(node, 0, RSErrorCode.invalidTypeOperation);
|
|
364
|
+
if (type1 === null) return null;
|
|
365
|
+
const type2 = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
366
|
+
if (type2 === null) return null;
|
|
367
|
+
const result = mergeTypifications(type1, type2);
|
|
368
|
+
if (result === null) return this.onError(RSErrorCode.typesNotEqual, node, [labelType(bool(type1)), labelType(bool(type2))]);
|
|
369
|
+
return bool(result);
|
|
370
|
+
}
|
|
371
|
+
visitProjectSet(node) {
|
|
372
|
+
const argument = this.childTypeDebool(node, 0, RSErrorCode.invalidProjectionSet);
|
|
373
|
+
if (argument === null) return null;
|
|
374
|
+
if (argument.typeID === TypeID.anyTypification) return EmptySetT;
|
|
375
|
+
if (argument.typeID !== TypeID.tuple) return this.onError(RSErrorCode.invalidProjectionSet, node.children[0], [labelRSLangNode(node), labelType(bool(argument))]);
|
|
376
|
+
const indices = getNodeIndices(node);
|
|
377
|
+
const components = [];
|
|
378
|
+
for (const index of indices) {
|
|
379
|
+
const newComponent = component(argument, index);
|
|
380
|
+
if (newComponent === null) return this.onError(RSErrorCode.invalidProjectionSet, node.children[0], [labelRSLangNode(node), labelType(bool(argument))]);
|
|
381
|
+
else components.push(newComponent);
|
|
382
|
+
}
|
|
383
|
+
if (components.length === 1) return bool(components[0]);
|
|
384
|
+
else return bool(tuple(components));
|
|
385
|
+
}
|
|
386
|
+
visitProjectTuple(node) {
|
|
387
|
+
const argument = this.childTypification(node, 0);
|
|
388
|
+
if (argument === null) return null;
|
|
389
|
+
if (argument.typeID === TypeID.anyTypification) return argument;
|
|
390
|
+
if (argument.typeID !== TypeID.tuple) return this.onError(RSErrorCode.invalidProjectionTuple, node.children[0], [labelRSLangNode(node), labelType(argument)]);
|
|
391
|
+
const indices = getNodeIndices(node);
|
|
392
|
+
const components = [];
|
|
393
|
+
for (const index of indices) {
|
|
394
|
+
const newComponent = component(argument, index);
|
|
395
|
+
if (newComponent === null) return this.onError(RSErrorCode.invalidProjectionTuple, node.children[0], [labelRSLangNode(node), labelType(argument)]);
|
|
396
|
+
else components.push(newComponent);
|
|
397
|
+
}
|
|
398
|
+
if (components.length === 1) return components[0];
|
|
399
|
+
else return tuple(components);
|
|
400
|
+
}
|
|
401
|
+
visitFilter(node) {
|
|
402
|
+
const indices = getNodeIndices(node);
|
|
403
|
+
const tupleParam = indices.length === node.children.length - 1;
|
|
404
|
+
if (!tupleParam && node.children.length > 2) return this.onError(RSErrorCode.invalidFilterArity, node);
|
|
405
|
+
const argument = this.childTypification(node, node.children.length - 1);
|
|
406
|
+
if (argument === null) return null;
|
|
407
|
+
if (argument.typeID === TypeID.anyTypification || argument.typeID === TypeID.collection && argument.base.typeID === TypeID.anyTypification) return EmptySetT;
|
|
408
|
+
if (argument.typeID !== TypeID.collection || argument.base.typeID !== TypeID.tuple) return this.onError(RSErrorCode.invalidFilterArgumentType, node.children[node.children.length - 1], [labelRSLangNode(node), labelType(argument)]);
|
|
409
|
+
const argBase = debool(argument);
|
|
410
|
+
const bases = [];
|
|
411
|
+
for (const index of indices) {
|
|
412
|
+
const newBase = component(argBase, index);
|
|
413
|
+
if (newBase === null) return this.onError(RSErrorCode.invalidFilterArgumentType, node.children[node.children.length - 1], [labelRSLangNode(node), labelType(argument)]);
|
|
414
|
+
bases.push(newBase);
|
|
415
|
+
}
|
|
416
|
+
if (tupleParam) for (let child = 0; child + 1 < node.children.length; child++) {
|
|
417
|
+
const param = this.childTypification(node, child);
|
|
418
|
+
if (param === null) return null;
|
|
419
|
+
if (param.typeID !== TypeID.collection || !checkCompatibility(bases[child], debool(param))) return this.onError(RSErrorCode.typesNotEqual, node.children[child], [labelType(param), labelType(bool(bases[child]))]);
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
const param = this.childTypification(node, 0);
|
|
423
|
+
if (param === null) return null;
|
|
424
|
+
const paramType = param;
|
|
425
|
+
const expected = bool(tuple(bases));
|
|
426
|
+
if (paramType.typeID !== TypeID.collection || !checkCompatibility(expected, paramType)) return this.onError(RSErrorCode.typesNotEqual, node.children[0], [labelType(paramType), labelType(expected)]);
|
|
427
|
+
}
|
|
428
|
+
return argument;
|
|
429
|
+
}
|
|
430
|
+
visitReduce(node) {
|
|
431
|
+
const argument = this.childTypification(node, 0);
|
|
432
|
+
if (argument === null) return null;
|
|
433
|
+
if (argument.typeID === TypeID.anyTypification || argument.typeID === TypeID.collection && argument.base.typeID === TypeID.anyTypification) return EmptySetT;
|
|
434
|
+
if (argument.typeID !== TypeID.collection || argument.base.typeID !== TypeID.collection) return this.onError(RSErrorCode.invalidReduce, node.children[0], [labelType(argument)]);
|
|
435
|
+
return debool(argument);
|
|
436
|
+
}
|
|
437
|
+
visitArgumentsEnum(node) {
|
|
438
|
+
return this.visitAllAndReturn(node, LogicT);
|
|
439
|
+
}
|
|
440
|
+
visitDeclarative(node) {
|
|
441
|
+
this.locals.startScope();
|
|
442
|
+
const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
443
|
+
if (domain === null) return null;
|
|
444
|
+
else if (!this.visitChildDeclaration(node, 0, domain)) return null;
|
|
445
|
+
else if (!this.childLogic(node, 2)) return null;
|
|
446
|
+
this.locals.endScope(node.children[2]);
|
|
447
|
+
return bool(domain);
|
|
448
|
+
}
|
|
449
|
+
visitImperative(node) {
|
|
450
|
+
this.locals.startScope();
|
|
451
|
+
for (let child = 1; child < node.children.length; child++) if (!this.childLogic(node, child)) return null;
|
|
452
|
+
const type = this.childTypification(node, 0);
|
|
453
|
+
if (type === null) return null;
|
|
454
|
+
this.locals.endScope(node);
|
|
455
|
+
return bool(type);
|
|
456
|
+
}
|
|
457
|
+
visitIterate(node) {
|
|
458
|
+
const domain = this.childTypeDebool(node, 1, RSErrorCode.invalidTypeOperation);
|
|
459
|
+
if (domain === null) return null;
|
|
460
|
+
if (!this.visitChildDeclaration(node, 0, domain)) return null;
|
|
461
|
+
return LogicT;
|
|
462
|
+
}
|
|
463
|
+
visitAssign(node) {
|
|
464
|
+
const domain = this.childTypification(node, 1);
|
|
465
|
+
if (domain === null) return null;
|
|
466
|
+
if (!this.visitChildDeclaration(node, 0, domain)) return null;
|
|
467
|
+
return LogicT;
|
|
468
|
+
}
|
|
469
|
+
visitRecursion(node) {
|
|
470
|
+
this.locals.startScope();
|
|
471
|
+
const initType = this.childTypification(node, 1);
|
|
472
|
+
if (initType === null) return null;
|
|
473
|
+
if (!this.visitChildDeclaration(node, 0, initType)) return null;
|
|
474
|
+
const isFull = node.typeID === TokenID.NT_RECURSIVE_FULL;
|
|
475
|
+
const iterationIndex = isFull ? 3 : 2;
|
|
476
|
+
let iterationValue = this.childTypification(node, iterationIndex);
|
|
477
|
+
if (iterationValue === null) return null;
|
|
478
|
+
if (!checkCompatibility(iterationValue, initType)) return this.onError(RSErrorCode.typesNotEqual, node.children[iterationIndex], [labelType(iterationValue), labelType(initType)]);
|
|
479
|
+
if (hasGenerics(initType)) for (let retries = TypeAuditor.TYPE_DEDUCTION_DEPTH; retries > 0; retries--) {
|
|
480
|
+
this.locals.endScope(node);
|
|
481
|
+
this.locals.clearUnused();
|
|
482
|
+
this.locals.startScope();
|
|
483
|
+
if (!this.visitChildDeclaration(node, 0, iterationValue)) return null;
|
|
484
|
+
const newIteration = this.childTypification(node, iterationIndex);
|
|
485
|
+
if (newIteration === null) return null;
|
|
486
|
+
if (checkEquality(newIteration, iterationValue)) break;
|
|
487
|
+
iterationValue = newIteration;
|
|
488
|
+
}
|
|
489
|
+
if (isFull) {
|
|
490
|
+
if (!this.childLogic(node, 2)) return null;
|
|
491
|
+
}
|
|
492
|
+
this.locals.endScope(node);
|
|
493
|
+
return iterationValue;
|
|
494
|
+
}
|
|
495
|
+
isSubset(token) {
|
|
496
|
+
return token === TokenID.SUBSET || token === TokenID.SUBSET_OR_EQ || token === TokenID.NOT_SUBSET;
|
|
497
|
+
}
|
|
498
|
+
isInsideFuncArgument(node) {
|
|
499
|
+
while (node.parent && node.parent !== node) {
|
|
500
|
+
if (node.typeID === TokenID.NT_ARGUMENTS) return true;
|
|
501
|
+
node = node.parent;
|
|
502
|
+
}
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
checkFuncArguments(node, alias, type) {
|
|
506
|
+
if (node.children.length - 1 !== type.args.length) return this.onError(RSErrorCode.invalidArgsArity, node.children[1], [String(type.args.length), String(node.children.length - 1)]);
|
|
507
|
+
const substitutes = /* @__PURE__ */ new Map();
|
|
508
|
+
for (let child = 1; child < node.children.length; child++) {
|
|
509
|
+
const childType = this.childTypification(node, child);
|
|
510
|
+
if (childType === null) return null;
|
|
511
|
+
const argType = mangleRadicals(alias, type.args[child - 1].type);
|
|
512
|
+
if (!compareTemplated(substitutes, argType, childType)) {
|
|
513
|
+
this.onError(RSErrorCode.invalidArgumentType, node.children[child], [`${type.args[child - 1].alias}∈${labelType(argType)}`, labelType(childType)]);
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return substitutes;
|
|
518
|
+
}
|
|
1476
519
|
};
|
|
1477
520
|
function mangleRadicals(funcName, type) {
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
for (let index = 1; index <= type.factors.length; ++index) {
|
|
1501
|
-
factors.push(mangleRadicals(funcName, component(type, index)));
|
|
1502
|
-
}
|
|
1503
|
-
return {
|
|
1504
|
-
typeID: type.typeID,
|
|
1505
|
-
factors
|
|
1506
|
-
};
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
521
|
+
switch (type.typeID) {
|
|
522
|
+
default: throw new Error(`Unexpected type: ${type.typeID}`);
|
|
523
|
+
case TypeID.integer: return type;
|
|
524
|
+
case TypeID.basic:
|
|
525
|
+
if (isRadical(type.baseID)) return {
|
|
526
|
+
typeID: type.typeID,
|
|
527
|
+
baseID: type.baseID + funcName
|
|
528
|
+
};
|
|
529
|
+
return type;
|
|
530
|
+
case TypeID.collection: return {
|
|
531
|
+
typeID: type.typeID,
|
|
532
|
+
base: mangleRadicals(funcName, debool(type))
|
|
533
|
+
};
|
|
534
|
+
case TypeID.tuple: {
|
|
535
|
+
const factors = [];
|
|
536
|
+
for (let index = 1; index <= type.factors.length; ++index) factors.push(mangleRadicals(funcName, component(type, index)));
|
|
537
|
+
return {
|
|
538
|
+
typeID: type.typeID,
|
|
539
|
+
factors
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
}
|
|
1509
543
|
}
|
|
544
|
+
/** Local variables context. */
|
|
1510
545
|
var LocalContext = class {
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
} else {
|
|
1562
|
-
local.useCount++;
|
|
1563
|
-
return local.type;
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
};
|
|
1567
|
-
export {
|
|
1568
|
-
TypeAuditor
|
|
546
|
+
onError;
|
|
547
|
+
data = [];
|
|
548
|
+
constructor(onError) {
|
|
549
|
+
this.onError = onError;
|
|
550
|
+
}
|
|
551
|
+
startScope() {
|
|
552
|
+
for (const local of this.data) if (local.level > 0) local.level = local.level + 1;
|
|
553
|
+
}
|
|
554
|
+
endScope(node, skipUnused = false) {
|
|
555
|
+
for (const local of this.data) {
|
|
556
|
+
local.level--;
|
|
557
|
+
if (!skipUnused && local.level === 0 && local.useCount === 0) this.onError(RSErrorCode.localNotUsed, node, [local.alias]);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
clearUnused() {
|
|
561
|
+
this.data = this.data.filter((data) => data.level > 0);
|
|
562
|
+
}
|
|
563
|
+
pushLocal(node, type) {
|
|
564
|
+
const alias = getNodeText(node);
|
|
565
|
+
const existing = this.data.find((data) => data.alias === alias);
|
|
566
|
+
if (existing) if (existing.level > 0) {
|
|
567
|
+
this.onError(RSErrorCode.localShadowing, node, [alias]);
|
|
568
|
+
return false;
|
|
569
|
+
} else {
|
|
570
|
+
this.onError(RSErrorCode.localDoubleDeclare, node, [alias]);
|
|
571
|
+
const index = this.data.indexOf(existing);
|
|
572
|
+
if (index !== -1) this.data.splice(index, 1);
|
|
573
|
+
}
|
|
574
|
+
this.data.push({
|
|
575
|
+
alias,
|
|
576
|
+
type,
|
|
577
|
+
level: 1,
|
|
578
|
+
useCount: 0
|
|
579
|
+
});
|
|
580
|
+
return true;
|
|
581
|
+
}
|
|
582
|
+
getLocalType(node) {
|
|
583
|
+
const alias = getNodeText(node);
|
|
584
|
+
const local = this.data.find((data) => data.alias === alias);
|
|
585
|
+
if (local === void 0) {
|
|
586
|
+
this.onError(RSErrorCode.localUndeclared, node, [alias]);
|
|
587
|
+
return null;
|
|
588
|
+
} else if (local.level < 1) {
|
|
589
|
+
this.onError(RSErrorCode.localOutOfScope, node, [alias]);
|
|
590
|
+
return null;
|
|
591
|
+
} else {
|
|
592
|
+
local.useCount++;
|
|
593
|
+
return local.type;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
1569
596
|
};
|
|
597
|
+
//#endregion
|
|
598
|
+
export { TypeAuditor };
|
|
599
|
+
|
|
1570
600
|
//# sourceMappingURL=type-auditor.js.map
|