@@ -12,517 +12,439 @@
13///////////////////////////////////////////////////////////////////////////////
13///////////////////////////////////////////////////////////////////////////////
15#include "PureScript.hh"
16#include "PureScript.hh"
17namespace PureScript {
18namespace PureScript {
20+#define COPY_DATA(src) \
22+ case Type::Integer: i = src.i; break; \
23+ case Type::Double: d = src.d; break; \
24+ case Type::Character: c = src.c; break; \
25+ case Type::Boolean: b = src.b; break; \
26+ case Type::StringLiteral: r = src.r; break; \
27+ case Type::String: new (&s) shared<std::string>(src.s); break; \
28+ case Type::Map: new (&m) shared<map>(src.m); break; \
29+ case Type::Vector: new (&v) shared<vector>(src.v); break; \
30+ case Type::Function: f = src.f; break; \
31+ case Type::Closure: new (&l) shared<closure>(src.l); break; \
32+ case Type::EffFunction: new (&e) shared<eff_fn>(src.e); break; \
33+ case Type::Thunk: t = src.t; break; \
34+ case Type::Pointer: new (&p) shared<void>(src.p); break; \
36+ default: assert(false && "Unsupported type in copy"); \
39+#define MOVE_DATA(src) \
41+ case Type::Integer: i = src.i; break; \
42+ case Type::Double: d = src.d; break; \
43+ case Type::Character: c = src.c; break; \
44+ case Type::Boolean: b = src.b; break; \
45+ case Type::StringLiteral: r = src.r; break; \
46+ case Type::String: new (&s) shared<std::string>(std::move(src.s)); break; \
47+ case Type::Map: new (&m) shared<map>(std::move(src.m)); break; \
48+ case Type::Vector: new (&v) shared<vector>(std::move(src.v)); break; \
49+ case Type::Function: f = src.f; break; \
50+ case Type::Closure: new (&l) shared<closure>(std::move(src.l)); break; \
51+ case Type::EffFunction: new (&e) shared<eff_fn>(std::move(src.e)); break; \
52+ case Type::Thunk: t = src.t; break; \
53+ case Type::Pointer: new (&p) shared<void>(std::move(src.p)); break; \
55+ default: assert(false && "Unsupported type in move"); \
19−any::any(const any& val) : type(val.type) {
58+any::any(const any& other) : type(other.type) {
20− switch (type) {
59+ COPY_DATA(other);
21− case Type::Integer: i = val.i; break;
22− case Type::Double: d = val.d; break;
23− case Type::Character: c = val.c; break;
24− case Type::Boolean: b = val.b; break;
25− case Type::String: new (&s) shared<string> (val.s); break;
26− case Type::Map: new (&m) shared<map> (val.m); break;
27− case Type::Vector: new (&v) shared<vector> (val.v); break;
28− case Type::Function: new (&f) shared<fn> (val.f); break;
29− case Type::EffFunction: new (&e) shared<eff_fn> (val.e); break;
30− case Type::Thunk: new (&t) shared<thunk> (val.t); break;
31− case Type::Pointer: new (&p) shared<void> (val.p); break;
33− default: assert(false && "Unsupported type in copy ctor");
37−void any::swap(any&& val) const {
62+any::any(any&& other) noexcept : type(other.type) {
66+auto any::operator=(const any& rhs) -> any& {
38− type = val.type;
67+ type = rhs.type;
39− switch (type) {
68+ COPY_DATA(rhs);
40− case Type::Integer: i = val.i; break;
69+ return *this;
41− case Type::Double: d = val.d; break;
70+}
42− case Type::Character: c = val.c; break;
71+
43− case Type::Boolean: b = val.b; break;
72+// Takes ownership -- might need to reconsider this
44− case Type::String: new (&s) shared<string> (std::move(val.s)); break;
73+auto any::operator=(any& rhs) noexcept -> any& {
45− case Type::Map: new (&m) shared<map> (std::move(val.m)); break;
74+ type = rhs.type;
46− case Type::Vector: new (&v) shared<vector> (std::move(val.v)); break;
75+ MOVE_DATA(rhs);
47− case Type::Function: new (&f) shared<fn> (std::move(val.f)); break;
76+ return *this;
48− case Type::EffFunction: new (&e) shared<eff_fn> (std::move(val.e)); break;
77+}
49− case Type::Thunk: new (&t) shared<thunk> (std::move(val.t)); break;
78+
50− case Type::Pointer: new (&p) shared<void> (std::move(val.p)); break;
79+auto any::operator=(any&& rhs) noexcept -> any& {
52− default: assert(false && "Unsupported type in move ctor");
81+ MOVE_DATA(rhs);
56any::~any() {
85any::~any() {
57− // std::cout << "destroy" << std::endl;
58 switch (type) {
86 switch (type) {
59− case Type::Integer: ; break;
87+ case Type::Integer: ; break;
60− case Type::Double: ; break;
88+ case Type::Double: ; break;
61− case Type::Character: ; break;
89+ case Type::Character: ; break;
62− case Type::Boolean: ; break;
90+ case Type::Boolean: ; break;
91+ case Type::StringLiteral: ; break;
63− case Type::String: s.~shared<string>(); break;
92+ case Type::String: s.~shared<std::string>(); break;
64− case Type::Map: m.~shared<map>(); break;
93+ case Type::Map: m.~shared<map>(); break;
65− case Type::Vector: v.~shared<vector>(); break;
94+ case Type::Vector: v.~shared<vector>(); break;
66− case Type::Function: f.~shared<fn>(); break;
95+ case Type::Function: ; break;
96+ case Type::Closure: l.~shared<closure>(); break;
67− case Type::EffFunction: e.~shared<eff_fn>(); break;
97+ case Type::EffFunction: e.~shared<eff_fn>(); break;
68− case Type::Thunk: t.~shared<thunk>(); break;
98+ case Type::Thunk: ; break;
69− case Type::Pointer: p.~shared<void>(); break;
99+ case Type::Pointer: p.~shared<void>(); break;
71 default: assert(false && "Unsupported type in destructor");
101 default: assert(false && "Unsupported type in destructor");
75− #define RETURN_VALUE(TYPE, VAL, FN) \
105+#define RETURN_VALUE(TYPE, ACCESSOR, INDIRECTION) \
76− if (type == TYPE) { \
106+ const any& variant = unthunkVariant(*this); \
79− const any* valuePtr = this; \
81− assert(valuePtr->type == Type::Thunk); \
82− const any& value = (*valuePtr->t)(unthunk); \
83− if (value.type == TYPE) { \
107+ assert(variant.type == TYPE); \
84− return FN(value.VAL); \
108+ return INDIRECTION(variant.ACCESSOR); \
87− } while (valuePtr->type != Type::Unknown); \
90− template <typename T>
91− auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
92− RETURN_VALUE(Type::Integer, i,)
94− template auto any::cast<long>() const -> long;
96− template <typename T>
97− auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
98− RETURN_VALUE(Type::Double, d,)
100− template auto any::cast<double>() const -> double;
102− template <typename T>
103− auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
104− RETURN_VALUE(Type::Character, c,)
106− template auto any::cast<char>() const -> char;
108− template <typename T>
109− auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
110− RETURN_VALUE(Type::Boolean, b,)
112− template auto any::cast<bool>() const -> bool;
114− template <typename T>
115− auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
116− RETURN_VALUE(Type::String, s, *)
118− template auto any::cast<string>() const -> const string&;
120− template <typename T>
121− auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
122− RETURN_VALUE(Type::String, s->c_str(),)
124− template auto any::cast<const char*>() const -> const char* const;
126− template <typename T>
127− auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
128− RETURN_VALUE(Type::Map, m, *)
130− template auto any::cast<any::map>() const -> const map&;
132− template <typename T>
133− auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
134− RETURN_VALUE(Type::Vector, v, *)
136− template auto any::cast<any::vector>() const -> const vector&;
139− auto any::operator()(const any& arg) const -> any {
140− if (type == Type::Function) {
143− const any* valuePtr = this;
145− assert(valuePtr->type == Type::Thunk);
146− const any& value = (*valuePtr->t)(unthunk);
147− if (value.type == Type::Function) {
148− return (*value.f)(arg);
151− } while (valuePtr->type != Type::Unknown);
155− auto any::operator()(const as_thunk) const -> const any& {
110+template <typename T>
156− assert(type == Type::Thunk);
111+auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
157− return (*t)(unthunk);
112+ RETURN_VALUE(Type::Integer, i,)
114+template auto any::cast<long>() const -> long;
160− auto any::operator()() const -> any {
116+template <typename T>
161− if (type == Type::EffFunction) {
117+auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
162− return (*e)();
118+ RETURN_VALUE(Type::Double, d,)
164− const any* valuePtr = this;
166− assert(valuePtr->type == Type::Thunk);
167− const any& value = (*valuePtr->t)(unthunk);
168− if (value.type == Type::EffFunction) {
169− return (*value.e)();
171− valuePtr = &value;
120+template auto any::cast<double>() const -> double;
172− } while (valuePtr->type != Type::Unknown);
176− any::operator long() const {
122+template <typename T>
123+auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
177− RETURN_VALUE(Type::Integer, i,)
124+ RETURN_VALUE(Type::Character, c,)
126+template auto any::cast<char>() const -> char;
180− any::operator double() const {
128+template <typename T>
129+auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
181− RETURN_VALUE(Type::Double, d,)
130+ RETURN_VALUE(Type::Boolean, b,)
132+template auto any::cast<bool>() const -> bool;
184− any::operator bool() const {
134+template <typename T>
185− RETURN_VALUE(Type::Boolean, b,)
135+auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type {
136+ const any& variant = unthunkVariant(*this);
137+ if (variant.type == Type::StringLiteral) {
140+ assert(variant.type == Type::String);
141+ return variant.s->c_str();
143+template auto any::cast<string>() const -> string;
188− any::operator const string&() const {
145+template <typename T>
146+auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
189− RETURN_VALUE(Type::String, s, *)
147+ RETURN_VALUE(Type::Map, m, *)
149+template auto any::cast<any::map>() const -> const map&;
192− any::operator const map&() const {
151+template <typename T>
152+auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
193− RETURN_VALUE(Type::Map, m, *)
153+ RETURN_VALUE(Type::Vector, v, *)
155+template auto any::cast<any::vector>() const -> const vector&;
196− any::operator const vector&() const {
157+auto any::operator()(const any& arg) const -> any {
197− RETURN_VALUE(Type::Vector, v, *)
158+ const any& variant = unthunkVariant(*this);
159+ if (variant.type == Type::Closure) {
160+ return (*variant.l)(arg);
162+ assert(variant.type == Type::Function);
163+ return (*variant.f)(arg);
200− auto any::extractPointer() const -> const void* {
166+auto any::operator()(const as_thunk) const -> const any& {
201− RETURN_VALUE(Type::Pointer, p.get(),)
167+ assert(type == Type::Thunk);
168+ return (*t)(unthunk);
204− auto any::extract_value(const any& a) -> const any& {
171+auto any::operator()() const -> any {
205− if (a.type != Type::Thunk) {
172+ const any& variant = unthunkVariant(*this);
206− return a;
173+ assert(variant.type == Type::EffFunction);
208− const any* valuePtr = &a;
210− const any& value = (*valuePtr->t)(unthunk);
211− if (value.type != Type::Thunk) {
212− return value;
174+ return (*variant.e)();
218− auto any::operator[](const map_key_t& rhs) const -> const any& {
177+any::operator long() const {
219− RETURN_VALUE(Type::Map, m->at(rhs),)
178+ return cast<long>();
222− auto any::operator[](const vector::size_type rhs) const -> const any& {
181+any::operator double() const {
223− RETURN_VALUE(Type::Vector, v->at(rhs),)
182+ return cast<double>();
226− auto any::operator[](const any& rhs) const -> const any& {
185+any::operator bool() const {
227− RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
186+ return cast<bool>();
230−#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
189+any::operator string() const {
231−auto operator OP(const T lhs, const any& rhs_) -> R { \
190+ return cast<string>();
232− const any& rhs = any::extract_value(rhs_); \
233− assert(rhs.type == any::Type::K); \
234− return lhs OP P(rhs.V); \
237−#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
238−auto any::operator OP(const T rhs) const -> R { \
193+any::operator const map&() const {
239− const any& lhs = any::extract_value(*this); \
240− assert(lhs.type == Type::K); \
241− return P(lhs.V) OP rhs; \
194+ return cast<map>();
244−auto any::operator==(const any& rhs_) const -> bool {
197+any::operator const vector&() const {
245− const any& lhs = extract_value(*this);
198+ return cast<vector>();
246− const any& rhs = extract_value(rhs_);
247− assert(lhs.type == rhs.type);
249− case Type::Integer: return lhs.i == rhs.i;
250− case Type::Double: return lhs.d == rhs.d;
251− case Type::Character: return lhs.c == rhs.c;
252− case Type::Boolean: return lhs.b == rhs.b;
253− case Type::String: return (*lhs.s) == (*rhs.s);
254− case Type::Pointer: return lhs.p == rhs.p;
255− default: assert(false && "Unsupported type for '==' operator");
260−DEFINE_OPERATOR_RHS(Integer, long, ==, i, bool,)
201+auto any::extractPointer() const -> void* {
261−DEFINE_OPERATOR_RHS(Double, double, ==, d, bool,)
202+ RETURN_VALUE(Type::Pointer, p.get(),)
262−DEFINE_OPERATOR_RHS(Character, char, ==, c, bool,)
203+}
263−DEFINE_OPERATOR_RHS(Boolean, bool, ==, b, bool,)
264−DEFINE_OPERATOR_RHS(String, string&, ==, s, bool, *)
265−DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
267−auto any::operator!=(const any& rhs_) const -> bool {
205+auto any::unthunkVariant(const any& a) -> const any& {
268− const any& lhs = extract_value(*this);
206+ const any * variant = &a;
269− const any& rhs = extract_value(rhs_);
207+ while (variant->type == Type::Thunk) {
270− assert(lhs.type == rhs.type);
208+ variant = &((*variant->t)(unthunk));
272− case Type::Integer: return lhs.i != rhs.i;
273− case Type::Double: return lhs.d != rhs.d;
274− case Type::Character: return lhs.c != rhs.c;
275− case Type::Boolean: return lhs.b != rhs.b;
276− case Type::String: return (*lhs.s) != (*rhs.s);
277− case Type::Pointer: return lhs.p != rhs.p;
278− default: assert(false && "Unsupported type for '!=' operator");
280− return false;
210+ return *variant;
283−DEFINE_OPERATOR_RHS(Integer, long, !=, i, bool,)
284−DEFINE_OPERATOR_RHS(Double, double, !=, d, bool,)
285−DEFINE_OPERATOR_RHS(Character, char, !=, c, bool,)
286−DEFINE_OPERATOR_RHS(Boolean, bool, !=, b, bool,)
287−DEFINE_OPERATOR_RHS(String, string&, !=, s, bool, *)
288−DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
290−auto any::operator<(const any& rhs_) const -> bool {
213+auto any::operator[](const char rhs[]) const -> const any& {
291− const any& lhs = extract_value(*this);
214+ const any& variant = unthunkVariant(*this);
292− const any& rhs = extract_value(rhs_);
293− assert(lhs.type == rhs.type);
215+ assert(variant.type == Type::Map);
294− switch (lhs.type) {
216+ const any::map::const_iterator begin = variant.m->begin();
295− case Type::Integer: return lhs.i < rhs.i;
217+ const any::map::const_iterator end = variant.m->end();
296− case Type::Double: return lhs.d < rhs.d;
218+ for (any::map::const_iterator it = begin; it != end; ++it) {
297− case Type::Character: return lhs.c < rhs.c;
219+ if (it->first == rhs) {
298− case Type::Boolean: return lhs.b < rhs.b;
220+ return it->second;
299− case Type::String: return (*lhs.s) < (*rhs.s);
221+ }
300− default: assert(false && "Unsupported type for '<' operator");
223+ for (any::map::const_iterator it = begin; it != end; ++it) {
224+ if (strcmp(it->first, rhs) == 0) {
302− return false;
225+ return it->second;
228+ throw runtime_error("map key not found");
305−DEFINE_OPERATOR_RHS(Integer, long, <, i, bool,)
306−DEFINE_OPERATOR_RHS(Double, double, <, d, bool,)
307−DEFINE_OPERATOR_RHS(Character, char, <, c, bool,)
308−DEFINE_OPERATOR_RHS(Boolean, bool, <, b, bool,)
309−DEFINE_OPERATOR_RHS(String, string&, <, s, bool, *)
310−DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
312−auto any::operator<=(const any& rhs_) const -> bool {
231+auto any::operator[](const vector::size_type rhs) const -> const any& {
313− const any& lhs = extract_value(*this);
232+ const any& variant = unthunkVariant(*this);
314− const any& rhs = extract_value(rhs_);
315− assert(lhs.type == rhs.type);
233+ assert(variant.type == Type::Vector);
317− case Type::Integer: return lhs.i <= rhs.i;
318− case Type::Double: return lhs.d <= rhs.d;
319− case Type::Character: return lhs.c <= rhs.c;
320− case Type::Boolean: return lhs.b <= rhs.b;
321− case Type::String: return (*lhs.s) <= (*rhs.s);
234+ return (*variant.v)[rhs];
322− default: assert(false && "Unsupported type for '<' operator");
327−DEFINE_OPERATOR_RHS(Integer, long, <=, i, bool,)
237+auto any::operator[](const any& rhs) const -> const any& {
328−DEFINE_OPERATOR_RHS(Double, double, <=, d, bool,)
238+ const any& variant = unthunkVariant(*this);
329−DEFINE_OPERATOR_RHS(Character, char, <=, c, bool,)
239+ assert(variant.type == Type::Vector);
330−DEFINE_OPERATOR_RHS(Boolean, bool, <=, b, bool,)
240+ return (*variant.v)[rhs.cast<long>()];
331−DEFINE_OPERATOR_RHS(String, string&, <=, s, bool, *)
241+}
332−DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
334−auto any::operator>(const any& rhs_) const -> bool {
243+auto any::contains(const char key[]) const -> bool {
335− const any& lhs = extract_value(*this);
244+ const any& variant = unthunkVariant(*this);
336− const any& rhs = extract_value(rhs_);
337− assert(lhs.type == rhs.type);
245+ assert(variant.type == Type::Map);
338− switch (lhs.type) {
246+ for (any::map::const_iterator it = variant.m->begin(), end = variant.m->end(); it != end; ++it) {
339− case Type::Integer: return lhs.i > rhs.i;
247+ if (it->first == key || strcmp(it->first, key) == 0) {
340− case Type::Double: return lhs.d > rhs.d;
248+ return true;
341− case Type::Character: return lhs.c > rhs.c;
249+ }
342− case Type::Boolean: return lhs.b > rhs.b;
343− case Type::String: return (*lhs.s) > (*rhs.s);
344− default: assert(false && "Unsupported type for '>' operator");
346 return false;
251 return false;
349−DEFINE_OPERATOR_RHS(Integer, long, >, i, bool,)
254+//-----------------------------------------------------------------------------
350−DEFINE_OPERATOR_RHS(Double, double, >, d, bool,)
255+// Operator helper macros
351−DEFINE_OPERATOR_RHS(Character, char, >, c, bool,)
256+//-----------------------------------------------------------------------------
352−DEFINE_OPERATOR_RHS(Boolean, bool, >, b, bool,)
353−DEFINE_OPERATOR_RHS(String, string&, >, s, bool, *)
354−DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
356−auto any::operator>=(const any& rhs_) const -> bool {
258+#define DEFINE_OPERATOR(op, ty, rty) \
357− const any& lhs = extract_value(*this);
259+auto operator op (const any& lhs, ty rhs) -> rty { \
358− const any& rhs = extract_value(rhs_);
260+ return lhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>() op rhs; \
359− assert(lhs.type == rhs.type);
361− case Type::Integer: return lhs.i >= rhs.i;
362− case Type::Double: return lhs.d >= rhs.d;
363− case Type::Character: return lhs.c >= rhs.c;
364− case Type::Boolean: return lhs.b >= rhs.b;
365− case Type::String: return (*lhs.s) >= (*rhs.s);
366− default: assert(false && "Unsupported type for '>' operator");
368− return false;
262+auto operator op (ty lhs, const any& rhs) -> rty { \
263+ return lhs op rhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>(); \
371−DEFINE_OPERATOR_RHS(Integer, long, >=, i, bool,)
266+#define DEFINE_CSTR_EQUALS_OPERATOR() \
372−DEFINE_OPERATOR_RHS(Double, double, >=, d, bool,)
267+ auto operator==(const any& lhs_, const char * rhs) -> bool { \
373−DEFINE_OPERATOR_RHS(Character, char, >=, c, bool,)
268+ const any& lhs = any::unthunkVariant(lhs_); \
374−DEFINE_OPERATOR_RHS(Boolean, bool, >=, b, bool,)
269+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
375−DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
270+ if (lhs.type == any::Type::StringLiteral) { \
376−DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
271+ return (lhs.r == rhs) || (strcmp(lhs.r, rhs) == 0); \
273+ return strcmp(lhs.s->c_str(), rhs) == 0; \
275+ auto operator==(const char * lhs, const any& rhs_) -> bool { \
276+ const any& rhs = any::unthunkVariant(rhs_); \
277+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
278+ if (rhs.type == any::Type::StringLiteral) { \
279+ return (lhs == rhs.r) || (strcmp(lhs, rhs) == 0); \
281+ return strcmp(lhs, rhs.s->c_str()) == 0; \
284+#define DEFINE_CSTR_COMPARISON_OPERATOR(op) \
285+ auto operator op (const any& lhs, const char * rhs) -> bool { \
286+ return strcmp(lhs.cast<string>(), rhs) op 0; \
288+ auto operator op (const char * lhs, const any& rhs) -> bool { \
289+ return strcmp(lhs, rhs.cast<string>()) op 0; \
292+#define DEFINE_COMPARISON_OPERATOR(op) \
293+ auto operator op (const any& lhs_, const any& rhs_) -> bool { \
294+ const any& lhs = any::unthunkVariant(lhs_); \
295+ const any& rhs = any::unthunkVariant(rhs_); \
296+ switch (lhs.type) { \
297+ case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i op rhs.i; \
298+ case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d op rhs.d; \
299+ case any::Type::Character: assert(lhs.type == any::Type::Character); return lhs.c op rhs.c; \
300+ case any::Type::Boolean: assert(lhs.type == any::Type::Boolean); return lhs.b op rhs.b; \
301+ case any::Type::StringLiteral: \
302+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
303+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
304+ return strcmp(lhs.r, rhs.type == any::Type::StringLiteral ? rhs.r : rhs.s->c_str()) op 0; \
305+ case any::Type::String: \
306+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
307+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
308+ return strcmp(lhs.s->c_str(), rhs.type == any::Type::StringLiteral ? rhs.r : rhs.s->c_str()) op 0; \
309+ case any::Type::Pointer: return lhs.p op rhs.p; \
310+ default: assert(false && "Unsupported type for operator " #op); \
314+ DEFINE_OPERATOR(op, long, bool) \
315+ DEFINE_OPERATOR(op, double, bool) \
316+ DEFINE_OPERATOR(op, char, bool) \
317+ DEFINE_OPERATOR(op, bool, bool) \
319+//-----------------------------------------------------------------------------
320+// Operator definitions
321+//-----------------------------------------------------------------------------
323+DEFINE_COMPARISON_OPERATOR(==)
324+DEFINE_COMPARISON_OPERATOR(!=)
325+DEFINE_COMPARISON_OPERATOR(<)
326+DEFINE_COMPARISON_OPERATOR(<=)
327+DEFINE_COMPARISON_OPERATOR(>)
328+DEFINE_COMPARISON_OPERATOR(>=)
330+DEFINE_CSTR_EQUALS_OPERATOR()
331+DEFINE_CSTR_COMPARISON_OPERATOR(!=)
332+DEFINE_CSTR_COMPARISON_OPERATOR(<)
333+DEFINE_CSTR_COMPARISON_OPERATOR(<=)
334+DEFINE_CSTR_COMPARISON_OPERATOR(>)
335+DEFINE_CSTR_COMPARISON_OPERATOR(>=)
378−auto any::operator+(const any& rhs_) const -> any {
337+auto operator+(const any& lhs_, const any& rhs_) -> any {
379− const any& lhs = extract_value(*this);
338+ const any& lhs = any::unthunkVariant(lhs_);
380− const any& rhs = extract_value(rhs_);
339+ const any& rhs = any::unthunkVariant(rhs_);
381− assert(lhs.type == rhs.type);
382 switch (lhs.type) {
340 switch (lhs.type) {
383− case Type::Integer: return lhs.i + rhs.i;
341+ case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i + rhs.i;
384− case Type::Double: return lhs.d + rhs.d;
342+ case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d + rhs.d;
385− case Type::Character: return any(char(lhs.c + rhs.c));
343+ case any::Type::Character: assert(lhs.type == any::Type::Character); return any(char(lhs.c + rhs.c));
386− case Type::String: return (*lhs.s) + (*rhs.s);
344+ case any::Type::StringLiteral:
345+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
346+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
347+ return rhs.type == any::Type::StringLiteral ? std::string(lhs.r) + rhs.r : lhs.r + *rhs.s;
348+ case any::Type::String:
349+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
350+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
351+ return rhs.type == any::Type::StringLiteral ? *lhs.s + rhs.r : *lhs.s + *rhs.s;
387 default: assert(false && "Unsupported type for '+' operator");
352 default: assert(false && "Unsupported type for '+' operator");
389 return nullptr;
354 return nullptr;
392−DEFINE_OPERATOR_RHS(Integer, long, +, i, long,)
357+DEFINE_OPERATOR(+, long, long)
393−DEFINE_OPERATOR_RHS(Double, double, +, d, double,)
358+DEFINE_OPERATOR(+, double, double)
394−DEFINE_OPERATOR_RHS(Character, char, +, c, char,)
359+DEFINE_OPERATOR(+, char, char)
395−DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
360+
396−DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
361+auto operator+(const any& lhs_, const char * rhs) -> std::string {
362+ const any& lhs = any::unthunkVariant(lhs_);
363+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
364+ return lhs.type == any::Type::StringLiteral ? std::string(lhs.r) + rhs : *lhs.s + rhs;
367+auto operator+(const char * lhs, const any& rhs_) -> std::string {
368+ const any& rhs = any::unthunkVariant(rhs_);
369+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
370+ return rhs.type == any::Type::StringLiteral ? lhs + std::string(rhs.r) : lhs + *rhs.s;
398−auto any::operator-(const any& rhs_) const -> any {
373+auto operator-(const any& lhs_, const any& rhs_) -> any {
399− const any& lhs = extract_value(*this);
374+ const any& lhs = any::unthunkVariant(lhs_);
400− const any& rhs = extract_value(rhs_);
375+ const any& rhs = any::unthunkVariant(rhs_);
401 assert(lhs.type == rhs.type);
376 assert(lhs.type == rhs.type);
402 switch (lhs.type) {
377 switch (lhs.type) {
403− case Type::Integer: return lhs.i - rhs.i;
378+ case any::Type::Integer: return lhs.i - rhs.i;
404− case Type::Double: return lhs.d - rhs.d;
379+ case any::Type::Double: return lhs.d - rhs.d;
405− case Type::Character: return any(char(lhs.c - rhs.c));
380+ case any::Type::Character: return any(char(lhs.c - rhs.c));
406− default: assert(false && "Unsupported type for '-' binary operator");
381+ default: assert(false && "Unsupported type for '-' operator");
408 return nullptr;
383 return nullptr;
411−DEFINE_OPERATOR_RHS(Integer, long, -, i, long,)
386+DEFINE_OPERATOR(-, long, long)
412−DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
387+DEFINE_OPERATOR(-, double, double)
413−DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
388+DEFINE_OPERATOR(-, char, char)
415−auto any::operator*(const any& rhs_) const -> any {
390+auto operator*(const any& lhs_, const any& rhs_) -> any {
416− const any& lhs = extract_value(*this);
391+ const any& lhs = any::unthunkVariant(lhs_);
417− const any& rhs = extract_value(rhs_);
392+ const any& rhs = any::unthunkVariant(rhs_);
418 assert(lhs.type == rhs.type);
393 assert(lhs.type == rhs.type);
419 switch (lhs.type) {
394 switch (lhs.type) {
420− case Type::Integer: return lhs.i * rhs.i;
395+ case any::Type::Integer: return lhs.i * rhs.i;
421− case Type::Double: return lhs.d * rhs.d;
396+ case any::Type::Double: return lhs.d * rhs.d;
397+ case any::Type::Character: return any(char(lhs.c * rhs.c));
422 default: assert(false && "Unsupported type for '*' operator");
398 default: assert(false && "Unsupported type for '*' operator");
424 return nullptr;
400 return nullptr;
427−DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
403+DEFINE_OPERATOR(*, long, long)
428−DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
404+DEFINE_OPERATOR(*, double, double)
405+DEFINE_OPERATOR(*, char, char)
430−auto any::operator/(const any& rhs_) const -> any {
407+auto operator/(const any& lhs_, const any& rhs_) -> any {
431− const any& lhs = extract_value(*this);
408+ const any& lhs = any::unthunkVariant(lhs_);
432− const any& rhs = extract_value(rhs_);
409+ const any& rhs = any::unthunkVariant(rhs_);
433 assert(lhs.type == rhs.type);
410 assert(lhs.type == rhs.type);
434 switch (lhs.type) {
411 switch (lhs.type) {
435− case Type::Integer: return lhs.i / rhs.i;
412+ case any::Type::Integer: return lhs.i / rhs.i;
436− case Type::Double: return lhs.d / rhs.d;
413+ case any::Type::Double: return lhs.d / rhs.d;
414+ case any::Type::Character: return any(char(lhs.c / rhs.c));
437 default: assert(false && "Unsupported type for '/' operator");
415 default: assert(false && "Unsupported type for '/' operator");
439 return nullptr;
417 return nullptr;
442−DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
420+DEFINE_OPERATOR(/, long, long)
443−DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
421+DEFINE_OPERATOR(/, double, double)
422+DEFINE_OPERATOR(/, char, char)
445−auto any::operator%(const any& rhs_) const -> any {
424+auto operator%(const any& lhs_, const any& rhs_) -> any {
446− const any& lhs = extract_value(*this);
425+ const any& lhs = any::unthunkVariant(lhs_);
447− const any& rhs = extract_value(rhs_);
426+ const any& rhs = any::unthunkVariant(rhs_);
448 assert(lhs.type == rhs.type);
427 assert(lhs.type == rhs.type);
449 switch (lhs.type) {
428 switch (lhs.type) {
450− case Type::Integer: return lhs.i % rhs.i;
429+ case any::Type::Integer: return lhs.i % rhs.i;
430+ case any::Type::Character: return any(char(lhs.c % rhs.c));
451 default: assert(false && "Unsupported type for '%' operator");
431 default: assert(false && "Unsupported type for '%' operator");
453 return nullptr;
433 return nullptr;
456−DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
436+DEFINE_OPERATOR(%, long, long)
437+DEFINE_OPERATOR(%, char, char)
458−auto any::operator-() const -> any {
440+auto operator-(const any& rhs_) -> any {
459− const any& lhs = any::extract_value(*this);
441+ const any& rhs = any::unthunkVariant(rhs_);
460− switch (lhs.type) {
442+ switch (rhs.type) {
461− case Type::Integer: return (- lhs.i);
443+ case any::Type::Integer: return (- rhs.i);
462− case Type::Double: return (- lhs.d);
444+ case any::Type::Double: return (- rhs.d);
463 default: assert(false && "Unsupported type for unary '-' operator");
445 default: assert(false && "Unsupported type for unary '-' operator");
465 return nullptr;
447 return nullptr;
468−DEFINE_OPERATOR_LHS(Integer, long, ==, i, bool,)
469−DEFINE_OPERATOR_LHS(Integer, long, !=, i, bool,)
470−DEFINE_OPERATOR_LHS(Integer, long, <, i, bool,)
471−DEFINE_OPERATOR_LHS(Integer, long, <=, i, bool,)
472−DEFINE_OPERATOR_LHS(Integer, long, >, i, bool,)
473−DEFINE_OPERATOR_LHS(Integer, long, >=, i, bool,)
475−DEFINE_OPERATOR_LHS(Double, double, ==, d, bool,)
476−DEFINE_OPERATOR_LHS(Double, double, !=, d, bool,)
477−DEFINE_OPERATOR_LHS(Double, double, <, d, bool,)
478−DEFINE_OPERATOR_LHS(Double, double, <=, d, bool,)
479−DEFINE_OPERATOR_LHS(Double, double, >, d, bool,)
480−DEFINE_OPERATOR_LHS(Double, double, >=, d, bool,)
482−DEFINE_OPERATOR_LHS(Character, char, ==, c, bool,)
483−DEFINE_OPERATOR_LHS(Character, char, !=, c, bool,)
484−DEFINE_OPERATOR_LHS(Character, char, <, c, bool,)
485−DEFINE_OPERATOR_LHS(Character, char, <=, c, bool,)
486−DEFINE_OPERATOR_LHS(Character, char, >, c, bool,)
487−DEFINE_OPERATOR_LHS(Character, char, >=, c, bool,)
489−DEFINE_OPERATOR_LHS(Boolean, bool, ==, b, bool,)
490−DEFINE_OPERATOR_LHS(Boolean, bool, !=, b, bool,)
491−DEFINE_OPERATOR_LHS(Boolean, bool, <, b, bool,)
492−DEFINE_OPERATOR_LHS(Boolean, bool, <=, b, bool,)
493−DEFINE_OPERATOR_LHS(Boolean, bool, >, b, bool,)
494−DEFINE_OPERATOR_LHS(Boolean, bool, >=, b, bool,)
496−DEFINE_OPERATOR_LHS(String, string&, ==, s, bool, *)
497−DEFINE_OPERATOR_LHS(String, string&, !=, s, bool, *)
498−DEFINE_OPERATOR_LHS(String, string&, <, s, bool, *)
499−DEFINE_OPERATOR_LHS(String, string&, <=, s, bool, *)
500−DEFINE_OPERATOR_LHS(String, string&, >, s, bool, *)
501−DEFINE_OPERATOR_LHS(String, string&, >=, s, bool, *)
503−DEFINE_OPERATOR_LHS(String, char* const, ==, s, bool, *)
504−DEFINE_OPERATOR_LHS(String, char* const, !=, s, bool, *)
505−DEFINE_OPERATOR_LHS(String, char* const, <, s, bool, *)
506−DEFINE_OPERATOR_LHS(String, char* const, <=, s, bool, *)
507−DEFINE_OPERATOR_LHS(String, char* const, >, s, bool, *)
508−DEFINE_OPERATOR_LHS(String, char* const, >=, s, bool, *)
510−DEFINE_OPERATOR_LHS(Integer, long, +, i, long,)
511−DEFINE_OPERATOR_LHS(Integer, long, -, i, long,)
512−DEFINE_OPERATOR_LHS(Integer, long, *, i, long,)
513−DEFINE_OPERATOR_LHS(Integer, long, /, i, long,)
514−DEFINE_OPERATOR_LHS(Integer, long, %, i, long,)
516−DEFINE_OPERATOR_LHS(Double, double, +, d, double,)
517−DEFINE_OPERATOR_LHS(Double, double, -, d, double,)
518−DEFINE_OPERATOR_LHS(Double, double, *, d, double,)
519−DEFINE_OPERATOR_LHS(Double, double, /, d, double,)
521−DEFINE_OPERATOR_LHS(Character, char, +, i, char,)
522−DEFINE_OPERATOR_LHS(Character, char, -, i, char,)
524−DEFINE_OPERATOR_LHS(String, string&, +, s, string, *)
525−DEFINE_OPERATOR_LHS(String, char* const, +, s, string, *)
528} // namespace PureScript
450} // namespace PureScript