git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: add/use map::make convenience function; other cleanup
812a9a7Andy Arvanitis
pcc/TestMain.hs+1−1
@@ -74,7 +74,7 @@ main = do
74 when testCaseDirExists $ callProcess "cp" ["-R", testCaseDir, srcDir]
74 when testCaseDirExists $ callProcess "cp" ["-R", testCaseDir, srcDir]
75
75
76 callProcess "make" ["clean"]
76 callProcess "make" ["clean"]
77− callProcess "make" ["debug"]
77+ callProcess "make" ["debug", "-Werror", "-j2"]
78 --
78 --
79 -- Run C++ files
79 -- Run C++ files
80 --
80 --
pcc/runtime/purescript.cc+5−5
@@ -201,7 +201,7 @@ auto operator+(const any& lhs_, const any& rhs_) -> any {
201 case any::Tag::StringLiteral:
201 case any::Tag::StringLiteral:
202 assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
202 assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
203 assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
203 assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
204− return rhs.tag == any::Tag::StringLiteral ? std::string(lhs.r) + rhs.r : lhs.r + *rhs.s;
204+ return rhs.tag == any::Tag::StringLiteral ? string(lhs.r) + rhs.r : lhs.r + *rhs.s;
205 case any::Tag::String:
205 case any::Tag::String:
206 assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
206 assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
207 assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
207 assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
@@ -211,16 +211,16 @@ auto operator+(const any& lhs_, const any& rhs_) -> any {
211 return nullptr;
211 return nullptr;
212}
212}
213
213
214−auto operator+(const any& lhs_, const char * rhs) -> std::string {
214+auto operator+(const any& lhs_, const char * rhs) -> string {
215 const any& lhs = any::unthunkVariant(lhs_);
215 const any& lhs = any::unthunkVariant(lhs_);
216 assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
216 assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
217− return lhs.tag == any::Tag::StringLiteral ? std::string(lhs.r) + rhs : *lhs.s + rhs;
217+ return lhs.tag == any::Tag::StringLiteral ? string(lhs.r) + rhs : *lhs.s + rhs;
218}
218}
219
219
220−auto operator+(const char * lhs, const any& rhs_) -> std::string {
220+auto operator+(const char * lhs, const any& rhs_) -> string {
221 const any& rhs = any::unthunkVariant(rhs_);
221 const any& rhs = any::unthunkVariant(rhs_);
222 assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
222 assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
223− return rhs.tag == any::Tag::StringLiteral ? lhs + std::string(rhs.r) : lhs + *rhs.s;
223+ return rhs.tag == any::Tag::StringLiteral ? lhs + string(rhs.r) : lhs + *rhs.s;
224}
224}
225
225
226auto operator-(const any& lhs_, const any& rhs_) -> any {
226auto operator-(const any& lhs_, const any& rhs_) -> any {
pcc/runtime/purescript.hh+63−17
@@ -44,6 +44,7 @@
44namespace PureScript {
44namespace PureScript {
45
45
46using cstring = const char *;
46using cstring = const char *;
47+using std::string;
47using std::nullptr_t;
48using std::nullptr_t;
48using std::runtime_error;
49using std::runtime_error;
49
50
@@ -163,7 +164,7 @@ class any {
163 mutable fn f;
164 mutable fn f;
164 mutable eff_fn e;
165 mutable eff_fn e;
165 mutable void * u;
166 mutable void * u;
166− mutable managed<std::string> s;
167+ mutable managed<string> s;
167 mutable managed<array> a;
168 mutable managed<array> a;
168 mutable managed<Closure> l;
169 mutable managed<Closure> l;
169 mutable managed<EffClosure> k;
170 mutable managed<EffClosure> k;
@@ -186,13 +187,13 @@ class any {
186
187
187 template <size_t N>
188 template <size_t N>
188 any(const char (&val)[N]) noexcept : tag(Tag::StringLiteral), r(val) {}
189 any(const char (&val)[N]) noexcept : tag(Tag::StringLiteral), r(val) {}
189− any(char * val) : tag(Tag::String), s(make_managed<std::string>(val)) {}
190+ any(char * val) : tag(Tag::String), s(make_managed<string>(val)) {}
190
191
191− any(const std::string& val) : tag(Tag::String), s(make_managed<std::string>(val)) {}
192+ any(const string& val) : tag(Tag::String), s(make_managed<string>(val)) {}
192− any(std::string&& val) noexcept : tag(Tag::String), s(make_managed<std::string>(std::move(val))) {}
193+ any(string&& val) noexcept : tag(Tag::String), s(make_managed<string>(std::move(val))) {}
193
194
194− any(const managed<std::string>& val) noexcept : tag(Tag::String), s(val) {}
195+ any(const managed<string>& val) noexcept : tag(Tag::String), s(val) {}
195− any(managed<std::string>&& val) noexcept : tag(Tag::String), s(std::move(val)) {}
196+ any(managed<string>&& val) noexcept : tag(Tag::String), s(std::move(val)) {}
196
197
197 template <size_t N>
198 template <size_t N>
198 any(map<N>&& val) noexcept : tag(Tag::Map), p(make_managed<map<N>>(std::move(val))) {}
199 any(map<N>&& val) noexcept : tag(Tag::Map), p(make_managed<map<N>>(std::move(val))) {}
@@ -272,13 +273,13 @@ class any {
272 case Tag::EffFunction: e = other.e; break;
273 case Tag::EffFunction: e = other.e; break;
273 case Tag::RawPointer: u = other.u; break;
274 case Tag::RawPointer: u = other.u; break;
274
275
275− case Tag::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
276+ case Tag::String: new (&s) managed<string>(move_if_rvalue<T>(other.s)); break;
276− case Tag::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
277+ case Tag::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
277− case Tag::Closure: new (&l) managed<Closure>(move_if_rvalue<T>(other.l)); break;
278+ case Tag::Closure: new (&l) managed<Closure>(move_if_rvalue<T>(other.l)); break;
278 case Tag::EffClosure: new (&k) managed<EffClosure>(move_if_rvalue<T>(other.k)); break;
279 case Tag::EffClosure: new (&k) managed<EffClosure>(move_if_rvalue<T>(other.k)); break;
279 case Tag::Map:
280 case Tag::Map:
280 case Tag::Data:
281 case Tag::Data:
281− case Tag::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
282+ case Tag::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
282
283
283 default: assert(false && "Bad 'any' tag"); break;
284 default: assert(false && "Bad 'any' tag"); break;
284 }
285 }
@@ -286,13 +287,13 @@ class any {
286
287
287 auto destruct() -> void {
288 auto destruct() -> void {
288 switch (tag) {
289 switch (tag) {
289− case Tag::String: s.~managed<std::string>(); break;
290+ case Tag::String: s.~managed<string>(); break;
290− case Tag::Array: a.~managed<array>(); break;
291+ case Tag::Array: a.~managed<array>(); break;
291− case Tag::Closure: l.~managed<Closure>(); break;
292+ case Tag::Closure: l.~managed<Closure>(); break;
292− case Tag::EffClosure: k.~managed<EffClosure>(); break;
293+ case Tag::EffClosure: k.~managed<EffClosure>(); break;
293 case Tag::Map:
294 case Tag::Map:
294 case Tag::Data:
295 case Tag::Data:
295− case Tag::Pointer: p.~managed<void>(); break;
296+ case Tag::Pointer: p.~managed<void>(); break;
296
297
297 default: break;
298 default: break;
298 }
299 }
@@ -386,8 +387,8 @@ class any {
386 DEFINE_OPERATOR(+, int, int)
387 DEFINE_OPERATOR(+, int, int)
387 DEFINE_OPERATOR(+, double, double)
388 DEFINE_OPERATOR(+, double, double)
388 DEFINE_OPERATOR(+, char, char)
389 DEFINE_OPERATOR(+, char, char)
389− friend auto operator+(const any& lhs, const char * const rhs) -> std::string;
390+ friend auto operator+(const any& lhs, const char * const rhs) -> string;
390− friend auto operator+(const char * const lhs, const any& rhs) -> std::string;
391+ friend auto operator+(const char * const lhs, const any& rhs) -> string;
391
392
392 friend auto operator-(const any&, const any&) -> any;
393 friend auto operator-(const any&, const any&) -> any;
393
394
@@ -461,6 +462,14 @@ inline auto cast(const any& a) ->
461 return *static_cast<T*>(a.extractPointer(IF_DEBUG(Private::TagHelper<T>::tag)));
462 return *static_cast<T*>(a.extractPointer(IF_DEBUG(Private::TagHelper<T>::tag)));
462}
463}
463
464
465+template <typename T,
466+ typename = typename std::enable_if<std::is_pointer<T>::value &&
467+ !std::is_same<T,void*>::value &&
468+ !std::is_same<T,cstring>::value>::type>
469+inline auto cast(const any& a) -> T {
470+ return static_cast<T>(a.extractPointer(IF_DEBUG(Private::TagHelper<T>::tag)));
471+}
472+
464template <typename T>
473template <typename T>
465inline auto cast(const any& a) ->
474inline auto cast(const any& a) ->
466 typename std::enable_if<std::is_same<void*, T>::value, T>::type {
475 typename std::enable_if<std::is_same<void*, T>::value, T>::type {
@@ -496,8 +505,45 @@ namespace map {
496 inline auto get(const Private::Symbol key, const any& a) -> const any& {
505 inline auto get(const Private::Symbol key, const any& a) -> const any& {
497 return get(key, cast<any::map<unknown_size>>(a));
506 return get(key, cast<any::map<unknown_size>>(a));
498 }
507 }
508+
509+ #define P(N) any::map_pair&& arg ## N
510+ #define T(N) any::map<N+1>
511+ #define E(N) std::forward<decltype(arg ## N)>(arg ## N)
512+ #define M(...) {{ __VA_ARGS__, { nullptr, nullptr } }}
513+
514+ inline auto make(P(1)) -> T(1) {
515+ return T(1) M(E(1));
516+ }
517+ inline auto make(P(1), P(2)) -> T(2) {
518+ return T(2) M(E(1), E(2));
519+ }
520+ inline auto make(P(1), P(2), P(3)) -> T(3) {
521+ return T(3) M(E(1), E(2), E(3));
522+ }
523+ inline auto make(P(1), P(2), P(3), P(4)) -> T(4) {
524+ return T(4) M(E(1), E(2), E(3), E(4));
525+ }
526+ inline auto make(P(1), P(2), P(3), P(4), P(5)) -> T(5) {
527+ return T(5) M(E(1), E(2), E(3), E(4), E(5));
528+ }
529+ inline auto make(P(1), P(2), P(3), P(4), P(5), P(6)) -> T(6) {
530+ return T(6) M(E(1), E(2), E(3), E(4), E(5), E(6));
531+ }
532+ inline auto make(P(1), P(2), P(3), P(4), P(5), P(6), P(7)) -> T(7) {
533+ return T(7) M(E(1), E(2), E(3), E(4), E(5), E(6), E(7));
534+ }
535+ inline auto make(P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8)) -> T(8) {
536+ return T(8) M(E(1), E(2), E(3), E(4), E(5), E(6), E(7), E(8));
537+ }
538+
539+ #undef P
540+ #undef T
541+ #undef E
542+ #undef M
499}
543}
500
544
545+namespace record = map;
546+
501namespace data {
547namespace data {
502 template <size_t N, typename T>
548 template <size_t N, typename T>
503 inline auto get(const T& a) ->
549 inline auto get(const T& a) ->
src/Language/PureScript/CodeGen/Cpp/Common.hs−3
@@ -125,7 +125,6 @@ nameIsCppReserved name =
125 , "bitand"
125 , "bitand"
126 , "bitor"
126 , "bitor"
127 , "bool"
127 , "bool"
128− , "boost"
129 , "break"
128 , "break"
130 , "case"
129 , "case"
131 , "cast"
130 , "cast"
@@ -165,7 +164,6 @@ nameIsCppReserved name =
165 , "import"
164 , "import"
166 , "inline"
165 , "inline"
167 , "int"
166 , "int"
168− , "list"
169 , "long"
167 , "long"
170 , "make_managed"
168 , "make_managed"
171 , "make_managed_and_finalized"
169 , "make_managed_and_finalized"
@@ -199,7 +197,6 @@ nameIsCppReserved name =
199 , "static"
197 , "static"
200 , "static_assert"
198 , "static_assert"
201 , "static_cast"
199 , "static_cast"
202− , "std"
203 , "string"
200 , "string"
204 , "struct"
201 , "struct"
205 , "switch"
202 , "switch"
src/Language/PureScript/Pretty/Cpp.hs+15
@@ -107,6 +107,21 @@ literals = mkPattern' match
107 , return " }"
107 , return " }"
108 ]
108 ]
109 match (CppMapLiteral Record []) = return "nullptr"
109 match (CppMapLiteral Record []) = return "nullptr"
110+ match (CppMapLiteral _ ps)
111+ | length ps <= 8 = mconcat <$> sequence
112+ [ return $ mapNS <> "::make(\n"
113+ , withIndent $ do
114+ cpps <-
115+ forM ps $ \(key, value) -> do
116+ value' <- prettyPrintCpp' value
117+ key' <- prettyPrintCpp' key
118+ return $ "{ " <> key' <> ", " <> value' <> " }"
119+ indentString <- currentIndent
120+ return $ T.intercalate ", \n" $ map (indentString <>) cpps
121+ , return "\n"
122+ , currentIndent
123+ , return ")"
124+ ]
110 match (CppMapLiteral _ ps) = mconcat <$> sequence
125 match (CppMapLiteral _ ps) = mconcat <$> sequence
111 [ return $ runType (mapType $ length ps + 1) <> "{{\n"
126 [ return $ runType (mapType $ length ps + 1) <> "{{\n"
112 , withIndent $ do
127 , withIndent $ do