mirror of
https://github.com/mrkkrp/megaparsec.git
synced 2024-11-27 15:32:14 +03:00
made interface of ‘Text.Megaparsec.Pos’ smarter
Now it's impossible to create ‘SourcePos’ with non-positive line number or column number. Unfortunately we cannot use ‘Numeric.Natural’ because we need to support older versions of ‘base’.
This commit is contained in:
parent
bedad01d98
commit
8356a05919
@ -1,3 +1,10 @@
|
||||
## Megaparsec 4.2.0
|
||||
|
||||
* Made `newPos` constructor and other functions in `Text.Megaparsec.Pos`
|
||||
smarter. Now it's impossible to create `SourcePos` with non-positive line
|
||||
number or column number. Unfortunately we cannot use `Numeric.Natural`
|
||||
because we need to support older versions of `base`.
|
||||
|
||||
## Megaparsec 4.1.1
|
||||
|
||||
* Fixed bug in implementation of `sepEndBy` and `sepEndBy1` and removed
|
||||
|
@ -28,9 +28,7 @@ module Text.Megaparsec.Pos
|
||||
, defaultTabWidth )
|
||||
where
|
||||
|
||||
import Data.Data (Data)
|
||||
import Data.List (foldl')
|
||||
import Data.Typeable (Typeable)
|
||||
|
||||
-- | The abstract data type @SourcePos@ represents source positions. It
|
||||
-- contains the name of the source (i.e. file name), a line number and a
|
||||
@ -44,7 +42,7 @@ data SourcePos = SourcePos
|
||||
, sourceLine :: !Int
|
||||
-- | Extract the column number from a source position.
|
||||
, sourceColumn :: !Int }
|
||||
deriving (Eq, Ord, Data, Typeable)
|
||||
deriving (Eq, Ord)
|
||||
|
||||
instance Show SourcePos where
|
||||
show (SourcePos n l c)
|
||||
@ -54,9 +52,12 @@ instance Show SourcePos where
|
||||
|
||||
-- | Create a new 'SourcePos' with the given source name, line number and
|
||||
-- column number.
|
||||
--
|
||||
-- In call @newPos name line column@, if @line@ is not a positive
|
||||
-- number, 1 will be used. The same holds for @column@ value.
|
||||
|
||||
newPos :: String -> Int -> Int -> SourcePos
|
||||
newPos = SourcePos
|
||||
newPos n l c = SourcePos n (max 1 l) (max 1 c)
|
||||
|
||||
-- | Create a new 'SourcePos' with the given source name, and line number
|
||||
-- and column number set to 1, the upper left.
|
||||
@ -64,30 +65,34 @@ newPos = SourcePos
|
||||
initialPos :: String -> SourcePos
|
||||
initialPos name = newPos name 1 1
|
||||
|
||||
-- | Increment the line number of a source position.
|
||||
-- | Increment the line number of a source position. If resulting line
|
||||
-- number is not positive, line number will be equal to 1.
|
||||
|
||||
incSourceLine :: SourcePos -> Int -> SourcePos
|
||||
incSourceLine (SourcePos n l c) d = SourcePos n (l + d) c
|
||||
incSourceLine (SourcePos n l c) d = SourcePos n (max 1 $ l + d) c
|
||||
|
||||
-- | Increments the column number of a source position.
|
||||
-- | Increments the column number of a source position. If resulting column
|
||||
-- number is not positive, column number will be equal to 1.
|
||||
|
||||
incSourceColumn :: SourcePos -> Int -> SourcePos
|
||||
incSourceColumn (SourcePos n l c) d = SourcePos n l (c + d)
|
||||
incSourceColumn (SourcePos n l c) d = SourcePos n l (max 1 $ c + d)
|
||||
|
||||
-- | Set the name of the source.
|
||||
|
||||
setSourceName :: SourcePos -> String -> SourcePos
|
||||
setSourceName (SourcePos _ l c) n = SourcePos n l c
|
||||
|
||||
-- | Set the line number of a source position.
|
||||
-- | Set the line number of a source position. If the line number is not
|
||||
-- positive, 1 will be used.
|
||||
|
||||
setSourceLine :: SourcePos -> Int -> SourcePos
|
||||
setSourceLine (SourcePos n _ c) l = SourcePos n l c
|
||||
setSourceLine (SourcePos n _ c) l = SourcePos n (max 1 l) c
|
||||
|
||||
-- | Set the column number of a source position.
|
||||
-- | Set the column number of a source position. If the line number is not
|
||||
-- positive, 1 will be used.
|
||||
|
||||
setSourceColumn :: SourcePos -> Int -> SourcePos
|
||||
setSourceColumn (SourcePos n l _) = SourcePos n l
|
||||
setSourceColumn (SourcePos n l _) c = SourcePos n l (max 1 c)
|
||||
|
||||
-- | Update a source position given a character. The first argument
|
||||
-- specifies tab width. If the character is a newline (\'\\n\') the line
|
||||
|
42
tests/Pos.hs
42
tests/Pos.hs
@ -47,6 +47,7 @@ import Control.Applicative ((<$>), (<*>), pure)
|
||||
tests :: Test
|
||||
tests = testGroup "Textual source positions"
|
||||
[ testProperty "components" prop_components
|
||||
, testProperty "positive coordinates" prop_positive
|
||||
, testProperty "show file name in source positions" prop_showFileName
|
||||
, testProperty "show line in source positions" prop_showLine
|
||||
, testProperty "show column in source positions" prop_showColumn
|
||||
@ -59,7 +60,7 @@ tests = testGroup "Textual source positions"
|
||||
, testProperty "position updating" prop_updating ]
|
||||
|
||||
instance Arbitrary SourcePos where
|
||||
arbitrary = newPos <$> fileName <*> choose (1, 1000) <*> choose (0, 100)
|
||||
arbitrary = newPos <$> fileName <*> choose (-10, 1000) <*> choose (-10, 100)
|
||||
|
||||
fileName :: Gen String
|
||||
fileName = do
|
||||
@ -74,6 +75,9 @@ prop_components :: SourcePos -> Bool
|
||||
prop_components pos = pos == copy
|
||||
where copy = newPos (sourceName pos) (sourceLine pos) (sourceColumn pos)
|
||||
|
||||
prop_positive :: SourcePos -> Bool
|
||||
prop_positive pos = sourceLine pos > 0 && sourceColumn pos > 0
|
||||
|
||||
prop_showFileName :: SourcePos -> Bool
|
||||
prop_showFileName pos = sourceName pos `isInfixOf` show pos
|
||||
|
||||
@ -90,21 +94,21 @@ prop_initialPos n =
|
||||
sourceColumn ipos == 1
|
||||
where ipos = initialPos n
|
||||
|
||||
prop_incSourceLine :: SourcePos -> NonNegative Int -> Bool
|
||||
prop_incSourceLine :: SourcePos -> Int -> Bool
|
||||
prop_incSourceLine pos l =
|
||||
d sourceName id pos incp &&
|
||||
d sourceLine (+ l') pos incp &&
|
||||
d sourceColumn id pos incp
|
||||
where l' = getNonNegative l
|
||||
incp = incSourceLine pos l'
|
||||
d sourceName id pos incp &&
|
||||
d sourceLine f pos incp &&
|
||||
d sourceColumn id pos incp
|
||||
where f = max 1 . (+ l)
|
||||
incp = incSourceLine pos l
|
||||
|
||||
prop_incSourceColumn :: SourcePos -> NonNegative Int -> Bool
|
||||
prop_incSourceColumn :: SourcePos -> Int -> Bool
|
||||
prop_incSourceColumn pos c =
|
||||
d sourceName id pos incp &&
|
||||
d sourceLine id pos incp &&
|
||||
d sourceColumn (+ c') pos incp
|
||||
where c' = getNonNegative c
|
||||
incp = incSourceColumn pos c'
|
||||
d sourceName id pos incp &&
|
||||
d sourceLine id pos incp &&
|
||||
d sourceColumn f pos incp
|
||||
where f = max 1 . (+ c)
|
||||
incp = incSourceColumn pos c
|
||||
|
||||
prop_setSourceName :: SourcePos -> String -> Bool
|
||||
prop_setSourceName pos n =
|
||||
@ -113,21 +117,21 @@ prop_setSourceName pos n =
|
||||
d sourceColumn id pos setp
|
||||
where setp = setSourceName pos n
|
||||
|
||||
prop_setSourceLine :: SourcePos -> Positive Int -> Bool
|
||||
prop_setSourceLine :: SourcePos -> Int -> Bool
|
||||
prop_setSourceLine pos l =
|
||||
d sourceName id pos setp &&
|
||||
d sourceLine (const l') pos setp &&
|
||||
d sourceColumn id pos setp
|
||||
where l' = getPositive l
|
||||
setp = setSourceLine pos l'
|
||||
where l' = max 1 l
|
||||
setp = setSourceLine pos l
|
||||
|
||||
prop_setSourceColumn :: SourcePos -> NonNegative Int -> Bool
|
||||
prop_setSourceColumn :: SourcePos -> Int -> Bool
|
||||
prop_setSourceColumn pos c =
|
||||
d sourceName id pos setp &&
|
||||
d sourceLine id pos setp &&
|
||||
d sourceColumn (const c') pos setp
|
||||
where c' = getNonNegative c
|
||||
setp = setSourceColumn pos c'
|
||||
where c' = max 1 c
|
||||
setp = setSourceColumn pos c
|
||||
|
||||
prop_updating :: Int -> SourcePos -> String -> Bool
|
||||
prop_updating w pos "" = updatePosString w pos "" == pos
|
||||
|
Loading…
Reference in New Issue
Block a user