Skip to content

Register the UnicodeString keyword handler - #5

Merged
partouf merged 2 commits into
mainfrom
fix/register-unicodestring
Oct 8, 2026
Merged

partouf merged 2 commits into
mainfrom
fix/register-unicodestring

Conversation

@partouf

@partouf partouf commented Oct 8, 2026

Copy link
Copy Markdown
Member

Bug. TmwBasePasLex.Func158 lexes UnicodeString as ptString with ExID ptUnicodeString, the same way AnsiString and WideString are lexed, but InitIdent never put it in FIdentFuncTable. 'UnicodeString' hashes to 158, which had no entry, so the handler was unreachable (Delphi: H2219 Private symbol 'Func158' declared but never used) and the word lexed as a plain identifier. It has been that way since Func158 was added in 8fb608d.

Declarations parse the same either way. The difference is a typecast:

s := UnicodeString(p^);   // CALL( IDENTIFIER name=UnicodeString, ... )  - before
s := UnicodeString(p^);   // CALL( TYPE name=UnicodeString, ... )        - after
r := AnsiString(p^);      // CALL( TYPE name=AnsiString, ... )           - always

Before, the cast could not be told apart from a call to a routine named UnicodeString.

Fix. Add 158: FIdentFuncTable[I] := Func158;.

Test. AST.UnicodeStringTypecast is added to Test/UnitTests. It fails on main ("A UnicodeString typecast has a type as its callee.") and passes with this change. A parse-tree dump of a unit using UnicodeString as field, parameter, return and variable type differs only in that typecast callee.

Serialization.BinaryRoundTrip fails with and without this change under Delphi 10.4 (line_seq comes back as 0), so it is not related.

🤖 Generated with Claude Code

Partouf and others added 2 commits October 8, 2026 18:16
TmwBasePasLex.Func158 lexes UnicodeString as ptString with ExID
ptUnicodeString, the way Func-handlers already treat AnsiString and
WideString, but InitIdent never put it in FIdentFuncTable. 'UnicodeString'
hashes to 158, which had no entry, so the handler was unreachable (Delphi:
H2219 Private symbol 'Func158' declared but never used) and the word lexed
as a plain identifier.

Declarations parse the same either way. The difference is a typecast:
UnicodeString(p^) built a CALL whose callee was an IDENTIFIER, which
cannot be told apart from a call to a routine of that name, while
AnsiString(p^) and WideString(p^) build a TYPE callee. Now all three do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AST.UnicodeStringTypecast parses `s := UnicodeString(p^)` and checks that
the CALL's callee is an ntType named UnicodeString. It fails without the
Func158 registration ("A UnicodeString typecast has a type as its callee.")
and passes with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@partouf
partouf merged commit 14e1339 into main Oct 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant