-- GENERATED by C->Haskell Compiler, version 0.16.0 Crystal Seed, 24 Jan 2009 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "src/Text/Antlrc/Lexer.chs" #-}-- Copyright (c)2010-2011, Mark Wright.  All rights reserved.

{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Text.Antlrc.Lexer where


import C2HS
import Foreign.C.Types
import Foreign.Storable
import Ptr
import Foreign.Ptr
import System.IO.Unsafe
import Foreign.C
import Control.Monad
import Control.Applicative ((<$>))


{-# LINE 19 "src/Text/Antlrc/Lexer.chs" #-}

-- | Lexer token struct.
newtype CommonToken = CommonToken (Ptr (CommonToken))
{-# LINE 22 "src/Text/Antlrc/Lexer.chs" #-}

-- | Lexer input stream struct.
newtype InputStream = InputStream (Ptr (InputStream))
{-# LINE 25 "src/Text/Antlrc/Lexer.chs" #-}

-- | Lexer struct.
newtype Lexer = Lexer (Ptr (Lexer))
{-# LINE 28 "src/Text/Antlrc/Lexer.chs" #-}

-- | Cast from a pointer to an input stream to an input stream.
toInputStream :: Ptr InputStream -> InputStream
toInputStream = InputStream . castPtr

-- | Cast from a pointer to a token to a token.
toCommonToken :: Ptr CommonToken -> CommonToken
toCommonToken = CommonToken . castPtr

-- | Cast from a token to a pointer to a token.
fromCommonToken :: CommonToken -> Ptr b
fromCommonToken (CommonToken x) = castPtr x

-- The C function definitions are in lexerc.c
-- | Lookahead in the input stream at the token at the specified
--   positive offset, where:
--
-- > LT input 1 
--
--   is the current token.  Or a negative offset may be specified, where: 
--
-- > LT input (-1) 
--
--   is the previous token.
--
-- > foreign export ccall isUnsignedInt :: Ptr InputStream -> IO Bool
-- > isUnsignedInt input =
-- >   do token1 <- lT input 1 >>= tokenGetType
-- >      if token1 /= UNSIGNED
-- >        then return False
-- >        else 
-- >        do 
-- >          token2 <- lT input 2 >>= tokenGetType
-- >          return ((token2 /= CHAR) && (token2 /= SHORT) && (token2 /= LONG))
--
lT :: Ptr (InputStream) -> Int -> IO (Ptr (CommonToken))
lT a1 a2 =
  let {a1' = toInputStream a1} in 
  let {a2' = cIntConv a2} in 
  lT'_ a1' a2' >>= \res ->
  let {res' = fromCommonToken res} in
  return (res')
{-# LINE 70 "src/Text/Antlrc/Lexer.chs" #-}

-- | Pointer to an ANTLR string.
newtype AntlrString = AntlrString (Ptr (AntlrString))
{-# LINE 73 "src/Text/Antlrc/Lexer.chs" #-}

-- | Cast from an ANTLR string to a pointer to an ANTLR string.
fromAntlrString :: AntlrString -> Ptr b
fromAntlrString (AntlrString x) = castPtr x

-- | Obtain the token name ANTLR string for the specified token.
--
-- > tokenGetAntlrString token
--
--   For identifier tokens, the token string is interesting.  For
--   other tokens such as operator tokens, the token string is
--   uninteresting, and may not be present, the token identifier enum 
--   should be used instead.
tokenGetAntlrString :: Ptr (CommonToken) -> IO (Ptr (AntlrString))
tokenGetAntlrString a1 =
  let {a1' = toCommonToken a1} in 
  tokenGetAntlrString'_ a1' >>= \res ->
  let {res' = fromAntlrString res} in
  return (res')
{-# LINE 92 "src/Text/Antlrc/Lexer.chs" #-}

-- | Convert an ANTLR string to a Maybe String. 
fromAntlrStringToMaybeString :: AntlrString -> IO (Maybe String)
fromAntlrStringToMaybeString (AntlrString x) = 
  if x == Ptr.nullPtr
  then return Nothing
  else 
    (\ptr -> do {peekByteOff ptr 4 ::IO (Ptr CUChar)}) x >>= \c ->
    (\ptr -> do {peekByteOff ptr 8 ::IO CUInt}) x >>= \l ->
    peekCStringLen ((castPtr c), (fromIntegral l)) >>= \s ->
    return (Just s)

-- | Obtain the token Maybe String for the specified token.
--   For identifier tokens, the token string is interesting.  For
--   other tokens such as operator tokens, the token string is
--   uninteresting, and may not be present, the token identifier enum 
--   should be used instead.
tokenGetTextMaybe :: Ptr (CommonToken) -> IO (Maybe String)
tokenGetTextMaybe c =
  tokenGetAntlrString c >>= \s ->
  fromAntlrStringToMaybeString (AntlrString s)

-- | Convert from an ANTLR string to a String.
--   Note: the peekCStringLen function does not say what will happen if the
--   C pointer is 0.
fromAntlrStringToString :: AntlrString -> IO String
fromAntlrStringToString (AntlrString x) = 
  (\ptr -> do {peekByteOff ptr 4 ::IO (Ptr CUChar)}) x >>= \c ->
  (\ptr -> do {peekByteOff ptr 8 ::IO CUInt}) x >>= \l ->
  peekCStringLen ((castPtr c), (fromIntegral l)) >>= \s ->
  return s

-- | Obtain the token String for the specified token.
--   Note: the peekCStringLen function does not say what will happen if the
--   C pointer is 0.
--
-- > foreign export ccall saIntV :: Ptr CommonToken -> IO (StablePtr TermInfo)
-- > saIntV token =
-- >   do
-- >     -- read the IntV integer value from the token text into n
-- >     t <- tokenGetText token
-- >     n <- readIO t
-- >     -- obtain the source code line and charPosition from the token
-- >     l <- tokenGetLine token
-- >     c <- tokenGetCharPositionInLine token
-- >     -- return the term, which is TmZero, or TmSucc TmZero, or TmSucc (TmSucc (...TmSucc TmZero))
-- >     newStablePtr (intV (Info l c) n)
--
tokenGetText :: Ptr (CommonToken) -> IO String
tokenGetText c =
  tokenGetAntlrString c >>= \s ->
  fromAntlrStringToString (AntlrString s)

-- | Obtain the token identifier for the specified token.
--
-- > foreign export ccall isInt :: Ptr InputStream -> IO Bool
-- > isInt input =
-- >   do 
-- >     token1 <- lT input 1 >>= tokenGetType
-- >     return (token1 == INT)
--
tokenGetType :: (Enum e) => Ptr (CommonToken) -> IO e
tokenGetType token = (\ptr -> do {peekByteOff ptr 0 ::IO CUInt}) token >>= return . cToEnum

-- | Obtain the character position in the source code line of where the token
--   was read, for non-imaginary tokens.
--
-- > foreign export ccall saTrue :: Ptr CommonToken -> IO (StablePtr TermInfo)
-- > saTrue token =
-- >   do
-- >     -- obtain the source code line and charPosition from the token
-- >     l <- tokenGetLine token
-- >     c <- tokenGetCharPositionInLine token
-- >     -- return the TmTrue term
-- >     newStablePtr (TmTrue (Info l c))
--
tokenGetCharPositionInLine :: Ptr (CommonToken) -> IO Int
tokenGetCharPositionInLine token = (\ptr -> do {peekByteOff ptr 20 ::IO CInt}) token >>= return . cIntConv

-- | Obtain the the source code line of where the token was read, for non-imaginary tokens.
--
-- > foreign export ccall saFalse :: Ptr CommonToken -> IO (StablePtr TermInfo)
-- > saFalse token =
-- >   do
-- >     -- obtain the source code line and charPosition from the token
-- >     l <- tokenGetLine token
-- >     c <- tokenGetCharPositionInLine token
-- >     -- return the TmFalse term
-- >     newStablePtr (TmFalse (Info l c))
--
tokenGetLine :: Ptr (CommonToken) -> IO Int
tokenGetLine token = (\ptr -> do {peekByteOff ptr 12 ::IO CUInt}) token >>= return . cIntConv

foreign import ccall safe "Text/Antlrc/Lexer.chs.h LT"
  lT'_ :: ((InputStream) -> (CInt -> (IO (CommonToken))))

foreign import ccall safe "Text/Antlrc/Lexer.chs.h tokenGetAntlrString"
  tokenGetAntlrString'_ :: ((CommonToken) -> (IO (AntlrString)))