@@ -18,11 +18,12 @@
1818
1919module Language.PureScript.CodeGen.Cpp.Common where
2020
21−import Prelude.Compat hiding (all, concatMap, last, init, null)
21+import Prelude.Compat hiding (all, any, concatMap, last, init, map, null)
2222
2323import Data.Char
24−import Data.Text hiding (map)
24+import Data.Text hiding (foldl1)
2525import Data.Monoid ((<>))
26+import qualified Language.PureScript.Constants as C
2627import Language.PureScript.Crash
2728import Language.PureScript.Names
2829
@@ -45,6 +46,10 @@ safeName name
4546safeName name
4647 | Just ('$', s) <- uncons name
4748 , all isDigit s = name
49+safeName name
50+ | C.__superclass_ `isPrefixOf` name
51+ , any (=='.') name
52+ = "$" <> (escaped $ dotsTo '_' name)
4853safeName name
4954 | "_" `isPrefixOf` name = "$" <> escaped name
5055safeName name = escaped name
@@ -52,6 +57,9 @@ safeName name = escaped name
5257escaped :: Text -> Text
5358escaped = escapeDoubleUnderscores . concatMap identCharToText
5459
60+dotsTo :: Char -> Text -> Text
61+dotsTo chr' = map (\c -> if c == '.' then chr' else c)
62+
5563-- |
5664-- C++ actually reserves all identifiers containing double
5765-- underscores.
@@ -235,8 +243,12 @@ normalizedName = unescapeDoubleUnderscores . normalizedName'
235243
236244moduleNameToCpp :: ModuleName -> Text
237245moduleNameToCpp (ModuleName pns) =
238− let name = intercalate "_" (runProperName `map` pns)
239− in if properNameIsCppReserved name then name <> "$" else name
246+ if properNameIsCppReserved name then name <> "$" else name
247+ where
248+ pnames = runProperName <$> pns
249+ name
250+ | foldl1 (||) (any (=='_') <$> pnames) = error "Module names can now contain underscores"
251+ | otherwise = intercalate "_" pnames
240252
241253-- |
242254-- Checks whether a proper name is reserved in C++11.