-
Notifications
You must be signed in to change notification settings - Fork 51
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
Generalize StringLike to StreamLike fix #58 #62
Closed
Closed
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
f0ba9e4
Generalize StringLike to StreamLike
safareli a991f94
update list instance
safareli 2f59245
fix redundant parens and imports
safareli fdcb5ba
update lists
safareli 4f74e34
Merge branch 'master' into string
safareli 9ff887b
update description
safareli 2471c05
add script.test
safareli ad4a76c
remove Token{token,when,match}
safareli b89442b
add 'drop (Prefix a) a >>= uncons = Nothing' law
safareli 67926be
remove String.whitespace
safareli 453d6a1
rename `String.char` to `String.match`
safareli 96dc7da
rename `String.anyChar` to `String.token`
safareli 95eee9b
rename `String.string` to `String.prefix`
safareli 858fda9
fix compiler warnings
safareli 478be1e
fix typo and whitespace char order
safareli b4dc8ce
update Prefix comment
safareli 902e4db
update prefix variable name
safareli e8c9bdb
add Lazy List instance for StreamLike
safareli 19e1ed4
move some parsers to String module; take out Stream module
safareli 499c1d0
add m to StreamLike
safareli 9c7e9e9
replace StreamLike to Stream
safareli 5b38fe8
Merge branch 'master' of github.com:purescript-contrib/purescript-par…
safareli ecb6a3f
resolve ShadowedName position
safareli ea96e73
use correct wording in setisfy
safareli 61d6317
Avoids closure in Stream class
safareli 13d4bf1
Merge branch 'master' into string
safareli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
-- | Primitive parsers for working with an `StreamLike` input. | ||
|
||
module Text.Parsing.Parser.Stream where | ||
|
||
import Control.Monad.State (modify, gets) | ||
import Control.Monad.Trans.Class (lift) | ||
import Data.Foldable (fold, elem, notElem) | ||
import Data.List as L | ||
import Data.List.Lazy as LazyL | ||
import Data.Maybe (Maybe(..)) | ||
import Data.Monoid.Endo (Endo(..)) | ||
import Data.Newtype (class Newtype, unwrap) | ||
import Data.String as S | ||
import Prelude hiding (between) | ||
import Text.Parsing.Parser (ParseState(..), ParserT, fail) | ||
import Text.Parsing.Parser.Combinators (try, (<?>)) | ||
import Text.Parsing.Parser.Pos (Position, updatePosString, updatePosChar) | ||
|
||
-- | A newtype used to identify a prefix of a stream | ||
newtype Prefix a = Prefix a | ||
|
||
derive instance eqPrefix :: Eq a => Eq (Prefix a) | ||
derive instance ordPrefix :: Ord a => Ord (Prefix a) | ||
derive instance newtypePrefix :: Newtype (Prefix a) _ | ||
|
||
instance showPrefix :: Show a => Show (Prefix a) where | ||
show (Prefix s) = "(Prefix " <> show s <> ")" | ||
|
||
class HasUpdatePosition a where | ||
updatePos :: Position -> a -> Position | ||
|
||
instance stringHasUpdatePosition :: HasUpdatePosition String where | ||
updatePos = updatePosString | ||
|
||
instance charHasUpdatePosition :: HasUpdatePosition Char where | ||
updatePos = updatePosChar | ||
|
||
-- | This class exists to abstract over streams which support the string-like | ||
-- | operations which this modules needs. | ||
-- | | ||
-- | Instances must satisfy the following laws: | ||
-- | - `stripPrefix (Prefix a) a >>= uncons = Nothing` | ||
class StreamLike s m t | s -> t where | ||
uncons :: s -> m (Maybe { head :: t, tail :: s, updatePos :: Position -> Position }) | ||
stripPrefix :: Prefix s -> s -> m (Maybe { rest :: s, updatePos :: Position -> Position }) | ||
|
||
instance stringStreamLike :: (Applicative m) => StreamLike String m Char where | ||
uncons f = pure $ S.uncons f <#> \({ head, tail}) -> | ||
{ head, tail, updatePos: (_ `updatePos` head)} | ||
stripPrefix (Prefix p) s = pure $ S.stripPrefix (S.Pattern p) s <#> \rest -> | ||
{ rest, updatePos: (_ `updatePos` p)} | ||
|
||
instance listStreamLike :: (Applicative m, Eq a, HasUpdatePosition a) => StreamLike (L.List a) m a where | ||
uncons f = pure $ L.uncons f <#> \({ head, tail}) -> | ||
{ head, tail, updatePos: (_ `updatePos` head)} | ||
stripPrefix (Prefix p) s = pure $ L.stripPrefix (L.Pattern p) s <#> \rest -> | ||
{ rest, updatePos: unwrap (fold (p <#> (flip updatePos >>> Endo)))} | ||
|
||
instance lazyListStreamLike :: (Applicative m, Eq a, HasUpdatePosition a) => StreamLike (LazyL.List a) m a where | ||
uncons f = pure $ LazyL.uncons f <#> \({ head, tail}) -> | ||
{ head, tail, updatePos: (_ `updatePos` head)} | ||
stripPrefix (Prefix p) s = pure $ LazyL.stripPrefix (LazyL.Pattern p) s <#> \rest -> | ||
{ rest, updatePos: unwrap (fold (p <#> (flip updatePos >>> Endo)))} | ||
|
||
-- | Match end of stream. | ||
eof :: forall s t m. StreamLike s m t => Monad m => ParserT s m Unit | ||
eof = do | ||
input <- gets \(ParseState input _ _) -> input | ||
(lift $ uncons input) >>= case _ of | ||
Nothing -> pure unit | ||
_ -> fail "Expected EOF" | ||
|
||
-- | Match the specified prefix. | ||
prefix :: forall f c m. StreamLike f m c => Show f => Monad m => f -> ParserT f m f | ||
prefix p = do | ||
input <- gets \(ParseState input _ _) -> input | ||
(lift $ stripPrefix (Prefix p) input) >>= case _ of | ||
Just {rest, updatePos} -> do | ||
modify \(ParseState _ position _) -> | ||
ParseState rest (updatePos position) true | ||
pure p | ||
_ -> fail ("Expected " <> show p) | ||
|
||
-- | Match any token. | ||
token :: forall s t m. StreamLike s m t => Monad m => ParserT s m t | ||
token = do | ||
input <- gets \(ParseState input _ _) -> input | ||
(lift $ uncons input) >>= case _ of | ||
Nothing -> fail "Unexpected EOF" | ||
Just ({ head, updatePos, tail }) -> do | ||
modify \(ParseState _ position _) -> | ||
ParseState tail (updatePos position) true | ||
pure head | ||
|
||
-- | Match a token satisfying the specified predicate. | ||
satisfy :: forall s t m. StreamLike s m t => Show t => Monad m => (t -> Boolean) -> ParserT s m t | ||
satisfy f = try do | ||
c <- token | ||
if f c then pure c | ||
else fail $ "Character " <> show c <> " did not satisfy predicate" | ||
|
||
-- | Match the specified token | ||
match :: forall s t m. StreamLike s m t => Eq t => Show t => Monad m => t -> ParserT s m t | ||
match c = satisfy (_ == c) <?> show c | ||
|
||
|
||
-- | Match one of the tokens in the array. | ||
oneOf :: forall s t m. StreamLike s m t => Show t => Eq t => Monad m => Array t -> ParserT s m t | ||
oneOf ss = satisfy (flip elem ss) <?> ("one of " <> show ss) | ||
|
||
-- | Match any token not in the array. | ||
noneOf :: forall s t m. StreamLike s m t => Show t => Eq t => Monad m => Array t -> ParserT s m t | ||
noneOf ss = satisfy (flip notElem ss) <?> ("none of " <> show ss) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we should add
s -> m
here too.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure, in parsec this is how it looks
class (Monad m) => Stream s m t | s -> t