    {-# LANGUAGE TypeFamilies #-}

    -- | Compile Futhark to sequential imperative code.
    module Futhark.CodeGen.ImpGen.Sequential
      ( compileProg,
        ImpGen.Warnings,
      )
    where

    import Futhark.CodeGen.ImpCode.Sequential qualified as Imp
    import Futhark.CodeGen.ImpGen qualified as ImpGen
    import Futhark.IR.SeqMem
    import Futhark.MonadFreshNames

    -- | Compile a 'SeqMem' program to sequential imperative code.
    compileProg :: (MonadFreshNames m) => Prog SeqMem -> m (ImpGen.Warnings, Imp.Program)
    compileProg :: forall (m :: * -> *).
    MonadFreshNames m =>
    Prog SeqMem -> m (Warnings, Program)
    compileProg = ()
    -> Operations SeqMem () Sequential
    -> Space
    -> Prog SeqMem
    -> m (Warnings, Program)
    forall rep (inner :: * -> *) op (m :: * -> *) r.
    (Mem rep inner, FreeIn op, MonadFreshNames m) =>
    r
    -> Operations rep r op
    -> Space
    -> Prog rep
    -> m (Warnings, Definitions op)
    ImpGen.compileProg () Operations SeqMem () Sequential
    forall {r}. Operations SeqMem r Sequential
    ops Space
    Imp.DefaultSpace
      where
        ops :: Operations SeqMem r Sequential
    ops = OpCompiler SeqMem r Sequential -> Operations SeqMem r Sequential
    forall rep (inner :: * -> *) op r.
    (Mem rep inner, FreeIn op) =>
    OpCompiler rep r op -> Operations rep r op
    ImpGen.defaultOperations OpCompiler SeqMem r Sequential
    Pat (LetDec SeqMem)
    -> MemOp NoOp SeqMem -> ImpM SeqMem r Sequential ()
    forall {rep} {inner :: * -> *} {rep} {r} {op}.
    (BranchType rep ~ BranchTypeMem, LParamInfo rep ~ LParamMem,
     FParamInfo rep ~ FParamMem, RetType rep ~ RetTypeMem,
     OpC rep ~ MemOp inner, HasLetDecMem (LetDec rep), ASTRep rep,
     OpReturns inner, RephraseOp inner, Pretty (inner rep),
     Rename (inner rep), Show (inner rep), Ord (inner rep),
     Substitute (inner rep), FreeIn (inner rep)) =>
    Pat (LetDec rep) -> MemOp NoOp rep -> ImpM rep r op ()
    opCompiler
        opCompiler :: Pat (LetDec rep) -> MemOp NoOp rep -> ImpM rep r op ()
    opCompiler Pat (LetDec rep)
    dest (Alloc SubExp
    e Space
    space) =
          Pat (LetDec rep) -> SubExp -> Space -> ImpM rep r op ()
    forall rep (inner :: * -> *) r op.
    Mem rep inner =>
    Pat (LetDec rep) -> SubExp -> Space -> ImpM rep r op ()
    ImpGen.compileAlloc Pat (LetDec rep)
    dest SubExp
    e Space
    space
        opCompiler Pat (LetDec rep)
    _ (Inner NoOp rep
    NoOp) = () -> ImpM rep r op ()
    forall a. a -> ImpM rep r op a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()