clr-inline-0.1.0.0: src/Clr/FSharp/Gen.hs
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeInType #-}
module Clr.FSharp.Gen (name, compile) where
import Clr.Inline.Config
import Clr.Inline.Quoter
import Clr.Inline.Utils
import Clr.Inline.Utils.Embed
import Clr.Inline.Types
import Control.Monad
import Control.Monad.Trans.Writer
import qualified Data.ByteString as BS
import qualified Data.Map as Map
import Data.Proxy
import Language.Haskell.TH.Syntax
import System.Directory
import System.FilePath ((<.>), (</>))
import System.IO.Temp
import System.Process
import Text.Printf
name :: Proxy "fsharp"
name = Proxy
genCode :: ClrInlinedGroup "fsharp" -> String
genCode ClrInlinedGroup {units, mod} =
unlines $
execWriter $ do
yield $ printf "namespace %s" (getNamespace mod)
forM_ units $ \case
ClrInlinedDec _ body -> yield body
ClrInlinedExp {} -> return ()
yield $ printf "type %s =" (getClassName mod)
forM_ units $ \case
ClrInlinedDec {} -> return ()
ClrInlinedExp exp@ClrInlinedExpDetails {..} -> do
let argsString =
case Map.toList args of
[] -> "()"
other -> unwords [printf "(%s:%s)" a t | (a, ClrType t) <- other]
yield $ printf " static member %s %s =" (getMethodName exp) argsString
yield $ printf "#line %d \"%s\"" (fst $ loc_start loc) (loc_filename loc)
forM_ (lines body) $ \l ->
yield $ printf " %s" l
compile :: ClrInlineConfig -> ClrInlinedGroup "fsharp" -> IO ClrBytecode
compile ClrInlineConfig {..} m@ClrInlinedGroup {..} = do
temp <- getTemporaryDirectory
let ass = getAssemblyName name mod
dir <- createTempDirectory temp "inline-fsharp"
let src = dir </> ass <.> ".fs"
tgt = dir </> ass <.> ".dll"
writeFile src (genCode m)
callCommand $
unwords $
execWriter $ do
yield configFSharpPath
yield "--nologo"
yield "--target:library"
yield $ "--out:" ++ tgt
when configDebugSymbols $ yield "--debug:embedded"
forM_ configExtraIncludeDirs $ \dir -> yield $ "--lib:" ++ dir
forM_ configDependencies $ \name -> yield $ "--reference:" ++ name
yieldAll configCustomCompilerFlags
yield src
bcode <- BS.readFile tgt
return $ ClrBytecode bcode