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/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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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
- type: APPLY,
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][SUB_TYPE] = PREDICATE
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].type
593
- env[name][STATS][SUB_TYPE] =
594
- env[re[0][VALUE]][STATS][SUB_TYPE]
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 (env[returns[VALUE]][STATS].type === APPLY) {
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][SUB_TYPE] === PREDICATE
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][SUB_TYPE] !== PREDICATE
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].type = fn[STATS][RETURNS]
627
- env[name][STATS][SUB_TYPE] = fn[STATS][SUB_TYPE]
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].type
647
- env[name][STATS][SUB_TYPE] =
648
- env[returns[VALUE]][SUB_TYPE]
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][SUB_TYPE] !== PREDICATE
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][SUB_TYPE] === PREDICATE
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][SUB_TYPE] = PREDICATE
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
- type: APPLY,
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
- type: ATOM
766
+ [TYPE_PROP]: [ATOM],
767
+ [RETURNS]: [UNKNOWN]
774
768
  }
775
769
  }
776
- if (isPredicate) env[name][STATS][SUB_TYPE] = PREDICATE
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
- type: isL
792
- ? right[TYPE]
793
- : env[right?.[VALUE]]?.[STATS]?.[RETURNS] ?? UNKNOWN
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) env[name][STATS][SUB_TYPE] = PREDICATE
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][SUB_TYPE] === PREDICATE
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][SUB_TYPE] !== PREDICATE
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].type = fn[STATS][RETURNS]
818
- env[name][STATS][SUB_TYPE] = fn[STATS][SUB_TYPE]
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]?.[SUB_TYPE]) {
837
+ if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
840
838
  if (
841
- env[right[VALUE]][STATS][SUB_TYPE] === PREDICATE &&
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][SUB_TYPE] =
851
- env[right[VALUE]][STATS][SUB_TYPE]
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]: { type: UNKNOWN, retried: 0 }
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][i] = copy[param[VALUE]]
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
- copy[param[VALUE]][STATS][SUB_TYPE] = PREDICATE
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].type === APPLY &&
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].type === ATOM) {
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
- env[first[VALUE]][STATS][RETURNS] = UNKNOWN
935
- env[first[VALUE]][STATS].type = APPLY
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][SUB_TYPE]
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][SUB_TYPE] ??
967
- env[rest[i][VALUE]][STATS].type
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][SUB_TYPE] !== args[i][SUB]
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][SUB_TYPE]
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][SUB_TYPE]
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][SUB_TYPE]
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
- env[current[VALUE]][STATS][SUB_TYPE] !==
1114
- args[i][SUB]
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][SUB_TYPE] ??
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] != undefined &&
1146
- env[CAR][STATS][RETURNS] !== UNKNOWN
1152
+ env[CAR][STATS][RETURNS][0] !== UNKNOWN
1147
1153
  if (
1148
1154
  isKnown &&
1149
- env[CAR][STATS][RETURNS] !== expectedArgs[i][TYPE]
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][SUB_TYPE] !== expectedArgs[i][SUB]
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][SUB_TYPE] ??
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].type =
1193
+ env[first[VALUE]][STATS][TYPE_PROP][0] =
1187
1194
  expectedArgs[i][TYPE]
1188
1195
  break
1189
1196
  case WORD:
1190
- const T = env[rest[i][VALUE]][STATS].type
1191
- if (Array.isArray(T)) {
1192
- const TT = T[VALUE]
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].type =
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].type
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].type
1245
+ ? env[rest[i][VALUE]][STATS][TYPE_PROP][0]
1256
1246
  : rest[i][TYPE]
1257
1247
  if (
1258
- (args[i][STATS].type !== UNKNOWN &&
1248
+ (args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
1259
1249
  T === ATOM &&
1260
- args[i][STATS].type !== ATOM) ||
1250
+ args[i][STATS][TYPE_PROP][0] !== ATOM) ||
1261
1251
  (env[rest[i][VALUE]] &&
1262
- env[rest[i][VALUE]][STATS].type !== UNKNOWN &&
1263
- args[i][STATS].type !== UNKNOWN &&
1264
- env[rest[i][VALUE]][STATS].type !==
1265
- args[i][STATS].type)
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].type
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].type === UNKNOWN
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] !== UNKNOWN &&
1300
- args[i][STATS].type !== UNKNOWN &&
1301
- env[rest[i][0][VALUE]][STATS][RETURNS] !==
1302
- args[i][STATS].type
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].type
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].type === UNKNOWN &&
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