summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-03-21 20:27:33 -0400
committerJoe Crayne <joe@jerkface.net>2019-03-21 20:27:33 -0400
commitee6ab44b37c184aef0b8260aad3b345fb2c41db7 (patch)
treecc33e2eceb9688935a272bb5e62ab985ed31a181
parentcde705a95f6456a8c91428fd4a2c5be18666bbee (diff)
Represent comments as functions.
-rw-r--r--monkeypatch.hs105
1 files changed, 96 insertions, 9 deletions
diff --git a/monkeypatch.hs b/monkeypatch.hs
index ea97252..8646b5b 100644
--- a/monkeypatch.hs
+++ b/monkeypatch.hs
@@ -28,6 +28,7 @@ import Data.Ord
28import qualified Data.Set as Set 28import qualified Data.Set as Set
29 ;import Data.Set (Set) 29 ;import Data.Set (Set)
30import Language.C.Data.Ident as C 30import Language.C.Data.Ident as C
31import Language.C.Data.Node as C
31import Language.C as C hiding (prettyUsingInclude) 32import Language.C as C hiding (prettyUsingInclude)
32import qualified Language.C as C 33import qualified Language.C as C
33import Language.C.System.GCC 34import Language.C.System.GCC
@@ -505,6 +506,36 @@ getSymbolExtent sym bdy =
505 stop = maximumBy (comparing posRow) allposss 506 stop = maximumBy (comparing posRow) allposss
506 in SymbolExtent start stop 507 in SymbolExtent start stop
507 508
509lastRowOf x = case getLastTokenPos $ nodeInfo x of
510 (p,len) | isSourcePos p -> posRow p + len
511 _ -> maxBound
512
513firstRowOf x = case posOfNode $ nodeInfo x of
514 p | isSourcePos p -> posRow p
515 _ -> minBound
516
517columnOf x = case posOfNode $ nodeInfo x of
518 p | isSourcePos p -> posColumn p
519 _ -> minBound
520
521comesBefore x c = lastRowOf x < commentRow c
522
523comesAfter x c = firstRowOf x > commentRow c
524
525insertComment :: Data t => StyledComment -> t -> t
526insertComment c stmts = everywhere (mkT go) stmts
527 where
528 go :: [CCompoundBlockItem NodeInfo] -> [CCompoundBlockItem NodeInfo]
529 go xs = case span (\a -> comesBefore a c) xs of
530 (a:as,b:bs) | b `comesAfter` c -> a:as ++ mkst c ++ b:bs
531 ([],b:bs) | commentRow c + 1 == firstRowOf b -> mkst c ++ b : bs
532 (as,[]) | (y:ys) <- reverse as, lastRowOf y + 1 == commentRow c -> as ++ mkst c
533 _ -> xs
534
535 mkst c = let x = rewriteComment c in [CBlockStmt (CExpr (Just x) $ nodeInfo x)]
536
537mixComments :: [StyledComment] -> [CCompoundBlockItem NodeInfo] -> [CCompoundBlockItem NodeInfo]
538mixComments cs stmts = foldr insertComment stmts cs
508 539
509transpile :: C2HaskellOptions -> FilePath -> IncludeStack -> CTranslationUnit NodeInfo -> IO () 540transpile :: C2HaskellOptions -> FilePath -> IncludeStack -> CTranslationUnit NodeInfo -> IO ()
510transpile o fname incs (CTranslUnit edecls _) = do 541transpile o fname incs (CTranslUnit edecls _) = do
@@ -533,7 +564,14 @@ transpile o fname incs (CTranslUnit edecls _) = do
533 putStrLn . HS.prettyPrint $ changeType makeFunctionUseIO hh 564 putStrLn . HS.prettyPrint $ changeType makeFunctionUseIO hh
534 putStrLn $ unwords (hname:as) ++ " =" 565 putStrLn $ unwords (hname:as) ++ " ="
535 forM_ mprintHeader $ \printHeader -> do 566 forM_ mprintHeader $ \printHeader -> do
536 let bdy = concat $ take 1 $ dropWhile null $ map body $ symbolSource sym 567 let bdy0 = concat $ take 1 $ dropWhile null $ map body $ symbolSource sym
568
569 let extent = getSymbolExtent sym bdy0
570 cs0 <- readComments (posFile $ startExtent extent) -- TODO: Avoid parsing the same file multiple times.
571 let (_,cs1) = seekComment (startExtent extent) cs0
572 (cs,_ ) = seekComment (stopExtent extent) cs1
573 bdy = mixComments (map reflowComment cs) bdy0
574
537 if oPrettyTree o 575 if oPrettyTree o
538 then do printHeader 576 then do printHeader
539 forM_ bdy $ \d -> putStrLn $ ppShow $ cleanTree d 577 forM_ bdy $ \d -> putStrLn $ ppShow $ cleanTree d
@@ -555,15 +593,20 @@ transpile o fname incs (CTranslUnit edecls _) = do
555 593
556 Nothing -> putStrLn $ "??: " ++ ppShow (cleanTree d) 594 Nothing -> putStrLn $ "??: " ++ ppShow (cleanTree d)
557 putStrLn "" 595 putStrLn ""
558 let extent = getSymbolExtent sym bdy
559 cs <- readComments (posFile $ startExtent extent)
560 let (pcs,cs') = seekComment (startExtent extent) cs
561 (cs'',ds) = seekComment (stopExtent extent) cs'
562 -- lineOfComment
563 forM_ cs' $ \(_,col,cmt) -> do
564 putStrLn ""
565 putStrLn $ replicate col ' ' ++ cmt
566 print extent 596 print extent
597 {-
598 -- Display comments as c functions.
599 forM_ cs $ \c@(_,col,cmt) -> do
600 putStrLn ""
601 let cc = reflowComment c
602 putStrLn $ replicate col ' ' ++ show (commentRow cc,commentCol cc) ++ show (pretty $ rewriteComment cc)
603 -- putStrLn $ replicate col ' ' ++ cmt
604
605 putStrLn "\n{"
606 forM_ bdy $ \x ->
607 putStrLn $ {- show (firstRowOf x,lastRowOf x) ++ " " ++ -} (show . pretty $ x)
608 putStrLn "}"
609 -}
567 return () 610 return ()
568 611
569isHeaderDecl :: CNode a => a -> Bool 612isHeaderDecl :: CNode a => a -> Bool
@@ -855,6 +898,7 @@ data C2HaskellOptions = C2HaskellOptions
855 , oVerbose :: Bool 898 , oVerbose :: Bool
856 , oPreprocess :: Bool 899 , oPreprocess :: Bool
857 , oTranspile :: Bool 900 , oTranspile :: Bool
901 , oCommentsOnly :: Bool
858 } 902 }
859 903
860defopts :: C2HaskellOptions 904defopts :: C2HaskellOptions
@@ -865,6 +909,7 @@ defopts = C2HaskellOptions
865 , oVerbose = False 909 , oVerbose = False
866 , oPreprocess = False 910 , oPreprocess = False
867 , oTranspile = False 911 , oTranspile = False
912 , oCommentsOnly = False
868 } 913 }
869 914
870parseOptions :: [String] -> C2HaskellOptions -> C2HaskellOptions 915parseOptions :: [String] -> C2HaskellOptions -> C2HaskellOptions
@@ -875,6 +920,7 @@ parseOptions ("-p":args) o = parseOptions args o{ oPrettyC = True }
875parseOptions ("--cpp":args) o = parseOptions args o{ oPreprocess = True } 920parseOptions ("--cpp":args) o = parseOptions args o{ oPreprocess = True }
876parseOptions ("-v":args) o = parseOptions args o{ oVerbose = True } 921parseOptions ("-v":args) o = parseOptions args o{ oVerbose = True }
877parseOptions ("--tohs":args) o = parseOptions args o{ oTranspile = True } 922parseOptions ("--tohs":args) o = parseOptions args o{ oTranspile = True }
923parseOptions ("--comments":args) o = parseOptions args o{ oCommentsOnly = True }
878parseOptions as o = error (show as) 924parseOptions as o = error (show as)
879 925
880 926
@@ -1392,6 +1438,42 @@ goMissing haskmod db cfun = do
1392 htyp -> hPutStr haskmod $ commented $ "Unsupported haskell type: " ++ HS.prettyPrint htyp 1438 htyp -> hPutStr haskmod $ commented $ "Unsupported haskell type: " ++ HS.prettyPrint htyp
1393 1439
1394 1440
1441-- Represent a comment as a C function call, so that it can be preserved in
1442-- syntax tree manipulations.
1443rewriteComment :: StyledComment -> CExpression NodeInfo
1444rewriteComment c = C.CCall (CVar (internalIdent "__cmt") ni)
1445 [ CConst (CIntConst (cInteger $ fromIntegral $ fromEnum (commentStyle c)) ni)
1446 , CConst (CStrConst (cString $ styledComment c) ni) ]
1447 ni
1448
1449 where
1450 ni = mkNodeInfoOnlyPos $ position 0 "" (commentRow c) (commentCol c) Nothing
1451
1452data CommentStyle = VanillaComment | StarBarComment
1453 deriving (Eq,Ord,Enum,Show)
1454
1455data StyledComment = StyledComment
1456 { styledComment :: String
1457 , commentStyle :: CommentStyle
1458 , commentRow :: Int
1459 , commentCol :: Int
1460 }
1461 deriving (Eq,Ord,Show)
1462
1463reflowComment :: (Int,Int,String) -> StyledComment
1464reflowComment (row,col,s) = StyledComment s' (if allstar then StarBarComment else VanillaComment) row col
1465 where
1466 xs = map (reverse . dropWhile isSpace . reverse) $ lines s
1467 ys = reverse $ dropWhile (null . snd) $ reverse $ map (span isSpace) xs
1468 countCols '\t' = 8
1469 countCols _ = 1
1470 starred (sp,'*':_) = sum (map countCols sp) == col
1471 starred _ = False
1472 allstar = all starred (drop 1 ys)
1473 unstar (_,'*':xs) | allstar = dropWhile isSpace xs
1474 unstar (_,x) = x
1475 s' = unwords $ map unstar ys
1476
1395readComments :: Num lin => FilePath -> IO [(lin, Int, [Char])] 1477readComments :: Num lin => FilePath -> IO [(lin, Int, [Char])]
1396readComments fname = grepCComments 1 1 <$> readFile fname 1478readComments fname = grepCComments 1 1 <$> readFile fname
1397 1479
@@ -1512,6 +1594,11 @@ main = do
1512 -- putStrLn $ "includes = " ++ ppShow (fmap fst r) 1594 -- putStrLn $ "includes = " ++ ppShow (fmap fst r)
1513 -- cs <- readComments fname 1595 -- cs <- readComments fname
1514 case () of 1596 case () of
1597 _ | oCommentsOnly hopts
1598 -> do cs <- readComments fname
1599 forM_ cs $ \c -> do
1600 putStrLn $ show c
1601 putStrLn $ show (reflowComment c)
1515 _ | oPreprocess hopts -- --cpp 1602 _ | oPreprocess hopts -- --cpp
1516 -> case prer of 1603 -> case prer of
1517 Left e -> print e 1604 Left e -> print e