Array Destructuring #17
|
|
@ -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 /* = */
|
||||
}
|
||||
|
|
@ -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', () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user