fez-lisp 1.5.85 → 1.5.87

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "fez-lisp",
3
3
  "description": "Lisp interpreted & compiled to JavaScript",
4
4
  "author": "AT290690",
5
- "version": "1.5.85",
5
+ "version": "1.5.87",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -1,11 +1,16 @@
1
1
  import {
2
2
  APPLY,
3
3
  ATOM,
4
+ FALSE,
4
5
  KEYWORDS,
5
6
  PLACEHOLDER,
7
+ PREDICATE_SUFFIX,
8
+ PREDICATES_INPUT_SET,
9
+ PREDICATES_OUTPUT_SET,
6
10
  SPECIAL_FORMS_SET,
7
11
  STATIC_TYPES,
8
12
  STATIC_TYPES_SET,
13
+ TRUE,
9
14
  TYPE,
10
15
  VALUE,
11
16
  WORD
@@ -29,7 +34,12 @@ import {
29
34
  VARIABLE_ORDER_INDEX,
30
35
  COLLECTION
31
36
  } from './types.js'
32
- import { hasApplyLambdaBlock, hasBlock, stringifyArgs } from './utils.js'
37
+ import {
38
+ getSuffix,
39
+ hasApplyLambdaBlock,
40
+ hasBlock,
41
+ stringifyArgs
42
+ } from './utils.js'
33
43
 
34
44
  export const identity = (name) => [
35
45
  [0, 'let'],
@@ -53,6 +63,50 @@ const deepLambdaReturn = (rest, condition) => {
53
63
  const rem = hasBlock(body) ? body.at(-1) : body
54
64
  return condition(rem) ? rem : deepLambdaReturn(rem, condition)
55
65
  }
66
+ const checkPredicateName = (exp, rest, warningStack) => {
67
+ if (getSuffix(rest[0][VALUE]) === PREDICATE_SUFFIX) {
68
+ const last = rest.at(-1)
69
+ if (isLeaf(last)) {
70
+ if (last[TYPE] === ATOM && last[VALUE] !== TRUE && last[VALUE] !== FALSE)
71
+ warningStack.add(
72
+ `Assigning predicate (ending in ?) variable (${
73
+ rest[0][VALUE]
74
+ }) to an (${
75
+ STATIC_TYPES.ATOM
76
+ }) that is not (or ${TRUE} ${FALSE}) (${stringifyArgs(rest)})`
77
+ )
78
+ else if (
79
+ last[TYPE] === WORD &&
80
+ getSuffix(last[VALUE]) !== PREDICATE_SUFFIX &&
81
+ !PREDICATES_OUTPUT_SET.has(last[VALUE])
82
+ )
83
+ warningStack.add(
84
+ `Assigning predicate (ending in ?) variable (${
85
+ rest[0][VALUE]
86
+ }) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
87
+ exp
88
+ )})`
89
+ )
90
+ } else if (last[0][0] === APPLY) {
91
+ const application = last[0]
92
+ switch (application[VALUE]) {
93
+ default:
94
+ if (
95
+ getSuffix(application[VALUE]) !== PREDICATE_SUFFIX &&
96
+ !PREDICATES_OUTPUT_SET.has(application[VALUE])
97
+ )
98
+ warningStack.add(
99
+ `Assigning predicate (ending in ?) variable (${
100
+ application[VALUE]
101
+ }) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
102
+ exp
103
+ )})`
104
+ )
105
+ break
106
+ }
107
+ }
108
+ }
109
+ }
56
110
  // const assign = (a, b, i) => {
57
111
  // a[i] = b[i]
58
112
  // }
@@ -163,6 +217,7 @@ export const typeCheck = (ast) => {
163
217
  )
164
218
  } else {
165
219
  const name = rest[0][VALUE]
220
+ // Predicate name consistency
166
221
  const resolveRetunType = (returns, rem, prop) => {
167
222
  if (returns[TYPE] === ATOM) {
168
223
  // ATOM ASSIGMENT
@@ -176,6 +231,7 @@ export const typeCheck = (ast) => {
176
231
  if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
177
232
  // ATOM ASSIGMENT
178
233
  env[name][STATS][prop][0] = ATOM
234
+ // TODO maybe delete this
179
235
  env[name][STATS][RETURNS][0] = ATOM
180
236
  } else if (
181
237
  !isLeaf(re[0]) &&
@@ -235,55 +291,43 @@ export const typeCheck = (ast) => {
235
291
  }
236
292
  break
237
293
  default:
238
- if (env[returns[VALUE]]) {
239
- if (
240
- env[returns[VALUE]][STATS][TYPE_PROP][0] === APPLY
241
- ) {
242
- if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
243
- if (isLeaf(rest.at(-1).at(-1).at(-1))) {
244
- const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
245
- const fn = env[fnName]
246
- env[name][STATS][TYPE_PROP][0] =
247
- fn[STATS][RETURNS][0]
248
- } else {
249
- const [returns, rem] = drillReturnType(
250
- rest.at(-1).at(-1).at(-1),
251
- (returns) =>
252
- returns[VALUE] === KEYWORDS.CALL_FUNCTION
253
- )
254
- resolveRetunType(returns, rem, TYPE_PROP)
255
- }
256
- }
257
- // ALWAYS APPLY
258
- // rest.at(-1)[0][TYPE] === APPLY
259
- // Here is upon application to store the result in the variable
260
- if (env[name][STATS][TYPE_PROP][0] === UNKNOWN)
261
- stack.unshift(() => {
262
- env[name][STATS][TYPE_PROP][0] =
263
- env[returns[VALUE]][STATS][RETURNS][0]
264
- env[name][STATS][TYPE_PROP][1] =
265
- env[returns[VALUE]][STATS][RETURNS][1]
266
- })
267
- env[name][STATS][RETURNS] =
268
- env[returns[VALUE]][STATS][RETURNS]
269
- } else {
270
- // Enclose function with it's own scope
271
- const args = env[name][STATS][ARGUMENTS] ?? []
272
- const fnScope = args.length
273
- ? Object.create(env)
274
- : env
275
- for (const arg of args)
276
- fnScope[arg[STATS][SIGNATURE]] = arg
277
- // RETURN TYPE OF FUNCTION ASSIGGMENT
278
- fnScope[name][STATS][RETURNS] =
279
- fnScope[returns[VALUE]][STATS][RETURNS]
280
- // assign(env[name][STATS][RETURNS],env[returns[VALUE]][STATS][RETURNS], 0)
281
- fnScope[name][STATS][RETURNS][0] =
282
- fnScope[returns[VALUE]][STATS][TYPE_PROP][0]
283
- }
284
- } else {
294
+ if (!env[returns[VALUE]])
285
295
  env[name][STATS][RETURNS] = [UNKNOWN]
286
- // env[name][STATS][RETURNS] = APPLY
296
+ // env[name][STATS][RETURNS] = APPLY
297
+ else if (
298
+ env[returns[VALUE]][STATS][TYPE_PROP][0] === APPLY
299
+ ) {
300
+ // TODO This seems to be able to be deleted
301
+ // FOR NOT IT CAN BE
302
+ // if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
303
+ // if (isLeaf(rest.at(-1).at(-1).at(-1))) {
304
+ // const fnName = rest.at(-1).at(-1).at(-1)[VALUE]
305
+ // const fn = env[fnName]
306
+ // env[name][STATS][TYPE_PROP][0] =
307
+ // fn[STATS][RETURNS][0]
308
+ // } else {
309
+ // const [returns, rem] = drillReturnType(
310
+ // rest.at(-1).at(-1).at(-1),
311
+ // (returns) =>
312
+ // returns[VALUE] === KEYWORDS.CALL_FUNCTION
313
+ // )
314
+ // resolveRetunType(returns, rem, TYPE_PROP)
315
+ // }
316
+ // }
317
+
318
+ // ALWAYS APPLY
319
+ // rest.at(-1)[0][TYPE] === APPLY
320
+ // Here is upon application to store the result in the variable
321
+ if (env[name][STATS][TYPE_PROP][0] === UNKNOWN)
322
+ stack.unshift(() => {
323
+ env[name][STATS][TYPE_PROP][0] =
324
+ env[returns[VALUE]][STATS][RETURNS][0]
325
+ // this seems to be able to be deleted
326
+ // env[name][STATS][TYPE_PROP][1] =
327
+ // env[returns[VALUE]][STATS][RETURNS][1]
328
+ })
329
+ env[name][STATS][RETURNS] =
330
+ env[returns[VALUE]][STATS][RETURNS]
287
331
  }
288
332
  break
289
333
  }
@@ -334,8 +378,8 @@ export const typeCheck = (ast) => {
334
378
  check(rightHand, env, exp)
335
379
  }
336
380
  } else {
381
+ checkPredicateName(exp, rest, warningStack)
337
382
  const isL = isLeaf(rightHand)
338
- // if (!(name in env)) {
339
383
  if (isL && rightHand[TYPE] === WORD) {
340
384
  // TODO make sure this prevents the assigment all together
341
385
  if (env[rest[1][VALUE]] === undefined) {
@@ -359,7 +403,7 @@ export const typeCheck = (ast) => {
359
403
  [RETURNS]: [ATOM]
360
404
  }
361
405
  }
362
- } else {
406
+ } else if (rightHand[0]) {
363
407
  const right = rightHand[0]
364
408
  //DECLARATION
365
409
  env[name] = {
@@ -371,35 +415,27 @@ export const typeCheck = (ast) => {
371
415
  [TYPE_PROP]: [
372
416
  isL
373
417
  ? right[TYPE]
374
- : env[right?.[VALUE]]?.[STATS]?.[RETURNS]?.[0] ??
375
- UNKNOWN
418
+ : env[right[VALUE]] == undefined
419
+ ? UNKNOWN
420
+ : env[right[VALUE]][STATS][RETURNS][0]
376
421
  ],
377
422
  [RETURNS]: [UNKNOWN]
378
423
  }
379
424
  }
380
- if (right && right[VALUE]) {
381
- if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
382
- if (isLeaf(rightHand.at(-1))) {
383
- const fnName = rightHand.at(-1)[VALUE]
384
- const fn = env[fnName]
385
- // FB assigment
386
- env[name][STATS][TYPE_PROP] = fn[STATS][RETURNS]
387
- env[name][STATS][RETURNS] = fn[STATS][RETURNS]
388
- } else {
389
- const body = rightHand.at(-1).at(-1)
390
- const rem = hasBlock(body) ? body.at(-1) : body
391
- const returns = isLeaf(rem) ? rem : rem[0]
392
- resolveRetunType(returns, rem, TYPE_PROP)
393
- }
394
- } else {
395
- const body = rightHand
425
+ if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
426
+ if (!isLeaf(rightHand.at(-1))) {
427
+ const body = rightHand.at(-1).at(-1)
396
428
  const rem = hasBlock(body) ? body.at(-1) : body
397
429
  const returns = isLeaf(rem) ? rem : rem[0]
398
430
  resolveRetunType(returns, rem, TYPE_PROP)
399
431
  }
432
+ } else {
433
+ const body = rightHand
434
+ const rem = hasBlock(body) ? body.at(-1) : body
435
+ const returns = isLeaf(rem) ? rem : rem[0]
436
+ resolveRetunType(returns, rem, TYPE_PROP)
400
437
  }
401
438
  }
402
- // }
403
439
  check(rightHand, env, scope)
404
440
  }
405
441
  Types.set(withScope(name, env), () => formatType(name, env))
@@ -511,7 +547,6 @@ export const typeCheck = (ast) => {
511
547
  ref[STATS][RETURNS] = concequent[STATS][TYPE_PROP]
512
548
  }
513
549
  }
514
-
515
550
  break
516
551
  default:
517
552
  if (copy[ret[VALUE]])
@@ -594,26 +629,38 @@ export const typeCheck = (ast) => {
594
629
  }
595
630
  }
596
631
  }
597
-
598
632
  // also type of arg
599
633
  const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
600
634
  for (let i = 0; i < args.length; ++i) {
635
+ const isRestILeaf = isLeaf(rest[i])
601
636
  // type check
602
- const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
637
+ // TODO get rof pred type
638
+ // const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
603
639
  const MAIN_TYPE = args[i][STATS][TYPE_PROP][0]
604
- if (PRED_TYPE != undefined && !isLeaf(rest[i])) {
605
- const current = rest[i][0]
606
- if (current[TYPE] === APPLY) {
607
- if (current[VALUE] == KEYWORDS.CALL_FUNCTION) {
640
+ if (first[TYPE] === APPLY && isSpecial) {
641
+ if (
642
+ MAIN_TYPE === ATOM &&
643
+ PREDICATES_INPUT_SET.has(first[VALUE])
644
+ ) {
645
+ // if (isRestILeaf && rest[i][TYPE] === ATOM && rest[i][VALUE] !== TRUE && rest[i][TYPE] !== FALSE) throw some rror
646
+ // else if (
647
+ // isRestILeaf && est[i][TYPE] === ATOM && (rest[i][VALUE] === TRUE || rest[i][VALUE] === FALSE)
648
+ // ) continue
649
+ // else
650
+ if (
651
+ !isRestILeaf &&
652
+ rest[i][0][TYPE] === APPLY &&
653
+ rest[i][0][VALUE] === KEYWORDS.CALL_FUNCTION
654
+ ) {
608
655
  if (isLeaf(rest[i].at(-1))) {
609
656
  const fnName = rest[i].at(-1)[VALUE]
610
657
  const fn = env[fnName]
611
- if (fn && fn[STATS][RETURNS][0] !== MAIN_TYPE) {
658
+ if (fn && fn[STATS][RETURNS][0] !== ATOM) {
612
659
  errorStack.add(
613
660
  `Incorrect type of argument (${i}) for (${
614
661
  first[VALUE]
615
662
  }). Expected (${toTypeNames(
616
- MAIN_TYPE
663
+ ATOM
617
664
  )}) but got an (${toTypeNames(
618
665
  fn[STATS][RETURNS][0]
619
666
  )}) (${stringifyArgs(exp)}) (check #26)`
@@ -635,112 +682,107 @@ export const typeCheck = (ast) => {
635
682
  )}) (${stringifyArgs(exp)}) (check #27)`
636
683
  )
637
684
  }
638
- } else if (env[returns[VALUE]]) {
639
- if (
640
- MAIN_TYPE !==
641
- env[returns[VALUE]][STATS][RETURNS][0]
642
- ) {
643
- errorStack.add(
644
- `Incorrect type of argument ${i} for (${
645
- first[VALUE]
646
- }). Expected (${toTypeNames(
647
- MAIN_TYPE
648
- )}) but got (${toTypeNames(
649
- env[returns[VALUE]][STATS][TYPE_PROP]
650
- )}) (${stringifyArgs(exp)}) (check #29)`
651
- )
652
- }
685
+ } else if (
686
+ env[returns[VALUE]] &&
687
+ env[returns[VALUE]][STATS][RETURNS][0] !== ATOM
688
+ ) {
689
+ errorStack.add(
690
+ `Incorrect type of argument ${i} for (${
691
+ first[VALUE]
692
+ }). Expected (${toTypeNames(
693
+ ATOM
694
+ )}) but got (${toTypeNames(
695
+ env[returns[VALUE]][STATS][TYPE_PROP]
696
+ )}) (${stringifyArgs(exp)}) (check #29)`
697
+ )
653
698
  }
654
699
  }
655
700
  }
656
701
  }
657
- }
658
- if (first[TYPE] === APPLY && isSpecial) {
659
702
  const isCast = STATIC_TYPES_SET.has(first[VALUE])
660
703
  const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
661
- for (let i = 0; i < rest.length; ++i) {
662
- const MAIN_TYPE = expectedArgs[i][STATS][TYPE_PROP][0]
663
- if (MAIN_TYPE === UNKNOWN && !isCast) continue
664
- if (!isLeaf(rest[i])) {
665
- const CAR = rest[i][0][VALUE]
666
- const isKnown =
667
- env[CAR] && env[CAR][STATS][RETURNS][0] !== UNKNOWN
668
- if (isKnown && !isCast) {
669
- if (env[CAR][STATS][RETURNS][0] !== MAIN_TYPE) {
704
+ const EXPECTED_TYPE = expectedArgs[i][STATS][TYPE_PROP][0]
705
+ // IF UKNOWN andnot csted -we have nothing much to do
706
+ if (EXPECTED_TYPE === UNKNOWN && !isCast) continue
707
+ if (!isRestILeaf) {
708
+ const CAR = rest[i][0][VALUE]
709
+ const isKnown =
710
+ env[CAR] && env[CAR][STATS][RETURNS][0] !== UNKNOWN
711
+ if (isKnown && !isCast) {
712
+ if (env[CAR][STATS][RETURNS][0] !== EXPECTED_TYPE) {
713
+ errorStack.add(
714
+ `Incorrect type of argument (${i}) for special form (${
715
+ first[VALUE]
716
+ }). Expected (${toTypeNames(
717
+ EXPECTED_TYPE
718
+ )}) but got (${toTypeNames(
719
+ env[CAR][STATS][RETURNS][0]
720
+ )}) (${stringifyArgs(exp)}) (check #1)`
721
+ )
722
+ }
723
+ // never reached because there is only 1 subtype at the moment
724
+ // else if (
725
+ // PRED_TYPE &&
726
+ // env[CAR][STATS][RETURNS][1] !== PRED_TYPE
727
+ // ) {
728
+ // }
729
+ }
730
+ } else {
731
+ switch (rest[i][TYPE]) {
732
+ case WORD:
733
+ {
734
+ const CAR = rest[i][VALUE]
735
+ const isKnown =
736
+ env[CAR] &&
737
+ env[CAR][STATS][TYPE_PROP][0] !== UNKNOWN
738
+ if (isKnown && !isCast) {
739
+ if (
740
+ EXPECTED_TYPE !== env[CAR][STATS][TYPE_PROP][0]
741
+ ) {
742
+ errorStack.add(
743
+ `Incorrect type of argument (${i}) for special form (${
744
+ first[VALUE]
745
+ }). Expected (${toTypeNames(
746
+ EXPECTED_TYPE
747
+ )}) but got (${toTypeNames(
748
+ env[CAR][STATS][TYPE_PROP][0]
749
+ )}) (${stringifyArgs(exp)}) (check #3)`
750
+ )
751
+ }
752
+ } else if (env[CAR]) {
753
+ if (isCast) {
754
+ // CAST assigment
755
+ env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
756
+ root[first[VALUE]][STATS][RETURNS][0]
757
+
758
+ // root[first[VALUE]][STATS][RETURNS] =
759
+ // root[first[VALUE]][STATS][RETURNS]
760
+ } else {
761
+ // VALUE assigment
762
+ env[CAR][STATS][TYPE_PROP][0] = EXPECTED_TYPE
763
+ }
764
+ }
765
+ }
766
+ break
767
+ case ATOM: {
768
+ if (rest[i][TYPE] !== EXPECTED_TYPE) {
670
769
  errorStack.add(
671
770
  `Incorrect type of argument (${i}) for special form (${
672
771
  first[VALUE]
673
772
  }). Expected (${toTypeNames(
674
- MAIN_TYPE
773
+ EXPECTED_TYPE
675
774
  )}) but got (${toTypeNames(
676
- env[CAR][STATS][RETURNS][0]
677
- )}) (${stringifyArgs(exp)}) (check #1)`
775
+ rest[i][TYPE]
776
+ )}) (${stringifyArgs(exp)}) (check #2)`
678
777
  )
679
778
  }
680
- // never reached because there is only 1 subtype at the moment
681
- // else if (
682
- // PRED_TYPE &&
683
- // env[CAR][STATS][RETURNS][1] !== PRED_TYPE
684
- // ) {
685
- // }
686
- }
687
- } else {
688
- switch (rest[i][TYPE]) {
689
- case WORD:
690
- {
691
- const CAR = rest[i][VALUE]
692
- const isKnown =
693
- env[CAR] &&
694
- env[CAR][STATS][TYPE_PROP][0] !== UNKNOWN
695
- if (isKnown && !isCast) {
696
- if (
697
- MAIN_TYPE !== env[CAR][STATS][TYPE_PROP][0]
698
- ) {
699
- errorStack.add(
700
- `Incorrect type of argument (${i}) for special form (${
701
- first[VALUE]
702
- }). Expected (${toTypeNames(
703
- MAIN_TYPE
704
- )}) but got (${toTypeNames(
705
- env[CAR][STATS][TYPE_PROP][0]
706
- )}) (${stringifyArgs(exp)}) (check #3)`
707
- )
708
- }
709
- } else if (env[rest[i][VALUE]]) {
710
- if (isCast) {
711
- // CAST assigment
712
- env[rest[i][VALUE]][STATS][TYPE_PROP] =
713
- root[first[VALUE]][STATS][RETURNS]
714
- root[first[VALUE]][STATS][RETURNS] =
715
- root[first[VALUE]][STATS][RETURNS]
716
- } else {
717
- // VALUE assigment
718
- env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
719
- MAIN_TYPE
720
- }
721
- }
722
- }
723
- break
724
- case ATOM: {
725
- if (rest[i][TYPE] !== MAIN_TYPE) {
726
- errorStack.add(
727
- `Incorrect type of argument (${i}) for special form (${
728
- first[VALUE]
729
- }). Expected (${toTypeNames(
730
- MAIN_TYPE
731
- )}) but got (${toTypeNames(
732
- rest[i][TYPE]
733
- )}) (${stringifyArgs(exp)}) (check #2)`
734
- )
735
- }
736
- break
737
- }
779
+ break
738
780
  }
739
781
  }
740
782
  }
741
783
  }
742
784
  // type checking
743
- else if (isLeaf(rest[i])) {
785
+ else if (isRestILeaf) {
744
786
  const T =
745
787
  rest[i][TYPE] === WORD && env[rest[i][VALUE]]
746
788
  ? env[rest[i][VALUE]][STATS][TYPE_PROP][0]
package/src/keywords.js CHANGED
@@ -15,7 +15,6 @@ export const STATIC_TYPES = {
15
15
  COLLECTION: 'Collection',
16
16
  PREDICATE: 'Predicate'
17
17
  }
18
- export const STATIC_TYPES_SET = new Set(Object.values(STATIC_TYPES))
19
18
  export const KEYWORDS = {
20
19
  LOOP: 'loop',
21
20
  CREATE_ARRAY: 'array',
@@ -77,3 +76,23 @@ export const DEBUG = {
77
76
  export const SPECIAL_FORMS_SET = new Set(
78
77
  Object.values(KEYWORDS).concat(Object.values(STATIC_TYPES))
79
78
  )
79
+ export const STATIC_TYPES_SET = new Set(Object.values(STATIC_TYPES))
80
+ export const PREDICATES_INPUT_SET = new Set([
81
+ KEYWORDS.IF,
82
+ KEYWORDS.AND,
83
+ KEYWORDS.OR,
84
+ KEYWORDS.NOT,
85
+ KEYWORDS.LOOP
86
+ ])
87
+ export const PREDICATES_OUTPUT_SET = new Set([
88
+ KEYWORDS.AND,
89
+ KEYWORDS.OR,
90
+ KEYWORDS.NOT,
91
+ KEYWORDS.EQUAL,
92
+ KEYWORDS.GREATHER_THAN,
93
+ KEYWORDS.LESS_THAN,
94
+ KEYWORDS.GREATHER_THAN_OR_EQUAL,
95
+ KEYWORDS.LESS_THAN_OR_EQUAL,
96
+ KEYWORDS.IS_ATOM,
97
+ KEYWORDS.IS_LAMBDA
98
+ ])
package/src/macros.js CHANGED
@@ -10,14 +10,12 @@ import {
10
10
  FALSE,
11
11
  KEYWORDS,
12
12
  PLACEHOLDER,
13
- PREDICATE_SUFFIX,
14
- STATIC_TYPES,
15
13
  TRUE,
16
14
  TYPE,
17
15
  VALUE,
18
16
  WORD
19
17
  } from './keywords.js'
20
- import { getSuffix, hasBlock, stringifyArgs } from './utils.js'
18
+ import { hasBlock, stringifyArgs } from './utils.js'
21
19
  export const SUGGAR = {
22
20
  // Syntactic suggars
23
21
  PIPE: '|>',