module Language.Haskell.Lexer.Utils
  ( module Language.Haskell.Lexer.Utils
  , Token(..)
  ) where

import Language.Haskell.Lexer.Tokens

gotEOF :: [a] -> [(Token,[a])]
gotEOF :: [a] -> [(Token, [a])]
gotEOF [] = []
gotEOF as :: [a]
as = [(Token
GotEOF, [a] -> [a]
forall a. [a] -> [a]
reverse [a]
as)]

gotError :: [a] -> [a] -> [(Token, [a])]
gotError :: [a] -> [a] -> [(Token, [a])]
gotError as :: [a]
as is :: [a]
is =
  (Token
ErrorToken, [a] -> [a]
forall a. [a] -> [a]
reverse [a]
as)(Token, [a]) -> [(Token, [a])] -> [(Token, [a])]
forall a. a -> [a] -> [a]
:
  if [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
is then [(Token
GotEOF,[])] else [(Token
TheRest,[a]
is{-reverse (take 80 is)-})]

-- Inlining the call to output does not make a big difference.
--output token as cont = (token, reverse as):cont

-- Not reversing the token string seems to save about 10% of the time with HBC.
-- The difference in speed seems insignificant with ghc-6.0.1 -O.

output :: t -> [a] -> [(t, [a])] -> [(t, [a])]
output :: t -> [a] -> [(t, [a])] -> [(t, [a])]
output token :: t
token as :: [a]
as cont :: [(t, [a])]
cont = (t
token,[a] -> [a]
forall a. [a] -> [a]
reverse [a]
as)(t, [a]) -> [(t, [a])] -> [(t, [a])]
forall a. a -> [a] -> [a]
:[(t, [a])]
cont

-- This avoids constructing a closure for the call to reverse.
-- This saves about 10% too.
{-
output token as cont =
    rev as []
  where
    rev [] as' = (token,as'):cont
    rev (a:as) as' = rev as (a:as')
--}

nestedComment :: [Char] -> [Char] -> (([a] -> [a] -> [(Token, [a])])
              -> [Char] -> [Char] -> [(Token, [Char])]) -> [(Token, [Char])]

nestedComment :: [Char]
-> [Char]
-> (([a] -> [a] -> [(Token, [a])])
    -> [Char] -> [Char] -> [(Token, [Char])])
-> [(Token, [Char])]
nestedComment as' :: [Char]
as' is' :: [Char]
is' next :: ([a] -> [a] -> [(Token, [a])])
-> [Char] -> [Char] -> [(Token, [Char])]
next = Int -> [Char] -> [Char] -> [(Token, [Char])]
forall a.
(Eq a, Num a) =>
a -> [Char] -> [Char] -> [(Token, [Char])]
nest (0::Int) [Char]
as' [Char]
is'
  where
    nest :: a -> [Char] -> [Char] -> [(Token, [Char])]
nest n :: a
n as :: [Char]
as is :: [Char]
is =
      case [Char]
is of
        '-' : '}' : is1 :: [Char]
is1   -> if a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== 0
                               then ([a] -> [a] -> [(Token, [a])])
-> [Char] -> [Char] -> [(Token, [Char])]
next [a] -> [a] -> [(Token, [a])]
forall a. [a] -> [a] -> [(Token, [a])]
gotError ('}'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:'-'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
as) [Char]
is1
                               else a -> [Char] -> [Char] -> [(Token, [Char])]
nest (a
na -> a -> a
forall a. Num a => a -> a -> a
-1) ('}'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:'-'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
as) [Char]
is1
        '{' : '-' : is1 :: [Char]
is1   -> a -> [Char] -> [Char] -> [(Token, [Char])]
nest (a
na -> a -> a
forall a. Num a => a -> a -> a
+1) ('-'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:'{'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
as) [Char]
is1
        c :: Char
c : is1 :: [Char]
is1           -> a -> [Char] -> [Char] -> [(Token, [Char])]
nest a
n (Char
cChar -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
as) [Char]
is1
        []                -> [Char] -> [Char] -> [(Token, [Char])]
forall a. [a] -> [a] -> [(Token, [a])]
gotError [Char]
as [Char]
is -- EOF inside comment