diff --git a/src/eval.js b/src/eval.js index 3a67f95..789a2f3 100644 --- a/src/eval.js +++ b/src/eval.js @@ -833,17 +833,14 @@ const apply_assignments = (node, assignments) => { .flat() .map(c => c.index) + const parent_assignments = Object.entries(assignments).filter(([index, v]) => + let_ids.find(i => i.toString() == index) == null + ) // Scope we return to parent block const scope = Object.fromEntries( - Object - .entries(assignments) - .filter(([index, v]) => - let_ids.find(i => i.toString() == index) == null - ) - .map(([k, {name, value}]) => [name, value]) + parent_assignments.map(([k, {name, value}]) => [name, value]) ) - - return {node, scope} + return {node, scope, assignments: Object.fromEntries(parent_assignments)} } const eval_decl_pair = (s, scope, calls, context, is_assignment) => { @@ -993,14 +990,14 @@ const eval_statement = (s, scope, calls, context) => { }, {ok: true, returned: false, children: [], scope: initial_scope, calls, assignments: {}} ) - const {node: next_node, scope: next_scope} = + const {node: next_node, scope: next_scope, assignments: parent_assignments} = apply_assignments({...s, children: children, result: {ok}}, assignments) return { ok, node: next_node, scope: {...scope, ...next_scope}, returned, - assignments, + parent_assignments, calls: next_calls, } } else if(['let', 'const', 'assignment'].includes(s.type)) { diff --git a/test/test.js b/test/test.js index cbe6e3c..a5daa62 100644 --- a/test/test.js +++ b/test/test.js @@ -1555,6 +1555,25 @@ export const tests = [ ) }), + test('block scoping shadow bug', () => { + assert_code_evals_to( + ` + let y = 3 + if(true) { + let y + y = 1 + if(true) { + let y + y = 2 + } + y + } + y + `, + 3 + ) + }), + test('step_into', () => { const code = ` const x = () => 1;