@@[target("rust")]

// RFC-0035 Round 8 — the framec compile pipeline AS a Frame state machine
// that DRIVES the orchestrator (it no longer merely observes it).
//
// Each compile phase is a STATE. The state's `$>` enter handler runs that
// phase (a `do_*` function over the shared `PipelineCtx`) and then transitions
// to the next phase — or, on an early exit (validation error, GraphViz DOT
// output, segmentation failure), stashes the finished `CompileResult` in
// `early` and jumps straight to `$Done`. The machine self-drives: `run()`
// kicks it from `$Idle`, and the enter-handler chain runs synchronously to a
// terminal state. The transition graph IS the pipeline control flow — delete
// `$ValidateCodegen`'s `-> $Assemble` and codegen genuinely stops feeding
// assembly. `framec compile -l graphviz` on this file renders the real
// pipeline, not a hand-maintained cartoon of it.
//
// The phase bodies stay native (in `pipeline/compiler.rs::do_*`) — Frame owns
// the *control structure*, the native fns are opaque pass-through, exactly as
// the dogfooding thesis intends. `PipelineCtx` (owned: source, config, and
// every intermediate) is the single domain field threaded through the phases;
// `early` carries the result out. The caller (`compile_ast_based`) builds the
// system, assigns the real `ctx`, calls `run()`, and returns `early`.

@@system PipelineFsm {
    interface:
        run()

    machine:
        $Idle {
            run() {
                -> $Segment
            }
        }

        $Segment {
            $>() {
                if let Some(r) = do_segment(&mut self.ctx) {
                    self.early = Some(r);
                    -> $Done
                }
                -> $Parse
            }
        }

        $Parse {
            $>() {
                if let Some(r) = do_parse(&mut self.ctx) {
                    self.early = Some(r);
                    -> $Done
                }
                -> $ModuleGates
            }
        }

        $ModuleGates {
            $>() {
                if let Some(r) = do_module_gates(&mut self.ctx) {
                    self.early = Some(r);
                    -> $Done
                }
                -> $Graphviz
            }
        }

        $Graphviz {
            $>() {
                if let Some(r) = do_graphviz(&mut self.ctx) {
                    self.early = Some(r);
                    -> $Done
                }
                -> $ValidateCodegen
            }
        }

        $ValidateCodegen {
            $>() {
                if let Some(r) = do_validate_codegen(&mut self.ctx) {
                    self.early = Some(r);
                    -> $Done
                }
                -> $Assemble
            }
        }

        $Assemble {
            $>() {
                self.early = Some(do_assemble(&mut self.ctx));
                -> $Done
            }
        }

        $Done { }

    domain:
        ctx: PipelineCtx = PipelineCtx::empty()
        early: Option<CompileResult> = None
}
