{-# LANGUAGE LambdaCase #-}
module Print.Util where
import Types.SourceAbstractSyntax (SeqSortOp(..))
import Types.CoreAbstractSyntax
import Data.List (intersperse, intercalate)
import Data.List.Split
import Data.Char (toUpper)
import Data.Text (Text, unpack)
import Text.PrettyPrint.HughesPJ
import Funcons.EDSL (Funcons(..))
import System.FilePath (splitDirectories, dropFileName, dropExtension, takeBaseName)
text' :: Text -> Doc
text' = text . unpack
gList :: [Doc] -> Doc
gList = brackets . hcat . punctuate comma
gTuple :: [Doc] -> Doc
gTuple = parens . hcat . punctuate comma
gAngle :: [Doc] -> Doc
gAngle = angles . hcat . punctuate comma
where angles d = text "<" <> d <> text ">"
gString :: String -> Doc
gString = doubleQuotes . text
ppSortOp :: SeqSortOp -> Doc
ppSortOp PlusOp = text "+"
ppSortOp StarOp = text "*"
ppSortOp QuestionMarkOp = text "?"
gMaybe :: Maybe Doc -> Doc
gMaybe Nothing = text cNothing
gMaybe (Just d) = text cJust <+> parens d
cNothing = "Nothing"
cJust = "Just"
camelcase :: String -> String
camelcase str = concatMap firstToCap (splitOneOf " -" str)
where firstToCap [] = []
firstToCap (hd:tl) = (toUpper hd):tl
dropUntil :: (a -> Bool) -> [a] -> [a]
dropUntil prop xs =
case dropWhile prop xs of
[] -> xs
xs' -> dropUntil prop (tail xs')
replace :: String -> String -> String -> String
replace f t orig = intercalate t (splitOn f orig)
infixl 6 <.>
infixl 6 <$>
infixl 6 <=>
infixl 6 <->>
infixl 6 <<->
d1 <$> d2 = d1 <+> parens d2
d1 <=> d2 = d1 <+> text "=" <+> d2
d1 <->> d2 = d1 <+> text "->" <+> d2
d1 <<-> d2 = d1 <+> text "<-" <+> d2
(<.>) :: Doc -> Doc -> Doc
d1 <.> d2 = d1 <> text "." <> d2
vsep = vcat . intersperse (text "")
{-
termHasVar :: FTerm -> Bool
termHasVar = \case
TVar _ -> True
TName nm -> False
TApp nm term -> any termHasVar term
TSeq terms -> any termHasVar terms
TSet terms -> any termHasVar terms
TMap terms -> any termHasVar terms
TList terms -> any termHasVar terms
TFuncon f -> False
TSortSeq term op -> termHasVar term
TSortUnion ty1 ty2 -> termHasVar ty1 || termHasVar ty2
TSortInter ty1 ty2 -> termHasVar ty1 || termHasVar ty2
TSortComplement ty -> termHasVar ty
TSortComputes term -> termHasVar term
TSortComputesFrom from to -> termHasVar from || termHasVar to
TAny -> False
staticSubstitute :: FTerm -> Funcons
staticSubstitute = \case
TVar "_" -> FValue VAny
TVar var -> error ("failed to apply static substitution to: " ++ var)
TName nm -> FName nm
TApp nm term -> FApp nm (map staticSubstitute term)
-- TSeq terms -> map staticSubstitute terms
TSet terms -> FSet (map staticSubstitute terms)
TMap terms -> FMap (map staticSubstitute terms)
TList terms -> FList (map staticSubstitute terms)
TFuncon f -> f
TSortSeq term op -> FSortSeq (staticSubstitute term) op
TSortUnion ty1 ty2 -> FSortUnion (staticSubstitute ty1) (staticSubstitute ty2)
TSortInter ty1 ty2 -> FSortInter (staticSubstitute ty1) (staticSubstitute ty2)
TSortComplement ty -> FSortComplement (staticSubstitute ty)
TSortComputes term -> FSortComputes (staticSubstitute term)
TSortComputesFrom from to -> FSortComputesFrom (staticSubstitute from)
(staticSubstitute to)
TAny -> FValue VAny
-}
funcons2FTerm :: Funcons -> FTerm
funcons2FTerm = \case
FName nm -> TName nm
FApp nm term -> TApp nm (map funcons2FTerm term)
-- FTuple terms -> TTuple (map funcons2FTerm terms)
FSet terms -> TSet (map funcons2FTerm terms)
FMap terms -> TMap (map funcons2FTerm terms)
FBinding t1 t2 -> TBinding (funcons2FTerm t1) (TSeq (map funcons2FTerm t2))
-- FList terms -> TList (map funcons2FTerm terms)
FSortSeq term op -> TSortSeq (funcons2FTerm term) op
FSortUnion ty1 ty2 -> TSortUnion (funcons2FTerm ty1) (funcons2FTerm ty2)
FSortInter ty1 ty2 -> TSortInter (funcons2FTerm ty1) (funcons2FTerm ty2)
FSortComplement ty -> TSortComplement (funcons2FTerm ty)
FSortComputes term -> TSortComputes (funcons2FTerm term)
FSortComputesFrom from to -> TSortComputesFrom (funcons2FTerm from)
(funcons2FTerm to)
FValue v -> TFuncon (FValue v)
FSortPower ty1 ty2 -> TSortPower (funcons2FTerm ty1) (funcons2FTerm ty2)
hsmodNameFromPath :: String -> FilePath -> [String]
hsmodNameFromPath lang file = hs_file_dir_as_list ++ [hs_file_name]
where hs_file_name = camelcase (takeBaseName file)
hs_file_dir_as_list =
(["Funcons", camelcase lang] ++) $
map camelcase $
dropUntil (not . (\x -> x `elem` roots)) $
splitDirectories $
dropFileName $
dropExtension file
roots = ["Funcons", "Funcons-beta", lang]