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/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,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][SUB_TYPE] = PREDICATE
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].type
592
- env[name][STATS][SUB_TYPE] =
593
- 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]
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 (env[returns[VALUE]][STATS].type === APPLY) {
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][SUB_TYPE] === PREDICATE
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][SUB_TYPE] !== PREDICATE
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].type = fn[STATS][RETURNS]
626
- 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]
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].type
646
- env[name][STATS][SUB_TYPE] =
647
- 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]
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][SUB_TYPE] !== PREDICATE
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][SUB_TYPE] === PREDICATE
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][SUB_TYPE] = PREDICATE
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
- type: APPLY,
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
- type: ATOM
766
+ [TYPE_PROP]: [ATOM],
767
+ [RETURNS]: [UNKNOWN]
773
768
  }
774
769
  }
775
- if (isPredicate) env[name][STATS][SUB_TYPE] = PREDICATE
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
- type: isL
791
- ? right[TYPE]
792
- : 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]
793
793
  }
794
794
  }
795
- if (isPredicate) env[name][STATS][SUB_TYPE] = PREDICATE
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][SUB_TYPE] === PREDICATE
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][SUB_TYPE] !== PREDICATE
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].type = fn[STATS][RETURNS]
817
- 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]
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]?.[SUB_TYPE]) {
837
+ if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
839
838
  if (
840
- env[right[VALUE]][STATS][SUB_TYPE] === PREDICATE &&
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][SUB_TYPE] =
850
- env[right[VALUE]][STATS][SUB_TYPE]
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]: { type: UNKNOWN, retried: 0 }
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][i] = copy[param[VALUE]]
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
- 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)
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].type === APPLY &&
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].type === ATOM) {
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
- env[first[VALUE]][STATS][RETURNS] = UNKNOWN
934
- 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]
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][SUB_TYPE]
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][SUB_TYPE] ??
966
- env[rest[i][VALUE]][STATS].type
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][SUB_TYPE] !== args[i][SUB]
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][SUB_TYPE]
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][SUB_TYPE]
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][SUB_TYPE]
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
- env[current[VALUE]][STATS][SUB_TYPE] !==
1113
- args[i][SUB]
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][SUB_TYPE] ??
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] != undefined &&
1145
- env[CAR][STATS][RETURNS] !== UNKNOWN
1152
+ env[CAR][STATS][RETURNS][0] !== UNKNOWN
1146
1153
  if (
1147
1154
  isKnown &&
1148
- env[CAR][STATS][RETURNS] !== expectedArgs[i][TYPE]
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][SUB_TYPE] !== expectedArgs[i][SUB]
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][SUB_TYPE] ??
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].type =
1193
+ env[first[VALUE]][STATS][TYPE_PROP][0] =
1186
1194
  expectedArgs[i][TYPE]
1187
1195
  break
1188
1196
  case WORD:
1189
- const T = env[rest[i][VALUE]][STATS].type
1190
- if (Array.isArray(T)) {
1191
- const TT = T[VALUE]
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].type =
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].type
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].type
1245
+ ? env[rest[i][VALUE]][STATS][TYPE_PROP][0]
1255
1246
  : rest[i][TYPE]
1256
1247
  if (
1257
- (args[i][STATS].type !== UNKNOWN &&
1248
+ (args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
1258
1249
  T === ATOM &&
1259
- args[i][STATS].type !== ATOM) ||
1250
+ args[i][STATS][TYPE_PROP][0] !== ATOM) ||
1260
1251
  (env[rest[i][VALUE]] &&
1261
- env[rest[i][VALUE]][STATS].type !== UNKNOWN &&
1262
- args[i][STATS].type !== UNKNOWN &&
1263
- env[rest[i][VALUE]][STATS].type !==
1264
- 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])
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].type
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].type === UNKNOWN
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] !== UNKNOWN &&
1299
- args[i][STATS].type !== UNKNOWN &&
1300
- env[rest[i][0][VALUE]][STATS][RETURNS] !==
1301
- 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]
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].type
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].type === UNKNOWN &&
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