1
1
mirror of https://github.com/github/semantic.git synced 2024-12-01 00:33:59 +03:00
semantic/app/Main.hs

133 lines
5.2 KiB
Haskell
Raw Normal View History

2015-11-18 01:44:16 +03:00
module Main where
import Diff
import Patch
import Term
import Syntax
import Control.Comonad.Cofree
2015-11-25 17:56:14 +03:00
import Control.Monad.Free hiding (unfoldM)
import Data.Map
2015-11-21 00:21:09 +03:00
import Data.Maybe
import Data.Set
2015-11-20 19:36:54 +03:00
import Language.Haskell.Parser
import Language.Haskell.Syntax
import System.Environment
2015-11-24 21:15:45 +03:00
import GHC.Generics
2015-11-25 00:40:47 +03:00
import GHC.Prim
2015-11-24 21:15:45 +03:00
import Foreign
2015-11-25 00:40:47 +03:00
import Foreign.C
2015-11-24 21:15:45 +03:00
import Foreign.CStorable
import Foreign.C.Types
2015-11-24 21:50:10 +03:00
import Foreign.C.String
2015-11-25 00:40:47 +03:00
import Foreign.ForeignPtr.Unsafe
2015-11-24 21:15:45 +03:00
data TSLanguage = TsLanguage deriving (Show, Eq, Generic, CStorable)
2015-11-25 18:06:14 +03:00
foreign import ccall "prototype/doubt-difftool/doubt-difftool-Bridging-Header.h ts_language_c" ts_language_c :: IO (Ptr TSLanguage)
2015-11-24 21:23:29 +03:00
data TSDocument = TsDocument deriving (Show, Eq, Generic, CStorable)
2015-11-25 18:06:14 +03:00
foreign import ccall "prototype/External/tree-sitter/include/tree_sitter/runtime.h ts_document_make" ts_document_make :: IO (Ptr TSDocument)
foreign import ccall "prototype/External/tree-sitter/include/tree_sitter/runtime.h ts_document_set_language" ts_document_set_language :: Ptr TSDocument -> Ptr TSLanguage -> IO ()
foreign import ccall "prototype/External/tree-sitter/include/tree_sitter/runtime.h ts_document_set_input_string" ts_document_set_input_string :: Ptr TSDocument -> CString -> IO ()
foreign import ccall "prototype/External/tree-sitter/include/tree_sitter/runtime.h ts_document_parse" ts_document_parse :: Ptr TSDocument -> IO ()
foreign import ccall "prototype/External/tree-sitter/include/tree_sitter/runtime.h ts_document_free" ts_document_free :: Ptr TSDocument -> IO ()
2015-11-24 21:23:29 +03:00
2015-11-24 22:35:40 +03:00
data TSLength = TsLength !CSize !CSize
2015-11-24 22:13:41 +03:00
deriving (Show, Eq, Generic, CStorable)
2015-11-25 00:39:31 +03:00
instance Storable TSLength where
alignment l = cAlignment l
sizeOf l = cSizeOf l
peek p = cPeek p
poke p l = cPoke p l
2015-11-25 18:06:14 +03:00
data TSNode = TsNode !(Ptr ()) !TSLength
2015-11-24 22:17:04 +03:00
deriving (Show, Eq, Generic, CStorable)
2015-11-25 00:39:42 +03:00
instance Storable TSNode where
alignment n = cAlignment n
sizeOf n = cSizeOf n
peek p = cPeek p
poke p n = cPoke p n
foreign import ccall "app/bridge.h ts_document_root_node_p" ts_document_root_node_p :: Ptr TSDocument -> Ptr TSNode -> IO ()
2015-11-25 20:24:07 +03:00
foreign import ccall "app/bridge.h ts_node_p_name" ts_node_p_name :: Ptr TSNode -> Ptr TSDocument -> IO CString
foreign import ccall "app/bridge.h ts_node_p_named_child_count" ts_node_p_named_child_count :: Ptr TSNode -> IO CSize
foreign import ccall "app/bridge.h ts_node_p_named_child" ts_node_p_named_child :: Ptr TSNode -> CSize -> Ptr TSNode -> IO CSize
foreign import ccall "app/bridge.h ts_node_p_pos_chars" ts_node_p_pos_chars :: Ptr TSNode -> IO CSize
foreign import ccall "app/bridge.h ts_node_p_size_chars" ts_node_p_size_chars :: Ptr TSNode -> IO CSize
2015-11-24 22:08:08 +03:00
2015-11-18 01:44:16 +03:00
main :: IO ()
2015-11-20 19:36:54 +03:00
main = do
2015-11-25 00:51:53 +03:00
args <- getArgs
let (a, b) = files args in do
a' <- parseTreeSitterFile a
b' <- parseTreeSitterFile b
return (a', b')
return ()
parseTreeSitterFile :: FilePath -> IO ()
parseTreeSitterFile file = do
2015-11-24 21:41:30 +03:00
document <- ts_document_make
2015-11-24 21:45:54 +03:00
language <- ts_language_c
2015-11-24 21:46:00 +03:00
ts_document_set_language document language
2015-11-25 00:51:53 +03:00
contents <- readFile file
source <- newCString contents
2015-11-24 21:51:21 +03:00
ts_document_set_input_string document source
2015-11-24 21:52:45 +03:00
ts_document_parse document
2015-11-25 23:05:10 +03:00
alloca (\root -> do
ts_document_root_node_p document root
unfoldM (toTerm document contents) (root, "program"))
ts_document_free document
2015-11-24 21:53:42 +03:00
free source
2015-11-25 19:12:16 +03:00
putStrLn $ "cSizeOf " ++ show (cSizeOf document)
toTerm :: Ptr TSDocument -> String -> (Ptr TSNode, String) -> IO (Info, Syntax String (Ptr TSNode, String))
toTerm document contents (node, category) = do
name <- ts_node_p_name node document
2015-11-25 20:06:21 +03:00
children <- namedChildren node
range <- range node
annotation <- return . Info range $ Data.Set.fromList [ category ]
case children of
2015-11-25 23:02:30 +03:00
[] -> return (annotation, Leaf $ substring range contents)
2015-11-25 23:17:40 +03:00
_ | Data.Set.member name fixedProductions -> do
2015-11-25 23:10:49 +03:00
children <- mapM nodeAndCategory children
return (annotation, Fixed children)
_ | otherwise -> do
2015-11-25 23:02:42 +03:00
children <- mapM nodeAndCategory children
return (annotation, Indexed children)
where
nodeAndCategory :: Ptr TSNode -> IO (Ptr TSNode, String)
nodeAndCategory node = do
name <- ts_node_p_name node document
name <- peekCString name
return (node, name)
2015-11-25 19:12:16 +03:00
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" ]
2015-11-20 19:36:54 +03:00
namedChildren :: Ptr TSNode -> IO [Ptr TSNode]
namedChildren node = do
count <- ts_node_p_named_child_count node
2015-11-25 23:05:10 +03:00
mapM (alloca . getChild) [0..count] where
getChild n out = do
ts_node_p_named_child node n out
return out
2015-11-25 20:51:11 +03:00
range :: Ptr TSNode -> IO Range
range node = do
pos <- ts_node_p_pos_chars node
size <- ts_node_p_size_chars node
return Range { start = fromEnum $ toInteger pos, end = (fromEnum $ toInteger pos) + (fromEnum $ toInteger size) }
2015-11-20 19:36:54 +03:00
parseModuleFile :: FilePath -> IO (ParseResult HsModule)
parseModuleFile file = do
contents <- readFile file
return $ parseModule contents
files (a : as) = (a, file as) where
file (a : as) = a
2015-11-24 21:40:07 +03:00
files [] = error "expected two files to diff"
2015-11-25 20:53:56 +03:00
substring :: Range -> String -> String
substring range = take (end range) . drop (start range)