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