1///////////////////////////////////////////////////////////////////////////////
3// Module : purescript.cc
4// Copyright : (c) Andy Arvanitis 2015
7// Maintainer : Andy Arvanitis <andy.arvanitis@gmail.com>
8// Stability : experimental
11// Basic types and functions to support purescript-to-C++1x rendering
13///////////////////////////////////////////////////////////////////////////////
15#include "PureScript.hh"
19#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::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; \
35 default: assert(false && "Unsupported type in copy"); \
38#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::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; \
54 default: assert(false && "Unsupported type in move"); \
57any::any(const any& other) {
61any::any(any&& other) noexcept {
65auto any::operator=(const any& rhs) -> any& {
70// Takes ownership -- might need to reconsider this
71auto any::operator=(any& rhs) noexcept -> any& {
76auto any::operator=(any&& rhs) noexcept -> any& {
82 // std::cout << "destroy" << std::endl;
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;
97 default: assert(false && "Unsupported type in destructor");
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); \
109 if (value.type == TYPE) { \
110 return FN(value.VAL); \
113 } while (valuePtr->type != Type::Unknown); \
114 assert(false && "Unknown value type"); \
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,)
121 template auto any::cast<long>() const -> long;
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,)
127 template auto any::cast<double>() const -> double;
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,)
133 template auto any::cast<char>() const -> char;
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,)
139 template auto any::cast<bool>() const -> bool;
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, *)
145 template auto any::cast<string>() const -> const string&;
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(),)
151 template auto any::cast<const char*>() const -> const char* const;
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, *)
157 template auto any::cast<any::map>() const -> const map&;
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, *)
163 template auto any::cast<any::vector>() const -> const vector&;
165 auto any::operator()(const any& arg) const -> any {
166 if (type == Type::Function) {
169 if (type == Type::Closure) {
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);
190 return (*t)(unthunk);
193 auto any::operator()() const -> any {
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) {
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;
244 const any& value = (*valuePtr->t)(unthunk);
245 if (value.type != Type::Thunk) {
249 } while (valuePtr->type != Type::Unknown);
250 assert(false && "Unknown value type");
254 auto any::operator[](const map_key_t& rhs) const -> const any& {
255 RETURN_VALUE(Type::Map, m->at(rhs),)
258 auto any::operator[](const vector::size_type rhs) const -> const any& {
259 RETURN_VALUE(Type::Vector, v->at(rhs),)
262 auto any::operator[](const any& rhs) const -> const any& {
263 RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
266#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
267auto 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); \
273#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
274auto 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; \
280auto 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);
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");
296DEFINE_OPERATOR_RHS(Integer, long, ==, i, bool,)
297DEFINE_OPERATOR_RHS(Double, double, ==, d, bool,)
298DEFINE_OPERATOR_RHS(Character, char, ==, c, bool,)
299DEFINE_OPERATOR_RHS(Boolean, bool, ==, b, bool,)
300DEFINE_OPERATOR_RHS(String, string&, ==, s, bool, *)
301DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
303auto 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);
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");
319DEFINE_OPERATOR_RHS(Integer, long, !=, i, bool,)
320DEFINE_OPERATOR_RHS(Double, double, !=, d, bool,)
321DEFINE_OPERATOR_RHS(Character, char, !=, c, bool,)
322DEFINE_OPERATOR_RHS(Boolean, bool, !=, b, bool,)
323DEFINE_OPERATOR_RHS(String, string&, !=, s, bool, *)
324DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
326auto 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);
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");
341DEFINE_OPERATOR_RHS(Integer, long, <, i, bool,)
342DEFINE_OPERATOR_RHS(Double, double, <, d, bool,)
343DEFINE_OPERATOR_RHS(Character, char, <, c, bool,)
344DEFINE_OPERATOR_RHS(Boolean, bool, <, b, bool,)
345DEFINE_OPERATOR_RHS(String, string&, <, s, bool, *)
346DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
348auto 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);
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");
363DEFINE_OPERATOR_RHS(Integer, long, <=, i, bool,)
364DEFINE_OPERATOR_RHS(Double, double, <=, d, bool,)
365DEFINE_OPERATOR_RHS(Character, char, <=, c, bool,)
366DEFINE_OPERATOR_RHS(Boolean, bool, <=, b, bool,)
367DEFINE_OPERATOR_RHS(String, string&, <=, s, bool, *)
368DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
370auto 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);
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");
385DEFINE_OPERATOR_RHS(Integer, long, >, i, bool,)
386DEFINE_OPERATOR_RHS(Double, double, >, d, bool,)
387DEFINE_OPERATOR_RHS(Character, char, >, c, bool,)
388DEFINE_OPERATOR_RHS(Boolean, bool, >, b, bool,)
389DEFINE_OPERATOR_RHS(String, string&, >, s, bool, *)
390DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
392auto 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);
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");
407DEFINE_OPERATOR_RHS(Integer, long, >=, i, bool,)
408DEFINE_OPERATOR_RHS(Double, double, >=, d, bool,)
409DEFINE_OPERATOR_RHS(Character, char, >=, c, bool,)
410DEFINE_OPERATOR_RHS(Boolean, bool, >=, b, bool,)
411DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
412DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
414auto any::operator+(const any& rhs_) const -> any {
415 const any& lhs = extract_value(*this);
416 const any& rhs = extract_value(rhs_);
417 assert(lhs.type == rhs.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);
423 default: assert(false && "Unsupported type for '+' operator");
428DEFINE_OPERATOR_RHS(Integer, long, +, i, long,)
429DEFINE_OPERATOR_RHS(Double, double, +, d, double,)
430DEFINE_OPERATOR_RHS(Character, char, +, c, char,)
431DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
432DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
434auto any::operator-(const any& rhs_) const -> any {
435 const any& lhs = extract_value(*this);
436 const any& rhs = extract_value(rhs_);
437 assert(lhs.type == rhs.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");
447DEFINE_OPERATOR_RHS(Integer, long, -, i, long,)
448DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
449DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
451auto any::operator*(const any& rhs_) const -> any {
452 const any& lhs = extract_value(*this);
453 const any& rhs = extract_value(rhs_);
454 assert(lhs.type == rhs.type);
456 case Type::Integer: return lhs.i * rhs.i;
457 case Type::Double: return lhs.d * rhs.d;
458 default: assert(false && "Unsupported type for '*' operator");
463DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
464DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
466auto any::operator/(const any& rhs_) const -> any {
467 const any& lhs = extract_value(*this);
468 const any& rhs = extract_value(rhs_);
469 assert(lhs.type == rhs.type);
471 case Type::Integer: return lhs.i / rhs.i;
472 case Type::Double: return lhs.d / rhs.d;
473 default: assert(false && "Unsupported type for '/' operator");
478DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
479DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
481auto any::operator%(const any& rhs_) const -> any {
482 const any& lhs = extract_value(*this);
483 const any& rhs = extract_value(rhs_);
484 assert(lhs.type == rhs.type);
486 case Type::Integer: return lhs.i % rhs.i;
487 default: assert(false && "Unsupported type for '%' operator");
492DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
494auto any::operator-() const -> any {
495 const any& lhs = any::extract_value(*this);
497 case Type::Integer: return (- lhs.i);
498 case Type::Double: return (- lhs.d);
499 default: assert(false && "Unsupported type for unary '-' operator");
504DEFINE_OPERATOR_LHS(Integer, long, ==, i, bool,)
505DEFINE_OPERATOR_LHS(Integer, long, !=, i, bool,)
506DEFINE_OPERATOR_LHS(Integer, long, <, i, bool,)
507DEFINE_OPERATOR_LHS(Integer, long, <=, i, bool,)
508DEFINE_OPERATOR_LHS(Integer, long, >, i, bool,)
509DEFINE_OPERATOR_LHS(Integer, long, >=, i, bool,)
511DEFINE_OPERATOR_LHS(Double, double, ==, d, bool,)
512DEFINE_OPERATOR_LHS(Double, double, !=, d, bool,)
513DEFINE_OPERATOR_LHS(Double, double, <, d, bool,)
514DEFINE_OPERATOR_LHS(Double, double, <=, d, bool,)
515DEFINE_OPERATOR_LHS(Double, double, >, d, bool,)
516DEFINE_OPERATOR_LHS(Double, double, >=, d, bool,)
518DEFINE_OPERATOR_LHS(Character, char, ==, c, bool,)
519DEFINE_OPERATOR_LHS(Character, char, !=, c, bool,)
520DEFINE_OPERATOR_LHS(Character, char, <, c, bool,)
521DEFINE_OPERATOR_LHS(Character, char, <=, c, bool,)
522DEFINE_OPERATOR_LHS(Character, char, >, c, bool,)
523DEFINE_OPERATOR_LHS(Character, char, >=, c, bool,)
525DEFINE_OPERATOR_LHS(Boolean, bool, ==, b, bool,)
526DEFINE_OPERATOR_LHS(Boolean, bool, !=, b, bool,)
527DEFINE_OPERATOR_LHS(Boolean, bool, <, b, bool,)
528DEFINE_OPERATOR_LHS(Boolean, bool, <=, b, bool,)
529DEFINE_OPERATOR_LHS(Boolean, bool, >, b, bool,)
530DEFINE_OPERATOR_LHS(Boolean, bool, >=, b, bool,)
532DEFINE_OPERATOR_LHS(String, string&, ==, s, bool, *)
533DEFINE_OPERATOR_LHS(String, string&, !=, s, bool, *)
534DEFINE_OPERATOR_LHS(String, string&, <, s, bool, *)
535DEFINE_OPERATOR_LHS(String, string&, <=, s, bool, *)
536DEFINE_OPERATOR_LHS(String, string&, >, s, bool, *)
537DEFINE_OPERATOR_LHS(String, string&, >=, s, bool, *)
539DEFINE_OPERATOR_LHS(String, char* const, ==, s, bool, *)
540DEFINE_OPERATOR_LHS(String, char* const, !=, s, bool, *)
541DEFINE_OPERATOR_LHS(String, char* const, <, s, bool, *)
542DEFINE_OPERATOR_LHS(String, char* const, <=, s, bool, *)
543DEFINE_OPERATOR_LHS(String, char* const, >, s, bool, *)
544DEFINE_OPERATOR_LHS(String, char* const, >=, s, bool, *)
546DEFINE_OPERATOR_LHS(Integer, long, +, i, long,)
547DEFINE_OPERATOR_LHS(Integer, long, -, i, long,)
548DEFINE_OPERATOR_LHS(Integer, long, *, i, long,)
549DEFINE_OPERATOR_LHS(Integer, long, /, i, long,)
550DEFINE_OPERATOR_LHS(Integer, long, %, i, long,)
552DEFINE_OPERATOR_LHS(Double, double, +, d, double,)
553DEFINE_OPERATOR_LHS(Double, double, -, d, double,)
554DEFINE_OPERATOR_LHS(Double, double, *, d, double,)
555DEFINE_OPERATOR_LHS(Double, double, /, d, double,)
557DEFINE_OPERATOR_LHS(Character, char, +, i, char,)
558DEFINE_OPERATOR_LHS(Character, char, -, i, char,)
560DEFINE_OPERATOR_LHS(String, string&, +, s, string, *)
561DEFINE_OPERATOR_LHS(String, char* const, +, s, string, *)
564} // namespace PureScript
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list