(P: ParseState)
| 1425 | } |
| 1426 | |
| 1427 | function tryParseAssignment(P: ParseState): TsNode | null { |
| 1428 | const save = saveLex(P.L) |
| 1429 | skipBlanks(P.L) |
| 1430 | const startB = P.L.b |
| 1431 | // Must start with identifier |
| 1432 | if (!isIdentStart(peek(P.L))) { |
| 1433 | restoreLex(P.L, save) |
| 1434 | return null |
| 1435 | } |
| 1436 | while (isIdentChar(peek(P.L))) advance(P.L) |
| 1437 | const nameEnd = P.L.b |
| 1438 | // Optional subscript |
| 1439 | let subEnd = nameEnd |
| 1440 | if (peek(P.L) === '[') { |
| 1441 | advance(P.L) |
| 1442 | let depth = 1 |
| 1443 | while (P.L.i < P.L.len && depth > 0) { |
| 1444 | const c = peek(P.L) |
| 1445 | if (c === '[') depth++ |
| 1446 | else if (c === ']') depth-- |
| 1447 | advance(P.L) |
| 1448 | } |
| 1449 | subEnd = P.L.b |
| 1450 | } |
| 1451 | const c = peek(P.L) |
| 1452 | const c1 = peek(P.L, 1) |
| 1453 | let op: string |
| 1454 | if (c === '=' && c1 !== '=') { |
| 1455 | op = '=' |
| 1456 | } else if (c === '+' && c1 === '=') { |
| 1457 | op = '+=' |
| 1458 | } else { |
| 1459 | restoreLex(P.L, save) |
| 1460 | return null |
| 1461 | } |
| 1462 | const nameNode = mk(P, 'variable_name', startB, nameEnd, []) |
| 1463 | // Subscript handling: wrap in subscript node if present |
| 1464 | let lhs: TsNode = nameNode |
| 1465 | if (subEnd > nameEnd) { |
| 1466 | const brOpen = mk(P, '[', nameEnd, nameEnd + 1, []) |
| 1467 | const idx = parseSubscriptIndex(P, nameEnd + 1, subEnd - 1) |
| 1468 | const brClose = mk(P, ']', subEnd - 1, subEnd, []) |
| 1469 | lhs = mk(P, 'subscript', startB, subEnd, [nameNode, brOpen, idx, brClose]) |
| 1470 | } |
| 1471 | const opStart = P.L.b |
| 1472 | advance(P.L) |
| 1473 | if (op === '+=') advance(P.L) |
| 1474 | const opEnd = P.L.b |
| 1475 | const opNode = mk(P, op, opStart, opEnd, []) |
| 1476 | let val: TsNode | null = null |
| 1477 | if (peek(P.L) === '(') { |
| 1478 | // Array |
| 1479 | const aoTok = nextToken(P.L, 'cmd') |
| 1480 | const aOpen = leaf(P, '(', aoTok) |
| 1481 | const elems: TsNode[] = [aOpen] |
| 1482 | while (true) { |
| 1483 | skipBlanks(P.L) |
| 1484 | if (peek(P.L) === ')') break |
no test coverage detected