Array Destructuring #17

Merged
probablycorey merged 4 commits from array-destructuring into main 2025-10-31 17:08:25 +00:00
2 changed files with 49 additions and 2 deletions
Showing only changes of commit f31be80bb0 - Show all commits

View File

@ -2,7 +2,7 @@ import { ContextTracker, InputStream } from '@lezer/lr'
import * as terms from './shrimp.terms'
export class Scope {
constructor(public parent: Scope | null, public vars = new Set<string>()) {}
constructor(public parent: Scope | null, public vars = new Set<string>()) { }
has(name: string): boolean {
return this.vars.has(name) || (this.parent?.has(name) ?? false)
@ -42,7 +42,7 @@ export class Scope {
// Tracker context that combines Scope with temporary pending identifiers
class TrackerContext {
constructor(public scope: Scope, public pendingIds: string[] = []) {}
constructor(public scope: Scope, public pendingIds: string[] = []) { }
}
// Extract identifier text from input stream
@ -75,6 +75,12 @@ export const trackScope = new ContextTracker<TrackerContext>({
return new TrackerContext(context.scope, [...context.pendingIds, text])
}
// Track identifiers in array destructuring: [ a b ] = ...
if (!inParams && term === terms.Identifier && isArrayDestructuring(input)) {
const text = readIdentifierText(input, input.pos, stack.pos)
return new TrackerContext(Scope.add(context.scope, text), context.pendingIds)
}
return context
},
@ -98,3 +104,26 @@ export const trackScope = new ContextTracker<TrackerContext>({
hash: (context) => context.scope.hash(),
})
// Check if we're parsing array destructuring: [ a b ] = ...
const isArrayDestructuring = (input: InputStream): boolean => {
let pos = 0
// Find closing bracket
while (pos < 200 && input.peek(pos) !== 93 /* ] */) {
if (input.peek(pos) === -1) return false // EOF
pos++
}
if (input.peek(pos) !== 93 /* ] */) return false
pos++
// Skip whitespace
while (input.peek(pos) === 32 /* space */ ||
input.peek(pos) === 9 /* tab */ ||
input.peek(pos) === 10 /* \n */) {
pos++
}
return input.peek(pos) === 61 /* = */
}

View File

@ -630,6 +630,24 @@ describe('Array destructuring', () => {
Number 1
Number 2`)
})
test('works with dotget', () => {
expect('[ a ] = [ [1 2 3] ]; a.1').toMatchTree(`
Assign
Array
Identifier a
Eq =
Array
Array
Number 1
Number 2
Number 3
FunctionCallOrIdentifier
DotGet
IdentifierBeforeDot a
Number 1`)
})
})
describe('Conditional ops', () => {