module BEncode.BLexer where

import Data.Char

import qualified Data.FastPackedString as FS
import Data.FastPackedString (FastString)

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


lexer :: FastString -> [Token]
lexer fs | FS.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') = FS.span isDigit rest
                   number = read (FS.unpack digits)
               in TNumber (-number) : lexer rest'
        _ | isDigit ch
              -> let (digits,rest') = FS.span isDigit fs
                     number = read (FS.unpack digits)
                 in if FS.null rest'
                       then [TNumber number]
                       else case FS.unsafeHead rest' of
                              ':' -> let (str, rest'') = FS.splitAt number (FS.unsafeTail rest')
                                     in TString str : lexer rest''
                              _ -> TNumber number : lexer rest'
          | otherwise -> error "Lexer error."
    where ch = FS.unsafeHead fs
          rest = FS.unsafeTail fs

