fez-lisp 1.5.161 → 1.5.162
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-T.js +1 -1
- package/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/check.js +179 -113
- package/src/keywords.js +4 -0
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -351,7 +351,7 @@ const equalSubTypes = (a, b) => {
|
|
351
351
|
getSubType(a).difference(getSubType(b)).size === 0
|
352
352
|
)
|
353
353
|
}
|
354
|
-
const
|
354
|
+
const equalSubReturns = (a, b) => {
|
355
355
|
return (
|
356
356
|
!hasSubReturn(a) ||
|
357
357
|
!hasSubReturn(b) ||
|
@@ -660,7 +660,7 @@ const resolveSetter = (first, rest, env, stack) => {
|
|
660
660
|
getSubType(env[right[VALUE]][STATS])
|
661
661
|
)
|
662
662
|
} else
|
663
|
-
|
663
|
+
retry(env[right[VALUE]][STATS], [first[VALUE], rest], stack, () =>
|
664
664
|
resolveSetter(first, rest, env, stack)
|
665
665
|
)
|
666
666
|
}
|
@@ -791,9 +791,31 @@ const resolveReturnType = ({
|
|
791
791
|
check
|
792
792
|
}) => {
|
793
793
|
if (returns[TYPE] === ATOM) setPropToAtom(env[name][STATS], prop)
|
794
|
-
else {
|
794
|
+
else if (returns[TYPE] === WORD) {
|
795
|
+
if (env[returns[VALUE]]) {
|
796
|
+
if (!isUnknownType(env[returns[VALUE]][STATS]))
|
797
|
+
setPropToType(env[name][STATS], prop, env[returns[VALUE]][STATS])
|
798
|
+
else
|
799
|
+
once(env[name][STATS], exp, stack, () => {
|
800
|
+
setPropToTypeRef(env[name][STATS], prop, env[returns[VALUE]][STATS])
|
801
|
+
if (isUnknownProp(env[name][STATS], prop)) {
|
802
|
+
// TODO: DRY
|
803
|
+
const index = env[name][STATS][ARGUMENTS]
|
804
|
+
? env[name][STATS][ARGUMENTS].findIndex(
|
805
|
+
(x) => x[STATS][SIGNATURE] === returns[VALUE]
|
806
|
+
)
|
807
|
+
: -1
|
808
|
+
if (index >= 0) {
|
809
|
+
setReturnToGeneric(env[name][STATS], index)
|
810
|
+
return true
|
811
|
+
} else if (!env[returns[VALUE]]) return false
|
812
|
+
}
|
813
|
+
})
|
814
|
+
}
|
815
|
+
} else {
|
795
816
|
switch (returns[VALUE]) {
|
796
817
|
case KEYWORDS.CREATE_ARRAY:
|
818
|
+
setPropToCollection(env[name][STATS], prop)
|
797
819
|
setPropToSubReturn(env[name][STATS], prop, initArrayType({ rem, env }))
|
798
820
|
break
|
799
821
|
case KEYWORDS.IF:
|
@@ -818,11 +840,13 @@ const resolveReturnType = ({
|
|
818
840
|
})
|
819
841
|
})
|
820
842
|
checkPredicateNameDeep(name, exp, exp.slice(1), returns)
|
843
|
+
// TODO: DRY
|
821
844
|
const index = env[name][STATS][ARGUMENTS]
|
822
845
|
? env[name][STATS][ARGUMENTS].findIndex(
|
823
846
|
(x) => x[STATS][SIGNATURE] === returns[VALUE]
|
824
847
|
)
|
825
848
|
: -1
|
849
|
+
|
826
850
|
if (index >= 0) {
|
827
851
|
setReturnToGeneric(env[name][STATS], index)
|
828
852
|
return true
|
@@ -910,7 +934,12 @@ const resolveReturnType = ({
|
|
910
934
|
env[returns[VALUE]][STATS]
|
911
935
|
)
|
912
936
|
})
|
913
|
-
else
|
937
|
+
else {
|
938
|
+
// if (SPECIAL_FORMS_SET.has(returns[VALUE]))
|
939
|
+
// setReturn(env[name][STATS], env[returns[VALUE]][STATS])
|
940
|
+
// else
|
941
|
+
setReturnRef(env[name][STATS], env[returns[VALUE]][STATS])
|
942
|
+
}
|
914
943
|
}
|
915
944
|
}
|
916
945
|
}
|
@@ -1029,7 +1058,7 @@ export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
|
|
1029
1058
|
getReturn(actual[STATS])
|
1030
1059
|
)}) (${stringifyArgs(exp)}) (check #779)`
|
1031
1060
|
)
|
1032
|
-
else if (!
|
1061
|
+
else if (!equalSubReturns(expected[STATS], actual[STATS]))
|
1033
1062
|
throw new TypeError(
|
1034
1063
|
`Incorrect return type for (${
|
1035
1064
|
expected[STATS][SIGNATURE]
|
@@ -1071,7 +1100,7 @@ export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
|
|
1071
1100
|
getType(actual[STATS])
|
1072
1101
|
)}) (${stringifyArgs(exp)}) (check #780)`
|
1073
1102
|
)
|
1074
|
-
else if (!
|
1103
|
+
else if (!equalSubReturns(expected[STATS], actual[STATS]))
|
1075
1104
|
throw new TypeError(
|
1076
1105
|
`Incorrect return type for (${
|
1077
1106
|
expected[STATS][SIGNATURE]
|
@@ -1151,6 +1180,36 @@ export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
|
|
1151
1180
|
)})`
|
1152
1181
|
)
|
1153
1182
|
if (name in env) {
|
1183
|
+
// const [head, ...tail] = isLeaf(rest.at(-1))
|
1184
|
+
// ? [rest.at(-1)]
|
1185
|
+
// : rest.at(-1)
|
1186
|
+
// const ref = env[name]
|
1187
|
+
// if (ref) {
|
1188
|
+
// if (getType(ref[STATS]) === APPLY && head[TYPE] !== APPLY)
|
1189
|
+
// throw new TypeError(
|
1190
|
+
// `Miss-matching type for (${name}) predifined expected type is (${toTypeNames(
|
1191
|
+
// APPLY
|
1192
|
+
// )}) but got (${stringifyArgs(exp)})`
|
1193
|
+
// )
|
1194
|
+
// const returns = deepLambdaReturn(
|
1195
|
+
// hasBlock(tail) ? tail.at(-1) : tail,
|
1196
|
+
// (result) => result[VALUE] !== KEYWORDS.IF
|
1197
|
+
// )
|
1198
|
+
// const [rhead] = isLeaf(returns) ? [returns] : returns
|
1199
|
+
// const rightRef = env[rhead[VALUE]]
|
1200
|
+
// if (rightRef)
|
1201
|
+
// if (
|
1202
|
+
// !equalReturns(ref[STATS], rightRef[STATS]) ||
|
1203
|
+
// !equalSubReturns(ref[STATS], rightRef[STATS])
|
1204
|
+
// )
|
1205
|
+
// throw new TypeError(
|
1206
|
+
// `Miss-matching return type for (${name}) predifined expected return is (${formatSubType(
|
1207
|
+
// getReturns(ref[STATS])
|
1208
|
+
// )}) but got (${formatSubType(
|
1209
|
+
// getReturns(rightRef[STATS])
|
1210
|
+
// )}) (${stringifyArgs(exp)})`
|
1211
|
+
// )
|
1212
|
+
// }
|
1154
1213
|
Types.set(withScope(name, env), () => formatType(name, env))
|
1155
1214
|
break
|
1156
1215
|
}
|
@@ -1175,36 +1234,11 @@ export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
|
|
1175
1234
|
[RETURNS]: [UNKNOWN]
|
1176
1235
|
}
|
1177
1236
|
}
|
1178
|
-
if (
|
1179
|
-
!checkReturnType({
|
1180
|
-
stack,
|
1181
|
-
exp,
|
1182
|
-
env,
|
1183
|
-
name,
|
1184
|
-
check
|
1185
|
-
}) ||
|
1186
|
-
isUnknownReturn(env[name][STATS])
|
1187
|
-
) {
|
1188
|
-
retry(env[name][STATS], [first, env], stack, () => {
|
1189
|
-
checkReturnType({
|
1190
|
-
stack,
|
1191
|
-
exp,
|
1192
|
-
env,
|
1193
|
-
name,
|
1194
|
-
check
|
1195
|
-
})
|
1196
|
-
// TODO: remove this as maybe it is not needed
|
1197
|
-
check(rightHand, env, exp)
|
1198
|
-
})
|
1199
|
-
check(rightHand, env, exp)
|
1200
|
-
}
|
1201
|
-
|
1202
1237
|
check(rightHand, env, exp)
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
// )
|
1238
|
+
if (isUnknownReturn(env[name][STATS]))
|
1239
|
+
retry(env[name][STATS], exp, stack, () =>
|
1240
|
+
check(rightHand, env, exp)
|
1241
|
+
)
|
1208
1242
|
} else {
|
1209
1243
|
checkPredicateName(exp, rest)
|
1210
1244
|
const isLeafNode = isLeaf(rightHand)
|
@@ -1275,90 +1309,122 @@ export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
|
|
1275
1309
|
Types.set(withScope(name, env), () => formatType(name, env))
|
1276
1310
|
break
|
1277
1311
|
case KEYWORDS.ANONYMOUS_FUNCTION:
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
const
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
[
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1312
|
+
{
|
1313
|
+
validateLambda(exp)
|
1314
|
+
const params = exp.slice(1, -1)
|
1315
|
+
const copy = Object.create(env)
|
1316
|
+
if (Array.isArray(scope[1]) && scope[1][TYPE] === WORD)
|
1317
|
+
copy[SCOPE_NAME] = scope[1][VALUE]
|
1318
|
+
else copy[SCOPE_NAME] = ++scopeIndex
|
1319
|
+
const ref = env[copy[SCOPE_NAME]]
|
1320
|
+
for (let i = 0; i < params.length; ++i) {
|
1321
|
+
const param = params[i]
|
1322
|
+
// TODO move this somewhere else
|
1323
|
+
if (!isLeaf(param))
|
1324
|
+
throw new TypeError(
|
1325
|
+
`Invalid body for (${
|
1326
|
+
first[VALUE]
|
1327
|
+
}) if it takes more than one expression it must be wrapped in a (${
|
1328
|
+
KEYWORDS.BLOCK
|
1329
|
+
}) (${stringifyArgs(exp)}) (check #666)`
|
1330
|
+
)
|
1331
|
+
copy[param[VALUE]] = {
|
1332
|
+
[STATS]: {
|
1333
|
+
[IS_ARGUMENT]: true,
|
1334
|
+
[SIGNATURE]: param[VALUE],
|
1335
|
+
[TYPE_PROP]: [UNKNOWN],
|
1336
|
+
[RETURNS]: [UNKNOWN],
|
1337
|
+
[ARGUMENTS]: [],
|
1338
|
+
argIndex: i,
|
1339
|
+
retried: 0,
|
1340
|
+
counter: 0
|
1341
|
+
}
|
1305
1342
|
}
|
1343
|
+
if (!ref) continue
|
1344
|
+
ref[STATS][ARGUMENTS][i] = copy[param[VALUE]]
|
1345
|
+
// TODO overwrite return type check here
|
1306
1346
|
}
|
1307
|
-
const
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
// TODO figure out what we do here
|
1320
|
-
// this here is a variable WORD
|
1321
|
-
// so return type of that function is that varible type
|
1322
|
-
stagger(
|
1323
|
-
stack,
|
1324
|
-
'append',
|
1325
|
-
[returns, copy],
|
1326
|
-
() =>
|
1327
|
-
copy[returns[VALUE]] &&
|
1328
|
-
setReturnToType(ref[STATS], copy[returns[VALUE]][STATS])
|
1329
|
-
)
|
1330
|
-
else {
|
1331
|
-
stagger(stack, 'append', [returns, copy], () => {
|
1332
|
-
const ret = returns[0]
|
1333
|
-
switch (ret[VALUE]) {
|
1334
|
-
case KEYWORDS.IF:
|
1335
|
-
resolveCondition({
|
1336
|
-
rem: returns,
|
1337
|
-
name: ref[STATS][SIGNATURE],
|
1338
|
-
env: copy,
|
1339
|
-
exp,
|
1340
|
-
stack,
|
1341
|
-
prop: RETURNS,
|
1342
|
-
check
|
1343
|
-
})
|
1347
|
+
const returns = deepLambdaReturn(
|
1348
|
+
hasBlock(exp) ? exp.at(-1) : exp,
|
1349
|
+
(result) => result[VALUE] !== KEYWORDS.IF
|
1350
|
+
)
|
1351
|
+
if (ref)
|
1352
|
+
if (isLeaf(returns)) {
|
1353
|
+
// TODO figure out what we do here
|
1354
|
+
// this here is a variable WORD
|
1355
|
+
// so return type of that function is that varible type
|
1356
|
+
switch (returns[TYPE]) {
|
1357
|
+
case ATOM:
|
1358
|
+
setReturnToAtom(ref[STATS])
|
1344
1359
|
break
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1360
|
+
case WORD:
|
1361
|
+
stagger(stack, 'append', [returns, copy], () => {
|
1362
|
+
copy[returns[VALUE]] &&
|
1363
|
+
checkReturnType({
|
1364
|
+
stack,
|
1365
|
+
exp: [
|
1366
|
+
[APPLY, KEYWORDS.DEFINE_VARIABLE],
|
1367
|
+
[WORD, ref[STATS][SIGNATURE]],
|
1368
|
+
exp
|
1369
|
+
],
|
1370
|
+
env: copy,
|
1371
|
+
name: ref[STATS][SIGNATURE],
|
1372
|
+
check
|
1350
1373
|
})
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
})
|
1374
|
+
// setReturnToType(
|
1375
|
+
// ref[STATS],
|
1376
|
+
// copy[returns[VALUE]][STATS]
|
1377
|
+
// )
|
1378
|
+
})
|
1357
1379
|
break
|
1358
1380
|
}
|
1359
|
-
}
|
1360
|
-
|
1361
|
-
|
1381
|
+
} else {
|
1382
|
+
stagger(stack, 'append', [returns, copy], () => {
|
1383
|
+
retry(ref[STATS], exp, stack, () => {
|
1384
|
+
checkReturnType({
|
1385
|
+
stack,
|
1386
|
+
exp: [
|
1387
|
+
[APPLY, KEYWORDS.DEFINE_VARIABLE],
|
1388
|
+
[WORD, ref[STATS][SIGNATURE]],
|
1389
|
+
exp
|
1390
|
+
],
|
1391
|
+
env: copy,
|
1392
|
+
name: ref[STATS][SIGNATURE],
|
1393
|
+
check
|
1394
|
+
})
|
1395
|
+
})
|
1396
|
+
// const ret = returns[0]
|
1397
|
+
// switch (ret[VALUE]) {
|
1398
|
+
// case KEYWORDS.IF:
|
1399
|
+
// resolveCondition({
|
1400
|
+
// rem: returns,
|
1401
|
+
// name: ref[STATS][SIGNATURE],
|
1402
|
+
// env: copy,
|
1403
|
+
// exp,
|
1404
|
+
// stack,
|
1405
|
+
// prop: RETURNS,
|
1406
|
+
// check
|
1407
|
+
// })
|
1408
|
+
// break
|
1409
|
+
// default:
|
1410
|
+
// if (copy[ret[VALUE]]) {
|
1411
|
+
// if (isUnknownReturn(copy[ret[VALUE]][STATS])) {
|
1412
|
+
// once(ref[STATS], [returns, copy], stack, () => {
|
1413
|
+
// setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
1414
|
+
// })
|
1415
|
+
// } else setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
1416
|
+
// } else
|
1417
|
+
// stagger(stack, 'append', [ret, copy], () => {
|
1418
|
+
// if (copy[ret[VALUE]])
|
1419
|
+
// setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
1420
|
+
// })
|
1421
|
+
// break
|
1422
|
+
// }
|
1423
|
+
})
|
1424
|
+
}
|
1425
|
+
check(rest.at(-1), copy, copy)
|
1426
|
+
}
|
1427
|
+
|
1362
1428
|
break
|
1363
1429
|
case STATIC_TYPES.ABSTRACTION:
|
1364
1430
|
case STATIC_TYPES.COLLECTION:
|
package/src/keywords.js
CHANGED
@@ -113,6 +113,10 @@ export const MUTATORS_SET = new Set([
|
|
113
113
|
])
|
114
114
|
export const GETTERS_SET = new Set([
|
115
115
|
KEYWORDS.GET_ARRAY,
|
116
|
+
'array:first',
|
117
|
+
'array:second',
|
118
|
+
'array:third',
|
119
|
+
'array:last',
|
116
120
|
'matrix:get',
|
117
121
|
'matrix:set-and-get!',
|
118
122
|
'array:set-and-get!',
|