fez-lisp 1.5.49 → 1.5.51
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/README.md +19 -87
- package/favicon.svg +5 -0
- package/lib/baked/std.js +1 -1
- package/logo.svg +15 -5
- package/package.json +1 -1
- package/src/check.js +125 -206
- package/src/evaluator.js +10 -16
- package/src/interpreter.js +0 -7
- package/src/keywords.js +1 -2
package/logo.svg
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
-
<svg width="
|
2
|
-
<path d="
|
3
|
-
<
|
4
|
-
<
|
5
|
-
<
|
1
|
+
<svg width="61" height="79" viewBox="0 0 61 79" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<path d="M58.8257 55.7684C63.4688 62.5468 57.2431 75.2357 42.5 78C34.5 79.5 2.00013 79.4982 2 64.3957C1.99984 45.77 28.6339 50.3503 39.5543 55.7684C56.8985 61.3234 54.329 49.2038 58.8257 55.7684Z" fill="#F9B949"/>
|
3
|
+
<circle cx="25.5" cy="35.5" r="25.5" fill="#F9B949"/>
|
4
|
+
<circle cx="36.5" cy="31.5" r="2.5" fill="#1F1B1B"/>
|
5
|
+
<circle cx="9.5" cy="21.5" r="2.5" fill="#1F1B1B"/>
|
6
|
+
<circle cx="10" cy="21" r="1" fill="#EBEBEB"/>
|
7
|
+
<circle cx="10" cy="21" r="1" fill="#EBEBEB"/>
|
8
|
+
<circle cx="10" cy="21" r="1" fill="#EBEBEB"/>
|
9
|
+
<circle cx="37" cy="31" r="1" fill="#EBEBEB"/>
|
10
|
+
<circle cx="37" cy="31" r="1" fill="#EBEBEB"/>
|
11
|
+
<circle cx="37" cy="31" r="1" fill="#EBEBEB"/>
|
12
|
+
<path d="M11.6564 26.818C17.5013 31.4502 17.7946 23.2377 23.0134 28.6252C28.2321 34.0127 30.2289 37.3689 19.8597 35.7179C9.49045 34.0669 5.8115 22.1858 11.6564 26.818Z" fill="#B44637"/>
|
13
|
+
<path d="M49.8808 7.37404C50.5137 5.27388 40.491 0.514532 39.3766 1.22816C38.2623 1.94179 33.2308 11.7323 33.2308 11.7323L43.7349 17.8782C43.7349 17.8782 49.2479 9.47421 49.8808 7.37404Z" fill="#B44637"/>
|
14
|
+
<path d="M49.8808 7.37404C50.5137 5.27388 40.491 0.514532 39.3766 1.22816C38.2623 1.94179 33.2308 11.7323 33.2308 11.7323L43.7349 17.8782C43.7349 17.8782 49.2479 9.47421 49.8808 7.37404Z" fill="#B44637"/>
|
15
|
+
<path d="M51 15C46 13.5 54.6472 7.06417 48.8171 5" stroke="#F9B949" stroke-width="2" stroke-linecap="round"/>
|
6
16
|
</svg>
|
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -70,22 +70,25 @@ const deepLambdaReturn = (rest, condition) => {
|
|
70
70
|
const rem = hasBlock(body) ? body.at(-1) : body
|
71
71
|
return condition(rem) ? rem : deepLambdaReturn(rem, condition)
|
72
72
|
}
|
73
|
-
const getScopeNames = (scope) => {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
}
|
84
|
-
const withScope = (name, scope) => {
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
73
|
+
// const getScopeNames = (scope) => {
|
74
|
+
// const scopeNames = []
|
75
|
+
// let current = scope
|
76
|
+
// while (current) {
|
77
|
+
// if (current[SCOPE_NAME]) {
|
78
|
+
// scopeNames.push(current[SCOPE_NAME])
|
79
|
+
// }
|
80
|
+
// current = Object.getPrototypeOf(current)
|
81
|
+
// }
|
82
|
+
// return scopeNames.reverse()
|
83
|
+
// }
|
84
|
+
// const withScope = (name, scope) => {
|
85
|
+
// const chain = getScopeNames(scope)
|
86
|
+
// const str = `${chain.join('_')}_${name}::${performance
|
87
|
+
// .now()
|
88
|
+
// .toString()
|
89
|
+
// .replace('.', 0)}`
|
90
|
+
// return { str, chain }
|
91
|
+
// }
|
89
92
|
export const typeCheck = (ast) => {
|
90
93
|
const root = {
|
91
94
|
[toTypeNames(APPLY)]: {
|
@@ -536,15 +539,8 @@ export const typeCheck = (ast) => {
|
|
536
539
|
}
|
537
540
|
}
|
538
541
|
}
|
539
|
-
const errorStack = new
|
542
|
+
const errorStack = new Set()
|
540
543
|
const warningStack = new Set()
|
541
|
-
|
542
|
-
// const isDefinitionOfAFunction = (head, tail) =>
|
543
|
-
// head[TYPE] === APPLY &&
|
544
|
-
// head[VALUE] === KEYWORDS.DEFINE_VARIABLE &&
|
545
|
-
// tail.at(-1)[0][TYPE] === APPLY &&
|
546
|
-
// tail.at(-1)[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
|
547
|
-
|
548
544
|
const stack = []
|
549
545
|
const check = (exp, env, scope) => {
|
550
546
|
const [first, ...rest] = isLeaf(exp) ? [exp] : exp
|
@@ -557,17 +553,9 @@ export const typeCheck = (ast) => {
|
|
557
553
|
case WORD:
|
558
554
|
{
|
559
555
|
stack.push(() => {
|
560
|
-
const key = withScope(first[VALUE], scope)
|
561
556
|
if (env[first[VALUE]] === undefined) {
|
562
|
-
errorStack.
|
563
|
-
key.str,
|
557
|
+
errorStack.add(
|
564
558
|
`Trying to access undefined variable ${first[VALUE]} (check #11)`
|
565
|
-
|
566
|
-
// `Trying to access undefined variable ${
|
567
|
-
// first[VALUE]
|
568
|
-
// }\n${formatCallstack(
|
569
|
-
// key.chain.filter((x) => isNaN(Number(x[0])))
|
570
|
-
// )}\n(check #11)`
|
571
559
|
)
|
572
560
|
}
|
573
561
|
})
|
@@ -597,67 +585,30 @@ export const typeCheck = (ast) => {
|
|
597
585
|
case KEYWORDS.IF:
|
598
586
|
{
|
599
587
|
const re = rem.slice(2)
|
600
|
-
// If either is an ATOM then IF returns an ATOM
|
601
588
|
if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
|
602
589
|
env[name][STATS][prop][0] = ATOM
|
603
|
-
// if (
|
604
|
-
// re[0][VALUE] === FALSE ||
|
605
|
-
// re[0][VALUE] === TRUE ||
|
606
|
-
// re[1][VALUE] === FALSE ||
|
607
|
-
// re[1][VALUE] === TRUE
|
608
|
-
// ) {
|
609
|
-
// env[name][STATS][RETURNS][1] = PREDICATE
|
610
|
-
// }
|
611
590
|
} else if (!isLeaf(re[0]) && env[re[0][0][VALUE]]) {
|
612
|
-
// const concequent = isLeaf(re[0])
|
613
|
-
// ? env[re[0][VALUE]]
|
614
|
-
// : env[re[0][0][VALUE]]
|
615
|
-
// const alternative = isLeaf(re[1])
|
616
|
-
// ? env[re[1][VALUE]]
|
617
|
-
// : env[re[1][0][VALUE]]
|
618
591
|
env[name][STATS][prop] =
|
619
592
|
env[re[0][0][VALUE]][STATS][RETURNS]
|
620
593
|
if (
|
621
594
|
re[0][0][TYPE] === APPLY &&
|
622
|
-
// turn off typechecks for optimized functions
|
623
595
|
!name.startsWith(OPTIMIZED_PREFIX)
|
624
596
|
) {
|
625
597
|
switch (re[0][0][VALUE]) {
|
626
598
|
case KEYWORDS.ANONYMOUS_FUNCTION:
|
627
|
-
// env[name][STATS][prop] =
|
628
|
-
// env[re[0][0][VALUE]][STATS][RETURNS]
|
629
|
-
// env[name][STATS][SUB_TYPE] =
|
630
|
-
// env[re[0][0][VALUE]][STATS][SUB_TYPE]
|
631
|
-
|
632
599
|
env[name][STATS][RETURNS] = [UNKNOWN]
|
633
600
|
env[name][STATS][ARGS_COUNT] =
|
634
601
|
re[0].length - 2
|
635
|
-
// check(
|
636
|
-
// [
|
637
|
-
// [APPLY, KEYWORDS.DEFINE_VARIABLE],
|
638
|
-
// [WORD, name],
|
639
|
-
// re[0]
|
640
|
-
// ],
|
641
|
-
// env,
|
642
|
-
// scope
|
643
|
-
// )
|
644
602
|
break
|
645
603
|
}
|
646
604
|
}
|
647
605
|
// env[name][STATS] = env[re[0][0][VALUE]][STATS]
|
648
|
-
} else {
|
649
|
-
|
650
|
-
env[
|
651
|
-
|
652
|
-
env[
|
653
|
-
|
654
|
-
// env[name][STATS] = env[name][STATS]
|
655
|
-
// env[re[0][VALUE]][STATS][SUB_TYPE]
|
656
|
-
} else {
|
657
|
-
env[name][STATS][prop] = [UNKNOWN]
|
658
|
-
// env[name][STATS][RETURNS] = APPLY
|
659
|
-
}
|
660
|
-
}
|
606
|
+
} else if (env[re[0][VALUE]]) {
|
607
|
+
env[name][STATS][prop][0] =
|
608
|
+
env[re[0][VALUE]][STATS][TYPE_PROP][0]
|
609
|
+
env[name][STATS][RETURNS][1] =
|
610
|
+
env[re[0][VALUE]][STATS][RETURNS][1]
|
611
|
+
} else env[name][STATS][prop] = [UNKNOWN]
|
661
612
|
}
|
662
613
|
break
|
663
614
|
default:
|
@@ -689,9 +640,6 @@ export const typeCheck = (ast) => {
|
|
689
640
|
env[name][STATS][RETURNS][1] =
|
690
641
|
fn[STATS][RETURNS][1]
|
691
642
|
} else {
|
692
|
-
// const body = rest.at(-1).at(-1).at(-1).at(-1)
|
693
|
-
// const rem = hasBlock(body) ? body.at(-1) : body
|
694
|
-
// const returns = isLeaf(rem) ? rem : rem[0]
|
695
643
|
const [returns, rem] = drillReturnType(
|
696
644
|
rest.at(-1).at(-1).at(-1),
|
697
645
|
(returns) =>
|
@@ -1002,7 +950,6 @@ export const typeCheck = (ast) => {
|
|
1002
950
|
}
|
1003
951
|
}
|
1004
952
|
// TODO overwrite return type check here
|
1005
|
-
// console.log(copy[SCOPE_NAME], env[copy[SCOPE_NAME]], copy)
|
1006
953
|
}
|
1007
954
|
}
|
1008
955
|
}
|
@@ -1011,10 +958,8 @@ export const typeCheck = (ast) => {
|
|
1011
958
|
break
|
1012
959
|
default:
|
1013
960
|
stack.push(() => {
|
1014
|
-
const key = withScope(first[VALUE], scope)
|
1015
961
|
if (env[first[VALUE]] === undefined)
|
1016
|
-
errorStack.
|
1017
|
-
key.str,
|
962
|
+
errorStack.add(
|
1018
963
|
`Trying to call undefined (lambda) ${first[VALUE]} (check #9)`
|
1019
964
|
)
|
1020
965
|
else {
|
@@ -1023,8 +968,7 @@ export const typeCheck = (ast) => {
|
|
1023
968
|
env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC &&
|
1024
969
|
env[first[VALUE]][STATS][ARGS_COUNT] !== rest.length
|
1025
970
|
) {
|
1026
|
-
errorStack.
|
1027
|
-
key.str,
|
971
|
+
errorStack.add(
|
1028
972
|
`Incorrect number of arguments for (${
|
1029
973
|
first[VALUE]
|
1030
974
|
}). Expected (= ${
|
@@ -1037,8 +981,7 @@ export const typeCheck = (ast) => {
|
|
1037
981
|
const isSpecial = SPECIAL_FORMS_SET.has(first[VALUE])
|
1038
982
|
if (first[TYPE] === APPLY && !isSpecial) {
|
1039
983
|
if (env[first[VALUE]][STATS][TYPE_PROP][0] === ATOM) {
|
1040
|
-
errorStack.
|
1041
|
-
key.str,
|
984
|
+
errorStack.add(
|
1042
985
|
`(${first[VALUE]}) is not a (lambda) (${stringifyArgs(
|
1043
986
|
exp
|
1044
987
|
)}) (check #12)`
|
@@ -1059,23 +1002,16 @@ export const typeCheck = (ast) => {
|
|
1059
1002
|
if (args) {
|
1060
1003
|
for (let i = 0; i < args.length; ++i) {
|
1061
1004
|
// type check
|
1062
|
-
// todo finish this
|
1063
|
-
|
1064
1005
|
if (args[i][SUB] != undefined) {
|
1065
|
-
// first[TYPE] === APPLY &&
|
1066
|
-
// env[first[VALUE]][STATS][SUB_TYPE] === PREDICATE
|
1067
|
-
// args[i][SUB] = env[rest[i][VALUE]][SUB_TYPE]
|
1068
1006
|
if (isLeaf(rest[i])) {
|
1069
1007
|
if (rest[i][TYPE] === WORD) {
|
1070
|
-
// TODO finish this
|
1071
1008
|
if (
|
1072
1009
|
env[rest[i][VALUE]] &&
|
1073
1010
|
args[i][SUB] !==
|
1074
1011
|
env[rest[i][VALUE]][STATS][RETURNS][1]
|
1075
1012
|
) {
|
1076
|
-
errorStack.
|
1077
|
-
|
1078
|
-
`Incorrect type of arguments for (${
|
1013
|
+
errorStack.add(
|
1014
|
+
`Incorrect type of argument (${i}) for (${
|
1079
1015
|
first[VALUE]
|
1080
1016
|
}). Expected (${toTypeNames(
|
1081
1017
|
args[i][SUB]
|
@@ -1091,8 +1027,7 @@ export const typeCheck = (ast) => {
|
|
1091
1027
|
rest[i][VALUE] !== TRUE &&
|
1092
1028
|
rest[i][VALUE] !== FALSE
|
1093
1029
|
) {
|
1094
|
-
errorStack.
|
1095
|
-
key.str,
|
1030
|
+
errorStack.add(
|
1096
1031
|
`Incorrect type of arguments for (${
|
1097
1032
|
first[VALUE]
|
1098
1033
|
}). Expected (${toTypeNames(
|
@@ -1116,9 +1051,8 @@ export const typeCheck = (ast) => {
|
|
1116
1051
|
fn &&
|
1117
1052
|
fn[STATS][RETURNS][0] !== args[i][TYPE]
|
1118
1053
|
) {
|
1119
|
-
errorStack.
|
1120
|
-
|
1121
|
-
`Incorrect type of arguments for (${
|
1054
|
+
errorStack.add(
|
1055
|
+
`Incorrect type of argument (${i}) for (${
|
1122
1056
|
first[VALUE]
|
1123
1057
|
}). Expected (${toTypeNames(
|
1124
1058
|
args[i][TYPE]
|
@@ -1131,14 +1065,14 @@ export const typeCheck = (ast) => {
|
|
1131
1065
|
fn &&
|
1132
1066
|
fn[STATS][RETURNS][1] !== args[i][SUB]
|
1133
1067
|
) {
|
1134
|
-
errorStack.
|
1135
|
-
|
1136
|
-
`Incorrect type of arguments for (${
|
1068
|
+
errorStack.add(
|
1069
|
+
`Incorrect type of argument (${i}) for (${
|
1137
1070
|
first[VALUE]
|
1138
1071
|
}). Expected (${toTypeNames(
|
1139
1072
|
args[i][SUB]
|
1140
1073
|
)}) but got an (${toTypeNames(
|
1141
|
-
fn[STATS][RETURNS][1]
|
1074
|
+
fn[STATS][RETURNS][1] ??
|
1075
|
+
fn[STATS][RETURNS][0]
|
1142
1076
|
)}) which is neither ${TRUE} or ${FALSE} (${stringifyArgs(
|
1143
1077
|
exp
|
1144
1078
|
)}) (check #27)`
|
@@ -1150,8 +1084,7 @@ export const typeCheck = (ast) => {
|
|
1150
1084
|
const returns = isLeaf(rem) ? rem : rem[0]
|
1151
1085
|
if (returns[TYPE] === ATOM) {
|
1152
1086
|
if (args[i][TYPE] !== ATOM) {
|
1153
|
-
errorStack.
|
1154
|
-
key.str,
|
1087
|
+
errorStack.add(
|
1155
1088
|
`Incorrect type of argument ${i} for (${
|
1156
1089
|
first[VALUE]
|
1157
1090
|
}). Expected (${toTypeNames(
|
@@ -1167,8 +1100,7 @@ export const typeCheck = (ast) => {
|
|
1167
1100
|
returns[VALUE] !== TRUE &&
|
1168
1101
|
returns[VALUE] !== FALSE
|
1169
1102
|
) {
|
1170
|
-
errorStack.
|
1171
|
-
key.str,
|
1103
|
+
errorStack.add(
|
1172
1104
|
`Incorrect type of argument ${i} for (${
|
1173
1105
|
first[VALUE]
|
1174
1106
|
}). Expected (${toTypeNames(
|
@@ -1185,8 +1117,7 @@ export const typeCheck = (ast) => {
|
|
1185
1117
|
args[i][TYPE] !==
|
1186
1118
|
env[returns[VALUE]][STATS][RETURNS][0]
|
1187
1119
|
) {
|
1188
|
-
errorStack.
|
1189
|
-
key.str,
|
1120
|
+
errorStack.add(
|
1190
1121
|
`Incorrect type of argument ${i} for (${
|
1191
1122
|
first[VALUE]
|
1192
1123
|
}). Expected (${toTypeNames(
|
@@ -1201,8 +1132,7 @@ export const typeCheck = (ast) => {
|
|
1201
1132
|
args[i][SUB] !==
|
1202
1133
|
env[returns[VALUE]][STATS][RETURNS][1]
|
1203
1134
|
) {
|
1204
|
-
errorStack.
|
1205
|
-
key.str,
|
1135
|
+
errorStack.add(
|
1206
1136
|
`Incorrect type of argument ${i} for (${
|
1207
1137
|
first[VALUE]
|
1208
1138
|
}). Expected (${toTypeNames(
|
@@ -1220,8 +1150,7 @@ export const typeCheck = (ast) => {
|
|
1220
1150
|
env[current[VALUE]][STATS][RETURNS][1] !==
|
1221
1151
|
args[i][SUB]
|
1222
1152
|
) {
|
1223
|
-
errorStack.
|
1224
|
-
key.str,
|
1153
|
+
errorStack.add(
|
1225
1154
|
`Incorrect type of arguments (${i}) for (${
|
1226
1155
|
first[VALUE]
|
1227
1156
|
}). Expected (${toTypeNames(
|
@@ -1236,12 +1165,7 @@ export const typeCheck = (ast) => {
|
|
1236
1165
|
}
|
1237
1166
|
}
|
1238
1167
|
|
1239
|
-
if (
|
1240
|
-
first[TYPE] === APPLY &&
|
1241
|
-
isSpecial
|
1242
|
-
// &&
|
1243
|
-
// env[first[VALUE]][STATS][ARGS_COUNT] !== VARIADIC
|
1244
|
-
) {
|
1168
|
+
if (first[TYPE] === APPLY && isSpecial) {
|
1245
1169
|
const expectedArgs = env[first[VALUE]][STATS][ARGS]
|
1246
1170
|
for (let i = 0; i < rest.length; ++i) {
|
1247
1171
|
if (expectedArgs[i][TYPE] === UNKNOWN) continue
|
@@ -1250,87 +1174,95 @@ export const typeCheck = (ast) => {
|
|
1250
1174
|
const isKnown =
|
1251
1175
|
env[CAR] &&
|
1252
1176
|
env[CAR][STATS][RETURNS][0] !== UNKNOWN
|
1253
|
-
if (
|
1254
|
-
|
1255
|
-
|
1177
|
+
if (isKnown) {
|
1178
|
+
if (
|
1179
|
+
env[CAR][STATS][RETURNS][0] !==
|
1256
1180
|
expectedArgs[i][TYPE]
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
)}) but got (${toTypeNames(
|
1265
|
-
env[CAR][STATS][RETURNS][0]
|
1266
|
-
)}) (${stringifyArgs(exp)}) (check #1)`
|
1267
|
-
)
|
1268
|
-
} else if (
|
1269
|
-
isKnown &&
|
1270
|
-
expectedArgs[i][SUB] &&
|
1271
|
-
env[CAR][STATS][RETURNS][1] !==
|
1272
|
-
expectedArgs[i][SUB]
|
1273
|
-
) {
|
1274
|
-
errorStack.set(
|
1275
|
-
key.str,
|
1276
|
-
`Incorrect type of arguments for special form (${
|
1277
|
-
first[VALUE]
|
1278
|
-
}). Expected (${toTypeNames(
|
1279
|
-
expectedArgs[i][SUB]
|
1280
|
-
)}) but got (${toTypeNames(
|
1281
|
-
env[CAR][STATS][RETURNS][1] ??
|
1181
|
+
) {
|
1182
|
+
errorStack.add(
|
1183
|
+
`Incorrect type of argument (${i}) for special form (${
|
1184
|
+
first[VALUE]
|
1185
|
+
}). Expected (${toTypeNames(
|
1186
|
+
expectedArgs[i][TYPE]
|
1187
|
+
)}) but got (${toTypeNames(
|
1282
1188
|
env[CAR][STATS][RETURNS][0]
|
1283
|
-
|
1284
|
-
|
1189
|
+
)}) (${stringifyArgs(exp)}) (check #1)`
|
1190
|
+
)
|
1191
|
+
} else if (
|
1192
|
+
expectedArgs[i][SUB] &&
|
1193
|
+
env[CAR][STATS][RETURNS][1] !==
|
1194
|
+
expectedArgs[i][SUB]
|
1195
|
+
) {
|
1196
|
+
errorStack.add(
|
1197
|
+
`Incorrect type of arguments for special form (${
|
1198
|
+
first[VALUE]
|
1199
|
+
}). Expected (${toTypeNames(
|
1200
|
+
expectedArgs[i][SUB]
|
1201
|
+
)}) but got (${toTypeNames(
|
1202
|
+
env[CAR][STATS][RETURNS][1] ??
|
1203
|
+
env[CAR][STATS][RETURNS][0]
|
1204
|
+
)}) (${stringifyArgs(exp)}) (check #13)`
|
1205
|
+
)
|
1206
|
+
}
|
1285
1207
|
}
|
1286
|
-
}
|
1287
|
-
if (
|
1288
|
-
env[rest[i][VALUE]] &&
|
1289
|
-
expectedArgs[i][TYPE] !== rest[i][TYPE]
|
1290
|
-
) {
|
1208
|
+
} else {
|
1291
1209
|
switch (rest[i][TYPE]) {
|
1292
|
-
// case UNKNOWN:
|
1293
|
-
// env[first[VALUE]][STATS][TYPE_PROP][0] =
|
1294
|
-
// expectedArgs[i][TYPE]
|
1295
|
-
// break
|
1296
1210
|
case WORD:
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1211
|
+
{
|
1212
|
+
const CAR = rest[i][VALUE]
|
1213
|
+
const isKnown =
|
1214
|
+
env[CAR] &&
|
1215
|
+
env[CAR][STATS][TYPE_PROP][0] !== UNKNOWN
|
1216
|
+
if (isKnown) {
|
1217
|
+
if (
|
1218
|
+
expectedArgs[i][TYPE] !==
|
1219
|
+
env[CAR][STATS][TYPE_PROP][0]
|
1220
|
+
) {
|
1221
|
+
errorStack.add(
|
1222
|
+
`Incorrect type of argument (${i}) for special form (${
|
1223
|
+
first[VALUE]
|
1224
|
+
}). Expected (${toTypeNames(
|
1225
|
+
expectedArgs[i][TYPE]
|
1226
|
+
)}) but got (${toTypeNames(
|
1227
|
+
env[CAR][STATS][TYPE_PROP][0]
|
1228
|
+
)}) (${stringifyArgs(exp)}) (check #3)`
|
1229
|
+
)
|
1230
|
+
} else if (
|
1231
|
+
expectedArgs[i][SUB] &&
|
1232
|
+
env[CAR][STATS][RETURNS][1] !==
|
1233
|
+
expectedArgs[i][SUB]
|
1234
|
+
)
|
1235
|
+
errorStack.add(
|
1236
|
+
`Incorrect type of argument (${i}) for special form (${
|
1237
|
+
first[VALUE]
|
1238
|
+
}). Expected (${toTypeNames(
|
1239
|
+
expectedArgs[i][SUB]
|
1240
|
+
)}) but got (${toTypeNames(
|
1241
|
+
env[CAR][STATS][RETURNS][1] ??
|
1242
|
+
env[CAR][STATS][TYPE_PROP][0]
|
1243
|
+
)}) (${stringifyArgs(exp)}) (check #6)`
|
1244
|
+
)
|
1245
|
+
} else if (env[rest[i][VALUE]]) {
|
1246
|
+
env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
|
1247
|
+
expectedArgs[i][TYPE]
|
1248
|
+
}
|
1249
|
+
}
|
1250
|
+
break
|
1251
|
+
case ATOM: {
|
1252
|
+
if (rest[i][TYPE] !== expectedArgs[i][TYPE]) {
|
1253
|
+
errorStack.add(
|
1254
|
+
`Incorrect type of argument (${i}) for special form (${
|
1307
1255
|
first[VALUE]
|
1308
1256
|
}). Expected (${toTypeNames(
|
1309
1257
|
expectedArgs[i][TYPE]
|
1310
1258
|
)}) but got (${toTypeNames(
|
1311
|
-
|
1312
|
-
)}) (${stringifyArgs(exp)}) (check #
|
1259
|
+
rest[i][TYPE]
|
1260
|
+
)}) (${stringifyArgs(exp)}) (check #2)`
|
1313
1261
|
)
|
1314
|
-
} else {
|
1315
|
-
env[rest[i][VALUE]][STATS][TYPE_PROP][0] =
|
1316
|
-
expectedArgs[i][TYPE]
|
1317
1262
|
}
|
1318
1263
|
break
|
1319
|
-
|
1320
|
-
case ATOM:
|
1321
|
-
errorStack.set(
|
1322
|
-
key.str,
|
1323
|
-
`Incorrect type of arguments for (${
|
1324
|
-
first[VALUE]
|
1325
|
-
}). Expected (${toTypeNames(
|
1326
|
-
expectedArgs[i][TYPE]
|
1327
|
-
)}) but got (${toTypeNames(
|
1328
|
-
rest[i][TYPE]
|
1329
|
-
)}) (${stringifyArgs(exp)}) (check #5)`
|
1330
|
-
)
|
1331
|
-
break
|
1264
|
+
}
|
1332
1265
|
}
|
1333
|
-
} else {
|
1334
1266
|
}
|
1335
1267
|
}
|
1336
1268
|
}
|
@@ -1356,8 +1288,7 @@ export const typeCheck = (ast) => {
|
|
1356
1288
|
env[rest[i][VALUE]][STATS][TYPE_PROP][0] !==
|
1357
1289
|
args[i][STATS][TYPE_PROP][0])
|
1358
1290
|
) {
|
1359
|
-
errorStack.
|
1360
|
-
key.str,
|
1291
|
+
errorStack.add(
|
1361
1292
|
`Incorrect type of arguments ${i} for (${
|
1362
1293
|
first[VALUE]
|
1363
1294
|
}). Expected (${toTypeNames(
|
@@ -1393,8 +1324,7 @@ export const typeCheck = (ast) => {
|
|
1393
1324
|
env[rest[i][0][VALUE]][STATS][RETURNS][0] !==
|
1394
1325
|
args[i][STATS][TYPE_PROP][0]
|
1395
1326
|
) {
|
1396
|
-
errorStack.
|
1397
|
-
key.str,
|
1327
|
+
errorStack.add(
|
1398
1328
|
`Incorrect type of arguments ${i} for (${
|
1399
1329
|
first[VALUE]
|
1400
1330
|
}). Expected (${toTypeNames(
|
@@ -1403,19 +1333,8 @@ export const typeCheck = (ast) => {
|
|
1403
1333
|
env[rest[i][0][VALUE]][STATS][RETURNS][0]
|
1404
1334
|
)}) (${stringifyArgs(exp)}) (check #4)`
|
1405
1335
|
)
|
1406
|
-
} else {
|
1407
|
-
if (
|
1408
|
-
rest[i].length &&
|
1409
|
-
env[rest[i][0][VALUE]] &&
|
1410
|
-
args[i][STATS][TYPE_PROP][0] === UNKNOWN &&
|
1411
|
-
env[rest[i][0][VALUE]][STATS].retried < RETRY_COUNT
|
1412
|
-
) {
|
1413
|
-
env[rest[i][0][VALUE]][STATS].retried += 1
|
1414
|
-
if (!scope[SCOPE_NAME])
|
1415
|
-
scope[SCOPE_NAME] = scope[1][VALUE]
|
1416
|
-
stack.unshift(() => check(exp, env, scope))
|
1417
|
-
}
|
1418
1336
|
}
|
1337
|
+
// TODO figure out what cann we do in this else ?
|
1419
1338
|
}
|
1420
1339
|
}
|
1421
1340
|
}
|
@@ -1432,7 +1351,7 @@ export const typeCheck = (ast) => {
|
|
1432
1351
|
copy[SCOPE_NAME] = 'root'
|
1433
1352
|
check(copy, root, copy)
|
1434
1353
|
while (stack.length) stack.pop()()
|
1435
|
-
const issues = [...
|
1354
|
+
const issues = [...errorStack, ...warningStack]
|
1436
1355
|
if (issues.length) throw new TypeError(issues.join('\n'))
|
1437
1356
|
return ast
|
1438
1357
|
}
|
package/src/evaluator.js
CHANGED
@@ -1,14 +1,5 @@
|
|
1
1
|
import { keywords } from './interpreter.js'
|
2
|
-
import {
|
3
|
-
APPLY,
|
4
|
-
ATOM,
|
5
|
-
DEBUG,
|
6
|
-
KEYWORDS,
|
7
|
-
SPECIAL_FORMS_SET,
|
8
|
-
TYPE,
|
9
|
-
VALUE,
|
10
|
-
WORD
|
11
|
-
} from './keywords.js'
|
2
|
+
import { APPLY, ATOM, KEYWORDS, TYPE, VALUE, WORD } from './keywords.js'
|
12
3
|
import { isLeaf } from './parser.js'
|
13
4
|
import { stringifyArgs } from './utils.js'
|
14
5
|
export const evaluate = (exp, env = keywords) => {
|
@@ -23,23 +14,26 @@ export const evaluate = (exp, env = keywords) => {
|
|
23
14
|
case WORD: {
|
24
15
|
const word = env[value]
|
25
16
|
if (word == undefined)
|
26
|
-
throw new ReferenceError(
|
17
|
+
throw new ReferenceError(
|
18
|
+
`Undefined variable ${value} (${stringifyArgs(exp)})`
|
19
|
+
)
|
27
20
|
return word
|
28
21
|
}
|
29
22
|
case APPLY: {
|
30
23
|
const apply = env[value]
|
31
24
|
if (apply == undefined)
|
32
25
|
throw new ReferenceError(
|
33
|
-
`Undefined (${
|
26
|
+
`Undefined (${
|
27
|
+
KEYWORDS.ANONYMOUS_FUNCTION
|
28
|
+
}) (${value}) (${stringifyArgs(exp)})`
|
34
29
|
)
|
35
30
|
if (typeof apply !== 'function')
|
36
31
|
throw new TypeError(
|
37
|
-
`${value} is not a (${KEYWORDS.ANONYMOUS_FUNCTION})
|
32
|
+
`${value} is not a (${KEYWORDS.ANONYMOUS_FUNCTION}) (${stringifyArgs(
|
33
|
+
exp
|
34
|
+
)})`
|
38
35
|
)
|
39
|
-
const isSpecial = SPECIAL_FORMS_SET.has(value)
|
40
36
|
const result = apply(tail, env, value)
|
41
|
-
if (!isSpecial && Array.isArray(env[DEBUG.CALLSTACK]))
|
42
|
-
env[DEBUG.CALLSTACK].pop()
|
43
37
|
return result
|
44
38
|
}
|
45
39
|
case ATOM:
|
package/src/interpreter.js
CHANGED
@@ -7,7 +7,6 @@ import {
|
|
7
7
|
TRUE,
|
8
8
|
TYPES,
|
9
9
|
RUNTIME_TYPES,
|
10
|
-
DEBUG,
|
11
10
|
STATIC_TYPES
|
12
11
|
} from './keywords.js'
|
13
12
|
import { evaluate } from './evaluator.js'
|
@@ -755,12 +754,6 @@ export const keywords = {
|
|
755
754
|
const value = evaluate(props[i], scope)
|
756
755
|
localEnv[params[i][VALUE]] = value
|
757
756
|
}
|
758
|
-
if (
|
759
|
-
name &&
|
760
|
-
Array.isArray(env[DEBUG.CALLSTACK]) &&
|
761
|
-
name !== env[DEBUG.CALLSTACK].at(-1)
|
762
|
-
)
|
763
|
-
env[DEBUG.CALLSTACK].push(name)
|
764
757
|
return evaluate(body, localEnv)
|
765
758
|
}
|
766
759
|
},
|
package/src/keywords.js
CHANGED
@@ -69,8 +69,7 @@ export const DEBUG = {
|
|
69
69
|
ASSERT: 'assert',
|
70
70
|
SIGNATURE: '?',
|
71
71
|
LIST_THEMES: 'theme?',
|
72
|
-
SET_THEME: 'theme!'
|
73
|
-
CALLSTACK: '(CALLSTACK)' // so that you can't use it in the code
|
72
|
+
SET_THEME: 'theme!'
|
74
73
|
}
|
75
74
|
|
76
75
|
export const SPECIAL_FORMS_SET = new Set(Object.values(KEYWORDS))
|