fez-lisp 1.5.158 → 1.5.160
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 -0
- package/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/check.js +13 -6
- package/src/types.js +86 -1
- package/src/utils.js +7 -4
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -841,7 +841,7 @@ const resolveReturnType = ({
|
|
841
841
|
// This is insitialisation of identity or any other
|
842
842
|
// function that returns it's argument
|
843
843
|
// Redifine the variable but since it's an error doing that
|
844
|
-
// Delete it
|
844
|
+
// Delete it first
|
845
845
|
delete env[name]
|
846
846
|
check(
|
847
847
|
[
|
@@ -920,7 +920,7 @@ const checkReturnType = ({ exp, stack, name, env, check }) => {
|
|
920
920
|
const stagger = (stack, method, data, fn) => {
|
921
921
|
stack[method]({ data, fn })
|
922
922
|
}
|
923
|
-
export const typeCheck = (ast) => {
|
923
|
+
export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
|
924
924
|
const Types = new Map()
|
925
925
|
const stack = new Brr()
|
926
926
|
let scopeIndex = 0
|
@@ -1124,6 +1124,7 @@ export const typeCheck = (ast) => {
|
|
1124
1124
|
exp
|
1125
1125
|
)})`
|
1126
1126
|
)
|
1127
|
+
// TODO check leT define types
|
1127
1128
|
const name = rest[0][VALUE]
|
1128
1129
|
if (env.hasOwnProperty(name))
|
1129
1130
|
throw new ReferenceError(
|
@@ -1131,6 +1132,11 @@ export const typeCheck = (ast) => {
|
|
1131
1132
|
exp
|
1132
1133
|
)})`
|
1133
1134
|
)
|
1135
|
+
|
1136
|
+
if (name in env) {
|
1137
|
+
Types.set(withScope(name, env), () => formatType(name, env))
|
1138
|
+
break
|
1139
|
+
}
|
1134
1140
|
// Predicate name consistency
|
1135
1141
|
const rightHand = rest.at(-1)
|
1136
1142
|
if (
|
@@ -1170,6 +1176,7 @@ export const typeCheck = (ast) => {
|
|
1170
1176
|
name,
|
1171
1177
|
check
|
1172
1178
|
})
|
1179
|
+
// TODO: remove this as maybe it is not needed
|
1173
1180
|
check(rightHand, env, exp)
|
1174
1181
|
})
|
1175
1182
|
check(rightHand, env, exp)
|
@@ -1307,9 +1314,9 @@ export const typeCheck = (ast) => {
|
|
1307
1314
|
})
|
1308
1315
|
break
|
1309
1316
|
default:
|
1310
|
-
if (copy[ret[VALUE]])
|
1317
|
+
if (copy[ret[VALUE]]) {
|
1311
1318
|
setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
1312
|
-
else
|
1319
|
+
} else
|
1313
1320
|
stagger(stack, 'append', [ret, copy], () => {
|
1314
1321
|
if (copy[ret[VALUE]])
|
1315
1322
|
setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
|
@@ -1657,8 +1664,8 @@ export const typeCheck = (ast) => {
|
|
1657
1664
|
}
|
1658
1665
|
}
|
1659
1666
|
}
|
1660
|
-
check(ast,
|
1667
|
+
check(ast, ctx, ast)
|
1661
1668
|
while (stack.length) stack.cut().fn()
|
1662
1669
|
return [ast, Types]
|
1663
1670
|
}
|
1664
|
-
export const type = (ast) => typeCheck(ast)[0]
|
1671
|
+
export const type = (ast, ctx) => typeCheck(ast, ctx)[0]
|
package/src/types.js
CHANGED
@@ -6,9 +6,11 @@ import {
|
|
6
6
|
KEYWORDS,
|
7
7
|
PLACEHOLDER,
|
8
8
|
STATIC_TYPES,
|
9
|
+
TYPE,
|
9
10
|
VALUE
|
10
11
|
} from './keywords.js'
|
11
|
-
import {
|
12
|
+
import { isLeaf } from './parser.js'
|
13
|
+
import { shakedList, stringifyArgs } from './utils.js'
|
12
14
|
export const ARG_COUNT = 'argumentsN'
|
13
15
|
export const VARIADIC = Infinity
|
14
16
|
export const STATS = '__stats__'
|
@@ -61,6 +63,30 @@ export const toTypeNames = (type) => {
|
|
61
63
|
break
|
62
64
|
}
|
63
65
|
}
|
66
|
+
export const toTypeCodes = (type) => {
|
67
|
+
switch (type) {
|
68
|
+
case 'Abstraction':
|
69
|
+
return [APPLY]
|
70
|
+
case 'Boolean':
|
71
|
+
return [ATOM, BOOLEAN_SUBTYPE()]
|
72
|
+
case 'Atom':
|
73
|
+
return [ATOM]
|
74
|
+
case 'Number':
|
75
|
+
return [ATOM, NUMBER_SUBTYPE()]
|
76
|
+
case 'Unknown':
|
77
|
+
return [UNKNOWN]
|
78
|
+
case 'Unknowns':
|
79
|
+
return [COLLECTION]
|
80
|
+
case 'Numbers':
|
81
|
+
return [COLLECTION, NUMBER_SUBTYPE()]
|
82
|
+
case 'Booleans':
|
83
|
+
return [COLLECTION, BOOLEAN_SUBTYPE()]
|
84
|
+
case 'Any':
|
85
|
+
return [ANY]
|
86
|
+
default:
|
87
|
+
break
|
88
|
+
}
|
89
|
+
}
|
64
90
|
export const toTypeNamesAnyToUknown = (type) => {
|
65
91
|
switch (type) {
|
66
92
|
case ANY:
|
@@ -1330,3 +1356,62 @@ export const validateLambda = (exp, name) => {
|
|
1330
1356
|
)})`
|
1331
1357
|
)
|
1332
1358
|
}
|
1359
|
+
|
1360
|
+
export const lambdaType = (t) => [t.slice(1, -1), t.at(-1)[1]]
|
1361
|
+
export const toArgType = (A, i) => {
|
1362
|
+
const out = []
|
1363
|
+
const arg = isLeaf(A) ? A : A[0]
|
1364
|
+
if (arg[TYPE] === APPLY) {
|
1365
|
+
const [args, returns] = lambdaType(A)
|
1366
|
+
out.push({
|
1367
|
+
[STATS]: {
|
1368
|
+
argIndex: i,
|
1369
|
+
retried: Infinity,
|
1370
|
+
[IS_ARGUMENT]: true,
|
1371
|
+
[SIGNATURE]: PLACEHOLDER,
|
1372
|
+
[TYPE_PROP]: [APPLY],
|
1373
|
+
[RETURNS]: toTypeCodes(returns[VALUE]),
|
1374
|
+
[ARGUMENTS]: args.map(toArgType).flat(1),
|
1375
|
+
[ARG_COUNT]: args.length
|
1376
|
+
}
|
1377
|
+
})
|
1378
|
+
} else {
|
1379
|
+
out.push({
|
1380
|
+
[STATS]: {
|
1381
|
+
argIndex: i,
|
1382
|
+
retried: Infinity,
|
1383
|
+
[IS_ARGUMENT]: true,
|
1384
|
+
[SIGNATURE]: PLACEHOLDER,
|
1385
|
+
[TYPE_PROP]: toTypeCodes(arg[VALUE]),
|
1386
|
+
[RETURNS]: toTypeCodes(arg[VALUE]),
|
1387
|
+
[ARGUMENTS]: [],
|
1388
|
+
[ARG_COUNT]: 0
|
1389
|
+
}
|
1390
|
+
})
|
1391
|
+
}
|
1392
|
+
return out
|
1393
|
+
}
|
1394
|
+
export const fromSourceToType = (T) => {
|
1395
|
+
const out = {}
|
1396
|
+
for (const t of T) {
|
1397
|
+
const name = t[1][VALUE]
|
1398
|
+
const [args, returns] = lambdaType(t[2])
|
1399
|
+
out[name] = {
|
1400
|
+
[STATS]: {
|
1401
|
+
retried: Infinity,
|
1402
|
+
[TYPE_PROP]: [APPLY],
|
1403
|
+
[SIGNATURE]: name,
|
1404
|
+
[ARG_COUNT]: args.length,
|
1405
|
+
[ARGUMENTS]: args.map(toArgType).flat(1),
|
1406
|
+
[RETURNS]: toTypeCodes(returns[VALUE])
|
1407
|
+
}
|
1408
|
+
}
|
1409
|
+
}
|
1410
|
+
return out
|
1411
|
+
}
|
1412
|
+
export const withCtxTypes = (T) => ({ ...SPECIAL_FORM_TYPES, ...T })
|
1413
|
+
export const filteredDefinedTypes = (program, lib, libT) => {
|
1414
|
+
const deps = new Set(shakedList(program, lib))
|
1415
|
+
return libT.filter((x) => deps.has(x[1][1]))
|
1416
|
+
}
|
1417
|
+
export const definedTypes = (T) => fromSourceToType(T)
|
package/src/utils.js
CHANGED
@@ -175,10 +175,13 @@ const isDefinition = (x) =>
|
|
175
175
|
x[TYPE] === APPLY && x[VALUE] === KEYWORDS.DEFINE_VARIABLE
|
176
176
|
// [[, [, libs]]] is because std is wrapped in (apply (lambda (do ...)))
|
177
177
|
const toDeps = ([[, [, libs]]]) =>
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
178
|
+
// slice 1 so we get rid of do
|
179
|
+
libs
|
180
|
+
.slice(1)
|
181
|
+
.reduce(
|
182
|
+
(a, x, i) => a.set(x.at(1)[VALUE], { value: x, index: i }),
|
183
|
+
new Map()
|
184
|
+
)
|
182
185
|
const deepShake = (tree, deps, visited = new Set(), ignored = new Set()) => {
|
183
186
|
const type = tree[TYPE]
|
184
187
|
const value = tree[VALUE]
|