git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: add/use map::make convenience function; other cleanup
commit812a9a70cede8e32ee40ed7dc0a447513798b0b2 authorAndy Arvanitis <andyarvanitis@gmail.com> dateSun 1 Jan 2017, 13:59 (10 years ago) parentaa9b6a2
5 files changed+84−26
pcc/TestMain.hs+1−1 pcc/runtime/purescript.cc+5−5 pcc/runtime/purescript.hh+63−17 src/Language/PureScript/CodeGen/Cpp/Common.hs−3 src/Language/PureScript/Pretty/Cpp.hs+15
pcc/TestMain.hs+1−1
@@ -74,7 +74,7 @@ main = do
7474 when testCaseDirExists $ callProcess "cp" ["-R", testCaseDir, srcDir]
7575
7676 callProcess "make" ["clean"]
77− callProcess "make" ["debug"]
77+ callProcess "make" ["debug", "-Werror", "-j2"]
7878 --
7979 -- Run C++ files
8080 --
pcc/runtime/purescript.cc+5−5
@@ -201,7 +201,7 @@ auto operator+(const any& lhs_, const any& rhs_) -> any {
201201 case any::Tag::StringLiteral:
202202 assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
203203 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;
205205 case any::Tag::String:
206206 assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
207207 assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
@@ -211,16 +211,16 @@ auto operator+(const any& lhs_, const any& rhs_) -> any {
211211 return nullptr;
212212}
213213
214−auto operator+(const any& lhs_, const char * rhs) -> std::string {
214+auto operator+(const any& lhs_, const char * rhs) -> string {
215215 const any& lhs = any::unthunkVariant(lhs_);
216216 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;
218218}
219219
220−auto operator+(const char * lhs, const any& rhs_) -> std::string {
220+auto operator+(const char * lhs, const any& rhs_) -> string {
221221 const any& rhs = any::unthunkVariant(rhs_);
222222 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;
224224}
225225
226226auto operator-(const any& lhs_, const any& rhs_) -> any {
pcc/runtime/purescript.hh+63−17
@@ -44,6 +44,7 @@
4444namespace PureScript {
4545
4646using cstring = const char *;
47+using std::string;
4748using std::nullptr_t;
4849using std::runtime_error;
4950
@@ -163,7 +164,7 @@ class any {
163164 mutable fn f;
164165 mutable eff_fn e;
165166 mutable void * u;
166− mutable managed<std::string> s;
167+ mutable managed<string> s;
167168 mutable managed<array> a;
168169 mutable managed<Closure> l;
169170 mutable managed<EffClosure> k;
@@ -186,13 +187,13 @@ class any {
186187
187188 template <size_t N>
188189 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)) {}
190191
191− any(const std::string& val) : tag(Tag::String), s(make_managed<std::string>(val)) {}
192− any(std::string&& val) noexcept : tag(Tag::String), s(make_managed<std::string>(std::move(val))) {}
192+ any(const string& val) : tag(Tag::String), s(make_managed<string>(val)) {}
193+ any(string&& val) noexcept : tag(Tag::String), s(make_managed<string>(std::move(val))) {}
193194
194− any(const managed<std::string>& val) noexcept : tag(Tag::String), s(val) {}
195− any(managed<std::string>&& val) noexcept : tag(Tag::String), s(std::move(val)) {}
195+ any(const managed<string>& val) noexcept : tag(Tag::String), s(val) {}
196+ any(managed<string>&& val) noexcept : tag(Tag::String), s(std::move(val)) {}
196197
197198 template <size_t N>
198199 any(map<N>&& val) noexcept : tag(Tag::Map), p(make_managed<map<N>>(std::move(val))) {}
@@ -272,13 +273,13 @@ class any {
272273 case Tag::EffFunction: e = other.e; break;
273274 case Tag::RawPointer: u = other.u; break;
274275
275− case Tag::String: new (&s) managed<std::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::Closure: new (&l) managed<Closure>(move_if_rvalue<T>(other.l)); break;
276+ case Tag::String: new (&s) managed<string>(move_if_rvalue<T>(other.s)); break;
277+ case Tag::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
278+ case Tag::Closure: new (&l) managed<Closure>(move_if_rvalue<T>(other.l)); break;
278279 case Tag::EffClosure: new (&k) managed<EffClosure>(move_if_rvalue<T>(other.k)); break;
279280 case Tag::Map:
280281 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;
282283
283284 default: assert(false && "Bad 'any' tag"); break;
284285 }
@@ -286,13 +287,13 @@ class any {
286287
287288 auto destruct() -> void {
288289 switch (tag) {
289− case Tag::String: s.~managed<std::string>(); break;
290− case Tag::Array: a.~managed<array>(); break;
291− case Tag::Closure: l.~managed<Closure>(); break;
292− case Tag::EffClosure: k.~managed<EffClosure>(); break;
290+ case Tag::String: s.~managed<string>(); break;
291+ case Tag::Array: a.~managed<array>(); break;
292+ case Tag::Closure: l.~managed<Closure>(); break;
293+ case Tag::EffClosure: k.~managed<EffClosure>(); break;
293294 case Tag::Map:
294295 case Tag::Data:
295− case Tag::Pointer: p.~managed<void>(); break;
296+ case Tag::Pointer: p.~managed<void>(); break;
296297
297298 default: break;
298299 }
@@ -386,8 +387,8 @@ class any {
386387 DEFINE_OPERATOR(+, int, int)
387388 DEFINE_OPERATOR(+, double, double)
388389 DEFINE_OPERATOR(+, char, char)
389− friend auto operator+(const any& lhs, const char * const rhs) -> std::string;
390− friend auto operator+(const char * const lhs, const any& rhs) -> std::string;
390+ friend auto operator+(const any& lhs, const char * const rhs) -> string;
391+ friend auto operator+(const char * const lhs, const any& rhs) -> string;
391392
392393 friend auto operator-(const any&, const any&) -> any;
393394
@@ -461,6 +462,14 @@ inline auto cast(const any& a) ->
461462 return *static_cast<T*>(a.extractPointer(IF_DEBUG(Private::TagHelper<T>::tag)));
462463}
463464
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+
464473template <typename T>
465474inline auto cast(const any& a) ->
466475 typename std::enable_if<std::is_same<void*, T>::value, T>::type {
@@ -496,8 +505,45 @@ namespace map {
496505 inline auto get(const Private::Symbol key, const any& a) -> const any& {
497506 return get(key, cast<any::map<unknown_size>>(a));
498507 }
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
499543}
500544
545+namespace record = map;
546+
501547namespace data {
502548 template <size_t N, typename T>
503549 inline auto get(const T& a) ->
src/Language/PureScript/CodeGen/Cpp/Common.hs−3
@@ -125,7 +125,6 @@ nameIsCppReserved name =
125125 , "bitand"
126126 , "bitor"
127127 , "bool"
128− , "boost"
129128 , "break"
130129 , "case"
131130 , "cast"
@@ -165,7 +164,6 @@ nameIsCppReserved name =
165164 , "import"
166165 , "inline"
167166 , "int"
168− , "list"
169167 , "long"
170168 , "make_managed"
171169 , "make_managed_and_finalized"
@@ -199,7 +197,6 @@ nameIsCppReserved name =
199197 , "static"
200198 , "static_assert"
201199 , "static_cast"
202− , "std"
203200 , "string"
204201 , "struct"
205202 , "switch"
src/Language/PureScript/Pretty/Cpp.hs+15
@@ -107,6 +107,21 @@ literals = mkPattern' match
107107 , return " }"
108108 ]
109109 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+ ]
110125 match (CppMapLiteral _ ps) = mconcat <$> sequence
111126 [ return $ runType (mapType $ length ps + 1) <> "{{\n"
112127 , withIndent $ do