Map: core / syntax
core/src/syntax/ turns source text into the surface AST — the only place that
sees raw bytes and bare words.
lexer.rs—lex(source) -> Result<Vec<(Token, Span)>, LexError>; theTokenenum.parser.rs—parse(source) -> Result<Vec<Stmt>, ParseError>;parse_withcarries aFileId. A digit glued to a comparison operator inside$[…]($[2>3], lexed as the file-descriptor redirect2>) earns a diagnostic that names the shape and asks for spaces, not a bare “redirect” token.<<is the here-string redirect; the bash spellings (<<<, a glued heredoc<<EOF) earn targeted diagnostics naming ral’s form.ast.rs— the surface AST.Astis the expression node andStmtthe statement node; the enum is deliberately wide and flat (ast-stays-flat).group.rs— pre-pass detecting mutually recursive binding groups, consumed by the elaborator.quote.rs— bare-word classification (is_bare_word,quote_word,quote_word_if_needed), shared with the REPL.tag.rs,free_refs.rs— variant-label tagging and free-reference scans.
Recursion is bounded by a single shared depth cap, so adversarial nesting
rejects cleanly instead of overflowing the stack. One NESTING_DEPTH_LIMIT
governs both stages.
- The lexer enforces it at
scan_token_group, the sole recursion through bracketed token groups. - The parser’s three mutually-recursive sub-grammars each descend through
exactly one guarded chokepoint, all counting against
Parser::nested’s shareddepth: values throughparse_primary, arithmetic throughparse_expr_atom(the unary prefixes-/notand parenthesised sub-expressions bottom out here), patterns throughparse_pattern(list and map patterns recurse back through it per element).
A command’s pipe modes are the modal projection of its declared type, read
once: a builtin’s boundary PipeSpec is sig_pipe_spec (the streaming reducer
reducer_spec) in typecheck::builtins, and the static
checker walks a prelude function’s body for its modes. With the runtime engine
retired (unconditional-mode-pass),
there is no shell-free fallback and no hand-maintained byte-mode residue: the baked
prelude’s schemes and the IR’s ground wires carry the real inferred modes for every
prelude export.
The five reserved control operators are recognised
at this layer; everything else is a library binding. See docs/SPEC.md §2–§4
for the grammar.