pec-0.2.2: Pec/PUtil.hs
{-# OPTIONS -Wall #-}
{-# LANGUAGE DeriveDataTypeable #-}
-- The pec embedded compiler
-- Copyright 2011-2012, Brett Letner
module Pec.PUtil where
import Control.Monad
import Data.Data
import Data.Generics.Uniplate.Data
import Data.List
import Development.Shake.FilePath
import Distribution.Text
import Grm.Layout
import Grm.Lex
import Grm.Prims
import Language.Pec.Par
import Paths_pec
import System.Console.CmdArgs
import qualified Language.Pds.Abs as D
import qualified Language.Pec.Abs as P
copyright :: String
copyright = "(C) Brett Letner 2011-2012"
vers :: String
vers = display version
getLibDir :: IO FilePath
getLibDir = liftM takeDirectory $ getDataFileName "lib/Prelude.pec"
parse_pec :: FilePath -> IO (P.Module Point)
parse_pec fn = do
ts <- P.grmLexFilePath fn
m@(P.Module _ a _ _ _) <-
return $ grmParse $ layout $ filter notWSToken ts
if ((splitDirectories $ dropExtension $ normalise fn) `has_suffix`
(unqual $ ppShow a))
then return m
else error $ "module name mismatch:" ++ fn ++ ":" ++ ppShow a
has_suffix :: Eq a => [a] -> [a] -> Bool
has_suffix a b = drop (length a - length b) a == b
imports :: D.Module -> [String]
imports (D.Module _ _ xs _ _ _) = [ a | D.ImportD a _ <- xs ]
modid :: D.Module -> String
modid (D.Module n _ _ _ _ _) = n
counts :: P.Module Point -> [Integer]
counts (P.Module _ _ _ _ xs) = nub $
[ genericLength (a :: [P.ConC Point])
| P.TyTagged _ a <- universeBi xs ] ++
[ genericLength (a :: [P.Exp Point]) | P.ArrayE _ a <- universeBi xs ] ++
[ pcount a | P.TyCount _ a <- universeBi xs ] ++
[ pcount a | P.CountE _ a <- universeBi xs ]
pcount :: P.Count Point -> Integer
pcount (P.Count _ i) = read i
qual_to_und :: String -> String
qual_to_und = map f
where f c = if c == '.' then '_' else c
und_to_path :: String -> String
und_to_path = joinPath . splitBy ((==) '_')
unqual :: String -> [String]
unqual = splitBy ((==) '.')
qual :: [String] -> String
qual = concat . intersperse "."
splitBy :: (a -> Bool) -> [a] -> [[a]]
splitBy p = loop [] []
where
loop [] ys [] = filter (not . null) $ reverse ys
loop xs ys [] = loop [] (reverse xs : ys) []
loop xs ys (c:cs)
| p c = loop [] (reverse xs : ys) cs
| otherwise = loop (c:xs) ys cs
summarize :: String -> String
summarize prog = prog ++ " v" ++ vers ++ ", " ++ copyright
readFileDeps :: FilePath -> IO ([String],[Integer])
readFileDeps = liftM read . readFile
writeFileDeps :: FilePath -> ([String],[Integer]) -> IO ()
writeFileDeps fn = writeFileBinary fn . show
data Arch = C | LLVM deriving (Show, Data, Typeable)
instance Default Arch where
def = C