summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-03-23 01:11:05 -0400
committerJoe Crayne <joe@jerkface.net>2019-03-23 01:11:05 -0400
commit56b8d9316dcb37aedf5a7727f05b6cd81f9f0f19 (patch)
tree8681e0a181013d504fbe7981791f0a10b41f911e
parent6cbcc42ef4ac75a9bccb4e9d0acc53116c7c68e8 (diff)
Binary ops and global pointer refs.
-rw-r--r--monkeypatch.hs132
1 files changed, 117 insertions, 15 deletions
diff --git a/monkeypatch.hs b/monkeypatch.hs
index bc55425..352a0f5 100644
--- a/monkeypatch.hs
+++ b/monkeypatch.hs
@@ -7,9 +7,12 @@
7{-# LANGUAGE QuasiQuotes #-} 7{-# LANGUAGE QuasiQuotes #-}
8{-# LANGUAGE TemplateHaskell #-} 8{-# LANGUAGE TemplateHaskell #-}
9{-# LANGUAGE TupleSections #-} 9{-# LANGUAGE TupleSections #-}
10{-# LANGUAGE ScopedTypeVariables #-}
10module Main where 11module Main where
11 12
13import Debug.Trace
12import Control.Arrow (left,first,second) 14import Control.Arrow (left,first,second)
15import Data.Bool
13import Data.Either 16import Data.Either
14import Data.Generics.Aliases 17import Data.Generics.Aliases
15import Data.Generics.Schemes 18import Data.Generics.Schemes
@@ -52,8 +55,10 @@ import Text.Show.Pretty
52import Sweeten 55import Sweeten
53import GrepNested 56import GrepNested
54 57
58{-
55trace :: p -> a -> a 59trace :: p -> a -> a
56trace _ = id 60trace _ = id
61-}
57 62
58-- | Pretty print the given tranlation unit, but replace declarations from header files with @#include@ directives. 63-- | Pretty print the given tranlation unit, but replace declarations from header files with @#include@ directives.
59-- 64--
@@ -197,16 +202,105 @@ varmap vs = Map.fromList $ map (,()) vs
197 202
198-} 203-}
199 204
205
206renameIntros :: forall v st. (Typeable st, Data st) =>
207 [Computation (HS.Exp st)]
208 -> Computation (HS.Exp st)
209 -> Map String v
210 -> ([Computation (HS.Exp st)], Computation (HS.Exp st))
211renameIntros bs cb vs = (bs',cb')
212 where
213 (rs,bs') = unzip $ map go bs
214
215 cb' = foldr rename2 cb $ concat rs
216
217 rename2 (x,v) c =
218 let subst p@(Var la (UnQual lc (HS.Ident lb s)))
219 | s==x = Var (la::st) (UnQual lc (HS.Ident lb v))
220 subst p = p
221 in c { comp = everywhere (mkT subst) (comp c) }
222
223 go c =
224 let xs = Map.keys (compIntro c)
225 in foldr rename1 ([],c) xs
226
227 rename1 x (rs,c) =
228 let v = uniqIdentifier x vs
229 subst p@(PVar la (HS.Ident lb s))
230 | s==x = PVar (la::st) (HS.Ident lb v)
231 subst p = p
232 in if x/=v then (,) ((x,v):rs) c { compIntro = Map.insert v () $ Map.delete x (compIntro c)
233 , comp = everywhere (mkT subst) (comp c)
234 }
235 else (rs,c)
236
237transpileBinOp :: CBinaryOp -> [Char]
238transpileBinOp = \case
239 CMulOp -> "*"
240 CDivOp -> "/"
241 CRmdOp -> "rem"
242 CAddOp -> "+"
243 CSubOp -> "-"
244 CShlOp -> "shiftL"
245 CShrOp -> "shiftR"
246 CLeOp -> "<"
247 CGrOp -> ">"
248 CLeqOp -> "<="
249 CGeqOp -> ">="
250 CEqOp -> "=="
251 CNeqOp -> "/="
252 CAndOp -> ".&."
253 CXorOp -> "xor"
254 COrOp -> ".|."
255 CLndOp -> "and"
256 CLorOp -> "or"
257
258-- This function decides whether to treat an identifier as a constant or as a
259-- pointer that must be peeked.
260isGlobalRef :: FunctionEnvironment -> String -> Bool
261isGlobalRef fe sym = fromMaybe False $ do
262 SymbolInformation{symbolSource = xs} <- Map.lookup sym (fnExternals fe)
263 forM_ xs $ \x -> do
264 -- Pattern fail for functions and pointers.
265 forM_ (sigf (\_ ds -> ds) x) $ \d -> do
266 CDeclr _ xs _ _ _ <- Just d
267 let func = filter (\case
268 CFunDeclr _ _ _ -> True
269 _ -> False) xs
270 guard $ null func -- Functions are not pointerized.
271 -- trace (sym ++ ": " ++ show xs) $ return ()
272 -- ring: [CPtrDeclr [] (NodeInfo ("fetchers/about.c": line 64) (("fetchers/about.c": line 64),4) (Name {nameId = 14030}))]
273 return ()
274 return True
275
200-- Returns a list of statements bringing variables into scope and an 276-- Returns a list of statements bringing variables into scope and an
201-- expression. 277-- expression.
202grokExpression :: FunctionEnvironment 278grokExpression :: FunctionEnvironment
203 -> CExpression a 279 -> CExpression a
204 -> Maybe ([Computation (HS.Exp ())], Computation (HS.Exp ())) 280 -> Maybe ([Computation (HS.Exp ())], Computation (HS.Exp ()))
205grokExpression fe (CVar cv _) = Just $ (,) [] $ Computation 281grokExpression fe (CVar cv _) =
206 { compFree = Map.singleton (identToString cv) () 282 let v = identToString cv
207 , compIntro = Map.empty 283 in Just $
208 , comp = hsvar (identToString cv) 284 if isGlobalRef fe v
209 } 285 then let k = uniqIdentifier "go" (varmap [v,hv])
286 s = Computation
287 { compFree = Map.singleton v ()
288 , compIntro = Map.singleton hv ()
289 , comp = Lambda () [hspvar k]
290 $ infixOp (App () (hsvar "peek") (hsvar v)) ">>="
291 $ Lambda () [hspvar hv] (hsvar k)
292 }
293 hv = "v" ++ v
294 in (,) [s] Computation
295 { compFree = Map.singleton hv ()
296 , compIntro = Map.empty
297 , comp = hsvar hv
298 }
299 else (,) [] $ Computation
300 { compFree = Map.singleton (identToString cv) ()
301 , compIntro = Map.empty
302 , comp = hsvar v
303 }
210grokExpression fe (CConst (CIntConst n _)) = Just $ (,) [] $ Computation 304grokExpression fe (CConst (CIntConst n _)) = Just $ (,) [] $ Computation
211 { compFree = Map.empty 305 { compFree = Map.empty
212 , compIntro = Map.empty 306 , compIntro = Map.empty
@@ -217,14 +311,20 @@ grokExpression fe (CConst (CStrConst s _)) = Just $ (,) [] $ Computation
217 , compIntro = Map.empty 311 , compIntro = Map.empty
218 , comp = Lit () (HS.String () (getCString s) (getCString s)) 312 , comp = Lit () (HS.String () (getCString s) (getCString s))
219 } 313 }
220grokExpression fe (CBinary CNeqOp a b _) = do 314grokExpression fe (CBinary op a b _) = do
221 (as,ca) <- grokExpression fe a 315 (as,ca) <- grokExpression fe a
222 (bs,cb) <- grokExpression fe b 316 (bs0,cb0) <- grokExpression fe b
223 let ss = as ++ bs -- TODO: resolve variable name conflicts 317 let (bs,cb) = renameIntros bs0 cb0 (foldr Map.union Map.empty $ map compIntro as)
318 ss = as ++ bs
319 hop = transpileBinOp op
320 infx | isLower (head hop) = infixFn
321 | otherwise = infixOp
322 -- trace ("intros("++hop++"): "++show (foldr Map.union Map.empty $ map compIntro as)) $ return ()
323 -- TODO: Short-circuit boolean evaluation side-effects.
224 return $ (,) ss $ Computation 324 return $ (,) ss $ Computation
225 { compFree = compFree ca `Map.union` compFree cb 325 { compFree = compFree ca `Map.union` compFree cb
226 , compIntro = Map.empty 326 , compIntro = Map.empty
227 , comp = infixOp (comp ca) "/=" (comp cb) 327 , comp = infx (comp ca) hop (comp cb)
228 } 328 }
229grokExpression fe (CUnary CAdrOp (CVar cv0 _) _) = do 329grokExpression fe (CUnary CAdrOp (CVar cv0 _) _) = do
230 let cv = identToString cv0 330 let cv = identToString cv0
@@ -573,6 +673,8 @@ insertComment c stmts = everywhere (mkT go) stmts
573mixComments :: [StyledComment] -> [CCompoundBlockItem NodeInfo] -> [CCompoundBlockItem NodeInfo] 673mixComments :: [StyledComment] -> [CCompoundBlockItem NodeInfo] -> [CCompoundBlockItem NodeInfo]
574mixComments cs stmts = foldr insertComment stmts cs 674mixComments cs stmts = foldr insertComment stmts cs
575 675
676applyDoSyntax' :: Data l =>
677 C2HaskellOptions -> HS.Exp l -> HS.Exp l
576applyDoSyntax' C2HaskellOptions{oSuppressDo=True} x = x 678applyDoSyntax' C2HaskellOptions{oSuppressDo=True} x = x
577applyDoSyntax' _ x = applyDoSyntax x 679applyDoSyntax' _ x = applyDoSyntax x
578 680
@@ -763,7 +865,7 @@ hsTypeSpec (CTypeSpec (CIntType _)) = [ R
763hsTypeSpec (CTypeSpec (CCharType _)) = [ Right "Char"] 865hsTypeSpec (CTypeSpec (CCharType _)) = [ Right "Char"]
764hsTypeSpec (CTypeSpec (CSUType (CStruct CStructTag mctyp Nothing [] _) _)) = maybeToList $ fmap Left mctyp 866hsTypeSpec (CTypeSpec (CSUType (CStruct CStructTag mctyp Nothing [] _) _)) = maybeToList $ fmap Left mctyp
765 867
766hsTypeSpec (CTypeSpec unhandled) = trace ("hsTypeSpec unhandled: "++ show (const () <$> unhandled)) $ [] 868hsTypeSpec (CTypeSpec unhandled) = [] -- trace ("hsTypeSpec unhandled: "++ show (const () <$> unhandled)) $ []
767hsTypeSpec _ = [] 869hsTypeSpec _ = []
768 870
769 871
@@ -786,15 +888,15 @@ hsTransField ctyps vars
786 (mcname,typname) <- second hsMkName . either ((\s -> (Just s,capitalize s)) . identToString) 888 (mcname,typname) <- second hsMkName . either ((\s -> (Just s,capitalize s)) . identToString)
787 (Nothing,) 889 (Nothing,)
788 <$> (hsTypeSpec =<< ctyps) 890 <$> (hsTypeSpec =<< ctyps)
789 trace ("typname="++show typname) $ return () 891 -- trace ("typname="++show typname) $ return ()
790 -- (var,Nothing,Nothing) <- vars 892 -- (var,Nothing,Nothing) <- vars
791 var <- vars 893 var <- vars
792 trace ("var="++show var) $ return () 894 -- trace ("var="++show var) $ return ()
793 -- CDeclr (Just fident) ptrdeclr Nothing [] _ <- maybeToList var 895 -- CDeclr (Just fident) ptrdeclr Nothing [] _ <- maybeToList var
794 let CDeclr mfident ptrdeclr Nothing ignored_attrs _ = var -- TODO: Look into: Irrefutable pattern failed (ctox/toxcore/DHT.c) 896 let CDeclr mfident ptrdeclr Nothing ignored_attrs _ = var -- TODO: Look into: Irrefutable pattern failed (ctox/toxcore/DHT.c)
795 -- let CDeclr mfident ptrdeclr _ _ _ = var 897 -- let CDeclr mfident ptrdeclr _ _ _ = var
796 trace ("fident="++show mfident) $ return () 898 -- trace ("fident="++show mfident) $ return ()
797 trace ("ptrdeclr="++show ptrdeclr) $ return () 899 -- trace ("ptrdeclr="++show ptrdeclr) $ return ()
798 let btyp = HS.TyCon () typname 900 let btyp = HS.TyCon () typname
799 grok :: Show a => [CDerivedDeclarator a] -> HS.Type () -> HS.Type () 901 grok :: Show a => [CDerivedDeclarator a] -> HS.Type () -> HS.Type ()
800 grok bs b = case bs of 902 grok bs b = case bs of
@@ -1306,7 +1408,7 @@ getArgList_ (CFDefExt (CFunDef xs ys zs c d)) = getArgList1 ys
1306getArgList_ (CDeclExt (CDecl xs ys pos)) = getArgList2 ys 1408getArgList_ (CDeclExt (CDecl xs ys pos)) = getArgList2 ys
1307 1409
1308getArgList :: CExternalDeclaration a -> [CDerivedDeclarator a] 1410getArgList :: CExternalDeclaration a -> [CDerivedDeclarator a]
1309getArgList x = let v=getArgList_ x in trace ("getArgList ("++show (u x)++") = "++show (fmap u v)) v 1411getArgList x = let v=getArgList_ x in {- trace ("getArgList ("++show (u x)++") = "++show (fmap u v)) -} v
1310 where 1412 where
1311 u :: Functor f => f a -> f () 1413 u :: Functor f => f a -> f ()
1312 u = fmap (const ()) 1414 u = fmap (const ())