Module node

Module node 

Source
Expand description

Node — the canonical AST, and an ordinary value.

docs/02-syntax.md §2.2 fixes the shape:

model Node:
    head: Sym | Lit
    args: list[Node]
    meta: Meta

Everything else is derived. Both surfaces — the Python one and the S-expression one — read to identical Node trees; beck fmt prints either. That is the whole trick: “significant whitespace is only hard if your macros do string concatenation. Ours cannot.”

One representational decision the doc leaves implicit: head is a symbol or a literal, so an application whose callee is itself an expression has nowhere to put the callee. Those use the reserved head sym::CALL(call (. f g) x) — which keeps the common case, and therefore the original sketch’s notation, literal: (update_at todos id ...) is a symbol head with three arguments, exactly as written.

Modules§

sym
The reserved heads. Named constants rather than string literals scattered through the compiler: a typo in "paramss" would otherwise be a silently-unmatched form.

Structs§

Meta
Everything a Node knows about itself beyond its shape.
Node
Scope
A hygiene scope. Fresh scopes are minted by the macro expander; the set a symbol carries is what decides which binding it refers to (crate::Symbol).
ScopeSet
A set of hygiene scopes, kept sorted and deduplicated so that subset tests are a merge.
Symbol
An identifier, with the hygiene scopes it was written (or introduced) in.

Enums§

Head
Lit
A literal. Floats compare by bit pattern so that Lit — and therefore Node — can be Eq: two source files that differ only in 0.0 versus -0.0 are different programs.