git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: switch 'map' to std::array
commitfc1751cc0f74d997a6bbc1b1a91b553799c3f0f8 authorAndy Arvanitis <andyarvanitis@gmail.com> dateWed 26 Oct 2016, 22:40 (10 years ago) parented3008c
9 files changed+119−77
pcc/include/purescript.cc+15−27 pcc/include/purescript.hh+39−24 src/Language/PureScript/CodeGen/Cpp.hs+37−11 src/Language/PureScript/CodeGen/Cpp/AST.hs+11−6 src/Language/PureScript/CodeGen/Cpp/Common.hs+1 src/Language/PureScript/CodeGen/Cpp/File.hs+1−1 src/Language/PureScript/CodeGen/Cpp/Optimizer/MagicDo.hs+1−1 src/Language/PureScript/CodeGen/Cpp/Types.hs+8−2 src/Language/PureScript/Pretty/Cpp.hs+6−5
pcc/include/purescript.cc+15−27
@@ -70,10 +70,6 @@ any::operator cstring() const {
7070 return variant.s->c_str();
7171}
7272
73−any::operator const map&() const {
74− RETURN_VALUE(Type::Map, m, *)
75−}
76−
7773any::operator const array&() const {
7874 RETURN_VALUE(Type::Array, a, *)
7975}
@@ -90,21 +86,17 @@ auto any::unthunkVariant(const any& a) -> const any& {
9086 return *variant;
9187}
9288
93−auto any::operator[](const char rhs[]) const -> const any& {
89+auto any::operator[](const symbol_t key) const -> const any& {
9490 const any& variant = unthunkVariant(*this);
9591 assert(variant.type == Type::Map);
96− const auto begin = variant.m->cbegin();
97− const auto end = variant.m->cend();
98− for (auto it = begin; it != end; ++it) {
99− if (it->first == rhs) {
100− return it->second;
92+ // TODO: assumes at least one element -- safe assumption?
93+ const auto m = cast<map<1>>(variant);
94+ decltype(m)::size_type i = 0;
95+ do {
96+ if (m[i].first == key) {
97+ return m[i].second;
10198 }
102− }
103− for (auto it = begin; it != end; ++it) {
104− if (strcmp(it->first, rhs) == 0) {
105− return it->second;
106− }
107− }
99+ } while (m[++i].first != nullptr);
108100 throw runtime_error("map key not found");
109101}
110102
@@ -120,21 +112,17 @@ auto any::operator[](const any& rhs) const -> const any& {
120112 return (*variant.a)[cast<int>(rhs)];
121113}
122114
123−auto any::contains(const char key[]) const -> bool {
115+auto any::contains(const symbol_t key) const -> bool {
124116 const any& variant = unthunkVariant(*this);
125117 assert(variant.type == Type::Map);
126− const auto begin = variant.m->cbegin();
127− const auto end = variant.m->cend();
128− for (auto it = begin; it != end; ++it) {
129− if (it->first == key) {
118+ // TODO: assumes at least one element -- safe assumption?
119+ const auto m = cast<map<1>>(variant);
120+ decltype(m)::size_type i = 0;
121+ do {
122+ if (m[i].first == key) {
130123 return true;
131124 }
132− }
133− for (auto it = begin; it != end; ++it) {
134− if (strcmp(it->first, key) == 0) {
135− return true;
136− }
137− }
125+ } while (m[++i].first != nullptr);
138126 return false;
139127}
140128
pcc/include/purescript.hh+39−24
@@ -30,7 +30,6 @@
3030
3131#include <functional>
3232#include <string>
33−#include <vector>
3433#include <array>
3534#include <deque>
3635#include <utility>
@@ -43,6 +42,18 @@ namespace PureScript {
4342using cstring = const char *;
4443using std::nullptr_t;
4544
45+struct symbol_generator_anchor {};
46+using symbol_t = const symbol_generator_anchor *;
47+
48+template <typename T>
49+struct symbol_generator {
50+ constexpr static symbol_generator_anchor anchor = symbol_generator_anchor{};
51+};
52+template <typename T>
53+constexpr symbol_generator_anchor symbol_generator<T>::anchor;
54+
55+#define SYMBOL(S) &symbol_generator<symbol::S>::anchor
56+
4657// Workaround for missing C++11 version in gcc
4758class runtime_error : public std::runtime_error {
4859public:
@@ -84,11 +95,13 @@ class any {
8495 };
8596 static constexpr as_thunk unthunk = as_thunk{};
8697
87− using map_pair = std::pair<const char * const, const any>;
88− using map = std::vector<map_pair WITH_ALLOCATOR(map_pair)>;
98+ using map_pair = std::pair<const symbol_t, const any>;
99+
100+ template <size_t N>
101+ using map = std::array<const map_pair, N>;
89102
90103 template <size_t N>
91− using data = std::array<any, N>;
104+ using data = std::array<const any, N>;
92105
93106 using array = std::deque<any WITH_ALLOCATOR(any)>;
94107 using fn = auto (*)(const any&) -> any;
@@ -140,7 +153,6 @@ class any {
140153 mutable eff_fn e;
141154 mutable void * u;
142155 mutable managed<std::string> s;
143− mutable managed<map> m;
144156 mutable managed<array> a;
145157 mutable managed<closure> l;
146158 mutable managed<eff_closure> k;
@@ -170,8 +182,8 @@ class any {
170182 any(const managed<std::string>& val) noexcept : type(Type::String), s(val) {}
171183 any(managed<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
172184
173− any(const map& val) : type(Type::Map), m(make_managed<map>(val)) {}
174− any(map&& val) noexcept : type(Type::Map), m(make_managed<map>(std::move(val))) {}
185+ template <size_t N>
186+ any(map<N>&& val) noexcept : type(Type::Map), p(make_managed<map<N>>(std::move(val))) {}
175187
176188 template <size_t N>
177189 any(data<N>&& val) noexcept : type(Type::Data), p(make_managed<data<N>>(std::move(val))) {}
@@ -216,7 +228,7 @@ class any {
216228 any(const T& val, typename std::enable_if<std::is_same<T,void*>::value>::type* = 0) noexcept
217229 : type(Type::RawPointer), u(val) {}
218230
219− any(std::nullptr_t) noexcept : type(Type::Pointer), p(nullptr) {}
231+ any(std::nullptr_t) noexcept : type(Type::RawPointer), u(nullptr) {}
220232
221233
222234#if !defined(USE_GC)
@@ -249,10 +261,10 @@ class any {
249261 case Type::RawPointer: u = other.u; break;
250262
251263 case Type::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
252− case Type::Map: new (&m) managed<map>(move_if_rvalue<T>(other.m)); break;
253264 case Type::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
254265 case Type::Closure: new (&l) managed<closure>(move_if_rvalue<T>(other.l)); break;
255266 case Type::EffClosure: new (&k) managed<eff_closure>(move_if_rvalue<T>(other.k)); break;
267+ case Type::Map:
256268 case Type::Data:
257269 case Type::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
258270
@@ -263,10 +275,10 @@ class any {
263275 auto destruct() -> void {
264276 switch (type) {
265277 case Type::String: s.~managed<std::string>(); break;
266− case Type::Map: m.~managed<map>(); break;
267278 case Type::Array: a.~managed<array>(); break;
268279 case Type::Closure: l.~managed<closure>(); break;
269280 case Type::EffClosure: k.~managed<eff_closure>(); break;
281+ case Type::Map:
270282 case Type::Data:
271283 case Type::Pointer: p.~managed<void>(); break;
272284
@@ -314,14 +326,13 @@ class any {
314326 operator bool() const;
315327 operator char() const;
316328 operator cstring() const;
317− operator const map&() const;
318329 operator const array&() const;
319330
320− auto operator[](const char[]) const -> const any&;
331+ auto operator[](const symbol_t) const -> const any&;
321332 auto operator[](const size_t) const -> const any&;
322333 auto operator[](const any&) const -> const any&;
323334
324− auto contains(const char[]) const -> bool;
335+ auto contains(const symbol_t) const -> bool;
325336
326337 auto extractPointer(IF_DEBUG(const Type)) const -> void*;
327338
@@ -389,19 +400,25 @@ class any {
389400 DEFINE_OPERATOR(%, char, char)
390401
391402 friend auto operator-(const any&) -> any; // unary negate
392−};
403+
404+}; // class any
393405
394406template <typename T, typename U=void>
395−struct TypeTag {};
407+struct tag_helper {};
408+
409+template <size_t N>
410+struct tag_helper<any::map<N>> {
411+ static constexpr any::Type tag = any::Type::Map;
412+};
396413
397414template <size_t N>
398−struct TypeTag<any::data<N>> {
399− static constexpr any::Type TypeId = any::Type::Data;
415+struct tag_helper<any::data<N>> {
416+ static constexpr any::Type tag = any::Type::Data;
400417};
401418
402419template <typename T>
403−struct TypeTag<T> {
404− static constexpr any::Type TypeId = any::Type::Pointer;
420+struct tag_helper<T> {
421+ static constexpr any::Type tag = any::Type::Pointer;
405422};
406423
407424template <typename T>
@@ -413,16 +430,14 @@ inline auto cast(const any& a) ->
413430
414431template <typename T>
415432inline auto cast(const any& a) ->
416− typename std::enable_if<std::is_same<T, any::map>::value ||
417− std::is_same<T, any::array>::value, const T&>::type {
433+ typename std::enable_if<std::is_same<T, any::array>::value, const T&>::type {
418434 return a;
419435}
420436
421437template <typename T, typename = typename std::enable_if<std::is_class<T>::value>::type>
422438inline auto cast(const any& a) ->
423− typename std::enable_if<!std::is_same<T, any::map>::value &&
424− !std::is_same<T, any::array>::value, T&>::type {
425− return *static_cast<T*>(a.extractPointer(IF_DEBUG(TypeTag<T>::TypeId)));
439+ typename std::enable_if<!std::is_same<T, any::array>::value, T&>::type {
440+ return *static_cast<T*>(a.extractPointer(IF_DEBUG(tag_helper<T>::tag)));
426441}
427442
428443template <typename T>
src/Language/PureScript/CodeGen/Cpp.hs+37−11
@@ -99,9 +99,10 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
9999 P.linebreak ++
100100 fileEnd mn "HH"
101101 let bodyCpps = toBodyDecl optimized ++ toBody optimized
102+ symbols = allSymbols bodyCpps
102103 moduleBody =
103104 CppInclude (runModuleName mn) (runModuleName mn) :
104− P.linebreak ++
105+ symbolDefs symbols :
105106 (if null bodyCpps
106107 then []
107108 else [ CppNamespace (runModuleName mn) $
@@ -186,10 +187,15 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
186187 args' = (\i -> (identToCpp i, aty)) <$> fst abs'
187188 abs' = unAbs body []
188189 isAccessor :: Expr Ann -> Bool
189− isAccessor Accessor{} = True
190+ isAccessor (Accessor _ _ e)
191+ | (_, f, _, _) <- everythingOnValues (&&) (const False) notAbs (const False) (const False) = f e
192+ where
193+ notAbs :: Expr Ann -> Bool
194+ notAbs Abs{} = False
195+ notAbs _ = True
190196 isAccessor _ = False
191197 isIndexer :: Cpp -> Bool
192− isIndexer (CppIndexer (CppStringLiteral _) (CppVar _)) = True
198+ isIndexer (CppIndexer (CppSymbol _) (CppVar _)) = True
193199 isIndexer _ = False
194200 classes = qualifiedToCpp (Ident . runProperName) . T.constraintClass <$>
195201 maybe [] extractConstraints ty'
@@ -440,18 +446,20 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
440446 CppArrayLiteral <$> mapM valueToCpp xs
441447
442448 valueToCpp (Literal _ (ObjectLiteral ps)) =
443− CppObjectLiteral CppRecord <$> sortBy (compare `on` fst) <$> mapM (sndM valueToCpp) ps
449+ CppObjectLiteral CppRecord <$>
450+ mapM (sndM valueToCpp) ((\(k,v) -> (CppSymbol k, v)) <$> sortBy (compare `on` fst) ps)
444451
445452 valueToCpp (Accessor _ prop val) =
446− CppIndexer <$> pure (CppStringLiteral prop) <*> valueToCpp val
453+ CppIndexer <$> pure (CppSymbol prop) <*> valueToCpp val
447454
448455 -- TODO: use a more efficient way of copying/updating the map?
449456 valueToCpp (ObjectUpdate (_, _, Just ty, _) obj ps) = do
450457 obj' <- valueToCpp obj
451458 updatedFields <- mapM (sndM valueToCpp) ps
452459 let origKeys = (allKeys ty) \\ (fst <$> updatedFields)
453− origFields = (\key -> (key, CppIndexer (CppStringLiteral key) obj')) <$> origKeys
454− return $ CppObjectLiteral CppRecord . sortBy (compare `on` fst) $ origFields ++ updatedFields
460+ origFields = (\key -> (key, CppIndexer (CppSymbol key) obj')) <$> origKeys
461+ return $ CppObjectLiteral CppRecord $
462+ (\(k,v) -> (CppSymbol k, v)) <$> sortBy (compare `on` fst) (origFields ++ updatedFields)
455463 where
456464 allKeys :: T.Type -> [String]
457465 allKeys (T.TypeApp (T.TypeConstructor _) r@(T.RCons {})) = fst <$> (fst $ T.rowToList r)
@@ -485,7 +493,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
485493 let Just (_, constraints, fns) = findClass (Qualified mn' (ProperName classname)) in
486494 return . CppObjectLiteral CppInstance $
487495 zip
488− ((sort $ superClassDictionaryNames constraints) ++ (fst <$> fns))
496+ (CppSymbol <$> (sort $ superClassDictionaryNames constraints) ++ (fst <$> fns))
489497 args'
490498 Var _ (Qualified (Just _) _) -> applied f args' curriedName'
491499 _ -> applied f args' id
@@ -716,7 +724,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
716724 (propVar, Nothing)
717725 []
718726 (Just $ CppIndexer
719− (CppStringLiteral prop)
727+ (CppSymbol prop)
720728 (CppVar varName))
721729 : cpp
722730
@@ -872,12 +880,12 @@ extractConstraints = go []
872880---------------------------------------------------------------------------------------------------
873881dictIndexerToEnum :: [(Cpp,Cpp)] -> Cpp -> Cpp
874882---------------------------------------------------------------------------------------------------
875−dictIndexerToEnum repls (CppIndexer (CppStringLiteral prop) dict)
883+dictIndexerToEnum repls (CppIndexer (CppSymbol prop) dict)
876884 | Just cls <- lookup dict repls =
877885 CppBinary Dot
878886 (CppIndexer
879887 (CppAccessor (CppVar . identToCpp $ Ident prop) cls)
880− (CppCast mapType dict))
888+ (CppCast (mapType 1) dict))
881889 (CppVar "second")
882890dictIndexerToEnum _ cpp = cpp
883891
@@ -918,3 +926,21 @@ convertIfPrimFn (Just ty) (CppFunction name params _ qs body)
918926 | (tys', Just rty') <- primFn ty =
919927 CppFunction name (zipWith (\(p, _) t -> (p, Just t)) params tys') (Just rty') qs body
920928convertIfPrimFn _ cpp = cpp
929+
930+---------------------------------------------------------------------------------------------------
931+allSymbols :: [Cpp] -> [String]
932+---------------------------------------------------------------------------------------------------
933+allSymbols cpps = nub $ concatMap (everythingOnCpp (++) symbols) cpps
934+ where
935+ symbols :: Cpp -> [String]
936+ symbols (CppSymbol s) = [symbolname s]
937+ symbols _ = []
938+
939+---------------------------------------------------------------------------------------------------
940+symbolDefs :: [String] -> Cpp
941+---------------------------------------------------------------------------------------------------
942+symbolDefs [] = CppNoOp
943+symbolDefs syms = CppNamespace "PureScript" [CppNamespace "symbol" (asFunc <$> syms)]
944+ where
945+ asFunc :: String -> Cpp
946+ asFunc s = CppStruct s []
src/Language/PureScript/CodeGen/Cpp/AST.hs+11−6
@@ -185,7 +185,7 @@ data Cpp
185185 -- |
186186 -- An object literal
187187 --
188− | CppObjectLiteral CppObjectType [(String, Cpp)]
188+ | CppObjectLiteral CppObjectType [(Cpp, Cpp)]
189189 -- |
190190 -- An general property accessor expression (property, expr)
191191 --
@@ -211,6 +211,11 @@ data Cpp
211211 --
212212 | CppVar String
213213 -- |
214+ -- Unique system-wide name/constant
215+ --
216+ | CppSymbol String
217+ -- |
218+ -- |
214219 -- A block of expressions in braces
215220 --
216221 | CppBlock [Cpp]
@@ -297,7 +302,7 @@ everywhereOnCpp f = go
297302 go (CppArrayLiteral cpp) = f (CppArrayLiteral (map go cpp))
298303 go (CppDataLiteral cpp) = f (CppDataLiteral (map go cpp))
299304 go (CppIndexer j1 j2) = f (CppIndexer (go j1) (go j2))
300− go (CppObjectLiteral t cpp) = f (CppObjectLiteral t (map (fmap go) cpp))
305+ go (CppObjectLiteral t cpps) = f (CppObjectLiteral t (map (fmap go) cpps))
301306 go (CppAccessor prop j) = f (CppAccessor (go prop) (go j))
302307 go (CppFunction name args rty qs j) = f (CppFunction name args rty qs (go j))
303308 go (CppLambda cps args rty j) = f (CppLambda cps args rty (go j))
@@ -328,7 +333,7 @@ everywhereOnCppTopDownM f = f >=> go
328333 go (CppArrayLiteral cpp) = CppArrayLiteral <$> traverse f' cpp
329334 go (CppDataLiteral cpp) = CppDataLiteral <$> traverse f' cpp
330335 go (CppIndexer j1 j2) = CppIndexer <$> f' j1 <*> f' j2
331− go (CppObjectLiteral t cpp) = CppObjectLiteral t <$> traverse (sndM f') cpp
336+ go (CppObjectLiteral t cpps) = CppObjectLiteral t <$> traverse (pairM f' f') cpps
332337 go (CppAccessor prop j) = CppAccessor prop <$> f' j
333338 go (CppFunction name args rty qs j) = CppFunction name args rty qs <$> f' j
334339 go (CppLambda cps args rty j) = CppLambda cps args rty <$> f' j
@@ -341,7 +346,7 @@ everywhereOnCppTopDownM f = f >=> go
341346 go (CppAssignment j1 j2) = CppAssignment <$> f' j1 <*> f' j2
342347 go (CppWhile j1 j2) = CppWhile <$> f' j1 <*> f' j2
343348 go (CppIfElse j1 j2 j3) = CppIfElse <$> f' j1 <*> f' j2 <*> traverse f' j3
344− go (CppSwitch cpp cpps) = CppSwitch <$> f' cpp <*> traverse (sndM f') cpps
349+ go (CppSwitch cpp cpps) = CppSwitch <$> f' cpp <*> traverse (pairM f' f') cpps
345350 go (CppReturn j) = CppReturn <$> f' j
346351 go (CppThrow j) = CppThrow <$> f' j
347352 go (CppComment com j) = CppComment com <$> f' j
@@ -355,7 +360,7 @@ everythingOnCpp (<>) f = go
355360 go j@(CppArrayLiteral cpp) = foldl (<>) (f j) (map go cpp)
356361 go j@(CppDataLiteral cpp) = foldl (<>) (f j) (map go cpp)
357362 go j@(CppIndexer j1 j2) = f j <> go j1 <> go j2
358− go j@(CppObjectLiteral _ cpp) = foldl (<>) (f j) (map (go . snd) cpp)
363+ go j@(CppObjectLiteral _ cpps) = foldl (<>) (f j) ((map (go . fst) cpps) ++ (map (go . snd) cpps))
359364 go j@(CppAccessor j1 j2) = f j <> go j1 <> go j2
360365 go j@(CppFunction _ _ _ _ j1) = f j <> go j1
361366 go j@(CppLambda _ _ _ j1) = f j <> go j1
@@ -369,7 +374,7 @@ everythingOnCpp (<>) f = go
369374 go j@(CppWhile j1 j2) = f j <> go j1 <> go j2
370375 go j@(CppIfElse j1 j2 Nothing) = f j <> go j1 <> go j2
371376 go j@(CppIfElse j1 j2 (Just j3)) = f j <> go j1 <> go j2 <> go j3
372− go j@(CppSwitch cpp cpps) = foldl (<>) (f j <> go cpp) (map (go . snd) cpps)
377+ go j@(CppSwitch cpp cpps) = foldl (<>) (f j <> go cpp) ((map (go . fst) cpps) ++ (map (go . snd) cpps))
373378 go j@(CppReturn j1) = f j <> go j1
374379 go j@(CppThrow j1) = f j <> go j1
375380 go j@(CppComment _ j1) = f j <> go j1
src/Language/PureScript/CodeGen/Cpp/Common.hs+1
@@ -167,6 +167,7 @@ nameIsCppReserved name =
167167 , "string"
168168 , "struct"
169169 , "switch"
170+ , "symbol"
170171 , "template"
171172 , "this"
172173 , "thread_local"
src/Language/PureScript/CodeGen/Cpp/File.hs+1−1
@@ -141,7 +141,7 @@ toBody = catMaybes . map go
141141 addCaptures :: Cpp -> Cpp
142142 addCaptures (CppObjectLiteral t objs) = CppObjectLiteral t (objlam <$> objs)
143143 where
144− objlam :: (String, Cpp) -> (String, Cpp)
144+ objlam :: (Cpp, Cpp) -> (Cpp, Cpp)
145145 objlam (name', (CppLambda _ args rty body)) = (name' , CppLambda [] args rty $ addCaptures body)
146146 objlam obj = obj
147147 addCaptures (CppApp (CppLambda _ [] rty body) []) = CppApp (CppLambda [] [] rty (addCaptures body)) []
src/Language/PureScript/CodeGen/Cpp/Optimizer/MagicDo.hs+1−1
@@ -128,7 +128,7 @@ inlineST = everywhereOnCpp convertBlock
128128 -- or in a more aggressive way, turning wrappers into local variables depending on the
129129 -- agg(ressive) parameter.
130130 convert agg (CppApp f [arg]) | isSTFunc C.newSTRef f =
131− CppLambda [CppCaptureAll] [] Nothing (CppBlock [CppReturn $ if agg then arg else CppObjectLiteral CppRecord [(C.stRefValue, arg)]])
131+ CppLambda [CppCaptureAll] [] Nothing (CppBlock [CppReturn $ if agg then arg else CppObjectLiteral CppRecord [(CppSymbol C.stRefValue, arg)]])
132132 convert agg (CppApp (CppApp f [ref]) []) | isSTFunc C.readSTRef f =
133133 if agg then ref else CppAccessor (CppVar C.stRefValue) ref
134134 convert agg (CppApp (CppApp (CppApp f [ref]) [arg]) []) | isSTFunc C.writeSTRef f =
src/Language/PureScript/CodeGen/Cpp/Types.hs+8−2
@@ -124,8 +124,11 @@ stringType = CppPrimitive "string"
124124charType :: CppType
125125charType = CppPrimitive "char"
126126
127−mapType :: CppType
128−mapType = CppPrimitive "any::map"
127+voidType :: CppType
128+voidType = CppPrimitive "void"
129+
130+mapType :: Int -> CppType
131+mapType n = CppPrimitive $ "any::map<" ++ show n ++ ">"
129132
130133dataType :: Int -> CppType
131134dataType n = CppPrimitive $ "any::data<" ++ show n ++ ">"
@@ -141,3 +144,6 @@ ctorKey = "constructor"
141144
142145constAnyRef :: Maybe CppType
143146constAnyRef = Just $ CppAny [CppConst, CppRef]
147+
148+symbolname :: String -> String
149+symbolname = identToCpp . Ident
src/Language/PureScript/Pretty/Cpp.hs+6−5
@@ -40,7 +40,6 @@ import qualified Control.Arrow as A
4040import Language.PureScript.CodeGen.Cpp.AST
4141import Language.PureScript.CodeGen.Cpp.Types
4242import Language.PureScript.Comments
43−-- import Language.PureScript.Pretty.Common
4443import qualified Language.PureScript.Constants as C
4544import Numeric
4645-- import Debug.Trace
@@ -118,17 +117,17 @@ literals = mkPattern' match
118117 , return " }"
119118 ]
120119 match (CppObjectLiteral _ ps) = fmap concat $ sequence
121− [ return $ runType mapType ++ "{\n"
120+ [ return $ runType (mapType $ length ps + 1) ++ "{{\n"
122121 , withIndent $ do
123122 cpps <- forM ps $ \(key, value) -> do
124123 value' <- prettyPrintCpp' value
125− key' <- prettyPrintCpp' (CppStringLiteral key)
124+ key' <- prettyPrintCpp' key
126125 return $ "{ " ++ key' ++ ", " ++ value' ++ " }"
127126 indentString <- currentIndent
128− return $ intercalate ", \n" $ map (indentString ++) cpps
127+ return $ intercalate ", \n" $ map (indentString ++) (cpps ++ ["{ nullptr, nullptr }"])
129128 , return "\n"
130129 , currentIndent
131− , return "}"
130+ , return "}}"
132131 ]
133132
134133 match (CppFunction name args rty qs ret) =
@@ -196,6 +195,7 @@ literals = mkPattern' match
196195 isUseNamespace :: Cpp -> Bool
197196 isUseNamespace (CppUseNamespace{}) = True
198197 isUseNamespace _ = False
198+ match (CppStruct (name) []) = return $ "struct " ++ name ++ " {}"
199199 match (CppStruct (name) mems) = fmap concat $ sequence $
200200 [ return "\n"
201201 , currentIndent
@@ -240,6 +240,7 @@ literals = mkPattern' match
240240
241241 match (CppVar ident) | ident == C.__unused = match (CppVar $ '$':ident)
242242 match (CppVar ident) = return ident
243+ match (CppSymbol ident) = return $ "SYMBOL" ++ parens (symbolname ident)
243244 match (CppApp v [CppNoOp]) = return (prettyPrintCpp1 v)
244245 match (CppVariableIntroduction (ident, typ) qs value)
245246 | ident == C.__unused = match (CppVariableIntroduction ('$':ident, typ) qs value)