Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
Download tar.gz
- Add test_inner_ret_failure_does_not_cascade_to_outer to verify inner
macro @ret errors don't produce spurious outer macro errors
- Fix inconsistent error collection in _expand_body_recursive (edge
errors now go to body_errors like node errors, not directly to
enclosing errors list)
- C1: Invalid port parameter values now produce MACRO errors instead of
silently falling back to Port.L. _clone_and_substitute_edge returns
errors like _clone_and_substitute_node already does.
- I1: Leaked @ret edges from failed inner macro expansions are now
filtered out to prevent spurious cascading errors at outer scope.
- I2/M3: Added tests for invalid port values and bare @ret with only
named outputs.
- M1: Fixed test-requirements.md file references to match actual names.
- M2: lower.py edge qualification now uses replace() to preserve all
fields (port_explicit, ctx_override) instead of constructing new IREdge.
- #reduce_add_N replaced with #reduce_N op (parameterized opcode via ${op})
- #loop_counted gains @ret_body/@ret_exit markers with pass fanout node
to avoid 3-edge constraint on brgt compare node
- #loop_while gains @ret_body/@ret_exit markers
- Tests updated for new macro names and invocation syntax
Enhancement 2: Parameterized placement, port, and context slot qualifiers
- Grammar: placement, port, ctx_slot accept param_ref
- IR: PlacementRef, PortRef, CtxSlotRef, CtxSlotRange wrapper types
- Lower: qualified_ref extracts typed qualifier refs; _normalize_port passes PortRef through
- Lower: _process_statements uses replace() instead of manual IRNode reconstruction
- Expand: resolves PlacementRef/PortRef/CtxSlotRef during substitution
Enhancement 3: @ret wiring for macros
- Grammar: macro_call_stmt accepts optional |> call_output_list
- IR: IRMacroCall gains output_dests field
- Lower: macro_call_stmt handler extracts output destinations
- Expand: rewrites @ret/@ret_name edges to concrete destinations after body expansion
- Expand: reports MACRO error for unmatched @ret or missing output wiring
Grammar: opcode rule now accepts param_ref alternative, positional_arg
accepts OPCODE token. Lower pass defers ParamRef opcodes and wraps bare
OPCODE tokens in macro call arguments as strings. Expand pass resolves
opcode mnemonic strings to ALUOp/MemOp via MNEMONIC_TO_OP during
macro body cloning.
Enables: #reduce_2 op |> { &r <| ${op} } / #reduce_2 add
Implement the dfasm macro system as designed in docs/design-plans/2026-02-28-dfasm-macros.md.
Grammar changes:
- Add macro definition (#name params |> { body }) and invocation syntax
- Add function call syntax ($func args |> outputs) with named outputs
- Require trailing colon on location directives (disambiguation)
- Add scoped references (#macro.&label, $func.&label)
- Add ${param} parameter reference syntax for const and edge positions
- Add variadic parameters (*args) and repetition blocks ($(body),*)
Pipeline:
- Lower: CST-to-IR for all new grammar rules, MacroDef/IRMacroCall/ParamRef
creation, token pasting pattern detection
- Expand: new pass between lower and resolve. Macro expansion with parameter
substitution, const expression evaluation, token pasting, variadic
repetition. Function call wiring with @ret return markers and per-call-site
context slots.
- Allocate: per-call-site context slot assignment via CallSite metadata
- Codegen: CTX_OVRD (ctx_mode=01) emission on cross-call-site edges
Built-in macro library: zero-param self-contained macros (dup, discard,
reduce_add) prepended to user source automatically.
Error handling: MACRO and CALL error categories with expansion stack
threading for precise error locations in nested macros.
Tests: 1034 passing (40 new macro/call tests + existing regression suite).
Macro system with IR-level expansion, static function call syntax
with @ret markers and auto-inserted free_ctx, trailing-colon
location directives, dot-notation scope resolution, and built-in
macro library. 8 implementation phases.