fez-lisp 1.6.59 → 1.6.61
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 +35 -12
- package/src/keywords.js +2 -2
- package/src/types.js +13 -23
- package/src/utils.js +4 -0
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -56,7 +56,9 @@ import {
|
|
56
56
|
hasBlock,
|
57
57
|
log,
|
58
58
|
logExp,
|
59
|
-
stringifyArgs
|
59
|
+
stringifyArgs,
|
60
|
+
wrapInApplyLambda,
|
61
|
+
wrapInBlock
|
60
62
|
} from './utils.js'
|
61
63
|
|
62
64
|
export const identity = (name) => [
|
@@ -603,10 +605,9 @@ const resolveCondition = ({ rem, name, env, exp, prop, stack, check }) => {
|
|
603
605
|
const resolveGetter = ({ rem, prop, name, env }) => {
|
604
606
|
const array = isLeaf(rem[1]) ? rem[1] : rem[1][0]
|
605
607
|
if (!env[array[VALUE]] || !env[name]) return true
|
606
|
-
|
607
608
|
switch (array[TYPE]) {
|
608
609
|
case APPLY:
|
609
|
-
if (
|
610
|
+
if (hasSubReturn(env[array[VALUE]][STATS])) {
|
610
611
|
const rightSub = getSubReturn(env[array[VALUE]][STATS])
|
611
612
|
const isAtom = rightSub.has(NUMBER) || rightSub.has(BOOLEAN)
|
612
613
|
const isCollection = rightSub.has(COLLECTION)
|
@@ -614,12 +615,12 @@ const resolveGetter = ({ rem, prop, name, env }) => {
|
|
614
615
|
setPropToAtom(env[name][STATS], prop)
|
615
616
|
setPropToSubReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
|
616
617
|
} else if (!isAtom && isCollection) {
|
617
|
-
setPropToReturn(env[name][STATS], prop,
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
618
|
+
setPropToReturn(env[name][STATS], prop, {
|
619
|
+
[RETURNS]: [
|
620
|
+
env[array[VALUE]][STATS][RETURNS][1].types[0],
|
621
|
+
new SubType(env[array[VALUE]][STATS][RETURNS][1].types.slice(1))
|
622
|
+
]
|
623
|
+
})
|
623
624
|
} else return false
|
624
625
|
} else return false
|
625
626
|
break
|
@@ -713,10 +714,12 @@ const resolveSetter = (first, rest, env, stack) => {
|
|
713
714
|
case APPLY:
|
714
715
|
if (env[right[VALUE]]) {
|
715
716
|
if (right[VALUE] === KEYWORDS.CREATE_ARRAY) {
|
716
|
-
|
717
|
+
const inner = initArrayType({
|
717
718
|
rem: rest.at(-1),
|
718
719
|
env
|
719
720
|
})[RETURNS][1]
|
721
|
+
current[STATS][TYPE_PROP][0] = COLLECTION
|
722
|
+
if (!inner.has(UNKNOWN)) current[STATS][TYPE_PROP][1] = inner
|
720
723
|
break
|
721
724
|
}
|
722
725
|
if (hasSubReturn(env[right[VALUE]][STATS])) {
|
@@ -782,7 +785,6 @@ const initArrayTypeRec = ({ rem, env }) => {
|
|
782
785
|
const initArrayType = ({ rem, env }) => {
|
783
786
|
const ret = initArrayTypeRec({ rem, env })
|
784
787
|
const known = ret.find((x) => x[0] !== ANY && x[0] !== UNKNOWN)
|
785
|
-
// console.log(known[0], ret[0])
|
786
788
|
if (known && ret.length) {
|
787
789
|
if (Array.isArray(ret[0][0])) {
|
788
790
|
let head = ret[0][0]
|
@@ -796,6 +798,7 @@ const initArrayType = ({ rem, env }) => {
|
|
796
798
|
if (head) subT.add(head[1].types[0])
|
797
799
|
}
|
798
800
|
const [main, sub] = ret[0]
|
801
|
+
if (isSubType(sub) && sub.types.at(-1) === COLLECTION) sub.types.pop()
|
799
802
|
return {
|
800
803
|
[TYPE_PROP]: [APPLY],
|
801
804
|
[RETURNS]: [COLLECTION, new SubType(isSubType(sub) ? [...sub] : [main])]
|
@@ -1204,7 +1207,7 @@ export const typeCheck = (
|
|
1204
1207
|
if (name in env) {
|
1205
1208
|
// Types.set(withScope(name, env), () => formatType(name, env))
|
1206
1209
|
// If current scope is root then these are user defined types
|
1207
|
-
if (isLambda
|
1210
|
+
if (isLambda) {
|
1208
1211
|
const lambdaName = `${PLACEHOLDER}${name}`
|
1209
1212
|
check(
|
1210
1213
|
[
|
@@ -1259,6 +1262,26 @@ export const typeCheck = (
|
|
1259
1262
|
}
|
1260
1263
|
checkReturns()
|
1261
1264
|
checkArgs()
|
1265
|
+
// Check lambda body with defined types
|
1266
|
+
const copy = Object.create(env)
|
1267
|
+
for (let i = 0; i < env[name][STATS][ARGUMENTS].length; ++i) {
|
1268
|
+
const A = env[lambdaName][STATS][ARGUMENTS][i]
|
1269
|
+
const B = env[name][STATS][ARGUMENTS][i]
|
1270
|
+
copy[A[STATS][SIGNATURE]] = {
|
1271
|
+
[STATS]: {
|
1272
|
+
[SIGNATURE]: A[STATS][SIGNATURE],
|
1273
|
+
[TYPE_PROP]: B[STATS][TYPE_PROP],
|
1274
|
+
[RETURNS]: B[STATS][RETURNS]
|
1275
|
+
}
|
1276
|
+
}
|
1277
|
+
}
|
1278
|
+
check(
|
1279
|
+
wrapInApplyLambda(exp.at(-1).slice(2)).at(-1),
|
1280
|
+
copy,
|
1281
|
+
scope
|
1282
|
+
)
|
1283
|
+
// console.log(exp.at(-1).slice(1))
|
1284
|
+
// check(exp.at(-1), env, scope)
|
1262
1285
|
// Types.delete(`; ${rootScopeIndex} ${lambdaName}`)
|
1263
1286
|
}
|
1264
1287
|
typeSet(Types, name, env, exp)
|
package/src/keywords.js
CHANGED
package/src/types.js
CHANGED
@@ -91,49 +91,39 @@ export const toTypeNames = (type) => {
|
|
91
91
|
return 'Atom'
|
92
92
|
case NUMBER:
|
93
93
|
return 'Number'
|
94
|
-
// case ATOM:
|
95
|
-
// return 'Atom'
|
96
94
|
case UNKNOWN:
|
97
95
|
return 'Unknown'
|
98
96
|
case COLLECTION:
|
99
|
-
// return 'Array'
|
100
97
|
return 'Unknown[]'
|
101
98
|
case ANY:
|
102
99
|
return 'Any'
|
103
100
|
default:
|
104
|
-
|
101
|
+
return 'Unknown'
|
105
102
|
}
|
106
103
|
}
|
104
|
+
|
105
|
+
export const extractArrayType = (type) => {
|
106
|
+
const arr = [...type].filter((x) => x === '[')
|
107
|
+
return [type.split('[')[0], arr.length]
|
108
|
+
}
|
109
|
+
const fillArrayType = (n) => Array.from({ length: n - 1 }).fill(COLLECTION)
|
107
110
|
export const toTypeCodes = (type) => {
|
108
|
-
|
111
|
+
const [t, n] = extractArrayType(type)
|
112
|
+
switch (t) {
|
109
113
|
case 'Abstraction':
|
110
114
|
return [APPLY]
|
111
115
|
case 'Boolean':
|
116
|
+
if (n) return [COLLECTION, new SubType(fillArrayType(n).concat(BOOLEAN))]
|
112
117
|
return [ATOM, BOOLEAN_SUBTYPE()]
|
113
118
|
case 'Atom':
|
119
|
+
if (n) return [COLLECTION, new SubType(fillArrayType(n).concat(ATOM))]
|
114
120
|
return [ATOM]
|
115
121
|
case 'Number':
|
122
|
+
if (n) return [COLLECTION, new SubType(fillArrayType(n).concat(NUMBER))]
|
116
123
|
return [ATOM, NUMBER_SUBTYPE()]
|
117
124
|
case 'Unknown':
|
125
|
+
if (n) return [COLLECTION, new SubType(fillArrayType(n))]
|
118
126
|
return [UNKNOWN]
|
119
|
-
case 'Unknown[]':
|
120
|
-
case 'Unknowns':
|
121
|
-
// case 'Collection':
|
122
|
-
return [COLLECTION, new SubType([ANY])]
|
123
|
-
case 'Numbers':
|
124
|
-
case 'Number[]':
|
125
|
-
return [COLLECTION, NUMBER_SUBTYPE()]
|
126
|
-
case 'Booleans':
|
127
|
-
case 'Boolean[]':
|
128
|
-
return [COLLECTION, BOOLEAN_SUBTYPE()]
|
129
|
-
// case 'Collections':
|
130
|
-
// case 'Collection[]':
|
131
|
-
case 'Unknown[][]':
|
132
|
-
return [COLLECTION, COLLECTION_SUBTYPE()]
|
133
|
-
case 'Boolean[][]':
|
134
|
-
return [COLLECTION, new SubType([COLLECTION, BOOLEAN])]
|
135
|
-
case 'Number[][]':
|
136
|
-
return [COLLECTION, new SubType([COLLECTION, NUMBER])]
|
137
127
|
case 'Any':
|
138
128
|
return [ANY]
|
139
129
|
default:
|
package/src/utils.js
CHANGED
@@ -304,6 +304,10 @@ export const wrapInBlock = (ast) => [
|
|
304
304
|
[[APPLY, KEYWORDS.BLOCK], ...ast]
|
305
305
|
]
|
306
306
|
]
|
307
|
+
export const wrapInApplyLambda = (ast) => [
|
308
|
+
[APPLY, KEYWORDS.CALL_FUNCTION],
|
309
|
+
[[APPLY, KEYWORDS.ANONYMOUS_FUNCTION], ...ast]
|
310
|
+
]
|
307
311
|
export const interpret = (ast, keywords) =>
|
308
312
|
ast.reduce((_, x) => evaluate(x, keywords), 0)
|
309
313
|
export const shake = (parsed, std) => treeShake(parsed, std).concat(parsed)
|