fez-lisp 1.5.126 → 1.5.128
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 +138 -45
- package/src/compiler.js +1 -0
- package/src/interpreter.js +1 -0
- package/src/keywords.js +1 -0
- package/src/types.js +24 -4
- package/src/utils.js +5 -0
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -52,6 +52,7 @@ import {
|
|
52
52
|
getSuffix,
|
53
53
|
hasApplyLambdaBlock,
|
54
54
|
hasBlock,
|
55
|
+
log,
|
55
56
|
logExp,
|
56
57
|
stringifyArgs
|
57
58
|
} from './utils.js'
|
@@ -113,10 +114,16 @@ export const isUnknownNotAnyType = (stats) =>
|
|
113
114
|
export const isUnknownNotAnyReturn = (stats) =>
|
114
115
|
stats && !isAnyReturn(stats) && isUnknownReturn(stats)
|
115
116
|
export const castType = (stats, type) => {
|
116
|
-
return (
|
117
|
+
return (
|
118
|
+
(stats[TYPE_PROP][0] = type[RETURNS][0]),
|
119
|
+
(stats[TYPE_PROP][1] = type[RETURNS][1])
|
120
|
+
)
|
117
121
|
}
|
118
122
|
export const castReturn = (stats, type) => {
|
119
|
-
return (
|
123
|
+
return (
|
124
|
+
(stats[RETURNS][0] = type[RETURNS][0]),
|
125
|
+
(stats[RETURNS][1] = type[RETURNS][1])
|
126
|
+
)
|
120
127
|
}
|
121
128
|
export const isTypeAbstraction = (stats) => stats[TYPE_PROP] === APPLY
|
122
129
|
export const setPropToAtom = (stats, prop) => {
|
@@ -129,7 +136,7 @@ export const setPropToPredicate = (stats, prop) => {
|
|
129
136
|
return (stats[prop][1] = BOOLEAN_SUBTYPE())
|
130
137
|
}
|
131
138
|
export const setReturnToPredicate = (stats) => {
|
132
|
-
return (stats[RETURNS][
|
139
|
+
return (stats[RETURNS][0] = BOOLEAN_SUBTYPE())
|
133
140
|
}
|
134
141
|
export const setTypeToPredicate = (stats) => {
|
135
142
|
return (stats[RETURNS][1] = BOOLEAN_SUBTYPE())
|
@@ -195,6 +202,9 @@ export const setTypeRef = (stats, value) =>
|
|
195
202
|
(isUnknownType(stats) || isAnyType(stats)) &&
|
196
203
|
(stats[TYPE_PROP] = value[TYPE_PROP])
|
197
204
|
export const setReturnRef = (stats, value) => {
|
205
|
+
if (SPECIAL_FORMS_SET.has(value[SIGNATURE])) {
|
206
|
+
return setReturn(stats, value)
|
207
|
+
}
|
198
208
|
return isUnknownReturn(stats) && (stats[RETURNS] = value[RETURNS])
|
199
209
|
}
|
200
210
|
export const setReturnToTypeRef = (stats, value) => {
|
@@ -237,7 +247,7 @@ export const setPropToSubType = (stats, prop, value) =>
|
|
237
247
|
hasSubType(value) && (stats[prop][1] = value[TYPE_PROP][1])
|
238
248
|
export const setPropToSubReturn = (stats, prop, value) =>
|
239
249
|
// makes no senseto protect this for now
|
240
|
-
|
250
|
+
hasSubReturn(value) && (stats[prop][1] = value[RETURNS][1])
|
241
251
|
export const setTypeToReturn = (stats, value) =>
|
242
252
|
(isUnknownType(stats) || isAnyType(stats)) &&
|
243
253
|
!isUnknownReturn(value) &&
|
@@ -264,12 +274,25 @@ export const getSubType = (stats) => stats && stats[TYPE_PROP][1]
|
|
264
274
|
export const hasSubType = (stats) => stats && stats[TYPE_PROP][1] instanceof Set
|
265
275
|
export const getSubReturn = (stats) => stats && stats[RETURNS][1]
|
266
276
|
export const hasSubReturn = (stats) => stats && stats[RETURNS][1] instanceof Set
|
277
|
+
export const isUknownSubReturn = (stats) =>
|
278
|
+
!hasSubReturn(stats) ||
|
279
|
+
(stats[RETURNS][1].size === 1 && stats[RETURNS][1].has(UNKNOWN))
|
280
|
+
export const isUknownSubType = (stats) =>
|
281
|
+
hasSubType(stats) &&
|
282
|
+
stats[TYPE_PROP][1].size === 1 &&
|
283
|
+
stats[TYPE_PROP][1].has(UNKNOWN)
|
267
284
|
export const isAtomType = (stats) =>
|
268
285
|
isAnyType(stats) || stats[TYPE_PROP][0] === ATOM
|
269
286
|
export const isAtomReturn = (stats) =>
|
270
287
|
isAnyType(stats) || stats[RETURNS][0] === ATOM
|
271
|
-
export const compareTypes = (a, b) =>
|
272
|
-
isAnyType(a) || isAnyType(b)
|
288
|
+
export const compareTypes = (a, b) => {
|
289
|
+
const isAnyAny = isAnyType(a) || isAnyType(b)
|
290
|
+
if (isAnyAny) return true
|
291
|
+
const isSameType = a[TYPE_PROP][0] === b[TYPE_PROP][0]
|
292
|
+
if (!isSameType) return false
|
293
|
+
return true
|
294
|
+
}
|
295
|
+
|
273
296
|
export const compareReturns = (a, b) =>
|
274
297
|
isAnyReturn(a) || isAnyReturn(b) || a[RETURNS][0] === b[RETURNS][0]
|
275
298
|
export const compareTypeWithReturn = (a, b) =>
|
@@ -294,15 +317,25 @@ const notABooleanType = (a, b) => {
|
|
294
317
|
(!hasSubType(b) || getSubType(a).difference(getSubType(b)).size !== 0)
|
295
318
|
)
|
296
319
|
}
|
320
|
+
// const notABooleanReturn = (a, b) => {
|
321
|
+
// return (
|
322
|
+
// hasSubType(a) &&
|
323
|
+
// getSubType(a).has(PREDICATE) &&
|
324
|
+
// !isUnknownReturn(b) &&
|
325
|
+
// !isAnyReturn(b) &&
|
326
|
+
// (
|
327
|
+
// !isAtomReturn(b) ||
|
328
|
+
// !hasSubReturn(b) ||
|
329
|
+
// getSubType(a).difference(getSubReturn(b)).size !== 0)
|
330
|
+
// )
|
331
|
+
// }
|
297
332
|
const notABooleanReturn = (a, b) => {
|
298
333
|
return (
|
299
334
|
hasSubType(a) &&
|
300
335
|
getSubType(a).has(PREDICATE) &&
|
301
336
|
!isUnknownReturn(b) &&
|
302
337
|
!isAnyReturn(b) &&
|
303
|
-
(!
|
304
|
-
!hasSubReturn(b) ||
|
305
|
-
getSubType(a).difference(getSubReturn(b)).size !== 0)
|
338
|
+
(!hasSubReturn(b) || getSubType(a).difference(getSubReturn(b)).size !== 0)
|
306
339
|
)
|
307
340
|
}
|
308
341
|
const isAtomABoolean = (atom) => atom === TRUE || atom === FALSE
|
@@ -516,39 +549,44 @@ const resolveSetter = (first, rest, env) => {
|
|
516
549
|
) {
|
517
550
|
const name = rest[0][VALUE]
|
518
551
|
const current = env[name]
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
if (env[right[VALUE]])
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
if (
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
current[STATS][TYPE_PROP][1] = new Set([
|
545
|
-
env[right[VALUE]][STATS][RETURNS][0]
|
546
|
-
])
|
552
|
+
const right = isLeaf(rest.at(-1)) ? rest.at(-1) : rest.at(-1)[0]
|
553
|
+
switch (right[TYPE]) {
|
554
|
+
case ATOM:
|
555
|
+
current[STATS][TYPE_PROP][1] = new Set([NUMBER])
|
556
|
+
break
|
557
|
+
case WORD:
|
558
|
+
if (env[right[VALUE]]) {
|
559
|
+
if (hasSubType(env[right[VALUE]][STATS]))
|
560
|
+
current[STATS][TYPE_PROP][1] = new Set(
|
561
|
+
getSubType(env[right[VALUE]][STATS])
|
562
|
+
)
|
563
|
+
else
|
564
|
+
current[STATS][TYPE_PROP][1] = new Set([
|
565
|
+
getType(env[right[VALUE]][STATS])
|
566
|
+
])
|
567
|
+
}
|
568
|
+
break
|
569
|
+
case APPLY:
|
570
|
+
if (env[right[VALUE]]) {
|
571
|
+
if (right[VALUE] === KEYWORDS.CREATE_ARRAY) {
|
572
|
+
current[STATS][TYPE_PROP][1] = (initArrayType({
|
573
|
+
rem: rest.at(-1),
|
574
|
+
env
|
575
|
+
}) ?? { [RETURNS]: [COLLECTION, new Set([])] })[RETURNS][1]
|
576
|
+
break
|
547
577
|
}
|
548
|
-
|
549
|
-
|
550
|
-
|
578
|
+
if (hasSubReturn(env[right[VALUE]][STATS]))
|
579
|
+
current[STATS][TYPE_PROP][1] = new Set([
|
580
|
+
...getSubReturn(env[right[VALUE]][STATS])
|
581
|
+
])
|
582
|
+
else if (!isUnknownReturn(env[right[VALUE]][STATS]))
|
583
|
+
current[STATS][TYPE_PROP][1] = new Set([
|
584
|
+
getReturn(env[right[VALUE]][STATS])
|
585
|
+
])
|
586
|
+
}
|
587
|
+
break
|
551
588
|
}
|
589
|
+
setTypeToCollection(current[STATS])
|
552
590
|
}
|
553
591
|
}
|
554
592
|
const resolveGetter = ({ rem, prop, name, env }) => {
|
@@ -572,7 +610,10 @@ const resolveGetter = ({ rem, prop, name, env }) => {
|
|
572
610
|
{
|
573
611
|
if (hasSubType(env[array[VALUE]][STATS])) {
|
574
612
|
const rightSub = getSubType(env[array[VALUE]][STATS])
|
575
|
-
const isAtom =
|
613
|
+
const isAtom =
|
614
|
+
rightSub.has(ATOM) ||
|
615
|
+
rightSub.has(NUMBER) ||
|
616
|
+
rightSub.has(PREDICATE)
|
576
617
|
const isCollection = rightSub.has(COLLECTION)
|
577
618
|
if (isAtom && !isCollection) {
|
578
619
|
setPropToAtom(env[name][STATS], prop)
|
@@ -586,12 +627,45 @@ const resolveGetter = ({ rem, prop, name, env }) => {
|
|
586
627
|
}
|
587
628
|
return true
|
588
629
|
}
|
630
|
+
const initArrayType = ({ rem, env }) => {
|
631
|
+
const ret = rem
|
632
|
+
.slice(1)
|
633
|
+
.map((x) =>
|
634
|
+
isLeaf(x)
|
635
|
+
? x[TYPE] === WORD
|
636
|
+
? env[x[VALUE]]
|
637
|
+
? getTypes(env[x[VALUE]][STATS])
|
638
|
+
: [UNKNOWN]
|
639
|
+
: [x[TYPE]]
|
640
|
+
: env[x[0][VALUE]]
|
641
|
+
? getReturns(env[x[0][VALUE]][STATS])
|
642
|
+
: [UNKNOWN]
|
643
|
+
)
|
644
|
+
const known = ret.find((x) => x[0] !== ANY && x[0] !== UNKNOWN)
|
645
|
+
if (
|
646
|
+
known &&
|
647
|
+
ret.length &&
|
648
|
+
!ret.some((x) => known[0] !== x[0] || known.length !== x.length)
|
649
|
+
) {
|
650
|
+
const [main, sub] = ret[0]
|
651
|
+
return {
|
652
|
+
[TYPE_PROP]: [APPLY],
|
653
|
+
[RETURNS]: [COLLECTION, new Set(sub ? [...sub] : [main])]
|
654
|
+
}
|
655
|
+
}
|
656
|
+
}
|
589
657
|
const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
|
590
658
|
if (returns[TYPE] === ATOM) {
|
591
659
|
// ATOM ASSIGMENT
|
592
660
|
setPropToAtom(env[name][STATS], prop)
|
593
661
|
} else {
|
594
662
|
switch (returns[VALUE]) {
|
663
|
+
case KEYWORDS.CREATE_ARRAY:
|
664
|
+
{
|
665
|
+
const r = initArrayType({ rem, env })
|
666
|
+
if (r) setPropToSubReturn(env[name][STATS], prop, r)
|
667
|
+
}
|
668
|
+
break
|
595
669
|
case KEYWORDS.IF:
|
596
670
|
resolveCondition({ rem, name, env, exp, prop })
|
597
671
|
break
|
@@ -881,6 +955,7 @@ export const typeCheck = (ast) => {
|
|
881
955
|
case STATIC_TYPES.ATOM:
|
882
956
|
case STATIC_TYPES.PREDICATE:
|
883
957
|
case STATIC_TYPES.ANY:
|
958
|
+
case STATIC_TYPES.NUMBER:
|
884
959
|
{
|
885
960
|
const ret = isLeaf(rest[0]) ? rest[0] : rest[0][0]
|
886
961
|
const ref = env[ret[VALUE]]
|
@@ -1071,7 +1146,21 @@ export const typeCheck = (ast) => {
|
|
1071
1146
|
getTypes(env[name][STATS])
|
1072
1147
|
)}) (${stringifyArgs(exp)}) (check #202)`
|
1073
1148
|
)
|
1074
|
-
else
|
1149
|
+
else {
|
1150
|
+
// TODO the special form will set type first but it
|
1151
|
+
// might be known already
|
1152
|
+
// example
|
1153
|
+
// (let xs [])
|
1154
|
+
// (let x (array:set-and-get! xs 0 100))
|
1155
|
+
// (length x)
|
1156
|
+
//
|
1157
|
+
// if (isUnknownType(env[name][STATS])) {
|
1158
|
+
// retry(env[name][STATS], stack, () =>
|
1159
|
+
// check(exp, env, scope)
|
1160
|
+
// )
|
1161
|
+
// } else
|
1162
|
+
setType(env[name][STATS], args[i][STATS])
|
1163
|
+
}
|
1075
1164
|
}
|
1076
1165
|
break
|
1077
1166
|
case ATOM: {
|
@@ -1298,7 +1387,11 @@ export const typeCheck = (ast) => {
|
|
1298
1387
|
}
|
1299
1388
|
} else if (env[rest[i][0][VALUE]]) {
|
1300
1389
|
const match = () => {
|
1301
|
-
const actual =
|
1390
|
+
const actual =
|
1391
|
+
rest[i][0][VALUE] === KEYWORDS.CREATE_ARRAY
|
1392
|
+
? initArrayType({ rem: rest[i], env }) ??
|
1393
|
+
env[rest[i][0][VALUE]][STATS]
|
1394
|
+
: env[rest[i][0][VALUE]][STATS]
|
1302
1395
|
const expected = args[i][STATS]
|
1303
1396
|
retryArgs(args[i][STATS], stack, () => match())
|
1304
1397
|
if (!isUnknownType(expected) && !isUnknownReturn(actual))
|
@@ -1314,13 +1407,13 @@ export const typeCheck = (ast) => {
|
|
1314
1407
|
)
|
1315
1408
|
else if (notABooleanReturn(expected, actual)) {
|
1316
1409
|
throw new TypeError(
|
1317
|
-
`Incorrect type of argument (${i}) for
|
1410
|
+
`Incorrect type of argument (${i}) for (${
|
1318
1411
|
first[VALUE]
|
1319
1412
|
}). Expected (${formatSubType(
|
1320
1413
|
getTypes(expected)
|
1321
1414
|
)}) but got (${formatSubType(
|
1322
1415
|
getReturns(actual)
|
1323
|
-
)}) (${stringifyArgs(exp)}) (check #
|
1416
|
+
)}) (${stringifyArgs(exp)}) (check #206)`
|
1324
1417
|
)
|
1325
1418
|
} else {
|
1326
1419
|
switch (getType(expected)) {
|
package/src/compiler.js
CHANGED
package/src/interpreter.js
CHANGED
@@ -837,6 +837,7 @@ export const keywords = {
|
|
837
837
|
[STATIC_TYPES.ATOM]: (args, env) => evaluate(args[0], env),
|
838
838
|
[STATIC_TYPES.COLLECTION]: (args, env) => evaluate(args[0], env),
|
839
839
|
[STATIC_TYPES.PREDICATE]: (args, env) => evaluate(args[0], env),
|
840
|
+
[STATIC_TYPES.NUMBER]: (args, env) => evaluate(args[0], env),
|
840
841
|
[STATIC_TYPES.UNKNOWN]: (args, env) => evaluate(args[0], env),
|
841
842
|
[STATIC_TYPES.ANY]: (args, env) => evaluate(args[0], env)
|
842
843
|
}
|
package/src/keywords.js
CHANGED
package/src/types.js
CHANGED
@@ -30,7 +30,6 @@ export const NIL = 'nil'
|
|
30
30
|
export const TRUE_WORD = 'true'
|
31
31
|
export const FALSE_WORD = 'false'
|
32
32
|
export const BOOLEAN_SUBTYPE = () => new Set([PREDICATE])
|
33
|
-
export const ANY_SUBTYPE = () => new Set([ANY])
|
34
33
|
export const COLLECTION_SUBTYPE = () => new Set([COLLECTION])
|
35
34
|
export const NUMBER_SUBTYPE = () => new Set([NUMBER])
|
36
35
|
|
@@ -134,6 +133,27 @@ export const SPECIAL_FORM_TYPES = {
|
|
134
133
|
[RETURNS]: [ATOM, BOOLEAN_SUBTYPE()]
|
135
134
|
}
|
136
135
|
},
|
136
|
+
[STATIC_TYPES.NUMBER]: {
|
137
|
+
[STATS]: {
|
138
|
+
[TYPE_PROP]: [APPLY],
|
139
|
+
[SIGNATURE]: STATIC_TYPES.NUMBER,
|
140
|
+
retried: Infinity,
|
141
|
+
[ARG_COUNT]: 1,
|
142
|
+
[ARGUMENTS]: [
|
143
|
+
{
|
144
|
+
[STATS]: {
|
145
|
+
retried: Infinity,
|
146
|
+
[SIGNATURE]: PLACEHOLDER,
|
147
|
+
[TYPE_PROP]: [UNKNOWN],
|
148
|
+
[RETURNS]: [UNKNOWN],
|
149
|
+
[ARGUMENTS]: [],
|
150
|
+
[ARG_COUNT]: 0
|
151
|
+
}
|
152
|
+
}
|
153
|
+
],
|
154
|
+
[RETURNS]: [ATOM, NUMBER_SUBTYPE()]
|
155
|
+
}
|
156
|
+
},
|
137
157
|
[STATIC_TYPES.COLLECTION]: {
|
138
158
|
[STATS]: {
|
139
159
|
[TYPE_PROP]: [APPLY],
|
@@ -765,8 +785,8 @@ export const SPECIAL_FORM_TYPES = {
|
|
765
785
|
[STATS]: {
|
766
786
|
retried: 0,
|
767
787
|
[SIGNATURE]: PLACEHOLDER,
|
768
|
-
[TYPE_PROP]: [COLLECTION
|
769
|
-
[RETURNS]: [COLLECTION
|
788
|
+
[TYPE_PROP]: [COLLECTION],
|
789
|
+
[RETURNS]: [COLLECTION],
|
770
790
|
|
771
791
|
[ARGUMENTS]: [],
|
772
792
|
[ARG_COUNT]: 0
|
@@ -795,7 +815,7 @@ export const SPECIAL_FORM_TYPES = {
|
|
795
815
|
}
|
796
816
|
}
|
797
817
|
],
|
798
|
-
[RETURNS]: [COLLECTION
|
818
|
+
[RETURNS]: [COLLECTION]
|
799
819
|
}
|
800
820
|
},
|
801
821
|
[KEYWORDS.POP_ARRAY]: {
|
package/src/utils.js
CHANGED
@@ -24,6 +24,10 @@ export const logExp = function (exp, ...args) {
|
|
24
24
|
console.log(wrapInBracesString(exp), ...args)
|
25
25
|
return exp
|
26
26
|
}
|
27
|
+
export const log = (x) => {
|
28
|
+
console.log(x)
|
29
|
+
return x
|
30
|
+
}
|
27
31
|
export const formatCallstack = (callstack) =>
|
28
32
|
callstack
|
29
33
|
.reverse()
|
@@ -332,6 +336,7 @@ export const addTypeIdentities = (ast) => {
|
|
332
336
|
identity(STATIC_TYPES.ATOM),
|
333
337
|
identity(STATIC_TYPES.COLLECTION),
|
334
338
|
identity(STATIC_TYPES.PREDICATE),
|
339
|
+
identity(STATIC_TYPES.NUMBER),
|
335
340
|
identity(STATIC_TYPES.ANY),
|
336
341
|
identity(STATIC_TYPES.UNKNOWN)
|
337
342
|
)
|