    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 -> Column
    line   (Pos l :: Column
    l _ _) = Column
    l
       column :: Pos -> Column
    column (Pos _ c :: Column
    c _) = Column
    c
       file :: Pos -> Filename
    file   (Pos _ _ f :: Filename
    f) = Filename
    f

    data Pos = Pos !Line !Column Filename

    instance Show Pos where
      show :: Pos -> Filename
    show (Pos l :: Column
    l c :: Column
    c f :: Filename
    f) | Column
    l Column -> Column -> Bool
    forall a. Eq a => a -> a -> Bool
    == (-1) = ""
                       | Bool
    otherwise = let file :: Filename
    file = if Filename -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null Filename
    f then "" else ShowS
    forall a. Show a => a -> Filename
    show Filename
    f
                                         lc :: Filename
    lc = "(line " Filename -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Column -> Filename
    forall a. Show a => a -> Filename
    show Column
    l Filename -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ", column " Filename -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Column -> Filename
    forall a. Show a => a -> Filename
    show Column
    c Filename -> ShowS
    forall a. [a] -> [a] -> [a]
    ++")"
                                     in Filename
    file Filename -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Filename
    lc
    initPos :: FilePath -> Pos
    initPos :: Filename -> Pos
    initPos fn :: Filename
    fn = Column -> Column -> Filename -> Pos
    Pos 1 1 Filename
    fn

    noPos :: Pos
    noPos :: Pos
    noPos = Column -> Column -> Filename -> Pos
    Pos (-1) (-1) ""

    advl ::  Line -> Pos ->Pos
    advl :: Column -> Pos -> Pos
    advl i :: Column
    i (Pos l :: Column
    l c :: Column
    c f :: Filename
    f) = (Column -> Column -> Filename -> Pos
    Pos (Column
    lColumn -> Column -> Column
    forall a. Num a => a -> a -> a
    +Column
    i) 1 Filename
    f)

    advc :: Column -> Pos ->  Pos
    advc :: Column -> Pos -> Pos
    advc i :: Column
    i (Pos l :: Column
    l c :: Column
    c f :: Filename
    f) = (Column -> Column -> Filename -> Pos
    Pos Column
    l (Column
    cColumn -> Column -> Column
    forall a. Num a => a -> a -> a
    +Column
    i) Filename
    f)

    adv :: Pos -> Char -> Pos
    adv :: Pos -> Char -> Pos
    adv pos :: Pos
    pos c :: Char
    c = case Char
    c of
      '\t' -> Column -> Pos -> Pos
    advc (Column -> Column
    tabWidth (Pos -> Column
    forall p. Position p => p -> Column
    column Pos
    pos)) Pos
    pos
      '\n' -> Column -> Pos -> Pos
    advl 1 Pos
    pos
      _    -> Column -> Pos -> Pos
    advc 1 Pos
    pos

    updPos :: Char -> Pos -> Pos
    updPos :: Char -> Pos -> Pos
    updPos x :: Char
    x = case Char
    x of
     '\n' -> Pos -> Pos
    newl
     '\t' -> Pos -> Pos
    tab
     _    -> Column -> Pos -> Pos
    advc 1

    tab              :: Pos -> Pos
    tab :: Pos -> Pos
    tab  (Pos l :: Column
    l c :: Column
    c f :: Filename
    f) =  Column -> Column -> Filename -> Pos
    Pos Column
    l (Column
    cColumn -> Column -> Column
    forall a. Num a => a -> a -> a
    +Column -> Column
    tabWidth Column
    c) Filename
    f

    newl :: Pos ->Pos
    newl :: Pos -> Pos
    newl =  Column -> Pos -> Pos
    advl 1

    tabWidth :: Column -> Int
    tabWidth :: Column -> Column
    tabWidth c :: Column
    c = 8 Column -> Column -> Column
    forall a. Num a => a -> a -> a
    - ((Column
    cColumn -> Column -> Column
    forall a. Num a => a -> a -> a
    -1) Column -> Column -> Column
    forall a. Integral a => a -> a -> a
    `mod` 8)

    updPos' :: Char -> Pos -> (Pos -> a) -> a
    updPos' :: Char -> Pos -> (Pos -> a) -> a
    updPos' c :: Char
    c p :: Pos
    p cont :: Pos -> a
    cont = Pos
    p Pos -> a -> a
    forall a b. a -> b -> b
    `seq` Pos -> a
    cont (Char -> Pos -> Pos
    updPos Char
    c Pos
    p)

    advc' :: Int -> Pos -> (Pos -> a) -> a
    advc' :: Column -> Pos -> (Pos -> a) -> a
    advc' i :: Column
    i p :: Pos
    p cont :: Pos -> a
    cont = Pos
    p Pos -> a -> a
    forall a b. a -> b -> b
    `seq` Pos -> a
    cont (Column -> Pos -> Pos
    advc Column
    i Pos
    p)

    tab' :: Pos -> (Pos -> a) -> a
    tab' :: Pos -> (Pos -> a) -> a
    tab'  p :: Pos
    p cont :: Pos -> a
    cont = Pos
    p Pos -> a -> a
    forall a b. a -> b -> b
    `seq` Pos -> a
    cont (Pos -> Pos
    tab Pos
    p)

    newl' :: Pos -> (Pos -> a) -> a
    newl' :: Pos -> (Pos -> a) -> a
    newl' p :: Pos
    p cont :: Pos -> a
    cont = Pos
    p Pos -> a -> a
    forall a b. a -> b -> b
    `seq` Pos -> a
    cont (Pos -> Pos
    newl Pos
    p)