summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-11-19 15:00:43 -0500
committerJoe Crayne <joe@jerkface.net>2018-11-19 15:00:43 -0500
commitd52b9beb1c8735b0915a0fa6a9e27ccd33478532 (patch)
treebfb0282442782a943bf18ac51c58dc40b51a5017
parent0f917b68b3a81bb4d79bc2954a01588558f12f63 (diff)
uncommitted hacking + verbose options + usage string
-rw-r--r--c2haskell.hs115
1 files changed, 89 insertions, 26 deletions
diff --git a/c2haskell.hs b/c2haskell.hs
index 03ba9cd..d3075e4 100644
--- a/c2haskell.hs
+++ b/c2haskell.hs
@@ -7,7 +7,7 @@
7 7
8import Data.Generics.Aliases 8import Data.Generics.Aliases
9import Data.Generics.Schemes 9import Data.Generics.Schemes
10import Debug.Trace 10-- import Debug.Trace
11import Control.Monad 11import Control.Monad
12import Data.Char 12import Data.Char
13import Data.Data 13import Data.Data
@@ -31,6 +31,8 @@ import Text.PrettyPrint (Doc, doubleQuotes, empty, text, vcat, ($$),
31 (<+>)) 31 (<+>))
32import Text.Show.Pretty 32import Text.Show.Pretty
33 33
34trace _ = id
35
34-- | Pretty print the given tranlation unit, but replace declarations from header files with @#include@ directives. 36-- | Pretty print the given tranlation unit, but replace declarations from header files with @#include@ directives.
35-- 37--
36-- The resulting file may not compile (because of missing @#define@ directives and similar things), but is very useful 38-- The resulting file may not compile (because of missing @#define@ directives and similar things), but is very useful
@@ -167,17 +169,28 @@ hsMkName str = HS.UnQual () (foo () str)
167 foo = HS.Ident -- alternative: HS.Symbol 169 foo = HS.Ident -- alternative: HS.Symbol
168 170
169hsTypeSpec :: CDeclarationSpecifier t -> [String] 171hsTypeSpec :: CDeclarationSpecifier t -> [String]
172hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint8_t" _ _) _)) = ["Word8"]
173hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint16_t" _ _) _)) = ["Word16"]
174hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint32_t" _ _) _)) = ["Word32"]
170hsTypeSpec (CTypeSpec (CTypeDef ctyp _)) = [capitalize . identToString $ ctyp] 175hsTypeSpec (CTypeSpec (CTypeDef ctyp _)) = [capitalize . identToString $ ctyp]
171hsTypeSpec (CTypeSpec (CBoolType _)) = ["Bool"] 176hsTypeSpec (CTypeSpec (CBoolType _)) = ["Bool"]
177hsTypeSpec (CTypeSpec (CIntType _)) = ["Int"]
178hsTypeSpec (CTypeSpec (CCharType _)) = ["Char"]
172hsTypeSpec (CTypeSpec (CSUType (CStruct CStructTag mctyp Nothing [] _) _)) = maybeToList $ fmap (capitalize . identToString) mctyp 179hsTypeSpec (CTypeSpec (CSUType (CStruct CStructTag mctyp Nothing [] _) _)) = maybeToList $ fmap (capitalize . identToString) mctyp
180hsTypeSpec (CTypeSpec unhandled) = trace ("hsTypeSpec unhandled: "++ show (const () <$> unhandled))
181 $ []
173hsTypeSpec _ = [] 182hsTypeSpec _ = []
174 183
175-- hsTransField :: [CDeclarationSpecifier t3] -> [(Maybe (CDeclarator t2), Maybe t1, Maybe t)] -> [HS.Decl ()] 184-- hsTransField :: [CDeclarationSpecifier t3] -> [(Maybe (CDeclarator t2), Maybe t1, Maybe t)] -> [HS.Decl ()]
176hsTransField ctyps vars 185hsTransField ctyps vars
177 = do 186 = do
178 typname <- hsMkName <$> (hsTypeSpec =<< ctyps) 187 typname <- hsMkName <$> (hsTypeSpec =<< ctyps)
188 trace ("typname="++show typname) $ return ()
179 (var,Nothing,Nothing) <- vars 189 (var,Nothing,Nothing) <- vars
190 trace ("var="++show var) $ return ()
180 CDeclr (Just fident) ptrdeclr Nothing [] _ <- maybeToList var 191 CDeclr (Just fident) ptrdeclr Nothing [] _ <- maybeToList var
192 trace ("fident="++show fident) $ return ()
193 trace ("ptrdeclr="++show ptrdeclr) $ return ()
181 let btyp = HS.TyCon () typname 194 let btyp = HS.TyCon () typname
182 grok bs b = case bs of 195 grok bs b = case bs of
183 [] -> b 196 [] -> b
@@ -242,27 +255,58 @@ mutations = everything (++) (mkQ [] mutations1)
242commented :: String -> String 255commented :: String -> String
243commented s = unlines $ map ("-- " ++) (lines s) 256commented s = unlines $ map ("-- " ++) (lines s)
244 257
245c2haskell cs (CTranslUnit edecls _) = do 258data C2HaskellOptions = C2HaskellOptions
259 { selectFunction :: Maybe String
260 , prettyC :: Bool
261 , verbose :: Bool
262 }
263
264defopts = C2HaskellOptions
265 { selectFunction = Nothing
266 , prettyC = False
267 , verbose = False
268 }
269
270parseOptions [] opts = opts
271parseOptions ("-f":f:args) opts = parseOptions args opts
272 { selectFunction = Just f
273 }
274parseOptions ("-p":args) opts = parseOptions args opts
275 { prettyC = True
276 }
277parseOptions ("-v":args) opts = parseOptions args opts
278 { verbose = True
279 }
280
281c2haskell opts cs (CTranslUnit edecls _) = do
246 let db = foldr update initTranspile edecls 282 let db = foldr update initTranspile edecls
247 es = Map.filter (\d -> symbolLocal d && not (symbolStatic d)) (syms db) 283 es = Map.filter (\d -> symbolLocal d && not (symbolStatic d)) (syms db)
248 forM_ (Map.toList es) $ \(k,si) -> do 284 case selectFunction opts of
249 putStrLn "" 285 Nothing -> forM_ (Map.toList es) $ \(k,si) -> do
250 putStrLn (commented k) 286 putStrLn ""
251 forM_ (symbolSource si) $ \d -> do 287 putStrLn (commented k)
252 putStr $ commented (ppShow (fmap (const ()) d)) 288 forM_ (symbolSource si) $ \d -> do
253 putStr $ commented (show $ pretty d) 289 putStr $ commented (ppShow (fmap (const ()) d))
254 mapM_ (putStrLn . HS.prettyPrint) (sig d) 290 putStr $ commented (show $ pretty d)
255 {- 291 mapM_ (putStrLn . HS.prettyPrint) (sig d)
256 forM_ (body d) $ \stmt -> do 292 {-
257 putStr $ commented (take 130 $ show (fmap (const ()) stmt)) 293 forM_ (body d) $ \stmt -> do
258 putStr $ commented (ppShow (fmap (const ()) stmt)) 294 putStr $ commented (take 130 $ show (fmap (const ()) stmt))
259 putStrLn $ commented . show . pretty $ stmt 295 putStr $ commented (ppShow (fmap (const ()) stmt))
260 putStr $ commented "calls" 296 putStrLn $ commented . show . pretty $ stmt
261 mapM_ (putStr . commented . show . pretty) (calls (body d)) 297 putStr $ commented "calls"
262 putStrLn "--" 298 mapM_ (putStr . commented . show . pretty) (calls (body d))
263 putStr $ commented "mutations" 299 putStrLn "--"
264 mapM_ (putStr . commented . show . pretty) (mutations (body d)) 300 putStr $ commented "mutations"
265 -} 301 mapM_ (putStr . commented . show . pretty) (mutations (body d))
302 -}
303 Just cfun -> do
304 forM_ (symbolSource $ syms db Map.! cfun) $ \d -> do
305 -- putStr $ commented (ppShow (fmap (const ()) d))
306 -- putStr $ commented (show $ pretty d)
307 when (verbose opts) $ print (sig d)
308 mapM_ (putStrLn . HS.prettyPrint) (sig d)
309
266 310
267readComments fname = parseComments 1 1 <$> readFile fname 311readComments fname = parseComments 1 1 <$> readFile fname
268 312
@@ -293,12 +337,31 @@ sanitizeArgs ("-o":args) = sanitizeArgs $ drop 1 args
293sanitizeArgs (arg:args) = arg : sanitizeArgs args 337sanitizeArgs (arg:args) = arg : sanitizeArgs args
294sanitizeArgs [] = [] 338sanitizeArgs [] = []
295 339
340usage :: [String] -> Maybe (C2HaskellOptions, [String], FilePath)
341usage args = do
342 let fname = last args
343 case break (=="--") args of
344 (targs,_:cargs0) -> do
345 let opts = init cargs0
346 cargs = (sanitizeArgs opts)
347 hopts = parseOptions targs defopts
348 return (hopts,cargs,fname)
349 _ -> Nothing
350
351m <&> f = fmap f m
352
296main :: IO () 353main :: IO ()
297main = do 354main = do
355 self <- getProgName
298 args <- getArgs 356 args <- getArgs
299 let fname = last args 357 let usageString = self ++ " [-v] [-p] [-f <sym>] -- [gcc options] <cfile>"
300 opts = init args 358 let m = usage args
301 r <- parseCFile (newGCC "gcc") Nothing (sanitizeArgs opts) fname 359 fromMaybe (putStrLn usageString) $ m <&> \(hopts,cargs,fname) -> do
302 -- print (fmap prettyUsingInclude r) 360 r <- parseCFile (newGCC "gcc") Nothing cargs fname
303 cs <- readComments fname 361 cs <- readComments fname
304 either print (c2haskell cs) r 362 putStrLn $ "----------------------------"
363 if prettyC hopts -- -p
364 then do
365 print (fmap prettyUsingInclude r)
366 else do
367 either print (c2haskell hopts cs) r