mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 21:14:28 -08:00
refactor calltree WIP
This commit is contained in:
@@ -176,8 +176,7 @@ const do_external_imports_loaded = (
|
|||||||
node.type == 'do' /* toplevel AST node */
|
node.type == 'do' /* toplevel AST node */
|
||||||
) {
|
) {
|
||||||
const result = eval_modules(
|
const result = eval_modules(
|
||||||
state.parse_result.modules,
|
state.parse_result,
|
||||||
state.parse_result.sorted,
|
|
||||||
external_imports,
|
external_imports,
|
||||||
state.on_async_call,
|
state.on_async_call,
|
||||||
)
|
)
|
||||||
@@ -199,8 +198,7 @@ const do_external_imports_loaded = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = eval_modules(
|
const result = eval_modules(
|
||||||
state.parse_result.modules,
|
state.parse_result,
|
||||||
state.parse_result.sorted,
|
|
||||||
external_imports,
|
external_imports,
|
||||||
state.on_async_call,
|
state.on_async_call,
|
||||||
{index: node.index, module: state.current_module},
|
{index: node.index, module: state.current_module},
|
||||||
@@ -680,7 +678,7 @@ const get_value_explorer = (state, index) => {
|
|||||||
result = {
|
result = {
|
||||||
ok: true,
|
ok: true,
|
||||||
value: pick_keys(
|
value: pick_keys(
|
||||||
state.calltree[stmt.full_import_path].exports,
|
state.modules[stmt.full_import_path],
|
||||||
stmt.imports.map(i => i.value)
|
stmt.imports.map(i => i.value)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|||||||
72
src/eval.js
72
src/eval.js
@@ -240,7 +240,7 @@ const codegen = (node, cxt, parent) => {
|
|||||||
return do_codegen(node.key) + ' : ' + do_codegen(node.value);
|
return do_codegen(node.key) + ' : ' + do_codegen(node.value);
|
||||||
} else if(node.type == 'import') {
|
} else if(node.type == 'import') {
|
||||||
const names = node.imports.map(n => n.value)
|
const names = node.imports.map(n => n.value)
|
||||||
return `const {${names.join(',')}} = __modules['${node.full_import_path}'].exports;`;
|
return `const {${names.join(',')}} = __modules['${node.full_import_path}'];`;
|
||||||
} else if(node.type == 'export') {
|
} else if(node.type == 'export') {
|
||||||
const identifiers = collect_destructuring_identifiers(node.binding.name_node)
|
const identifiers = collect_destructuring_identifiers(node.binding.name_node)
|
||||||
.map(i => i.value)
|
.map(i => i.value)
|
||||||
@@ -254,8 +254,7 @@ const codegen = (node, cxt, parent) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const eval_modules = (
|
export const eval_modules = (
|
||||||
modules,
|
parse_result,
|
||||||
sorted,
|
|
||||||
external_imports,
|
external_imports,
|
||||||
on_async_call,
|
on_async_call,
|
||||||
location
|
location
|
||||||
@@ -311,11 +310,11 @@ export const eval_modules = (
|
|||||||
|
|
||||||
const find_call = (location) => {
|
const find_call = (location) => {
|
||||||
searched_location = location
|
searched_location = location
|
||||||
const calltree = run()
|
const {modules, calltree} = run()
|
||||||
searched_location = null
|
searched_location = null
|
||||||
const call = found_call
|
const call = found_call
|
||||||
found_call = null
|
found_call = null
|
||||||
return {calltree, call}
|
return {modules, calltree, call}
|
||||||
}
|
}
|
||||||
|
|
||||||
const trace = (fn, name, argscount, __location, get_closure) => {
|
const trace = (fn, name, argscount, __location, get_closure) => {
|
||||||
@@ -488,23 +487,22 @@ export const eval_modules = (
|
|||||||
|
|
||||||
`
|
`
|
||||||
+
|
+
|
||||||
sorted
|
parse_result.sorted
|
||||||
.map((m, i) =>
|
.map((m, i) =>
|
||||||
`
|
`
|
||||||
__modules['${m}'] = {}
|
const current_module = '${m}'
|
||||||
found_call = null
|
found_call = null
|
||||||
children = null
|
children = null
|
||||||
current_call = {
|
current_call = {
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
module: '${m}',
|
module: current_module,
|
||||||
id: call_counter++
|
id: call_counter++
|
||||||
}
|
}
|
||||||
__modules['${m}'].calls = current_call
|
__modules[current_module] =
|
||||||
__modules['${m}'].exports =
|
|
||||||
(() => {
|
(() => {
|
||||||
try {
|
try {
|
||||||
const __exports = {};
|
const __exports = {};
|
||||||
${codegen(modules[m], {module: m})};
|
${codegen(parse_result.modules[m], {module: m})};
|
||||||
current_call.ok = true
|
current_call.ok = true
|
||||||
return __exports
|
return __exports
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
@@ -513,10 +511,10 @@ export const eval_modules = (
|
|||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
current_call.children = children
|
current_call.children = children
|
||||||
if(!__modules['${m}'].calls.ok) {
|
if(!current_call.ok) {
|
||||||
is_recording_async_calls = true
|
is_recording_async_calls = true
|
||||||
children = null
|
children = null
|
||||||
return __modules
|
return { modules: __modules, calltree: current_call }
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@@ -525,7 +523,7 @@ export const eval_modules = (
|
|||||||
`
|
`
|
||||||
is_recording_async_calls = true
|
is_recording_async_calls = true
|
||||||
children = null
|
children = null
|
||||||
return __modules
|
return { modules: __modules, call: calltree: current_call }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -549,18 +547,18 @@ export const eval_modules = (
|
|||||||
,
|
,
|
||||||
|
|
||||||
/* on_async_call */
|
/* on_async_call */
|
||||||
call => on_async_call(assign_code(modules, call))
|
call => on_async_call(assign_code(parse_result.modules, call))
|
||||||
)
|
)
|
||||||
|
|
||||||
const calltree_actions = {
|
const calltree_actions = {
|
||||||
expand_calltree_node: (node) => {
|
expand_calltree_node: (node) => {
|
||||||
const expanded = actions.expand_calltree_node(node)
|
const expanded = actions.expand_calltree_node(node)
|
||||||
return assign_code(modules, expanded)
|
return assign_code(parse_result.modules, expanded)
|
||||||
},
|
},
|
||||||
find_call: (loc) => {
|
find_call: (loc) => {
|
||||||
const {calltree, call} = actions.find_call(loc)
|
const {modules, calltree, call} = actions.find_call(loc)
|
||||||
return {
|
return {
|
||||||
calltree: assign_code_calltree(modules, calltree),
|
calltree: assign_code(parse_result.modules, calltree),
|
||||||
// TODO: `call` does not have `code` property here. Currently it is
|
// TODO: `call` does not have `code` property here. Currently it is
|
||||||
// worked around by callers. Refactor
|
// worked around by callers. Refactor
|
||||||
call,
|
call,
|
||||||
@@ -568,38 +566,23 @@ export const eval_modules = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let calltree, call
|
const result = location == null
|
||||||
|
? actions.run()
|
||||||
if(location == null) {
|
: calltree_actions.find_call(location)
|
||||||
calltree = actions.run()
|
|
||||||
} else {
|
|
||||||
const result = calltree_actions.find_call(location)
|
|
||||||
calltree = result.calltree
|
|
||||||
call = result.call
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
calltree: assign_code_calltree(modules, calltree),
|
modules: result.modules,
|
||||||
call,
|
calltree: assign_code(parse_result.modules, result.calltree),
|
||||||
|
call: result.call,
|
||||||
calltree_actions,
|
calltree_actions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: assign_code: benchmark and use imperative version for perf?
|
// TODO: assign_code: benchmark and use imperative version for perf?
|
||||||
const assign_code_calltree = (modules, calltree) =>
|
const assign_code = (modules, call) => {
|
||||||
map_object(
|
|
||||||
calltree,
|
|
||||||
(module, {calls, exports, is_external}) => {
|
|
||||||
return is_external
|
|
||||||
? {is_external, exports}
|
|
||||||
: {exports, calls: assign_code(modules, calls, modules[module])}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const assign_code = (modules, call, module) => {
|
|
||||||
if(call.toplevel) {
|
if(call.toplevel) {
|
||||||
return {...call,
|
return {...call,
|
||||||
code: module,
|
code: modules[call.module],
|
||||||
children: call.children && call.children.map(call => assign_code(modules, call)),
|
children: call.children && call.children.map(call => assign_code(modules, call)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -614,7 +597,12 @@ const assign_code = (modules, call, module) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const eval_tree = node => {
|
export const eval_tree = node => {
|
||||||
return eval_modules({'': node}, ['']).calltree[''].calls
|
return eval_modules(
|
||||||
|
{
|
||||||
|
modules: {'': node}},
|
||||||
|
sorted: ['']
|
||||||
|
}
|
||||||
|
).calltree[''].calls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ run([
|
|||||||
} else {
|
} else {
|
||||||
assert_equal(parsed.ok, true)
|
assert_equal(parsed.ok, true)
|
||||||
console.time('eval')
|
console.time('eval')
|
||||||
const result = eval_modules(parsed.modules, parsed.sorted).calltree
|
const result = eval_modules(parsed).calltree
|
||||||
console.timeEnd('eval')
|
console.timeEnd('eval')
|
||||||
|
|
||||||
/* TODO remove
|
/* TODO remove
|
||||||
|
|||||||
@@ -633,7 +633,7 @@ export const tests = [
|
|||||||
'b' : 'import {a} from "a"; export const b = a*2;',
|
'b' : 'import {a} from "a"; export const b = a*2;',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const calltree = eval_modules(parsed.modules, parsed.sorted).calltree;
|
const calltree = eval_modules(parsed).calltree;
|
||||||
const frame = eval_frame(calltree.b.calls, calltree)
|
const frame = eval_frame(calltree.b.calls, calltree)
|
||||||
assert_equal(frame.children[1].result, {ok: true})
|
assert_equal(frame.children[1].result, {ok: true})
|
||||||
assert_equal(frame.children[1].children[0].children[1].result, {ok: true, value: 2})
|
assert_equal(frame.children[1].children[0].children[1].result, {ok: true, value: 2})
|
||||||
@@ -757,7 +757,7 @@ export const tests = [
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
assert_equal(parsed.sorted, ['a', 'b', 'c1', 'c2', 'd'])
|
assert_equal(parsed.sorted, ['a', 'b', 'c1', 'c2', 'd'])
|
||||||
const result = eval_modules(parsed.modules, parsed.sorted).calltree;
|
const result = eval_modules(parsed).calltree;
|
||||||
assert_equal(result.d.exports.d, 8)
|
assert_equal(result.d.exports.d, 8)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -779,7 +779,7 @@ export const tests = [
|
|||||||
'leaf' : 'export const leaf = {}',
|
'leaf' : 'export const leaf = {}',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const mods = eval_modules(parsed.modules, parsed.sorted).calltree
|
const mods = eval_modules(parsed).calltree
|
||||||
// Check that the same symbol improted through different paths gives the
|
// Check that the same symbol improted through different paths gives the
|
||||||
// same result
|
// same result
|
||||||
assert_equal(mods.root.exports.is_eq, true)
|
assert_equal(mods.root.exports.is_eq, true)
|
||||||
|
|||||||
Reference in New Issue
Block a user