mirror of
https://github.com/mrkkrp/megaparsec.git
synced 2024-12-18 22:01:41 +03:00
131 lines
4.0 KiB
Haskell
131 lines
4.0 KiB
Haskell
-- |
|
||
-- Module : Text.MegaParsec.Pos
|
||
-- Copyright : © 1999–2001 Daan Leijen, © 2007 Paolo Martini, © 2015 MegaParsec contributors
|
||
-- License : BSD3
|
||
--
|
||
-- Maintainer : Mark Karpov <markkarpov@opmbx.org>
|
||
-- Stability : provisional
|
||
-- Portability : portable
|
||
--
|
||
-- Textual source positions.
|
||
|
||
module Text.MegaParsec.Pos
|
||
( SourceName
|
||
, Line
|
||
, Column
|
||
, SourcePos
|
||
, sourceLine
|
||
, sourceColumn
|
||
, sourceName
|
||
, incSourceLine
|
||
, incSourceColumn
|
||
, setSourceLine
|
||
, setSourceColumn
|
||
, setSourceName
|
||
, newPos
|
||
, initialPos
|
||
, updatePosChar
|
||
, updatePosString )
|
||
where
|
||
|
||
import Data.Data (Data)
|
||
import Data.Typeable (Typeable)
|
||
|
||
-- Source positions: a file name, a line and a column upper left is (1,1)
|
||
|
||
type SourceName = String
|
||
type Line = Int
|
||
type Column = Int
|
||
|
||
-- | The abstract data type @SourcePos@ represents source positions. It
|
||
-- 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.
|
||
|
||
data SourcePos = SourcePos SourceName !Line !Column
|
||
deriving ( Eq, Ord, Data, Typeable)
|
||
|
||
-- | Create a new 'SourcePos' with the given source name,
|
||
-- line number and column number.
|
||
|
||
newPos :: SourceName -> Line -> Column -> SourcePos
|
||
newPos = SourcePos
|
||
|
||
-- | Create a new 'SourcePos' with the given source name,
|
||
-- and line number and column number set to 1, the upper left.
|
||
|
||
initialPos :: SourceName -> SourcePos
|
||
initialPos name
|
||
= newPos name 1 1
|
||
|
||
-- | Extracts the name of the source from a source position.
|
||
|
||
sourceName :: SourcePos -> SourceName
|
||
sourceName (SourcePos name _line _column) = name
|
||
|
||
-- | Extracts the line number from a source position.
|
||
|
||
sourceLine :: SourcePos -> Line
|
||
sourceLine (SourcePos _name line _column) = line
|
||
|
||
-- | Extracts the column number from a source position.
|
||
|
||
sourceColumn :: SourcePos -> Column
|
||
sourceColumn (SourcePos _name _line column) = column
|
||
|
||
-- | Increments the line number of a source position.
|
||
|
||
incSourceLine :: SourcePos -> Line -> SourcePos
|
||
incSourceLine (SourcePos name line column) n = SourcePos name (line+n) column
|
||
|
||
-- | Increments the column number of a source position.
|
||
|
||
incSourceColumn :: SourcePos -> Column -> SourcePos
|
||
incSourceColumn (SourcePos name line column) n = SourcePos name line (column+n)
|
||
|
||
-- | Set the name of the source.
|
||
|
||
setSourceName :: SourcePos -> SourceName -> SourcePos
|
||
setSourceName (SourcePos _name line column) n = SourcePos n line column
|
||
|
||
-- | Set the line number of a source position.
|
||
|
||
setSourceLine :: SourcePos -> Line -> SourcePos
|
||
setSourceLine (SourcePos name _line column) n = SourcePos name n column
|
||
|
||
-- | Set the column number of a source position.
|
||
|
||
setSourceColumn :: SourcePos -> Column -> SourcePos
|
||
setSourceColumn (SourcePos name line _column) n = SourcePos name line n
|
||
|
||
-- | The expression @updatePosString pos s@ updates the source position
|
||
-- @pos@ by calling 'updatePosChar' on every character in @s@, ie.
|
||
-- @foldl updatePosChar pos string@.
|
||
|
||
updatePosString :: SourcePos -> String -> SourcePos
|
||
updatePosString pos string
|
||
= foldl updatePosChar pos string
|
||
|
||
-- | Update a source position given a character. If the character is a
|
||
-- newline (\'\\n\') or carriage return (\'\\r\') the line number is
|
||
-- incremented by 1. If the character is a tab (\'\t\') the column
|
||
-- number is incremented to the nearest 8'th column, ie. @column + 8 -
|
||
-- ((column-1) \`mod\` 8)@. In all other cases, the column is
|
||
-- incremented by 1.
|
||
|
||
updatePosChar :: SourcePos -> Char -> SourcePos
|
||
updatePosChar (SourcePos name line column) c
|
||
= case c of
|
||
'\n' -> SourcePos name (line+1) 1
|
||
'\t' -> SourcePos name line (column + 8 - ((column-1) `mod` 8))
|
||
_ -> SourcePos name line (column + 1)
|
||
|
||
instance Show SourcePos where
|
||
show (SourcePos name line column)
|
||
| null name = showLineColumn
|
||
| otherwise = "\"" ++ name ++ "\" " ++ showLineColumn
|
||
where
|
||
showLineColumn = "(line " ++ show line ++
|
||
", column " ++ show column ++
|
||
")"
|