The blaise compiler now compiles its own source (tests/blaise-compiler.pas)
into a second-stage binary that successfully compiles and runs a hello-world
program. All 834 compiler tests still pass.
Codegen and RTL fixes that unblocked self-hosting:
- String literal interning (uCodeGenQBE): set FStrLits.CaseSensitive := True.
FPC's TStringList.IndexOf is case-insensitive by default, so distinct
literals like 'WRITELN' and 'WriteLn' collapsed to the same label.
- ARC on implicit Self.Field assignments (uCodeGenQBE): EmitAssignment's
implicit-Self branch did a raw storel for class/string fields. Fresh
_ClassAlloc'ed objects start at refcnt 0, so without the addref they were
freed by later local releases. Now addrefs new value and releases old.
- #nn character literals (uLexer): UnescapeString handled only 'text'.
Extended to decode #nn decimal literals and concatenated forms like
'abc'#13#10'def'. Local OrdAt helper lets the body parse under FPC and
the self-hosted compiler.
- Chr() builtin: registered in uSymbolTable, handled in uSemantic, emitted
in uCodeGenQBE as _Chr, implemented in rtl/blaise_str.c.
- LF line separator (Classes.pas): TStringList.GetText used #13#10; QBE
rejects CR in its input. Changed to #10.
Self-hosting source (tests/blaise-compiler.pas) — needs a virtual Destroy
on TASTNode and Exception (post-TObject-stripping they became root classes
without a vtable, breaking `is` checks and exception message layout).
TAST* descendants chain `override`.
Migration tooling: add tools/migrate_full.py — the script that generates
tests/blaise-compiler.pas by flattening the eight compiler units and RTL
Classes unit into a single self-contained Pascal source. The postprocess()
step injects virtual Destroy on TASTNode / TTypeDesc and strips `override`
from non-vtable root classes.