@@ -19,18 +19,19 @@ namespace PureScript {
1919#define COPY_DATA(src) \
2020 type = src.type; \
2121 switch (type) { \
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::String: new (&s) shared<string> (src.s); break; \
27− case Type::Map: new (&m) shared<map> (src.m); break; \
28− case Type::Vector: new (&v) shared<vector> (src.v); break; \
29− case Type::Function: f = src.f; break; \
30− case Type::Closure: new (&l) shared<closure> (src.l); break; \
31− case Type::EffFunction: new (&e) shared<eff_fn> (src.e); break; \
32− case Type::Thunk: t = src.t; break; \
33− case Type::Pointer: new (&p) shared<void> (src.p); break; \
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; \
3435 \
3536 default: assert(false && "Unsupported type in copy"); \
3637 }
@@ -38,18 +39,19 @@ namespace PureScript {
3839#define MOVE_DATA(src) \
3940 type = src.type; \
4041 switch (type) { \
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::String: new (&s) shared<string> (std::move(src.s)); break; \
46− case Type::Map: new (&m) shared<map> (std::move(src.m)); break; \
47− case Type::Vector: new (&v) shared<vector> (std::move(src.v)); break; \
48− case Type::Function: f = src.f; break; \
49− case Type::Closure: new (&l) shared<closure> (std::move(src.l)); break; \
50− case Type::EffFunction: new (&e) shared<eff_fn> (std::move(src.e)); break; \
51− case Type::Thunk: t = src.t; break; \
52− case Type::Pointer: new (&p) shared<void> (std::move(src.p)); break; \
42+ case Type::Integer: i = src.i; break; \
43+ case Type::Double: d = src.d; break; \
44+ case Type::Character: c = src.c; break; \
45+ case Type::Boolean: b = src.b; break; \
46+ case Type::StringLiteral: r = src.r; break; \
47+ case Type::String: new (&s) shared<std::string>(std::move(src.s)); break; \
48+ case Type::Map: new (&m) shared<map>(std::move(src.m)); break; \
49+ case Type::Vector: new (&v) shared<vector>(std::move(src.v)); break; \
50+ case Type::Function: f = src.f; break; \
51+ case Type::Closure: new (&l) shared<closure>(std::move(src.l)); break; \
52+ case Type::EffFunction: new (&e) shared<eff_fn>(std::move(src.e)); break; \
53+ case Type::Thunk: t = src.t; break; \
54+ case Type::Pointer: new (&p) shared<void>(std::move(src.p)); break; \
5355 \
5456 default: assert(false && "Unsupported type in move"); \
5557 }
@@ -81,18 +83,19 @@ auto any::operator=(any&& rhs) noexcept -> any& {
8183any::~any() {
8284 // std::cout << "destroy" << std::endl;
8385 switch (type) {
84− case Type::Integer: ; break;
85− case Type::Double: ; break;
86− case Type::Character: ; break;
87− case Type::Boolean: ; break;
88− case Type::String: s.~shared<string>(); break;
89− case Type::Map: m.~shared<map>(); break;
90− case Type::Vector: v.~shared<vector>(); break;
91− case Type::Function: ; break;
92− case Type::Closure: l.~shared<closure>(); break;
93− case Type::EffFunction: e.~shared<eff_fn>(); break;
94− case Type::Thunk: ; break;
95− case Type::Pointer: p.~shared<void>(); break;
86+ case Type::Integer: ; break;
87+ case Type::Double: ; break;
88+ case Type::Character: ; break;
89+ case Type::Boolean: ; break;
90+ case Type::StringLiteral: ; break;
91+ case Type::String: s.~shared<std::string>(); break;
92+ case Type::Map: m.~shared<map>(); break;
93+ case Type::Vector: v.~shared<vector>(); break;
94+ case Type::Function: ; break;
95+ case Type::Closure: l.~shared<closure>(); break;
96+ case Type::EffFunction: e.~shared<eff_fn>(); break;
97+ case Type::Thunk: ; break;
98+ case Type::Pointer: p.~shared<void>(); break;
9699
97100 default: assert(false && "Unsupported type in destructor");
98101 }
@@ -139,16 +142,15 @@ auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value,
139142template auto any::cast<bool>() const -> bool;
140143
141144template <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&;
146−
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(),)
145+auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type {
146+ const any& val = extractValue(*this);
147+ if (val.type == Type::StringLiteral) {
148+ return val.r;
149+ }
150+ assert(val.type == Type::String);
151+ return val.s->c_str();
150152}
151−template auto any::cast<const char*>() const -> const char* const;
153+template auto any::cast<string>() const -> string;
152154
153155template <typename T>
154156auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
@@ -219,8 +221,12 @@ any::operator bool() const {
219221 RETURN_VALUE(Type::Boolean, b,)
220222}
221223
222−any::operator const string&() const {
223− RETURN_VALUE(Type::String, s, *)
224+any::operator string() const {
225+ return cast<string>();
226+}
227+
228+any::operator std::string() const {
229+ return cast<string>();
224230}
225231
226232any::operator const map&() const {
@@ -275,25 +281,49 @@ auto operator op (ty lhs, const any& rhs) -> rty { \
275281 return lhs op rhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>(); \
276282}
277283
284+#define DEFINE_CSTR_EQUALS_OPERATOR() \
285+ auto operator==(const any& lhs_, const char * rhs) -> bool { \
286+ const any& lhs = any::extractValue(lhs_); \
287+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
288+ if (lhs.type == any::Type::StringLiteral) { \
289+ return (lhs.r == rhs) || (strcmp(lhs.r, rhs) == 0); \
290+ } \
291+ return strcmp(lhs.s->c_str(), rhs) == 0; \
292+ } \
293+ auto operator==(const char * lhs, const any& rhs_) -> bool { \
294+ const any& rhs = any::extractValue(rhs_); \
295+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
296+ if (rhs.type == any::Type::StringLiteral) { \
297+ return (lhs == rhs.r) || (strcmp(lhs, rhs) == 0); \
298+ } \
299+ return strcmp(lhs, rhs.s->c_str()) == 0; \
300+ }
301+
278302#define DEFINE_CSTR_COMPARISON_OPERATOR(op) \
279303 auto operator op (const any& lhs, const char * rhs) -> bool { \
280− return lhs.cast<string>() op rhs; \
304+ return strcmp(lhs.cast<string>(), rhs) op 0; \
281305 } \
282306 auto operator op (const char * lhs, const any& rhs) -> bool { \
283− return lhs op rhs.cast<string>(); \
307+ return strcmp(lhs, rhs.cast<string>()) op 0; \
284308 }
285309
286310#define DEFINE_COMPARISON_OPERATOR(op) \
287311 auto operator op (const any& lhs_, const any& rhs_) -> bool { \
288312 const any& lhs = any::extractValue(lhs_); \
289313 const any& rhs = any::extractValue(rhs_); \
290− assert(lhs.type == rhs.type); \
291314 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); \
315+ case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i op rhs.i; \
316+ case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d op rhs.d; \
317+ case any::Type::Character: assert(lhs.type == any::Type::Character); return lhs.c op rhs.c; \
318+ case any::Type::Boolean: assert(lhs.type == any::Type::Boolean); return lhs.b op rhs.b; \
319+ case any::Type::StringLiteral: \
320+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
321+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
322+ return strcmp(lhs.r, rhs.type == any::Type::StringLiteral ? rhs.r : rhs.s->c_str()) op 0; \
323+ case any::Type::String: \
324+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
325+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
326+ return strcmp(lhs.s->c_str(), rhs.type == any::Type::StringLiteral ? rhs.r : rhs.s->c_str()) op 0; \
297327 case any::Type::Pointer: return lhs.p op rhs.p; \
298328 default: assert(false && "Unsupported type for operator " #op); \
299329 } \
@@ -303,8 +333,6 @@ auto operator op (ty lhs, const any& rhs) -> rty { \
303333 DEFINE_OPERATOR(op, double, bool) \
304334 DEFINE_OPERATOR(op, char, bool) \
305335 DEFINE_OPERATOR(op, bool, bool) \
306− DEFINE_OPERATOR(op, const string&, bool) \
307− DEFINE_CSTR_COMPARISON_OPERATOR(op)
308336
309337//-----------------------------------------------------------------------------
310338// Operator definitions
@@ -317,15 +345,28 @@ DEFINE_COMPARISON_OPERATOR(<=)
317345DEFINE_COMPARISON_OPERATOR(>)
318346DEFINE_COMPARISON_OPERATOR(>=)
319347
348+DEFINE_CSTR_EQUALS_OPERATOR()
349+DEFINE_CSTR_COMPARISON_OPERATOR(!=)
350+DEFINE_CSTR_COMPARISON_OPERATOR(<)
351+DEFINE_CSTR_COMPARISON_OPERATOR(<=)
352+DEFINE_CSTR_COMPARISON_OPERATOR(>)
353+DEFINE_CSTR_COMPARISON_OPERATOR(>=)
354+
320355auto operator+(const any& lhs_, const any& rhs_) -> any {
321356 const any& lhs = any::extractValue(lhs_);
322357 const any& rhs = any::extractValue(rhs_);
323− assert(lhs.type == rhs.type);
324358 switch (lhs.type) {
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);
359+ case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i + rhs.i;
360+ case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d + rhs.d;
361+ case any::Type::Character: assert(lhs.type == any::Type::Character); return any(char(lhs.c + rhs.c));
362+ case any::Type::StringLiteral:
363+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
364+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
365+ return rhs.type == any::Type::StringLiteral ? std::string(lhs.r) + rhs.r : lhs.r + *rhs.s;
366+ case any::Type::String:
367+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
368+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
369+ return rhs.type == any::Type::StringLiteral ? *lhs.s + rhs.r : *lhs.s + *rhs.s;
329370 default: assert(false && "Unsupported type for '+' operator");
330371 }
331372 return nullptr;
@@ -334,14 +375,17 @@ auto operator+(const any& lhs_, const any& rhs_) -> any {
334375DEFINE_OPERATOR(+, long, long)
335376DEFINE_OPERATOR(+, double, double)
336377DEFINE_OPERATOR(+, char, char)
337−DEFINE_OPERATOR(+, const string&, string)
338378
339−auto operator+(const any& lhs, const char * rhs) -> string {
340− return lhs.cast<string>() + rhs;
379+auto operator+(const any& lhs_, const char * rhs) -> std::string {
380+ const any& lhs = any::extractValue(lhs_);
381+ assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
382+ return lhs.type == any::Type::StringLiteral ? std::string(lhs.r) + rhs : *lhs.s + rhs;
341383}
342384
343−auto operator+(const char * lhs, const any& rhs) -> string {
344− return lhs + rhs.cast<string>();
385+auto operator+(const char * lhs, const any& rhs_) -> std::string {
386+ const any& rhs = any::extractValue(rhs_);
387+ assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
388+ return rhs.type == any::Type::StringLiteral ? lhs + std::string(rhs.r) : lhs + *rhs.s;
345389}
346390
347391auto operator-(const any& lhs_, const any& rhs_) -> any {