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

    data Pos = Pos !Line !Column Filename

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

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

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

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

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

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

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

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

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

    updPos' :: Char -> Pos -> (Pos -> a) -> a
    updPos' :: forall a. Char -> Pos -> (Pos -> a) -> a
    updPos' Char
    c Pos
    p 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' :: forall a. Int -> Pos -> (Pos -> a) -> a
    advc' Int
    i Pos
    p Pos -> a
    cont = Pos
    p Pos -> a -> a
    forall a b. a -> b -> b
    `seq` Pos -> a
    cont (Int -> Pos -> Pos
    advc Int
    i Pos
    p)

    tab' :: Pos -> (Pos -> a) -> a
    tab' :: forall a. Pos -> (Pos -> a) -> a
    tab'  Pos
    p 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' :: forall a. Pos -> (Pos -> a) -> a
    newl' Pos
    p Pos -> a
    cont = Pos
    p Pos -> a -> a
    forall a b. a -> b -> b
    `seq` Pos -> a
    cont (Pos -> Pos
    newl Pos
    p)