{-# 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 = 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 () forall {r}. Operations SeqMem r Sequential
ops Space
Imp.DefaultSpace
  where
    ops :: Operations SeqMem r Sequential
ops = forall rep (inner :: * -> *) op r.
(Mem rep inner, FreeIn op) =>
OpCompiler rep r op -> Operations rep r op
ImpGen.defaultOperations forall {rep} {inner :: * -> *} {rep} {r} {op}.
(FParamInfo rep ~ FParamMem, LParamInfo rep ~ LParamMem,
 RetType rep ~ RetTypeMem, BranchType rep ~ BranchTypeMem,
 OpC rep ~ MemOp inner, HasLetDecMem (LetDec rep), ASTRep rep,
 OpReturns (inner rep), RephraseOp inner) =>
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) =
      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) = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()