fez-lisp 1.5.104 → 1.5.106

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.104",
5
+ "version": "1.5.106",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -34,7 +34,8 @@ import {
34
34
  ANY,
35
35
  formatType,
36
36
  ANONYMOUS_FUNCTION_TYPE_PREFIX,
37
- validateLambda
37
+ validateLambda,
38
+ NIL
38
39
  } from './types.js'
39
40
  import {
40
41
  Brr,
@@ -54,6 +55,11 @@ export const identity = (name) => [
54
55
  [1, 'x']
55
56
  ]
56
57
  ]
58
+ const returnType = (rest) => {
59
+ const body = rest.at(-1)
60
+ const rem = hasBlock(body) ? body.at(-1) : body
61
+ return isLeaf(rem) ? rem : rem[0]
62
+ }
57
63
  const drillReturnType = (rest, condition) => {
58
64
  const body = rest.at(-1)
59
65
  const rem = hasBlock(body) ? body.at(-1) : body
@@ -71,64 +77,111 @@ export const isUnknownNotAnyType = (stats) =>
71
77
  stats && !isAnyType(stats) && isUnknownType(stats)
72
78
  export const isUnknownNotAnyReturn = (stats) =>
73
79
  stats && !isAnyReturn(stats) && isUnknownReturn(stats)
74
- export const castType = (stats, type) =>
75
- (stats[TYPE_PROP][0] = type[RETURNS][0])
76
- export const castReturn = (stats, type) =>
77
- (stats[RETURNS][0] = type[RETURNS][0])
80
+ export const castType = (stats, type) => {
81
+ return (stats[TYPE_PROP][0] = type[RETURNS][0])
82
+ }
83
+ export const castReturn = (stats, type) => {
84
+ return (stats[RETURNS][0] = type[RETURNS][0])
85
+ }
78
86
  export const isTypeAbstraction = (stats) => stats[TYPE_PROP] === APPLY
79
- export const setPropToAtom = (stats, prop) =>
80
- (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
81
- (stats[prop][0] = ATOM)
82
- export const setProp = (stats, prop, value) =>
83
- (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
84
- value[prop][0] !== UNKNOWN &&
85
- (stats[prop][0] = value[prop][0])
86
- export const setPropToReturn = (stats, prop, value) =>
87
- (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
88
- value[RETURNS][0] !== UNKNOWN &&
89
- (stats[prop][0] = value[RETURNS][0])
90
- export const setPropToReturnRef = (stats, prop, value) =>
91
- (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
92
- value[RETURNS][0] !== UNKNOWN &&
93
- (stats[prop] = value[RETURNS])
94
- export const setPropToType = (stats, prop, value) =>
95
- (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
96
- value[UNKNOWN][0] !== UNKNOWN &&
97
- (stats[prop][0] = value[UNKNOWN][0])
98
- export const setPropToTypeRef = (stats, prop, value) =>
99
- (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
100
- value[TYPE_PROP][0] !== UNKNOWN &&
101
- (stats[prop] = value[TYPE_PROP])
102
- export const setReturnToAtom = (stats) =>
103
- isUnknownReturn(stats) && (stats[RETURNS][0] = ATOM)
87
+ export const setPropToAtom = (stats, prop) => {
88
+ return (
89
+ (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
90
+ (stats[prop][0] = ATOM)
91
+ )
92
+ }
93
+ export const setPropToAbstraction = (stats, prop) => {
94
+ return (
95
+ (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
96
+ (stats[prop][0] = APPLY)
97
+ )
98
+ }
99
+ export const setProp = (stats, prop, value) => {
100
+ return (
101
+ (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
102
+ value[prop][0] !== UNKNOWN &&
103
+ (stats[prop][0] = value[prop][0])
104
+ )
105
+ }
106
+ export const setPropToReturn = (stats, prop, value) => {
107
+ return (
108
+ (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
109
+ value[RETURNS][0] !== UNKNOWN &&
110
+ (stats[prop][0] = value[RETURNS][0])
111
+ )
112
+ }
113
+ export const setPropToReturnRef = (stats, prop, value) => {
114
+ return (
115
+ (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
116
+ value[RETURNS][0] !== UNKNOWN &&
117
+ (stats[prop] = value[RETURNS])
118
+ )
119
+ }
120
+ export const setPropToType = (stats, prop, value) => {
121
+ return (
122
+ (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
123
+ (stats[prop][0] = value[TYPE_PROP][0])
124
+ )
125
+ }
126
+ export const setPropToTypeRef = (stats, prop, value) => {
127
+ return (
128
+ (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
129
+ (stats[prop] = value[TYPE_PROP])
130
+ )
131
+ }
132
+ export const setReturnToAtom = (stats) => {
133
+ return (
134
+ (isUnknownReturn(stats) || isAnyReturn(stats)) && (stats[RETURNS][0] = ATOM)
135
+ )
136
+ }
104
137
  export const setTypeToAtom = (stats) =>
105
- isUnknownType(stats) && (stats[TYPE_PROP][0] = ATOM)
138
+ (isUnknownType(stats) || isAnyType(stats)) && (stats[TYPE_PROP][0] = ATOM)
106
139
  export const setReturnToAbbstraction = (stats) =>
107
- isUnknownReturn(stats) && (stats[RETURNS][0] = APPLY)
140
+ (isUnknownReturn(stats) || isAnyReturn(stats)) && (stats[RETURNS][0] = APPLY)
108
141
  export const setTypeRef = (stats, value) =>
109
- isUnknownType(stats) && (stats[TYPE_PROP] = value[TYPE_PROP])
110
- export const setReturnRef = (stats, value) =>
111
- isUnknownReturn(stats) && (stats[RETURNS] = value[RETURNS])
112
- export const setReturnToTypeRef = (stats, value) =>
113
- isUnknownReturn(stats) && (stats[RETURNS] = value[TYPE_PROP])
114
- export const setTypeToReturnRef = (stats, value) =>
115
- isUnknownType(stats) && (stats[TYPE_PROP] = value[RETURNS])
116
- export const setPropRef = (stats, prop, value) =>
117
- stats[prop][0] === UNKNOWN && (stats[prop] = value[prop])
118
- export const setReturn = (stats, value) =>
119
- isUnknownReturn(stats) &&
120
- !isUnknownReturn(value) &&
121
- (stats[RETURNS][0] = value[RETURNS][0])
142
+ (isUnknownType(stats) || isAnyType(stats)) &&
143
+ (stats[TYPE_PROP] = value[TYPE_PROP])
144
+ export const setReturnRef = (stats, value) => {
145
+ return (
146
+ (isUnknownReturn(stats) || isAnyReturn(stats)) &&
147
+ (stats[RETURNS] = value[RETURNS])
148
+ )
149
+ }
150
+ export const setReturnToTypeRef = (stats, value) => {
151
+ return (
152
+ (isUnknownReturn(stats) || isAnyReturn(stats)) &&
153
+ (stats[RETURNS] = value[TYPE_PROP])
154
+ )
155
+ }
156
+ export const setTypeToReturnRef = (stats, value) => {
157
+ return (
158
+ (isUnknownType(stats) || isAnyType(stats)) &&
159
+ (stats[TYPE_PROP] = value[RETURNS])
160
+ )
161
+ }
162
+ export const setPropRef = (stats, prop, value) => {
163
+ return (
164
+ (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
165
+ (stats[prop] = value[prop])
166
+ )
167
+ }
168
+ export const setReturn = (stats, value) => {
169
+ return (
170
+ isUnknownReturn(stats) &&
171
+ !isUnknownReturn(value) &&
172
+ (stats[RETURNS][0] = value[RETURNS][0])
173
+ )
174
+ }
122
175
  export const setType = (stats, value) =>
123
- isUnknownType(stats) &&
176
+ (isUnknownType(stats) || isAnyType(stats)) &&
124
177
  !isUnknownType(value) &&
125
178
  (stats[TYPE_PROP][0] = value[TYPE_PROP][0])
126
179
  export const setTypeToReturn = (stats, value) =>
127
- isUnknownType(stats) &&
180
+ (isUnknownType(stats) || isAnyType(stats)) &&
128
181
  !isUnknownReturn(value) &&
129
182
  (stats[TYPE_PROP][0] = value[RETURNS][0])
130
183
  export const setReturnToType = (stats, value) =>
131
- isUnknownReturn(stats) &&
184
+ (isUnknownReturn(stats) || isAnyReturn(stats)) &&
132
185
  !isUnknownType(value) &&
133
186
  (stats[RETURNS][0] = value[TYPE_PROP][0])
134
187
  export const isAnyReturn = (stats) => stats && stats[RETURNS][0] === ANY
@@ -173,24 +226,18 @@ const checkPredicateName = (exp, rest) => {
173
226
  )
174
227
  } else if (last[0][0] === APPLY) {
175
228
  const application = last[0]
176
- switch (application[VALUE]) {
177
- case KEYWORDS.IF:
178
- // TODO finishthis #1
179
- break
180
- default:
181
- if (
182
- getSuffix(application[VALUE]) !== PREDICATE_SUFFIX &&
183
- !PREDICATES_OUTPUT_SET.has(application[VALUE])
184
- )
185
- throw new TypeError(
186
- `Assigning predicate (ending in ?) variable (${
187
- application[VALUE]
188
- }) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
189
- exp
190
- )})`
191
- )
192
- break
193
- }
229
+ if (
230
+ application[VALUE] !== KEYWORDS.IF &&
231
+ getSuffix(application[VALUE]) !== PREDICATE_SUFFIX &&
232
+ !PREDICATES_OUTPUT_SET.has(application[VALUE])
233
+ )
234
+ throw new TypeError(
235
+ `Assigning predicate (ending in ?) variable (${
236
+ application[VALUE]
237
+ }) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
238
+ exp
239
+ )})`
240
+ )
194
241
  }
195
242
  }
196
243
  }
@@ -250,88 +297,109 @@ const retryArgs = (stats, stack, cb) => {
250
297
  stack.prepend(cb)
251
298
  }
252
299
  }
253
- const ifExpression = ({ re, env, ref }) => {
254
- if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) setReturnToAtom(ref[STATS])
300
+ const IfApplyBranch = ({ leaf, branch, re, prop, ref, env }) => {
301
+ switch (leaf[VALUE]) {
302
+ case KEYWORDS.IF:
303
+ return ifExpression({
304
+ re: re.slice(2),
305
+ env,
306
+ ref,
307
+ prop
308
+ })
309
+ case KEYWORDS.ANONYMOUS_FUNCTION:
310
+ setPropToAbstraction(ref[STATS], prop)
311
+ ref[STATS][RETURNS] = [UNKNOWN]
312
+ ref[STATS][ARG_COUNT] = re.length - 2
313
+ ref[STATS][ARGUMENTS] = fillUknownArgs(re.length - 2)
314
+ break
315
+ case KEYWORDS.CALL_FUNCTION:
316
+ if (re.at(-1)[TYPE] === WORD) {
317
+ if (env[re.at(-1)[VALUE]])
318
+ setPropToReturnRef(ref[STATS], prop, env[re.at(-1)[VALUE]][STATS])
319
+ } else {
320
+ const returns = returnType(re.at(-1))
321
+ if (env[returns[VALUE]])
322
+ IfApplyBranch({
323
+ branch: env[returns[VALUE]],
324
+ ref,
325
+ env,
326
+ prop,
327
+ leaf: re.at(-1),
328
+ re: re.at(-1).slice(2)
329
+ })
330
+ }
331
+ break
332
+ default:
333
+ return setPropToReturnRef(ref[STATS], prop, branch[STATS])
334
+ }
335
+ }
336
+ const ifExpression = ({ re, env, ref, prop }) => {
337
+ // console.log(ref, JSON.stringify(env[KEYWORDS.IF][STATS][RETURNS]))
338
+ if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM)
339
+ return setPropToAtom(ref[STATS], prop)
255
340
  // TODO check that both brancehs are predicates if one is
256
341
  else {
257
- const concequent = isLeaf(re[0]) ? env[re[0][VALUE]] : env[re[0][0][VALUE]]
258
- const alternative = isLeaf(re[1]) ? env[re[1][VALUE]] : env[re[1][0][VALUE]]
259
- // todo check if condition matches alternative
342
+ const conc = isLeaf(re[0]) ? re[0] : re[0][0]
343
+ const alt = isLeaf(re[1]) ? re[1] : re[1][0]
344
+ const concequent = env[conc[VALUE]]
345
+ const alternative = env[alt[VALUE]]
260
346
  // TODO make this more simple - it's so many different things just because types are functions or not
261
347
  // WHY not consiter making return types for everything
262
- if (concequent && getType(concequent[STATS]) !== UNKNOWN) {
263
- if (getType(concequent[STATS]) === APPLY)
264
- setReturnRef(ref[STATS], concequent[STATS])
265
- else ref[STATS][RETURNS] = concequent[STATS][TYPE_PROP]
266
- } else if (alternative && isUnknownType(alternative[STATS])) {
267
- if (getType(alternative[STATS]) === APPLY)
268
- setReturnRef(ref[STATS], alternative[STATS])
269
- else setReturnToTypeRef(ref[STATS], alternative[STATS])
270
- } else if (concequent) {
271
- if (getType(concequent[STATS]) === APPLY)
272
- setReturnRef(ref[STATS], concequent[STATS])
273
- else setReturnToTypeRef(ref[STATS], concequent[STATS])
274
- }
275
- }
276
- }
277
- const resolveApplyAssigment = (re, name, env) => {
278
- if (re[0][TYPE] === APPLY) {
279
- switch (re[0][VALUE]) {
280
- case KEYWORDS.ANONYMOUS_FUNCTION:
281
- // FN ASSIGMENT
282
- env[name][STATS][TYPE_PROP] = [APPLY]
283
- env[name][STATS][RETURNS] = [UNKNOWN]
284
- env[name][STATS][ARG_COUNT] = re.length - 2
285
- env[name][STATS][ARGUMENTS] = fillUknownArgs(re.length - 2)
286
- break
348
+ if (concequent)
349
+ if (conc[TYPE] === WORD && conc[VALUE] !== NIL) {
350
+ return setPropToTypeRef(ref[STATS], prop, concequent[STATS])
351
+ } else if (
352
+ conc[TYPE] === APPLY &&
353
+ getType(concequent[STATS]) === APPLY &&
354
+ // Making sure the recursive function don't look for their own return type
355
+ concequent[STATS][SIGNATURE] !== ref[STATS][SIGNATURE]
356
+ ) {
357
+ return IfApplyBranch({
358
+ leaf: conc,
359
+ branch: concequent,
360
+ re: re[0],
361
+ prop,
362
+ env,
363
+ ref
364
+ })
365
+ }
366
+ if (alternative) {
367
+ if (alt[TYPE] === WORD && alt[VALUE] !== NIL) {
368
+ return setPropToTypeRef(ref[STATS], prop, alternative[STATS])
369
+ } else if (
370
+ alt[TYPE] === APPLY &&
371
+ getType(alternative[STATS]) === APPLY &&
372
+ // Making sure the recursive function don't look for their own return type
373
+ alternative[STATS][SIGNATURE] !== ref[STATS][SIGNATURE]
374
+ ) {
375
+ return IfApplyBranch({
376
+ leaf: alt,
377
+ branch: alternative,
378
+ re: re[1],
379
+ prop,
380
+ env,
381
+ ref
382
+ })
383
+ }
287
384
  }
288
385
  }
289
386
  }
290
- const resolveIfAssigment = ({ rem, name, env, exp, prop }) => {
291
- const re = rem.slice(2)
292
- checkPredicateName(exp, [[WORD, name], isLeaf(re[0]) ? re[0] : re[0][0]])
293
- checkPredicateName(exp, [[WORD, name], isLeaf(re[1]) ? re[1] : re[1][0]])
294
- if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM)
295
- // ATOM ASSIGMENT
296
- setPropToAtom(env[name][STATS], prop)
297
- else if (
298
- !isLeaf(re[0]) &&
299
- env[re[0][0][VALUE]] &&
300
- !isUnknownReturn(env[re[0][0][VALUE]][STATS])
301
- ) {
302
- setPropToReturnRef(env[name][STATS], prop, env[re[0][0][VALUE]][STATS])
303
- resolveApplyAssigment(re[0], name, env)
304
- // env[name][STATS] = env[re[0][0][VALUE]][STATS]
305
- } else if (
306
- !isLeaf(re[1]) &&
307
- env[re[1][0][VALUE]] &&
308
- !isUnknownReturn(env[re[1][0][VALUE]][STATS])
309
- ) {
310
- setPropToReturnRef(env[name][STATS], prop, env[re[1][0][VALUE]][STATS])
311
- resolveApplyAssigment(re[1], name, env)
312
- } else if (env[re[0][VALUE]])
313
- // ASSIGMENT
314
- setPropRef(env[name][STATS], prop, env[re[0][VALUE]][STATS])
315
- else if (env[re[1][VALUE]])
316
- // ASSIGMENT
317
- setPropRef(env[name][STATS], prop, env[re[1][VALUE]][STATS])
318
- }
319
- const resolveCondition = ({ rem, name, env, exp }) => {
387
+ const resolveCondition = ({ rem, name, env, exp, prop }) => {
320
388
  const ret = rem[0]
321
389
  const re = rem.slice(2)
322
- resolveApplyAssigment(re, name, env)
323
390
  const ref = env[name]
324
391
  checkPredicateName(exp, [[WORD, name], isLeaf(re[0]) ? re[0] : re[0][0]])
325
392
  checkPredicateName(exp, [[WORD, name], isLeaf(re[1]) ? re[1] : re[1][0]])
326
393
  switch (ret[VALUE]) {
327
394
  case KEYWORDS.IF:
328
- ifExpression({ re, env, ref })
395
+ ifExpression({ re, env, ref, prop })
329
396
  break
330
397
  default:
331
- if (env[ret[VALUE]]) setReturnRef(ref[STATS], env[ret[VALUE]][STATS])
398
+ if (env[ret[VALUE]]) setPropRef(ref[STATS], prop, env[ret[VALUE]][STATS])
332
399
  else
333
400
  stack.append(() => {
334
- if (env[ret[VALUE]]) setReturnRef(ref[STATS], env[ret[VALUE]][STATS])
401
+ if (env[ret[VALUE]])
402
+ setPropRef(ref[STATS], prop, env[ret[VALUE]][STATS])
335
403
  })
336
404
  break
337
405
  }
@@ -344,7 +412,7 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
344
412
  } else {
345
413
  switch (returns[VALUE]) {
346
414
  case KEYWORDS.IF:
347
- resolveIfAssigment({ rem, name, env, exp, prop })
415
+ resolveCondition({ rem, name, env, exp, prop })
348
416
  break
349
417
  default:
350
418
  checkPredicateNameDeep(name, exp, exp.slice(1), returns)
@@ -574,28 +642,30 @@ export const typeCheck = (ast, error = true) => {
574
642
  setReturnToType(ref[STATS], copy[returns[VALUE]][STATS])
575
643
  )
576
644
  else {
577
- const ret = returns[0]
578
-
579
- switch (ret[VALUE]) {
580
- case KEYWORDS.IF:
581
- resolveCondition({
582
- rem: returns,
583
- name: ref[STATS][SIGNATURE],
584
- env: copy,
585
- exp,
586
- stack
587
- })
588
- break
589
- default:
590
- if (copy[ret[VALUE]])
591
- setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
592
- else
593
- stack.append(() => {
594
- if (copy[ret[VALUE]])
595
- setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
645
+ stack.append(() => {
646
+ const ret = returns[0]
647
+ switch (ret[VALUE]) {
648
+ case KEYWORDS.IF:
649
+ resolveCondition({
650
+ rem: returns,
651
+ name: ref[STATS][SIGNATURE],
652
+ env: copy,
653
+ exp,
654
+ stack,
655
+ prop: RETURNS
596
656
  })
597
- break
598
- }
657
+ break
658
+ default:
659
+ if (copy[ret[VALUE]])
660
+ setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
661
+ else
662
+ stack.append(() => {
663
+ if (copy[ret[VALUE]])
664
+ setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
665
+ })
666
+ break
667
+ }
668
+ })
599
669
  }
600
670
  // TODO overwrite return type check here
601
671
  }
@@ -782,10 +852,11 @@ export const typeCheck = (ast, error = true) => {
782
852
  // It turns out it's not possible to determine return type of function here
783
853
  // what if it's a global function used elsewhere where the return type mwould be different
784
854
  // THIS willgive lambda return types but refactor is needed still
785
- setReturn(
786
- env[name][STATS],
787
- expectedArgs[i][STATS]
788
- )
855
+ if (!SPECIAL_FORMS_SET.has(name))
856
+ setReturn(
857
+ env[name][STATS],
858
+ expectedArgs[i][STATS]
859
+ )
789
860
  break
790
861
  }
791
862
  // TODO also handle casting
@@ -863,33 +934,50 @@ export const typeCheck = (ast, error = true) => {
863
934
  !isUnknownType(env[rest[i][VALUE]][STATS]) &&
864
935
  env[rest[i][VALUE]][STATS][ARG_COUNT] !== VARIADIC
865
936
  ) {
866
- if (getType(args[i][STATS]) !== APPLY)
867
- // TODO this should really happen in 10 or 16
868
- throw new TypeError(
869
- `Incorrect type for argument of (${
870
- first[VALUE]
871
- }) at position (${i}). Expected (${
872
- STATIC_TYPES.ABSTRACTION
873
- }) but got (${toTypeNames(
874
- getType(args[i][STATS])
875
- )}) (${stringifyArgs(exp)}) (check #111)`
876
- )
877
- // Handles words that are Lambdas
878
- else if (
937
+ // if (
938
+ // getType(args[i][STATS]) !==
939
+ // getType(env[rest[i][VALUE]][STATS][ARGUMENTS][i][STATS])
940
+ // )
941
+ // // TODO this should really happen in 10 or 16
942
+ // throw new TypeError(
943
+ // `Incorrect type for argument of (${
944
+ // first[VALUE]
945
+ // }) at position (${i}). Expected (${
946
+ // STATIC_TYPES.ABSTRACTION
947
+ // }) but got (${toTypeNames(
948
+ // getType(
949
+ // env[rest[i][VALUE]][STATS][ARGUMENTS][i][STATS]
950
+ // )
951
+ // )}) (${stringifyArgs(exp)}) (check #111)`
952
+ // )
953
+ // // Handles words that are Lambdas
954
+ // else
955
+ if (
879
956
  env[rest[i][VALUE]][STATS][ARG_COUNT] !==
880
957
  args[i][STATS][ARG_COUNT]
881
958
  ) {
882
- throw new TypeError(
883
- `Incorrect number of arguments for (${
884
- args[i][STATS][SIGNATURE]
885
- }) the (lambda) argument of (${
886
- first[VALUE]
887
- }) at position (${i}). Expected (= ${
888
- args[i][STATS][ARG_COUNT]
889
- }) but got ${
890
- env[rest[i][VALUE]][STATS][ARG_COUNT]
891
- } (${stringifyArgs(exp)}) (check #778)`
892
- )
959
+ if (args[i][STATS][ARG_COUNT] === undefined)
960
+ throw new TypeError(
961
+ `Incorrect type for argument of (${
962
+ first[VALUE]
963
+ }) at position (${i}). Expected (${
964
+ STATIC_TYPES.ABSTRACTION
965
+ }) but got (${toTypeNames(
966
+ getType(args[i][STATS])
967
+ )}) (${stringifyArgs(exp)}) (check #111)`
968
+ )
969
+ else if (getType(args[i][STATS]) === APPLY)
970
+ throw new TypeError(
971
+ `Incorrect number of arguments for (${
972
+ args[i][STATS][SIGNATURE]
973
+ }) the (lambda) argument of (${
974
+ first[VALUE]
975
+ }) at position (${i}). Expected (= ${
976
+ args[i][STATS][ARG_COUNT]
977
+ }) but got ${
978
+ env[rest[i][VALUE]][STATS][ARG_COUNT]
979
+ } (${stringifyArgs(exp)}) (check #778)`
980
+ )
893
981
  } else {
894
982
  // DEFINED LAMBDAS TYPE CHECKING
895
983
  // #C1
@@ -1122,7 +1210,6 @@ export const typeCheck = (ast, error = true) => {
1122
1210
  }
1123
1211
  }
1124
1212
  })
1125
-
1126
1213
  for (let i = 0; i < rest.length; ++i) {
1127
1214
  const r = rest[i]
1128
1215
  if (isLeaf(r) && r[TYPE] !== ATOM)
package/src/macros.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  WORD
17
17
  } from './keywords.js'
18
18
  import { hasBlock, stringifyArgs } from './utils.js'
19
+ import { NIL } from './types.js'
19
20
  export const SUGGAR = {
20
21
  // Syntactic suggars
21
22
  PIPE: '|>',
@@ -357,7 +358,7 @@ export const deSuggarAst = (ast, scope) => {
357
358
  )
358
359
  exp[0][VALUE] = KEYWORDS.IF
359
360
  const temp = exp[2]
360
- exp[2] = exp[3] ?? [ATOM, FALSE]
361
+ exp[2] = exp[3] ?? [WORD, NIL]
361
362
  exp[3] = temp
362
363
  }
363
364
  deSuggarAst(exp, scope)
@@ -372,7 +373,7 @@ export const deSuggarAst = (ast, scope) => {
372
373
  KEYWORDS.IF
373
374
  } ${stringifyArgs(rest)})`
374
375
  )
375
- if (rest.length === 2) exp.push([ATOM, FALSE])
376
+ if (rest.length === 2) exp.push([WORD, NIL])
376
377
  }
377
378
  deSuggarAst(exp[1], scope)
378
379
  break
package/src/types.js CHANGED
@@ -24,6 +24,7 @@ export const ANY = 5
24
24
  export const ANONYMOUS_FUNCTION_TYPE_PREFIX = 'lambda::annonymous::'
25
25
  export const MAX_ARGUMENT_RETRY = 1
26
26
  export const MAX_RETRY_DEFINITION = 100
27
+ export const NIL = 'nil'
27
28
  export const toTypeNames = (type) => {
28
29
  switch (type) {
29
30
  case APPLY: