module Data.BEncode.Lexer where

import Data.Char

import qualified Data.ByteString.Char8 as BS
import Data.ByteString (ByteString)

data Token
    = TDict
    | TList
    | TInt
    | TString ByteString
    | TNumber Int
    | TEnd
      deriving (Show,Eq)


lexer :: ByteString -> [Token]
lexer fs | BS.null fs = []
lexer fs
    = case ch of
        'd' -> TDict : lexer rest
        'l' -> TList : lexer rest
        'i' -> TInt  : lexer rest
        'e' -> TEnd  : lexer rest
        '-' -> let (digits,rest') = BS.span isDigit rest
                   number = read (BS.unpack digits)
               in TNumber (-number) : lexer rest'
        _ | isDigit ch
              -> let (digits,rest') = BS.span isDigit fs
                     number = read (BS.unpack digits)
                 in if BS.null rest'
                       then [TNumber number]
                       else case BS.head rest' of
                              ':' -> let (str, rest'') = BS.splitAt number (BS.tail rest')
                                     in TString str : lexer rest''
                              _ -> TNumber number : lexer rest'
          | otherwise -> error "Lexer error."
    where ch = BS.head fs
          rest = BS.tail fs