megaparsec/Text/Megaparsec/Pos.hs

128 lines
3.8 KiB
Haskell
Raw Normal View History

2008-01-13 20:53:15 +03:00
-- |
-- Module : Text.Megaparsec.Pos
-- Copyright : © 2015 Megaparsec contributors
-- © 2007 Paolo Martini
-- © 19992001 Daan Leijen
2015-07-28 16:32:19 +03:00
-- License : BSD3
--
-- Maintainer : Mark Karpov <markkarpov@opmbx.org>
2015-07-29 11:38:32 +03:00
-- Stability : experimental
2008-01-13 20:53:15 +03:00
-- Portability : portable
2015-07-28 16:32:19 +03:00
--
2008-01-13 20:53:15 +03:00
-- Textual source positions.
module Text.Megaparsec.Pos
2015-07-28 16:32:19 +03:00
( SourceName
, Line
, Column
2008-01-13 20:53:15 +03:00
, SourcePos
2015-07-28 16:32:19 +03:00
, sourceLine
, sourceColumn
, sourceName
, incSourceLine
, incSourceColumn
, setSourceLine
, setSourceColumn
, setSourceName
, newPos
, initialPos
, updatePosChar
, updatePosString )
where
2008-01-13 20:53:15 +03:00
2010-09-08 09:37:47 +04:00
import Data.Data (Data)
2015-07-29 11:38:32 +03:00
import Data.List (foldl')
2010-09-08 09:37:47 +04:00
import Data.Typeable (Typeable)
2008-12-26 11:29:54 +03:00
2015-07-30 21:36:54 +03:00
-- | @SourceName@ is a file name, in our case it's @String@.
2008-01-13 20:53:15 +03:00
type SourceName = String
2015-07-30 21:36:54 +03:00
-- | @Line@ represents line number, 1 is the minimum.
type Line = Int
-- | @Column@ is column number, 1 is the the minimum.
type Column = Int
2008-01-13 20:53:15 +03:00
-- | The abstract data type @SourcePos@ represents source positions. It
2015-07-28 16:32:19 +03:00
-- contains the name of the source (i.e. file name), a line number and a
-- column number. @SourcePos@ is an instance of the 'Show', 'Eq' and 'Ord'
-- class.
2015-07-29 11:38:32 +03:00
data SourcePos = SourcePos
{ -- | Extract the name of the source from a source position.
sourceName :: SourceName
-- | Extract the line number from a source position.
, sourceLine :: !Line
-- | Extract the column number from a source position.
, sourceColumn :: !Column }
deriving (Eq, Ord, Data, Typeable)
instance Show SourcePos where
show (SourcePos n l c)
| null n = showLC
| otherwise = "\"" ++ n ++ "\" " ++ showLC
where showLC = "line " ++ show l ++ ", column " ++ show c
2008-01-13 20:53:15 +03:00
-- | Create a new 'SourcePos' with the given source name,
-- line number and column number.
2008-01-13 20:53:15 +03:00
newPos :: SourceName -> Line -> Column -> SourcePos
2015-07-28 16:32:19 +03:00
newPos = SourcePos
2008-01-13 20:53:15 +03:00
-- | Create a new 'SourcePos' with the given source name,
-- and line number and column number set to 1, the upper left.
2008-01-13 20:53:15 +03:00
initialPos :: SourceName -> SourcePos
2015-07-29 11:38:32 +03:00
initialPos name = newPos name 1 1
2015-07-29 11:38:32 +03:00
-- | Increment the line number of a source position.
2008-01-13 20:53:15 +03:00
incSourceLine :: SourcePos -> Line -> SourcePos
2015-07-29 11:38:32 +03:00
incSourceLine (SourcePos n l c) d = SourcePos n (l + d) c
2008-01-13 20:53:15 +03:00
2015-07-28 16:32:19 +03:00
-- | Increments the column number of a source position.
2008-01-13 20:53:15 +03:00
incSourceColumn :: SourcePos -> Column -> SourcePos
2015-07-29 11:38:32 +03:00
incSourceColumn (SourcePos n l c) d = SourcePos n l (c + d)
2008-01-13 20:53:15 +03:00
-- | Set the name of the source.
2008-01-13 20:53:15 +03:00
setSourceName :: SourcePos -> SourceName -> SourcePos
2015-07-29 11:38:32 +03:00
setSourceName (SourcePos _ l c) n = SourcePos n l c
2008-01-13 20:53:15 +03:00
2015-07-28 16:32:19 +03:00
-- | Set the line number of a source position.
2008-01-13 20:53:15 +03:00
setSourceLine :: SourcePos -> Line -> SourcePos
2015-07-29 11:38:32 +03:00
setSourceLine (SourcePos n _ c) l = SourcePos n l c
2008-01-13 20:53:15 +03:00
2015-07-28 16:32:19 +03:00
-- | Set the column number of a source position.
2008-01-13 20:53:15 +03:00
setSourceColumn :: SourcePos -> Column -> SourcePos
2015-07-29 11:38:32 +03:00
setSourceColumn (SourcePos n l _) = SourcePos n l
2008-01-13 20:53:15 +03:00
-- | Update a source position given a character. If the character is a
-- newline (\'\\n\') the line number is incremented by 1. If the character
-- is carriage return (\'\\r\') the line number is unaltered, but column
-- number is reset to 1. If the character is a tab (\'\\t\') the column
-- number is incremented to the nearest 8'th column, i.e. @column + 8 -
-- ((column - 1) \`rem\` 8)@. In all other cases, the column is incremented
-- by 1.
2015-07-29 11:38:32 +03:00
updatePosChar :: SourcePos -> Char -> SourcePos
updatePosChar (SourcePos n l c) ch =
case ch of
'\n' -> SourcePos n (l + 1) 1
'\r' -> SourcePos n l 1
'\t' -> SourcePos n l (c + 8 - ((c - 1) `rem` 8))
2015-07-29 11:38:32 +03:00
_ -> SourcePos n l (c + 1)
-- | The expression @updatePosString pos s@ updates the source position
-- @pos@ by calling 'updatePosChar' on every character in @s@, i.e. @foldl
-- updatePosChar pos string@.
updatePosString :: SourcePos -> String -> SourcePos
updatePosString = foldl' updatePosChar