@@ -16,7 +16,7 @@
1616
1717namespace PureScript {
1818
19−#define copy_data(src) \
19+#define COPY_DATA(src) \
2020 type = src.type; \
2121 switch (type) { \
2222 case Type::Integer: i = src.i; break; \
@@ -35,7 +35,7 @@ namespace PureScript {
3535 default: assert(false && "Unsupported type in copy"); \
3636 }
3737
38−#define move_data(src) \
38+#define MOVE_DATA(src) \
3939 type = src.type; \
4040 switch (type) { \
4141 case Type::Integer: i = src.i; break; \
@@ -55,26 +55,26 @@ namespace PureScript {
5555 }
5656
5757any::any(const any& other) {
58− copy_data(other);
58+ COPY_DATA(other);
5959}
6060
6161any::any(any&& other) noexcept {
62− move_data(other);
62+ MOVE_DATA(other);
6363}
6464
6565auto any::operator=(const any& rhs) -> any& {
66− copy_data(rhs);
66+ COPY_DATA(rhs);
6767 return *this;
6868}
6969
7070// Takes ownership -- might need to reconsider this
7171auto any::operator=(any& rhs) noexcept -> any& {
72− move_data(rhs);
72+ MOVE_DATA(rhs);
7373 return *this;
7474}
7575
7676auto any::operator=(any&& rhs) noexcept -> any& {
77− move_data(rhs);
77+ MOVE_DATA(rhs);
7878 return *this;
7979}
8080
@@ -98,467 +98,327 @@ any::~any() {
9898 }
9999};
100100
101− #define RETURN_VALUE(TYPE, VAL, FN) \
102− if (type == TYPE) { \
103− return FN(VAL); \
101+#define RETURN_VALUE(TYPE, VAL, FN) \
102+ if (type == TYPE) { \
103+ return FN(VAL); \
104+ } \
105+ const any* valuePtr = this; \
106+ do { \
107+ assert(valuePtr->type == Type::Thunk); \
108+ const any& value = (*valuePtr->t)(unthunk); \
109+ if (value.type == TYPE) { \
110+ return FN(value.VAL); \
104111 } \
105− const any* valuePtr = this; \
106− do { \
107− assert(valuePtr->type == Type::Thunk); \
108− const any& value = (*valuePtr->t)(unthunk); \
109− if (value.type == TYPE) { \
110− return FN(value.VAL); \
111− } \
112− valuePtr = &value; \
113− } while (valuePtr->type != Type::Unknown); \
114− assert(false && "Unknown value type"); \
115− return FN(VAL);
116−
117− template <typename T>
118− auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
119− RETURN_VALUE(Type::Integer, i,)
120− }
121− template auto any::cast<long>() const -> long;
112+ valuePtr = &value; \
113+ } while (valuePtr->type != Type::Unknown); \
114+ assert(false && "Unknown value type"); \
115+ return FN(VAL);
116+
117+template <typename T>
118+auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
119+ RETURN_VALUE(Type::Integer, i,)
120+}
121+template auto any::cast<long>() const -> long;
122122
123− template <typename T>
124− auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
125− RETURN_VALUE(Type::Double, d,)
126− }
127− template auto any::cast<double>() const -> double;
123+template <typename T>
124+auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
125+ RETURN_VALUE(Type::Double, d,)
126+}
127+template auto any::cast<double>() const -> double;
128128
129− template <typename T>
130− auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
131− RETURN_VALUE(Type::Character, c,)
132− }
133− template auto any::cast<char>() const -> char;
129+template <typename T>
130+auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
131+ RETURN_VALUE(Type::Character, c,)
132+}
133+template auto any::cast<char>() const -> char;
134134
135− template <typename T>
136− auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
137− RETURN_VALUE(Type::Boolean, b,)
138− }
139− template auto any::cast<bool>() const -> bool;
135+template <typename T>
136+auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
137+ RETURN_VALUE(Type::Boolean, b,)
138+}
139+template auto any::cast<bool>() const -> bool;
140140
141− template <typename T>
142− auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
143− RETURN_VALUE(Type::String, s, *)
144− }
145− template auto any::cast<string>() const -> const string&;
141+template <typename T>
142+auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
143+ RETURN_VALUE(Type::String, s, *)
144+}
145+template auto any::cast<string>() const -> const string&;
146146
147− template <typename T>
148− auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
149− RETURN_VALUE(Type::String, s->c_str(),)
150− }
151− template auto any::cast<const char*>() const -> const char* const;
147+template <typename T>
148+auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
149+ RETURN_VALUE(Type::String, s->c_str(),)
150+}
151+template auto any::cast<const char*>() const -> const char* const;
152152
153− template <typename T>
154− auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
155− RETURN_VALUE(Type::Map, m, *)
156− }
157− template auto any::cast<any::map>() const -> const map&;
153+template <typename T>
154+auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
155+ RETURN_VALUE(Type::Map, m, *)
156+}
157+template auto any::cast<any::map>() const -> const map&;
158158
159− template <typename T>
160− auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
161− RETURN_VALUE(Type::Vector, v, *)
162− }
163− template auto any::cast<any::vector>() const -> const vector&;
159+template <typename T>
160+auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
161+ RETURN_VALUE(Type::Vector, v, *)
162+}
163+template auto any::cast<any::vector>() const -> const vector&;
164164
165− auto any::operator()(const any& arg) const -> any {
166− if (type == Type::Function) {
167− return (*f)(arg);
168− }
169− if (type == Type::Closure) {
170− return (*l)(arg);
171− }
172− const any* valuePtr = this;
173− do {
174− assert(valuePtr->type == Type::Thunk);
175− const any& value = (*valuePtr->t)(unthunk);
176− if (value.type == Type::Function) {
177− return (*value.f)(arg);
178− }
179− if (value.type == Type::Closure) {
180− return (*value.l)(arg);
181− }
182− valuePtr = &value;
183− } while (valuePtr->type != Type::Unknown);
184− assert(false && "Unknown value type");
185− return nullptr;
165+auto any::operator()(const any& arg) const -> any {
166+ if (type == Type::Function) {
167+ return (*f)(arg);
186168 }
187−
188− auto any::operator()(const as_thunk) const -> const any& {
189− assert(type == Type::Thunk);
190− return (*t)(unthunk);
169+ if (type == Type::Closure) {
170+ return (*l)(arg);
191171 }
192−
193− auto any::operator()() const -> any {
194− if (type == Type::EffFunction) {
195− return (*e)();
172+ const any* valuePtr = this;
173+ do {
174+ assert(valuePtr->type == Type::Thunk);
175+ const any& value = (*valuePtr->t)(unthunk);
176+ if (value.type == Type::Function) {
177+ return (*value.f)(arg);
196178 }
197− const any* valuePtr = this;
198− do {
199− assert(valuePtr->type == Type::Thunk);
200− const any& value = (*valuePtr->t)(unthunk);
201− if (value.type == Type::EffFunction) {
202− return (*value.e)();
203− }
204− valuePtr = &value;
205− } while (valuePtr->type != Type::Unknown);
206− assert(false && "Unknown value type");
207− return nullptr;
208− }
209−
210− any::operator long() const {
211− RETURN_VALUE(Type::Integer, i,)
212− }
213−
214− any::operator double() const {
215− RETURN_VALUE(Type::Double, d,)
216− }
217−
218− any::operator bool() const {
219− RETURN_VALUE(Type::Boolean, b,)
220− }
221−
222− any::operator const string&() const {
223− RETURN_VALUE(Type::String, s, *)
224− }
225−
226− any::operator const map&() const {
227− RETURN_VALUE(Type::Map, m, *)
228− }
229−
230− any::operator const vector&() const {
231− RETURN_VALUE(Type::Vector, v, *)
232− }
233−
234− auto any::extractPointer() const -> void* {
235− RETURN_VALUE(Type::Pointer, p.get(),)
236− }
237−
238− auto any::extract_value(const any& a) -> const any& {
239− if (a.type != Type::Thunk) {
240− return a;
179+ if (value.type == Type::Closure) {
180+ return (*value.l)(arg);
241181 }
242− const any* valuePtr = &a;
243− do {
244− const any& value = (*valuePtr->t)(unthunk);
245− if (value.type != Type::Thunk) {
246− return value;
247− }
248− valuePtr = &value;
249− } while (valuePtr->type != Type::Unknown);
250− assert(false && "Unknown value type");
251− return a;
252− }
182+ valuePtr = &value;
183+ } while (valuePtr->type != Type::Unknown);
184+ assert(false && "Unknown value type");
185+ return nullptr;
186+}
253187
254− auto any::operator[](const map_key_t& rhs) const -> const any& {
255− RETURN_VALUE(Type::Map, m->at(rhs),)
256− }
188+auto any::operator()(const as_thunk) const -> const any& {
189+ assert(type == Type::Thunk);
190+ return (*t)(unthunk);
191+}
257192
258− auto any::operator[](const vector::size_type rhs) const -> const any& {
259− RETURN_VALUE(Type::Vector, v->at(rhs),)
193+auto any::operator()() const -> any {
194+ if (type == Type::EffFunction) {
195+ return (*e)();
260196 }
197+ const any* valuePtr = this;
198+ do {
199+ assert(valuePtr->type == Type::Thunk);
200+ const any& value = (*valuePtr->t)(unthunk);
201+ if (value.type == Type::EffFunction) {
202+ return (*value.e)();
203+ }
204+ valuePtr = &value;
205+ } while (valuePtr->type != Type::Unknown);
206+ assert(false && "Unknown value type");
207+ return nullptr;
208+}
261209
262− auto any::operator[](const any& rhs) const -> const any& {
263− RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
264− }
210+any::operator long() const {
211+ RETURN_VALUE(Type::Integer, i,)
212+}
265213
266−#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
267−auto operator OP(const T lhs, const any& rhs_) -> R { \
268− const any& rhs = any::extract_value(rhs_); \
269− assert(rhs.type == any::Type::K); \
270− return lhs OP P(rhs.V); \
214+any::operator double() const {
215+ RETURN_VALUE(Type::Double, d,)
271216}
272217
273−#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
274−auto any::operator OP(const T rhs) const -> R { \
275− const any& lhs = any::extract_value(*this); \
276− assert(lhs.type == Type::K); \
277− return P(lhs.V) OP rhs; \
218+any::operator bool() const {
219+ RETURN_VALUE(Type::Boolean, b,)
278220}
279221
280−auto any::operator==(const any& rhs_) const -> bool {
281− const any& lhs = extract_value(*this);
282− const any& rhs = extract_value(rhs_);
283− assert(lhs.type == rhs.type);
284− switch (lhs.type) {
285− case Type::Integer: return lhs.i == rhs.i;
286− case Type::Double: return lhs.d == rhs.d;
287− case Type::Character: return lhs.c == rhs.c;
288− case Type::Boolean: return lhs.b == rhs.b;
289− case Type::String: return (*lhs.s) == (*rhs.s);
290− case Type::Pointer: return lhs.p == rhs.p;
291− default: assert(false && "Unsupported type for '==' operator");
292− }
293− return false;
222+any::operator const string&() const {
223+ RETURN_VALUE(Type::String, s, *)
294224}
295225
296−DEFINE_OPERATOR_RHS(Integer, long, ==, i, bool,)
297−DEFINE_OPERATOR_RHS(Double, double, ==, d, bool,)
298−DEFINE_OPERATOR_RHS(Character, char, ==, c, bool,)
299−DEFINE_OPERATOR_RHS(Boolean, bool, ==, b, bool,)
300−DEFINE_OPERATOR_RHS(String, string&, ==, s, bool, *)
301−DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
226+any::operator const map&() const {
227+ RETURN_VALUE(Type::Map, m, *)
228+}
302229
303−auto any::operator!=(const any& rhs_) const -> bool {
304− const any& lhs = extract_value(*this);
305− const any& rhs = extract_value(rhs_);
306− assert(lhs.type == rhs.type);
307− switch (lhs.type) {
308− case Type::Integer: return lhs.i != rhs.i;
309− case Type::Double: return lhs.d != rhs.d;
310− case Type::Character: return lhs.c != rhs.c;
311− case Type::Boolean: return lhs.b != rhs.b;
312− case Type::String: return (*lhs.s) != (*rhs.s);
313− case Type::Pointer: return lhs.p != rhs.p;
314− default: assert(false && "Unsupported type for '!=' operator");
315− }
316− return false;
230+any::operator const vector&() const {
231+ RETURN_VALUE(Type::Vector, v, *)
317232}
318233
319−DEFINE_OPERATOR_RHS(Integer, long, !=, i, bool,)
320−DEFINE_OPERATOR_RHS(Double, double, !=, d, bool,)
321−DEFINE_OPERATOR_RHS(Character, char, !=, c, bool,)
322−DEFINE_OPERATOR_RHS(Boolean, bool, !=, b, bool,)
323−DEFINE_OPERATOR_RHS(String, string&, !=, s, bool, *)
324−DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
234+auto any::extractPointer() const -> void* {
235+ RETURN_VALUE(Type::Pointer, p.get(),)
236+}
325237
326−auto any::operator<(const any& rhs_) const -> bool {
327− const any& lhs = extract_value(*this);
328− const any& rhs = extract_value(rhs_);
329− assert(lhs.type == rhs.type);
330− switch (lhs.type) {
331− case Type::Integer: return lhs.i < rhs.i;
332− case Type::Double: return lhs.d < rhs.d;
333− case Type::Character: return lhs.c < rhs.c;
334− case Type::Boolean: return lhs.b < rhs.b;
335− case Type::String: return (*lhs.s) < (*rhs.s);
336− default: assert(false && "Unsupported type for '<' operator");
238+auto any::extractValue(const any& a) -> const any& {
239+ if (a.type != Type::Thunk) {
240+ return a;
337241 }
338− return false;
242+ const any* valuePtr = &a;
243+ do {
244+ const any& value = (*valuePtr->t)(unthunk);
245+ if (value.type != Type::Thunk) {
246+ return value;
247+ }
248+ valuePtr = &value;
249+ } while (valuePtr->type != Type::Unknown);
250+ assert(false && "Unknown value type");
251+ return a;
339252}
340253
341−DEFINE_OPERATOR_RHS(Integer, long, <, i, bool,)
342−DEFINE_OPERATOR_RHS(Double, double, <, d, bool,)
343−DEFINE_OPERATOR_RHS(Character, char, <, c, bool,)
344−DEFINE_OPERATOR_RHS(Boolean, bool, <, b, bool,)
345−DEFINE_OPERATOR_RHS(String, string&, <, s, bool, *)
346−DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
347−
348−auto any::operator<=(const any& rhs_) const -> bool {
349− const any& lhs = extract_value(*this);
350− const any& rhs = extract_value(rhs_);
351− assert(lhs.type == rhs.type);
352− switch (lhs.type) {
353− case Type::Integer: return lhs.i <= rhs.i;
354− case Type::Double: return lhs.d <= rhs.d;
355− case Type::Character: return lhs.c <= rhs.c;
356− case Type::Boolean: return lhs.b <= rhs.b;
357− case Type::String: return (*lhs.s) <= (*rhs.s);
358− default: assert(false && "Unsupported type for '<' operator");
359− }
360− return false;
254+auto any::operator[](const map_key_t& rhs) const -> const any& {
255+ RETURN_VALUE(Type::Map, m->at(rhs),)
361256}
362257
363−DEFINE_OPERATOR_RHS(Integer, long, <=, i, bool,)
364−DEFINE_OPERATOR_RHS(Double, double, <=, d, bool,)
365−DEFINE_OPERATOR_RHS(Character, char, <=, c, bool,)
366−DEFINE_OPERATOR_RHS(Boolean, bool, <=, b, bool,)
367−DEFINE_OPERATOR_RHS(String, string&, <=, s, bool, *)
368−DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
258+auto any::operator[](const vector::size_type rhs) const -> const any& {
259+ RETURN_VALUE(Type::Vector, v->at(rhs),)
260+}
369261
370−auto any::operator>(const any& rhs_) const -> bool {
371− const any& lhs = extract_value(*this);
372− const any& rhs = extract_value(rhs_);
373− assert(lhs.type == rhs.type);
374− switch (lhs.type) {
375− case Type::Integer: return lhs.i > rhs.i;
376− case Type::Double: return lhs.d > rhs.d;
377− case Type::Character: return lhs.c > rhs.c;
378− case Type::Boolean: return lhs.b > rhs.b;
379− case Type::String: return (*lhs.s) > (*rhs.s);
380− default: assert(false && "Unsupported type for '>' operator");
381− }
382− return false;
262+auto any::operator[](const any& rhs) const -> const any& {
263+ RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
383264}
384265
385−DEFINE_OPERATOR_RHS(Integer, long, >, i, bool,)
386−DEFINE_OPERATOR_RHS(Double, double, >, d, bool,)
387−DEFINE_OPERATOR_RHS(Character, char, >, c, bool,)
388−DEFINE_OPERATOR_RHS(Boolean, bool, >, b, bool,)
389−DEFINE_OPERATOR_RHS(String, string&, >, s, bool, *)
390−DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
266+//-----------------------------------------------------------------------------
267+// Operator helper macros
268+//-----------------------------------------------------------------------------
391269
392−auto any::operator>=(const any& rhs_) const -> bool {
393− const any& lhs = extract_value(*this);
394− const any& rhs = extract_value(rhs_);
395− assert(lhs.type == rhs.type);
396− switch (lhs.type) {
397− case Type::Integer: return lhs.i >= rhs.i;
398− case Type::Double: return lhs.d >= rhs.d;
399− case Type::Character: return lhs.c >= rhs.c;
400− case Type::Boolean: return lhs.b >= rhs.b;
401− case Type::String: return (*lhs.s) >= (*rhs.s);
402− default: assert(false && "Unsupported type for '>' operator");
403− }
404− return false;
270+#define DEFINE_OPERATOR(op, ty, rty) \
271+auto operator op (const any& lhs, ty rhs) -> rty { \
272+ return lhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>() op rhs; \
273+} \
274+auto operator op (ty lhs, const any& rhs) -> rty { \
275+ return lhs op rhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>(); \
405276}
406277
407−DEFINE_OPERATOR_RHS(Integer, long, >=, i, bool,)
408−DEFINE_OPERATOR_RHS(Double, double, >=, d, bool,)
409−DEFINE_OPERATOR_RHS(Character, char, >=, c, bool,)
410−DEFINE_OPERATOR_RHS(Boolean, bool, >=, b, bool,)
411−DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
412−DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
413−
414−auto any::operator+(const any& rhs_) const -> any {
415− const any& lhs = extract_value(*this);
416− const any& rhs = extract_value(rhs_);
278+#define DEFINE_CSTR_COMPARISON_OPERATOR(op) \
279+ auto operator op (const any& lhs, const char * rhs) -> bool { \
280+ return lhs.cast<string>() op rhs; \
281+ } \
282+ auto operator op (const char * lhs, const any& rhs) -> bool { \
283+ return lhs op rhs.cast<string>(); \
284+ }
285+
286+#define DEFINE_COMPARISON_OPERATOR(op) \
287+ auto operator op (const any& lhs_, const any& rhs_) -> bool { \
288+ const any& lhs = any::extractValue(lhs_); \
289+ const any& rhs = any::extractValue(rhs_); \
290+ assert(lhs.type == rhs.type); \
291+ switch (lhs.type) { \
292+ case any::Type::Integer: return lhs.i op rhs.i; \
293+ case any::Type::Double: return lhs.d op rhs.d; \
294+ case any::Type::Character: return lhs.c op rhs.c; \
295+ case any::Type::Boolean: return lhs.b op rhs.b; \
296+ case any::Type::String: return (*lhs.s) op (*rhs.s); \
297+ case any::Type::Pointer: return lhs.p op rhs.p; \
298+ default: assert(false && "Unsupported type for operator " #op); \
299+ } \
300+ return false; \
301+ } \
302+ DEFINE_OPERATOR(op, long, bool) \
303+ DEFINE_OPERATOR(op, double, bool) \
304+ DEFINE_OPERATOR(op, char, bool) \
305+ DEFINE_OPERATOR(op, bool, bool) \
306+ DEFINE_OPERATOR(op, const string&, bool) \
307+ DEFINE_CSTR_COMPARISON_OPERATOR(op)
308+
309+//-----------------------------------------------------------------------------
310+// Operator definitions
311+//-----------------------------------------------------------------------------
312+
313+DEFINE_COMPARISON_OPERATOR(==)
314+DEFINE_COMPARISON_OPERATOR(!=)
315+DEFINE_COMPARISON_OPERATOR(<)
316+DEFINE_COMPARISON_OPERATOR(<=)
317+DEFINE_COMPARISON_OPERATOR(>)
318+DEFINE_COMPARISON_OPERATOR(>=)
319+
320+auto operator+(const any& lhs_, const any& rhs_) -> any {
321+ const any& lhs = any::extractValue(lhs_);
322+ const any& rhs = any::extractValue(rhs_);
417323 assert(lhs.type == rhs.type);
418324 switch (lhs.type) {
419− case Type::Integer: return lhs.i + rhs.i;
420− case Type::Double: return lhs.d + rhs.d;
421− case Type::Character: return any(char(lhs.c + rhs.c));
422− case Type::String: return (*lhs.s) + (*rhs.s);
325+ case any::Type::Integer: return lhs.i + rhs.i;
326+ case any::Type::Double: return lhs.d + rhs.d;
327+ case any::Type::Character: return any(char(lhs.c + rhs.c));
328+ case any::Type::String: return (*lhs.s) + (*rhs.s);
423329 default: assert(false && "Unsupported type for '+' operator");
424330 }
425331 return nullptr;
426332}
427333
428−DEFINE_OPERATOR_RHS(Integer, long, +, i, long,)
429−DEFINE_OPERATOR_RHS(Double, double, +, d, double,)
430−DEFINE_OPERATOR_RHS(Character, char, +, c, char,)
431−DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
432−DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
334+DEFINE_OPERATOR(+, long, long)
335+DEFINE_OPERATOR(+, double, double)
336+DEFINE_OPERATOR(+, char, char)
337+DEFINE_OPERATOR(+, const string&, string)
433338
434−auto any::operator-(const any& rhs_) const -> any {
435− const any& lhs = extract_value(*this);
436− const any& rhs = extract_value(rhs_);
339+auto operator+(const any& lhs, const char * rhs) -> string {
340+ return lhs.cast<string>() + rhs;
341+}
342+
343+auto operator+(const char * lhs, const any& rhs) -> string {
344+ return lhs + rhs.cast<string>();
345+}
346+
347+auto operator-(const any& lhs_, const any& rhs_) -> any {
348+ const any& lhs = any::extractValue(lhs_);
349+ const any& rhs = any::extractValue(rhs_);
437350 assert(lhs.type == rhs.type);
438351 switch (lhs.type) {
439− case Type::Integer: return lhs.i - rhs.i;
440− case Type::Double: return lhs.d - rhs.d;
441− case Type::Character: return any(char(lhs.c - rhs.c));
442− default: assert(false && "Unsupported type for '-' binary operator");
352+ case any::Type::Integer: return lhs.i - rhs.i;
353+ case any::Type::Double: return lhs.d - rhs.d;
354+ case any::Type::Character: return any(char(lhs.c - rhs.c));
355+ default: assert(false && "Unsupported type for '-' operator");
443356 }
444357 return nullptr;
445358}
446359
447−DEFINE_OPERATOR_RHS(Integer, long, -, i, long,)
448−DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
449−DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
360+DEFINE_OPERATOR(-, long, long)
361+DEFINE_OPERATOR(-, double, double)
362+DEFINE_OPERATOR(-, char, char)
450363
451−auto any::operator*(const any& rhs_) const -> any {
452− const any& lhs = extract_value(*this);
453− const any& rhs = extract_value(rhs_);
364+auto operator*(const any& lhs_, const any& rhs_) -> any {
365+ const any& lhs = any::extractValue(lhs_);
366+ const any& rhs = any::extractValue(rhs_);
454367 assert(lhs.type == rhs.type);
455368 switch (lhs.type) {
456− case Type::Integer: return lhs.i * rhs.i;
457− case Type::Double: return lhs.d * rhs.d;
369+ case any::Type::Integer: return lhs.i * rhs.i;
370+ case any::Type::Double: return lhs.d * rhs.d;
371+ case any::Type::Character: return any(char(lhs.c * rhs.c));
458372 default: assert(false && "Unsupported type for '*' operator");
459373 }
460374 return nullptr;
461375}
462376
463−DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
464−DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
377+DEFINE_OPERATOR(*, long, long)
378+DEFINE_OPERATOR(*, double, double)
379+DEFINE_OPERATOR(*, char, char)
465380
466−auto any::operator/(const any& rhs_) const -> any {
467− const any& lhs = extract_value(*this);
468− const any& rhs = extract_value(rhs_);
381+auto operator/(const any& lhs_, const any& rhs_) -> any {
382+ const any& lhs = any::extractValue(lhs_);
383+ const any& rhs = any::extractValue(rhs_);
469384 assert(lhs.type == rhs.type);
470385 switch (lhs.type) {
471− case Type::Integer: return lhs.i / rhs.i;
472− case Type::Double: return lhs.d / rhs.d;
386+ case any::Type::Integer: return lhs.i / rhs.i;
387+ case any::Type::Double: return lhs.d / rhs.d;
388+ case any::Type::Character: return any(char(lhs.c / rhs.c));
473389 default: assert(false && "Unsupported type for '/' operator");
474390 }
475391 return nullptr;
476392}
477393
478−DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
479−DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
394+DEFINE_OPERATOR(/, long, long)
395+DEFINE_OPERATOR(/, double, double)
396+DEFINE_OPERATOR(/, char, char)
480397
481−auto any::operator%(const any& rhs_) const -> any {
482− const any& lhs = extract_value(*this);
483− const any& rhs = extract_value(rhs_);
398+auto operator%(const any& lhs_, const any& rhs_) -> any {
399+ const any& lhs = any::extractValue(lhs_);
400+ const any& rhs = any::extractValue(rhs_);
484401 assert(lhs.type == rhs.type);
485402 switch (lhs.type) {
486− case Type::Integer: return lhs.i % rhs.i;
403+ case any::Type::Integer: return lhs.i % rhs.i;
404+ case any::Type::Character: return any(char(lhs.c % rhs.c));
487405 default: assert(false && "Unsupported type for '%' operator");
488406 }
489407 return nullptr;
490408}
491409
492−DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
410+DEFINE_OPERATOR(%, long, long)
411+DEFINE_OPERATOR(%, char, char)
493412
494−auto any::operator-() const -> any {
495− const any& lhs = any::extract_value(*this);
496− switch (lhs.type) {
497− case Type::Integer: return (- lhs.i);
498− case Type::Double: return (- lhs.d);
413+// unary negate
414+auto operator-(const any& rhs_) -> any {
415+ const any& rhs = any::extractValue(rhs_);
416+ switch (rhs.type) {
417+ case any::Type::Integer: return (- rhs.i);
418+ case any::Type::Double: return (- rhs.d);
499419 default: assert(false && "Unsupported type for unary '-' operator");
500420 }
501421 return nullptr;
502422}
503423
504−DEFINE_OPERATOR_LHS(Integer, long, ==, i, bool,)
505−DEFINE_OPERATOR_LHS(Integer, long, !=, i, bool,)
506−DEFINE_OPERATOR_LHS(Integer, long, <, i, bool,)
507−DEFINE_OPERATOR_LHS(Integer, long, <=, i, bool,)
508−DEFINE_OPERATOR_LHS(Integer, long, >, i, bool,)
509−DEFINE_OPERATOR_LHS(Integer, long, >=, i, bool,)
510−
511−DEFINE_OPERATOR_LHS(Double, double, ==, d, bool,)
512−DEFINE_OPERATOR_LHS(Double, double, !=, d, bool,)
513−DEFINE_OPERATOR_LHS(Double, double, <, d, bool,)
514−DEFINE_OPERATOR_LHS(Double, double, <=, d, bool,)
515−DEFINE_OPERATOR_LHS(Double, double, >, d, bool,)
516−DEFINE_OPERATOR_LHS(Double, double, >=, d, bool,)
517−
518−DEFINE_OPERATOR_LHS(Character, char, ==, c, bool,)
519−DEFINE_OPERATOR_LHS(Character, char, !=, c, bool,)
520−DEFINE_OPERATOR_LHS(Character, char, <, c, bool,)
521−DEFINE_OPERATOR_LHS(Character, char, <=, c, bool,)
522−DEFINE_OPERATOR_LHS(Character, char, >, c, bool,)
523−DEFINE_OPERATOR_LHS(Character, char, >=, c, bool,)
524−
525−DEFINE_OPERATOR_LHS(Boolean, bool, ==, b, bool,)
526−DEFINE_OPERATOR_LHS(Boolean, bool, !=, b, bool,)
527−DEFINE_OPERATOR_LHS(Boolean, bool, <, b, bool,)
528−DEFINE_OPERATOR_LHS(Boolean, bool, <=, b, bool,)
529−DEFINE_OPERATOR_LHS(Boolean, bool, >, b, bool,)
530−DEFINE_OPERATOR_LHS(Boolean, bool, >=, b, bool,)
531−
532−DEFINE_OPERATOR_LHS(String, string&, ==, s, bool, *)
533−DEFINE_OPERATOR_LHS(String, string&, !=, s, bool, *)
534−DEFINE_OPERATOR_LHS(String, string&, <, s, bool, *)
535−DEFINE_OPERATOR_LHS(String, string&, <=, s, bool, *)
536−DEFINE_OPERATOR_LHS(String, string&, >, s, bool, *)
537−DEFINE_OPERATOR_LHS(String, string&, >=, s, bool, *)
538−
539−DEFINE_OPERATOR_LHS(String, char* const, ==, s, bool, *)
540−DEFINE_OPERATOR_LHS(String, char* const, !=, s, bool, *)
541−DEFINE_OPERATOR_LHS(String, char* const, <, s, bool, *)
542−DEFINE_OPERATOR_LHS(String, char* const, <=, s, bool, *)
543−DEFINE_OPERATOR_LHS(String, char* const, >, s, bool, *)
544−DEFINE_OPERATOR_LHS(String, char* const, >=, s, bool, *)
545−
546−DEFINE_OPERATOR_LHS(Integer, long, +, i, long,)
547−DEFINE_OPERATOR_LHS(Integer, long, -, i, long,)
548−DEFINE_OPERATOR_LHS(Integer, long, *, i, long,)
549−DEFINE_OPERATOR_LHS(Integer, long, /, i, long,)
550−DEFINE_OPERATOR_LHS(Integer, long, %, i, long,)
551−
552−DEFINE_OPERATOR_LHS(Double, double, +, d, double,)
553−DEFINE_OPERATOR_LHS(Double, double, -, d, double,)
554−DEFINE_OPERATOR_LHS(Double, double, *, d, double,)
555−DEFINE_OPERATOR_LHS(Double, double, /, d, double,)
556−
557−DEFINE_OPERATOR_LHS(Character, char, +, i, char,)
558−DEFINE_OPERATOR_LHS(Character, char, -, i, char,)
559−
560−DEFINE_OPERATOR_LHS(String, string&, +, s, string, *)
561−DEFINE_OPERATOR_LHS(String, char* const, +, s, string, *)
562−
563−
564424} // namespace PureScript