    {-# LANGUAGE  MagicHash,
                  UnboxedTuples,
                  ScopedTypeVariables #-}

    module UU.Parsing.CharParser where
    import GHC.Prim
    import UU.Parsing.Interface
    import UU.Scanner.Position

    type CharParser = AnaParser Input Pair Char Pos

    instance Symbol Char where
     symBefore    = pred
     symAfter     = succ
     deleteCost _ = 5#

    data Input = Input String !Pos

    instance InputState Input Char Pos where
      splitStateE (Input inp pos) =
            case inp of
              ('\CR':      xs) -> case xs of
                                    ('\LF' : _ ) -> Left' '\CR' (Input xs pos)
                                    _            -> Left' '\CR' (Input xs (newl pos))
              ('\LF':      xs) -> Left' '\LF' (Input xs (newl   pos))
    --          ('\n' :      xs) -> Left' '\n'  (Input xs (newl pos))  -- \n already captured above
              ('\t' :      xs) -> Left' '\t' (Input xs (tab    pos))
              (x    :      xs) -> Left' x    (Input xs (advc 1 pos))
              []               -> Right'     (Input [] pos)

      splitState  (Input inp pos) =
            case inp of
              ('\CR':      xs) -> case xs of
                                    ('\LF' : _ ) -> (# '\CR', Input xs pos #)
                                    _            -> (# '\CR', Input xs (newl pos) #)
              ('\LF':      xs) -> (# '\LF', Input xs (newl   pos) #)
    --          ('\n' :      xs) -> ( '\n' , Input xs (newl   pos)) -- \n already captured above
              ('\t' :      xs) -> (# '\t' , Input xs (tab    pos) #)
              (x    :      xs) -> (# x    , Input xs (advc 1 pos) #)

      getPosition (Input inp pos) = pos

    parseString :: CharParser a
                -> [Char]
                -> Steps (Pair a (Pair Input ())) Char Pos
    parseString p txt = parse p ((Input txt (initPos "")))

    parseStringIO :: (Message Char Pos -> String)
                  -> CharParser a
                  -> [Char]
                  -> IO a
    parseStringIO showM p txt = parseIOMessage showM p (Input txt (initPos ""))

    parseFile :: (Message Char Pos -> String) -> CharParser a -> [Char] -> IO a
    parseFile showM p filename = do txt <- readFile filename
                                    parseIOMessage showM p (Input txt (initPos filename))