diff options
author | Joe Crayne <joe@jerkface.net> | 2019-03-21 20:27:33 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-03-21 20:27:33 -0400 |
commit | ee6ab44b37c184aef0b8260aad3b345fb2c41db7 (patch) | |
tree | cc33e2eceb9688935a272bb5e62ab985ed31a181 | |
parent | cde705a95f6456a8c91428fd4a2c5be18666bbee (diff) |
Represent comments as functions.
-rw-r--r-- | monkeypatch.hs | 105 |
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 | |||
28 | import qualified Data.Set as Set | 28 | import qualified Data.Set as Set |
29 | ;import Data.Set (Set) | 29 | ;import Data.Set (Set) |
30 | import Language.C.Data.Ident as C | 30 | import Language.C.Data.Ident as C |
31 | import Language.C.Data.Node as C | ||
31 | import Language.C as C hiding (prettyUsingInclude) | 32 | import Language.C as C hiding (prettyUsingInclude) |
32 | import qualified Language.C as C | 33 | import qualified Language.C as C |
33 | import Language.C.System.GCC | 34 | import 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 | ||
509 | lastRowOf x = case getLastTokenPos $ nodeInfo x of | ||
510 | (p,len) | isSourcePos p -> posRow p + len | ||
511 | _ -> maxBound | ||
512 | |||
513 | firstRowOf x = case posOfNode $ nodeInfo x of | ||
514 | p | isSourcePos p -> posRow p | ||
515 | _ -> minBound | ||
516 | |||
517 | columnOf x = case posOfNode $ nodeInfo x of | ||
518 | p | isSourcePos p -> posColumn p | ||
519 | _ -> minBound | ||
520 | |||
521 | comesBefore x c = lastRowOf x < commentRow c | ||
522 | |||
523 | comesAfter x c = firstRowOf x > commentRow c | ||
524 | |||
525 | insertComment :: Data t => StyledComment -> t -> t | ||
526 | insertComment 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 | |||
537 | mixComments :: [StyledComment] -> [CCompoundBlockItem NodeInfo] -> [CCompoundBlockItem NodeInfo] | ||
538 | mixComments cs stmts = foldr insertComment stmts cs | ||
508 | 539 | ||
509 | transpile :: C2HaskellOptions -> FilePath -> IncludeStack -> CTranslationUnit NodeInfo -> IO () | 540 | transpile :: C2HaskellOptions -> FilePath -> IncludeStack -> CTranslationUnit NodeInfo -> IO () |
510 | transpile o fname incs (CTranslUnit edecls _) = do | 541 | transpile 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 | ||
569 | isHeaderDecl :: CNode a => a -> Bool | 612 | isHeaderDecl :: 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 | ||
860 | defopts :: C2HaskellOptions | 904 | defopts :: 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 | ||
870 | parseOptions :: [String] -> C2HaskellOptions -> C2HaskellOptions | 915 | parseOptions :: [String] -> C2HaskellOptions -> C2HaskellOptions |
@@ -875,6 +920,7 @@ parseOptions ("-p":args) o = parseOptions args o{ oPrettyC = True } | |||
875 | parseOptions ("--cpp":args) o = parseOptions args o{ oPreprocess = True } | 920 | parseOptions ("--cpp":args) o = parseOptions args o{ oPreprocess = True } |
876 | parseOptions ("-v":args) o = parseOptions args o{ oVerbose = True } | 921 | parseOptions ("-v":args) o = parseOptions args o{ oVerbose = True } |
877 | parseOptions ("--tohs":args) o = parseOptions args o{ oTranspile = True } | 922 | parseOptions ("--tohs":args) o = parseOptions args o{ oTranspile = True } |
923 | parseOptions ("--comments":args) o = parseOptions args o{ oCommentsOnly = True } | ||
878 | parseOptions as o = error (show as) | 924 | parseOptions 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. | ||
1443 | rewriteComment :: StyledComment -> CExpression NodeInfo | ||
1444 | rewriteComment 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 | |||
1452 | data CommentStyle = VanillaComment | StarBarComment | ||
1453 | deriving (Eq,Ord,Enum,Show) | ||
1454 | |||
1455 | data StyledComment = StyledComment | ||
1456 | { styledComment :: String | ||
1457 | , commentStyle :: CommentStyle | ||
1458 | , commentRow :: Int | ||
1459 | , commentCol :: Int | ||
1460 | } | ||
1461 | deriving (Eq,Ord,Show) | ||
1462 | |||
1463 | reflowComment :: (Int,Int,String) -> StyledComment | ||
1464 | reflowComment (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 | |||
1395 | readComments :: Num lin => FilePath -> IO [(lin, Int, [Char])] | 1477 | readComments :: Num lin => FilePath -> IO [(lin, Int, [Char])] |
1396 | readComments fname = grepCComments 1 1 <$> readFile fname | 1478 | readComments 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 |