fez-lisp 1.5.45 → 1.5.47
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/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/check.js +235 -250
- package/src/macros.js +4 -5
package/src/check.js
CHANGED
@@ -22,13 +22,12 @@ import {
|
|
22
22
|
stringifyArgs
|
23
23
|
} from './utils.js'
|
24
24
|
const ARGS_COUNT = 'n'
|
25
|
-
const VARIADIC =
|
25
|
+
const VARIADIC = Infinity
|
26
26
|
const STATS = '__stats__'
|
27
27
|
const ARGS = 'args'
|
28
28
|
const UNKNOWN = -1
|
29
29
|
const RETURNS = 'returns'
|
30
30
|
const SCOPE_NAME = '__scope__'
|
31
|
-
const SUB_TYPE = 'subType'
|
32
31
|
const TYPE_PROP = 'type'
|
33
32
|
const PREDICATE = 3
|
34
33
|
const COLLECTION = 4
|
@@ -49,249 +48,273 @@ const toTypeNames = (type) => {
|
|
49
48
|
return 'Collection'
|
50
49
|
}
|
51
50
|
}
|
51
|
+
const drillReturnType = (rest, condition) => {
|
52
|
+
const body = rest.at(-1)
|
53
|
+
const rem = hasBlock(body) ? body.at(-1) : body
|
54
|
+
const returns = isLeaf(rem) ? rem : rem[0]
|
55
|
+
return condition(returns)
|
56
|
+
? drillReturnType(rem.at(-1), condition)
|
57
|
+
: [returns, rem]
|
58
|
+
}
|
59
|
+
const getScopeNames = (scope) => {
|
60
|
+
const scopeNames = []
|
61
|
+
let current = scope
|
62
|
+
while (current) {
|
63
|
+
if (current[SCOPE_NAME]) {
|
64
|
+
scopeNames.push(current[SCOPE_NAME])
|
65
|
+
}
|
66
|
+
current = Object.getPrototypeOf(current)
|
67
|
+
}
|
68
|
+
return scopeNames.reverse()
|
69
|
+
}
|
70
|
+
const withScope = (name, scope) => {
|
71
|
+
const chain = getScopeNames(scope)
|
72
|
+
const str = `${chain.join('_')}_${name}`
|
73
|
+
return { str, chain }
|
74
|
+
}
|
52
75
|
export const typeCheck = (ast) => {
|
53
76
|
const root = {
|
54
77
|
[DEBUG.LOG]: {
|
55
78
|
[STATS]: {
|
56
|
-
|
79
|
+
[TYPE_PROP]: [APPLY],
|
57
80
|
retried: 0,
|
58
81
|
[ARGS]: [
|
59
82
|
[UNKNOWN, PLACEHOLDER],
|
60
83
|
[COLLECTION, PLACEHOLDER]
|
61
84
|
],
|
62
85
|
[ARGS_COUNT]: 2,
|
63
|
-
[RETURNS]: UNKNOWN
|
86
|
+
[RETURNS]: [UNKNOWN]
|
64
87
|
}
|
65
88
|
},
|
66
89
|
[DEBUG.STRING]: {
|
67
90
|
[STATS]: {
|
68
|
-
|
91
|
+
[TYPE_PROP]: [APPLY],
|
69
92
|
retried: 0,
|
70
93
|
[ARGS_COUNT]: 1,
|
71
94
|
[ARGS]: [[COLLECTION, PLACEHOLDER]],
|
72
|
-
[RETURNS]: COLLECTION
|
95
|
+
[RETURNS]: [COLLECTION]
|
73
96
|
}
|
74
97
|
},
|
75
98
|
[DEBUG.ASSERT]: {
|
76
99
|
[STATS]: {
|
77
|
-
|
100
|
+
[TYPE_PROP]: [APPLY],
|
78
101
|
retried: 0,
|
79
102
|
[ARGS_COUNT]: VARIADIC,
|
80
|
-
[RETURNS]: UNKNOWN
|
103
|
+
[RETURNS]: [UNKNOWN]
|
81
104
|
}
|
82
105
|
},
|
83
106
|
[DEBUG.SIGNATURE]: {
|
84
107
|
[STATS]: {
|
85
|
-
|
108
|
+
[TYPE_PROP]: [APPLY],
|
86
109
|
retried: 0,
|
87
110
|
[ARGS_COUNT]: VARIADIC,
|
88
|
-
[RETURNS]: UNKNOWN
|
111
|
+
[RETURNS]: [UNKNOWN]
|
89
112
|
}
|
90
113
|
},
|
91
114
|
[DEBUG.LIST_THEMES]: {
|
92
115
|
[STATS]: {
|
93
|
-
|
116
|
+
[TYPE_PROP]: [APPLY],
|
94
117
|
retried: 0,
|
95
118
|
[ARGS_COUNT]: VARIADIC,
|
96
|
-
[RETURNS]: UNKNOWN
|
119
|
+
[RETURNS]: [UNKNOWN]
|
97
120
|
}
|
98
121
|
},
|
99
122
|
[DEBUG.SET_THEME]: {
|
100
123
|
[STATS]: {
|
101
|
-
|
124
|
+
[TYPE_PROP]: [APPLY],
|
102
125
|
retried: 0,
|
103
126
|
[ARGS_COUNT]: VARIADIC,
|
104
|
-
[RETURNS]: UNKNOWN
|
127
|
+
[RETURNS]: [UNKNOWN]
|
105
128
|
}
|
106
129
|
},
|
107
130
|
[KEYWORDS.BLOCK]: {
|
108
131
|
[STATS]: {
|
109
|
-
|
132
|
+
[TYPE_PROP]: [APPLY],
|
110
133
|
retried: 0,
|
111
134
|
[ARGS_COUNT]: VARIADIC,
|
112
|
-
[RETURNS]: UNKNOWN
|
135
|
+
[RETURNS]: [UNKNOWN]
|
113
136
|
}
|
114
137
|
},
|
115
138
|
[KEYWORDS.ANONYMOUS_FUNCTION]: {
|
116
139
|
[STATS]: {
|
117
|
-
|
140
|
+
[TYPE_PROP]: [APPLY],
|
118
141
|
retried: 0,
|
119
142
|
[ARGS_COUNT]: VARIADIC,
|
120
|
-
[RETURNS]: APPLY
|
143
|
+
[RETURNS]: [APPLY]
|
121
144
|
}
|
122
145
|
},
|
123
146
|
[KEYWORDS.CALL_FUNCTION]: {
|
124
147
|
[STATS]: {
|
125
|
-
|
148
|
+
[TYPE_PROP]: [APPLY],
|
126
149
|
retried: 0,
|
127
150
|
[ARGS_COUNT]: VARIADIC,
|
128
|
-
[RETURNS]: UNKNOWN
|
151
|
+
[RETURNS]: [UNKNOWN]
|
129
152
|
}
|
130
153
|
},
|
131
154
|
[KEYWORDS.CREATE_ARRAY]: {
|
132
155
|
[STATS]: {
|
133
|
-
|
156
|
+
[TYPE_PROP]: [APPLY],
|
134
157
|
retried: 0,
|
135
158
|
[ARGS_COUNT]: VARIADIC,
|
136
|
-
[RETURNS]: COLLECTION
|
159
|
+
[RETURNS]: [COLLECTION]
|
137
160
|
}
|
138
161
|
},
|
139
162
|
[KEYWORDS.LOOP]: {
|
140
163
|
[STATS]: {
|
141
|
-
|
164
|
+
[TYPE_PROP]: [APPLY],
|
142
165
|
retried: 0,
|
143
166
|
[ARGS_COUNT]: 2,
|
144
167
|
[ARGS]: [
|
145
168
|
[ATOM, PLACEHOLDER, PREDICATE],
|
146
169
|
[UNKNOWN, PLACEHOLDER]
|
147
170
|
],
|
148
|
-
[RETURNS]: ATOM
|
171
|
+
[RETURNS]: [ATOM]
|
149
172
|
}
|
150
173
|
},
|
151
174
|
[KEYWORDS.ADDITION]: {
|
152
175
|
[STATS]: {
|
153
|
-
|
176
|
+
[TYPE_PROP]: [APPLY],
|
154
177
|
retried: 0,
|
155
178
|
[ARGS_COUNT]: 2,
|
156
179
|
[ARGS]: [
|
157
180
|
[ATOM, PLACEHOLDER],
|
158
181
|
[ATOM, PLACEHOLDER]
|
159
182
|
],
|
160
|
-
[RETURNS]: ATOM
|
183
|
+
[RETURNS]: [ATOM]
|
161
184
|
}
|
162
185
|
},
|
163
186
|
[KEYWORDS.MULTIPLICATION]: {
|
164
187
|
[STATS]: {
|
165
|
-
|
188
|
+
[TYPE_PROP]: [APPLY],
|
166
189
|
retried: 0,
|
167
190
|
[ARGS_COUNT]: 2,
|
168
191
|
[ARGS]: [
|
169
192
|
[ATOM, PLACEHOLDER],
|
170
193
|
[ATOM, PLACEHOLDER]
|
171
194
|
],
|
172
|
-
[RETURNS]: ATOM
|
195
|
+
[RETURNS]: [ATOM]
|
173
196
|
}
|
174
197
|
},
|
175
198
|
[KEYWORDS.SUBTRACTION]: {
|
176
199
|
[STATS]: {
|
177
|
-
|
200
|
+
[TYPE_PROP]: [APPLY],
|
178
201
|
retried: 0,
|
179
202
|
[ARGS_COUNT]: 2,
|
180
203
|
[ARGS]: [
|
181
204
|
[ATOM, PLACEHOLDER],
|
182
205
|
[ATOM, PLACEHOLDER]
|
183
206
|
],
|
184
|
-
[RETURNS]: ATOM
|
207
|
+
[RETURNS]: [ATOM]
|
185
208
|
}
|
186
209
|
},
|
187
210
|
[KEYWORDS.DIVISION]: {
|
188
211
|
[STATS]: {
|
189
|
-
|
212
|
+
[TYPE_PROP]: [APPLY],
|
190
213
|
retried: 0,
|
191
214
|
[ARGS_COUNT]: 2,
|
192
215
|
[ARGS]: [
|
193
216
|
[ATOM, PLACEHOLDER],
|
194
217
|
[ATOM, PLACEHOLDER]
|
195
218
|
],
|
196
|
-
[RETURNS]: ATOM
|
219
|
+
[RETURNS]: [ATOM]
|
197
220
|
}
|
198
221
|
},
|
199
222
|
[KEYWORDS.REMAINDER_OF_DIVISION]: {
|
200
223
|
[STATS]: {
|
201
|
-
|
224
|
+
[TYPE_PROP]: [APPLY],
|
202
225
|
retried: 0,
|
203
226
|
[ARGS_COUNT]: 2,
|
204
227
|
[ARGS]: [
|
205
228
|
[ATOM, PLACEHOLDER],
|
206
229
|
[ATOM, PLACEHOLDER]
|
207
230
|
],
|
208
|
-
[RETURNS]: ATOM
|
231
|
+
[RETURNS]: [ATOM]
|
209
232
|
}
|
210
233
|
},
|
211
234
|
[KEYWORDS.BITWISE_AND]: {
|
212
235
|
[STATS]: {
|
213
|
-
|
236
|
+
[TYPE_PROP]: [APPLY],
|
214
237
|
retried: 0,
|
215
238
|
[ARGS_COUNT]: 2,
|
216
239
|
[ARGS]: [
|
217
240
|
[ATOM, PLACEHOLDER],
|
218
241
|
[ATOM, PLACEHOLDER]
|
219
242
|
],
|
220
|
-
[RETURNS]: ATOM
|
243
|
+
[RETURNS]: [ATOM]
|
221
244
|
}
|
222
245
|
},
|
223
246
|
[KEYWORDS.BITWISE_NOT]: {
|
224
247
|
[STATS]: {
|
225
|
-
|
248
|
+
[TYPE_PROP]: [APPLY],
|
226
249
|
retried: 0,
|
227
250
|
[ARGS_COUNT]: 1,
|
228
251
|
[ARGS]: [[ATOM, PLACEHOLDER]],
|
229
|
-
[RETURNS]: ATOM
|
252
|
+
[RETURNS]: [ATOM]
|
230
253
|
}
|
231
254
|
},
|
232
255
|
[KEYWORDS.BITWISE_OR]: {
|
233
256
|
[STATS]: {
|
234
|
-
|
257
|
+
[TYPE_PROP]: [APPLY],
|
235
258
|
retried: 0,
|
236
259
|
[ARGS_COUNT]: 2,
|
237
260
|
[ARGS]: [
|
238
261
|
[ATOM, PLACEHOLDER],
|
239
262
|
[ATOM, PLACEHOLDER]
|
240
263
|
],
|
241
|
-
[RETURNS]: ATOM
|
264
|
+
[RETURNS]: [ATOM]
|
242
265
|
}
|
243
266
|
},
|
244
267
|
[KEYWORDS.BITWISE_XOR]: {
|
245
268
|
[STATS]: {
|
246
|
-
|
269
|
+
[TYPE_PROP]: [APPLY],
|
247
270
|
retried: 0,
|
248
271
|
[ARGS_COUNT]: 2,
|
249
272
|
[ARGS]: [
|
250
273
|
[ATOM, PLACEHOLDER],
|
251
274
|
[ATOM, PLACEHOLDER]
|
252
275
|
],
|
253
|
-
[RETURNS]: ATOM
|
276
|
+
[RETURNS]: [ATOM]
|
254
277
|
}
|
255
278
|
},
|
256
279
|
[KEYWORDS.BITWISE_LEFT_SHIFT]: {
|
257
280
|
[STATS]: {
|
258
|
-
|
281
|
+
[TYPE_PROP]: [APPLY],
|
259
282
|
retried: 0,
|
260
283
|
[ARGS_COUNT]: 2,
|
261
284
|
[ARGS]: [
|
262
285
|
[ATOM, PLACEHOLDER],
|
263
286
|
[ATOM, PLACEHOLDER]
|
264
287
|
],
|
265
|
-
[RETURNS]: ATOM
|
288
|
+
[RETURNS]: [ATOM]
|
266
289
|
}
|
267
290
|
},
|
268
291
|
[KEYWORDS.BITWISE_RIGHT_SHIFT]: {
|
269
292
|
[STATS]: {
|
270
|
-
|
293
|
+
[TYPE_PROP]: [APPLY],
|
271
294
|
retried: 0,
|
272
295
|
[ARGS_COUNT]: 2,
|
273
296
|
[ARGS]: [
|
274
297
|
[ATOM, PLACEHOLDER],
|
275
298
|
[ATOM, PLACEHOLDER]
|
276
299
|
],
|
277
|
-
[RETURNS]: ATOM
|
300
|
+
[RETURNS]: [ATOM]
|
278
301
|
}
|
279
302
|
},
|
280
303
|
[KEYWORDS.GET_ARRAY]: {
|
281
304
|
[STATS]: {
|
282
|
-
|
305
|
+
[TYPE_PROP]: [APPLY],
|
283
306
|
retried: 0,
|
284
307
|
[ARGS_COUNT]: 2,
|
285
308
|
[ARGS]: [
|
286
309
|
[COLLECTION, PLACEHOLDER],
|
287
310
|
[ATOM, PLACEHOLDER]
|
288
311
|
],
|
289
|
-
[RETURNS]: UNKNOWN
|
312
|
+
[RETURNS]: [UNKNOWN]
|
290
313
|
}
|
291
314
|
},
|
292
315
|
[KEYWORDS.SET_ARRAY]: {
|
293
316
|
[STATS]: {
|
294
|
-
|
317
|
+
[TYPE_PROP]: [APPLY],
|
295
318
|
retried: 0,
|
296
319
|
[ARGS_COUNT]: 3,
|
297
320
|
[ARGS]: [
|
@@ -299,30 +322,30 @@ export const typeCheck = (ast) => {
|
|
299
322
|
[ATOM, PLACEHOLDER],
|
300
323
|
[UNKNOWN, PLACEHOLDER]
|
301
324
|
],
|
302
|
-
[RETURNS]: COLLECTION
|
325
|
+
[RETURNS]: [COLLECTION]
|
303
326
|
}
|
304
327
|
},
|
305
328
|
[KEYWORDS.POP_ARRAY]: {
|
306
329
|
[STATS]: {
|
307
|
-
|
330
|
+
[TYPE_PROP]: [APPLY],
|
308
331
|
retried: 0,
|
309
332
|
[ARGS_COUNT]: 1,
|
310
333
|
[ARGS]: [[COLLECTION, PLACEHOLDER]],
|
311
|
-
[RETURNS]: COLLECTION
|
334
|
+
[RETURNS]: [COLLECTION]
|
312
335
|
}
|
313
336
|
},
|
314
337
|
[KEYWORDS.ARRAY_LENGTH]: {
|
315
338
|
[STATS]: {
|
316
|
-
|
339
|
+
[TYPE_PROP]: [APPLY],
|
317
340
|
retried: 0,
|
318
341
|
[ARGS_COUNT]: 1,
|
319
342
|
[ARGS]: [[COLLECTION, PLACEHOLDER]],
|
320
|
-
[RETURNS]: ATOM
|
343
|
+
[RETURNS]: [ATOM]
|
321
344
|
}
|
322
345
|
},
|
323
346
|
[KEYWORDS.IF]: {
|
324
347
|
[STATS]: {
|
325
|
-
|
348
|
+
[TYPE_PROP]: [APPLY],
|
326
349
|
retried: 0,
|
327
350
|
[ARGS_COUNT]: 3,
|
328
351
|
[ARGS]: [
|
@@ -330,137 +353,127 @@ export const typeCheck = (ast) => {
|
|
330
353
|
[UNKNOWN, PLACEHOLDER],
|
331
354
|
[UNKNOWN, PLACEHOLDER]
|
332
355
|
],
|
333
|
-
[RETURNS]: ATOM
|
356
|
+
[RETURNS]: [ATOM]
|
334
357
|
}
|
335
358
|
},
|
336
359
|
[KEYWORDS.NOT]: {
|
337
360
|
[STATS]: {
|
338
|
-
|
361
|
+
[TYPE_PROP]: [APPLY],
|
339
362
|
retried: 0,
|
340
363
|
[ARGS_COUNT]: 1,
|
341
364
|
[ARGS]: [[ATOM, PLACEHOLDER, PREDICATE]],
|
342
|
-
[RETURNS]: ATOM,
|
343
|
-
[SUB_TYPE]: PREDICATE
|
365
|
+
[RETURNS]: [ATOM, PREDICATE]
|
344
366
|
}
|
345
367
|
},
|
346
368
|
[KEYWORDS.EQUAL]: {
|
347
369
|
[STATS]: {
|
348
|
-
|
370
|
+
[TYPE_PROP]: [APPLY],
|
349
371
|
retried: 0,
|
350
372
|
[ARGS_COUNT]: 2,
|
351
373
|
[ARGS]: [
|
352
374
|
[ATOM, PLACEHOLDER],
|
353
375
|
[ATOM, PLACEHOLDER]
|
354
376
|
],
|
355
|
-
[RETURNS]: ATOM,
|
356
|
-
[SUB_TYPE]: PREDICATE
|
377
|
+
[RETURNS]: [ATOM, PREDICATE]
|
357
378
|
}
|
358
379
|
},
|
359
380
|
[KEYWORDS.LESS_THAN]: {
|
360
381
|
[STATS]: {
|
361
|
-
|
382
|
+
[TYPE_PROP]: [APPLY],
|
362
383
|
retried: 0,
|
363
384
|
[ARGS_COUNT]: 2,
|
364
385
|
[ARGS]: [
|
365
386
|
[ATOM, PLACEHOLDER],
|
366
387
|
[ATOM, PLACEHOLDER]
|
367
388
|
],
|
368
|
-
[RETURNS]: ATOM,
|
369
|
-
[SUB_TYPE]: PREDICATE
|
389
|
+
[RETURNS]: [ATOM, PREDICATE]
|
370
390
|
}
|
371
391
|
},
|
372
392
|
[KEYWORDS.GREATHER_THAN]: {
|
373
393
|
[STATS]: {
|
374
|
-
|
394
|
+
[TYPE_PROP]: [APPLY],
|
375
395
|
retried: 0,
|
376
396
|
[ARGS_COUNT]: 2,
|
377
397
|
[ARGS]: [
|
378
398
|
[ATOM, PLACEHOLDER],
|
379
399
|
[ATOM, PLACEHOLDER]
|
380
400
|
],
|
381
|
-
[RETURNS]: ATOM,
|
382
|
-
[SUB_TYPE]: PREDICATE
|
401
|
+
[RETURNS]: [ATOM, PREDICATE]
|
383
402
|
}
|
384
403
|
},
|
385
404
|
[KEYWORDS.GREATHER_THAN_OR_EQUAL]: {
|
386
405
|
[STATS]: {
|
387
|
-
|
406
|
+
[TYPE_PROP]: [APPLY],
|
388
407
|
retried: 0,
|
389
408
|
[ARGS_COUNT]: 2,
|
390
409
|
[ARGS]: [
|
391
410
|
[ATOM, PLACEHOLDER],
|
392
411
|
[ATOM, PLACEHOLDER]
|
393
412
|
],
|
394
|
-
[RETURNS]: ATOM,
|
395
|
-
[SUB_TYPE]: PREDICATE
|
413
|
+
[RETURNS]: [ATOM, PREDICATE]
|
396
414
|
}
|
397
415
|
},
|
398
416
|
[KEYWORDS.LESS_THAN_OR_EQUAL]: {
|
399
417
|
[STATS]: {
|
400
|
-
|
418
|
+
[TYPE_PROP]: [APPLY],
|
401
419
|
retried: 0,
|
402
420
|
[ARGS_COUNT]: 2,
|
403
421
|
[ARGS]: [
|
404
422
|
[ATOM, PLACEHOLDER],
|
405
423
|
[ATOM, PLACEHOLDER]
|
406
424
|
],
|
407
|
-
[RETURNS]: ATOM,
|
408
|
-
[SUB_TYPE]: PREDICATE
|
425
|
+
[RETURNS]: [ATOM, PREDICATE]
|
409
426
|
}
|
410
427
|
},
|
411
428
|
[KEYWORDS.AND]: {
|
412
429
|
[STATS]: {
|
413
|
-
|
430
|
+
[TYPE_PROP]: [APPLY],
|
414
431
|
retried: 0,
|
415
432
|
[ARGS_COUNT]: 2,
|
416
433
|
[ARGS]: [
|
417
434
|
[ATOM, PLACEHOLDER, PREDICATE],
|
418
435
|
[ATOM, PLACEHOLDER, PREDICATE]
|
419
436
|
],
|
420
|
-
[RETURNS]: ATOM,
|
421
|
-
[SUB_TYPE]: PREDICATE
|
437
|
+
[RETURNS]: [ATOM, PREDICATE]
|
422
438
|
}
|
423
439
|
},
|
424
440
|
[KEYWORDS.OR]: {
|
425
441
|
[STATS]: {
|
426
|
-
|
442
|
+
[TYPE_PROP]: [APPLY],
|
427
443
|
retried: 0,
|
428
444
|
[ARGS_COUNT]: 2,
|
429
445
|
[ARGS]: [
|
430
446
|
[ATOM, PLACEHOLDER, PREDICATE],
|
431
447
|
[ATOM, PLACEHOLDER, PREDICATE]
|
432
448
|
],
|
433
|
-
[RETURNS]: ATOM,
|
434
|
-
[SUB_TYPE]: PREDICATE
|
449
|
+
[RETURNS]: [ATOM, PREDICATE]
|
435
450
|
}
|
436
451
|
},
|
437
452
|
[KEYWORDS.IS_ATOM]: {
|
438
453
|
[STATS]: {
|
439
|
-
|
454
|
+
[TYPE_PROP]: [APPLY],
|
440
455
|
retried: 0,
|
441
456
|
[ARGS_COUNT]: 1,
|
442
457
|
[ARGS]: [[UNKNOWN, PLACEHOLDER]],
|
443
|
-
[RETURNS]: ATOM,
|
444
|
-
[SUB_TYPE]: PREDICATE
|
458
|
+
[RETURNS]: [ATOM, PREDICATE]
|
445
459
|
}
|
446
460
|
},
|
447
461
|
[KEYWORDS.IS_LAMBDA]: {
|
448
462
|
[STATS]: {
|
449
|
-
|
463
|
+
[TYPE_PROP]: [APPLY],
|
450
464
|
retried: 0,
|
451
465
|
[ARGS_COUNT]: 1,
|
452
466
|
[ARGS]: [[UNKNOWN, PLACEHOLDER]],
|
453
|
-
[RETURNS]: ATOM,
|
454
|
-
[SUB_TYPE]: PREDICATE
|
467
|
+
[RETURNS]: [ATOM, PREDICATE]
|
455
468
|
}
|
456
469
|
},
|
457
470
|
[KEYWORDS.ERROR]: {
|
458
471
|
[STATS]: {
|
459
|
-
|
472
|
+
[TYPE_PROP]: [APPLY],
|
460
473
|
retried: 0,
|
461
474
|
[ARGS_COUNT]: 1,
|
462
475
|
[ARGS]: [[COLLECTION, PLACEHOLDER]],
|
463
|
-
[RETURNS]: UNKNOWN
|
476
|
+
[RETURNS]: [UNKNOWN]
|
464
477
|
}
|
465
478
|
}
|
466
479
|
}
|
@@ -472,22 +485,6 @@ export const typeCheck = (ast) => {
|
|
472
485
|
// head[VALUE] === KEYWORDS.DEFINE_VARIABLE &&
|
473
486
|
// tail.at(-1)[0][TYPE] === APPLY &&
|
474
487
|
// tail.at(-1)[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
|
475
|
-
const getScopeNames = (scope) => {
|
476
|
-
const scopeNames = []
|
477
|
-
let current = scope
|
478
|
-
while (current) {
|
479
|
-
if (current[SCOPE_NAME]) {
|
480
|
-
scopeNames.push(current[SCOPE_NAME])
|
481
|
-
}
|
482
|
-
current = Object.getPrototypeOf(current)
|
483
|
-
}
|
484
|
-
return scopeNames.reverse()
|
485
|
-
}
|
486
|
-
const withScope = (name, scope) => {
|
487
|
-
const chain = getScopeNames(scope)
|
488
|
-
const str = `${chain.join('_')}_${name}`
|
489
|
-
return { str, chain }
|
490
|
-
}
|
491
488
|
|
492
489
|
const stack = []
|
493
490
|
const check = (exp, env, scope) => {
|
@@ -535,7 +532,7 @@ export const typeCheck = (ast) => {
|
|
535
532
|
const name = rest[0][VALUE]
|
536
533
|
const resolveRetunType = (returns, rem, prop, isPredicate) => {
|
537
534
|
if (returns[TYPE] === ATOM) {
|
538
|
-
env[name][STATS][prop] = ATOM
|
535
|
+
env[name][STATS][prop][0] = ATOM
|
539
536
|
} else {
|
540
537
|
switch (returns[VALUE]) {
|
541
538
|
case KEYWORDS.IF:
|
@@ -543,21 +540,25 @@ export const typeCheck = (ast) => {
|
|
543
540
|
const re = rem.slice(2)
|
544
541
|
// If either is an ATOM then IF returns an ATOM
|
545
542
|
if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
|
546
|
-
env[name][STATS][prop] = ATOM
|
543
|
+
env[name][STATS][prop][0] = ATOM
|
547
544
|
// if (
|
548
545
|
// re[0][VALUE] === FALSE ||
|
549
546
|
// re[0][VALUE] === TRUE ||
|
550
547
|
// re[1][VALUE] === FALSE ||
|
551
548
|
// re[1][VALUE] === TRUE
|
552
549
|
// ) {
|
553
|
-
// env[name][STATS][
|
550
|
+
// env[name][STATS][RETURNS][1] = PREDICATE
|
554
551
|
// }
|
555
552
|
} else if (!isLeaf(re[0]) && env[re[0][0][VALUE]]) {
|
553
|
+
// const concequent = isLeaf(re[0])
|
554
|
+
// ? env[re[0][VALUE]]
|
555
|
+
// : env[re[0][0][VALUE]]
|
556
|
+
// const alternative = isLeaf(re[1])
|
557
|
+
// ? env[re[1][VALUE]]
|
558
|
+
// : env[re[1][0][VALUE]]
|
559
|
+
|
556
560
|
env[name][STATS][prop] =
|
557
561
|
env[re[0][0][VALUE]][STATS][RETURNS]
|
558
|
-
env[name][STATS][SUB_TYPE] =
|
559
|
-
env[re[0][0][VALUE]][STATS][SUB_TYPE]
|
560
|
-
|
561
562
|
if (
|
562
563
|
re[0][0][TYPE] === APPLY &&
|
563
564
|
// turn off typechecks for optimized functions
|
@@ -570,7 +571,7 @@ export const typeCheck = (ast) => {
|
|
570
571
|
// env[name][STATS][SUB_TYPE] =
|
571
572
|
// env[re[0][0][VALUE]][STATS][SUB_TYPE]
|
572
573
|
|
573
|
-
env[name][STATS][RETURNS] = UNKNOWN
|
574
|
+
env[name][STATS][RETURNS] = [UNKNOWN]
|
574
575
|
env[name][STATS][ARGS_COUNT] =
|
575
576
|
re[0].length - 2
|
576
577
|
// check(
|
@@ -588,14 +589,14 @@ export const typeCheck = (ast) => {
|
|
588
589
|
// env[name][STATS] = env[re[0][0][VALUE]][STATS]
|
589
590
|
} else {
|
590
591
|
if (env[re[0][VALUE]]) {
|
591
|
-
env[name][STATS][prop] =
|
592
|
-
env[re[0][VALUE]][STATS]
|
593
|
-
env[name][STATS][
|
594
|
-
env[re[0][VALUE]][STATS][
|
592
|
+
env[name][STATS][prop][0] =
|
593
|
+
env[re[0][VALUE]][STATS][TYPE_PROP][0]
|
594
|
+
env[name][STATS][RETURNS][1] =
|
595
|
+
env[re[0][VALUE]][STATS][RETURNS][1]
|
595
596
|
// env[name][STATS] = env[name][STATS]
|
596
597
|
// env[re[0][VALUE]][STATS][SUB_TYPE]
|
597
598
|
} else {
|
598
|
-
env[name][STATS][prop] = UNKNOWN
|
599
|
+
env[name][STATS][prop] = [UNKNOWN]
|
599
600
|
// env[name][STATS][RETURNS] = APPLY
|
600
601
|
}
|
601
602
|
}
|
@@ -603,32 +604,41 @@ export const typeCheck = (ast) => {
|
|
603
604
|
break
|
604
605
|
default:
|
605
606
|
if (env[returns[VALUE]]) {
|
606
|
-
if (
|
607
|
+
if (
|
608
|
+
env[returns[VALUE]][STATS][TYPE_PROP][0] === APPLY
|
609
|
+
) {
|
607
610
|
if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
|
608
611
|
if (isLeaf(rest.at(-1).at(-1).at(-1))) {
|
609
612
|
const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
|
610
613
|
const fn = env[fnName]
|
611
614
|
if (
|
612
615
|
!isPredicate &&
|
613
|
-
fn[STATS][
|
616
|
+
fn[STATS][RETURNS][1] === PREDICATE
|
614
617
|
) {
|
615
618
|
warningStack.add(
|
616
619
|
`${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
|
617
620
|
)
|
618
621
|
} else if (
|
619
622
|
isPredicate &&
|
620
|
-
fn[STATS][
|
623
|
+
fn[STATS][RETURNS][1] !== PREDICATE
|
621
624
|
) {
|
622
625
|
warningStack.add(
|
623
626
|
`${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (try wrapping it in a (true?) or (false?)) (check #25)`
|
624
627
|
)
|
625
628
|
}
|
626
|
-
env[name][STATS]
|
627
|
-
|
629
|
+
env[name][STATS][TYPE_PROP][0] =
|
630
|
+
fn[STATS][RETURNS][0]
|
631
|
+
env[name][STATS][RETURNS][1] =
|
632
|
+
fn[STATS][RETURNS][1]
|
628
633
|
} else {
|
629
|
-
const body = rest.at(-1).at(-1).at(-1).at(-1)
|
630
|
-
const rem = hasBlock(body) ? body.at(-1) : body
|
631
|
-
const returns = isLeaf(rem) ? rem : rem[0]
|
634
|
+
// const body = rest.at(-1).at(-1).at(-1).at(-1)
|
635
|
+
// const rem = hasBlock(body) ? body.at(-1) : body
|
636
|
+
// const returns = isLeaf(rem) ? rem : rem[0]
|
637
|
+
const [returns, rem] = drillReturnType(
|
638
|
+
rest.at(-1).at(-1).at(-1),
|
639
|
+
(returns) =>
|
640
|
+
returns[VALUE] === KEYWORDS.CALL_FUNCTION
|
641
|
+
)
|
632
642
|
resolveRetunType(
|
633
643
|
returns,
|
634
644
|
rem,
|
@@ -639,16 +649,14 @@ export const typeCheck = (ast) => {
|
|
639
649
|
}
|
640
650
|
env[name][STATS][RETURNS] =
|
641
651
|
env[returns[VALUE]][STATS][RETURNS]
|
642
|
-
env[name][STATS][SUB_TYPE] =
|
643
|
-
env[returns[VALUE]][STATS][SUB_TYPE]
|
644
652
|
} else {
|
645
653
|
env[name][STATS][RETURNS] =
|
646
|
-
env[returns[VALUE]][STATS]
|
647
|
-
env[name][STATS][
|
648
|
-
env[returns[VALUE]][
|
654
|
+
env[returns[VALUE]][STATS][RETURNS]
|
655
|
+
env[name][STATS][RETURNS][0] =
|
656
|
+
env[returns[VALUE]][STATS][TYPE_PROP][0]
|
649
657
|
}
|
650
658
|
} else {
|
651
|
-
env[name][STATS][RETURNS] = UNKNOWN
|
659
|
+
env[name][STATS][RETURNS] = [UNKNOWN]
|
652
660
|
// env[name][STATS][RETURNS] = APPLY
|
653
661
|
}
|
654
662
|
break
|
@@ -656,34 +664,27 @@ export const typeCheck = (ast) => {
|
|
656
664
|
}
|
657
665
|
if (
|
658
666
|
isPredicate &&
|
659
|
-
env[name][STATS][prop] !== UNKNOWN &&
|
660
|
-
env[name][STATS][
|
667
|
+
env[name][STATS][prop][0] !== UNKNOWN &&
|
668
|
+
env[name][STATS][RETURNS][1] !== PREDICATE
|
661
669
|
) {
|
662
670
|
warningStack.add(
|
663
671
|
`${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (try wrapping it in a (true?) or (false?)) (check #7)`
|
664
672
|
)
|
665
673
|
} else if (
|
666
674
|
!isPredicate &&
|
667
|
-
env[name][STATS][
|
675
|
+
env[name][STATS][RETURNS][1] === PREDICATE
|
668
676
|
) {
|
669
677
|
warningStack.add(
|
670
678
|
`${name} should end in (${PREDICATE_SUFFIX}) because it return (Predicate) (try adding ? at the end of the lambda name) (check #8)`
|
671
679
|
)
|
672
680
|
}
|
673
681
|
if (isPredicate) {
|
674
|
-
env[name][STATS][prop] = ATOM
|
675
|
-
env[name][STATS][
|
682
|
+
env[name][STATS][prop] = [ATOM]
|
683
|
+
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
676
684
|
}
|
677
685
|
}
|
678
686
|
const checkReturnType = () => {
|
679
|
-
// if (name[name.length - 1] === PREDICATE_SUFFIX) {
|
680
|
-
// env[name][STATS][RETURNS] = ATOM
|
681
|
-
// env[name][STATS][SUB_TYPE] = PREDICATE
|
682
|
-
// } else {
|
683
687
|
const last = rest.at(-1).at(-1)
|
684
|
-
// const isApplyLambdaDoBlock = hasApplyLambdaBlock(
|
685
|
-
// rest.at(-1)
|
686
|
-
// )
|
687
688
|
const body = hasApplyLambdaBlock(last)
|
688
689
|
? last.at(-1).at(-1)
|
689
690
|
: last
|
@@ -691,15 +692,6 @@ export const typeCheck = (ast) => {
|
|
691
692
|
const returns = isLeaf(rem) ? rem : rem[0]
|
692
693
|
const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
|
693
694
|
resolveRetunType(returns, rem, RETURNS, isPredicate)
|
694
|
-
// }
|
695
|
-
// if (
|
696
|
-
// env[name][STATS][RETURNS] === UNKNOWN &&
|
697
|
-
// env[name][STATS].retried < RETRY_COUNT
|
698
|
-
// ) {
|
699
|
-
// env[name][STATS].retried += 1
|
700
|
-
// console.log(name, env[name][STATS])
|
701
|
-
// checkReturnType()
|
702
|
-
// }
|
703
695
|
}
|
704
696
|
if (
|
705
697
|
rest.at(-1) &&
|
@@ -710,16 +702,17 @@ export const typeCheck = (ast) => {
|
|
710
702
|
const n = rest.at(-1).length
|
711
703
|
env[name] = {
|
712
704
|
[STATS]: {
|
713
|
-
|
705
|
+
[TYPE_PROP]: [APPLY],
|
714
706
|
retried: 0,
|
715
707
|
[ARGS_COUNT]: n - 2,
|
716
|
-
[ARGS]: []
|
708
|
+
[ARGS]: [],
|
709
|
+
[RETURNS]: [UNKNOWN]
|
717
710
|
}
|
718
711
|
}
|
719
712
|
|
720
713
|
checkReturnType()
|
721
714
|
if (
|
722
|
-
env[name][STATS][RETURNS] === UNKNOWN &&
|
715
|
+
env[name][STATS][RETURNS][0] === UNKNOWN &&
|
723
716
|
env[name][STATS].retried < DEFINITON_RETRY_COUNT
|
724
717
|
) {
|
725
718
|
env[name][STATS].retried += 1
|
@@ -770,10 +763,12 @@ export const typeCheck = (ast) => {
|
|
770
763
|
env[name] = {
|
771
764
|
[STATS]: {
|
772
765
|
retried: 0,
|
773
|
-
|
766
|
+
[TYPE_PROP]: [ATOM],
|
767
|
+
[RETURNS]: [UNKNOWN]
|
774
768
|
}
|
775
769
|
}
|
776
|
-
if (isPredicate)
|
770
|
+
if (isPredicate)
|
771
|
+
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
777
772
|
} else {
|
778
773
|
const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
|
779
774
|
if (
|
@@ -788,12 +783,17 @@ export const typeCheck = (ast) => {
|
|
788
783
|
env[name] = {
|
789
784
|
[STATS]: {
|
790
785
|
retried: 0,
|
791
|
-
|
792
|
-
|
793
|
-
|
786
|
+
[TYPE_PROP]: [
|
787
|
+
isL
|
788
|
+
? right[TYPE]
|
789
|
+
: env[right?.[VALUE]]?.[STATS]?.[RETURNS]?.[0] ??
|
790
|
+
UNKNOWN
|
791
|
+
],
|
792
|
+
[RETURNS]: [UNKNOWN]
|
794
793
|
}
|
795
794
|
}
|
796
|
-
if (isPredicate)
|
795
|
+
if (isPredicate)
|
796
|
+
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
797
797
|
if (right && right[VALUE]) {
|
798
798
|
if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
|
799
799
|
if (isLeaf(rest.at(-1).at(-1))) {
|
@@ -801,21 +801,21 @@ export const typeCheck = (ast) => {
|
|
801
801
|
const fn = env[fnName]
|
802
802
|
if (
|
803
803
|
!isPredicate &&
|
804
|
-
fn[STATS][
|
804
|
+
fn[STATS][RETURNS][1] === PREDICATE
|
805
805
|
) {
|
806
806
|
warningStack.add(
|
807
807
|
`${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
|
808
808
|
)
|
809
809
|
} else if (
|
810
810
|
isPredicate &&
|
811
|
-
fn[STATS][
|
811
|
+
fn[STATS][RETURNS][1] !== PREDICATE
|
812
812
|
) {
|
813
813
|
warningStack.add(
|
814
814
|
`${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (try wrapping it in a (true?) or (false?)) (check #25)`
|
815
815
|
)
|
816
816
|
}
|
817
|
-
env[name][STATS]
|
818
|
-
env[name][STATS][
|
817
|
+
env[name][STATS][TYPE_PROP] = fn[STATS][RETURNS]
|
818
|
+
env[name][STATS][RETURNS] = fn[STATS][RETURNS]
|
819
819
|
} else {
|
820
820
|
const body = rest.at(-1).at(-1).at(-1)
|
821
821
|
const rem = hasBlock(body) ? body.at(-1) : body
|
@@ -829,16 +829,15 @@ export const typeCheck = (ast) => {
|
|
829
829
|
)
|
830
830
|
}
|
831
831
|
} else {
|
832
|
-
// TIODO finish this
|
833
832
|
const body = rest.at(-1)
|
834
833
|
const rem = hasBlock(body) ? body.at(-1) : body
|
835
834
|
const returns = isLeaf(rem) ? rem : rem[0]
|
836
835
|
resolveRetunType(returns, rem, TYPE_PROP, isPredicate)
|
837
|
-
// console.log({ name })
|
838
836
|
}
|
839
|
-
if (env[right[VALUE]]?.[STATS]?.[
|
837
|
+
if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
|
840
838
|
if (
|
841
|
-
env[right[VALUE]][STATS][
|
839
|
+
env[right[VALUE]][STATS][RETURNS][1] ===
|
840
|
+
PREDICATE &&
|
842
841
|
!isPredicate
|
843
842
|
) {
|
844
843
|
warningStack.add(
|
@@ -847,13 +846,11 @@ export const typeCheck = (ast) => {
|
|
847
846
|
)}) so ${name} must end in (${PREDICATE_SUFFIX}) (check #23)`
|
848
847
|
)
|
849
848
|
}
|
850
|
-
env[name][STATS][
|
851
|
-
env[right[VALUE]][STATS][
|
849
|
+
env[name][STATS][RETURNS] =
|
850
|
+
env[right[VALUE]][STATS][RETURNS]
|
852
851
|
}
|
853
852
|
}
|
854
853
|
}
|
855
|
-
|
856
|
-
// console.log(name, env[name])
|
857
854
|
}
|
858
855
|
// }
|
859
856
|
check(rest.at(-1), env, scope)
|
@@ -882,13 +879,20 @@ export const typeCheck = (ast) => {
|
|
882
879
|
for (let i = 0; i < params.length; ++i) {
|
883
880
|
const param = params[i]
|
884
881
|
copy[param[VALUE]] = {
|
885
|
-
[STATS]: {
|
882
|
+
[STATS]: {
|
883
|
+
[TYPE_PROP]: [UNKNOWN],
|
884
|
+
[RETURNS]: [UNKNOWN],
|
885
|
+
retried: 0
|
886
|
+
}
|
886
887
|
}
|
887
888
|
if (env[copy[SCOPE_NAME]]) {
|
888
|
-
env[copy[SCOPE_NAME]][STATS][ARGS]
|
889
|
+
if (env[copy[SCOPE_NAME]][STATS][ARGS])
|
890
|
+
env[copy[SCOPE_NAME]][STATS][ARGS][i] = copy[param[VALUE]]
|
889
891
|
if (getSuffix(param[VALUE]) === PREDICATE_SUFFIX) {
|
890
|
-
copy[param[VALUE]][STATS][RETURNS] = ATOM
|
891
|
-
|
892
|
+
copy[param[VALUE]][STATS][RETURNS] = [ATOM, PREDICATE]
|
893
|
+
} else {
|
894
|
+
// TODO overwrite return type check here
|
895
|
+
// console.log(copy[SCOPE_NAME], env[copy[SCOPE_NAME]], copy)
|
892
896
|
}
|
893
897
|
}
|
894
898
|
}
|
@@ -905,7 +909,7 @@ export const typeCheck = (ast) => {
|
|
905
909
|
)
|
906
910
|
else {
|
907
911
|
if (
|
908
|
-
env[first[VALUE]][STATS]
|
912
|
+
env[first[VALUE]][STATS][TYPE_PROP][0] === APPLY &&
|
909
913
|
env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC &&
|
910
914
|
env[first[VALUE]][STATS][ARGS_COUNT] !== rest.length
|
911
915
|
) {
|
@@ -923,7 +927,7 @@ export const typeCheck = (ast) => {
|
|
923
927
|
const isSpecial = SPECIAL_FORMS_SET.has(first[VALUE])
|
924
928
|
|
925
929
|
if (first[TYPE] === APPLY && !isSpecial) {
|
926
|
-
if (env[first[VALUE]][STATS]
|
930
|
+
if (env[first[VALUE]][STATS][TYPE_PROP][0] === ATOM) {
|
927
931
|
errorStack.set(
|
928
932
|
key.str,
|
929
933
|
`(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
|
@@ -931,8 +935,11 @@ export const typeCheck = (ast) => {
|
|
931
935
|
)}) (check #12)`
|
932
936
|
)
|
933
937
|
} else if (!env[first[VALUE]][STATS][ARGS_COUNT]) {
|
934
|
-
|
935
|
-
env[first[VALUE]][STATS]
|
938
|
+
// TODO recursively take return type of applicaion
|
939
|
+
if (env[first[VALUE]][STATS][RETURNS][0] === APPLY) {
|
940
|
+
env[first[VALUE]][STATS][RETURNS] = [UNKNOWN]
|
941
|
+
}
|
942
|
+
env[first[VALUE]][STATS][TYPE_PROP] = [APPLY]
|
936
943
|
env[first[VALUE]][STATS][ARGS_COUNT] = rest.length
|
937
944
|
}
|
938
945
|
}
|
@@ -954,7 +961,7 @@ export const typeCheck = (ast) => {
|
|
954
961
|
if (
|
955
962
|
env[rest[i][VALUE]] &&
|
956
963
|
args[i][SUB] !==
|
957
|
-
env[rest[i][VALUE]][STATS][
|
964
|
+
env[rest[i][VALUE]][STATS][RETURNS][1]
|
958
965
|
) {
|
959
966
|
errorStack.set(
|
960
967
|
key.str,
|
@@ -963,8 +970,8 @@ export const typeCheck = (ast) => {
|
|
963
970
|
}). Expected (${toTypeNames(
|
964
971
|
args[i][SUB]
|
965
972
|
)}) but got (${toTypeNames(
|
966
|
-
env[rest[i][VALUE]][STATS][
|
967
|
-
env[rest[i][VALUE]][STATS]
|
973
|
+
env[rest[i][VALUE]][STATS][RETURNS][1] ??
|
974
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0]
|
968
975
|
)}) (${stringifyArgs(exp)}) (check #16)`
|
969
976
|
)
|
970
977
|
}
|
@@ -997,7 +1004,7 @@ export const typeCheck = (ast) => {
|
|
997
1004
|
const fn = env[fnName]
|
998
1005
|
if (
|
999
1006
|
fn &&
|
1000
|
-
fn[STATS][RETURNS] !== args[i][TYPE]
|
1007
|
+
fn[STATS][RETURNS][0] !== args[i][TYPE]
|
1001
1008
|
) {
|
1002
1009
|
errorStack.set(
|
1003
1010
|
key.str,
|
@@ -1006,13 +1013,13 @@ export const typeCheck = (ast) => {
|
|
1006
1013
|
}). Expected (${toTypeNames(
|
1007
1014
|
args[i][TYPE]
|
1008
1015
|
)}) but got an (${toTypeNames(
|
1009
|
-
fn[STATS][RETURNS]
|
1016
|
+
fn[STATS][RETURNS][0]
|
1010
1017
|
)}) (${stringifyArgs(exp)}) (check #26)`
|
1011
1018
|
)
|
1012
1019
|
}
|
1013
1020
|
if (
|
1014
1021
|
fn &&
|
1015
|
-
fn[STATS][
|
1022
|
+
fn[STATS][RETURNS][1] !== args[i][SUB]
|
1016
1023
|
) {
|
1017
1024
|
errorStack.set(
|
1018
1025
|
key.str,
|
@@ -1021,14 +1028,12 @@ export const typeCheck = (ast) => {
|
|
1021
1028
|
}). Expected (${toTypeNames(
|
1022
1029
|
args[i][SUB]
|
1023
1030
|
)}) but got an (${toTypeNames(
|
1024
|
-
fn[STATS][
|
1031
|
+
fn[STATS][RETURNS][1]
|
1025
1032
|
)}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
|
1026
1033
|
exp
|
1027
1034
|
)}) (check #27)`
|
1028
1035
|
)
|
1029
1036
|
}
|
1030
|
-
// env[name][STATS].type = fn[STATS][RETURNS]
|
1031
|
-
// env[name][STATS][SUB_TYPE] = fn[STATS][SUB_TYPE]
|
1032
1037
|
} else {
|
1033
1038
|
const body = rest[i].at(-1).at(-1)
|
1034
1039
|
const rem = hasBlock(body) ? body.at(-1) : body
|
@@ -1068,7 +1073,7 @@ export const typeCheck = (ast) => {
|
|
1068
1073
|
} else if (env[returns[VALUE]]) {
|
1069
1074
|
if (
|
1070
1075
|
args[i][TYPE] !==
|
1071
|
-
env[returns[VALUE]][STATS][RETURNS]
|
1076
|
+
env[returns[VALUE]][STATS][RETURNS][0]
|
1072
1077
|
) {
|
1073
1078
|
errorStack.set(
|
1074
1079
|
key.str,
|
@@ -1084,7 +1089,7 @@ export const typeCheck = (ast) => {
|
|
1084
1089
|
if (
|
1085
1090
|
args[i][SUB] &&
|
1086
1091
|
args[i][SUB] !==
|
1087
|
-
env[returns[VALUE]][STATS][
|
1092
|
+
env[returns[VALUE]][STATS][RETURNS][1]
|
1088
1093
|
) {
|
1089
1094
|
errorStack.set(
|
1090
1095
|
key.str,
|
@@ -1093,7 +1098,7 @@ export const typeCheck = (ast) => {
|
|
1093
1098
|
}). Expected (${toTypeNames(
|
1094
1099
|
args[i][SUB]
|
1095
1100
|
)}) but got (${toTypeNames(
|
1096
|
-
env[returns[VALUE]][STATS][
|
1101
|
+
env[returns[VALUE]][STATS][RETURNS][1]
|
1097
1102
|
)}) (${stringifyArgs(exp)}) (check #28)`
|
1098
1103
|
)
|
1099
1104
|
}
|
@@ -1110,8 +1115,10 @@ export const typeCheck = (ast) => {
|
|
1110
1115
|
|
1111
1116
|
// console.log(args[i], env[current[VALUE]][STATS])
|
1112
1117
|
} else if (
|
1113
|
-
|
1114
|
-
|
1118
|
+
args[i][SUB] &&
|
1119
|
+
env[current[VALUE]] &&
|
1120
|
+
env[current[VALUE]][STATS][RETURNS][1] !==
|
1121
|
+
args[i][SUB]
|
1115
1122
|
) {
|
1116
1123
|
errorStack.set(
|
1117
1124
|
key.str,
|
@@ -1120,8 +1127,8 @@ export const typeCheck = (ast) => {
|
|
1120
1127
|
}). Expected (${toTypeNames(
|
1121
1128
|
args[i][SUB]
|
1122
1129
|
)}) but got (${toTypeNames(
|
1123
|
-
env[current[VALUE]][STATS][
|
1124
|
-
env[current[VALUE]][STATS][RETURNS]
|
1130
|
+
env[current[VALUE]][STATS][RETURNS][1] ??
|
1131
|
+
env[current[VALUE]][STATS][RETURNS][0]
|
1125
1132
|
)}) (${stringifyArgs(exp)}) (check #21)`
|
1126
1133
|
)
|
1127
1134
|
}
|
@@ -1142,13 +1149,12 @@ export const typeCheck = (ast) => {
|
|
1142
1149
|
const CAR = rest[i][0][VALUE]
|
1143
1150
|
const isKnown =
|
1144
1151
|
env[CAR] &&
|
1145
|
-
env[CAR][STATS][RETURNS]
|
1146
|
-
env[CAR][STATS][RETURNS] !== UNKNOWN
|
1152
|
+
env[CAR][STATS][RETURNS][0] !== UNKNOWN
|
1147
1153
|
if (
|
1148
1154
|
isKnown &&
|
1149
|
-
env[CAR][STATS][RETURNS] !==
|
1155
|
+
env[CAR][STATS][RETURNS][0] !==
|
1156
|
+
expectedArgs[i][TYPE]
|
1150
1157
|
) {
|
1151
|
-
// console.log(env[CAR][STATS], expectedArgs[i][TYPE])
|
1152
1158
|
errorStack.set(
|
1153
1159
|
key.str,
|
1154
1160
|
`Incorrect type of argument (${i}) for special form (${
|
@@ -1156,13 +1162,14 @@ export const typeCheck = (ast) => {
|
|
1156
1162
|
}). Expected (${toTypeNames(
|
1157
1163
|
expectedArgs[i][TYPE]
|
1158
1164
|
)}) but got (${toTypeNames(
|
1159
|
-
env[CAR][STATS][RETURNS]
|
1165
|
+
env[CAR][STATS][RETURNS][0]
|
1160
1166
|
)}) (${stringifyArgs(exp)}) (check #1)`
|
1161
1167
|
)
|
1162
1168
|
} else if (
|
1163
1169
|
isKnown &&
|
1164
1170
|
expectedArgs[i][SUB] &&
|
1165
|
-
env[CAR][STATS][
|
1171
|
+
env[CAR][STATS][RETURNS][1] !==
|
1172
|
+
expectedArgs[i][SUB]
|
1166
1173
|
) {
|
1167
1174
|
errorStack.set(
|
1168
1175
|
key.str,
|
@@ -1171,8 +1178,8 @@ export const typeCheck = (ast) => {
|
|
1171
1178
|
}). Expected (${toTypeNames(
|
1172
1179
|
expectedArgs[i][SUB]
|
1173
1180
|
)}) but got (${toTypeNames(
|
1174
|
-
env[CAR][STATS][
|
1175
|
-
env[CAR][STATS][RETURNS]
|
1181
|
+
env[CAR][STATS][RETURNS][1] ??
|
1182
|
+
env[CAR][STATS][RETURNS][0]
|
1176
1183
|
)}) (${stringifyArgs(exp)}) (check #13)`
|
1177
1184
|
)
|
1178
1185
|
}
|
@@ -1183,30 +1190,13 @@ export const typeCheck = (ast) => {
|
|
1183
1190
|
) {
|
1184
1191
|
switch (rest[i][TYPE]) {
|
1185
1192
|
case UNKNOWN:
|
1186
|
-
env[first[VALUE]][STATS]
|
1193
|
+
env[first[VALUE]][STATS][TYPE_PROP][0] =
|
1187
1194
|
expectedArgs[i][TYPE]
|
1188
1195
|
break
|
1189
1196
|
case WORD:
|
1190
|
-
const T =
|
1191
|
-
|
1192
|
-
|
1193
|
-
if (
|
1194
|
-
env[TT][STATS][RETURNS] &&
|
1195
|
-
env[TT][STATS][RETURNS] !== UNKNOWN &&
|
1196
|
-
expectedArgs[i][TYPE] !==
|
1197
|
-
env[TT][STATS][RETURNS]
|
1198
|
-
)
|
1199
|
-
errorStack.set(
|
1200
|
-
key.str,
|
1201
|
-
`Incorrect type of arguments for special form (${
|
1202
|
-
first[VALUE]
|
1203
|
-
}). Expected (${toTypeNames(
|
1204
|
-
expectedArgs[i][TYPE]
|
1205
|
-
)}) but got (${toTypeNames(
|
1206
|
-
rest[i][TYPE]
|
1207
|
-
)}) (${stringifyArgs(exp)}) (check #2)`
|
1208
|
-
)
|
1209
|
-
} else if (
|
1197
|
+
const T =
|
1198
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0]
|
1199
|
+
if (
|
1210
1200
|
T !== UNKNOWN &&
|
1211
1201
|
expectedArgs[i][TYPE] !== UNKNOWN &&
|
1212
1202
|
expectedArgs[i][TYPE] !== T
|
@@ -1222,7 +1212,7 @@ export const typeCheck = (ast) => {
|
|
1222
1212
|
)}) (${stringifyArgs(exp)}) (check #3)`
|
1223
1213
|
)
|
1224
1214
|
} else {
|
1225
|
-
env[rest[i][VALUE]][STATS]
|
1215
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
|
1226
1216
|
expectedArgs[i][TYPE]
|
1227
1217
|
}
|
1228
1218
|
break
|
@@ -1247,75 +1237,70 @@ export const typeCheck = (ast) => {
|
|
1247
1237
|
else if (
|
1248
1238
|
rest[i] &&
|
1249
1239
|
args[i][STATS] &&
|
1250
|
-
rest[i][TYPE] !== args[i][STATS]
|
1240
|
+
rest[i][TYPE] !== args[i][STATS][TYPE_PROP][0]
|
1251
1241
|
) {
|
1252
1242
|
if (isLeaf(rest[i])) {
|
1253
1243
|
const T =
|
1254
1244
|
rest[i][TYPE] === WORD && env[rest[i][VALUE]]
|
1255
|
-
? env[rest[i][VALUE]][STATS]
|
1245
|
+
? env[rest[i][VALUE]][STATS][TYPE_PROP][0]
|
1256
1246
|
: rest[i][TYPE]
|
1257
1247
|
if (
|
1258
|
-
(args[i][STATS]
|
1248
|
+
(args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
|
1259
1249
|
T === ATOM &&
|
1260
|
-
args[i][STATS]
|
1250
|
+
args[i][STATS][TYPE_PROP][0] !== ATOM) ||
|
1261
1251
|
(env[rest[i][VALUE]] &&
|
1262
|
-
env[rest[i][VALUE]][STATS]
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1252
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0] !==
|
1253
|
+
UNKNOWN &&
|
1254
|
+
args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
|
1255
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0] !==
|
1256
|
+
args[i][STATS][TYPE_PROP][0])
|
1266
1257
|
) {
|
1267
1258
|
errorStack.set(
|
1268
1259
|
key.str,
|
1269
1260
|
`Incorrect type of arguments ${i} for (${
|
1270
1261
|
first[VALUE]
|
1271
1262
|
}). Expected (${toTypeNames(
|
1272
|
-
args[i][STATS]
|
1263
|
+
args[i][STATS][TYPE_PROP][0]
|
1273
1264
|
)}) but got (${toTypeNames(T)}) (${stringifyArgs(
|
1274
1265
|
exp
|
1275
1266
|
)}) (check #30)`
|
1276
1267
|
)
|
1277
1268
|
} else {
|
1278
|
-
// env[rest[i][VALUE]][STATS] THiss SHOULD BE
|
1279
1269
|
const retry = env[rest[i][VALUE]]
|
1280
1270
|
if (
|
1281
1271
|
retry &&
|
1282
1272
|
retry[STATS].retried < RETRY_COUNT &&
|
1283
|
-
args[i][STATS]
|
1273
|
+
args[i][STATS][TYPE_PROP][0] === UNKNOWN
|
1284
1274
|
) {
|
1285
1275
|
retry[STATS].retried += 1
|
1286
1276
|
stack.unshift(() => check(exp, env, scope))
|
1287
1277
|
}
|
1288
|
-
// console.log(
|
1289
|
-
// first[VALUE],
|
1290
|
-
// env[first[VALUE]][STATS],
|
1291
|
-
// rest[i][TYPE],
|
1292
|
-
// args[i][STATS].type
|
1293
|
-
// )
|
1294
1278
|
}
|
1295
1279
|
} else if (
|
1296
1280
|
rest[i].length &&
|
1297
1281
|
SPECIAL_FORMS_SET.has(rest[i][0][VALUE]) &&
|
1298
1282
|
env[rest[i][0][VALUE]] &&
|
1299
|
-
env[rest[i][0][VALUE]][STATS][RETURNS] !==
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1283
|
+
env[rest[i][0][VALUE]][STATS][RETURNS][0] !==
|
1284
|
+
UNKNOWN &&
|
1285
|
+
args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
|
1286
|
+
env[rest[i][0][VALUE]][STATS][RETURNS][0] !==
|
1287
|
+
args[i][STATS][TYPE_PROP][0]
|
1303
1288
|
) {
|
1304
1289
|
errorStack.set(
|
1305
1290
|
key.str,
|
1306
1291
|
`Incorrect type of arguments ${i} for (${
|
1307
1292
|
first[VALUE]
|
1308
1293
|
}). Expected (${toTypeNames(
|
1309
|
-
args[i][STATS]
|
1294
|
+
args[i][STATS][TYPE_PROP][0]
|
1310
1295
|
)}) but got (${toTypeNames(
|
1311
|
-
env[rest[i][0][VALUE]][STATS][RETURNS]
|
1296
|
+
env[rest[i][0][VALUE]][STATS][RETURNS][0]
|
1312
1297
|
)}) (${stringifyArgs(exp)}) (check #4)`
|
1313
1298
|
)
|
1314
1299
|
} else {
|
1315
1300
|
if (
|
1316
1301
|
rest[i].length &&
|
1317
1302
|
env[rest[i][0][VALUE]] &&
|
1318
|
-
args[i][STATS]
|
1303
|
+
args[i][STATS][TYPE_PROP][0] === UNKNOWN &&
|
1319
1304
|
env[rest[i][0][VALUE]][STATS].retried < RETRY_COUNT
|
1320
1305
|
) {
|
1321
1306
|
env[rest[i][0][VALUE]][STATS].retried += 1
|