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/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/check.js +268 -181
- package/src/macros.js +3 -2
- package/src/types.js +1 -0
package/package.json
CHANGED
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
|
-
|
77
|
-
|
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
|
-
(
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
export const
|
99
|
-
(
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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)
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
)
|
185
|
-
|
186
|
-
|
187
|
-
|
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
|
254
|
-
|
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
|
258
|
-
const
|
259
|
-
|
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
|
263
|
-
if (
|
264
|
-
|
265
|
-
else
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
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
|
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]])
|
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]])
|
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
|
-
|
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
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
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
|
-
|
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
|
-
|
786
|
-
|
787
|
-
|
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 (
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
//
|
878
|
-
|
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
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
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] ?? [
|
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([
|
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:
|