diff options
author | Joe Crayne <joe@jerkface.net> | 2018-11-19 15:00:43 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2018-11-19 15:00:43 -0500 |
commit | d52b9beb1c8735b0915a0fa6a9e27ccd33478532 (patch) | |
tree | bfb0282442782a943bf18ac51c58dc40b51a5017 | |
parent | 0f917b68b3a81bb4d79bc2954a01588558f12f63 (diff) |
uncommitted hacking + verbose options + usage string
-rw-r--r-- | c2haskell.hs | 115 |
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 | ||
8 | import Data.Generics.Aliases | 8 | import Data.Generics.Aliases |
9 | import Data.Generics.Schemes | 9 | import Data.Generics.Schemes |
10 | import Debug.Trace | 10 | -- import Debug.Trace |
11 | import Control.Monad | 11 | import Control.Monad |
12 | import Data.Char | 12 | import Data.Char |
13 | import Data.Data | 13 | import Data.Data |
@@ -31,6 +31,8 @@ import Text.PrettyPrint (Doc, doubleQuotes, empty, text, vcat, ($$), | |||
31 | (<+>)) | 31 | (<+>)) |
32 | import Text.Show.Pretty | 32 | import Text.Show.Pretty |
33 | 33 | ||
34 | trace _ = 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 | ||
169 | hsTypeSpec :: CDeclarationSpecifier t -> [String] | 171 | hsTypeSpec :: CDeclarationSpecifier t -> [String] |
172 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint8_t" _ _) _)) = ["Word8"] | ||
173 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint16_t" _ _) _)) = ["Word16"] | ||
174 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint32_t" _ _) _)) = ["Word32"] | ||
170 | hsTypeSpec (CTypeSpec (CTypeDef ctyp _)) = [capitalize . identToString $ ctyp] | 175 | hsTypeSpec (CTypeSpec (CTypeDef ctyp _)) = [capitalize . identToString $ ctyp] |
171 | hsTypeSpec (CTypeSpec (CBoolType _)) = ["Bool"] | 176 | hsTypeSpec (CTypeSpec (CBoolType _)) = ["Bool"] |
177 | hsTypeSpec (CTypeSpec (CIntType _)) = ["Int"] | ||
178 | hsTypeSpec (CTypeSpec (CCharType _)) = ["Char"] | ||
172 | hsTypeSpec (CTypeSpec (CSUType (CStruct CStructTag mctyp Nothing [] _) _)) = maybeToList $ fmap (capitalize . identToString) mctyp | 179 | hsTypeSpec (CTypeSpec (CSUType (CStruct CStructTag mctyp Nothing [] _) _)) = maybeToList $ fmap (capitalize . identToString) mctyp |
180 | hsTypeSpec (CTypeSpec unhandled) = trace ("hsTypeSpec unhandled: "++ show (const () <$> unhandled)) | ||
181 | $ [] | ||
173 | hsTypeSpec _ = [] | 182 | hsTypeSpec _ = [] |
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 ()] |
176 | hsTransField ctyps vars | 185 | hsTransField 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) | |||
242 | commented :: String -> String | 255 | commented :: String -> String |
243 | commented s = unlines $ map ("-- " ++) (lines s) | 256 | commented s = unlines $ map ("-- " ++) (lines s) |
244 | 257 | ||
245 | c2haskell cs (CTranslUnit edecls _) = do | 258 | data C2HaskellOptions = C2HaskellOptions |
259 | { selectFunction :: Maybe String | ||
260 | , prettyC :: Bool | ||
261 | , verbose :: Bool | ||
262 | } | ||
263 | |||
264 | defopts = C2HaskellOptions | ||
265 | { selectFunction = Nothing | ||
266 | , prettyC = False | ||
267 | , verbose = False | ||
268 | } | ||
269 | |||
270 | parseOptions [] opts = opts | ||
271 | parseOptions ("-f":f:args) opts = parseOptions args opts | ||
272 | { selectFunction = Just f | ||
273 | } | ||
274 | parseOptions ("-p":args) opts = parseOptions args opts | ||
275 | { prettyC = True | ||
276 | } | ||
277 | parseOptions ("-v":args) opts = parseOptions args opts | ||
278 | { verbose = True | ||
279 | } | ||
280 | |||
281 | c2haskell 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 | ||
267 | readComments fname = parseComments 1 1 <$> readFile fname | 311 | readComments fname = parseComments 1 1 <$> readFile fname |
268 | 312 | ||
@@ -293,12 +337,31 @@ sanitizeArgs ("-o":args) = sanitizeArgs $ drop 1 args | |||
293 | sanitizeArgs (arg:args) = arg : sanitizeArgs args | 337 | sanitizeArgs (arg:args) = arg : sanitizeArgs args |
294 | sanitizeArgs [] = [] | 338 | sanitizeArgs [] = [] |
295 | 339 | ||
340 | usage :: [String] -> Maybe (C2HaskellOptions, [String], FilePath) | ||
341 | usage 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 | |||
351 | m <&> f = fmap f m | ||
352 | |||
296 | main :: IO () | 353 | main :: IO () |
297 | main = do | 354 | main = 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 | ||