packages feed

madlang 3.1.1.13 → 3.1.1.18

raw patch · 10 files changed

+70/−31 lines, 10 filesdep +recursion-schemes-extPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependencies added: recursion-schemes-ext

API changes (from Hackage documentation)

+ Text.Madlibs: ImportNotFound :: FilePath -> SemanticError
+ Text.Madlibs: runCata :: (MonadRandom m) => RandTok -> m Text

Files

cabal.project.local view
@@ -1,3 +1,3 @@ with-compiler: ghc-8.2.1-optimization: 2+optimization: 1 constraints: madlang +development
madlang.cabal view
@@ -1,5 +1,5 @@ name:                madlang-version:             3.1.1.13+version:             3.1.1.18 synopsis:            Randomized templating language DSL description:         Madlang is a text templating language written in Haskell,                      meant to explore computational creativity and generative@@ -27,15 +27,16 @@                  , directory                  , process >= 1.4.0.0 -Flag development {-  Description: Turn on '-Werror'+Flag profile {+  Description: Build for profiling   Default: False   Manual: True } -Flag llvm-fast {-  Description: Enable build with llvm backend (produces a faster executable)+Flag development {+  Description: Turn on '-Werror'   Default: False+  Manual: True }  Flag library {@@ -69,6 +70,7 @@                      , file-embed                      , random-shuffle                      , mtl+                     , recursion-schemes-ext                      , ansi-wl-pprint                      , containers                      , titlecase >= 1.0@@ -83,7 +85,7 @@   if flag(development)     ghc-options:       -Werror   if impl(ghc >= 8.0)-    ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates+    ghc-options:       -Wincomplete-uni-patterns -Wincomplete-record-updates   ghc-options:         -Wall  executable madlang@@ -93,8 +95,8 @@     Buildable: True   hs-source-dirs:      app   main-is:             Main.hs-  if flag(llvm-fast)-    ghc-options:       -fllvm -O3 -optlo-O3 -opta-march=native -opta-mtune=native+  if flag(profile)+    ghc-options:       -rtsopts -fprof-auto -prof   if flag(development)     ghc-options:       -Werror   if impl(ghc >= 8.0)@@ -117,9 +119,6 @@     ghc-options:    -Werror   if impl(ghc >= 8.0)     ghc-options:    -Wincomplete-uni-patterns -Wincomplete-record-updates-  if flag(llvm-fast)-    ghc-options:       -fllvm -O3 -optlo-O3 -opta-march=native -opta-mtune=native-  ghc-options:      -O2   default-language: Haskell2010  test-suite madlang-test
man/madlang.1 view
@@ -1,4 +1,4 @@-.\" Automatically generated by Pandoc 2.0+.\" Automatically generated by Pandoc 2.0.1 .\" .TH "madlang (1)" "" "" "" "" .hy
src/Text/Madlibs.hs view
@@ -29,6 +29,7 @@                     , makeTree                     -- * Functions and constructs for the `RandTok` data type                     , run+                    , runCata                     , runText                     , RandTok (..)                     , Key
src/Text/Madlibs/Ana/ParseUtils.hs view
@@ -20,6 +20,7 @@ import qualified Data.Map                    as M import           Data.Maybe                  (catMaybes) import           Data.Monoid+import qualified Data.Set                    as S import qualified Data.Text                   as T import           Data.Text.Titlecase import           System.Random.Shuffle@@ -107,9 +108,9 @@ maybeList (Just x) = x maybeList Nothing  = [] -allDeps :: [(Key, [(Prob, [PreTok])])] -> Key -> [Key]-allDeps context key = let deps = (maybeList . fmap (catMaybes . fmap maybeName) . getNames) context in deps <> (allDeps context =<< deps)-    where getNames = fmap ((=<<) snd) . lookup key+allDeps :: M.Map Key [(Prob, [PreTok])] -> Key -> S.Set Key+allDeps context key = let deps = (maybeList . fmap (catMaybes . fmap maybeName) . getNames) context in S.fromList (deps <> (S.toList . allDeps context =<< deps))+    where getNames = fmap ((=<<) snd) . M.lookup key           maybeName (Name n _) = Just n           maybeName _          = Nothing @@ -120,6 +121,6 @@     | key2 == "Return" = LT     | orderHelper key1 l2 = LT     | orderHelper key2 l1 = GT-    | key2 `elem` allDeps context key1 = GT-    | key1 `elem` allDeps context key2 = LT+    | key2 `S.member` allDeps (M.fromList context) key1 = GT+    | key1 `S.member` allDeps (M.fromList context) key2 = LT     | otherwise = EQ
src/Text/Madlibs/Ana/Resolve.hs view
@@ -6,12 +6,13 @@   , runFile   , makeTree   , runText+  , runFileN   ) where  import           Control.Arrow               (first) import           Control.Composition import           Control.Exception-import           Control.Monad               (void)+import           Control.Monad               (replicateM, void) import           Control.Monad.IO.Class      (MonadIO, liftIO) import           Control.Monad.Random.Class import           Data.Monoid@@ -39,23 +40,37 @@ getInclusionCtx :: (MonadIO m) => Bool -> [T.Text] -> FilePath -> FilePath -> m (Either (ParseError Char (ErrorFancy Void)) [(Key, RandTok)]) getInclusionCtx isTree ins folder filepath = liftIO $ do     libDir <- do { home <- getEnv "HOME" ; if os /= home then pure (home <> "/.madlang/") else pure (home <> "\\.madlang\\") }-    file <- catch (readFile' (folder ++ filepath)) (const (readFile' (libDir <> folder <> filepath)) :: IOException -> IO T.Text)+    file <- catch (readFile' (folder ++ filepath)) (const (readLibFile (libDir <> folder <> filepath)) :: IOException -> IO T.Text)     let filenames = map T.unpack $ either (error . show) id $ parseInclusions filepath file -- TODO pass up errors correctly     let resolveKeys file' = fmap (first (((T.pack . (<> "-")) . dropExtension) file' <>))     ctxPure <- mapM (getInclusionCtx isTree ins folder) filenames     let ctx = zipWith resolveKeys filenames <$> sequence ctxPure     catch         (parseCtx isTree ins (concat . either (const []) id $ ctx) (folder ++ filepath))-        (const (do { home <- getEnv "HOME" ; parseCtx isTree ins (concat . either (const []) id $ ctx) (home <> "/.madlang/" <> folder <> filepath) }) :: IOException -> IO (Either (ParseError Char (ErrorFancy Void)) [(Key, RandTok)]))+        (const (do { home <- getEnv "HOME" ; parseCtx isTree ins (concat . either (const []) id $ ctx) (home <> (pathSep : ".madlang") <> [pathSep] <> folder <> filepath) }) :: IOException -> IO (Either (ParseError Char (ErrorFancy Void)) [(Key, RandTok)])) +pathSep :: Char+pathSep | os == "windows" = '\\'+        | otherwise = '/'+ -- | Generate randomized text from a file containing a template runFile :: [T.Text] -- ^ List of variables to substitute into the template     -> FilePath -- ^ Path to @.mad@ file.     -> IO T.Text -- ^ Result runFile ins toFolder = do     void $ doesDirectoryExist (getDir toFolder)-    let filepath = reverse . takeWhile (/= '/') . reverse $ toFolder+    let filepath = reverse . takeWhile (/= pathSep) . reverse $ toFolder     runInFolder ins (getDir toFolder) filepath++runFileN :: Int -> [T.Text] -> FilePath -> IO [T.Text]+runFileN n ins toFolder = do+    void $ doesDirectoryExist (getDir toFolder)+    let filepath = reverse . takeWhile (/= pathSep) . reverse $ toFolder+    runInFolderN n ins (getDir toFolder) filepath++-- | Run 'n' times.+runInFolderN :: Int -> [T.Text] -> FilePath -> FilePath -> IO [T.Text]+runInFolderN n = replicateM n .** runInFolder  -- | Run in the appropriate folder runInFolder :: [T.Text] -> FilePath -> FilePath -> IO T.Text
src/Text/Madlibs/Cata/Run.hs view
@@ -1,8 +1,10 @@ -- | Module containing functions to get `Text` from `RandTok`-module Text.Madlibs.Cata.Run (run) where+module Text.Madlibs.Cata.Run ( run+                             , runCata ) where  import           Control.Monad.Random.Class-import qualified Data.Text                   as T+import           Data.Functor.Foldable.Exotic (cataM)+import qualified Data.Text                    as T import           Text.Madlibs.Internal.Types import           Text.Madlibs.Internal.Utils @@ -23,7 +25,19 @@         tokNest@List{} -> run tokNest run (Value txt) = pure txt +-- | Same thing, but uses a catamorphism (slower)+runCata :: (MonadRandom m) => RandTok -> m T.Text+runCata = cataM alg where+    alg (ListF tok) = do+        value <- getRandomR (0,1)+        pure $ ((snd . head) . filter ((>= value) . fst)) $ mkCdfCata tok+    alg (ValueF txt) = pure txt+ -- | Helper function to compute the cdf when we have a pdf-mkCdf :: RandTok -> [(Double, RandTok)]-mkCdf (List rs) = zip (cdf . map fst $ rs) (map snd rs)+mkCdf :: RandTok -> [(Prob, RandTok)]+mkCdf (List rs) = zip (cdf . fmap fst $ rs) (fmap snd rs) mkCdf v@Value{} = [(1, v)]++-- | Another helper function, this time for use with our catamorphism.+mkCdfCata :: [(Prob, T.Text)] -> [(Prob, T.Text)]+mkCdfCata rs = zip (cdf . fmap fst $ rs) (fmap snd rs)
src/Text/Madlibs/Cata/SemErr.hs view
@@ -22,7 +22,7 @@ type Parser = Parsec (ErrorFancy Void) T.Text  -- | Datatype for a semantic error-data SemanticError = NoReturn | CircularFunctionCalls T.Text T.Text | InsufficientArgs Int Int | DoubleDefinition T.Text | NoContext T.Text+data SemanticError = NoReturn | CircularFunctionCalls T.Text T.Text | InsufficientArgs Int Int | DoubleDefinition T.Text | NoContext T.Text | ImportNotFound FilePath     deriving (Typeable)  -- | display a `SemanticError` nicely with coloration & whatnot@@ -53,6 +53,10 @@         <> (text . show $ i)         <> ", expected at least "         <> (text . show $ j)+    show (ImportNotFound p) = show $+        semErrStart+        <> text "Import file not found: "+        </> indent 4 (yellow $ text p)  -- | Derived via our show instance; instance Exception SemanticError where
src/Text/Madlibs/Exec/Main.hs view
@@ -2,11 +2,11 @@ module Text.Madlibs.Exec.Main (     runMadlang ) where -import           Control.Monad import           Data.Maybe import           Data.Monoid import qualified Data.Text                    as T-import qualified Data.Text.IO                 as TIO+import qualified Data.Text.Lazy               as TL+import qualified Data.Text.Lazy.IO            as TLIO import           Data.Version import           Options.Applicative          hiding (ParseError) import           Paths_madlang@@ -129,9 +129,9 @@             let ins = map T.pack (clInputs . sub $ rec)             case sub rec of                 (Run reps _ _) ->-                    replicateM_ (fromMaybe 1 reps) $ runFile ins filepath >>= TIO.putStrLn+                    (TL.init . TL.unlines . fmap TL.fromStrict <$> runFileN (fromMaybe 1 reps) ins filepath) >>= TLIO.putStrLn                 (Sample _ _) ->-                    replicateM_ 60 $ runFile ins filepath >>= TIO.putStrLn+                    (TL.init . TL.unlines . fmap TL.fromStrict <$> runFileN 60 ins filepath) >>= TLIO.putStrLn                 (Debug _) -> putStr . (either show displayTree) =<< makeTree ins "" filepath                 (Lint _ _) -> do                     parsed <- parseFile ins "" filepath
src/Text/Madlibs/Internal/Utils.hs view
@@ -6,8 +6,10 @@ module Text.Madlibs.Internal.Utils where  import           Control.Arrow               (first)+import           Control.Exception           (IOException, catch, throw) import qualified Data.Text                   as T import           Data.Void+import           Text.Madlibs.Cata.SemErr import           Text.Madlibs.Internal.Types import           Text.Megaparsec.Error @@ -46,6 +48,9 @@ unTok :: PreTok -> T.Text unTok PreTok{}     = "" unTok (Name txt _) = txt++readLibFile :: FilePath -> IO T.Text+readLibFile path = catch (fmap T.pack . readFile $ path) (throw (ImportNotFound path) :: IOException -> IO T.Text)  -- | Read a file in as a `Text` readFile' :: FilePath -> IO T.Text