Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

rnjtranjan
Copy link
Contributor

No description provided.

@rnjtranjan
Copy link
Contributor Author

Fixes: #73

Comment on lines +31 to +87
data StrSegment
= StrText String
| StrVar String
deriving (Show, Eq)

formatSpace :: String -> String
formatSpace = foldr go ""
where
go x acc = x:if x == ' ' then dropWhile (' ' ==) acc else acc

-- | Replace a newline by a space and convert multiple spaces to single space
--
-- >>> :set -XQuasiQuotes
-- >>> import Streamly.Internal.System
-- >>> trim " abc \n bbb \n ccc "
-- " abc bbb ccc "
--
trim :: String -> String
trim = formatSpace <$> (unwords . fmap formatSpace . lines)

haskellIdentifier :: Monad m => Parser Char m String
haskellIdentifier =
let p = Parser.alphaNum <|> Parser.char '\'' <|> Parser.char '_'
in Parser.some p Fold.toList

strParser :: Monad m => Parser Char m [StrSegment]
strParser = Parser.many content Fold.toList

where

plainText = StrText . trim <$> Parser.takeWhile1 (/= '#') Fold.toList
escHash = StrText . (: []) <$> (Parser.char '#' *> Parser.char '#')
lineCont = StrText [] <$ (Parser.char '#' *> Parser.char '\n')
var = StrVar <$>
( Parser.char '#'
*> Parser.char '{'
*> haskellIdentifier
<* Parser.char '}'
)
plainHash = StrText . (: []) <$> Parser.char '#'

-- order is important
content = plainText <|> escHash <|> lineCont <|> var <|> plainHash

strSegmentExp :: StrSegment -> Q Exp
strSegmentExp (StrText text) = stringE text
strSegmentExp (StrVar name) = do
valueName <- lookupValueName name
case valueName of
Just vn -> varE vn
Nothing ->
fail
$ "cmd quote: Haskell symbol `" ++ name
++ "` is not in scope"

strExp :: [StrSegment] -> Q Exp
strExp xs = appE [| concat |] $ listE $ map strSegmentExp xs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need all this. This is replicated.

Comment on lines +36 to +49
formatSpace :: String -> String
formatSpace = foldr go ""
where
go x acc = x:if x == ' ' then dropWhile (' ' ==) acc else acc

-- | Replace a newline by a space and convert multiple spaces to single space
--
-- >>> :set -XQuasiQuotes
-- >>> import Streamly.Internal.System
-- >>> trim " abc \n bbb \n ccc "
-- " abc bbb ccc "
--
trim :: String -> String
trim = formatSpace <$> (unwords . fmap formatSpace . lines)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You only need formatSpace and trim.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have idiomatic code to do this:

-- | Replace newlines followed by any number of spaces with a single space.
oneLine :: String -> String
oneLine = unwords . fmap (dropWhile isSpace) . lines


expandVars :: String -> Q Exp
expandVars ln =
case runIdentity $ Stream.parse strParser (Stream.fromList ln) of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can import strParser from Unicode.String. If not exported, you can export it internally.
After runIdentity, you can use trim and formatSpace

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's import as much as we can from streamly-core instead of writing it again.

Right x ->
strExp x

-- | A QuasiQuoter that treats the input as a string literal:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to change the documentation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can point it to the str documentation and add the doc for the changes that you made.


expandVars :: String -> Q Exp
expandVars ln =
case runIdentity $ Stream.parse strParser (Stream.fromList ln) of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's import as much as we can from streamly-core instead of writing it again.

Comment on lines +36 to +49
formatSpace :: String -> String
formatSpace = foldr go ""
where
go x acc = x:if x == ' ' then dropWhile (' ' ==) acc else acc

-- | Replace a newline by a space and convert multiple spaces to single space
--
-- >>> :set -XQuasiQuotes
-- >>> import Streamly.Internal.System
-- >>> trim " abc \n bbb \n ccc "
-- " abc bbb ccc "
--
trim :: String -> String
trim = formatSpace <$> (unwords . fmap formatSpace . lines)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have idiomatic code to do this:

-- | Replace newlines followed by any number of spaces with a single space.
oneLine :: String -> String
oneLine = unwords . fmap (dropWhile isSpace) . lines

--
{-# LANGUAGE TemplateHaskell #-}

module Streamly.Internal.System
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this in the command module rather than creating a new module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.