rewire-frontend-2.8: A Haskell-to-Verilog/VHDL compiler, front end (GHC driver, Eidos, Synolon)
Safe HaskellSafe
LanguageHaskell2010

ReWire.Eidos.ToSynolon

Description

purify (doc/synolon.md §8): convert the reactive fragment of a monomorphic ANF program into one process. The traversal is CPS-shaped — compile e k compiles a reactive computation under a continuation — which right-associates binds by construction:

  • rwPrimSignal o >>= k becomes pause o -> L_k (the continuation block's last parameter is the resumed input);
  • rwPrimReturn v becomes goto L_k (v) (or halt v at the root);
  • lifted rwPrimGet/rwPrimPut become cell commands, the cell resolved from the operation's own residual state stack;
  • rwPrimExtrude m s is a cell write (put) followed by m — cells written in entry before the first pause become register initials (doc/synolon.md §3.4), so no separate initials extraction exists;
  • a reactive case becomes a terminator case (arms with commands get their own blocks — continuations are shared blocks, so the retired lift-once rule is the default by construction);
  • join points become blocks; jumps become gotos;
  • a reactive call is compiled once per continuation — block-graph splicing memoized on (definition, continuation), the retired unfoldHead's successor; recursion closes through the memo table (a tail self-call recurs under the same continuation, so it hits the memo and becomes a goto). Two shapes are rejected with located errors: a NOINLINE reactive callee on the left-hand side of a bind (the user's opt-out from per-continuation splicing), and recursion THROUGH a bind's left-hand side (re-entering a definition whose splice is still open mints a fresh continuation per iteration — each pending continuation is a resumption-stack frame, and the machine has no stack).

Blocks are closure-converted afterward: a fixpoint over the block graph computes each block's live-in locals, which become leading parameters, with every pause/goto site supplying them (this is the machine record's args field).

This stage constructs the process — the Eidos-to-Synolon boundary; the block graph is then cleaned by ReWire.Synolon.Transform, checked by the machine lint (ReWire.Synolon.Lint), and lowered by the Synolon-to-Hyle fold (ReWire.Synolon.ToHyle).

Synopsis

Documentation

purify :: MonadError AstError m => Program -> m Program Source #

The Synolon program of an Eidos program: the process compiled from the reactive root, over the definitions the machine calls (machineDefn, in their order — Hyle names are assigned by position; the consumed reactive definitions and the builtin signature carriers do not ride along) and the datatypes those mention (usedDatas). The root must be a nullary ReacT computation (the mono lint's device rule).