Skip to main content

The pipeline

There is no intermediate bytecode or compiled form — the interpreter walks the AST directly. This is a deliberate Phase 1 simplification (see Roadmap): fast to change while the language’s semantics are still moving, not a permanent architectural commitment.

Statement and expression dispatch

Both the statement executor and the expression evaluator use the same pattern — reflection over the node’s class name, rather than a big if/elif chain or a separate visitor class per concern:
Adding a new statement or expression kind means adding one AST dataclass and one correspondingly-named method — no central switch statement to keep in sync.

Control flow inside the interpreter

return, break, and continue are implemented as internal Python exceptions (_Return, _Break, _Continue) that unwind the Python call stack until something is prepared to catch them — a function call catches _Return, a loop catches _Break/_Continue. This is a standard tree-walking-interpreter technique: it reuses Python’s own stack-unwinding machinery instead of threading explicit “did we hit a return” signals through every level of statement execution by hand.

Environments carry more than variables

Every statement/expression method takes an env: Environment parameter — the current lexical scope. As of the agent pause/resume work, Environment also carries the current scope’s delegation and policy overrides (see Scoping & Delegation) and, for an agent’s own scope, a reference back to that agent (so pause() can find “which agent am I currently inside,” the same way a variable lookup finds “which binding am I currently inside”).

Modules and the global environment

Interpreter.globals is a single Environment holding every builtin. Running a file (or importing a module) creates a child of globals for that file/module’s own top-level bindings — so builtins are visible everywhere, but two different files’ top-level variables never collide. Imported modules are cached by absolute path and executed exactly once, with in-progress imports tracked separately to detect cycles (see Modules).

Continue

Indentation-sensitive lexing

How the lexer turns leading whitespace into INDENT/DEDENT tokens.

Scoping & delegation

Why set delegation and policy live on Environment, not the interpreter.