@@ -16,7 +16,7 @@
17namespace PureScript {
17namespace PureScript {
19−#define copy_data(src) \
19+#define COPY_DATA(src) \
20 type = src.type; \
20 type = src.type; \
21 switch (type) { \
21 switch (type) { \
22 case Type::Integer: i = src.i; break; \
22 case Type::Integer: i = src.i; break; \
@@ -35,7 +35,7 @@ namespace PureScript {
35 default: assert(false && "Unsupported type in copy"); \
35 default: assert(false && "Unsupported type in copy"); \
38−#define move_data(src) \
38+#define MOVE_DATA(src) \
39 type = src.type; \
39 type = src.type; \
40 switch (type) { \
40 switch (type) { \
41 case Type::Integer: i = src.i; break; \
41 case Type::Integer: i = src.i; break; \
@@ -55,26 +55,26 @@ namespace PureScript {
57any::any(const any& other) {
57any::any(const any& other) {
58− copy_data(other);
58+ COPY_DATA(other);
61any::any(any&& other) noexcept {
61any::any(any&& other) noexcept {
62− move_data(other);
62+ MOVE_DATA(other);
65auto any::operator=(const any& rhs) -> any& {
65auto any::operator=(const any& rhs) -> any& {
66− copy_data(rhs);
66+ COPY_DATA(rhs);
67 return *this;
67 return *this;
70// Takes ownership -- might need to reconsider this
70// Takes ownership -- might need to reconsider this
71auto any::operator=(any& rhs) noexcept -> any& {
71auto any::operator=(any& rhs) noexcept -> any& {
72− move_data(rhs);
72+ MOVE_DATA(rhs);
73 return *this;
73 return *this;
76auto any::operator=(any&& rhs) noexcept -> any& {
76auto any::operator=(any&& rhs) noexcept -> any& {
77− move_data(rhs);
77+ MOVE_DATA(rhs);
78 return *this;
78 return *this;
@@ -98,467 +98,327 @@ any::~any() {
101− #define RETURN_VALUE(TYPE, VAL, FN) \
101+#define RETURN_VALUE(TYPE, VAL, FN) \
102+ if (type == TYPE) { \
105+ const any* valuePtr = this; \
107+ assert(valuePtr->type == Type::Thunk); \
108+ const any& value = (*valuePtr->t)(unthunk); \
102− if (type == TYPE) { \
109+ if (value.type == TYPE) { \
103− return FN(VAL); \
110+ return FN(value.VAL); \
105− const any* valuePtr = this; \
112+ valuePtr = &value; \
107− assert(valuePtr->type == Type::Thunk); \
108− const any& value = (*valuePtr->t)(unthunk); \
109− if (value.type == TYPE) { \
110− return FN(value.VAL); \
112− valuePtr = &value; \
113− } while (valuePtr->type != Type::Unknown); \
113+ } while (valuePtr->type != Type::Unknown); \
114− assert(false && "Unknown value type"); \
114+ assert(false && "Unknown value type"); \
115− return FN(VAL);
115+ return FN(VAL);
117− template <typename T>
117+template <typename T>
118− auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
118+auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
119− RETURN_VALUE(Type::Integer, i,)
119+ RETURN_VALUE(Type::Integer, i,)
121− template auto any::cast<long>() const -> long;
121+template auto any::cast<long>() const -> long;
123− template <typename T>
123+template <typename T>
124− auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
124+auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
125− RETURN_VALUE(Type::Double, d,)
125+ RETURN_VALUE(Type::Double, d,)
127− template auto any::cast<double>() const -> double;
127+template auto any::cast<double>() const -> double;
129− template <typename T>
129+template <typename T>
130− auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
130+auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
131− RETURN_VALUE(Type::Character, c,)
131+ RETURN_VALUE(Type::Character, c,)
133− template auto any::cast<char>() const -> char;
133+template auto any::cast<char>() const -> char;
135− template <typename T>
135+template <typename T>
136− auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
136+auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
137− RETURN_VALUE(Type::Boolean, b,)
137+ RETURN_VALUE(Type::Boolean, b,)
139− template auto any::cast<bool>() const -> bool;
139+template auto any::cast<bool>() const -> bool;
141− template <typename T>
141+template <typename T>
142− auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
142+auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
143− RETURN_VALUE(Type::String, s, *)
143+ RETURN_VALUE(Type::String, s, *)
145− template auto any::cast<string>() const -> const string&;
145+template auto any::cast<string>() const -> const string&;
147− template <typename T>
147+template <typename T>
148− auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
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(),)
149+ RETURN_VALUE(Type::String, s->c_str(),)
151− template auto any::cast<const char*>() const -> const char* const;
151+template auto any::cast<const char*>() const -> const char* const;
153− template <typename T>
153+template <typename T>
154− auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
154+auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
155− RETURN_VALUE(Type::Map, m, *)
155+ RETURN_VALUE(Type::Map, m, *)
157− template auto any::cast<any::map>() const -> const map&;
157+template auto any::cast<any::map>() const -> const map&;
159− template <typename T>
159+template <typename T>
160− auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
160+auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
161− RETURN_VALUE(Type::Vector, v, *)
161+ RETURN_VALUE(Type::Vector, v, *)
163− template auto any::cast<any::vector>() const -> const vector&;
163+template auto any::cast<any::vector>() const -> const vector&;
165− auto any::operator()(const any& arg) const -> any {
165+auto any::operator()(const any& arg) const -> any {
166− if (type == Type::Function) {
166+ if (type == Type::Function) {
169− if (type == Type::Closure) {
170− return (*l)(arg);
167+ return (*f)(arg);
172− const any* valuePtr = this;
174− assert(valuePtr->type == Type::Thunk);
175− const any& value = (*valuePtr->t)(unthunk);
176− if (value.type == Type::Function) {
177− return (*value.f)(arg);
179− if (value.type == Type::Closure) {
180− return (*value.l)(arg);
183− } while (valuePtr->type != Type::Unknown);
184− assert(false && "Unknown value type");
188− auto any::operator()(const as_thunk) const -> const any& {
189− assert(type == Type::Thunk);
169+ if (type == Type::Closure) {
190− return (*t)(unthunk);
170+ return (*l)(arg);
192−
172+ const any* valuePtr = this;
193− auto any::operator()() const -> any {
173+ do {
174+ assert(valuePtr->type == Type::Thunk);
175+ const any& value = (*valuePtr->t)(unthunk);
194− if (type == Type::EffFunction) {
176+ if (value.type == Type::Function) {
195− return (*e)();
177+ return (*value.f)(arg);
197− const any* valuePtr = this;
199− assert(valuePtr->type == Type::Thunk);
200− const any& value = (*valuePtr->t)(unthunk);
201− if (value.type == Type::EffFunction) {
179+ if (value.type == Type::Closure) {
202− return (*value.e)();
180+ return (*value.l)(arg);
205− } while (valuePtr->type != Type::Unknown);
206− assert(false && "Unknown value type");
210− any::operator long() const {
211− RETURN_VALUE(Type::Integer, i,)
214− any::operator double() const {
215− RETURN_VALUE(Type::Double, d,)
218− any::operator bool() const {
219− RETURN_VALUE(Type::Boolean, b,)
222− any::operator const string&() const {
223− RETURN_VALUE(Type::String, s, *)
226− any::operator const map&() const {
227− RETURN_VALUE(Type::Map, m, *)
230− any::operator const vector&() const {
231− RETURN_VALUE(Type::Vector, v, *)
234− auto any::extractPointer() const -> void* {
235− RETURN_VALUE(Type::Pointer, p.get(),)
238− auto any::extract_value(const any& a) -> const any& {
239− if (a.type != Type::Thunk) {
242− const any* valuePtr = &a;
182+ valuePtr = &value;
244− const any& value = (*valuePtr->t)(unthunk);
245− if (value.type != Type::Thunk) {
249− } while (valuePtr->type != Type::Unknown);
183+ } while (valuePtr->type != Type::Unknown);
250− assert(false && "Unknown value type");
184+ assert(false && "Unknown value type");
251− return a;
185+ return nullptr;
254− auto any::operator[](const map_key_t& rhs) const -> const any& {
188+auto any::operator()(const as_thunk) const -> const any& {
255− RETURN_VALUE(Type::Map, m->at(rhs),)
189+ assert(type == Type::Thunk);
190+ return (*t)(unthunk);
258− auto any::operator[](const vector::size_type rhs) const -> const any& {
193+auto any::operator()() const -> any {
259− RETURN_VALUE(Type::Vector, v->at(rhs),)
194+ if (type == Type::EffFunction) {
197+ const any* valuePtr = this;
199+ assert(valuePtr->type == Type::Thunk);
200+ const any& value = (*valuePtr->t)(unthunk);
201+ if (value.type == Type::EffFunction) {
202+ return (*value.e)();
205+ } while (valuePtr->type != Type::Unknown);
206+ assert(false && "Unknown value type");
262− auto any::operator[](const any& rhs) const -> const any& {
210+any::operator long() const {
263− RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
211+ RETURN_VALUE(Type::Integer, i,)
266−#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
214+any::operator double() const {
267−auto operator OP(const T lhs, const any& rhs_) -> R { \
215+ RETURN_VALUE(Type::Double, d,)
268− const any& rhs = any::extract_value(rhs_); \
269− assert(rhs.type == any::Type::K); \
270− return lhs OP P(rhs.V); \
273−#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
274−auto any::operator OP(const T rhs) const -> R { \
218+any::operator bool() const {
275− const any& lhs = any::extract_value(*this); \
219+ RETURN_VALUE(Type::Boolean, b,)
276− assert(lhs.type == Type::K); \
277− return P(lhs.V) OP rhs; \
280−auto any::operator==(const any& rhs_) const -> bool {
222+any::operator const string&() const {
281− const any& lhs = extract_value(*this);
282− const any& rhs = extract_value(rhs_);
283− assert(lhs.type == rhs.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);
223+ RETURN_VALUE(Type::String, s, *)
290− case Type::Pointer: return lhs.p == rhs.p;
291− default: assert(false && "Unsupported type for '==' operator");
296−DEFINE_OPERATOR_RHS(Integer, long, ==, i, bool,)
226+any::operator const map&() const {
297−DEFINE_OPERATOR_RHS(Double, double, ==, d, bool,)
227+ RETURN_VALUE(Type::Map, m, *)
298−DEFINE_OPERATOR_RHS(Character, char, ==, c, bool,)
228+}
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, *)
303−auto any::operator!=(const any& rhs_) const -> bool {
230+any::operator const vector&() const {
304− const any& lhs = extract_value(*this);
231+ RETURN_VALUE(Type::Vector, v, *)
305− const any& rhs = extract_value(rhs_);
306− assert(lhs.type == rhs.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");
319−DEFINE_OPERATOR_RHS(Integer, long, !=, i, bool,)
234+auto any::extractPointer() const -> void* {
320−DEFINE_OPERATOR_RHS(Double, double, !=, d, bool,)
235+ RETURN_VALUE(Type::Pointer, p.get(),)
321−DEFINE_OPERATOR_RHS(Character, char, !=, c, bool,)
236+}
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, *)
326−auto any::operator<(const any& rhs_) const -> bool {
238+auto any::extractValue(const any& a) -> const any& {
327− const any& lhs = extract_value(*this);
239+ if (a.type != Type::Thunk) {
328− const any& rhs = extract_value(rhs_);
240+ return a;
329− assert(lhs.type == rhs.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");
242+ const any* valuePtr = &a;
244+ const any& value = (*valuePtr->t)(unthunk);
245+ if (value.type != Type::Thunk) {
338− return false;
246+ return value;
249+ } while (valuePtr->type != Type::Unknown);
250+ assert(false && "Unknown value type");
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, *)
348−auto any::operator<=(const any& rhs_) const -> bool {
254+auto any::operator[](const map_key_t& rhs) const -> const any& {
349− const any& lhs = extract_value(*this);
255+ RETURN_VALUE(Type::Map, m->at(rhs),)
350− const any& rhs = extract_value(rhs_);
351− assert(lhs.type == rhs.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");
363−DEFINE_OPERATOR_RHS(Integer, long, <=, i, bool,)
258+auto any::operator[](const vector::size_type rhs) const -> const any& {
364−DEFINE_OPERATOR_RHS(Double, double, <=, d, bool,)
259+ RETURN_VALUE(Type::Vector, v->at(rhs),)
365−DEFINE_OPERATOR_RHS(Character, char, <=, c, bool,)
260+}
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, *)
370−auto any::operator>(const any& rhs_) const -> bool {
262+auto any::operator[](const any& rhs) const -> const any& {
371− const any& lhs = extract_value(*this);
263+ RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
372− const any& rhs = extract_value(rhs_);
373− assert(lhs.type == rhs.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");
385−DEFINE_OPERATOR_RHS(Integer, long, >, i, bool,)
266+//-----------------------------------------------------------------------------
386−DEFINE_OPERATOR_RHS(Double, double, >, d, bool,)
267+// Operator helper macros
387−DEFINE_OPERATOR_RHS(Character, char, >, c, bool,)
268+//-----------------------------------------------------------------------------
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, *)
392−auto any::operator>=(const any& rhs_) const -> bool {
270+#define DEFINE_OPERATOR(op, ty, rty) \
393− const any& lhs = extract_value(*this);
271+auto operator op (const any& lhs, ty rhs) -> rty { \
394− const any& rhs = extract_value(rhs_);
272+ return lhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>() op rhs; \
395− assert(lhs.type == rhs.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");
404− return false;
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>(); \
407−DEFINE_OPERATOR_RHS(Integer, long, >=, i, bool,)
278+#define DEFINE_CSTR_COMPARISON_OPERATOR(op) \
408−DEFINE_OPERATOR_RHS(Double, double, >=, d, bool,)
279+ auto operator op (const any& lhs, const char * rhs) -> bool { \
409−DEFINE_OPERATOR_RHS(Character, char, >=, c, bool,)
280+ return lhs.cast<string>() op rhs; \
410−DEFINE_OPERATOR_RHS(Boolean, bool, >=, b, bool,)
281+ } \
411−DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
282+ auto operator op (const char * lhs, const any& rhs) -> bool { \
412−DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
283+ return lhs op rhs.cast<string>(); \
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); \
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)
309+//-----------------------------------------------------------------------------
310+// Operator definitions
311+//-----------------------------------------------------------------------------
313+DEFINE_COMPARISON_OPERATOR(==)
314+DEFINE_COMPARISON_OPERATOR(!=)
315+DEFINE_COMPARISON_OPERATOR(<)
316+DEFINE_COMPARISON_OPERATOR(<=)
317+DEFINE_COMPARISON_OPERATOR(>)
318+DEFINE_COMPARISON_OPERATOR(>=)
414−auto any::operator+(const any& rhs_) const -> any {
320+auto operator+(const any& lhs_, const any& rhs_) -> any {
415− const any& lhs = extract_value(*this);
321+ const any& lhs = any::extractValue(lhs_);
416− const any& rhs = extract_value(rhs_);
322+ const any& rhs = any::extractValue(rhs_);
417 assert(lhs.type == rhs.type);
323 assert(lhs.type == rhs.type);
418 switch (lhs.type) {
324 switch (lhs.type) {
419− case Type::Integer: return lhs.i + rhs.i;
325+ case any::Type::Integer: return lhs.i + rhs.i;
420− case Type::Double: return lhs.d + rhs.d;
326+ case any::Type::Double: return lhs.d + rhs.d;
421− case Type::Character: return any(char(lhs.c + rhs.c));
327+ case any::Type::Character: return any(char(lhs.c + rhs.c));
422− case Type::String: return (*lhs.s) + (*rhs.s);
328+ case any::Type::String: return (*lhs.s) + (*rhs.s);
423 default: assert(false && "Unsupported type for '+' operator");
329 default: assert(false && "Unsupported type for '+' operator");
425 return nullptr;
331 return nullptr;
428−DEFINE_OPERATOR_RHS(Integer, long, +, i, long,)
334+DEFINE_OPERATOR(+, long, long)
429−DEFINE_OPERATOR_RHS(Double, double, +, d, double,)
335+DEFINE_OPERATOR(+, double, double)
430−DEFINE_OPERATOR_RHS(Character, char, +, c, char,)
336+DEFINE_OPERATOR(+, char, char)
431−DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
337+DEFINE_OPERATOR(+, const string&, string)
432−DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
339+auto operator+(const any& lhs, const char * rhs) -> string {
340+ return lhs.cast<string>() + rhs;
343+auto operator+(const char * lhs, const any& rhs) -> string {
344+ return lhs + rhs.cast<string>();
434−auto any::operator-(const any& rhs_) const -> any {
347+auto operator-(const any& lhs_, const any& rhs_) -> any {
435− const any& lhs = extract_value(*this);
348+ const any& lhs = any::extractValue(lhs_);
436− const any& rhs = extract_value(rhs_);
349+ const any& rhs = any::extractValue(rhs_);
437 assert(lhs.type == rhs.type);
350 assert(lhs.type == rhs.type);
438 switch (lhs.type) {
351 switch (lhs.type) {
439− case Type::Integer: return lhs.i - rhs.i;
352+ case any::Type::Integer: return lhs.i - rhs.i;
440− case Type::Double: return lhs.d - rhs.d;
353+ case any::Type::Double: return lhs.d - rhs.d;
441− case Type::Character: return any(char(lhs.c - rhs.c));
354+ case any::Type::Character: return any(char(lhs.c - rhs.c));
442− default: assert(false && "Unsupported type for '-' binary operator");
355+ default: assert(false && "Unsupported type for '-' operator");
444 return nullptr;
357 return nullptr;
447−DEFINE_OPERATOR_RHS(Integer, long, -, i, long,)
360+DEFINE_OPERATOR(-, long, long)
448−DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
361+DEFINE_OPERATOR(-, double, double)
449−DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
362+DEFINE_OPERATOR(-, char, char)
451−auto any::operator*(const any& rhs_) const -> any {
364+auto operator*(const any& lhs_, const any& rhs_) -> any {
452− const any& lhs = extract_value(*this);
365+ const any& lhs = any::extractValue(lhs_);
453− const any& rhs = extract_value(rhs_);
366+ const any& rhs = any::extractValue(rhs_);
454 assert(lhs.type == rhs.type);
367 assert(lhs.type == rhs.type);
455 switch (lhs.type) {
368 switch (lhs.type) {
456− case Type::Integer: return lhs.i * rhs.i;
369+ case any::Type::Integer: return lhs.i * rhs.i;
457− case Type::Double: return lhs.d * rhs.d;
370+ case any::Type::Double: return lhs.d * rhs.d;
371+ case any::Type::Character: return any(char(lhs.c * rhs.c));
458 default: assert(false && "Unsupported type for '*' operator");
372 default: assert(false && "Unsupported type for '*' operator");
460 return nullptr;
374 return nullptr;
463−DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
377+DEFINE_OPERATOR(*, long, long)
464−DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
378+DEFINE_OPERATOR(*, double, double)
379+DEFINE_OPERATOR(*, char, char)
466−auto any::operator/(const any& rhs_) const -> any {
381+auto operator/(const any& lhs_, const any& rhs_) -> any {
467− const any& lhs = extract_value(*this);
382+ const any& lhs = any::extractValue(lhs_);
468− const any& rhs = extract_value(rhs_);
383+ const any& rhs = any::extractValue(rhs_);
469 assert(lhs.type == rhs.type);
384 assert(lhs.type == rhs.type);
470 switch (lhs.type) {
385 switch (lhs.type) {
471− case Type::Integer: return lhs.i / rhs.i;
386+ case any::Type::Integer: return lhs.i / rhs.i;
472− case Type::Double: return lhs.d / rhs.d;
387+ case any::Type::Double: return lhs.d / rhs.d;
388+ case any::Type::Character: return any(char(lhs.c / rhs.c));
473 default: assert(false && "Unsupported type for '/' operator");
389 default: assert(false && "Unsupported type for '/' operator");
475 return nullptr;
391 return nullptr;
478−DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
394+DEFINE_OPERATOR(/, long, long)
479−DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
395+DEFINE_OPERATOR(/, double, double)
396+DEFINE_OPERATOR(/, char, char)
481−auto any::operator%(const any& rhs_) const -> any {
398+auto operator%(const any& lhs_, const any& rhs_) -> any {
482− const any& lhs = extract_value(*this);
399+ const any& lhs = any::extractValue(lhs_);
483− const any& rhs = extract_value(rhs_);
400+ const any& rhs = any::extractValue(rhs_);
484 assert(lhs.type == rhs.type);
401 assert(lhs.type == rhs.type);
485 switch (lhs.type) {
402 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));
487 default: assert(false && "Unsupported type for '%' operator");
405 default: assert(false && "Unsupported type for '%' operator");
489 return nullptr;
407 return nullptr;
492−DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
410+DEFINE_OPERATOR(%, long, long)
411+DEFINE_OPERATOR(%, char, char)
494−auto any::operator-() const -> any {
414+auto operator-(const any& rhs_) -> any {
495− const any& lhs = any::extract_value(*this);
415+ const any& rhs = any::extractValue(rhs_);
496− switch (lhs.type) {
416+ switch (rhs.type) {
497− case Type::Integer: return (- lhs.i);
417+ case any::Type::Integer: return (- rhs.i);
498− case Type::Double: return (- lhs.d);
418+ case any::Type::Double: return (- rhs.d);
499 default: assert(false && "Unsupported type for unary '-' operator");
419 default: assert(false && "Unsupported type for unary '-' operator");
501 return nullptr;
421 return nullptr;
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,)
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,)
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,)
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,)
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, *)
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, *)
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,)
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,)
557−DEFINE_OPERATOR_LHS(Character, char, +, i, char,)
558−DEFINE_OPERATOR_LHS(Character, char, -, i, char,)
560−DEFINE_OPERATOR_LHS(String, string&, +, s, string, *)
561−DEFINE_OPERATOR_LHS(String, char* const, +, s, string, *)
564} // namespace PureScript
424} // namespace PureScript