Skip to main content

Module scope

Module scope 

Source
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 use form, 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: old in the declaring bidama is home::new now. home is empty when the target was not written home::new.

Enums§

BinderKind
What introduced a local binding.
HeadKind
Which of the evaluator’s three arbiters claims a name in head position.
LegacyKind
What a legacy_names declaration 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::SpecialForm for, 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-typed form 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 form defines 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_names declaration? A version string, then a prefix string or a list of [old, "home::new"] string pairs, or it is not one (and legacy_names is 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 use declaration? 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.