"""Built-in macro library for dfasm. These macros are automatically available in all dfasm programs. The BUILTIN_MACROS string is prepended to user source before parsing. Macro parameters can appear in edge endpoints via ${param} syntax, in opcode position via ${op}, and in qualifier positions via |${pe} and :${port}. The expand pass resolves all ParamRef placeholders. Macros use @ret/@ret_name markers for output wiring via the |> syntax at call sites. """ BUILTIN_MACROS = """\ ; === Built-in Macro Library === ; These macros are automatically available in all dfasm programs. ; --- Counted loop --- ; Topology: counter -> compare -> body_fan (fanout) -> inc -> feedback ; compare L -> body_fan (pass as fanout) -> @ret_body + &inc ; compare R -> @ret_exit ; Call with: #loop_counted &init, &limit |> body=&process, exit=&done #loop_counted init, limit |> { &counter <| add &compare <| brgt &counter |> &compare:L &body_fan <| pass &compare |> &body_fan:L &inc <| inc &body_fan |> &inc:L &inc |> &counter:R ${init} |> &counter:L ${limit} |> &compare:R &body_fan |> @ret_body &compare |> @ret_exit:R } ; --- Condition-tested loop --- ; Topology: &gate (gate) -> L=body, R=exit ; Call with: #loop_while &test_src |> body=&process, exit=&done #loop_while test |> { &gate <| gate ${test} |> &gate:L &gate |> @ret_body &gate |> @ret_exit:R } ; --- Permit injection (variadic) --- ; Injects one const(1) seed token per target. ; Call with: #permit_inject &gate_a, &gate_b, &gate_c |> @a, @b, @c #permit_inject *targets |> { $( &p <| const, 1 ${targets} |> &p &p |> @ret ),* } ; --- Binary reduction trees (parameterized opcode) --- ; Call with: #reduce_2 add |> &result_node #reduce_2 op |> { &r <| ${op} &r |> @ret } ; Call with: #reduce_3 sub |> &result_node #reduce_3 op |> { &r0 <| ${op} &r1 <| ${op} &r0 |> &r1:L &r1 |> @ret } ; Call with: #reduce_4 add |> &result_node #reduce_4 op |> { &r0 <| ${op} &r1 <| ${op} &r2 <| ${op} &r0 |> &r2:L &r1 |> &r2:R &r2 |> @ret } """ # Count newlines in BUILTIN_MACROS for line number offset calculation _BUILTIN_LINE_COUNT: int = BUILTIN_MACROS.count("\n") __all__ = [ "BUILTIN_MACROS", ]