fez-lisp 1.1.14 → 1.1.15
Sign up to get free protection for your applications and to get access to all the features.
- package/index.js +1 -0
- package/package.json +1 -1
- package/src/utils.js +66 -61
package/index.js
CHANGED
package/package.json
CHANGED
package/src/utils.js
CHANGED
@@ -133,70 +133,68 @@ export const handleUnbalancedQuotes = (source) => {
|
|
133
133
|
return source
|
134
134
|
}
|
135
135
|
export const removeMutation = (source) => source.replace(new RegExp(/!/g), 'ǃ')
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
136
|
+
const isDefinition = (x) =>
|
137
|
+
x[TYPE] === APPLY &&
|
138
|
+
(x[VALUE] === KEYWORDS.DEFINE_VARIABLE ||
|
139
|
+
x[VALUE] === KEYWORDS.TAIL_CALLS_OPTIMISED_RECURSIVE_FUNCTION)
|
140
|
+
const toDeps = (libs) =>
|
141
|
+
libs.reduce(
|
142
|
+
(a, x, i) => a.set(x.at(1)[VALUE], { value: x, index: i }),
|
143
|
+
new Map()
|
144
|
+
)
|
145
|
+
const deepShake = (tree, deps, visited = new Set(), ignored = new Set()) => {
|
146
|
+
const type = tree[TYPE]
|
147
|
+
const value = tree[VALUE]
|
148
|
+
if (!isLeaf(tree)) {
|
149
|
+
const [car, ...rest] = tree
|
150
|
+
if (car == undefined) return
|
151
|
+
if (isDefinition(car)) {
|
145
152
|
if (
|
146
|
-
|
147
|
-
|
148
|
-
|
153
|
+
!isLeaf(rest.at(-1)) &&
|
154
|
+
rest
|
155
|
+
.at(-1)
|
156
|
+
.some(
|
157
|
+
(x) => x[TYPE] === APPLY && x[VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
|
158
|
+
)
|
149
159
|
) {
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
x[TYPE] === APPLY &&
|
165
|
-
(x[VALUE] === KEYWORDS.ANONYMOUS_FUNCTION ||
|
166
|
-
x[VALUE] === KEYWORDS.IMMUTABLE_FUNCTION)
|
167
|
-
)
|
168
|
-
)
|
169
|
-
const body = args.pop()
|
170
|
-
const params = new Set(args.map((x) => x[VALUE]))
|
171
|
-
dfs(body, params)
|
172
|
-
} else rest.forEach((x) => dfs(x, ignore))
|
173
|
-
} else tree.forEach((x) => dfs(x, ignore))
|
174
|
-
} else if (
|
175
|
-
(type === APPLY || type === WORD) &&
|
176
|
-
deps.has(value) &&
|
177
|
-
!visited.has(value) &&
|
178
|
-
!ignore.has(value)
|
179
|
-
) {
|
180
|
-
visited.add(value)
|
181
|
-
// Recursively explore the dependencies of the current node
|
182
|
-
dfs(deps.get(value), ignore)
|
183
|
-
}
|
160
|
+
const args = rest.at(-1).filter((x) => !isDefinition(x))
|
161
|
+
const body = args.pop()
|
162
|
+
const params = new Set(args.map((x) => x[VALUE]))
|
163
|
+
deepShake(body, deps, visited, params)
|
164
|
+
} else rest.forEach((x) => deepShake(x, deps, visited, ignored))
|
165
|
+
} else tree.forEach((x) => deepShake(x, deps, visited, ignored))
|
166
|
+
} else if (
|
167
|
+
(type === APPLY || type === WORD) &&
|
168
|
+
deps.has(value) &&
|
169
|
+
!visited.has(value) &&
|
170
|
+
!ignored.has(value)
|
171
|
+
) {
|
172
|
+
visited.add(value)
|
173
|
+
deepShake(deps.get(value).value, deps, visited, ignored)
|
184
174
|
}
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
)
|
198
|
-
|
199
|
-
|
175
|
+
}
|
176
|
+
const extractDeps = (visited, deps) =>
|
177
|
+
[...visited]
|
178
|
+
.map((x) => deps.get(x))
|
179
|
+
.sort((a, b) => a.index - b.index)
|
180
|
+
.map((x) => x.value)
|
181
|
+
const toIgnore = (ast) =>
|
182
|
+
ast.filter(([x]) => isDefinition(x)).map(([_, x]) => x[VALUE])
|
183
|
+
export const treeShake = (ast, libs) => {
|
184
|
+
const deps = toDeps(libs)
|
185
|
+
const visited = new Set()
|
186
|
+
const ignored = new Set(toIgnore(ast))
|
187
|
+
deepShake(ast, deps, visited, ignored)
|
188
|
+
return extractDeps(visited, deps)
|
189
|
+
}
|
190
|
+
export const shakedList = (ast, libs) => {
|
191
|
+
const deps = toDeps(libs)
|
192
|
+
const visited = new Set()
|
193
|
+
const ignored = new Set(toIgnore(ast))
|
194
|
+
deepShake(ast, deps, visited, ignored)
|
195
|
+
const out = []
|
196
|
+
for (const [key] of deps) if (visited.has(key)) out.push(key)
|
197
|
+
return out
|
200
198
|
}
|
201
199
|
export const dfs = (tree, callback) => {
|
202
200
|
if (!isLeaf(tree)) for (const leaf of tree) dfs(leaf)
|
@@ -323,6 +321,13 @@ export const ast = (source, deps) => {
|
|
323
321
|
...source
|
324
322
|
]
|
325
323
|
}
|
324
|
+
export const dependencies = (source, deps) => {
|
325
|
+
source = prep(source)
|
326
|
+
return shakedList(
|
327
|
+
source,
|
328
|
+
deps.reduce((a, b) => a.concat(b), [])
|
329
|
+
)
|
330
|
+
}
|
326
331
|
export const js = (source, deps) => {
|
327
332
|
source = prep(source)
|
328
333
|
const { top, program } = comp([
|