@@ -85,24 +85,18 @@ literals = mkPattern' match
85 match (CppCharLiteral c) = return $ "'" <> T.singleton c <> "'"
85 match (CppCharLiteral c) = return $ "'" <> T.singleton c <> "'"
86 match (CppBooleanLiteral True) = return "true"
86 match (CppBooleanLiteral True) = return "true"
87 match (CppBooleanLiteral False) = return "false"
87 match (CppBooleanLiteral False) = return "false"
88− match (CppArrayLiteral [x@CppArrayLiteral {}]) = -- Works around what appears to be a recent clang bug
90− [ return $ runType arrayType
88+ match (CppArrayLiteral []) = return $ runType arrayType <> "{}"
95 match (CppArrayLiteral xs) = mconcat <$> sequence
89 match (CppArrayLiteral xs) = mconcat <$> sequence
96 [ return $ runType arrayType
90 [ return $ runType arrayType
97− , return "{ "
91+ , return "{{ "
98 , fmap (T.intercalate ", ") $ forM xs prettyPrintCpp'
92 , fmap (T.intercalate ", ") $ forM xs prettyPrintCpp'
99− , return " }"
93+ , return " }}"
101 match (CppDataLiteral xs) = mconcat <$> sequence
95 match (CppDataLiteral xs) = mconcat <$> sequence
102 [ return $ runType (dataType $ length xs)
96 [ return $ runType (dataType $ length xs)
103− , return "{ "
97+ , return "{{ "
104 , fmap (T.intercalate ", ") $ forM xs prettyPrintCpp'
98 , fmap (T.intercalate ", ") $ forM xs prettyPrintCpp'
105− , return " }"
99+ , return " }}"
107 match (CppEnum name ty es) = mconcat <$> sequence
101 match (CppEnum name ty es) = mconcat <$> sequence
108 [ return "enum"
102 [ return "enum"
@@ -276,15 +270,17 @@ literals = mkPattern' match
276 , prettyPrintCpp' thens
270 , prettyPrintCpp' thens
277 , maybe (return "") (fmap (" else " <>) . prettyPrintCpp') elses
271 , maybe (return "") (fmap (" else " <>) . prettyPrintCpp') elses
279− match (CppSwitch cond cases@((case1,_):_:_)) = mconcat <$> sequence
273+ match (CppSwitch cond cases@((case1,_):_:_) default') = mconcat <$> sequence
280 [ return "switch "
274 [ return "switch "
281 , return . parensT $ prettyPrintCpp1 (cast case1 cond)
275 , return . parensT $ prettyPrintCpp1 (cast case1 cond)
282 , return " {\n"
276 , return " {\n"
283 , withIndent $ do
277 , withIndent $ do
284− cpps <- forM cases $ \(c, s) -> do
278+ cpps <- forM (normalizeBlocks $
279+ cases ++ maybe [] (\c -> [(CppNoOp,c)]) default')
285− c' <- prettyPrintCpp' c
281+ c' <- prettyPrintCpp' c
286− s' <- prettyPrintCpp' s
282+ s' <- prettyPrintCpp' s
287− return $ "case " <> c' <> ": " <> s' <> ";"
283+ return $ label c <> c' <> ": " <> s' <> caseEnd s
288 indentString <- currentIndent
284 indentString <- currentIndent
289 return $ T.intercalate "\n" $ map (indentString <>) cpps
285 return $ T.intercalate "\n" $ map (indentString <>) cpps
290 , return "\n"
286 , return "\n"
@@ -297,6 +293,25 @@ literals = mkPattern' match
297 cast CppBooleanLiteral {} cpp' = CppCast boolType cpp'
293 cast CppBooleanLiteral {} cpp' = CppCast boolType cpp'
298 cast CppCharLiteral {} cpp' = CppCast charType cpp'
294 cast CppCharLiteral {} cpp' = CppCast charType cpp'
299 cast _ cpp' = cpp'
295 cast _ cpp' = cpp'
296+ normalizeBlocks :: [(Cpp,Cpp)] -> [(Cpp,Cpp)]
297+ normalizeBlocks cpps
298+ | any (isBlock . snd) cpps = addBlock <$> cpps
301+ addBlock (cpp1, cpp2@(CppBlock _)) = (cpp1, cpp2)
302+ addBlock (cpp1, cpp2) = (cpp1, CppBlock [cpp2])
303+ label :: Cpp -> Text
304+ label CppNoOp = "default"
306+ caseEnd :: Cpp -> Text
307+ caseEnd (CppReturn {}) = ";"
308+ caseEnd (CppThrow {}) = ";"
309+ caseEnd (CppContinue) = ";"
310+ caseEnd (CppBlock stmts@(_:_))
311+ | (CppReturn {}) <- last stmts = ""
312+ | (CppThrow {}) <- last stmts = ""
313+ | CppContinue <- last stmts = ""
314+ caseEnd _ = " break;"
300 match (CppReturn (CppBlock (cpp:cpps))) = mconcat <$> sequence
315 match (CppReturn (CppBlock (cpp:cpps))) = mconcat <$> sequence
301 [ do s <- prettyPrintCpp' cpp
316 [ do s <- prettyPrintCpp' cpp
302 return $ T.dropWhile isSpace s
317 return $ T.dropWhile isSpace s
@@ -500,9 +515,6 @@ prettyPrintCpp' = A.runKleisli $ runPattern matchValue
500 , [ binary Or " || " ]
515 , [ binary Or " || " ]
503−dotsTo :: Char -> Text -> Text
504−dotsTo chr' = T.map (\c -> if c == '.' then chr' else c)
506argstr :: (Text, Maybe CppType) -> Text
518argstr :: (Text, Maybe CppType) -> Text
507argstr (name, Nothing) = argStr name (Auto [])
519argstr (name, Nothing) = argStr name (Auto [])
508argstr (name, Just typ)
520argstr (name, Just typ)
@@ -538,6 +550,10 @@ isNoOp CppNoOp = True
538isNoOp (CppComment [] CppNoOp) = True
550isNoOp (CppComment [] CppNoOp) = True
539isNoOp _ = False
551isNoOp _ = False
553+isBlock :: Cpp -> Bool
554+isBlock (CppBlock {}) = True
541renderName :: Text -> Text
557renderName :: Text -> Text
542renderName name
558renderName name
543 | Just ('*', name') <- T.uncons name = '$' `T.cons` name'
559 | Just ('*', name') <- T.uncons name = '$' `T.cons` name'