Expand description
The binder grammar: which forms open a scope, which names they bind, and
which symbols are references. One walker, and every pass that needs
scopes drives it — the check stage’s name table
(blue_lang_check::names) and the capability frame’s reach walk
(blue_lang_waku::check_reach_program). Two hand-written walkers used to
answer this question, and they disagreed: waku bound a define only at the
level of a begin, so a name assigned inside an if branch and read after
it was reported as an escape, and it knew no let*, letrec or catch.
The walker knows the SHAPES of tatara-lisp’s binding forms, as blue lowers
them: lambda and a function define introduce parameters; let, let*
and letrec their bindings (a named let its name); try’s catch clause
its variable; a define inside a body binds in that body’s frame,
including through if, cond and begin, which open no frame of their
own. quote is data; inside a quasiquote only the unquoted parts are
code, and the rest is handed to Scopes::template_symbol.
What a pass DOES with a binding or a reference is the Scopes
implementation’s business — the checker tracks reads for its unused
warning, the reach walk tests each free name against a frame — and which
head is a special form or a macro is the implementation’s oracle
(Scopes::head_kind), since only the pass knows which interpreter it
answers to.
Structs§
- Import
- One
useform, as the file that wrote it declared it. - Legacy
- A bidama’s rename ledger, declared at its top level. Two forms:
- Moved
- One moved definition:
oldin the declaring bidama ishome::newnow.homeis empty when the target was not writtenhome::new.
Enums§
- Binder
Kind - What introduced a local binding.
- Head
Kind - Which of the evaluator’s three arbiters claims a name in head position.
- Legacy
Kind - What a
legacy_namesdeclaration records.
Constants§
- LEGACY_
NAMES - The head of the rename-ledger declaration:
legacy_names("0.1.1", "lc"). - SHAPED_
FORMS - The special forms whose SHAPE the walker knows — the heads a pass without
an interpreter to ask (the reach walk) answers
HeadKind::SpecialFormfor, so their binders bind. Every other special form is walked as an ordinary application, which is what it is for scoping purposes.
Traits§
- Scopes
- A pass over the binder grammar. The walker calls these in source order.
Functions§
- defined_
name_ node - The name node a
define/define-typedform binds. - definition_
nodes definitions_of, handing over the NAME NODE of each definition, so a pass that rewrites definitions can find the symbol it renames.- definitions_
of - The names
formdefines into the frame it is evaluated in, with the span of each name and whether it is a value or a macro. - legacy_
target - Is this form a
legacy_namesdeclaration? A version string, then a prefix string, a list of[old, "home::new"]string pairs (or[old, "home::new", "args"]retirements), or a list of flat-era:namekeywords, or it is not one (andlegacy_namesis then an unbound call). - nullary_
definition - params_
of - A lambda parameter list: symbols, skipping
&rest/&optional/.markers; a bare symbol is a variadic parameter. - use_
target - Is this form a
usedeclaration? If so, what it declares. - walk_
program - Walk a whole program. Top-level definitions are the pass’s to know (they
are globals, see
definitions_of); the walker opens frames only below them. - walk_
top - Walk one top-level form.