OR-1 dataflow CPU sketch

Macro Enhancements — Test Requirements#

Maps each enhancement from docs/macro-enhancements.md to specific automated test cases.

Slug: macro-enh


Enhancement 1: Opcode Parameters#

macro-enh.E1.1: Grammar accepts param_ref in opcode position#

  • E1.1a Success: &r <| ${op} parses without error inside a macro body
  • E1.1b Success: ${op} &src |> &dst (strong_edge with param opcode) parses
  • E1.1c Success: &dst ${op} <| &src (weak_edge with param opcode) parses
  • Test type: Unit (parse + lower)
  • File: tests/test_opcode_params.py

macro-enh.E1.2: Lower pass stores ParamRef in IRNode.opcode#

  • E1.2a Success: After lowering a macro body with ${op}, the IRNode has opcode as ParamRef(param="op")
  • E1.2b Success: Anonymous nodes from strong/weak edges with ${op} also have ParamRef opcode
  • Test type: Unit (lower)
  • File: tests/test_opcode_params.py

macro-enh.E1.3: OPCODE accepted as positional macro argument#

  • E1.3a Success: #reduce_2 add parses — bare add in macro call argument position is accepted
  • E1.3b Success: Lower pass wraps the OPCODE token as a string "add" in IRMacroCall.positional_args
  • Test type: Unit (parse + lower)
  • File: tests/test_opcode_params.py

macro-enh.E1.4: Expand pass resolves opcode ParamRef#

  • E1.4a Success: Macro #wrap op |> { &n <| ${op} } invoked as #wrap add produces node with opcode=ArithOp.ADD
  • E1.4b Success: Macro invoked with sub, gate, read (different op types) all resolve correctly
  • E1.4c Failure: Macro invoked with #wrap banana produces MACRO error — invalid opcode mnemonic
  • E1.4d Failure: Macro invoked with #wrap 42 (numeric, not opcode) produces MACRO error
  • Test type: Unit (expand)
  • File: tests/test_opcode_params.py

macro-enh.E1.5: Full pipeline with opcode params#

  • E1.5a Success: #reduce_2 op |> { &r <| ${op} } + #reduce_2 add assembles through full pipeline (parse → lower → expand → resolve → place → allocate → codegen)
  • E1.5b Success: Output PEConfig has correct ALUInst with ArithOp.ADD
  • Test type: Integration (full pipeline via assemble())
  • File: tests/test_opcode_params.py

Enhancement 2: Parameterized Placement and Port Qualifiers#

macro-enh.E2.1: Grammar accepts param_ref in placement position#

  • E2.1a Success: &n <| add |${pe} parses inside macro body
  • E2.1b Success: Lower pass returns ParamRef (wrapped as PlacementRef) from placement handler
  • Test type: Unit (parse + lower)
  • File: tests/test_qualified_ref_params.py

macro-enh.E2.2: Grammar accepts param_ref in port position#

  • E2.2a Success: &src |> &dst:${port} parses inside macro body
  • E2.2b Success: Lower pass returns ParamRef (wrapped as PortRef) from port handler
  • Test type: Unit (parse + lower)
  • File: tests/test_qualified_ref_params.py

macro-enh.E2.3: Context slot bracket syntax parses#

  • E2.3a Success: &node[2] parses (literal context slot)
  • E2.3b Success: &node|pe0[2]:L parses (full qualifier chain)
  • E2.3c Success: &node[${ctx}] parses (parameterized context slot)
  • E2.3d Success: &node[0..4] parses (range reservation)
  • Test type: Unit (parse + lower)
  • File: tests/test_qualified_ref_params.py

macro-enh.E2.4: Expand pass resolves placement ParamRef#

  • E2.4a Success: Macro with |${pe} invoked with pe0 places node on PE 0
  • E2.4b Success: Macro with |${pe} invoked with pe1 places node on PE 1
  • E2.4c Failure: Macro invoked with |${pe} where arg is "banana" produces MACRO error
  • Test type: Unit (expand)
  • File: tests/test_qualified_ref_params.py

macro-enh.E2.5: Expand pass resolves port ParamRef#

  • E2.5a Success: Macro with :${port} invoked with L resolves to Port.L
  • E2.5b Success: Macro with :${port} invoked with R resolves to Port.R
  • E2.5c Failure: Macro invoked with invalid port value produces MACRO error
  • Test type: Unit (expand)
  • File: tests/test_qualified_ref_params.py

macro-enh.E2.6: Expand pass resolves context slot ParamRef#

  • E2.6a Success: Macro with [${ctx}] invoked with 2 resolves to ctx slot 2
  • E2.6b Failure: Non-numeric ctx slot value produces MACRO error
  • Test type: Unit (expand)
  • File: tests/test_qualified_ref_params.py

macro-enh.E2.7: Full pipeline with placement/port params#

  • E2.7a Success: Macro parameterizing PE placement assembles through full pipeline; node placed on correct PE
  • E2.7b Success: Macro parameterizing port assembles through full pipeline; edge targets correct port
  • Test type: Integration (full pipeline)
  • File: tests/test_qualified_ref_params.py

Enhancement 3: @ret Wiring for Macros#

macro-enh.E3.1: Grammar accepts output list on macro_call_stmt#

  • E3.1a Success: #macro args |> &dest parses
  • E3.1b Success: #macro args |> name=&dest parses (named output)
  • E3.1c Success: #macro args |> &a, &b parses (multiple outputs)
  • E3.1d Success: #macro args |> name1=&a, name2=&b parses (multiple named outputs)
  • Test type: Unit (parse + lower)
  • File: tests/test_macro_ret_wiring.py

macro-enh.E3.2: Lower pass stores output_dests on IRMacroCall#

  • E3.2a Success: IRMacroCall.output_dests contains positional output refs
  • E3.2b Success: IRMacroCall.output_dests contains named output refs (name, ref) tuples
  • Test type: Unit (lower)
  • File: tests/test_macro_ret_wiring.py

macro-enh.E3.3: Expand pass rewrites @ret edges#

  • E3.3a Success: Macro body edge &src |> @ret becomes &src |> &actual_dest after expansion
  • E3.3b Success: Named @ret_body maps to body=&dest in call site output
  • E3.3c Success: Multiple @ret variants (e.g., @ret_body + @ret_exit) each map to their named outputs
  • E3.3d Failure: @ret_body in macro body but call site has no body= output → MACRO error
  • E3.3e Failure: Macro body has @ret but call site provides zero outputs → MACRO error
  • E3.3f Success: Positional @ret maps to first positional output
  • Test type: Unit (expand)
  • File: tests/test_macro_ret_wiring.py

macro-enh.E3.4: @ret port preservation#

  • E3.4a Success: &src |> @ret:R rewrites to &src |> &dest:R — port on @ret is preserved
  • E3.4b Success: &src |> @ret_exit:R also preserves port
  • Test type: Unit (expand)
  • File: tests/test_macro_ret_wiring.py

macro-enh.E3.5: Nested macro @ret scoping#

  • E3.5a Success: Macro A calls macro B which has @ret; B's @ret resolves at B's call site (inside A's body), A's @ret resolves at A's call site
  • Test type: Unit (expand)
  • File: tests/test_macro_ret_wiring.py

macro-enh.E3.6: Full pipeline with @ret macros#

  • E3.6a Success: Macro with @ret + call site output list assembles through full pipeline
  • E3.6b Success: Generated edges connect expanded macro internals to call-site-specified destinations
  • Test type: Integration (full pipeline)
  • File: tests/test_macro_ret_wiring.py

Enhancement 4: Built-in Macro Rewrite#

macro-enh.E4.1: New builtins use opcode params#

  • E4.1a Success: #reduce_2 add expands correctly (single node with ArithOp.ADD)
  • E4.1b Success: #reduce_3 sub expands correctly (two nodes with ArithOp.SUB, wired)
  • E4.1c Success: #reduce_4 add expands correctly (three nodes, tree structure)
  • Test type: Unit (expand)
  • File: tests/test_builtins.py

macro-enh.E4.2: New builtins use @ret wiring#

  • E4.2a Success: #loop_counted |> body=&proc, exit=&done wires @ret_body → &proc, @ret_exit → &done
  • E4.2b Success: #loop_while |> body=&proc, exit=&done wires similarly
  • Test type: Unit (expand)
  • File: tests/test_builtins.py

macro-enh.E4.3: Backwards compatibility#

  • E4.3a: Old macro names that are removed are documented in CHANGELOG or similar
  • Test type: Manual verification (pre-1.0, acceptable breakage)

macro-enh.E4.4: Full pipeline with new builtins#

  • E4.4a Success: Program using #loop_counted |> body=&body, exit=&done + #reduce_2 add assembles through full pipeline
  • Test type: Integration (full pipeline)
  • File: tests/test_builtins.py

Human Verification#

macro-enh.HV1: dfgraph renders programs using new macros#

  • Verify that dfgraph correctly visualises programs using opcode params, @ret wiring
  • Justification: Graph rendering depends on pipeline output; visual verification needed

macro-enh.HV2: Error messages are useful#

  • Verify that error messages for invalid opcode params, mismatched @ret, etc. include actionable context (macro name, line, suggestions)
  • Justification: Error message quality is subjective; automated tests check presence but not clarity