module UU.Scanner.Position where
type Line = Int
type Column = Int
type Filename = String
class Position p where
line :: p -> Line
column :: p -> Column
file :: p -> Filename
instance Position Pos where
line (Pos l _ _) = l
column (Pos _ c _) = c
file (Pos _ _ f) = f
data Pos = Pos !Line !Column Filename
instance Show Pos where
show (Pos l c f) | l == (1) = ""
| otherwise = let file = if null f then "" else show f
lc = "(line " ++ show l ++ ", column " ++ show c ++")"
in file ++ lc
initPos :: FilePath -> Pos
initPos fn = Pos 1 1 fn
noPos :: Pos
noPos = Pos (1) (1) ""
advl :: Line -> Pos ->Pos
advl i (Pos l c f) = (Pos (l+i) 1 f)
advc :: Column -> Pos -> Pos
advc i (Pos l c f) = (Pos l (c+i) f)
adv :: Pos -> Char -> Pos
adv pos c = case c of
'\t' -> advc (tabWidth (column pos)) pos
'\n' -> advl 1 pos
_ -> advc 1 pos
updPos :: Char -> Pos -> Pos
updPos x = case x of
'\n' -> newl
'\t' -> tab
_ -> advc 1
tab :: Pos -> Pos
tab (Pos l c f) = Pos l (c+tabWidth c) f
newl :: Pos ->Pos
newl = advl 1
tabWidth :: Column -> Int
tabWidth c = 8 ((c1) `mod` 8)
updPos' :: Char -> Pos -> (Pos -> a) -> a
updPos' c p cont = p `seq` cont (updPos c p)
advc' :: Int -> Pos -> (Pos -> a) -> a
advc' i p cont = p `seq` cont (advc i p)
tab' :: Pos -> (Pos -> a) -> a
tab' p cont = p `seq` cont (tab p)
newl' :: Pos -> (Pos -> a) -> a
newl' p cont = p `seq` cont (newl p)