fez-lisp 1.5.110 → 1.5.111
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 +1 -1
- package/src/check.js +99 -27
- package/src/types.js +2 -1
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -41,7 +41,9 @@ import {
|
|
41
41
|
NIL,
|
42
42
|
TRUE_WORD,
|
43
43
|
FALSE_WORD,
|
44
|
-
BOOLEAN_SUBTYPE
|
44
|
+
BOOLEAN_SUBTYPE,
|
45
|
+
formatSubType,
|
46
|
+
PREDICATE
|
45
47
|
} from './types.js'
|
46
48
|
import {
|
47
49
|
Brr,
|
@@ -51,7 +53,35 @@ import {
|
|
51
53
|
logExp,
|
52
54
|
stringifyArgs
|
53
55
|
} from './utils.js'
|
56
|
+
Set.prototype.union = function (B) {
|
57
|
+
const A = this
|
58
|
+
const out = new Set()
|
59
|
+
A.forEach((element) => out.add(element))
|
60
|
+
B.forEach((element) => out.add(element))
|
61
|
+
return out
|
62
|
+
}
|
63
|
+
|
64
|
+
Set.prototype.xor = function (B) {
|
65
|
+
const A = this
|
66
|
+
const out = new Set()
|
67
|
+
B.forEach((element) => !A.has(element) && out.add(element))
|
68
|
+
A.forEach((element) => !B.has(element) && out.add(element))
|
69
|
+
return out
|
70
|
+
}
|
54
71
|
|
72
|
+
Set.prototype.intersection = function (B) {
|
73
|
+
const A = this
|
74
|
+
const out = new Set()
|
75
|
+
B.forEach((element) => A.has(element) && out.add(element))
|
76
|
+
return out
|
77
|
+
}
|
78
|
+
|
79
|
+
Set.prototype.difference = function (B) {
|
80
|
+
const A = this
|
81
|
+
const out = new Set()
|
82
|
+
A.forEach((element) => !B.has(element) && out.add(element))
|
83
|
+
return out
|
84
|
+
}
|
55
85
|
export const identity = (name) => [
|
56
86
|
[0, 'let'],
|
57
87
|
[1, name],
|
@@ -214,6 +244,10 @@ export const getType = (stats) => stats && stats[TYPE_PROP][0]
|
|
214
244
|
export const getTypes = (stats) => stats && stats[TYPE_PROP]
|
215
245
|
export const getReturn = (stats) => stats && stats[RETURNS][0]
|
216
246
|
export const getReturns = (stats) => stats && stats[RETURNS]
|
247
|
+
export const getSubType = (stats) => stats && stats[TYPE_PROP][1]
|
248
|
+
export const hasSubType = (stats) => stats && stats[TYPE_PROP][1] instanceof Set
|
249
|
+
export const getSubReturn = (stats) => stats && stats[RETURNS][1]
|
250
|
+
export const hasSubReturn = (stats) => stats && stats[RETURNS][1] instanceof Set
|
217
251
|
export const isAtomType = (stats) =>
|
218
252
|
isAnyType(stats) || stats[TYPE_PROP][0] === ATOM
|
219
253
|
export const isAtomReturn = (stats) =>
|
@@ -234,6 +268,20 @@ const IsPredicate = (leaf) =>
|
|
234
268
|
(leaf[TYPE] === APPLY &&
|
235
269
|
(PREDICATES_OUTPUT_SET.has(leaf[VALUE]) ||
|
236
270
|
getSuffix(leaf[VALUE]) === PREDICATE_SUFFIX))
|
271
|
+
|
272
|
+
const notABooleanType = (a, b) =>
|
273
|
+
hasSubType(a) &&
|
274
|
+
getSubType(a).has(PREDICATE) &&
|
275
|
+
!isUnknownType(b) &&
|
276
|
+
!isAnyType(b) &&
|
277
|
+
(!hasSubType(b) || getSubType(a).difference(getSubType(b)).size !== 0)
|
278
|
+
const notABooleanReturn = (a, b) =>
|
279
|
+
hasSubType(a) &&
|
280
|
+
getSubType(a).has(PREDICATE) &&
|
281
|
+
!isUnknownReturn(b) &&
|
282
|
+
!isAnyReturn(b) &&
|
283
|
+
(!hasSubReturn(b) || getSubType(a).difference(getSubReturn(b)).size !== 0)
|
284
|
+
const isAtomABoolean = (atom) => atom === TRUE || atom === FALSE
|
237
285
|
const checkPredicateName = (exp, rest) => {
|
238
286
|
if (getSuffix(rest[0][VALUE]) === PREDICATE_SUFFIX) {
|
239
287
|
const last = rest.at(-1)
|
@@ -789,34 +837,42 @@ export const typeCheck = (ast, error = true) => {
|
|
789
837
|
// also type of arg
|
790
838
|
const args = env[first[VALUE]][STATS][ARGUMENTS] ?? []
|
791
839
|
for (let i = 0; i < args.length; ++i) {
|
792
|
-
const
|
840
|
+
const isResLeaf = isLeaf(rest[i])
|
793
841
|
// type check
|
794
842
|
// TODO get rof pred type
|
795
843
|
// const PRED_TYPE = args[i][STATS][TYPE_PROP][1]
|
796
844
|
const MAIN_TYPE = getType(args[i][STATS])
|
797
845
|
if (MAIN_TYPE === ANY) continue
|
798
846
|
if (first[TYPE] === APPLY && isSpecial) {
|
799
|
-
|
800
|
-
if (!isRestILeaf) {
|
847
|
+
if (!isResLeaf) {
|
801
848
|
const name = rest[i][0][VALUE]
|
802
849
|
if (!env[name]) continue
|
803
850
|
if (
|
804
851
|
!isUnknownReturn(env[name][STATS]) &&
|
805
|
-
!compareTypeWithReturn(
|
806
|
-
expectedArgs[i][STATS],
|
807
|
-
env[name][STATS]
|
808
|
-
)
|
852
|
+
!compareTypeWithReturn(args[i][STATS], env[name][STATS])
|
809
853
|
)
|
810
854
|
throw new TypeError(
|
811
855
|
`Incorrect type of argument (${i}) for special form (${
|
812
856
|
first[VALUE]
|
813
857
|
}). Expected (${toTypeNames(
|
814
|
-
getType(
|
858
|
+
getType(args[i][STATS])
|
815
859
|
)}) but got (${toTypeNames(
|
816
860
|
getReturn(env[name][STATS])
|
817
861
|
)}) (${stringifyArgs(exp)}) (check #1)`
|
818
862
|
)
|
819
|
-
else
|
863
|
+
else if (
|
864
|
+
notABooleanReturn(args[i][STATS], env[name][STATS])
|
865
|
+
) {
|
866
|
+
throw new TypeError(
|
867
|
+
`Incorrect type of argument (${i}) for special form (${
|
868
|
+
first[VALUE]
|
869
|
+
}). Expected (${formatSubType(
|
870
|
+
getTypes(args[i][STATS])
|
871
|
+
)}) but got (${formatSubType(
|
872
|
+
getReturns(env[name][STATS])
|
873
|
+
)}) (${stringifyArgs(exp)}) (check #201)`
|
874
|
+
)
|
875
|
+
} else {
|
820
876
|
if (env[name] && getType(env[name][STATS]) === APPLY)
|
821
877
|
switch (first[VALUE]) {
|
822
878
|
case KEYWORDS.IF:
|
@@ -827,10 +883,7 @@ export const typeCheck = (ast, error = true) => {
|
|
827
883
|
// what if it's a global function used elsewhere where the return type mwould be different
|
828
884
|
// THIS willgive lambda return types but refactor is needed still
|
829
885
|
if (!SPECIAL_FORMS_SET.has(name))
|
830
|
-
setReturn(
|
831
|
-
env[name][STATS],
|
832
|
-
expectedArgs[i][STATS]
|
833
|
-
)
|
886
|
+
setReturn(env[name][STATS], args[i][STATS])
|
834
887
|
break
|
835
888
|
}
|
836
889
|
// TODO also handle casting
|
@@ -843,45 +896,64 @@ export const typeCheck = (ast, error = true) => {
|
|
843
896
|
if (!env[name]) continue
|
844
897
|
if (
|
845
898
|
!isUnknownType(env[name][STATS]) &&
|
846
|
-
!compareTypes(
|
847
|
-
expectedArgs[i][STATS],
|
848
|
-
env[name][STATS]
|
849
|
-
)
|
899
|
+
!compareTypes(args[i][STATS], env[name][STATS])
|
850
900
|
)
|
851
901
|
throw new TypeError(
|
852
902
|
`Incorrect type of argument (${i}) for special form (${
|
853
903
|
first[VALUE]
|
854
904
|
}). Expected (${toTypeNames(
|
855
|
-
getType(
|
905
|
+
getType(args[i][STATS])
|
856
906
|
)}) but got (${toTypeNames(
|
857
907
|
getType(env[name][STATS])
|
858
908
|
)}) (${stringifyArgs(exp)}) (check #3)`
|
859
909
|
)
|
860
|
-
else
|
861
|
-
|
910
|
+
else if (
|
911
|
+
notABooleanType(args[i][STATS], env[name][STATS])
|
912
|
+
)
|
913
|
+
throw new TypeError(
|
914
|
+
`Incorrect type of argument (${i}) for special form (${
|
915
|
+
first[VALUE]
|
916
|
+
}). Expected (${formatSubType(
|
917
|
+
getTypes(args[i][STATS])
|
918
|
+
)}) but got (${formatSubType(
|
919
|
+
getTypes(env[name][STATS])
|
920
|
+
)}) (${stringifyArgs(exp)}) (check #202)`
|
921
|
+
)
|
922
|
+
else setType(env[name][STATS], args[i][STATS])
|
862
923
|
}
|
863
924
|
break
|
864
925
|
case ATOM: {
|
865
|
-
if (
|
866
|
-
rest[i][TYPE] !==
|
867
|
-
expectedArgs[i][STATS][TYPE_PROP][0]
|
868
|
-
)
|
926
|
+
if (rest[i][TYPE] !== args[i][STATS][TYPE_PROP][0])
|
869
927
|
throw new TypeError(
|
870
928
|
`Incorrect type of argument (${i}) for special form (${
|
871
929
|
first[VALUE]
|
872
930
|
}). Expected (${toTypeNames(
|
873
|
-
|
931
|
+
args[i][STATS][TYPE_PROP][0]
|
874
932
|
)}) but got (${toTypeNames(
|
875
933
|
rest[i][TYPE]
|
876
934
|
)}) (${stringifyArgs(exp)}) (check #2)`
|
877
935
|
)
|
936
|
+
else if (
|
937
|
+
hasSubType(args[i][STATS]) &&
|
938
|
+
getSubType(args[i][STATS]).has(PREDICATE) &&
|
939
|
+
!isAtomABoolean(rest[i][VALUE])
|
940
|
+
)
|
941
|
+
throw new TypeError(
|
942
|
+
`Incorrect type of argument (${i}) for special form (${
|
943
|
+
first[VALUE]
|
944
|
+
}). Expected (${formatSubType(
|
945
|
+
getTypes(args[i][STATS])
|
946
|
+
)}) but got (${rest[i][VALUE]}) (${stringifyArgs(
|
947
|
+
exp
|
948
|
+
)}) (check #203)`
|
949
|
+
)
|
878
950
|
break
|
879
951
|
}
|
880
952
|
}
|
881
953
|
}
|
882
954
|
}
|
883
955
|
// type checking
|
884
|
-
else if (
|
956
|
+
else if (isResLeaf) {
|
885
957
|
const T =
|
886
958
|
rest[i][TYPE] === WORD
|
887
959
|
? env[rest[i][VALUE]]
|
package/src/types.js
CHANGED
@@ -29,6 +29,7 @@ export const NIL = 'nil'
|
|
29
29
|
export const TRUE_WORD = 'true'
|
30
30
|
export const FALSE_WORD = 'false'
|
31
31
|
export const BOOLEAN_SUBTYPE = () => new Set([PREDICATE])
|
32
|
+
|
32
33
|
export const toTypeNames = (type) => {
|
33
34
|
switch (type) {
|
34
35
|
case APPLY:
|
@@ -1180,7 +1181,7 @@ export const SPECIAL_FORM_TYPES = {
|
|
1180
1181
|
}
|
1181
1182
|
}
|
1182
1183
|
|
1183
|
-
const formatSubType = (T) => {
|
1184
|
+
export const formatSubType = (T) => {
|
1184
1185
|
switch (T[0]) {
|
1185
1186
|
case COLLECTION:
|
1186
1187
|
return `[${
|