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: new (&f) shared<fn> (src.f); break; \
30 case Type::EffFunction: new (&e) shared<eff_fn> (src.e); break; \
31 case Type::Thunk: new (&t) shared<thunk> (src.t); break; \
32 case Type::Pointer: new (&p) shared<void> (src.p); break; \
34 default: assert(false && "Unsupported type in copy"); \
37#define move_data(src) \
40 case Type::Integer: i = src.i; break; \
41 case Type::Double: d = src.d; break; \
42 case Type::Character: c = src.c; break; \
43 case Type::Boolean: b = src.b; break; \
44 case Type::String: new (&s) shared<string> (std::move(src.s)); break; \
45 case Type::Map: new (&m) shared<map> (std::move(src.m)); break; \
46 case Type::Vector: new (&v) shared<vector> (std::move(src.v)); break; \
47 case Type::Function: new (&f) shared<fn> (std::move(src.f)); break; \
48 case Type::EffFunction: new (&e) shared<eff_fn> (std::move(src.e)); break; \
49 case Type::Thunk: new (&t) shared<thunk> (std::move(src.t)); break; \
50 case Type::Pointer: new (&p) shared<void> (std::move(src.p)); break; \
52 default: assert(false && "Unsupported type in move"); \
55any::any(const any& other) {
59any::any(any&& other) {
63auto any::operator=(const any& rhs) -> any& {
68// Takes ownership -- might need to reconsider this
69auto any::operator=(any& rhs) -> any& {
74auto any::operator=(any&& rhs) -> any& {
80 // std::cout << "destroy" << std::endl;
82 case Type::Integer: ; break;
83 case Type::Double: ; break;
84 case Type::Character: ; break;
85 case Type::Boolean: ; break;
86 case Type::String: s.~shared<string>(); break;
87 case Type::Map: m.~shared<map>(); break;
88 case Type::Vector: v.~shared<vector>(); break;
89 case Type::Function: f.~shared<fn>(); break;
90 case Type::EffFunction: e.~shared<eff_fn>(); break;
91 case Type::Thunk: t.~shared<thunk>(); break;
92 case Type::Pointer: p.~shared<void>(); break;
94 default: assert(false && "Unsupported type in destructor");
98 #define RETURN_VALUE(TYPE, VAL, FN) \
102 const any* valuePtr = this; \
104 assert(valuePtr->type == Type::Thunk); \
105 const any& value = (*valuePtr->t)(unthunk); \
106 if (value.type == TYPE) { \
107 return FN(value.VAL); \
110 } while (valuePtr->type != Type::Unknown); \
111 assert(false && "Unknown value type"); \
114 template <typename T>
115 auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
116 RETURN_VALUE(Type::Integer, i,)
118 template auto any::cast<long>() const -> long;
120 template <typename T>
121 auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
122 RETURN_VALUE(Type::Double, d,)
124 template auto any::cast<double>() const -> double;
126 template <typename T>
127 auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
128 RETURN_VALUE(Type::Character, c,)
130 template auto any::cast<char>() const -> char;
132 template <typename T>
133 auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
134 RETURN_VALUE(Type::Boolean, b,)
136 template auto any::cast<bool>() const -> bool;
138 template <typename T>
139 auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
140 RETURN_VALUE(Type::String, s, *)
142 template auto any::cast<string>() const -> const string&;
144 template <typename T>
145 auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
146 RETURN_VALUE(Type::String, s->c_str(),)
148 template auto any::cast<const char*>() const -> const char* const;
150 template <typename T>
151 auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
152 RETURN_VALUE(Type::Map, m, *)
154 template auto any::cast<any::map>() const -> const map&;
156 template <typename T>
157 auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
158 RETURN_VALUE(Type::Vector, v, *)
160 template auto any::cast<any::vector>() const -> const vector&;
162 auto any::operator()(const any& arg) const -> any {
163 if (type == Type::Function) {
166 const any* valuePtr = this;
168 assert(valuePtr->type == Type::Thunk);
169 const any& value = (*valuePtr->t)(unthunk);
170 if (value.type == Type::Function) {
171 return (*value.f)(arg);
174 } while (valuePtr->type != Type::Unknown);
175 assert(false && "Unknown value type");
179 auto any::operator()(const as_thunk) const -> const any& {
180 assert(type == Type::Thunk);
181 return (*t)(unthunk);
184 auto any::operator()() const -> any {
185 if (type == Type::EffFunction) {
188 const any* valuePtr = this;
190 assert(valuePtr->type == Type::Thunk);
191 const any& value = (*valuePtr->t)(unthunk);
192 if (value.type == Type::EffFunction) {
196 } while (valuePtr->type != Type::Unknown);
197 assert(false && "Unknown value type");
201 any::operator long() const {
202 RETURN_VALUE(Type::Integer, i,)
205 any::operator double() const {
206 RETURN_VALUE(Type::Double, d,)
209 any::operator bool() const {
210 RETURN_VALUE(Type::Boolean, b,)
213 any::operator const string&() const {
214 RETURN_VALUE(Type::String, s, *)
217 any::operator const map&() const {
218 RETURN_VALUE(Type::Map, m, *)
221 any::operator const vector&() const {
222 RETURN_VALUE(Type::Vector, v, *)
225 auto any::extractPointer() const -> void* {
226 RETURN_VALUE(Type::Pointer, p.get(),)
229 auto any::extract_value(const any& a) -> const any& {
230 if (a.type != Type::Thunk) {
233 const any* valuePtr = &a;
235 const any& value = (*valuePtr->t)(unthunk);
236 if (value.type != Type::Thunk) {
240 } while (valuePtr->type != Type::Unknown);
241 assert(false && "Unknown value type");
245 auto any::operator[](const map_key_t& rhs) const -> const any& {
246 RETURN_VALUE(Type::Map, m->at(rhs),)
249 auto any::operator[](const vector::size_type rhs) const -> const any& {
250 RETURN_VALUE(Type::Vector, v->at(rhs),)
253 auto any::operator[](const any& rhs) const -> const any& {
254 RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
257#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
258auto operator OP(const T lhs, const any& rhs_) -> R { \
259 const any& rhs = any::extract_value(rhs_); \
260 assert(rhs.type == any::Type::K); \
261 return lhs OP P(rhs.V); \
264#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
265auto any::operator OP(const T rhs) const -> R { \
266 const any& lhs = any::extract_value(*this); \
267 assert(lhs.type == Type::K); \
268 return P(lhs.V) OP rhs; \
271auto any::operator==(const any& rhs_) const -> bool {
272 const any& lhs = extract_value(*this);
273 const any& rhs = extract_value(rhs_);
274 assert(lhs.type == rhs.type);
276 case Type::Integer: return lhs.i == rhs.i;
277 case Type::Double: return lhs.d == rhs.d;
278 case Type::Character: return lhs.c == rhs.c;
279 case Type::Boolean: return lhs.b == rhs.b;
280 case Type::String: return (*lhs.s) == (*rhs.s);
281 case Type::Pointer: return lhs.p == rhs.p;
282 default: assert(false && "Unsupported type for '==' operator");
287DEFINE_OPERATOR_RHS(Integer, long, ==, i, bool,)
288DEFINE_OPERATOR_RHS(Double, double, ==, d, bool,)
289DEFINE_OPERATOR_RHS(Character, char, ==, c, bool,)
290DEFINE_OPERATOR_RHS(Boolean, bool, ==, b, bool,)
291DEFINE_OPERATOR_RHS(String, string&, ==, s, bool, *)
292DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
294auto any::operator!=(const any& rhs_) const -> bool {
295 const any& lhs = extract_value(*this);
296 const any& rhs = extract_value(rhs_);
297 assert(lhs.type == rhs.type);
299 case Type::Integer: return lhs.i != rhs.i;
300 case Type::Double: return lhs.d != rhs.d;
301 case Type::Character: return lhs.c != rhs.c;
302 case Type::Boolean: return lhs.b != rhs.b;
303 case Type::String: return (*lhs.s) != (*rhs.s);
304 case Type::Pointer: return lhs.p != rhs.p;
305 default: assert(false && "Unsupported type for '!=' operator");
310DEFINE_OPERATOR_RHS(Integer, long, !=, i, bool,)
311DEFINE_OPERATOR_RHS(Double, double, !=, d, bool,)
312DEFINE_OPERATOR_RHS(Character, char, !=, c, bool,)
313DEFINE_OPERATOR_RHS(Boolean, bool, !=, b, bool,)
314DEFINE_OPERATOR_RHS(String, string&, !=, s, bool, *)
315DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
317auto any::operator<(const any& rhs_) const -> bool {
318 const any& lhs = extract_value(*this);
319 const any& rhs = extract_value(rhs_);
320 assert(lhs.type == rhs.type);
322 case Type::Integer: return lhs.i < rhs.i;
323 case Type::Double: return lhs.d < rhs.d;
324 case Type::Character: return lhs.c < rhs.c;
325 case Type::Boolean: return lhs.b < rhs.b;
326 case Type::String: return (*lhs.s) < (*rhs.s);
327 default: assert(false && "Unsupported type for '<' operator");
332DEFINE_OPERATOR_RHS(Integer, long, <, i, bool,)
333DEFINE_OPERATOR_RHS(Double, double, <, d, bool,)
334DEFINE_OPERATOR_RHS(Character, char, <, c, bool,)
335DEFINE_OPERATOR_RHS(Boolean, bool, <, b, bool,)
336DEFINE_OPERATOR_RHS(String, string&, <, s, bool, *)
337DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
339auto any::operator<=(const any& rhs_) const -> bool {
340 const any& lhs = extract_value(*this);
341 const any& rhs = extract_value(rhs_);
342 assert(lhs.type == rhs.type);
344 case Type::Integer: return lhs.i <= rhs.i;
345 case Type::Double: return lhs.d <= rhs.d;
346 case Type::Character: return lhs.c <= rhs.c;
347 case Type::Boolean: return lhs.b <= rhs.b;
348 case Type::String: return (*lhs.s) <= (*rhs.s);
349 default: assert(false && "Unsupported type for '<' operator");
354DEFINE_OPERATOR_RHS(Integer, long, <=, i, bool,)
355DEFINE_OPERATOR_RHS(Double, double, <=, d, bool,)
356DEFINE_OPERATOR_RHS(Character, char, <=, c, bool,)
357DEFINE_OPERATOR_RHS(Boolean, bool, <=, b, bool,)
358DEFINE_OPERATOR_RHS(String, string&, <=, s, bool, *)
359DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
361auto any::operator>(const any& rhs_) const -> bool {
362 const any& lhs = extract_value(*this);
363 const any& rhs = extract_value(rhs_);
364 assert(lhs.type == rhs.type);
366 case Type::Integer: return lhs.i > rhs.i;
367 case Type::Double: return lhs.d > rhs.d;
368 case Type::Character: return lhs.c > rhs.c;
369 case Type::Boolean: return lhs.b > rhs.b;
370 case Type::String: return (*lhs.s) > (*rhs.s);
371 default: assert(false && "Unsupported type for '>' operator");
376DEFINE_OPERATOR_RHS(Integer, long, >, i, bool,)
377DEFINE_OPERATOR_RHS(Double, double, >, d, bool,)
378DEFINE_OPERATOR_RHS(Character, char, >, c, bool,)
379DEFINE_OPERATOR_RHS(Boolean, bool, >, b, bool,)
380DEFINE_OPERATOR_RHS(String, string&, >, s, bool, *)
381DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
383auto any::operator>=(const any& rhs_) const -> bool {
384 const any& lhs = extract_value(*this);
385 const any& rhs = extract_value(rhs_);
386 assert(lhs.type == rhs.type);
388 case Type::Integer: return lhs.i >= rhs.i;
389 case Type::Double: return lhs.d >= rhs.d;
390 case Type::Character: return lhs.c >= rhs.c;
391 case Type::Boolean: return lhs.b >= rhs.b;
392 case Type::String: return (*lhs.s) >= (*rhs.s);
393 default: assert(false && "Unsupported type for '>' operator");
398DEFINE_OPERATOR_RHS(Integer, long, >=, i, bool,)
399DEFINE_OPERATOR_RHS(Double, double, >=, d, bool,)
400DEFINE_OPERATOR_RHS(Character, char, >=, c, bool,)
401DEFINE_OPERATOR_RHS(Boolean, bool, >=, b, bool,)
402DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
403DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
405auto any::operator+(const any& rhs_) const -> any {
406 const any& lhs = extract_value(*this);
407 const any& rhs = extract_value(rhs_);
408 assert(lhs.type == rhs.type);
410 case Type::Integer: return lhs.i + rhs.i;
411 case Type::Double: return lhs.d + rhs.d;
412 case Type::Character: return any(char(lhs.c + rhs.c));
413 case Type::String: return (*lhs.s) + (*rhs.s);
414 default: assert(false && "Unsupported type for '+' operator");
419DEFINE_OPERATOR_RHS(Integer, long, +, i, long,)
420DEFINE_OPERATOR_RHS(Double, double, +, d, double,)
421DEFINE_OPERATOR_RHS(Character, char, +, c, char,)
422DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
423DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
425auto any::operator-(const any& rhs_) const -> any {
426 const any& lhs = extract_value(*this);
427 const any& rhs = extract_value(rhs_);
428 assert(lhs.type == rhs.type);
430 case Type::Integer: return lhs.i - rhs.i;
431 case Type::Double: return lhs.d - rhs.d;
432 case Type::Character: return any(char(lhs.c - rhs.c));
433 default: assert(false && "Unsupported type for '-' binary operator");
438DEFINE_OPERATOR_RHS(Integer, long, -, i, long,)
439DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
440DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
442auto any::operator*(const any& rhs_) const -> any {
443 const any& lhs = extract_value(*this);
444 const any& rhs = extract_value(rhs_);
445 assert(lhs.type == rhs.type);
447 case Type::Integer: return lhs.i * rhs.i;
448 case Type::Double: return lhs.d * rhs.d;
449 default: assert(false && "Unsupported type for '*' operator");
454DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
455DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
457auto any::operator/(const any& rhs_) const -> any {
458 const any& lhs = extract_value(*this);
459 const any& rhs = extract_value(rhs_);
460 assert(lhs.type == rhs.type);
462 case Type::Integer: return lhs.i / rhs.i;
463 case Type::Double: return lhs.d / rhs.d;
464 default: assert(false && "Unsupported type for '/' operator");
469DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
470DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
472auto any::operator%(const any& rhs_) const -> any {
473 const any& lhs = extract_value(*this);
474 const any& rhs = extract_value(rhs_);
475 assert(lhs.type == rhs.type);
477 case Type::Integer: return lhs.i % rhs.i;
478 default: assert(false && "Unsupported type for '%' operator");
483DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
485auto any::operator-() const -> any {
486 const any& lhs = any::extract_value(*this);
488 case Type::Integer: return (- lhs.i);
489 case Type::Double: return (- lhs.d);
490 default: assert(false && "Unsupported type for unary '-' operator");
495DEFINE_OPERATOR_LHS(Integer, long, ==, i, bool,)
496DEFINE_OPERATOR_LHS(Integer, long, !=, i, bool,)
497DEFINE_OPERATOR_LHS(Integer, long, <, i, bool,)
498DEFINE_OPERATOR_LHS(Integer, long, <=, i, bool,)
499DEFINE_OPERATOR_LHS(Integer, long, >, i, bool,)
500DEFINE_OPERATOR_LHS(Integer, long, >=, i, bool,)
502DEFINE_OPERATOR_LHS(Double, double, ==, d, bool,)
503DEFINE_OPERATOR_LHS(Double, double, !=, d, bool,)
504DEFINE_OPERATOR_LHS(Double, double, <, d, bool,)
505DEFINE_OPERATOR_LHS(Double, double, <=, d, bool,)
506DEFINE_OPERATOR_LHS(Double, double, >, d, bool,)
507DEFINE_OPERATOR_LHS(Double, double, >=, d, bool,)
509DEFINE_OPERATOR_LHS(Character, char, ==, c, bool,)
510DEFINE_OPERATOR_LHS(Character, char, !=, c, bool,)
511DEFINE_OPERATOR_LHS(Character, char, <, c, bool,)
512DEFINE_OPERATOR_LHS(Character, char, <=, c, bool,)
513DEFINE_OPERATOR_LHS(Character, char, >, c, bool,)
514DEFINE_OPERATOR_LHS(Character, char, >=, c, bool,)
516DEFINE_OPERATOR_LHS(Boolean, bool, ==, b, bool,)
517DEFINE_OPERATOR_LHS(Boolean, bool, !=, b, bool,)
518DEFINE_OPERATOR_LHS(Boolean, bool, <, b, bool,)
519DEFINE_OPERATOR_LHS(Boolean, bool, <=, b, bool,)
520DEFINE_OPERATOR_LHS(Boolean, bool, >, b, bool,)
521DEFINE_OPERATOR_LHS(Boolean, bool, >=, b, bool,)
523DEFINE_OPERATOR_LHS(String, string&, ==, s, bool, *)
524DEFINE_OPERATOR_LHS(String, string&, !=, s, bool, *)
525DEFINE_OPERATOR_LHS(String, string&, <, s, bool, *)
526DEFINE_OPERATOR_LHS(String, string&, <=, s, bool, *)
527DEFINE_OPERATOR_LHS(String, string&, >, s, bool, *)
528DEFINE_OPERATOR_LHS(String, string&, >=, s, bool, *)
530DEFINE_OPERATOR_LHS(String, char* const, ==, s, bool, *)
531DEFINE_OPERATOR_LHS(String, char* const, !=, s, bool, *)
532DEFINE_OPERATOR_LHS(String, char* const, <, s, bool, *)
533DEFINE_OPERATOR_LHS(String, char* const, <=, s, bool, *)
534DEFINE_OPERATOR_LHS(String, char* const, >, s, bool, *)
535DEFINE_OPERATOR_LHS(String, char* const, >=, s, bool, *)
537DEFINE_OPERATOR_LHS(Integer, long, +, i, long,)
538DEFINE_OPERATOR_LHS(Integer, long, -, i, long,)
539DEFINE_OPERATOR_LHS(Integer, long, *, i, long,)
540DEFINE_OPERATOR_LHS(Integer, long, /, i, long,)
541DEFINE_OPERATOR_LHS(Integer, long, %, i, long,)
543DEFINE_OPERATOR_LHS(Double, double, +, d, double,)
544DEFINE_OPERATOR_LHS(Double, double, -, d, double,)
545DEFINE_OPERATOR_LHS(Double, double, *, d, double,)
546DEFINE_OPERATOR_LHS(Double, double, /, d, double,)
548DEFINE_OPERATOR_LHS(Character, char, +, i, char,)
549DEFINE_OPERATOR_LHS(Character, char, -, i, char,)
551DEFINE_OPERATOR_LHS(String, string&, +, s, string, *)
552DEFINE_OPERATOR_LHS(String, char* const, +, s, string, *)
555} // 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