    -- | C code generator.  This module can convert a correct ImpCode
    -- program to an equivalent C program. The C code is strictly
    -- sequential, but can handle the full Futhark language.
    module Futhark.CodeGen.Backends.SequentialC
      ( compileProg,
        GC.CParts (..),
        GC.asLibrary,
        GC.asExecutable,
        GC.asServer,
      )
    where

    import Control.Monad
    import Data.Text qualified as T
    import Futhark.CodeGen.Backends.GenericC qualified as GC
    import Futhark.CodeGen.Backends.SequentialC.Boilerplate
    import Futhark.CodeGen.ImpCode.Sequential qualified as Imp
    import Futhark.CodeGen.ImpGen.Sequential qualified as ImpGen
    import Futhark.IR.SeqMem
    import Futhark.MonadFreshNames

    -- | Compile the program to sequential C.
    compileProg :: (MonadFreshNames m) => T.Text -> Prog SeqMem -> m (ImpGen.Warnings, GC.CParts)
    compileProg :: forall (m :: * -> *).
    MonadFreshNames m =>
    Text -> Prog SeqMem -> m (Warnings, CParts)
    compileProg Text
    version =
      (Definitions Sequential -> m CParts)
    -> (Warnings, Definitions Sequential) -> m (Warnings, CParts)
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> (Warnings, a) -> f (Warnings, b)
    traverse
        ( Text
    -> Text
    -> ParamMap
    -> Operations Sequential ()
    -> CompilerM Sequential () ()
    -> Text
    -> (Space, [Space])
    -> [Option]
    -> Definitions Sequential
    -> m CParts
    forall (m :: * -> *) op.
    MonadFreshNames m =>
    Text
    -> Text
    -> ParamMap
    -> Operations op ()
    -> CompilerM op () ()
    -> Text
    -> (Space, [Space])
    -> [Option]
    -> Definitions op
    -> m CParts
    GC.compileProg
            Text
    "c"
            Text
    version
            ParamMap
    forall a. Monoid a => a
    mempty
            Operations Sequential ()
    operations
            CompilerM Sequential () ()
    forall op s. CompilerM op s ()
    generateBoilerplate
            Text
    forall a. Monoid a => a
    mempty
            (Space
    DefaultSpace, [Space
    DefaultSpace])
            []
        )
        ((Warnings, Definitions Sequential) -> m (Warnings, CParts))
    -> (Prog SeqMem -> m (Warnings, Definitions Sequential))
    -> Prog SeqMem
    -> m (Warnings, CParts)
    forall (m :: * -> *) b c a.
    Monad m =>
    (b -> m c) -> (a -> m b) -> a -> m c
    <=< Prog SeqMem -> m (Warnings, Definitions Sequential)
    forall (m :: * -> *).
    MonadFreshNames m =>
    Prog SeqMem -> m (Warnings, Definitions Sequential)
    ImpGen.compileProg
      where
        operations :: GC.Operations Imp.Sequential ()
        operations :: Operations Sequential ()
    operations =
          Operations Sequential ()
    forall op s. Operations op s
    GC.defaultOperations
            { GC.opsCompiler = const $ pure ()
            }