{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Main where import Control.Monad import Data.Char import Data.Either import Data.Maybe import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.IO as T import System.Directory import System.Environment import System.Exit import Text.Printf import Lex import Parse import Print import Types main :: IO () main = mapM_ writeToDisk =<< getDirectoryFiles getDirectoryFiles :: IO [String] getDirectoryFiles = do filter (`notElem` exclude) <$> listDirectory "include" where exclude = [ "defines.h" , "complex.h" , "extra.h" ] writeToDisk :: String -> IO () writeToDisk fileName = do bindings <- map run . drop 1 . filter (not . T.null) . T.lines <$> T.readFile ("include/" <> fileName) case partitionEithers bindings of (failures, successes) -> do if length failures > 0 then do mapM_ print (listToMaybe failures) printf "%s failed to generate bindings\n" fileName else do let name = makeName (reverse . drop 2 . reverse $ fileName) T.writeFile (makePath name) $ file name <> T.intercalate "\n" (genBinding <$> successes) printf "Wrote bindings to %s\n" (makePath name) -- | Filename remappings makeName :: String -> String makeName n | n == "lapack" = "LAPACK" | n == "blas" = "BLAS" | n == "cuda" = "CUDA" | otherwise = n makePath :: String -> String makePath s = printf "src/ArrayFire/Internal/%s.hsc" (capitalName (makeName s)) file :: String -> Text file a = T.pack $ printf "{-# LANGUAGE CPP #-}\n\ \module ArrayFire.Internal.%s where\n\n\ \import ArrayFire.Internal.Defines\n\ \import ArrayFire.Internal.Types\n\ \import Foreign.Ptr\n\ \import Foreign.C.Types\n\n\ \#include \"af/%s.h\"\n\ \" (capitalName a) (if lowerCase a == "exception" then "defines" else lowerCase a) capitalName, lowerCase :: [Char] -> [Char] capitalName (x:xs) = toUpper x : xs lowerCase (x:xs) = map toLower (x:xs)