← Contents

Appendix C

Source Map and Glossary

Where to look for what

If you are changingStart inAlso read
tokenization, quoting, heredocsLexer.cpp, Token.hChapter 4
statement or expression syntaxParser.cpp, Ast.hChapters 5 and 7
a user-declared operatorParser.cpp parseSub, the userInfix_ familyChapter 6
what a value isValue.hChapter 8
string performanceValue.h CowStr, BuiltinsShared.hChapters 9 and 24
the number towerBigInt.cpp, IntOps.h, Value::ratChapter 11
scoping, assignment, bindingInterpreter.cpp lvalue, evalAssignChapter 12
calls and signaturesInterpreter.cpp callCallableRaw, bindParamsChapter 14
return, next, last, whenthe cooperative registers in ExecContextChapter 15
a built-in routineBuiltins.cpp registerBuiltinsChapter 16
a built-in methodthe four methodCall segments, in orderChapters 2 and 16
classes, roles, mixinsInterpreter.cpp ClassDecl handling, Value.hChapter 17
laziness, gatherLazySeqState, seqOp, the gather stackChapter 18
interpreter speedevalBinary, evalIndex, the decided-once fieldsChapter 19
regex syntaxRegex.cpp parseAtomChapter 20
regex matchingRegex.cpp matchNodeChapter 21
grammarsGrammarMatcher, Interpreter::grammarParseChapter 22
alternation rankingLtmNfa.cppChapter 23
UnicodeUnicode.cpp, tools/ucd/, the generatorsChapter 24
the CLI and compile driversmain.cppChapter 25
the native compilerCodegen.cpp, the rt* helpers in Interpreter.hChapters 26 to 28
what a binary keepsSlimScan.cpp, ucd_seam.h, src/stubs/Chapter 29
the parse cacheAstSerial.cppChapter 30
the browser buildrakujs/rakupp_web.cpp, rakujs/build.sh, raku.jsChapter 31
module loadingInterpreter.cpp loadModule, Parser.cpp scanModuleOpsChapter 32
the installer and the storetools/install.raku, Builtins.cpp .installChapter 33
nqp:: opsParser::makeNqpOp, Interpreter::evalNqpOpChapter 34
NativeCallFfi.cpp, Interpreter::callNativeChapter 35
the extension ABIrakupp_ext.h, ExtApi.cppChapter 36
embedding — Raku inside a hostrakupp.h, EmbedApi.cppChapter 36
threads, the GIL, suppliesInterpreter.h's concurrency sectionChapter 37
lint, highlight, profile, REPLLint.cpp, Highlight.cpp, Profiler.cpp, Repl.cppChapter 38
the undeclared-variable gateDeclCheck.cpp, isSpecialVar in Interpreter.cppChapter 38
the MCP serverMcpServer.cppChapter 38

Rules that are easy to break by accident

Collected here because each has cost real debugging time.

The method-dispatch chain is order-sensitive. The four segments are ordered slices of one function; later arms deliberately catch what earlier ones decline. Moving an arm for readability is a behaviour change.

A decided-once field may hold a fact about the syntax, never a value that can change. The literal cache is the one exception, and a literal is a constant by definition.

Never store an FnRef. It borrows the caller's lambda; storing it dangles.

A pointer is only a valid map key when its target's lifetime is at least the map's. AST nodes are never freed, so a flip-flop state map keyed on one is fine. Regex nodes are freed and their addresses recycled, which is why a cache keyed on one produced automata built for other patterns.

Intern a closed vocabulary, never an open one. The intern table is append-only, so a field that can hold arbitrary runtime data would leak an entry per distinct value.

Do not add a non-const operator[], begin() or data() to CowStr. That is exactly the interface that made copy-on-write non-conforming for std::string.

Add an early exit, never restructure the general path underneath it. The first node specialisation cost the control 5.7% by doing the latter.

A memo is only sound if the thing memoised is a function of the key. A grammar rule that reads a dynamic variable is not a function of (rule, position), which is what the dynDep flag records.

gilPark's window must touch no interpreter state. Only thread-local buffers and syscalls.

Never join a thread while holding the lock the joinee might want.

A derived-data mechanism must degrade to recomputation, never to a guess. Every failure mode in the caching and emitting paths ends in "parse it again".

Glossary

AOT — the --aot mode: parse at build time, emit C++ that rebuilds the AST, then interpret it at run time.

Allomorph — a value that is simultaneously a number and its own string, such as IntStr. Represented as a numeric tag with the text in s.

Autothreading — distributing an operation over a junction's eigenstates and recombining the results.

Bundle — the --bundle mode: embed the source bytes in a standalone binary that parses and interprets them at run time.

Byteset — a 256-bit bitmap cached on a regex character-class node, answering "does this byte match?" without re-deriving the class.

Cooperative control flow — implementing return, next, last and when with a flag and a frame counter instead of a C++ exception, when no callable boundary was crossed.

Declarative prefix — the leading part of a regex alternative made of literals, character classes and quantifiers, up to the first procedural construct. What longest-token matching ranks by.

Decided-once field — a mutable field on an AST node holding a fact about the syntax, computed on first evaluation and never recomputed.

Eigenstate — one of the values inside a junction.

Fat struct — the Value design: one struct with a type tag and a field for every kind of payload, several of which may be live at once.

Seam — an accessor that is the only way to reach a piece of data, so the object defining it can be swapped for a stub at link time. What makes a Unicode table cuttable.

Trigger (in --slim) — a construct meaning the program can run code the scan never saw, so every feature is kept. An unmodelled AST node is one.

Emscripten — the toolchain that compiles the runtime to WebAssembly. Its -fexceptions mode routes C++ throws through JavaScript, which is what bounds recursion depth in the browser.

GIL — the global interpreter lock. Only its holder may touch interpreter state; it is engaged lazily on first concurrent use.

Grapheme — what a reader calls a character. Raku's string indices are grapheme indices; storage is UTF-8 bytes.

Handle — an opaque RkValue in the extension ABI. The mechanism by which an extension never sees Value.

Model gap — a construct the longest-token automaton builder could not model, as opposed to one that genuinely ends the declarative prefix. A gap forces a fallback to the probe ranker.

NFG — Raku's normalization-form-grapheme storage model. Strings are normalised to NFC on the way in.

Packrat memo — the cache of a ratcheting grammar rule's match at a position, sound because such a rule does not backtrack.

Publish — the step at the end of module loading that copies the module's environment into the global one.

Ratchet — the property of token and rule that their quantifiers are possessive and their matches commit.

Sigspace — the :s adverb and the rule declarator, under which whitespace in a pattern means "match optional whitespace here". Implemented by wrapping atoms with a <ws> subrule at compile time.

Sink context — a statement whose value is discarded, signalled down so an assignment need not materialise its result.

Slip|@a, a list that splices into the surrounding list or argument list.

Specificity — the score scoreCandidate assigns a multi-dispatch candidate.

Superinstruction — a fused node kind representing a common pattern. The approach node specialisation deliberately did not take.

Transparent (of a regex construct, in ranking) — treated as an epsilon transition by the longest-token automaton, because the commit engine will enforce it for real.

Twigil — the second sigil character: * dynamic, !/. attribute, ^ placeholder, ? compile-time.

Wrapper stack — the &routine.wrap({…}) layers on a Callable, run outermost first, each able to callsame into the next.