fez-lisp 1.5.44 → 1.5.46
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 +236 -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,28 +532,33 @@ 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:
|
542
539
|
{
|
543
540
|
const re = rem.slice(2)
|
541
|
+
// If either is an ATOM then IF returns an ATOM
|
544
542
|
if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
|
545
|
-
env[name][STATS][prop] = ATOM
|
543
|
+
env[name][STATS][prop][0] = ATOM
|
546
544
|
// if (
|
547
545
|
// re[0][VALUE] === FALSE ||
|
548
546
|
// re[0][VALUE] === TRUE ||
|
549
547
|
// re[1][VALUE] === FALSE ||
|
550
548
|
// re[1][VALUE] === TRUE
|
551
549
|
// ) {
|
552
|
-
// env[name][STATS][
|
550
|
+
// env[name][STATS][RETURNS][1] = PREDICATE
|
553
551
|
// }
|
554
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
|
+
|
555
560
|
env[name][STATS][prop] =
|
556
561
|
env[re[0][0][VALUE]][STATS][RETURNS]
|
557
|
-
env[name][STATS][SUB_TYPE] =
|
558
|
-
env[re[0][0][VALUE]][STATS][SUB_TYPE]
|
559
|
-
|
560
562
|
if (
|
561
563
|
re[0][0][TYPE] === APPLY &&
|
562
564
|
// turn off typechecks for optimized functions
|
@@ -569,7 +571,7 @@ export const typeCheck = (ast) => {
|
|
569
571
|
// env[name][STATS][SUB_TYPE] =
|
570
572
|
// env[re[0][0][VALUE]][STATS][SUB_TYPE]
|
571
573
|
|
572
|
-
env[name][STATS][RETURNS] = UNKNOWN
|
574
|
+
env[name][STATS][RETURNS] = [UNKNOWN]
|
573
575
|
env[name][STATS][ARGS_COUNT] =
|
574
576
|
re[0].length - 2
|
575
577
|
// check(
|
@@ -587,14 +589,14 @@ export const typeCheck = (ast) => {
|
|
587
589
|
// env[name][STATS] = env[re[0][0][VALUE]][STATS]
|
588
590
|
} else {
|
589
591
|
if (env[re[0][VALUE]]) {
|
590
|
-
env[name][STATS][prop] =
|
591
|
-
env[re[0][VALUE]][STATS]
|
592
|
-
env[name][STATS][
|
593
|
-
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]
|
594
596
|
// env[name][STATS] = env[name][STATS]
|
595
597
|
// env[re[0][VALUE]][STATS][SUB_TYPE]
|
596
598
|
} else {
|
597
|
-
env[name][STATS][prop] = UNKNOWN
|
599
|
+
env[name][STATS][prop] = [UNKNOWN]
|
598
600
|
// env[name][STATS][RETURNS] = APPLY
|
599
601
|
}
|
600
602
|
}
|
@@ -602,32 +604,41 @@ export const typeCheck = (ast) => {
|
|
602
604
|
break
|
603
605
|
default:
|
604
606
|
if (env[returns[VALUE]]) {
|
605
|
-
if (
|
607
|
+
if (
|
608
|
+
env[returns[VALUE]][STATS][TYPE_PROP][0] === APPLY
|
609
|
+
) {
|
606
610
|
if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
|
607
611
|
if (isLeaf(rest.at(-1).at(-1).at(-1))) {
|
608
612
|
const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
|
609
613
|
const fn = env[fnName]
|
610
614
|
if (
|
611
615
|
!isPredicate &&
|
612
|
-
fn[STATS][
|
616
|
+
fn[STATS][RETURNS][1] === PREDICATE
|
613
617
|
) {
|
614
618
|
warningStack.add(
|
615
619
|
`${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
|
616
620
|
)
|
617
621
|
} else if (
|
618
622
|
isPredicate &&
|
619
|
-
fn[STATS][
|
623
|
+
fn[STATS][RETURNS][1] !== PREDICATE
|
620
624
|
) {
|
621
625
|
warningStack.add(
|
622
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)`
|
623
627
|
)
|
624
628
|
}
|
625
|
-
env[name][STATS]
|
626
|
-
|
629
|
+
env[name][STATS][TYPE_PROP][0] =
|
630
|
+
fn[STATS][RETURNS][0]
|
631
|
+
env[name][STATS][RETURNS][1] =
|
632
|
+
fn[STATS][RETURNS][1]
|
627
633
|
} else {
|
628
|
-
const body = rest.at(-1).at(-1).at(-1).at(-1)
|
629
|
-
const rem = hasBlock(body) ? body.at(-1) : body
|
630
|
-
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
|
+
)
|
631
642
|
resolveRetunType(
|
632
643
|
returns,
|
633
644
|
rem,
|
@@ -638,16 +649,14 @@ export const typeCheck = (ast) => {
|
|
638
649
|
}
|
639
650
|
env[name][STATS][RETURNS] =
|
640
651
|
env[returns[VALUE]][STATS][RETURNS]
|
641
|
-
env[name][STATS][SUB_TYPE] =
|
642
|
-
env[returns[VALUE]][STATS][SUB_TYPE]
|
643
652
|
} else {
|
644
653
|
env[name][STATS][RETURNS] =
|
645
|
-
env[returns[VALUE]][STATS]
|
646
|
-
env[name][STATS][
|
647
|
-
env[returns[VALUE]][
|
654
|
+
env[returns[VALUE]][STATS][RETURNS]
|
655
|
+
env[name][STATS][RETURNS][0] =
|
656
|
+
env[returns[VALUE]][STATS][TYPE_PROP][0]
|
648
657
|
}
|
649
658
|
} else {
|
650
|
-
env[name][STATS][RETURNS] = UNKNOWN
|
659
|
+
env[name][STATS][RETURNS] = [UNKNOWN]
|
651
660
|
// env[name][STATS][RETURNS] = APPLY
|
652
661
|
}
|
653
662
|
break
|
@@ -655,34 +664,27 @@ export const typeCheck = (ast) => {
|
|
655
664
|
}
|
656
665
|
if (
|
657
666
|
isPredicate &&
|
658
|
-
env[name][STATS][prop] !== UNKNOWN &&
|
659
|
-
env[name][STATS][
|
667
|
+
env[name][STATS][prop][0] !== UNKNOWN &&
|
668
|
+
env[name][STATS][RETURNS][1] !== PREDICATE
|
660
669
|
) {
|
661
670
|
warningStack.add(
|
662
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)`
|
663
672
|
)
|
664
673
|
} else if (
|
665
674
|
!isPredicate &&
|
666
|
-
env[name][STATS][
|
675
|
+
env[name][STATS][RETURNS][1] === PREDICATE
|
667
676
|
) {
|
668
677
|
warningStack.add(
|
669
678
|
`${name} should end in (${PREDICATE_SUFFIX}) because it return (Predicate) (try adding ? at the end of the lambda name) (check #8)`
|
670
679
|
)
|
671
680
|
}
|
672
681
|
if (isPredicate) {
|
673
|
-
env[name][STATS][prop] = ATOM
|
674
|
-
env[name][STATS][
|
682
|
+
env[name][STATS][prop] = [ATOM]
|
683
|
+
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
675
684
|
}
|
676
685
|
}
|
677
686
|
const checkReturnType = () => {
|
678
|
-
// if (name[name.length - 1] === PREDICATE_SUFFIX) {
|
679
|
-
// env[name][STATS][RETURNS] = ATOM
|
680
|
-
// env[name][STATS][SUB_TYPE] = PREDICATE
|
681
|
-
// } else {
|
682
687
|
const last = rest.at(-1).at(-1)
|
683
|
-
// const isApplyLambdaDoBlock = hasApplyLambdaBlock(
|
684
|
-
// rest.at(-1)
|
685
|
-
// )
|
686
688
|
const body = hasApplyLambdaBlock(last)
|
687
689
|
? last.at(-1).at(-1)
|
688
690
|
: last
|
@@ -690,15 +692,6 @@ export const typeCheck = (ast) => {
|
|
690
692
|
const returns = isLeaf(rem) ? rem : rem[0]
|
691
693
|
const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
|
692
694
|
resolveRetunType(returns, rem, RETURNS, isPredicate)
|
693
|
-
// }
|
694
|
-
// if (
|
695
|
-
// env[name][STATS][RETURNS] === UNKNOWN &&
|
696
|
-
// env[name][STATS].retried < RETRY_COUNT
|
697
|
-
// ) {
|
698
|
-
// env[name][STATS].retried += 1
|
699
|
-
// console.log(name, env[name][STATS])
|
700
|
-
// checkReturnType()
|
701
|
-
// }
|
702
695
|
}
|
703
696
|
if (
|
704
697
|
rest.at(-1) &&
|
@@ -709,16 +702,17 @@ export const typeCheck = (ast) => {
|
|
709
702
|
const n = rest.at(-1).length
|
710
703
|
env[name] = {
|
711
704
|
[STATS]: {
|
712
|
-
|
705
|
+
[TYPE_PROP]: [APPLY],
|
713
706
|
retried: 0,
|
714
707
|
[ARGS_COUNT]: n - 2,
|
715
|
-
[ARGS]: []
|
708
|
+
[ARGS]: [],
|
709
|
+
[RETURNS]: [UNKNOWN]
|
716
710
|
}
|
717
711
|
}
|
718
712
|
|
719
713
|
checkReturnType()
|
720
714
|
if (
|
721
|
-
env[name][STATS][RETURNS] === UNKNOWN &&
|
715
|
+
env[name][STATS][RETURNS][0] === UNKNOWN &&
|
722
716
|
env[name][STATS].retried < DEFINITON_RETRY_COUNT
|
723
717
|
) {
|
724
718
|
env[name][STATS].retried += 1
|
@@ -769,10 +763,12 @@ export const typeCheck = (ast) => {
|
|
769
763
|
env[name] = {
|
770
764
|
[STATS]: {
|
771
765
|
retried: 0,
|
772
|
-
|
766
|
+
[TYPE_PROP]: [ATOM],
|
767
|
+
[RETURNS]: [UNKNOWN]
|
773
768
|
}
|
774
769
|
}
|
775
|
-
if (isPredicate)
|
770
|
+
if (isPredicate)
|
771
|
+
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
776
772
|
} else {
|
777
773
|
const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
|
778
774
|
if (
|
@@ -787,12 +783,17 @@ export const typeCheck = (ast) => {
|
|
787
783
|
env[name] = {
|
788
784
|
[STATS]: {
|
789
785
|
retried: 0,
|
790
|
-
|
791
|
-
|
792
|
-
|
786
|
+
[TYPE_PROP]: [
|
787
|
+
isL
|
788
|
+
? right[TYPE]
|
789
|
+
: env[right?.[VALUE]]?.[STATS]?.[RETURNS]?.[0] ??
|
790
|
+
UNKNOWN
|
791
|
+
],
|
792
|
+
[RETURNS]: [UNKNOWN]
|
793
793
|
}
|
794
794
|
}
|
795
|
-
if (isPredicate)
|
795
|
+
if (isPredicate)
|
796
|
+
env[name][STATS][RETURNS] = [ATOM, PREDICATE]
|
796
797
|
if (right && right[VALUE]) {
|
797
798
|
if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
|
798
799
|
if (isLeaf(rest.at(-1).at(-1))) {
|
@@ -800,21 +801,21 @@ export const typeCheck = (ast) => {
|
|
800
801
|
const fn = env[fnName]
|
801
802
|
if (
|
802
803
|
!isPredicate &&
|
803
|
-
fn[STATS][
|
804
|
+
fn[STATS][RETURNS][1] === PREDICATE
|
804
805
|
) {
|
805
806
|
warningStack.add(
|
806
807
|
`${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
|
807
808
|
)
|
808
809
|
} else if (
|
809
810
|
isPredicate &&
|
810
|
-
fn[STATS][
|
811
|
+
fn[STATS][RETURNS][1] !== PREDICATE
|
811
812
|
) {
|
812
813
|
warningStack.add(
|
813
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)`
|
814
815
|
)
|
815
816
|
}
|
816
|
-
env[name][STATS]
|
817
|
-
env[name][STATS][
|
817
|
+
env[name][STATS][TYPE_PROP] = fn[STATS][RETURNS]
|
818
|
+
env[name][STATS][RETURNS] = fn[STATS][RETURNS]
|
818
819
|
} else {
|
819
820
|
const body = rest.at(-1).at(-1).at(-1)
|
820
821
|
const rem = hasBlock(body) ? body.at(-1) : body
|
@@ -828,16 +829,15 @@ export const typeCheck = (ast) => {
|
|
828
829
|
)
|
829
830
|
}
|
830
831
|
} else {
|
831
|
-
// TIODO finish this
|
832
832
|
const body = rest.at(-1)
|
833
833
|
const rem = hasBlock(body) ? body.at(-1) : body
|
834
834
|
const returns = isLeaf(rem) ? rem : rem[0]
|
835
835
|
resolveRetunType(returns, rem, TYPE_PROP, isPredicate)
|
836
|
-
// console.log({ name })
|
837
836
|
}
|
838
|
-
if (env[right[VALUE]]?.[STATS]?.[
|
837
|
+
if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
|
839
838
|
if (
|
840
|
-
env[right[VALUE]][STATS][
|
839
|
+
env[right[VALUE]][STATS][RETURNS][1] ===
|
840
|
+
PREDICATE &&
|
841
841
|
!isPredicate
|
842
842
|
) {
|
843
843
|
warningStack.add(
|
@@ -846,13 +846,11 @@ export const typeCheck = (ast) => {
|
|
846
846
|
)}) so ${name} must end in (${PREDICATE_SUFFIX}) (check #23)`
|
847
847
|
)
|
848
848
|
}
|
849
|
-
env[name][STATS][
|
850
|
-
env[right[VALUE]][STATS][
|
849
|
+
env[name][STATS][RETURNS] =
|
850
|
+
env[right[VALUE]][STATS][RETURNS]
|
851
851
|
}
|
852
852
|
}
|
853
853
|
}
|
854
|
-
|
855
|
-
// console.log(name, env[name])
|
856
854
|
}
|
857
855
|
// }
|
858
856
|
check(rest.at(-1), env, scope)
|
@@ -881,13 +879,20 @@ export const typeCheck = (ast) => {
|
|
881
879
|
for (let i = 0; i < params.length; ++i) {
|
882
880
|
const param = params[i]
|
883
881
|
copy[param[VALUE]] = {
|
884
|
-
[STATS]: {
|
882
|
+
[STATS]: {
|
883
|
+
[TYPE_PROP]: [UNKNOWN],
|
884
|
+
[RETURNS]: [UNKNOWN],
|
885
|
+
retried: 0
|
886
|
+
}
|
885
887
|
}
|
886
888
|
if (env[copy[SCOPE_NAME]]) {
|
887
|
-
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]]
|
888
891
|
if (getSuffix(param[VALUE]) === PREDICATE_SUFFIX) {
|
889
|
-
copy[param[VALUE]][STATS][RETURNS] = ATOM
|
890
|
-
|
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)
|
891
896
|
}
|
892
897
|
}
|
893
898
|
}
|
@@ -904,7 +909,7 @@ export const typeCheck = (ast) => {
|
|
904
909
|
)
|
905
910
|
else {
|
906
911
|
if (
|
907
|
-
env[first[VALUE]][STATS]
|
912
|
+
env[first[VALUE]][STATS][TYPE_PROP][0] === APPLY &&
|
908
913
|
env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC &&
|
909
914
|
env[first[VALUE]][STATS][ARGS_COUNT] !== rest.length
|
910
915
|
) {
|
@@ -922,7 +927,7 @@ export const typeCheck = (ast) => {
|
|
922
927
|
const isSpecial = SPECIAL_FORMS_SET.has(first[VALUE])
|
923
928
|
|
924
929
|
if (first[TYPE] === APPLY && !isSpecial) {
|
925
|
-
if (env[first[VALUE]][STATS]
|
930
|
+
if (env[first[VALUE]][STATS][TYPE_PROP][0] === ATOM) {
|
926
931
|
errorStack.set(
|
927
932
|
key.str,
|
928
933
|
`(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
|
@@ -930,8 +935,11 @@ export const typeCheck = (ast) => {
|
|
930
935
|
)}) (check #12)`
|
931
936
|
)
|
932
937
|
} else if (!env[first[VALUE]][STATS][ARGS_COUNT]) {
|
933
|
-
|
934
|
-
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]
|
935
943
|
env[first[VALUE]][STATS][ARGS_COUNT] = rest.length
|
936
944
|
}
|
937
945
|
}
|
@@ -953,7 +961,7 @@ export const typeCheck = (ast) => {
|
|
953
961
|
if (
|
954
962
|
env[rest[i][VALUE]] &&
|
955
963
|
args[i][SUB] !==
|
956
|
-
env[rest[i][VALUE]][STATS][
|
964
|
+
env[rest[i][VALUE]][STATS][RETURNS][1]
|
957
965
|
) {
|
958
966
|
errorStack.set(
|
959
967
|
key.str,
|
@@ -962,8 +970,8 @@ export const typeCheck = (ast) => {
|
|
962
970
|
}). Expected (${toTypeNames(
|
963
971
|
args[i][SUB]
|
964
972
|
)}) but got (${toTypeNames(
|
965
|
-
env[rest[i][VALUE]][STATS][
|
966
|
-
env[rest[i][VALUE]][STATS]
|
973
|
+
env[rest[i][VALUE]][STATS][RETURNS][1] ??
|
974
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0]
|
967
975
|
)}) (${stringifyArgs(exp)}) (check #16)`
|
968
976
|
)
|
969
977
|
}
|
@@ -996,7 +1004,7 @@ export const typeCheck = (ast) => {
|
|
996
1004
|
const fn = env[fnName]
|
997
1005
|
if (
|
998
1006
|
fn &&
|
999
|
-
fn[STATS][RETURNS] !== args[i][TYPE]
|
1007
|
+
fn[STATS][RETURNS][0] !== args[i][TYPE]
|
1000
1008
|
) {
|
1001
1009
|
errorStack.set(
|
1002
1010
|
key.str,
|
@@ -1005,13 +1013,13 @@ export const typeCheck = (ast) => {
|
|
1005
1013
|
}). Expected (${toTypeNames(
|
1006
1014
|
args[i][TYPE]
|
1007
1015
|
)}) but got an (${toTypeNames(
|
1008
|
-
fn[STATS][RETURNS]
|
1016
|
+
fn[STATS][RETURNS][0]
|
1009
1017
|
)}) (${stringifyArgs(exp)}) (check #26)`
|
1010
1018
|
)
|
1011
1019
|
}
|
1012
1020
|
if (
|
1013
1021
|
fn &&
|
1014
|
-
fn[STATS][
|
1022
|
+
fn[STATS][RETURNS][1] !== args[i][SUB]
|
1015
1023
|
) {
|
1016
1024
|
errorStack.set(
|
1017
1025
|
key.str,
|
@@ -1020,14 +1028,12 @@ export const typeCheck = (ast) => {
|
|
1020
1028
|
}). Expected (${toTypeNames(
|
1021
1029
|
args[i][SUB]
|
1022
1030
|
)}) but got an (${toTypeNames(
|
1023
|
-
fn[STATS][
|
1031
|
+
fn[STATS][RETURNS][1]
|
1024
1032
|
)}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
|
1025
1033
|
exp
|
1026
1034
|
)}) (check #27)`
|
1027
1035
|
)
|
1028
1036
|
}
|
1029
|
-
// env[name][STATS].type = fn[STATS][RETURNS]
|
1030
|
-
// env[name][STATS][SUB_TYPE] = fn[STATS][SUB_TYPE]
|
1031
1037
|
} else {
|
1032
1038
|
const body = rest[i].at(-1).at(-1)
|
1033
1039
|
const rem = hasBlock(body) ? body.at(-1) : body
|
@@ -1067,7 +1073,7 @@ export const typeCheck = (ast) => {
|
|
1067
1073
|
} else if (env[returns[VALUE]]) {
|
1068
1074
|
if (
|
1069
1075
|
args[i][TYPE] !==
|
1070
|
-
env[returns[VALUE]][STATS][RETURNS]
|
1076
|
+
env[returns[VALUE]][STATS][RETURNS][0]
|
1071
1077
|
) {
|
1072
1078
|
errorStack.set(
|
1073
1079
|
key.str,
|
@@ -1083,7 +1089,7 @@ export const typeCheck = (ast) => {
|
|
1083
1089
|
if (
|
1084
1090
|
args[i][SUB] &&
|
1085
1091
|
args[i][SUB] !==
|
1086
|
-
env[returns[VALUE]][STATS][
|
1092
|
+
env[returns[VALUE]][STATS][RETURNS][1]
|
1087
1093
|
) {
|
1088
1094
|
errorStack.set(
|
1089
1095
|
key.str,
|
@@ -1092,7 +1098,7 @@ export const typeCheck = (ast) => {
|
|
1092
1098
|
}). Expected (${toTypeNames(
|
1093
1099
|
args[i][SUB]
|
1094
1100
|
)}) but got (${toTypeNames(
|
1095
|
-
env[returns[VALUE]][STATS][
|
1101
|
+
env[returns[VALUE]][STATS][RETURNS][1]
|
1096
1102
|
)}) (${stringifyArgs(exp)}) (check #28)`
|
1097
1103
|
)
|
1098
1104
|
}
|
@@ -1109,8 +1115,10 @@ export const typeCheck = (ast) => {
|
|
1109
1115
|
|
1110
1116
|
// console.log(args[i], env[current[VALUE]][STATS])
|
1111
1117
|
} else if (
|
1112
|
-
|
1113
|
-
|
1118
|
+
args[i][SUB] &&
|
1119
|
+
env[current[VALUE]] &&
|
1120
|
+
env[current[VALUE]][STATS][RETURNS][1] !==
|
1121
|
+
args[i][SUB]
|
1114
1122
|
) {
|
1115
1123
|
errorStack.set(
|
1116
1124
|
key.str,
|
@@ -1119,8 +1127,8 @@ export const typeCheck = (ast) => {
|
|
1119
1127
|
}). Expected (${toTypeNames(
|
1120
1128
|
args[i][SUB]
|
1121
1129
|
)}) but got (${toTypeNames(
|
1122
|
-
env[current[VALUE]][STATS][
|
1123
|
-
env[current[VALUE]][STATS][RETURNS]
|
1130
|
+
env[current[VALUE]][STATS][RETURNS][1] ??
|
1131
|
+
env[current[VALUE]][STATS][RETURNS][0]
|
1124
1132
|
)}) (${stringifyArgs(exp)}) (check #21)`
|
1125
1133
|
)
|
1126
1134
|
}
|
@@ -1141,13 +1149,12 @@ export const typeCheck = (ast) => {
|
|
1141
1149
|
const CAR = rest[i][0][VALUE]
|
1142
1150
|
const isKnown =
|
1143
1151
|
env[CAR] &&
|
1144
|
-
env[CAR][STATS][RETURNS]
|
1145
|
-
env[CAR][STATS][RETURNS] !== UNKNOWN
|
1152
|
+
env[CAR][STATS][RETURNS][0] !== UNKNOWN
|
1146
1153
|
if (
|
1147
1154
|
isKnown &&
|
1148
|
-
env[CAR][STATS][RETURNS] !==
|
1155
|
+
env[CAR][STATS][RETURNS][0] !==
|
1156
|
+
expectedArgs[i][TYPE]
|
1149
1157
|
) {
|
1150
|
-
// console.log(env[CAR][STATS], expectedArgs[i][TYPE])
|
1151
1158
|
errorStack.set(
|
1152
1159
|
key.str,
|
1153
1160
|
`Incorrect type of argument (${i}) for special form (${
|
@@ -1155,13 +1162,14 @@ export const typeCheck = (ast) => {
|
|
1155
1162
|
}). Expected (${toTypeNames(
|
1156
1163
|
expectedArgs[i][TYPE]
|
1157
1164
|
)}) but got (${toTypeNames(
|
1158
|
-
env[CAR][STATS][RETURNS]
|
1165
|
+
env[CAR][STATS][RETURNS][0]
|
1159
1166
|
)}) (${stringifyArgs(exp)}) (check #1)`
|
1160
1167
|
)
|
1161
1168
|
} else if (
|
1162
1169
|
isKnown &&
|
1163
1170
|
expectedArgs[i][SUB] &&
|
1164
|
-
env[CAR][STATS][
|
1171
|
+
env[CAR][STATS][RETURNS][1] !==
|
1172
|
+
expectedArgs[i][SUB]
|
1165
1173
|
) {
|
1166
1174
|
errorStack.set(
|
1167
1175
|
key.str,
|
@@ -1170,8 +1178,8 @@ export const typeCheck = (ast) => {
|
|
1170
1178
|
}). Expected (${toTypeNames(
|
1171
1179
|
expectedArgs[i][SUB]
|
1172
1180
|
)}) but got (${toTypeNames(
|
1173
|
-
env[CAR][STATS][
|
1174
|
-
env[CAR][STATS][RETURNS]
|
1181
|
+
env[CAR][STATS][RETURNS][1] ??
|
1182
|
+
env[CAR][STATS][RETURNS][0]
|
1175
1183
|
)}) (${stringifyArgs(exp)}) (check #13)`
|
1176
1184
|
)
|
1177
1185
|
}
|
@@ -1182,30 +1190,13 @@ export const typeCheck = (ast) => {
|
|
1182
1190
|
) {
|
1183
1191
|
switch (rest[i][TYPE]) {
|
1184
1192
|
case UNKNOWN:
|
1185
|
-
env[first[VALUE]][STATS]
|
1193
|
+
env[first[VALUE]][STATS][TYPE_PROP][0] =
|
1186
1194
|
expectedArgs[i][TYPE]
|
1187
1195
|
break
|
1188
1196
|
case WORD:
|
1189
|
-
const T =
|
1190
|
-
|
1191
|
-
|
1192
|
-
if (
|
1193
|
-
env[TT][STATS][RETURNS] &&
|
1194
|
-
env[TT][STATS][RETURNS] !== UNKNOWN &&
|
1195
|
-
expectedArgs[i][TYPE] !==
|
1196
|
-
env[TT][STATS][RETURNS]
|
1197
|
-
)
|
1198
|
-
errorStack.set(
|
1199
|
-
key.str,
|
1200
|
-
`Incorrect type of arguments for special form (${
|
1201
|
-
first[VALUE]
|
1202
|
-
}). Expected (${toTypeNames(
|
1203
|
-
expectedArgs[i][TYPE]
|
1204
|
-
)}) but got (${toTypeNames(
|
1205
|
-
rest[i][TYPE]
|
1206
|
-
)}) (${stringifyArgs(exp)}) (check #2)`
|
1207
|
-
)
|
1208
|
-
} else if (
|
1197
|
+
const T =
|
1198
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0]
|
1199
|
+
if (
|
1209
1200
|
T !== UNKNOWN &&
|
1210
1201
|
expectedArgs[i][TYPE] !== UNKNOWN &&
|
1211
1202
|
expectedArgs[i][TYPE] !== T
|
@@ -1221,7 +1212,7 @@ export const typeCheck = (ast) => {
|
|
1221
1212
|
)}) (${stringifyArgs(exp)}) (check #3)`
|
1222
1213
|
)
|
1223
1214
|
} else {
|
1224
|
-
env[rest[i][VALUE]][STATS]
|
1215
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
|
1225
1216
|
expectedArgs[i][TYPE]
|
1226
1217
|
}
|
1227
1218
|
break
|
@@ -1246,75 +1237,70 @@ export const typeCheck = (ast) => {
|
|
1246
1237
|
else if (
|
1247
1238
|
rest[i] &&
|
1248
1239
|
args[i][STATS] &&
|
1249
|
-
rest[i][TYPE] !== args[i][STATS]
|
1240
|
+
rest[i][TYPE] !== args[i][STATS][TYPE_PROP][0]
|
1250
1241
|
) {
|
1251
1242
|
if (isLeaf(rest[i])) {
|
1252
1243
|
const T =
|
1253
1244
|
rest[i][TYPE] === WORD && env[rest[i][VALUE]]
|
1254
|
-
? env[rest[i][VALUE]][STATS]
|
1245
|
+
? env[rest[i][VALUE]][STATS][TYPE_PROP][0]
|
1255
1246
|
: rest[i][TYPE]
|
1256
1247
|
if (
|
1257
|
-
(args[i][STATS]
|
1248
|
+
(args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
|
1258
1249
|
T === ATOM &&
|
1259
|
-
args[i][STATS]
|
1250
|
+
args[i][STATS][TYPE_PROP][0] !== ATOM) ||
|
1260
1251
|
(env[rest[i][VALUE]] &&
|
1261
|
-
env[rest[i][VALUE]][STATS]
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
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])
|
1265
1257
|
) {
|
1266
1258
|
errorStack.set(
|
1267
1259
|
key.str,
|
1268
1260
|
`Incorrect type of arguments ${i} for (${
|
1269
1261
|
first[VALUE]
|
1270
1262
|
}). Expected (${toTypeNames(
|
1271
|
-
args[i][STATS]
|
1263
|
+
args[i][STATS][TYPE_PROP][0]
|
1272
1264
|
)}) but got (${toTypeNames(T)}) (${stringifyArgs(
|
1273
1265
|
exp
|
1274
1266
|
)}) (check #30)`
|
1275
1267
|
)
|
1276
1268
|
} else {
|
1277
|
-
// env[rest[i][VALUE]][STATS] THiss SHOULD BE
|
1278
1269
|
const retry = env[rest[i][VALUE]]
|
1279
1270
|
if (
|
1280
1271
|
retry &&
|
1281
1272
|
retry[STATS].retried < RETRY_COUNT &&
|
1282
|
-
args[i][STATS]
|
1273
|
+
args[i][STATS][TYPE_PROP][0] === UNKNOWN
|
1283
1274
|
) {
|
1284
1275
|
retry[STATS].retried += 1
|
1285
1276
|
stack.unshift(() => check(exp, env, scope))
|
1286
1277
|
}
|
1287
|
-
// console.log(
|
1288
|
-
// first[VALUE],
|
1289
|
-
// env[first[VALUE]][STATS],
|
1290
|
-
// rest[i][TYPE],
|
1291
|
-
// args[i][STATS].type
|
1292
|
-
// )
|
1293
1278
|
}
|
1294
1279
|
} else if (
|
1295
1280
|
rest[i].length &&
|
1296
1281
|
SPECIAL_FORMS_SET.has(rest[i][0][VALUE]) &&
|
1297
1282
|
env[rest[i][0][VALUE]] &&
|
1298
|
-
env[rest[i][0][VALUE]][STATS][RETURNS] !==
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
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]
|
1302
1288
|
) {
|
1303
1289
|
errorStack.set(
|
1304
1290
|
key.str,
|
1305
1291
|
`Incorrect type of arguments ${i} for (${
|
1306
1292
|
first[VALUE]
|
1307
1293
|
}). Expected (${toTypeNames(
|
1308
|
-
args[i][STATS]
|
1294
|
+
args[i][STATS][TYPE_PROP][0]
|
1309
1295
|
)}) but got (${toTypeNames(
|
1310
|
-
env[rest[i][0][VALUE]][STATS][RETURNS]
|
1296
|
+
env[rest[i][0][VALUE]][STATS][RETURNS][0]
|
1311
1297
|
)}) (${stringifyArgs(exp)}) (check #4)`
|
1312
1298
|
)
|
1313
1299
|
} else {
|
1314
1300
|
if (
|
1315
1301
|
rest[i].length &&
|
1316
1302
|
env[rest[i][0][VALUE]] &&
|
1317
|
-
args[i][STATS]
|
1303
|
+
args[i][STATS][TYPE_PROP][0] === UNKNOWN &&
|
1318
1304
|
env[rest[i][0][VALUE]][STATS].retried < RETRY_COUNT
|
1319
1305
|
) {
|
1320
1306
|
env[rest[i][0][VALUE]][STATS].retried += 1
|