{-# Language TypeFamilies #-}
module Data.Source.Class where
import Data.Char

class Source src where
 type Location src      :: *
 type Element src       :: *
 type Token src         :: * 
 type Error src         :: *
 uncons         :: src -> Either (Error src) (Maybe (Element src,src))
 view           :: src -> (Error src -> a) -> a -> (Element src -> src -> a) -> a
 location       :: src -> Location src
 token          :: src -> src -> Token src
 offset         :: src -> Int

data ErrCode
 = Incomplete 
 | Conflicting
 | Unknown
 | Forbidden
 | Unimplemented
 deriving (Eq,Ord,Show,Read,Enum)

data SrcLoc
 = SrcLoc
 { src'name     :: String
 , src'line     :: Int
 , src'clmn     :: Int
 , src'offs     :: Int
 } deriving (Eq,Ord,Show,Read)

adjLoc :: Char -> SrcLoc -> SrcLoc
adjLoc ch
 | generalCategory ch `elem` [LineSeparator,ParagraphSeparator] = \(SrcLoc nm ln cl os) -> SrcLoc nm (ln+1) 0 (os+1)
 | otherwise                                                    = \(SrcLoc nm ln cl os) -> SrcLoc nm ln (cl+1) (os+1)

adjByted :: Int -> Char -> SrcLoc -> SrcLoc
adjByted i ch
 | generalCategory ch `elem` [LineSeparator,ParagraphSeparator] = \(SrcLoc nm ln cl os) -> SrcLoc nm (ln+1) 0 (os+i)
 | otherwise                                                    = \(SrcLoc nm ln cl os) -> SrcLoc nm ln (cl+1) (os+i)




