fez-lisp 1.5.84 → 1.5.86

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
@@ -1,16 +1,12 @@
1
1
  import {
2
2
  APPLY,
3
3
  ATOM,
4
- DEBUG,
5
- FALSE,
6
4
  KEYWORDS,
7
- MUTATION_SUFFIX,
8
5
  PLACEHOLDER,
9
- PREDICATE_SUFFIX,
6
+ PREDICATES_SET,
10
7
  SPECIAL_FORMS_SET,
11
8
  STATIC_TYPES,
12
9
  STATIC_TYPES_SET,
13
- TRUE,
14
10
  TYPE,
15
11
  VALUE,
16
12
  WORD
@@ -28,19 +24,13 @@ import {
28
24
  SCOPE_NAME,
29
25
  TYPE_PROP,
30
26
  SIGNATURE,
31
- PREDICATE,
32
- COLLECTION,
33
27
  MAX_RETRY_DEFINITION,
34
28
  MAX_ARGUMENT_RETRY,
35
29
  ORDER,
36
- VARIABLE_ORDER_INDEX
30
+ VARIABLE_ORDER_INDEX,
31
+ COLLECTION
37
32
  } from './types.js'
38
- import {
39
- getSuffix,
40
- hasApplyLambdaBlock,
41
- hasBlock,
42
- stringifyArgs
43
- } from './utils.js'
33
+ import { hasApplyLambdaBlock, hasBlock, stringifyArgs } from './utils.js'
44
34
 
45
35
  export const identity = (name) => [
46
36
  [0, 'let'],
@@ -94,18 +84,15 @@ export const formatType = (name, env) => {
94
84
  `${
95
85
  x[STATS][TYPE_PROP][0] === APPLY
96
86
  ? `${formatType(i, stats[ARGUMENTS])}`
97
- : `${toTypeNames(
98
- x[STATS][TYPE_PROP][1] ?? x[STATS][TYPE_PROP][0]
99
- )}`
87
+ : `${toTypeNames(x[STATS][TYPE_PROP][0])}`
100
88
  }`
101
89
  )
102
90
  .join(' ')
103
- } (${KEYWORDS.BLOCK} ${toTypeNames(
104
- stats[RETURNS][1] ?? stats[RETURNS][0]
105
- )})${isAnonymous ? '' : ')'})`
106
- : `(let ${name} ${toTypeNames(
107
- stats[TYPE_PROP][1] ?? stats[TYPE_PROP][0]
108
- )})`
91
+ // TODO format returned functions when type support is added
92
+ } (${KEYWORDS.BLOCK} ${toTypeNames(stats[RETURNS][0])})${
93
+ isAnonymous ? '' : ')'
94
+ })`
95
+ : `(let ${name} ${toTypeNames(stats[TYPE_PROP][0])})`
109
96
  : name
110
97
  }
111
98
  const formatTypes = (env) => {
@@ -157,37 +144,6 @@ export const typeCheck = (ast) => {
157
144
  errorStack.add(
158
145
  `Trying to access undefined variable ${first[VALUE]} (check #11)`
159
146
  )
160
- } else {
161
- const T = env[first[VALUE]][STATS]
162
- const isKnown = T[TYPE_PROP][0] !== UNKNOWN
163
- switch (first[VALUE]) {
164
- case 'xs':
165
- case 'arr':
166
- case 'matrix':
167
- case 'table':
168
- if (isKnown && T[TYPE_PROP][0] !== COLLECTION) {
169
- warningStack.add(
170
- `A variable named ${first[VALUE]} must be of type (${
171
- STATIC_TYPES.COLLECTION
172
- }) but got type (${toTypeNames(
173
- T[TYPE_PROP][0]
174
- )}) (check #32)`
175
- )
176
- }
177
- //else T[TYPE_PROP] = [COLLECTION]
178
- break
179
- default:
180
- {
181
- const isPredicate =
182
- getSuffix(first[VALUE]) === PREDICATE_SUFFIX
183
- if (isPredicate) {
184
- // PRED ASSIGMENT
185
- if (isKnown) T[TYPE_PROP][1] = PREDICATE
186
- T[RETURNS] = [ATOM, PREDICATE]
187
- }
188
- }
189
- break
190
- }
191
147
  }
192
148
  })
193
149
  }
@@ -208,7 +164,7 @@ export const typeCheck = (ast) => {
208
164
  )
209
165
  } else {
210
166
  const name = rest[0][VALUE]
211
- const resolveRetunType = (returns, rem, prop, isPredicate) => {
167
+ const resolveRetunType = (returns, rem, prop) => {
212
168
  if (returns[TYPE] === ATOM) {
213
169
  // ATOM ASSIGMENT
214
170
  env[name][STATS][prop][0] = ATOM
@@ -221,15 +177,8 @@ export const typeCheck = (ast) => {
221
177
  if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
222
178
  // ATOM ASSIGMENT
223
179
  env[name][STATS][prop][0] = ATOM
180
+ // TODO maybe delete this
224
181
  env[name][STATS][RETURNS][0] = ATOM
225
- if (
226
- getSuffix(re[0][VALUE]) === PREDICATE_SUFFIX ||
227
- getSuffix(re[1][VALUE]) === PREDICATE_SUFFIX
228
- ) {
229
- // ATOM ASSIGMENT PREDICATE ASSIGMENT
230
- env[name][STATS][TYPE_PROP][1] = [PREDICATE]
231
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
232
- }
233
182
  } else if (
234
183
  !isLeaf(re[0]) &&
235
184
  env[re[0][0][VALUE]] &&
@@ -288,102 +237,47 @@ export const typeCheck = (ast) => {
288
237
  }
289
238
  break
290
239
  default:
291
- if (env[returns[VALUE]]) {
292
- if (
293
- env[returns[VALUE]][STATS][TYPE_PROP][0] === APPLY
294
- ) {
295
- if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
296
- if (isLeaf(rest.at(-1).at(-1).at(-1))) {
297
- const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
298
- const fn = env[fnName]
299
- if (
300
- !isPredicate &&
301
- fn[STATS][RETURNS][1] === PREDICATE
302
- ) {
303
- warningStack.add(
304
- `${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
305
- )
306
- } else if (
307
- isPredicate &&
308
- fn[STATS][RETURNS][1] !== PREDICATE
309
- ) {
310
- warningStack.add(
311
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #25)`
312
- )
313
- }
314
- env[name][STATS][TYPE_PROP][0] =
315
- fn[STATS][RETURNS][0]
316
- env[name][STATS][RETURNS][1] =
317
- fn[STATS][RETURNS][1]
318
- } else {
319
- const [returns, rem] = drillReturnType(
320
- rest.at(-1).at(-1).at(-1),
321
- (returns) =>
322
- returns[VALUE] === KEYWORDS.CALL_FUNCTION
323
- )
324
- resolveRetunType(
325
- returns,
326
- rem,
327
- TYPE_PROP,
328
- isPredicate
329
- )
330
- }
331
- }
332
- // ALWAYS APPLY
333
- // rest.at(-1)[0][TYPE] === APPLY
334
- // Here is upon application to store the result in the variable
335
- if (env[name][STATS][TYPE_PROP][0] === UNKNOWN)
336
- stack.unshift(() => {
337
- env[name][STATS][TYPE_PROP][0] =
338
- env[returns[VALUE]][STATS][RETURNS][0]
339
- env[name][STATS][TYPE_PROP][1] =
340
- env[returns[VALUE]][STATS][RETURNS][1]
341
- })
342
- env[name][STATS][RETURNS] =
343
- env[returns[VALUE]][STATS][RETURNS]
344
- } else {
345
- // Enclose function with it's own scope
346
- const args = env[name][STATS][ARGUMENTS] ?? []
347
- const fnScope = args.length
348
- ? Object.create(env)
349
- : env
350
- for (const arg of args)
351
- fnScope[arg[STATS][SIGNATURE]] = arg
352
- // RETURN TYPE OF FUNCTION ASSIGGMENT
353
- fnScope[name][STATS][RETURNS] =
354
- fnScope[returns[VALUE]][STATS][RETURNS]
355
- // assign(env[name][STATS][RETURNS],env[returns[VALUE]][STATS][RETURNS], 0)
356
- fnScope[name][STATS][RETURNS][0] =
357
- fnScope[returns[VALUE]][STATS][TYPE_PROP][0]
358
- }
359
- } else {
240
+ if (!env[returns[VALUE]])
360
241
  env[name][STATS][RETURNS] = [UNKNOWN]
361
- // env[name][STATS][RETURNS] = APPLY
242
+ // env[name][STATS][RETURNS] = APPLY
243
+ else if (
244
+ env[returns[VALUE]][STATS][TYPE_PROP][0] === APPLY
245
+ ) {
246
+ // TODO This seems to be able to be deleted
247
+ // FOR NOT IT CAN BE
248
+ // if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
249
+ // if (isLeaf(rest.at(-1).at(-1).at(-1))) {
250
+ // const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
251
+ // const fn = env[fnName]
252
+ // env[name][STATS][TYPE_PROP][0] =
253
+ // fn[STATS][RETURNS][0]
254
+ // } else {
255
+ // const [returns, rem] = drillReturnType(
256
+ // rest.at(-1).at(-1).at(-1),
257
+ // (returns) =>
258
+ // returns[VALUE] === KEYWORDS.CALL_FUNCTION
259
+ // )
260
+ // resolveRetunType(returns, rem, TYPE_PROP)
261
+ // }
262
+ // }
263
+
264
+ // ALWAYS APPLY
265
+ // rest.at(-1)[0][TYPE] === APPLY
266
+ // Here is upon application to store the result in the variable
267
+ if (env[name][STATS][TYPE_PROP][0] === UNKNOWN)
268
+ stack.unshift(() => {
269
+ env[name][STATS][TYPE_PROP][0] =
270
+ env[returns[VALUE]][STATS][RETURNS][0]
271
+ // this seems to be able to be deleted
272
+ // env[name][STATS][TYPE_PROP][1] =
273
+ // env[returns[VALUE]][STATS][RETURNS][1]
274
+ })
275
+ env[name][STATS][RETURNS] =
276
+ env[returns[VALUE]][STATS][RETURNS]
362
277
  }
363
278
  break
364
279
  }
365
280
  }
366
- if (
367
- isPredicate &&
368
- env[name][STATS][prop][0] !== UNKNOWN &&
369
- env[name][STATS][RETURNS][1] !== PREDICATE
370
- ) {
371
- warningStack.add(
372
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #7)`
373
- )
374
- } else if (
375
- !isPredicate &&
376
- env[name][STATS][RETURNS][1] === PREDICATE
377
- ) {
378
- warningStack.add(
379
- `${name} should end in (${PREDICATE_SUFFIX}) because it return (Predicate) (try adding ? at the end of the lambda name) (check #8)`
380
- )
381
- }
382
- if (isPredicate) {
383
- // ATOM ASSIGMENT PREDICATE ASSIGMENT
384
- env[name][STATS][prop] = [ATOM, PREDICATE]
385
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
386
- }
387
281
  }
388
282
  const checkReturnType = () => {
389
283
  const last = rest.at(-1).at(-1)
@@ -392,8 +286,7 @@ export const typeCheck = (ast) => {
392
286
  : last
393
287
  const rem = hasBlock(body) ? body.at(-1) : body
394
288
  const returns = isLeaf(rem) ? rem : rem[0]
395
- const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
396
- resolveRetunType(returns, rem, RETURNS, isPredicate)
289
+ resolveRetunType(returns, rem, RETURNS)
397
290
  }
398
291
  const rightHand = rest.at(-1)
399
292
  if (
@@ -432,7 +325,6 @@ export const typeCheck = (ast) => {
432
325
  }
433
326
  } else {
434
327
  const isL = isLeaf(rightHand)
435
- // if (!(name in env)) {
436
328
  if (isL && rightHand[TYPE] === WORD) {
437
329
  // TODO make sure this prevents the assigment all together
438
330
  if (env[rest[1][VALUE]] === undefined) {
@@ -444,30 +336,7 @@ export const typeCheck = (ast) => {
444
336
  env[name] = SPECIAL_FORMS_SET.has(rest[1][VALUE])
445
337
  ? structuredClone(env[rest[1][VALUE]])
446
338
  : env[rest[1][VALUE]]
447
-
448
- if (
449
- getSuffix(rest[1][VALUE]) === PREDICATE_SUFFIX &&
450
- getSuffix(name) !== PREDICATE_SUFFIX
451
- )
452
- warningStack.add(
453
- `${name} is assigned to ${rest[1][VALUE]} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #17)`
454
- )
455
- else if (
456
- getSuffix(rest[1][VALUE]) === MUTATION_SUFFIX &&
457
- getSuffix(name) !== MUTATION_SUFFIX
458
- )
459
- warningStack.add(
460
- `${name} is assigned to ${rest[1][VALUE]} which ends in (${MUTATION_SUFFIX}) so ${name} must also end in (${MUTATION_SUFFIX}) (check #18)`
461
- )
462
339
  } else if (isL && rightHand[TYPE] === ATOM) {
463
- const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
464
- // This never happens
465
- // if (
466
- // isPredicate &&
467
- // right[VALUE] !== TRUE &&
468
- // right[VALUE] !== FALSE
469
- // ) {
470
- // }
471
340
  // DECLARATION of ATOM
472
341
  env[name] = {
473
342
  [STATS]: {
@@ -479,31 +348,8 @@ export const typeCheck = (ast) => {
479
348
  [RETURNS]: [ATOM]
480
349
  }
481
350
  }
482
- if (isPredicate) {
483
- if (rightHand[VALUE] !== TRUE && rightHand !== FALSE) {
484
- warningStack.add(
485
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but the (Atom) value is neither ${TRUE} or ${FALSE} (${stringifyArgs(
486
- exp
487
- )}) (check #14)`
488
- )
489
- } else {
490
- // PREDICATE ASSIGMENT
491
- env[name][STATS][TYPE_PROP][1] = PREDICATE
492
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
493
- }
494
- }
495
- } else {
351
+ } else if (rightHand[0]) {
496
352
  const right = rightHand[0]
497
- const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
498
- if (
499
- right &&
500
- right[VALUE] &&
501
- getSuffix(right[VALUE]) === PREDICATE_SUFFIX &&
502
- !isPredicate
503
- )
504
- warningStack.add(
505
- `${name} is assigned to ${right[VALUE]} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #19)`
506
- )
507
353
  //DECLARATION
508
354
  env[name] = {
509
355
  [STATS]: {
@@ -514,71 +360,27 @@ export const typeCheck = (ast) => {
514
360
  [TYPE_PROP]: [
515
361
  isL
516
362
  ? right[TYPE]
517
- : env[right?.[VALUE]]?.[STATS]?.[RETURNS]?.[0] ??
518
- UNKNOWN
363
+ : env[right[VALUE]] == undefined
364
+ ? UNKNOWN
365
+ : env[right[VALUE]][STATS][RETURNS][0]
519
366
  ],
520
367
  [RETURNS]: [UNKNOWN]
521
368
  }
522
369
  }
523
- if (isPredicate) {
524
- // PREDICATE ASSIGMENT
525
- env[name][STATS][TYPE_PROP][1] = PREDICATE
526
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
527
- }
528
- if (right && right[VALUE]) {
529
- if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
530
- if (isLeaf(rightHand.at(-1))) {
531
- const fnName = rightHand.at(-1)[VALUE]
532
- const fn = env[fnName]
533
- if (
534
- !isPredicate &&
535
- fn[STATS][RETURNS][1] === PREDICATE
536
- ) {
537
- warningStack.add(
538
- `${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
539
- )
540
- } else if (
541
- isPredicate &&
542
- fn[STATS][RETURNS][1] !== PREDICATE
543
- ) {
544
- warningStack.add(
545
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #25)`
546
- )
547
- }
548
- // FB assigment
549
- env[name][STATS][TYPE_PROP] = fn[STATS][RETURNS]
550
- env[name][STATS][RETURNS] = fn[STATS][RETURNS]
551
- } else {
552
- const body = rightHand.at(-1).at(-1)
553
- const rem = hasBlock(body) ? body.at(-1) : body
554
- const returns = isLeaf(rem) ? rem : rem[0]
555
- resolveRetunType(returns, rem, TYPE_PROP, isPredicate)
556
- }
557
- } else {
558
- const body = rightHand
370
+ if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
371
+ if (!isLeaf(rightHand.at(-1))) {
372
+ const body = rightHand.at(-1).at(-1)
559
373
  const rem = hasBlock(body) ? body.at(-1) : body
560
374
  const returns = isLeaf(rem) ? rem : rem[0]
561
- resolveRetunType(returns, rem, TYPE_PROP, isPredicate)
562
- }
563
- if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
564
- if (
565
- env[right[VALUE]][STATS][RETURNS][1] === PREDICATE &&
566
- !isPredicate
567
- ) {
568
- warningStack.add(
569
- `${name} is assigned to the result of a (${toTypeNames(
570
- PREDICATE
571
- )}) so ${name} must end in (${PREDICATE_SUFFIX}) (check #23)`
572
- )
573
- }
574
-
575
- // FN assigment
576
- env[name][STATS][RETURNS] =
577
- env[right[VALUE]][STATS][RETURNS]
375
+ resolveRetunType(returns, rem, TYPE_PROP)
578
376
  }
377
+ } else {
378
+ const body = rightHand
379
+ const rem = hasBlock(body) ? body.at(-1) : body
380
+ const returns = isLeaf(rem) ? rem : rem[0]
381
+ resolveRetunType(returns, rem, TYPE_PROP)
579
382
  }
580
383
  }
581
- // }
582
384
  check(rightHand, env, scope)
583
385
  }
584
386
  Types.set(withScope(name, env), () => formatType(name, env))
@@ -629,99 +431,82 @@ export const typeCheck = (ast) => {
629
431
  const ref = env[copy[SCOPE_NAME]]
630
432
  if (ref) {
631
433
  ref[STATS][ARGUMENTS][i] = copy[param[VALUE]]
632
- if (getSuffix(param[VALUE]) === PREDICATE_SUFFIX) {
633
- // copy[param[VALUE]][STATS][TYPE_PROP][1]= PREDICATE
634
- copy[param[VALUE]][STATS][RETURNS] = [ATOM, PREDICATE]
434
+ const returns = deepLambdaReturn(
435
+ hasBlock(exp) ? exp.at(-1) : exp,
436
+ (result) => result[VALUE] !== KEYWORDS.IF
437
+ )
438
+ if (isLeaf(returns)) {
439
+ // TODO figure out what we do here
440
+ // this here is a variable WORD
441
+ // so return type of that function is that varible type
442
+ if (copy[returns[VALUE]])
443
+ ref[STATS][RETURNS] =
444
+ copy[returns[VALUE]][STATS][TYPE_PROP]
445
+ else
446
+ stack.push(() => {
447
+ if (copy[returns[VALUE]])
448
+ ref[STATS][RETURNS] =
449
+ copy[returns[VALUE]][STATS][TYPE_PROP]
450
+ })
635
451
  } else {
636
- const returns = deepLambdaReturn(
637
- hasBlock(exp) ? exp.at(-1) : exp,
638
- (result) => result[VALUE] !== KEYWORDS.IF
639
- )
640
- if (isLeaf(returns)) {
641
- // TODO figure out what we do here
642
- // this here is a variable WORD
643
- // so return type of that function is that varible type
644
- if (copy[returns[VALUE]])
645
- ref[STATS][RETURNS] =
646
- copy[returns[VALUE]][STATS][TYPE_PROP]
647
- else
648
- stack.push(() => {
649
- if (copy[returns[VALUE]])
650
- ref[STATS][RETURNS] =
651
- copy[returns[VALUE]][STATS][TYPE_PROP]
652
- })
653
- } else {
654
- const ret = returns[0]
655
- switch (ret[VALUE]) {
656
- case KEYWORDS.IF:
657
- const re = returns.slice(2)
658
- // If either is an ATOM then IF returns an ATOM
659
- if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
660
- ref[STATS][RETURNS][0] = ATOM
661
- // TODO check that both brancehs are predicates if one is
662
- if (
663
- getSuffix(re[0][VALUE]) === PREDICATE_SUFFIX ||
664
- getSuffix(re[1][VALUE]) === PREDICATE_SUFFIX
665
- ) {
666
- ref[STATS][TYPE_PROP][1] = PREDICATE
667
- ref[STATS][RETURNS][1] = PREDICATE
668
- }
669
- } else {
670
- const concequent = isLeaf(re[0])
671
- ? copy[re[0][VALUE]]
672
- : copy[re[0][0][VALUE]]
673
- const alternative = isLeaf(re[1])
674
- ? copy[re[1][VALUE]]
675
- : copy[re[1][0][VALUE]]
452
+ const ret = returns[0]
453
+ switch (ret[VALUE]) {
454
+ case KEYWORDS.IF:
455
+ const re = returns.slice(2)
456
+ // If either is an ATOM then IF returns an ATOM
457
+ if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
458
+ ref[STATS][RETURNS][0] = ATOM
459
+ // TODO check that both brancehs are predicates if one is
460
+ } else {
461
+ const concequent = isLeaf(re[0])
462
+ ? copy[re[0][VALUE]]
463
+ : copy[re[0][0][VALUE]]
464
+ const alternative = isLeaf(re[1])
465
+ ? copy[re[1][VALUE]]
466
+ : copy[re[1][0][VALUE]]
676
467
 
677
- // todo check if condition matches alternative
678
- // TODO make this more simple - it's so many different things just because types are functions or not
679
- // WHY not consiter making return types for everything
680
- if (
681
- concequent &&
682
- concequent[STATS][TYPE_PROP][0] !== UNKNOWN
683
- ) {
684
- if (concequent[STATS][TYPE_PROP][0] === APPLY)
685
- ref[STATS][RETURNS] = concequent[STATS][RETURNS]
686
- else
687
- ref[STATS][RETURNS] =
688
- concequent[STATS][TYPE_PROP]
689
- } else if (
690
- alternative &&
691
- alternative[STATS][TYPE_PROP][0] !== UNKNOWN
692
- ) {
693
- if (alternative[STATS][TYPE_PROP][0] === APPLY)
694
- ref[STATS][RETURNS] =
695
- alternative[STATS][RETURNS]
696
- else
697
- ref[STATS][RETURNS] =
698
- alternative[STATS][TYPE_PROP]
699
- } else if (concequent) {
700
- if (concequent[STATS][TYPE_PROP][0] === APPLY)
701
- ref[STATS][RETURNS] = concequent[STATS][RETURNS]
702
- else
703
- ref[STATS][RETURNS] =
704
- concequent[STATS][TYPE_PROP]
705
- }
468
+ // todo check if condition matches alternative
469
+ // TODO make this more simple - it's so many different things just because types are functions or not
470
+ // WHY not consiter making return types for everything
471
+ if (
472
+ concequent &&
473
+ concequent[STATS][TYPE_PROP][0] !== UNKNOWN
474
+ ) {
475
+ if (concequent[STATS][TYPE_PROP][0] === APPLY)
476
+ ref[STATS][RETURNS] = concequent[STATS][RETURNS]
477
+ else
478
+ ref[STATS][RETURNS] = concequent[STATS][TYPE_PROP]
479
+ } else if (
480
+ alternative &&
481
+ alternative[STATS][TYPE_PROP][0] !== UNKNOWN
482
+ ) {
483
+ if (alternative[STATS][TYPE_PROP][0] === APPLY)
484
+ ref[STATS][RETURNS] = alternative[STATS][RETURNS]
485
+ else
486
+ ref[STATS][RETURNS] =
487
+ alternative[STATS][TYPE_PROP]
488
+ } else if (concequent) {
489
+ if (concequent[STATS][TYPE_PROP][0] === APPLY)
490
+ ref[STATS][RETURNS] = concequent[STATS][RETURNS]
491
+ else
492
+ ref[STATS][RETURNS] = concequent[STATS][TYPE_PROP]
706
493
  }
494
+ }
495
+ break
496
+ default:
497
+ if (copy[ret[VALUE]])
498
+ ref[STATS][RETURNS] = copy[ret[VALUE]][STATS][RETURNS]
499
+ else
500
+ stack.push(() => {
501
+ if (copy[ret[VALUE]])
502
+ ref[STATS][RETURNS] =
503
+ copy[ret[VALUE]][STATS][RETURNS]
504
+ })
707
505
 
708
- break
709
- default:
710
- if (copy[ret[VALUE]])
711
- ref[STATS][RETURNS] =
712
- copy[ret[VALUE]][STATS][RETURNS]
713
- else
714
- stack.push(() => {
715
- if (copy[ret[VALUE]])
716
- ref[STATS][RETURNS] =
717
- copy[ret[VALUE]][STATS][RETURNS]
718
- })
719
-
720
- break
721
- }
506
+ break
722
507
  }
723
- // TODO overwrite return type check here
724
508
  }
509
+ // TODO overwrite return type check here
725
510
  }
726
511
  }
727
512
  check(rest.at(-1), copy, copy)
@@ -794,133 +579,67 @@ export const typeCheck = (ast) => {
794
579
  const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
795
580
  for (let i = 0; i < args.length; ++i) {
796
581
  // type check
797
- const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
582
+ // TODO get rof pred type
583
+ // const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
798
584
  const MAIN_TYPE = args[i][STATS][TYPE_PROP][0]
799
- if (PRED_TYPE != undefined && !isLeaf(rest[i])) {
800
- const current = rest[i][0]
801
- if (current[TYPE] === APPLY) {
802
- if (current[VALUE] == KEYWORDS.CALL_FUNCTION) {
803
- if (isLeaf(rest[i].at(-1))) {
804
- const fnName = rest[i].at(-1)[VALUE]
805
- const fn = env[fnName]
806
- if (fn && fn[STATS][RETURNS][0] !== MAIN_TYPE) {
585
+ if (first[TYPE] === APPLY && isSpecial) {
586
+ if (
587
+ MAIN_TYPE === ATOM &&
588
+ PREDICATES_SET.has(first[VALUE]) &&
589
+ !isLeaf(rest[i]) &&
590
+ rest[i][0][TYPE] === APPLY &&
591
+ rest[i][0][VALUE] === KEYWORDS.CALL_FUNCTION
592
+ ) {
593
+ if (isLeaf(rest[i].at(-1))) {
594
+ const fnName = rest[i].at(-1)[VALUE]
595
+ const fn = env[fnName]
596
+ if (fn && fn[STATS][RETURNS][0] !== MAIN_TYPE) {
597
+ errorStack.add(
598
+ `Incorrect type of argument (${i}) for (${
599
+ first[VALUE]
600
+ }). Expected (${toTypeNames(
601
+ MAIN_TYPE
602
+ )}) but got an (${toTypeNames(
603
+ fn[STATS][RETURNS][0]
604
+ )}) (${stringifyArgs(exp)}) (check #26)`
605
+ )
606
+ }
607
+ } else {
608
+ const body = rest[i].at(-1).at(-1)
609
+ const rem = hasBlock(body) ? body.at(-1) : body
610
+ const returns = isLeaf(rem) ? rem : rem[0]
611
+ if (returns[TYPE] === ATOM) {
612
+ if (MAIN_TYPE !== ATOM) {
807
613
  errorStack.add(
808
- `Incorrect type of argument (${i}) for (${
614
+ `Incorrect type of argument ${i} for (${
809
615
  first[VALUE]
810
616
  }). Expected (${toTypeNames(
811
617
  MAIN_TYPE
812
618
  )}) but got an (${toTypeNames(
813
- fn[STATS][RETURNS][0]
814
- )}) (${stringifyArgs(exp)}) (check #26)`
619
+ ATOM
620
+ )}) (${stringifyArgs(exp)}) (check #27)`
815
621
  )
816
622
  }
817
- if (fn && fn[STATS][RETURNS][1] !== PRED_TYPE) {
818
- errorStack.add(
819
- `Incorrect type of argument (${i}) for (${
820
- first[VALUE]
821
- }). Expected (${toTypeNames(
822
- PRED_TYPE
823
- )}) but got an (${toTypeNames(
824
- fn[STATS][RETURNS][1] ?? fn[STATS][RETURNS][0]
825
- )}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
826
- exp
827
- )}) (check #27)`
828
- )
829
- }
830
- } else {
831
- const body = rest[i].at(-1).at(-1)
832
- const rem = hasBlock(body) ? body.at(-1) : body
833
- const returns = isLeaf(rem) ? rem : rem[0]
834
- if (returns[TYPE] === ATOM) {
835
- if (MAIN_TYPE !== ATOM) {
836
- errorStack.add(
837
- `Incorrect type of argument ${i} for (${
838
- first[VALUE]
839
- }). Expected (${toTypeNames(
840
- MAIN_TYPE
841
- )}) but got an (${toTypeNames(
842
- ATOM
843
- )}) (${stringifyArgs(exp)}) (check #27)`
844
- )
845
- }
846
- if (
847
- PRED_TYPE &&
848
- PRED_TYPE === PREDICATE &&
849
- returns[VALUE] !== TRUE &&
850
- returns[VALUE] !== FALSE
851
- ) {
852
- errorStack.add(
853
- `Incorrect type of argument ${i} for (${
854
- first[VALUE]
855
- }). Expected (${toTypeNames(
856
- PRED_TYPE
857
- )}) but got an (${toTypeNames(
858
- ATOM
859
- )}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
860
- exp
861
- )}) (check #27)`
862
- )
863
- }
864
- } else if (env[returns[VALUE]]) {
865
- if (
866
- MAIN_TYPE !==
867
- env[returns[VALUE]][STATS][RETURNS][0]
868
- ) {
869
- errorStack.add(
870
- `Incorrect type of argument ${i} for (${
871
- first[VALUE]
872
- }). Expected (${toTypeNames(
873
- MAIN_TYPE
874
- )}) but got (${toTypeNames(
875
- env[returns[VALUE]][STATS][TYPE_PROP]
876
- )}) (${stringifyArgs(exp)}) (check #29)`
877
- )
878
- }
879
- // Never happens because there is only 1 sub type at the moment
880
- // if (
881
- // PRED_TYPE &&
882
- // PRED_TYPE !==
883
- // env[returns[VALUE]][STATS][RETURNS][1]
884
- // ) {
885
- // }
886
- }
887
- }
888
- } else if (
889
- PRED_TYPE &&
890
- env[current[VALUE]] &&
891
- env[current[VALUE]][STATS][RETURNS][1] !== PRED_TYPE
892
- ) {
893
- if (current[VALUE] === KEYWORDS.ANONYMOUS_FUNCTION) {
894
- const body = rest[i].at(-1)
895
- const rem = hasBlock(body) ? body.at(-1) : body
896
- const returns = isLeaf(rem) ? rem : rem[0]
623
+ } else if (env[returns[VALUE]]) {
897
624
  if (
898
- env[returns[VALUE]] &&
899
- root[returns[VALUE]][STATS][RETURNS][1] ===
900
- PREDICATE
625
+ MAIN_TYPE !== env[returns[VALUE]][STATS][RETURNS][0]
901
626
  ) {
902
- // TODO invert this logic
903
- } else {
904
627
  errorStack.add(
905
- `Incorrect type of arguments (${i}) for (${
628
+ `Incorrect type of argument ${i} for (${
906
629
  first[VALUE]
907
630
  }). Expected (${toTypeNames(
908
- PRED_TYPE
631
+ MAIN_TYPE
909
632
  )}) but got (${toTypeNames(
910
- env[current[VALUE]][STATS][RETURNS][1] ??
911
- env[current[VALUE]][STATS][RETURNS][0]
912
- )}) (${stringifyArgs(exp)}) (check #21)`
633
+ env[returns[VALUE]][STATS][TYPE_PROP]
634
+ )}) (${stringifyArgs(exp)}) (check #29)`
913
635
  )
914
636
  }
915
637
  }
916
638
  }
917
639
  }
918
- }
919
- if (first[TYPE] === APPLY && isSpecial) {
920
640
  const isCast = STATIC_TYPES_SET.has(first[VALUE])
921
641
  const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
922
642
  for (let i = 0; i < rest.length; ++i) {
923
- const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
924
643
  const MAIN_TYPE = expectedArgs[i][STATS][TYPE_PROP][0]
925
644
  if (MAIN_TYPE === UNKNOWN && !isCast) continue
926
645
  if (!isLeaf(rest[i])) {
@@ -967,32 +686,18 @@ export const typeCheck = (ast) => {
967
686
  env[CAR][STATS][TYPE_PROP][0]
968
687
  )}) (${stringifyArgs(exp)}) (check #3)`
969
688
  )
970
- } else if (
971
- PRED_TYPE === PREDICATE &&
972
- env[CAR][STATS][RETURNS][1] !== PRED_TYPE &&
973
- !isCast
974
- )
975
- errorStack.add(
976
- `Incorrect type of argument (${i}) for special form (${
977
- first[VALUE]
978
- }). Expected (${toTypeNames(
979
- PRED_TYPE
980
- )}) but got (${toTypeNames(
981
- env[CAR][STATS][RETURNS][1] ??
982
- env[CAR][STATS][TYPE_PROP][0]
983
- )}) (${stringifyArgs(exp)}) (check #6)`
984
- )
985
- } else if (env[rest[i][VALUE]]) {
689
+ }
690
+ } else if (env[CAR]) {
986
691
  if (isCast) {
987
692
  // CAST assigment
988
- env[rest[i][VALUE]][STATS][TYPE_PROP] =
989
- root[first[VALUE]][STATS][RETURNS]
990
- root[first[VALUE]][STATS][RETURNS] =
991
- root[first[VALUE]][STATS][RETURNS]
693
+ env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
694
+ root[first[VALUE]][STATS][RETURNS][0]
695
+
696
+ // root[first[VALUE]][STATS][RETURNS] =
697
+ // root[first[VALUE]][STATS][RETURNS]
992
698
  } else {
993
699
  // VALUE assigment
994
- env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
995
- MAIN_TYPE
700
+ env[CAR][STATS][TYPE_PROP][0] = MAIN_TYPE
996
701
  }
997
702
  }
998
703
  }
@@ -1009,22 +714,6 @@ export const typeCheck = (ast) => {
1009
714
  )}) (${stringifyArgs(exp)}) (check #2)`
1010
715
  )
1011
716
  }
1012
- if (
1013
- PRED_TYPE === PREDICATE &&
1014
- rest[i][VALUE] !== TRUE &&
1015
- rest[i][VALUE] !== FALSE
1016
- ) {
1017
- errorStack.add(
1018
- `Incorrect type of argument (${i}) for special form (${
1019
- first[VALUE]
1020
- }). Expected (${toTypeNames(
1021
- PRED_TYPE
1022
- )}) but got (${toTypeNames(
1023
- rest[i][VALUE]
1024
- )}) (${stringifyArgs(exp)}) (check #5)`
1025
- )
1026
- }
1027
-
1028
717
  break
1029
718
  }
1030
719
  }
@@ -1051,22 +740,6 @@ export const typeCheck = (ast) => {
1051
740
  exp
1052
741
  )}) (check #10)`
1053
742
  )
1054
- } else if (
1055
- T === ATOM &&
1056
- args[i][STATS][RETURNS][0] === ATOM &&
1057
- args[i][STATS][RETURNS][1] === PREDICATE &&
1058
- rest[i][VALUE] !== TRUE &&
1059
- rest[i][VALUE] !== FALSE
1060
- ) {
1061
- errorStack.add(
1062
- `Incorrect type of arguments ${i} for (${
1063
- first[VALUE]
1064
- }). Expected (${toTypeNames(
1065
- args[i][STATS][RETURNS][1]
1066
- )}) but got (${toTypeNames(T)}) (${stringifyArgs(
1067
- exp
1068
- )}) (check #13)`
1069
- )
1070
743
  } else if (
1071
744
  T === APPLY &&
1072
745
  args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
@@ -1092,6 +765,7 @@ export const typeCheck = (ast) => {
1092
765
  }
1093
766
  }
1094
767
  if (
768
+ T === COLLECTION &&
1095
769
  env[rest[i][VALUE]] &&
1096
770
  env[rest[i][VALUE]][STATS][TYPE_PROP][0] !== UNKNOWN &&
1097
771
  args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&