1
1
mirror of https://github.com/github/semantic.git synced 2024-12-25 07:55:12 +03:00

Operate strictly recursively.

This means we’re ensured of using allocations solely within the scopes
in which they are valid.
This commit is contained in:
Rob Rix 2015-11-26 16:07:04 -05:00
parent 19818231f5
commit 018f4dcbd5

View File

@ -70,41 +70,46 @@ parseTreeSitterFile file = do
source <- newCString contents source <- newCString contents
ts_document_set_input_string document source ts_document_set_input_string document source
ts_document_parse document ts_document_parse document
alloca (\root -> do term <- parse document contents
ts_document_root_node_p document root
unfoldM (toTerm document contents) root)
ts_document_free document ts_document_free document
free source free source
putStrLn $ "hooray" putStrLn $ "hooray"
toTerm :: Ptr TSDocument -> String -> Ptr TSNode -> IO (Info, Syntax String (Ptr TSNode)) parse :: Ptr TSDocument -> String -> IO (Term String Info)
toTerm document contents node = do parse document contents = do
name <- ts_node_p_name node document alloca unpack where
name <- peekCString name unpack root = do
children <- namedChildren node ts_document_root_node_p document root
range <- range node toTerm root
annotation <- return . Info range $ Data.Set.fromList [ name ] toTerm :: Ptr TSNode -> IO (Term String Info)
return (annotation, case children of toTerm node = do
[] -> Leaf $ substring range contents name <- ts_node_p_name node document
_ | Data.Set.member name fixedProductions -> Fixed children name <- peekCString name
_ | otherwise -> Indexed children) children <- withNamedChildren node toTerm
where range <- range node
keyedProductions = Data.Set.fromList [ "object" ] annotation <- return . Info range $ Data.Set.fromList [ name ]
fixedProductions = Data.Set.fromList [ "pair", "rel_op", "math_op", "bool_op", "bitwise_op", "type_op", "math_assignment", "assignment", "subscript_access", "member_access", "new_expression", "function_call", "function", "ternary" ] return $ annotation :< case children of
[] -> Leaf $ substring range contents
_ | Data.Set.member name fixedProductions -> Fixed children
_ | otherwise -> Indexed children
keyedProductions = Data.Set.fromList [ "object" ]
fixedProductions = Data.Set.fromList [ "pair", "rel_op", "math_op", "bool_op", "bitwise_op", "type_op", "math_assignment", "assignment", "subscript_access", "member_access", "new_expression", "function_call", "function", "ternary" ]
withAlloc :: Storable a => (Ptr a -> IO b) -> IO b withAlloc :: Storable a => (Ptr a -> IO b) -> IO b
withAlloc writeTo = do withAlloc writeTo = do
bytes <- malloc bytes <- malloc
writeTo bytes writeTo bytes
namedChildren :: Ptr TSNode -> IO [Ptr TSNode] withNamedChildren :: Ptr TSNode -> (Ptr TSNode -> IO a) -> IO [a]
namedChildren node = do withNamedChildren node f = do
count <- ts_node_p_named_child_count node count <- ts_node_p_named_child_count node
if count == 0 if count == 0
then return [] then return []
else mapM (withAlloc . getChild) [0..pred count] where else mapM (withAlloc . getChild f) [0..pred count] where
getChild n out = do getChild f n out = do
ts_node_p_named_child node n out ts_node_p_named_child node n out
out <- f out
return out return out
range :: Ptr TSNode -> IO Range range :: Ptr TSNode -> IO Range