module TreeSitter.Parser
( Parser
, withParser
, withParseTree
, ts_parser_new
, ts_parser_halt_on_error
, ts_parser_parse_string
, ts_parser_delete
, ts_parser_set_language
, ts_parser_timeout_micros
, ts_parser_set_timeout_micros
, ts_parser_log_to_stderr
) where

import Control.Exception as Exc
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Foreign
import Foreign.C
import TreeSitter.Language
import TreeSitter.Tree

-- | A tree-sitter parser.
--
--   This type is uninhabited and used only for type safety within 'Ptr' values.
data Parser

withParser :: Ptr Language -> (Ptr Parser -> IO a) -> IO a
withParser :: forall a. Ptr Language -> (Ptr Parser -> IO a) -> IO a
withParser Ptr Language
language Ptr Parser -> IO a
action = IO (Ptr Parser)
-> (Ptr Parser -> IO ()) -> (Ptr Parser -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
Exc.bracket
  IO (Ptr Parser)
ts_parser_new
  Ptr Parser -> IO ()
ts_parser_delete
  ((Ptr Parser -> IO a) -> IO a) -> (Ptr Parser -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \ Ptr Parser
parser -> do
    Bool
_ <- Ptr Parser -> Ptr Language -> IO Bool
ts_parser_set_language Ptr Parser
parser Ptr Language
language
    Ptr Parser -> IO a
action Ptr Parser
parser

withParseTree :: Ptr Parser -> ByteString -> (Ptr Tree -> IO a) -> IO a
withParseTree :: forall a. Ptr Parser -> ByteString -> (Ptr Tree -> IO a) -> IO a
withParseTree Ptr Parser
parser ByteString
bytestring Ptr Tree -> IO a
action =
  ByteString -> (CStringLen -> IO a) -> IO a
forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen ByteString
bytestring ((CStringLen -> IO a) -> IO a) -> (CStringLen -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \ (Ptr CChar
source, Int
len) -> IO (Ptr Tree) -> (Ptr Tree -> IO ()) -> (Ptr Tree -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
Exc.bracket
    (Ptr Parser -> Ptr Tree -> Ptr CChar -> Int -> IO (Ptr Tree)
ts_parser_parse_string Ptr Parser
parser Ptr Tree
forall a. Ptr a
nullPtr Ptr CChar
source Int
len)
    Ptr Tree -> IO ()
releaseTree
    Ptr Tree -> IO a
action
  where releaseTree :: Ptr Tree -> IO ()
releaseTree Ptr Tree
t
          | Ptr Tree
t Ptr Tree -> Ptr Tree -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr Tree
forall a. Ptr a
nullPtr = () -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
          | Bool
otherwise    = Ptr Tree -> IO ()
ts_tree_delete Ptr Tree
t

foreign import ccall safe "ts_parser_new" ts_parser_new :: IO (Ptr Parser)
foreign import ccall safe "ts_parser_halt_on_error" ts_parser_halt_on_error :: Ptr Parser -> CBool -> IO ()
foreign import ccall safe "ts_parser_parse_string" ts_parser_parse_string :: Ptr Parser -> Ptr Tree -> CString -> Int -> IO (Ptr Tree)
foreign import ccall safe "ts_parser_delete" ts_parser_delete :: Ptr Parser -> IO ()
foreign import ccall safe "ts_parser_set_language" ts_parser_set_language :: Ptr Parser -> Ptr Language -> IO Bool
foreign import ccall safe "ts_parser_timeout_micros" ts_parser_timeout_micros :: Ptr Parser -> IO Word64
foreign import ccall safe "ts_parser_set_timeout_micros" ts_parser_set_timeout_micros :: Ptr Parser -> Word64 -> IO ()

foreign import ccall safe "src/bridge.c ts_parser_log_to_stderr" ts_parser_log_to_stderr :: Ptr Parser -> IO ()