Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support more paths #2000

Merged
merged 19 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Juvix/Compiler/Backend/Html/Translation/FromTyped.hs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ goJudoc (Judoc bs) = mconcatMapM goBlock bs
JudocExample e -> goExample e

goLine :: JudocParagraphLine 'Scoped -> Sem r Html
goLine (JudocParagraphLine atoms) = mconcatMapM goAtom (map (^. withLocParam) (toList atoms))
goLine (JudocParagraphLine atoms) = mconcatMapM goAtom (fmap (^. withLocParam) atoms)

goExample :: Example 'Scoped -> Sem r Html
goExample ex = do
Expand Down Expand Up @@ -425,7 +425,7 @@ goInductive def = do

goConstructors :: forall r. (Members '[Reader HtmlOptions, Reader NormalizedTable] r) => NonEmpty (InductiveConstructorDef 'Scoped) -> Sem r Html
goConstructors cc = do
tbl' <- table . tbody <$> mconcatMapM goConstructor (toList cc)
tbl' <- table . tbody <$> mconcatMapM goConstructor cc
return $
Html.div ! Attr.class_ "subs constructors" $
(p ! Attr.class_ "caption" $ "Constructors")
Expand Down
4 changes: 2 additions & 2 deletions src/Juvix/Compiler/Concrete/Extra.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Juvix.Compiler.Concrete.Extra
( module Juvix.Compiler.Concrete.Extra.Base,
( module Juvix.Prelude.Parsing,
mkScopedModule,
getAllModules,
getModuleFilePath,
Expand All @@ -9,9 +9,9 @@ where

import Data.HashMap.Strict qualified as HashMap
import Juvix.Compiler.Concrete.Data.ScopedName qualified as S
import Juvix.Compiler.Concrete.Extra.Base
import Juvix.Compiler.Concrete.Language
import Juvix.Prelude hiding (some)
import Juvix.Prelude.Parsing

data ScopedModule = forall t. MkScopedModule (SModuleIsTop t) (Module 'Scoped t)

Expand Down
32 changes: 13 additions & 19 deletions src/Juvix/Compiler/Core/Data/TransformationId/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,30 @@ module Juvix.Compiler.Core.Data.TransformationId.Parser (parseTransformations, T
import Data.Text qualified as Text
import Juvix.Compiler.Core.Data.TransformationId
import Juvix.Prelude
import Juvix.Prelude.Pretty hiding (comma)
import Text.Megaparsec as P
import Text.Megaparsec.Char qualified as L
import Juvix.Prelude.Parsing (MonadParsec)
import Juvix.Prelude.Parsing qualified as P
import Text.Megaparsec.Char.Lexer qualified as L

parseHelper :: Parsec Void Text a -> Text -> Either Text a
parseHelper p t = case runParser p "<input>" t of
Left (err :: ParseErrorBundle Text Void) -> Left (prettyText (errorBundlePretty err))
Right r -> return r

parseTransformations :: Text -> Either Text [TransformationId]
parseTransformations = fmap fromTransformationLikes . parseHelper transformations
parseTransformations = fmap fromTransformationLikes . P.parseHelper transformations

completionsString :: String -> [String]
completionsString = map unpack . completions . pack

completions :: Text -> [Text]
completions = fromRight [] . parseHelper pcompletions
completions = fromRight [] . P.parseHelper pcompletions

transformations :: (MonadParsec e Text m) => m [TransformationLikeId]
transformations = do
L.hspace
sepEndBy transformationLike comma <* eof
P.hspace
P.sepEndBy transformationLike comma <* P.eof

-- | returns a possible list of completions
pcompletions :: (MonadParsec e Text m) => m [Text]
pcompletions = do
L.hspace
l <- sepEndBy transformationLike comma
rest <- Text.strip <$> takeRest
P.hspace
l <- P.sepEndBy transformationLike comma
rest <- Text.strip <$> P.takeRest
return [ppTransL (notNull l) l <> str | str <- allStrings, Text.isPrefixOf rest str]
where
ppTransL :: Bool -> [TransformationLikeId] -> Text
Expand All @@ -41,13 +35,13 @@ pcompletions = do
in f . Text.intercalate "," . map transformationLikeText

lexeme :: (MonadParsec e Text m) => m a -> m a
lexeme = L.lexeme L.hspace
lexeme = L.lexeme P.hspace

comma :: (MonadParsec e Text m) => m ()
comma = symbol ","

symbol :: (MonadParsec e Text m) => Text -> m ()
symbol = void . lexeme . chunk
symbol = void . lexeme . P.chunk

transformationLike :: MonadParsec e Text m => m TransformationLikeId
transformationLike =
Expand Down Expand Up @@ -88,10 +82,10 @@ transformationText = \case
FoldTypeSynonyms -> strFoldTypeSynonyms

parsePipeline :: MonadParsec e Text m => m PipelineId
parsePipeline = choice [symbol (pipelineText t) $> t | t <- allElements]
parsePipeline = P.choice [symbol (pipelineText t) $> t | t <- allElements]

transformation :: MonadParsec e Text m => m TransformationId
transformation = choice [symbol (transformationText t) $> t | t <- allElements]
transformation = P.choice [symbol (transformationText t) $> t | t <- allElements]

allStrings :: [Text]
allStrings = map transformationLikeText allTransformationLikeIds
Expand Down
2 changes: 0 additions & 2 deletions src/Juvix/Prelude.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module Juvix.Prelude
module Juvix.Prelude.Trace,
module Juvix.Prelude.Path,
module Juvix.Prelude.Prepath,
module Juvix.Prelude.Shell,
module Juvix.Data,
)
where
Expand All @@ -14,5 +13,4 @@ import Juvix.Prelude.Base
import Juvix.Prelude.Lens
import Juvix.Prelude.Path
import Juvix.Prelude.Prepath
import Juvix.Prelude.Shell
import Juvix.Prelude.Trace
6 changes: 5 additions & 1 deletion src/Juvix/Prelude/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ where

import Control.Applicative
import Control.Monad.Catch (MonadMask, MonadThrow, throwM)
import Control.Monad.Extra hiding (fail)
import Control.Monad.Extra hiding (fail, mconcatMapM)
import Control.Monad.Extra qualified as Monad
import Control.Monad.Fix
import Control.Monad.IO.Class (MonadIO (..))
import Data.Bifunctor hiding (first, second)
Expand Down Expand Up @@ -247,6 +248,9 @@ allSame t
mconcatMap :: (Monoid c, Foldable t) => (a -> c) -> t a -> c
mconcatMap f = List.mconcatMap f . toList

mconcatMapM :: (Monad m, Monoid c, Foldable t) => (a -> m c) -> t a -> m c
mconcatMapM f = Monad.mconcatMapM f . toList

concatWith :: (Foldable t, Monoid a) => (a -> a -> a) -> t a -> a
concatWith f ds
| null ds = mempty
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Juvix.Compiler.Concrete.Extra.Base
module Juvix.Prelude.Parsing
( module Text.Megaparsec,
module Data.List.NonEmpty,
module Juvix.Prelude.Parsing,
module Text.Megaparsec.Char,
module Control.Monad.Combinators.Expr,
module Control.Monad.Combinators.NonEmpty,
Expand All @@ -11,7 +11,12 @@ where
import Control.Monad.Combinators.Expr
import Control.Monad.Combinators.NonEmpty (sepBy1, sepEndBy1, some)
import Control.Monad.Trans.Class (lift)
import Data.List.NonEmpty (NonEmpty)
import Juvix.Prelude hiding (some)
import Text.Megaparsec hiding (sepBy1, sepEndBy1, some)
import Text.Megaparsec.Char
import Juvix.Prelude.Base
import Juvix.Prelude.Pretty

parseHelper :: (TraversableStream txt, VisualStream txt) => Parsec Void txt a -> txt -> Either Text a
parseHelper p t = case runParser p "<input>" t of
Left (err :: ParseErrorBundle txt Void) -> Left (prettyText (errorBundlePretty err))
Right r -> return r
61 changes: 59 additions & 2 deletions src/Juvix/Prelude/Prepath.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,74 @@ where

import Data.Yaml
import Juvix.Prelude.Base
-- import Text.Megaparsec as P
-- import Text.Megaparsec.Char qualified as P
-- import Text.Megaparsec.Char.Lexer qualified as P
import Juvix.Prelude.Parsing as P
import Juvix.Prelude.Path
import Juvix.Prelude.Pretty
import Juvix.Prelude.Shell
import System.Directory (getHomeDirectory)
import System.Directory qualified as System
import System.Environment

-- | A file/directory path that may contain environmental variables
newtype Prepath d = Prepath {_prepath :: String}
deriving stock (Show, Eq, Data, Generic)

makeLenses ''Prepath

type PrepathParts = NonEmpty PrepathPart

data PrepathPart
= PrepathVar String
| PrepathString String
| PrepathHome

-- | Paths have the following restrictions:
-- 1. Environment variables are given with the makefile-like syntax $(VAR)
-- 2. The three characters $ ( ) are reserved for the environment variables syntax.
-- They cannot be part of the path.
-- 3. ~ is reserved for $(HOME). I.e. the prepath ~~ will expand to $HOME$HOME.
-- 4. Nested environment variables are not allowed.
expandPrepath :: Prepath a -> IO FilePath
expandPrepath (Prepath p) =
let e = parseHelper prepathParts p
in case e of
Left er -> error er
Right r -> expandParts r
where
prepathParts :: forall e m. MonadParsec e String m => m PrepathParts
prepathParts = some1 prepathPart
where
prepathPart :: m PrepathPart
prepathPart =
PrepathVar <$> evar
<|> PrepathString <$> str
paulcadman marked this conversation as resolved.
Show resolved Hide resolved
where
reserved :: [Char]
reserved = "$()"
notReserved :: Char -> Bool
notReserved = (`notElem` reserved)
evar :: m String
evar = do
P.chunk "$("
v <- P.takeWhile1P (Just "<EnvVar>") notReserved
P.chunk ")"
return v
str :: m String
str = P.takeWhile1P (Just "<Path>") notReserved

expandParts :: PrepathParts -> IO FilePath
expandParts = mconcatMapM fromPart
where
fromPart :: PrepathPart -> IO String
fromPart = \case
PrepathString s -> return s
PrepathHome -> getHomeDirectory
PrepathVar s -> fromMaybe err <$> lookupEnv s
where
err = error ("The environment variable " <> pack s <> " is not defined")

mkPrepath :: String -> Prepath d
mkPrepath = Prepath

Expand All @@ -48,7 +105,7 @@ prepathToAbsDir root = fmap absDir . prepathToFilePath root
prepathToFilePath :: Path Abs Dir -> Prepath d -> IO FilePath
prepathToFilePath root pre =
withCurrentDir root $
shellExpandCwd (pre ^. prepath) >>= System.canonicalizePath
expandPrepath pre >>= System.canonicalizePath

fromPreFileOrDir :: Path Abs Dir -> Prepath FileOrDir -> IO (Either (Path Abs File) (Path Abs Dir))
fromPreFileOrDir cwd fp = do
Expand Down
2 changes: 1 addition & 1 deletion src/Juvix/Prelude/Pretty.hs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ toAnsiText useColors
toPlainText :: HasTextBackend a => a -> Text
toPlainText = Text.renderStrict . toTextStream

prettyText :: (Pretty a) => a -> Text
prettyText :: Pretty a => a -> Text
prettyText = Text.renderStrict . layoutPretty defaultLayoutOptions . pretty

vsepHard :: Foldable f => f (Doc a) -> Doc a
Expand Down
19 changes: 0 additions & 19 deletions src/Juvix/Prelude/Shell.hs

This file was deleted.

2 changes: 1 addition & 1 deletion tests/positive/FancyPaths/juvix.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
dependencies:
- "../FancyPaths/././path with spaces"
# $JUVIX_TEST_PATH is meant to contain "other dep"
- $JUVIX_TEST_PATH/../$JUVIX_TEST_PATH/
- $(JUVIX_TEST_PATH)/../$(JUVIX_TEST_PATH)/