The `#` dispatch fired `consumeLineComment()` whenever
`paramBraceDepth == 0`, regardless of preceding context. That broke
every case where `#` is NOT a comment per zsh's lexer rules:
* `echo "0xff=$((0xff)) 2#1010=$((2#1010))"` — base-N separator
inside arith. `# 1010 ))` got eaten as a comment and the closing
`))` never got tokenized, cascading the rest of the file.
* `(( 2#10 ))` — same, outside DQ string.
* `abc#def` — mid-word `#`. zsh prints `abc#def` (one word); we
were splitting at `#` and ate `def\n` as a comment.
* `*##.zsh` / `x#` — extended-glob quantifiers (one-or-more /
zero-or-more of preceding pattern).
Audit: surveyed every zsh non-comment `#` context:
- `${#var}` length-op, `${var/#pat/repl}` pattern-anchor —
handled by `paramBraceDepth > 0` arm (unchanged).
- `$#` positional count — handled by consumeDollar special-vars
set `?!$#*@-_` (unchanged).
- `(#qX)` glob qualifier prefix — handled by tryConsumeGlobQualifier's
GLOB_QUAL_CHARS set (`#` included; unchanged).
- `#!` shebang — handled at line 128 (unchanged).
- All other contexts (arith base, mid-word, glob quantifier) need
the word-start gate added here.
Fix: new `isCommentStart()` peek-back. `#` opens a comment only when
preceded by BOL / whitespace / `;|&()[]{}<>!` (zsh's word-separator
metachars per Src/lex.c::isep + Src/utils.c::inittyptab). Anywhere
else, `#` is mid-word and emits as a single-char OPERATOR token
(distinct color from STRING_DQ; doesn't cascade).