git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: remove StringLiteral code; runtime operators cleanup
bb9396aAndy Arvanitis
pcc/runtime/purescript.cc+40−109
@@ -65,24 +65,23 @@ any::operator char32_t() const {
65}
65}
66
66
67any::operator char() const {
67any::operator char() const {
68− const auto val = cast<decltype(c)>(*this);
68+ const auto val = static_cast<decltype(c)>(*this);
69 assert(val <= std::numeric_limits<char>::max());
69 assert(val <= std::numeric_limits<char>::max());
70 return static_cast<char>(val);
70 return static_cast<char>(val);
71}
71}
72
72
73any::operator size_t() const {
73any::operator size_t() const {
74− const auto sz = cast<int>(*this);
74+ const auto val = static_cast<decltype(i)>(*this);
75− assert(sz >= 0);
75+ assert(val >= 0);
76− return static_cast<size_t>(sz);
76+ return static_cast<size_t>(val);
77+}
78+
79+any::operator const string&() const {
80+ RETURN_VALUE(Tag::String, s, *)
77}
81}
78
82
79any::operator const char *() const {
83any::operator const char *() const {
80− const any& variant = unthunkVariant(*this);
84+ RETURN_VALUE(Tag::String, s->c_str(),)
81− if (variant.tag == Tag::StringLiteral) {
82− return variant.r;
83− }
84− assert(variant.tag == Tag::String);
85− return variant.s->c_str();
86}
85}
87
86
88any::operator const array&() const {
87any::operator const array&() const {
@@ -102,16 +101,16 @@ auto any::unthunkVariant(const any& a) -> const any& {
102}
101}
103
102
104auto any::operator[](const size_t rhs) const -> const any& {
103auto any::operator[](const size_t rhs) const -> const any& {
105− const auto& xs = cast<array>(*this);
104+ const auto& xs = static_cast<const array&>(*this);
106 return xs[rhs];
105 return xs[rhs];
107}
106}
108
107
109auto any::size() const -> size_t {
108auto any::size() const -> size_t {
110− return cast<array>(*this).size();
109+ return static_cast<const array&>(*this).size();
111}
110}
112
111
113auto any::empty() const -> bool {
112auto any::empty() const -> bool {
114− return cast<array>(*this).empty();
113+ return static_cast<const array&>(*this).empty();
115}
114}
116
115
117auto any::contains(const Private::Symbol key) const -> bool {
116auto any::contains(const Private::Symbol key) const -> bool {
@@ -130,50 +129,17 @@ auto any::contains(const Private::Symbol key) const -> bool {
130// Operator helper macros
129// Operator helper macros
131//-----------------------------------------------------------------------------
130//-----------------------------------------------------------------------------
132
131
133−#define DEFINE_CSTR_EQUALS_OPERATOR() \
134− auto operator==(const any& lhs_, const char * rhs) -> bool { \
135− const any& lhs = any::unthunkVariant(lhs_); \
136− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String); \
137− if (lhs.tag == any::Tag::StringLiteral) { \
138− return (lhs.r == rhs) || (strcmp(lhs.r, rhs) == 0); \
139− } \
140− return strcmp(lhs.s->c_str(), rhs) == 0; \
141− } \
142− auto operator==(const char * lhs, const any& rhs_) -> bool { \
143− const any& rhs = any::unthunkVariant(rhs_); \
144− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String); \
145− if (rhs.tag == any::Tag::StringLiteral) { \
146− return (lhs == rhs.r) || (strcmp(lhs, rhs) == 0); \
147− } \
148− return strcmp(lhs, rhs.s->c_str()) == 0; \
149− }
150−
151−#define DEFINE_CSTR_COMPARISON_OPERATOR(op) \
152− auto operator op (const any& lhs, const char * rhs) -> bool { \
153− return strcmp(cast<const char *>(lhs), rhs) op 0; \
154− } \
155− auto operator op (const char * lhs, const any& rhs) -> bool { \
156− return strcmp(lhs, cast<const char *>(rhs)) op 0; \
157− }
158−
159#define DEFINE_COMPARISON_OPERATOR(op) \
132#define DEFINE_COMPARISON_OPERATOR(op) \
160− auto operator op (const any& lhs_, const any& rhs_) -> bool { \
133+ auto operator op (const any& lhs_, const any& rhs) -> bool { \
161 const any& lhs = any::unthunkVariant(lhs_); \
134 const any& lhs = any::unthunkVariant(lhs_); \
162− const any& rhs = any::unthunkVariant(rhs_); \
163 switch (lhs.tag) { \
135 switch (lhs.tag) { \
164− case any::Tag::Integer: assert(lhs.tag == any::Tag::Integer); return lhs.i op rhs.i; \
136+ case any::Tag::Integer: return lhs.i op static_cast<decltype(any::i)>(rhs); \
165− case any::Tag::Double: assert(lhs.tag == any::Tag::Double); return lhs.d op rhs.d; \
137+ case any::Tag::Double: return lhs.d op static_cast<decltype(any::d)>(rhs); \
166− case any::Tag::Character: assert(lhs.tag == any::Tag::Character); return lhs.c op rhs.c; \
138+ case any::Tag::Character: return lhs.c op static_cast<decltype(any::c)>(rhs); \
167− case any::Tag::Boolean: assert(lhs.tag == any::Tag::Boolean); return lhs.b op rhs.b; \
139+ case any::Tag::Boolean: return lhs.b op static_cast<decltype(any::b)>(rhs); \
168− case any::Tag::StringLiteral: \
140+ case any::Tag::String: return *lhs.s op static_cast<const string&>(rhs); \
169− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String); \
141+ case any::Tag::RawPointer: return lhs.v op cast<decltype(any::v)>(rhs); \
170− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String); \
171− return strcmp(lhs.r, rhs.tag == any::Tag::StringLiteral ? rhs.r : rhs.s->c_str()) op 0; \
172− case any::Tag::String: \
173− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String); \
174− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String); \
175− return strcmp(lhs.s->c_str(), rhs.tag == any::Tag::StringLiteral ? rhs.r : rhs.s->c_str()) op 0; \
176− case any::Tag::Pointer: return lhs.p op rhs.p; \
142+ case any::Tag::Pointer: return lhs.p op any::unthunkVariant(rhs).p; \
177 default: assert(false && "Unsupported tag for operator " #op); \
143 default: assert(false && "Unsupported tag for operator " #op); \
178 } \
144 } \
179 return false; \
145 return false; \
@@ -190,91 +156,56 @@ DEFINE_COMPARISON_OPERATOR(<=)
190DEFINE_COMPARISON_OPERATOR(>)
156DEFINE_COMPARISON_OPERATOR(>)
191DEFINE_COMPARISON_OPERATOR(>=)
157DEFINE_COMPARISON_OPERATOR(>=)
192
158
193−DEFINE_CSTR_EQUALS_OPERATOR()
194−DEFINE_CSTR_COMPARISON_OPERATOR(!=)
195−DEFINE_CSTR_COMPARISON_OPERATOR(<)
196−DEFINE_CSTR_COMPARISON_OPERATOR(<=)
197−DEFINE_CSTR_COMPARISON_OPERATOR(>)
198−DEFINE_CSTR_COMPARISON_OPERATOR(>=)
199−
200−auto operator+(const any& lhs_, const any& rhs_) -> any {
159+auto operator+(const any& lhs_, const any& rhs) -> any {
201 const any& lhs = any::unthunkVariant(lhs_);
160 const any& lhs = any::unthunkVariant(lhs_);
202− const any& rhs = any::unthunkVariant(rhs_);
203 switch (lhs.tag) {
161 switch (lhs.tag) {
204− case any::Tag::Integer: assert(lhs.tag == any::Tag::Integer); return lhs.i + rhs.i;
162+ case any::Tag::Integer: return lhs.i + static_cast<decltype(any::i)>(rhs);
205− case any::Tag::Double: assert(lhs.tag == any::Tag::Double); return lhs.d + rhs.d;
163+ case any::Tag::Double: return lhs.d + static_cast<decltype(any::d)>(rhs);
206− case any::Tag::Character: assert(lhs.tag == any::Tag::Character); return decltype(any::c){lhs.c + rhs.c};
164+ case any::Tag::Character: return decltype(any::c){lhs.c + static_cast<decltype(any::c)>(rhs)};
207− case any::Tag::StringLiteral:
165+ case any::Tag::String: return *lhs.s + static_cast<const string&>(rhs);
208− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
209− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
210− return rhs.tag == any::Tag::StringLiteral ? string(lhs.r) + rhs.r : lhs.r + *rhs.s;
211− case any::Tag::String:
212− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
213− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
214− return rhs.tag == any::Tag::StringLiteral ? *lhs.s + rhs.r : *lhs.s + *rhs.s;
215 default: assert(false && "Unsupported tag for '+' operator");
166 default: assert(false && "Unsupported tag for '+' operator");
216 }
167 }
217 return nullptr;
168 return nullptr;
218}
169}
219
170
220−auto operator+(const any& lhs_, const char * rhs) -> string {
171+auto operator-(const any& lhs_, const any& rhs) -> any {
221 const any& lhs = any::unthunkVariant(lhs_);
172 const any& lhs = any::unthunkVariant(lhs_);
222− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String);
223− return lhs.tag == any::Tag::StringLiteral ? string(lhs.r) + rhs : *lhs.s + rhs;
224−}
225−
226−auto operator+(const char * lhs, const any& rhs_) -> string {
227− const any& rhs = any::unthunkVariant(rhs_);
228− assert(rhs.tag == any::Tag::StringLiteral || rhs.tag == any::Tag::String);
229− return rhs.tag == any::Tag::StringLiteral ? lhs + string(rhs.r) : lhs + *rhs.s;
230−}
231−
232−auto operator-(const any& lhs_, const any& rhs_) -> any {
233− const any& lhs = any::unthunkVariant(lhs_);
234− const any& rhs = any::unthunkVariant(rhs_);
235− assert(lhs.tag == rhs.tag);
236 switch (lhs.tag) {
173 switch (lhs.tag) {
237− case any::Tag::Integer: return lhs.i - rhs.i;
174+ case any::Tag::Integer: return lhs.i - static_cast<decltype(any::i)>(rhs);
238− case any::Tag::Double: return lhs.d - rhs.d;
175+ case any::Tag::Double: return lhs.d - static_cast<decltype(any::d)>(rhs);
239− case any::Tag::Character: return decltype(any::c){lhs.c - rhs.c};
176+ case any::Tag::Character: return decltype(any::c){lhs.c - static_cast<decltype(any::c)>(rhs)};
240 default: assert(false && "Unsupported tag for '-' operator");
177 default: assert(false && "Unsupported tag for '-' operator");
241 }
178 }
242 return nullptr;
179 return nullptr;
243}
180}
244
181
245−auto operator*(const any& lhs_, const any& rhs_) -> any {
182+auto operator*(const any& lhs_, const any& rhs) -> any {
246 const any& lhs = any::unthunkVariant(lhs_);
183 const any& lhs = any::unthunkVariant(lhs_);
247− const any& rhs = any::unthunkVariant(rhs_);
248− assert(lhs.tag == rhs.tag);
249 switch (lhs.tag) {
184 switch (lhs.tag) {
250− case any::Tag::Integer: return lhs.i * rhs.i;
185+ case any::Tag::Integer: return lhs.i * static_cast<decltype(any::i)>(rhs);
251− case any::Tag::Double: return lhs.d * rhs.d;
186+ case any::Tag::Double: return lhs.d * static_cast<decltype(any::d)>(rhs);
252− case any::Tag::Character: return decltype(lhs.c){lhs.c - rhs.c};
187+ case any::Tag::Character: return decltype(lhs.c){lhs.c - static_cast<decltype(any::c)>(rhs)};
253 default: assert(false && "Unsupported tag for '*' operator");
188 default: assert(false && "Unsupported tag for '*' operator");
254 }
189 }
255 return nullptr;
190 return nullptr;
256}
191}
257
192
258−auto operator/(const any& lhs_, const any& rhs_) -> any {
193+auto operator/(const any& lhs_, const any& rhs) -> any {
259 const any& lhs = any::unthunkVariant(lhs_);
194 const any& lhs = any::unthunkVariant(lhs_);
260− const any& rhs = any::unthunkVariant(rhs_);
261− assert(lhs.tag == rhs.tag);
262 switch (lhs.tag) {
195 switch (lhs.tag) {
263− case any::Tag::Integer: return lhs.i / rhs.i;
196+ case any::Tag::Integer: return lhs.i / static_cast<decltype(any::i)>(rhs);
264− case any::Tag::Double: return lhs.d / rhs.d;
197+ case any::Tag::Double: return lhs.d / static_cast<decltype(any::d)>(rhs);
265− case any::Tag::Character: return decltype(any::c){lhs.c / rhs.c};
198+ case any::Tag::Character: return decltype(any::c){lhs.c / static_cast<decltype(any::c)>(rhs)};
266 default: assert(false && "Unsupported tag for '/' operator");
199 default: assert(false && "Unsupported tag for '/' operator");
267 }
200 }
268 return nullptr;
201 return nullptr;
269}
202}
270
203
271−auto operator%(const any& lhs_, const any& rhs_) -> any {
204+auto operator%(const any& lhs_, const any& rhs) -> any {
272 const any& lhs = any::unthunkVariant(lhs_);
205 const any& lhs = any::unthunkVariant(lhs_);
273− const any& rhs = any::unthunkVariant(rhs_);
274− assert(lhs.tag == rhs.tag);
275 switch (lhs.tag) {
206 switch (lhs.tag) {
276− case any::Tag::Integer: return lhs.i % rhs.i;
207+ case any::Tag::Integer: return lhs.i % static_cast<decltype(any::i)>(rhs);
277− case any::Tag::Character: return decltype(any::c){lhs.c % rhs.c};
208+ case any::Tag::Character: return decltype(any::c){lhs.c % static_cast<decltype(any::c)>(rhs)};
278 default: assert(false && "Unsupported tag for '%' operator");
209 default: assert(false && "Unsupported tag for '%' operator");
279 }
210 }
280 return nullptr;
211 return nullptr;
pcc/runtime/purescript.hh+34−20
@@ -86,7 +86,6 @@ class any {
86 Double,
86 Double,
87 Character,
87 Character,
88 Boolean,
88 Boolean,
89− StringLiteral,
90 Function,
89 Function,
91 EffFunction,
90 EffFunction,
92 RawPointer,
91 RawPointer,
@@ -115,10 +114,10 @@ class any {
115 template <size_t N>
114 template <size_t N>
116 using data = std::array<const any, N>;
115 using data = std::array<const any, N>;
117
116
118− using array = std::deque<any WITH_ALLOCATOR(any)>;
117+ using array = std::deque<any WITH_ALLOCATOR(any)>;
119− using fn = auto (*)(const any&) -> any;
118+ using fn = auto (*)(const any&) -> any;
120− using eff_fn = auto (*)() -> any;
119+ using eff_fn = auto (*)() -> any;
121− using thunk = auto (*)(const as_thunk) -> const any&;
120+ using thunk = auto (*)(const as_thunk) -> const any&;
122
121
123 private:
122 private:
124 class Closure {
123 class Closure {
@@ -160,7 +159,6 @@ class any {
160 mutable double d;
159 mutable double d;
161 mutable char32_t c;
160 mutable char32_t c;
162 mutable bool b;
161 mutable bool b;
163− mutable cstring r;
164 mutable fn f;
162 mutable fn f;
165 mutable eff_fn e;
163 mutable eff_fn e;
166 mutable void * v;
164 mutable void * v;
@@ -265,7 +263,6 @@ class any {
265 case Tag::Double: d = other.d; break;
263 case Tag::Double: d = other.d; break;
266 case Tag::Character: c = other.c; break;
264 case Tag::Character: c = other.c; break;
267 case Tag::Boolean: b = other.b; break;
265 case Tag::Boolean: b = other.b; break;
268− case Tag::StringLiteral: r = other.r; break;
269 case Tag::Function: f = other.f; break;
266 case Tag::Function: f = other.f; break;
270 case Tag::EffFunction: e = other.e; break;
267 case Tag::EffFunction: e = other.e; break;
271 case Tag::RawPointer: v = other.v; break;
268 case Tag::RawPointer: v = other.v; break;
@@ -337,6 +334,7 @@ class any {
337 operator char32_t() const;
334 operator char32_t() const;
338 operator char() const;
335 operator char() const;
339 operator size_t() const;
336 operator size_t() const;
337+ operator const string&() const;
340 operator const char *() const;
338 operator const char *() const;
341 operator const array&() const;
339 operator const array&() const;
342
340
@@ -357,28 +355,40 @@ class any {
357 static auto unthunkVariant(const any&) -> const any&;
355 static auto unthunkVariant(const any&) -> const any&;
358
356
359 #define DEFINE_OPERATOR(op) \
357 #define DEFINE_OPERATOR(op) \
360− template <typename T> \
358+ template <typename T, \
359+ typename = typename std::enable_if<!std::is_same<T,any>::value && \
360+ !std::is_same<T,const char *>::value>::type> \
361 inline friend auto operator op (const any& lhs, T rhs) -> T { \
361 inline friend auto operator op (const any& lhs, T rhs) -> T { \
362− return static_cast<T>(lhs) op rhs; \
362+ return static_cast<typename std::add_lvalue_reference<typename std::add_const<T>::type >::type>(lhs) op rhs; \
363 } \
363 } \
364− template <typename T> \
364+ template <typename T, \
365+ typename = typename std::enable_if<!std::is_same<T,any>::value && \
366+ !std::is_same<T,const char *>::value>::type> \
365 inline friend auto operator op (T lhs, const any& rhs) -> T { \
367 inline friend auto operator op (T lhs, const any& rhs) -> T { \
366− return lhs op static_cast<T>(rhs); \
368+ return lhs op static_cast<typename std::add_lvalue_reference<typename std::add_const<T>::type >::type>(rhs); \
367 } \
369 } \
368− friend auto operator op (const any&, const any&) -> any;
370+ friend auto operator op (const any&, const any&) -> any; \
369
371
370 #define DEFINE_COMPARISON_OPERATOR(op) \
372 #define DEFINE_COMPARISON_OPERATOR(op) \
371− template <typename T> \
373+ template <typename T, \
374+ typename = typename std::enable_if<!std::is_same<T,any>::value && \
375+ !std::is_same<T,const char *>::value>::type> \
372 inline friend auto operator op (const any& lhs, T rhs) -> bool { \
376 inline friend auto operator op (const any& lhs, T rhs) -> bool { \
373− return static_cast<T>(lhs) op rhs; \
377+ return static_cast<typename std::add_lvalue_reference<typename std::add_const<T>::type >::type>(lhs) op rhs; \
374 } \
378 } \
375− template <typename T> \
379+ template <typename T, \
380+ typename = typename std::enable_if<!std::is_same<T,any>::value && \
381+ !std::is_same<T,const char *>::value>::type> \
376 inline friend auto operator op (T lhs, const any& rhs) -> bool { \
382 inline friend auto operator op (T lhs, const any& rhs) -> bool { \
377− return lhs op static_cast<T>(rhs); \
383+ return lhs op static_cast<typename std::add_lvalue_reference<typename std::add_const<T>::type >::type>(rhs); \
384+ } \
385+ inline friend auto operator op (const any& lhs, const char * rhs) -> bool { \
386+ return static_cast<const string&>(lhs) op rhs; \
387+ } \
388+ inline friend auto operator op (const char * lhs, const any& rhs) -> bool { \
389+ return lhs op static_cast<const string&>(rhs); \
378 } \
390 } \
379 friend auto operator op (const any&, const any&) -> bool; \
391 friend auto operator op (const any&, const any&) -> bool; \
380− friend auto operator op (const any&, const char * const) -> bool; \
381− friend auto operator op (const char * const, const any&) -> bool;
382
392
383 DEFINE_COMPARISON_OPERATOR(==)
393 DEFINE_COMPARISON_OPERATOR(==)
384 DEFINE_COMPARISON_OPERATOR(!=)
394 DEFINE_COMPARISON_OPERATOR(!=)
@@ -393,8 +403,12 @@ class any {
393 DEFINE_OPERATOR(/)
403 DEFINE_OPERATOR(/)
394 DEFINE_OPERATOR(%)
404 DEFINE_OPERATOR(%)
395
405
396− friend auto operator+(const any& lhs, const char * const rhs) -> string;
406+ inline friend auto operator+(const any& lhs, const char * rhs) -> string {
407+ return static_cast<const string&>(lhs) + rhs;
408+ }
397− friend auto operator+(const char * const lhs, const any& rhs) -> string;
409+ inline friend auto operator+(const char * lhs, const any& rhs) -> string {
410+ return lhs + static_cast<const string&>(rhs);
411+ }
398
412
399 friend auto operator-(const any&) -> any; // unary negate
413 friend auto operator-(const any&) -> any; // unary negate
400
414