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"
19any::any(const any& val) : type(val.type) {
21 case Type::Integer: i = val.i; break;
22 case Type::Double: d = val.d; break;
23 case Type::Character: c = val.c; break;
24 case Type::Boolean: b = val.b; break;
25 case Type::String: new (&s) shared<string> (val.s); break;
26 case Type::Map: new (&m) shared<map> (val.m); break;
27 case Type::Vector: new (&v) shared<vector> (val.v); break;
28 case Type::Function: new (&f) shared<fn> (val.f); break;
29 case Type::EffFunction: new (&e) shared<eff_fn> (val.e); break;
30 case Type::Thunk: new (&t) shared<thunk> (val.t); break;
31 case Type::Pointer: new (&p) shared<void> (val.p); break;
33 default: assert(false && "Unsupported type in copy ctor");
37void any::swap(any&& val) const {
40 case Type::Integer: i = val.i; break;
41 case Type::Double: d = val.d; break;
42 case Type::Character: c = val.c; break;
43 case Type::Boolean: b = val.b; break;
44 case Type::String: new (&s) shared<string> (std::move(val.s)); break;
45 case Type::Map: new (&m) shared<map> (std::move(val.m)); break;
46 case Type::Vector: new (&v) shared<vector> (std::move(val.v)); break;
47 case Type::Function: new (&f) shared<fn> (std::move(val.f)); break;
48 case Type::EffFunction: new (&e) shared<eff_fn> (std::move(val.e)); break;
49 case Type::Thunk: new (&t) shared<thunk> (std::move(val.t)); break;
50 case Type::Pointer: new (&p) shared<void> (std::move(val.p)); break;
52 default: assert(false && "Unsupported type in move ctor");
57 // std::cout << "destroy" << std::endl;
59 case Type::Integer: ; break;
60 case Type::Double: ; break;
61 case Type::Character: ; break;
62 case Type::Boolean: ; break;
63 case Type::String: s.~shared<string>(); break;
64 case Type::Map: m.~shared<map>(); break;
65 case Type::Vector: v.~shared<vector>(); break;
66 case Type::Function: f.~shared<fn>(); break;
67 case Type::EffFunction: e.~shared<eff_fn>(); break;
68 case Type::Thunk: t.~shared<thunk>(); break;
69 case Type::Pointer: p.~shared<void>(); break;
71 default: assert(false && "Unsupported type in destructor");
75 #define RETURN_VALUE(TYPE, VAL, FN) \
79 const any* valuePtr = this; \
81 assert(valuePtr->type == Type::Thunk); \
82 const any& value = (*valuePtr->t)(unthunk); \
83 if (value.type == TYPE) { \
84 return FN(value.VAL); \
87 } while (valuePtr->type != Type::Unknown); \
91 auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
92 RETURN_VALUE(Type::Integer, i,)
94 template auto any::cast<long>() const -> long;
97 auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
98 RETURN_VALUE(Type::Double, d,)
100 template auto any::cast<double>() const -> double;
102 template <typename T>
103 auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
104 RETURN_VALUE(Type::Character, c,)
106 template auto any::cast<char>() const -> char;
108 template <typename T>
109 auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
110 RETURN_VALUE(Type::Boolean, b,)
112 template auto any::cast<bool>() const -> bool;
114 template <typename T>
115 auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
116 RETURN_VALUE(Type::String, s, *)
118 template auto any::cast<string>() const -> const string&;
120 template <typename T>
121 auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
122 RETURN_VALUE(Type::String, s->c_str(),)
124 template auto any::cast<const char*>() const -> const char* const;
126 template <typename T>
127 auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
128 RETURN_VALUE(Type::Map, m, *)
130 template auto any::cast<any::map>() const -> const map&;
132 template <typename T>
133 auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
134 RETURN_VALUE(Type::Vector, v, *)
136 template auto any::cast<any::vector>() const -> const vector&;
139 auto any::operator()(const any arg) const -> any {
140 if (type == Type::Function) {
143 const any* valuePtr = this;
145 assert(valuePtr->type == Type::Thunk);
146 const any& value = (*valuePtr->t)(unthunk);
147 if (value.type == Type::Function) {
148 return (*value.f)(arg);
151 } while (valuePtr->type != Type::Unknown);
155 auto any::operator()(const as_thunk) const -> const any& {
156 assert(type == Type::Thunk);
157 return (*t)(unthunk);
160 auto any::operator()() const -> any {
161 if (type == Type::EffFunction) {
164 const any* valuePtr = this;
166 assert(valuePtr->type == Type::Thunk);
167 const any& value = (*valuePtr->t)(unthunk);
168 if (value.type == Type::EffFunction) {
172 } while (valuePtr->type != Type::Unknown);
176 any::operator long() const {
177 RETURN_VALUE(Type::Integer, i,)
180 any::operator double() const {
181 RETURN_VALUE(Type::Double, d,)
184 any::operator bool() const {
185 RETURN_VALUE(Type::Boolean, b,)
188 any::operator const string&() const {
189 RETURN_VALUE(Type::String, s, *)
192 any::operator const map&() const {
193 RETURN_VALUE(Type::Map, m, *)
196 any::operator const vector&() const {
197 RETURN_VALUE(Type::Vector, v, *)
200 auto any::extractPointer() const -> const void* {
201 RETURN_VALUE(Type::Pointer, p.get(),)
204 auto any::extract_value(const any& a) -> const any& {
205 if (a.type != Type::Thunk) {
208 const any* valuePtr = &a;
210 const any& value = (*valuePtr->t)(unthunk);
211 if (value.type != Type::Thunk) {
218 auto any::operator[](const char rhs[]) const -> const any& {
219 RETURN_VALUE(Type::Map, m->at(rhs),)
222 auto any::operator[](const vector::size_type rhs) const -> const any& {
223 RETURN_VALUE(Type::Vector, v->at(rhs),)
226 auto any::operator[](const any& rhs) const -> const any& {
227 RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
230#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
231auto operator OP(const T lhs, const any& rhs_) -> R { \
232 const any& rhs = any::extract_value(rhs_); \
233 assert(rhs.type == any::Type::K); \
234 return lhs OP P(rhs.V); \
237#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
238auto any::operator OP(const T rhs) const -> R { \
239 const any& lhs = any::extract_value(*this); \
240 assert(lhs.type == Type::K); \
241 return P(lhs.V) OP rhs; \
244auto any::operator==(const any& rhs_) const -> bool {
245 const any& lhs = extract_value(*this);
246 const any& rhs = extract_value(rhs_);
247 assert(lhs.type == rhs.type);
249 case Type::Integer: return lhs.i == rhs.i;
250 case Type::Double: return lhs.d == rhs.d;
251 case Type::Character: return lhs.c == rhs.c;
252 case Type::Boolean: return lhs.b == rhs.b;
253 case Type::String: return (*lhs.s) == (*rhs.s);
254 case Type::Pointer: return lhs.p == rhs.p;
255 default: assert(false && "Unsupported type for '==' operator");
260DEFINE_OPERATOR_RHS(Integer, long, ==, i, bool,)
261DEFINE_OPERATOR_RHS(Double, double, ==, d, bool,)
262DEFINE_OPERATOR_RHS(Character, char, ==, c, bool,)
263DEFINE_OPERATOR_RHS(Boolean, bool, ==, b, bool,)
264DEFINE_OPERATOR_RHS(String, string&, ==, s, bool, *)
265DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
267auto any::operator!=(const any& rhs_) const -> bool {
268 const any& lhs = extract_value(*this);
269 const any& rhs = extract_value(rhs_);
270 assert(lhs.type == rhs.type);
272 case Type::Integer: return lhs.i != rhs.i;
273 case Type::Double: return lhs.d != rhs.d;
274 case Type::Character: return lhs.c != rhs.c;
275 case Type::Boolean: return lhs.b != rhs.b;
276 case Type::String: return (*lhs.s) != (*rhs.s);
277 case Type::Pointer: return lhs.p != rhs.p;
278 default: assert(false && "Unsupported type for '!=' operator");
283DEFINE_OPERATOR_RHS(Integer, long, !=, i, bool,)
284DEFINE_OPERATOR_RHS(Double, double, !=, d, bool,)
285DEFINE_OPERATOR_RHS(Character, char, !=, c, bool,)
286DEFINE_OPERATOR_RHS(Boolean, bool, !=, b, bool,)
287DEFINE_OPERATOR_RHS(String, string&, !=, s, bool, *)
288DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
290auto any::operator<(const any& rhs_) const -> bool {
291 const any& lhs = extract_value(*this);
292 const any& rhs = extract_value(rhs_);
293 assert(lhs.type == rhs.type);
295 case Type::Integer: return lhs.i < rhs.i;
296 case Type::Double: return lhs.d < rhs.d;
297 case Type::Character: return lhs.c < rhs.c;
298 case Type::Boolean: return lhs.b < rhs.b;
299 case Type::String: return (*lhs.s) < (*rhs.s);
300 default: assert(false && "Unsupported type for '<' operator");
305DEFINE_OPERATOR_RHS(Integer, long, <, i, bool,)
306DEFINE_OPERATOR_RHS(Double, double, <, d, bool,)
307DEFINE_OPERATOR_RHS(Character, char, <, c, bool,)
308DEFINE_OPERATOR_RHS(Boolean, bool, <, b, bool,)
309DEFINE_OPERATOR_RHS(String, string&, <, s, bool, *)
310DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
312auto any::operator<=(const any& rhs_) const -> bool {
313 const any& lhs = extract_value(*this);
314 const any& rhs = extract_value(rhs_);
315 assert(lhs.type == rhs.type);
317 case Type::Integer: return lhs.i <= rhs.i;
318 case Type::Double: return lhs.d <= rhs.d;
319 case Type::Character: return lhs.c <= rhs.c;
320 case Type::Boolean: return lhs.b <= rhs.b;
321 case Type::String: return (*lhs.s) <= (*rhs.s);
322 default: assert(false && "Unsupported type for '<' operator");
327DEFINE_OPERATOR_RHS(Integer, long, <=, i, bool,)
328DEFINE_OPERATOR_RHS(Double, double, <=, d, bool,)
329DEFINE_OPERATOR_RHS(Character, char, <=, c, bool,)
330DEFINE_OPERATOR_RHS(Boolean, bool, <=, b, bool,)
331DEFINE_OPERATOR_RHS(String, string&, <=, s, bool, *)
332DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
334auto any::operator>(const any& rhs_) const -> bool {
335 const any& lhs = extract_value(*this);
336 const any& rhs = extract_value(rhs_);
337 assert(lhs.type == rhs.type);
339 case Type::Integer: return lhs.i > rhs.i;
340 case Type::Double: return lhs.d > rhs.d;
341 case Type::Character: return lhs.c > rhs.c;
342 case Type::Boolean: return lhs.b > rhs.b;
343 case Type::String: return (*lhs.s) > (*rhs.s);
344 default: assert(false && "Unsupported type for '>' operator");
349DEFINE_OPERATOR_RHS(Integer, long, >, i, bool,)
350DEFINE_OPERATOR_RHS(Double, double, >, d, bool,)
351DEFINE_OPERATOR_RHS(Character, char, >, c, bool,)
352DEFINE_OPERATOR_RHS(Boolean, bool, >, b, bool,)
353DEFINE_OPERATOR_RHS(String, string&, >, s, bool, *)
354DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
356auto any::operator>=(const any& rhs_) const -> bool {
357 const any& lhs = extract_value(*this);
358 const any& rhs = extract_value(rhs_);
359 assert(lhs.type == rhs.type);
361 case Type::Integer: return lhs.i >= rhs.i;
362 case Type::Double: return lhs.d >= rhs.d;
363 case Type::Character: return lhs.c >= rhs.c;
364 case Type::Boolean: return lhs.b >= rhs.b;
365 case Type::String: return (*lhs.s) >= (*rhs.s);
366 default: assert(false && "Unsupported type for '>' operator");
371DEFINE_OPERATOR_RHS(Integer, long, >=, i, bool,)
372DEFINE_OPERATOR_RHS(Double, double, >=, d, bool,)
373DEFINE_OPERATOR_RHS(Character, char, >=, c, bool,)
374DEFINE_OPERATOR_RHS(Boolean, bool, >=, b, bool,)
375DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
376DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
378auto any::operator+(const any& rhs_) const -> any {
379 const any& lhs = extract_value(*this);
380 const any& rhs = extract_value(rhs_);
381 assert(lhs.type == rhs.type);
383 case Type::Integer: return lhs.i + rhs.i;
384 case Type::Double: return lhs.d + rhs.d;
385 case Type::Character: return any(char(lhs.c + rhs.c));
386 case Type::String: return (*lhs.s) + (*rhs.s);
387 default: assert(false && "Unsupported type for '+' operator");
392DEFINE_OPERATOR_RHS(Integer, long, +, i, long,)
393DEFINE_OPERATOR_RHS(Double, double, +, d, double,)
394DEFINE_OPERATOR_RHS(Character, char, +, c, char,)
395DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
396DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
398auto any::operator-(const any& rhs_) const -> any {
399 const any& lhs = extract_value(*this);
400 const any& rhs = extract_value(rhs_);
401 assert(lhs.type == rhs.type);
403 case Type::Integer: return lhs.i - rhs.i;
404 case Type::Double: return lhs.d - rhs.d;
405 case Type::Character: return any(char(lhs.c - rhs.c));
406 default: assert(false && "Unsupported type for '-' binary operator");
411DEFINE_OPERATOR_RHS(Integer, long, -, i, long,)
412DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
413DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
415auto any::operator*(const any& rhs_) const -> any {
416 const any& lhs = extract_value(*this);
417 const any& rhs = extract_value(rhs_);
418 assert(lhs.type == rhs.type);
420 case Type::Integer: return lhs.i * rhs.i;
421 case Type::Double: return lhs.d * rhs.d;
422 default: assert(false && "Unsupported type for '*' operator");
427DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
428DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
430auto any::operator/(const any& rhs_) const -> any {
431 const any& lhs = extract_value(*this);
432 const any& rhs = extract_value(rhs_);
433 assert(lhs.type == rhs.type);
435 case Type::Integer: return lhs.i / rhs.i;
436 case Type::Double: return lhs.d / rhs.d;
437 default: assert(false && "Unsupported type for '/' operator");
442DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
443DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
445auto any::operator%(const any& rhs_) const -> any {
446 const any& lhs = extract_value(*this);
447 const any& rhs = extract_value(rhs_);
448 assert(lhs.type == rhs.type);
450 case Type::Integer: return lhs.i % rhs.i;
451 default: assert(false && "Unsupported type for '%' operator");
456DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
458auto any::operator-() const -> any {
459 const any& lhs = any::extract_value(*this);
461 case Type::Integer: return (- lhs.i);
462 case Type::Double: return (- lhs.d);
463 default: assert(false && "Unsupported type for unary '-' operator");
468DEFINE_OPERATOR_LHS(Integer, long, ==, i, bool,)
469DEFINE_OPERATOR_LHS(Integer, long, !=, i, bool,)
470DEFINE_OPERATOR_LHS(Integer, long, <, i, bool,)
471DEFINE_OPERATOR_LHS(Integer, long, <=, i, bool,)
472DEFINE_OPERATOR_LHS(Integer, long, >, i, bool,)
473DEFINE_OPERATOR_LHS(Integer, long, >=, i, bool,)
475DEFINE_OPERATOR_LHS(Double, double, ==, d, bool,)
476DEFINE_OPERATOR_LHS(Double, double, !=, d, bool,)
477DEFINE_OPERATOR_LHS(Double, double, <, d, bool,)
478DEFINE_OPERATOR_LHS(Double, double, <=, d, bool,)
479DEFINE_OPERATOR_LHS(Double, double, >, d, bool,)
480DEFINE_OPERATOR_LHS(Double, double, >=, d, bool,)
482DEFINE_OPERATOR_LHS(Character, char, ==, c, bool,)
483DEFINE_OPERATOR_LHS(Character, char, !=, c, bool,)
484DEFINE_OPERATOR_LHS(Character, char, <, c, bool,)
485DEFINE_OPERATOR_LHS(Character, char, <=, c, bool,)
486DEFINE_OPERATOR_LHS(Character, char, >, c, bool,)
487DEFINE_OPERATOR_LHS(Character, char, >=, c, bool,)
489DEFINE_OPERATOR_LHS(Boolean, bool, ==, b, bool,)
490DEFINE_OPERATOR_LHS(Boolean, bool, !=, b, bool,)
491DEFINE_OPERATOR_LHS(Boolean, bool, <, b, bool,)
492DEFINE_OPERATOR_LHS(Boolean, bool, <=, b, bool,)
493DEFINE_OPERATOR_LHS(Boolean, bool, >, b, bool,)
494DEFINE_OPERATOR_LHS(Boolean, bool, >=, b, bool,)
496DEFINE_OPERATOR_LHS(String, string&, ==, s, bool, *)
497DEFINE_OPERATOR_LHS(String, string&, !=, s, bool, *)
498DEFINE_OPERATOR_LHS(String, string&, <, s, bool, *)
499DEFINE_OPERATOR_LHS(String, string&, <=, s, bool, *)
500DEFINE_OPERATOR_LHS(String, string&, >, s, bool, *)
501DEFINE_OPERATOR_LHS(String, string&, >=, s, bool, *)
503DEFINE_OPERATOR_LHS(String, char* const, ==, s, bool, *)
504DEFINE_OPERATOR_LHS(String, char* const, !=, s, bool, *)
505DEFINE_OPERATOR_LHS(String, char* const, <, s, bool, *)
506DEFINE_OPERATOR_LHS(String, char* const, <=, s, bool, *)
507DEFINE_OPERATOR_LHS(String, char* const, >, s, bool, *)
508DEFINE_OPERATOR_LHS(String, char* const, >=, s, bool, *)
510DEFINE_OPERATOR_LHS(Integer, long, +, i, long,)
511DEFINE_OPERATOR_LHS(Integer, long, -, i, long,)
512DEFINE_OPERATOR_LHS(Integer, long, *, i, long,)
513DEFINE_OPERATOR_LHS(Integer, long, /, i, long,)
514DEFINE_OPERATOR_LHS(Integer, long, %, i, long,)
516DEFINE_OPERATOR_LHS(Double, double, +, d, double,)
517DEFINE_OPERATOR_LHS(Double, double, -, d, double,)
518DEFINE_OPERATOR_LHS(Double, double, *, d, double,)
519DEFINE_OPERATOR_LHS(Double, double, /, d, double,)
521DEFINE_OPERATOR_LHS(Character, char, +, i, char,)
522DEFINE_OPERATOR_LHS(Character, char, -, i, char,)
524DEFINE_OPERATOR_LHS(String, string&, +, s, string, *)
525DEFINE_OPERATOR_LHS(String, char* const, +, s, string, *)
528} // 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