Expand description
String interning.
Identifiers are compared constantly: on every macro lookup, every scope lookup, every
typedef disambiguation. Interning turns those comparisons into an integer compare and
turns the storage into one arena instead of a String per occurrence. The lexer interns
during the scan rather than after it, per spec/06-lexer-and-parser.md, so an identifier
is never materialised as a String at all.
§Reserved names
Every interner starts with the names in RESERVED already in it, in that order, which is
what makes the constants in sym the symbols they are. The reason is that a pass past the
lexer holds the interner through a shared reference and cannot add to it, and a pass that
builds a type of its own still has to name it: the members of the target’s va_list are
named by the ABI and never by the source, so the names have to exist before anything is read.
§Determinism
Symbol ordering is allocation order, which is the order the source was read in. That
is deterministic for a given input, and it is the reason the compiler can sort by symbol
anywhere it needs a stable order without reaching for the string. Hashing a Symbol must
never leak into output ordering, because hash order is not stable across runs, and
spec/02-the-goal.md makes byte-identical output a requirement rather than a nicety.
Modules§
Structs§
- Interner
- An append-only set of strings, each mapped to a
Symbol. - Symbol
- An interned string.
- Symbol
Table - Marker for the symbol table, so that
Idx<SymbolTable>cannot be confused with any other index.
Constants§
- RESERVED
- The names every interner is built with, in the order they are interned.