Skip to content
Snippets Groups Projects
Commit e06548f1 authored by chrg's avatar chrg
Browse files

Work in progress

parent ad637237
No related branches found
No related tags found
No related merge requests found
Showing
with 132 additions and 16 deletions
...@@ -28,12 +28,14 @@ import qualified Language.C.Data.Ident as C ...@@ -28,12 +28,14 @@ import qualified Language.C.Data.Ident as C
data Context = Context data Context = Context
{ keywords :: !(Set.Set Keyword) { keywords :: !(Set.Set Keyword)
, typeDefs :: !(Map.Map C.Ident [C.CDeclarationSpecifier C.NodeInfo]) , typeDefs :: !(Map.Map C.Ident [C.CDeclarationSpecifier C.NodeInfo])
, inlineExprs :: !(Map.Map C.Ident C.CExpr)
} }
data Keyword data Keyword
= KeepMain = KeepMain
| DoNoops | DoNoops
| NoSemantics | NoSemantics
| AllowEmptyDeclarations
deriving (Show, Read, Enum, Eq, Ord) deriving (Show, Read, Enum, Eq, Ord)
type CM m = (MonadReduce (String, C.Position) m, MonadReader Context m, MonadFail m) type CM m = (MonadReduce (String, C.Position) m, MonadReader Context m, MonadFail m)
...@@ -49,11 +51,19 @@ addTypeDefs ids cs Context{..} = ...@@ -49,11 +51,19 @@ addTypeDefs ids cs Context{..} =
, .. , ..
} }
addInlineExpr :: C.Ident -> C.CExpr -> Context -> Context
addInlineExpr i e Context{..} =
Context
{ inlineExprs = Map.insert i e inlineExprs
, ..
}
defaultContext :: Context defaultContext :: Context
defaultContext = defaultContext =
Context Context
{ keywords = Set.fromList [KeepMain] { keywords = Set.fromList [KeepMain]
, typeDefs = Map.empty , typeDefs = Map.empty
, inlineExprs = Map.empty
} }
keyword :: (MonadReader Context m) => Keyword -> m Bool keyword :: (MonadReader Context m) => Keyword -> m Bool
...@@ -87,9 +97,37 @@ instance CReducible C.CTranslUnit where ...@@ -87,9 +97,37 @@ instance CReducible C.CTranslUnit where
("inline typedef " <> C.identToString ids, C.posOf r) ("inline typedef " <> C.identToString ids, C.posOf r)
(local (addTypeDefs [ids] rst) cont) (local (addTypeDefs [ids] rst) cont)
((r :) <$> local (addTypeDefs [ids] [C.CTypeSpec (C.CTypeDef ids n)]) cont) ((r :) <$> local (addTypeDefs [ids] [C.CTypeSpec (C.CTypeDef ids n)]) cont)
-- A const
C.CDecl rec decl ni' -> do
(decl', cont') <- foldr reduceCDeclarationItem (pure ([], cont)) decl
allow <- keyword AllowEmptyDeclarations
case decl' of
[]
| allow ->
split ("remove empty declaration", C.posOf r) cont' do
(C.CDeclExt (C.CDecl rec decl' ni') :) <$> cont'
| otherwise -> cont'
_ow -> (C.CDeclExt (C.CDecl rec decl' ni') :) <$> cont'
a -> don'tHandle a a -> don'tHandle a
_r -> don'tHandle r _r -> don'tHandle r
reduceCDeclarationItem
:: (CM m)
=> C.CDeclarationItem C.NodeInfo
-> m ([C.CDeclarationItem C.NodeInfo], m a)
-> m ([C.CDeclarationItem C.NodeInfo], m a)
reduceCDeclarationItem d ma = case d of
C.CDeclarationItem
(C.CDeclr (Just i) [] Nothing [] ni)
(Just (C.CInitExpr c _))
Nothing -> do
(ds, cont) <- ma
split
("inline variable " <> C.identToString i, C.posOf ni)
(pure (ds, local (addInlineExpr i c) cont))
(pure (d : ds, local (addInlineExpr i (C.CVar i ni)) cont))
a -> don'tHandle a
prettyIdent :: C.Identifier C.NodeInfo -> [Char] prettyIdent :: C.Identifier C.NodeInfo -> [Char]
prettyIdent (C.Ident s _ a) = s ++ " at " ++ show (C.posOfNode a) prettyIdent (C.Ident s _ a) = s ++ " at " ++ show (C.posOfNode a)
...@@ -109,10 +147,18 @@ reduceCCompoundBlockItem r cont = case r of ...@@ -109,10 +147,18 @@ reduceCCompoundBlockItem r cont = case r of
split ("remove statement", C.posOf r) cont do split ("remove statement", C.posOf r) cont do
smt' <- reduceC smt smt' <- reduceC smt
(C.CBlockStmt smt' :) <$> cont (C.CBlockStmt smt' :) <$> cont
C.CBlockDecl decl -> do C.CBlockDecl declr -> do
case decl of case declr of
C.CDecl{} -> do C.CDecl rec decl ni' -> do
(r :) <$> cont (decl', cont') <- foldr reduceCDeclarationItem (pure ([], cont)) decl
allow <- keyword AllowEmptyDeclarations
case decl' of
[]
| allow ->
split ("remove empty declaration", C.posOf r) cont' do
(C.CBlockDecl (C.CDecl rec decl' ni') :) <$> cont'
| otherwise -> cont'
_ow -> (C.CBlockDecl (C.CDecl rec decl' ni') :) <$> cont'
d -> don'tHandle d d -> don'tHandle d
a -> don'tHandle a a -> don'tHandle a
...@@ -142,15 +188,6 @@ instance CReducible (C.CStatement C.NodeInfo) where ...@@ -142,15 +188,6 @@ instance CReducible (C.CStatement C.NodeInfo) where
pure $ C.CReturn Nothing ni pure $ C.CReturn Nothing ni
a -> don'tHandle a a -> don'tHandle a
splitIf :: (MonadReduce l m) => Bool -> l -> m a -> m a -> m a
splitIf True s a b = split s a b
splitIf False _ _ b = b
splitOn :: (MonadReduce l m, MonadReader Context m) => Keyword -> l -> m a -> m a -> m a
splitOn k s a b = do
con <- keyword k
splitIf con s a b
-- C.CCompound is cbi ni -> do -- C.CCompound is cbi ni -> do
-- cbi' <- collect (reduce @C.CCompoundBlockItem) cbi -- cbi' <- collect (reduce @C.CCompoundBlockItem) cbi
-- pure $ C.CCompound is cbi' ni -- pure $ C.CCompound is cbi' ni
...@@ -214,8 +251,10 @@ instance CReducible C.CExpr where ...@@ -214,8 +251,10 @@ instance CReducible C.CExpr where
elhs' <- reduceC elhs elhs' <- reduceC elhs
erhs' <- reduceC erhs erhs' <- reduceC erhs
pure $ C.CBinary o elhs' erhs' ni pure $ C.CBinary o elhs' erhs' ni
C.CVar i ni -> do C.CVar i _ -> do
pure $ C.CVar i ni asks (Map.lookup i . inlineExprs) >>= \case
Just mx -> pure mx
Nothing -> fail ("Could not find " <> show i)
C.CConst x -> do C.CConst x -> do
pure $ C.CConst x pure $ C.CConst x
C.CUnary o elhs ni -> do C.CUnary o elhs ni -> do
...@@ -264,6 +303,15 @@ instance CReducible C.CExpr where ...@@ -264,6 +303,15 @@ instance CReducible C.CExpr where
-- where -- where
-- onBothExpr elhs erhs = onBoth (reduce elhs) (reduce erhs) -- onBothExpr elhs erhs = onBoth (reduce elhs) (reduce erhs)
splitIf :: (MonadReduce l m) => Bool -> l -> m a -> m a -> m a
splitIf True s a b = split s a b
splitIf False _ _ b = b
splitOn :: (MonadReduce l m, MonadReader Context m) => Keyword -> l -> m a -> m a -> m a
splitOn k s a b = do
con <- keyword k
splitIf con s a b
inlineTypeDefs :: forall d m. (Data d, MonadFail m, MonadReader Context m) => d -> m d inlineTypeDefs :: forall d m. (Data d, MonadFail m, MonadReader Context m) => d -> m d
inlineTypeDefs r = do inlineTypeDefs r = do
case eqT @d @[C.CDeclarationSpecifier C.NodeInfo] of case eqT @d @[C.CDeclarationSpecifier C.NodeInfo] of
......
int x = 10;
int main () {
int y = 25;
return x + y;
}
int x = 10;
int main()
{
int y = 25;
return x + y;
}
int x = 10;
int main()
{
int y = 25;
return x + y;
}
0 remove statement at ("test/cases/constant.c": line 5)
0 inline variable y at ("test/cases/constant.c": line 4)
0 inline variable x at ("test/cases/constant.c": line 1)
int x = 10;
int main()
{
int y = 25;
}
1 remove statement at ("test/cases/constant.c": line 5)
0 inline variable y at ("test/cases/constant.c": line 4)
0 inline variable x at ("test/cases/constant.c": line 1)
int x = 10;
int main()
{
return x + 25;
}
0 remove statement at ("test/cases/constant.c": line 5)
1 inline variable y at ("test/cases/constant.c": line 4)
0 inline variable x at ("test/cases/constant.c": line 1)
int x = 10;
int main() int main()
{ {
int i = 0;
} }
1 remove statement at ("test/cases/constant.c": line 5)
1 inline variable y at ("test/cases/constant.c": line 4)
0 inline variable x at ("test/cases/constant.c": line 1)
int main()
{
int y = 25;
return 10 + y;
}
0 remove statement at ("test/cases/constant.c": line 5)
0 inline variable y at ("test/cases/constant.c": line 4)
1 inline variable x at ("test/cases/constant.c": line 1)
int main()
{
int y = 25;
}
1 remove statement at ("test/cases/constant.c": line 5)
0 inline variable y at ("test/cases/constant.c": line 4)
1 inline variable x at ("test/cases/constant.c": line 1)
int main()
{
return 10 + 25;
}
0 remove statement at ("test/cases/constant.c": line 5)
1 inline variable y at ("test/cases/constant.c": line 4)
1 inline variable x at ("test/cases/constant.c": line 1)
int main()
{
}
1 remove statement at ("test/cases/constant.c": line 5)
1 inline variable y at ("test/cases/constant.c": line 4)
1 inline variable x at ("test/cases/constant.c": line 1)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment