diff --git a/src/evaluate/declaration.ts b/src/evaluate/declaration.ts index 8b0984e..e687df9 100644 --- a/src/evaluate/declaration.ts +++ b/src/evaluate/declaration.ts @@ -38,11 +38,11 @@ export function* VariableDeclarator( scope: Scope, options: VariableDeclaratorOptions & VariableDeclarationOptions = {}, ) { - const { kind = 'let', hoist = false, onlyBlock = false, feed } = options + const { kind = 'var', hoist = false, onlyBlock = false, feed } = options if (hoist) { if (onlyBlock || kind === 'var') { if (node.id.type === 'Identifier') { - scope[onlyBlock ? kind : 'var'](node.id.name, onlyBlock ? DEADZONE : undefined) + scope[kind](node.id.name, onlyBlock ? DEADZONE : kind === 'var' ? NOINIT : undefined) } else { yield* pattern(node.id, scope, { kind, hoist, onlyBlock }) } diff --git a/src/evaluate/helper.ts b/src/evaluate/helper.ts index 18aa37f..8622e17 100644 --- a/src/evaluate/helper.ts +++ b/src/evaluate/helper.ts @@ -143,9 +143,9 @@ export function createFunc( for (let i = 0; i < params.length; i++) { const param = params[i] if (param.type === 'Identifier') { - subScope.let(param.name, args[i]) + subScope.var(param.name, args[i]) } else if (param.type === 'RestElement') { - yield* RestElement(param, subScope, { kind: 'let', feed: args.slice(i) }) + yield* RestElement(param, subScope, { kind: 'var', feed: args.slice(i) }) } else { yield* pattern(param, subScope, { feed: args[i] }) } diff --git a/src/evaluate/pattern.ts b/src/evaluate/pattern.ts index 4721478..8585582 100644 --- a/src/evaluate/pattern.ts +++ b/src/evaluate/pattern.ts @@ -1,6 +1,6 @@ +import { NOINIT, DEADZONE } from '../share/const' import { VarKind } from '../scope/variable' import { Identifier } from './identifier' -import { DEADZONE } from '../share/const' import { assign } from '../share/util' import { pattern } from './helper' import * as estree from 'estree' @@ -15,7 +15,7 @@ export interface PatternOptions { } export function* ObjectPattern(node: estree.ObjectPattern, scope: Scope, options: PatternOptions = {}) { - const { kind = 'let', hoist = false, onlyBlock = false, feed = {} } = options + const { kind = 'var', hoist = false, onlyBlock = false, feed = {} } = options const fedKeys: string[] = [] for (let i = 0; i < node.properties.length; i++) { const property = node.properties[i] @@ -24,7 +24,7 @@ export function* ObjectPattern(node: estree.ObjectPattern, scope: Scope, options if (property.type === 'Property') { const value = property.value if (value.type === 'Identifier') { - scope[onlyBlock ? kind : 'var'](value.name, onlyBlock ? DEADZONE : undefined) + scope[kind](value.name, onlyBlock ? DEADZONE : kind === 'var' ? NOINIT : undefined) } else { yield* pattern(value, scope, { kind, hoist, onlyBlock }) } @@ -64,7 +64,7 @@ export function* ArrayPattern(node: estree.ArrayPattern, scope: Scope, options: if (hoist) { if (onlyBlock || kind === 'var') { if (element.type === 'Identifier') { - scope[onlyBlock ? kind : 'var'](element.name, onlyBlock ? DEADZONE : undefined) + scope[kind](element.name, onlyBlock ? DEADZONE : kind === 'var' ? NOINIT : undefined) } else { yield* pattern(element, scope, { kind, hoist, onlyBlock }) } @@ -96,7 +96,7 @@ export function* RestElement(node: estree.RestElement, scope: Scope, options: Pa if (hoist) { if (onlyBlock || kind === 'var') { if (arg.type === 'Identifier') { - scope[onlyBlock ? kind : 'var'](arg.name, onlyBlock ? DEADZONE : undefined) + scope[kind](arg.name, onlyBlock ? DEADZONE : kind === 'var' ? NOINIT : undefined) } else { yield* pattern(arg, scope, { kind, hoist, onlyBlock }) } @@ -116,12 +116,12 @@ export function* RestElement(node: estree.RestElement, scope: Scope, options: Pa } export function* AssignmentPattern(node: estree.AssignmentPattern, scope: Scope, options: PatternOptions = {}) { - const { kind = 'let', hoist = false, onlyBlock = false, feed = yield* evaluate(node.right, scope) } = options + const { kind = 'var', hoist = false, onlyBlock = false, feed = yield* evaluate(node.right, scope) } = options const left = node.left if (hoist) { if (onlyBlock || kind === 'var') { if (left.type === 'Identifier') { - scope[onlyBlock ? kind : 'var'](left.name, onlyBlock ? DEADZONE : undefined) + scope[kind](left.name, onlyBlock ? DEADZONE : kind === 'var' ? NOINIT : undefined) } else { yield* pattern(left, scope, { kind, hoist, onlyBlock }) } diff --git a/src/evaluate/statement.ts b/src/evaluate/statement.ts index 56d217c..399cf3b 100644 --- a/src/evaluate/statement.ts +++ b/src/evaluate/statement.ts @@ -116,7 +116,7 @@ export function* TryStatement(node: estree.TryStatement, scope: Scope) { if (param) { if (param.type === 'Identifier') { const name = param.name - subScope.let(name, err) + subScope.var(name, err) } else { yield* pattern(param, scope, { feed: err }) } diff --git a/tests/function.test.ts b/tests/function.test.ts index 6df3a30..5733976 100644 --- a/tests/function.test.ts +++ b/tests/function.test.ts @@ -15,6 +15,18 @@ describe('testing src/index.ts', () => { expect(interpreter.exports.x).toBeTruthy() }) + it('should redeclare param inside function by var', () => { + const interpreter = new Sval() + interpreter.run(` + a(1) + function a(b) { + var b = b + 1 + exports.b = b + } + `) + + expect(interpreter.exports.b).toBe(2) + }) it('should yield generator normally', () => { const interpreter = new Sval()