parsimony-1: src/Parsimony/Pos.hs
-----------------------------------------------------------------------------
-- |
-- Module : Parsimony.Pos
-- Copyright : (c) Daan Leijen 1999-2001
-- License : BSD3
--
-- Maintainer : iavor.diatchki@gmail.com
-- Stability : provisional
-- Portability : portable
--
-- Textual source positions.
--
-----------------------------------------------------------------------------
module Parsimony.Pos
( SourceName, Line, Column
, SourcePos
, sourceLine, sourceColumn, sourceName
, incSourceLine, incSourceColumn
, setSourceLine, setSourceColumn, setSourceName
, newPos, initialPos
, updatePosChar, updatePosString
) where
-----------------------------------------------------------
-- Source Positions, a file name, a line and a column.
-- upper left is (1,1)
-----------------------------------------------------------
type SourceName = String
type Line = Int
type Column = Int
data SourcePos = SourcePos { sourceName :: SourceName
, sourceLine :: !Line
, sourceColumn :: !Column
}
deriving (Eq,Ord)
newPos :: SourceName -> Line -> Column -> SourcePos
newPos name line column = SourcePos { sourceName = name
, sourceLine = line
, sourceColumn = column
}
initialPos :: SourceName -> SourcePos
initialPos name = newPos name 1 1
incSourceLine :: SourcePos -> Line -> SourcePos
incSourceLine p n = setSourceLine p (n + sourceLine p)
incSourceColumn :: SourcePos -> Column -> SourcePos
incSourceColumn p n = setSourceColumn p (n + sourceColumn p)
setSourceName :: SourcePos -> SourceName -> SourcePos
setSourceName p n = p { sourceName = n }
setSourceLine :: SourcePos -> Line -> SourcePos
setSourceLine p n = p { sourceLine = n }
setSourceColumn :: SourcePos -> Column -> SourcePos
setSourceColumn p n = p { sourceColumn = n }
-----------------------------------------------------------
-- Update source positions on characters
-----------------------------------------------------------
updatePosString :: SourcePos -> String -> SourcePos
updatePosString pos string
= forcePos (foldl updatePosChar pos string)
updatePosChar :: SourcePos -> Char -> SourcePos
updatePosChar p c
= forcePos $
case c of
'\n' -> incSourceLine p 1
'\t' -> incSourceColumn p (8 - ((sourceColumn p - 1) `mod` 8))
_ -> incSourceColumn p 1
forcePos :: SourcePos -> SourcePos
forcePos pos@(SourcePos _ line column)
= seq line (seq column (pos))
-----------------------------------------------------------
-- Show positions
-----------------------------------------------------------
instance Show SourcePos where
show (SourcePos name line column)
| null name = showLineColumn
| otherwise = "\"" ++ name ++ "\" " ++ showLineColumn
where
showLineColumn = "(line " ++ show line ++
", column " ++ show column ++
")"