diff options
author | Joe Crayne <joe@jerkface.net> | 2018-11-20 17:47:40 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2018-11-20 17:47:40 -0500 |
commit | bb2f9fbbc4992cfff65b8ff59439046217a2c1ef (patch) | |
tree | 165fe387fdb736c90a76440f05effd28f6ba1c99 | |
parent | aa9e2931acdda7663df96ae7bf5ac2c75d66b6ff (diff) |
import signatures should be IO actions.
-rw-r--r-- | c2haskell.hs | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/c2haskell.hs b/c2haskell.hs index 5602c10..832e613 100644 --- a/c2haskell.hs +++ b/c2haskell.hs | |||
@@ -1,4 +1,5 @@ | |||
1 | {-# LANGUAGE BangPatterns #-} | 1 | {-# LANGUAGE BangPatterns #-} |
2 | {-# LANGUAGE DeriveFunctor #-} | ||
2 | {-# LANGUAGE FlexibleContexts #-} | 3 | {-# LANGUAGE FlexibleContexts #-} |
3 | {-# LANGUAGE LambdaCase #-} | 4 | {-# LANGUAGE LambdaCase #-} |
4 | {-# LANGUAGE NondecreasingIndentation #-} | 5 | {-# LANGUAGE NondecreasingIndentation #-} |
@@ -59,9 +60,9 @@ prettyUsingInclude (CTranslUnit edecls _) = | |||
59 | | otherwise = text "/* Warning: The #include directives in this file aren't necessarily correct. */" | 60 | | otherwise = text "/* Warning: The #include directives in this file aren't necessarily correct. */" |
60 | 61 | ||
61 | specs :: CExternalDeclaration a -> [CDeclarationSpecifier a] | 62 | specs :: CExternalDeclaration a -> [CDeclarationSpecifier a] |
62 | specs (CFDefExt (CFunDef specs _ _ _ _)) = specs | 63 | specs (CFDefExt (CFunDef ss _ _ _ _)) = ss |
63 | specs (CDeclExt (CDecl specs _ _)) = specs | 64 | specs (CDeclExt (CDecl ss _ _)) = ss |
64 | specs _ = [] | 65 | specs _ = [] |
65 | 66 | ||
66 | declrSym :: CDeclarator t -> Maybe Ident | 67 | declrSym :: CDeclarator t -> Maybe Ident |
67 | declrSym (CDeclr m _ _ _ _) = m | 68 | declrSym (CDeclr m _ _ _ _) = m |
@@ -131,7 +132,7 @@ data SymbolInformation c = SymbolInformation | |||
131 | , symbolStatic :: Bool | 132 | , symbolStatic :: Bool |
132 | , symbolSource :: c | 133 | , symbolSource :: c |
133 | } | 134 | } |
134 | deriving (Eq,Ord,Show) | 135 | deriving (Eq,Ord,Show,Functor) |
135 | 136 | ||
136 | symbolInformation = SymbolInformation | 137 | symbolInformation = SymbolInformation |
137 | { symbolLocal = False | 138 | { symbolLocal = False |
@@ -178,6 +179,11 @@ hsMkName str = HS.UnQual () (foo () str) | |||
178 | notKnown "Word8" = False | 179 | notKnown "Word8" = False |
179 | notKnown "Word16" = False | 180 | notKnown "Word16" = False |
180 | notKnown "Word32" = False | 181 | notKnown "Word32" = False |
182 | notKnown "Word64" = False | ||
183 | notKnown "Int8" = False | ||
184 | notKnown "Int16" = False | ||
185 | notKnown "Int32" = False | ||
186 | notKnown "Int64" = False | ||
181 | notKnown "Bool" = False | 187 | notKnown "Bool" = False |
182 | notKnown "Int" = False | 188 | notKnown "Int" = False |
183 | notKnown "Char" = False | 189 | notKnown "Char" = False |
@@ -189,6 +195,11 @@ hsTypeSpec (CTypeSpec (CVoidType _)) = [ Right "()" ] | |||
189 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint8_t" _ _) _)) = [ Right "Word8"] | 195 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint8_t" _ _) _)) = [ Right "Word8"] |
190 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint16_t" _ _) _)) = [ Right "Word16"] | 196 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint16_t" _ _) _)) = [ Right "Word16"] |
191 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint32_t" _ _) _)) = [ Right "Word32"] | 197 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint32_t" _ _) _)) = [ Right "Word32"] |
198 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "uint64_t" _ _) _)) = [ Right "Word64"] | ||
199 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "int8_t" _ _) _)) = [ Right "Int8"] | ||
200 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "int16_t" _ _) _)) = [ Right "Int16"] | ||
201 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "int32_t" _ _) _)) = [ Right "Int32"] | ||
202 | hsTypeSpec (CTypeSpec (CTypeDef (C.Ident "int64_t" _ _) _)) = [ Right "Int64"] | ||
192 | hsTypeSpec (CTypeSpec (CTypeDef ctyp _)) = [ Left ctyp ] | 203 | hsTypeSpec (CTypeSpec (CTypeDef ctyp _)) = [ Left ctyp ] |
193 | hsTypeSpec (CTypeSpec (CBoolType _)) = [ Right "Bool"] | 204 | hsTypeSpec (CTypeSpec (CBoolType _)) = [ Right "Bool"] |
194 | hsTypeSpec (CTypeSpec (CIntType _)) = [ Right "Int"] | 205 | hsTypeSpec (CTypeSpec (CIntType _)) = [ Right "Int"] |
@@ -274,6 +285,9 @@ pointers decls = do | |||
274 | d <- decls | 285 | d <- decls |
275 | maybeToList $ getPtrType d | 286 | maybeToList $ getPtrType d |
276 | 287 | ||
288 | unpointer t = case getPtrType t of | ||
289 | Nothing -> t | ||
290 | Just t' -> t' | ||
277 | 291 | ||
278 | sig :: Show t => CExternalDeclaration t -> [HS.Decl ()] | 292 | sig :: Show t => CExternalDeclaration t -> [HS.Decl ()] |
279 | sig = sigf hsTransFieldExt | 293 | sig = sigf hsTransFieldExt |
@@ -340,17 +354,31 @@ parseOptions ("-v":args) opts = parseOptions args opts | |||
340 | 354 | ||
341 | getsig (k,si) = do | 355 | getsig (k,si) = do |
342 | d <- take 1 $ symbolSource si | 356 | d <- take 1 $ symbolSource si |
343 | let ts = filter notKnown $ map tname $ pointers $ concatMap types $ sigf hsTransSig d | 357 | let ts = filter notKnown $ map tname $ map unpointer $ concatMap types $ sigf hsTransSig d |
344 | s = sig d | 358 | s = sig d |
345 | [(ts,(k,s))] | 359 | [(ts,(k,s))] |
346 | 360 | ||
347 | isAcceptableImport (HS.TyFun _ (TyCon _ (UnQual _ (HS.Ident _ x))) xs) | not (notKnown x) = isAcceptableImport xs | 361 | isAcceptableImport (HS.TyFun _ (TyCon _ (UnQual _ (HS.Ident _ x))) xs) | not (notKnown x) = isAcceptableImport xs |
348 | isAcceptableImport (HS.TyFun _ (TyApp _ (TyCon _ (UnQual _ (HS.Ident _ "Ptr"))) x) xs) = isAcceptableImport xs | 362 | isAcceptableImport (HS.TyFun _ (TyApp _ (TyCon _ (UnQual _ (HS.Ident _ "Ptr"))) x) xs) = isAcceptableImport xs |
349 | isAcceptableImport (HS.TyFun _ (TyApp _ (TyCon _ (UnQual _ (HS.Ident _ "Ptr"))) x) xs) = isAcceptableImport xs | ||
350 | isAcceptableImport (TyCon _ _) = True | 363 | isAcceptableImport (TyCon _ _) = True |
351 | isAcceptableImport (TyApp _ _ _) = True | 364 | isAcceptableImport (TyApp _ _ _) = True |
352 | isAcceptableImport _ = False | 365 | isAcceptableImport _ = False |
353 | 366 | ||
367 | makeFunctionUseIO :: HS.Type () -> HS.Type () | ||
368 | makeFunctionUseIO (HS.TyFun a x xs) = (HS.TyFun a x (makeFunctionUseIO xs)) | ||
369 | makeFunctionUseIO t@(TyApp a (TyCon b (UnQual c (HS.Ident d "IO"))) x) = t | ||
370 | makeFunctionUseIO t = TyApp () (TyCon () (UnQual () (HS.Ident () "IO"))) t | ||
371 | |||
372 | |||
373 | makeAcceptableImport (HS.TyFun a (TyCon b (UnQual c (HS.Ident d x))) xs) | not (notKnown x) | ||
374 | = (HS.TyFun a (TyCon b (UnQual c (HS.Ident d x))) (makeAcceptableImport xs)) | ||
375 | makeAcceptableImport (HS.TyFun a (TyApp b (TyCon c (UnQual d (HS.Ident e "Ptr"))) x) xs) | ||
376 | = (HS.TyFun a (TyApp b (TyCon c (UnQual d (HS.Ident e "Ptr"))) x) (makeAcceptableImport xs)) | ||
377 | makeAcceptableImport (HS.TyFun a (TyCon c (UnQual d (HS.Ident e x))) xs) | ||
378 | = (HS.TyFun a (TyApp c (TyCon c (UnQual d (HS.Ident e "Ptr"))) (TyCon e (UnQual e (HS.Ident e x)))) (makeAcceptableImport xs)) | ||
379 | makeAcceptableImport t = t | ||
380 | |||
381 | -- c2haskell :: Foldable t => C2HaskellOptions -> p -> t String -> CTranslationUnit NodeInfo -> IO () | ||
354 | c2haskell opts cs missings (CTranslUnit edecls _) = do | 382 | c2haskell opts cs missings (CTranslUnit edecls _) = do |
355 | let db = foldr update initTranspile edecls | 383 | let db = foldr update initTranspile edecls |
356 | es = Map.filter (\d -> symbolLocal d && not (symbolStatic d)) (syms db) | 384 | es = Map.filter (\d -> symbolLocal d && not (symbolStatic d)) (syms db) |
@@ -359,9 +387,20 @@ c2haskell opts cs missings (CTranslUnit edecls _) = do | |||
359 | putStrLn $ "module T where" | 387 | putStrLn $ "module T where" |
360 | putStrLn $ "import Foreign.Ptr" | 388 | putStrLn $ "import Foreign.Ptr" |
361 | putStrLn $ "import Data.Word" | 389 | putStrLn $ "import Data.Word" |
390 | putStrLn $ "import Data.Int" | ||
391 | putStrLn $ "-- " ++ show (fmap (fmap (fmap (const ()))) <$> Map.lookup "ip_is_lan" (syms db)) | ||
362 | let sigs = concatMap getsig (Map.toList es) | 392 | let sigs = concatMap getsig (Map.toList es) |
363 | ts = foldr (\t -> Map.insert t ()) Map.empty $ concatMap fst sigs | 393 | sigs2 = concatMap (\s -> do |
364 | forM_ (Map.keys ts) $ \t -> do | 394 | x <- maybeToList $ Map.lookup s (syms db) |
395 | (y,_) <- getsig (s,x) | ||
396 | y) | ||
397 | missings | ||
398 | ts = concatMap fst sigs | ||
399 | putStrLn $ "-- IP `elem` db = " ++ show (length . symbolSource <$> Map.lookup "IP" (syms db)) | ||
400 | putStrLn $ "-- IP `elem` sigs2 = " ++ show (elem "IP" sigs2) | ||
401 | putStrLn $ "-- ip_is_lan `elem` db = " ++ show (length . symbolSource <$> Map.lookup "ip_is_lan" (syms db)) | ||
402 | putStrLn $ "-- ip_is_lan `elem` sigs2 = " ++ show (elem "ip_is_lan" sigs2) | ||
403 | forM_ (uniq $ ts ++ sigs2) $ \t -> do | ||
365 | putStrLn $ "data " ++ t | 404 | putStrLn $ "data " ++ t |
366 | forM_ sigs $ \(_,(k,hs)) -> do | 405 | forM_ sigs $ \(_,(k,hs)) -> do |
367 | forM_ hs $ \hdecl -> do | 406 | forM_ hs $ \hdecl -> do |
@@ -377,7 +416,7 @@ c2haskell opts cs missings (CTranslUnit edecls _) = do | |||
377 | forM_ (sig d) $ \hs -> case hs of | 416 | forM_ (sig d) $ \hs -> case hs of |
378 | htyp -> -- putStr $ commented $ "Unsupported haskell type: " ++ HS.prettyPrint htyp | 417 | htyp -> -- putStr $ commented $ "Unsupported haskell type: " ++ HS.prettyPrint htyp |
379 | -} | 418 | -} |
380 | let htyp = extractType hdecl | 419 | let htyp = makeFunctionUseIO $ extractType hdecl |
381 | putStrLn $ (if isAcceptableImport htyp then id else commented) | 420 | putStrLn $ (if isAcceptableImport htyp then id else commented) |
382 | $ HS.prettyPrint $ (HS.ForImp () (HS.CCall ()) Nothing (Just k) | 421 | $ HS.prettyPrint $ (HS.ForImp () (HS.CCall ()) Nothing (Just k) |
383 | (HS.Ident () k) | 422 | (HS.Ident () k) |
@@ -409,6 +448,9 @@ c2haskell opts cs missings (CTranslUnit edecls _) = do | |||
409 | -} | 448 | -} |
410 | Just cfun -> goMissing db cfun | 449 | Just cfun -> goMissing db cfun |
411 | 450 | ||
451 | makeAcceptableDecl (HS.TypeDecl a (DHead b (HS.Ident c signame)) ftyp) | ||
452 | = (HS.TypeDecl a (DHead b (HS.Ident c signame)) (makeFunctionUseIO $ makeAcceptableImport ftyp)) | ||
453 | |||
412 | goMissing db cfun = do | 454 | goMissing db cfun = do |
413 | forM_ (Map.lookup cfun $ syms db) $ \si -> do | 455 | forM_ (Map.lookup cfun $ syms db) $ \si -> do |
414 | forM_ (take 1 $ symbolSource si) $ \d -> do | 456 | forM_ (take 1 $ symbolSource si) $ \d -> do |
@@ -416,10 +458,9 @@ goMissing db cfun = do | |||
416 | -- putStr $ commented (show $ pretty d) | 458 | -- putStr $ commented (show $ pretty d) |
417 | -- when (verbose opts) $ print (sig d) | 459 | -- when (verbose opts) $ print (sig d) |
418 | let ts = filter notKnown $ map tname $ pointers $ concatMap types $ sigf hsTransSig d | 460 | let ts = filter notKnown $ map tname $ pointers $ concatMap types $ sigf hsTransSig d |
419 | forM_ ts $ \t -> do | 461 | -- forM_ ts $ \t -> putStrLn $ "data " ++ t |
420 | putStrLn $ "data " ++ t | ||
421 | forM_ (sigf hsTransSig d) $ \hs -> do | 462 | forM_ (sigf hsTransSig d) $ \hs -> do |
422 | putStrLn . HS.prettyPrint $ hs | 463 | putStrLn . HS.prettyPrint $ makeAcceptableDecl hs |
423 | case hs of | 464 | case hs of |
424 | HS.TypeDecl _ (DHead _ (HS.Ident _ signame)) ftyp -> do | 465 | HS.TypeDecl _ (DHead _ (HS.Ident _ signame)) ftyp -> do |
425 | let wrapname = "wrap" ++ drop 3 signame | 466 | let wrapname = "wrap" ++ drop 3 signame |
@@ -529,7 +570,6 @@ main = do | |||
529 | fromMaybe (putStrLn usageString) $ m <&> \(hopts,cargs,fname) -> do | 570 | fromMaybe (putStrLn usageString) $ m <&> \(hopts,cargs,fname) -> do |
530 | r <- parseCFile (newGCC "gcc") Nothing cargs fname | 571 | r <- parseCFile (newGCC "gcc") Nothing cargs fname |
531 | cs <- readComments fname | 572 | cs <- readComments fname |
532 | putStrLn $ "----------------------------" | ||
533 | if prettyC hopts -- -p | 573 | if prettyC hopts -- -p |
534 | then do | 574 | then do |
535 | print (fmap prettyUsingInclude r) | 575 | print (fmap prettyUsingInclude r) |