git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: remove StringLiteral code; runtime operators cleanup
commitbb9396aa18d0f511c3e23baec0c9c4b41a181e7d authorAndy Arvanitis <andyarvanitis@gmail.com> dateWed 11 Jan 2017, 11:44 (10 years ago) parent22aec46
2 files changed+74−129
pcc/runtime/purescript.cc+40−109 pcc/runtime/purescript.hh+34−20
pcc/runtime/purescript.cc+40−109
@@ -65,24 +65,23 @@ any::operator char32_t() const {
6565}
6666
6767any::operator char() const {
68− const auto val = cast<decltype(c)>(*this);
68+ const auto val = static_cast<decltype(c)>(*this);
6969 assert(val <= std::numeric_limits<char>::max());
7070 return static_cast<char>(val);
7171}
7272
7373any::operator size_t() const {
74− const auto sz = cast<int>(*this);
75− assert(sz >= 0);
76− return static_cast<size_t>(sz);
74+ const auto val = static_cast<decltype(i)>(*this);
75+ assert(val >= 0);
76+ return static_cast<size_t>(val);
77+}
78+
79+any::operator const string&() const {
80+ RETURN_VALUE(Tag::String, s, *)
7781}
7882
7983any::operator const char *() const {
80− const any& variant = unthunkVariant(*this);
81− if (variant.tag == Tag::StringLiteral) {
82− return variant.r;
83− }
84− assert(variant.tag == Tag::String);
85− return variant.s->c_str();
84+ RETURN_VALUE(Tag::String, s->c_str(),)
8685}
8786
8887any::operator const array&() const {
@@ -102,16 +101,16 @@ auto any::unthunkVariant(const any& a) -> const any& {
102101}
103102
104103auto 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);
106105 return xs[rhs];
107106}
108107
109108auto any::size() const -> size_t {
110− return cast<array>(*this).size();
109+ return static_cast<const array&>(*this).size();
111110}
112111
113112auto any::empty() const -> bool {
114− return cast<array>(*this).empty();
113+ return static_cast<const array&>(*this).empty();
115114}
116115
117116auto any::contains(const Private::Symbol key) const -> bool {
@@ -130,50 +129,17 @@ auto any::contains(const Private::Symbol key) const -> bool {
130129// Operator helper macros
131130//-----------------------------------------------------------------------------
132131
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−
159132#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 { \
161134 const any& lhs = any::unthunkVariant(lhs_); \
162− const any& rhs = any::unthunkVariant(rhs_); \
163135 switch (lhs.tag) { \
164− case any::Tag::Integer: assert(lhs.tag == any::Tag::Integer); return lhs.i op rhs.i; \
165− case any::Tag::Double: assert(lhs.tag == any::Tag::Double); return lhs.d op rhs.d; \
166− case any::Tag::Character: assert(lhs.tag == any::Tag::Character); return lhs.c op rhs.c; \
167− case any::Tag::Boolean: assert(lhs.tag == any::Tag::Boolean); return lhs.b op rhs.b; \
168− case any::Tag::StringLiteral: \
169− assert(lhs.tag == any::Tag::StringLiteral || lhs.tag == any::Tag::String); \
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; \
136+ case any::Tag::Integer: return lhs.i op static_cast<decltype(any::i)>(rhs); \
137+ case any::Tag::Double: return lhs.d op static_cast<decltype(any::d)>(rhs); \
138+ case any::Tag::Character: return lhs.c op static_cast<decltype(any::c)>(rhs); \
139+ case any::Tag::Boolean: return lhs.b op static_cast<decltype(any::b)>(rhs); \
140+ case any::Tag::String: return *lhs.s op static_cast<const string&>(rhs); \
141+ case any::Tag::RawPointer: return lhs.v op cast<decltype(any::v)>(rhs); \
142+ case any::Tag::Pointer: return lhs.p op any::unthunkVariant(rhs).p; \
177143 default: assert(false && "Unsupported tag for operator " #op); \
178144 } \
179145 return false; \
@@ -190,91 +156,56 @@ DEFINE_COMPARISON_OPERATOR(<=)
190156DEFINE_COMPARISON_OPERATOR(>)
191157DEFINE_COMPARISON_OPERATOR(>=)
192158
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 {
201160 const any& lhs = any::unthunkVariant(lhs_);
202− const any& rhs = any::unthunkVariant(rhs_);
203161 switch (lhs.tag) {
204− case any::Tag::Integer: assert(lhs.tag == any::Tag::Integer); return lhs.i + rhs.i;
205− case any::Tag::Double: assert(lhs.tag == any::Tag::Double); return lhs.d + rhs.d;
206− case any::Tag::Character: assert(lhs.tag == any::Tag::Character); return decltype(any::c){lhs.c + rhs.c};
207− case any::Tag::StringLiteral:
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;
162+ case any::Tag::Integer: return lhs.i + static_cast<decltype(any::i)>(rhs);
163+ case any::Tag::Double: return lhs.d + static_cast<decltype(any::d)>(rhs);
164+ case any::Tag::Character: return decltype(any::c){lhs.c + static_cast<decltype(any::c)>(rhs)};
165+ case any::Tag::String: return *lhs.s + static_cast<const string&>(rhs);
215166 default: assert(false && "Unsupported tag for '+' operator");
216167 }
217168 return nullptr;
218169}
219170
220−auto operator+(const any& lhs_, const char * rhs) -> string {
171+auto operator-(const any& lhs_, const any& rhs) -> any {
221172 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);
236173 switch (lhs.tag) {
237− case any::Tag::Integer: return lhs.i - rhs.i;
238− case any::Tag::Double: return lhs.d - rhs.d;
239− case any::Tag::Character: return decltype(any::c){lhs.c - rhs.c};
174+ case any::Tag::Integer: return lhs.i - static_cast<decltype(any::i)>(rhs);
175+ case any::Tag::Double: return lhs.d - static_cast<decltype(any::d)>(rhs);
176+ case any::Tag::Character: return decltype(any::c){lhs.c - static_cast<decltype(any::c)>(rhs)};
240177 default: assert(false && "Unsupported tag for '-' operator");
241178 }
242179 return nullptr;
243180}
244181
245−auto operator*(const any& lhs_, const any& rhs_) -> any {
182+auto operator*(const any& lhs_, const any& rhs) -> any {
246183 const any& lhs = any::unthunkVariant(lhs_);
247− const any& rhs = any::unthunkVariant(rhs_);
248− assert(lhs.tag == rhs.tag);
249184 switch (lhs.tag) {
250− case any::Tag::Integer: return lhs.i * rhs.i;
251− case any::Tag::Double: return lhs.d * rhs.d;
252− case any::Tag::Character: return decltype(lhs.c){lhs.c - rhs.c};
185+ case any::Tag::Integer: return lhs.i * static_cast<decltype(any::i)>(rhs);
186+ case any::Tag::Double: return lhs.d * static_cast<decltype(any::d)>(rhs);
187+ case any::Tag::Character: return decltype(lhs.c){lhs.c - static_cast<decltype(any::c)>(rhs)};
253188 default: assert(false && "Unsupported tag for '*' operator");
254189 }
255190 return nullptr;
256191}
257192
258−auto operator/(const any& lhs_, const any& rhs_) -> any {
193+auto operator/(const any& lhs_, const any& rhs) -> any {
259194 const any& lhs = any::unthunkVariant(lhs_);
260− const any& rhs = any::unthunkVariant(rhs_);
261− assert(lhs.tag == rhs.tag);
262195 switch (lhs.tag) {
263− case any::Tag::Integer: return lhs.i / rhs.i;
264− case any::Tag::Double: return lhs.d / rhs.d;
265− case any::Tag::Character: return decltype(any::c){lhs.c / rhs.c};
196+ case any::Tag::Integer: return lhs.i / static_cast<decltype(any::i)>(rhs);
197+ case any::Tag::Double: return lhs.d / static_cast<decltype(any::d)>(rhs);
198+ case any::Tag::Character: return decltype(any::c){lhs.c / static_cast<decltype(any::c)>(rhs)};
266199 default: assert(false && "Unsupported tag for '/' operator");
267200 }
268201 return nullptr;
269202}
270203
271−auto operator%(const any& lhs_, const any& rhs_) -> any {
204+auto operator%(const any& lhs_, const any& rhs) -> any {
272205 const any& lhs = any::unthunkVariant(lhs_);
273− const any& rhs = any::unthunkVariant(rhs_);
274− assert(lhs.tag == rhs.tag);
275206 switch (lhs.tag) {
276− case any::Tag::Integer: return lhs.i % rhs.i;
277− case any::Tag::Character: return decltype(any::c){lhs.c % rhs.c};
207+ case any::Tag::Integer: return lhs.i % static_cast<decltype(any::i)>(rhs);
208+ case any::Tag::Character: return decltype(any::c){lhs.c % static_cast<decltype(any::c)>(rhs)};
278209 default: assert(false && "Unsupported tag for '%' operator");
279210 }
280211 return nullptr;
pcc/runtime/purescript.hh+34−20
@@ -86,7 +86,6 @@ class any {
8686 Double,
8787 Character,
8888 Boolean,
89− StringLiteral,
9089 Function,
9190 EffFunction,
9291 RawPointer,
@@ -115,10 +114,10 @@ class any {
115114 template <size_t N>
116115 using data = std::array<const any, N>;
117116
118− using array = std::deque<any WITH_ALLOCATOR(any)>;
119− using fn = auto (*)(const any&) -> any;
120− using eff_fn = auto (*)() -> any;
121− using thunk = auto (*)(const as_thunk) -> const any&;
117+ using array = std::deque<any WITH_ALLOCATOR(any)>;
118+ using fn = auto (*)(const any&) -> any;
119+ using eff_fn = auto (*)() -> any;
120+ using thunk = auto (*)(const as_thunk) -> const any&;
122121
123122 private:
124123 class Closure {
@@ -160,7 +159,6 @@ class any {
160159 mutable double d;
161160 mutable char32_t c;
162161 mutable bool b;
163− mutable cstring r;
164162 mutable fn f;
165163 mutable eff_fn e;
166164 mutable void * v;
@@ -265,7 +263,6 @@ class any {
265263 case Tag::Double: d = other.d; break;
266264 case Tag::Character: c = other.c; break;
267265 case Tag::Boolean: b = other.b; break;
268− case Tag::StringLiteral: r = other.r; break;
269266 case Tag::Function: f = other.f; break;
270267 case Tag::EffFunction: e = other.e; break;
271268 case Tag::RawPointer: v = other.v; break;
@@ -337,6 +334,7 @@ class any {
337334 operator char32_t() const;
338335 operator char() const;
339336 operator size_t() const;
337+ operator const string&() const;
340338 operator const char *() const;
341339 operator const array&() const;
342340
@@ -357,28 +355,40 @@ class any {
357355 static auto unthunkVariant(const any&) -> const any&;
358356
359357 #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> \
361361 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; \
363363 } \
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> \
365367 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); \
367369 } \
368− friend auto operator op (const any&, const any&) -> any;
370+ friend auto operator op (const any&, const any&) -> any; \
369371
370372 #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> \
372376 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; \
374378 } \
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> \
376382 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); \
378390 } \
379391 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;
382392
383393 DEFINE_COMPARISON_OPERATOR(==)
384394 DEFINE_COMPARISON_OPERATOR(!=)
@@ -393,8 +403,12 @@ class any {
393403 DEFINE_OPERATOR(/)
394404 DEFINE_OPERATOR(%)
395405
396− friend auto operator+(const any& lhs, const char * const rhs) -> string;
397− friend auto operator+(const char * const lhs, const any& rhs) -> string;
406+ inline friend auto operator+(const any& lhs, const char * rhs) -> string {
407+ return static_cast<const string&>(lhs) + rhs;
408+ }
409+ inline friend auto operator+(const char * lhs, const any& rhs) -> string {
410+ return lhs + static_cast<const string&>(rhs);
411+ }
398412
399413 friend auto operator-(const any&) -> any; // unary negate
400414