git.iko.soy/rowtype-yoga/purescript-native
on 0711464 help sign in
347 lines 12 kB history raw
1///////////////////////////////////////////////////////////////////////////////
2//
3// Module : purescript.hh
4// Copyright : (c) Andy Arvanitis 2015
5// License : MIT
6//
7// Maintainer : Andy Arvanitis <andy.arvanitis@gmail.com>
8// Stability : experimental
9// Portability :
10//
11// Basic types and functions to support purescript-to-C++1x rendering
12//
13///////////////////////////////////////////////////////////////////////////////
14//
15#ifndef PureScript_HH
16#define PureScript_HH
18// Standard includes
20#if defined(DEBUG)
21 #include <cassert>
22#else
23 #define NDEBUG
24 #undef assert
25 #define assert(x)
26#endif
28#include <memory>
29#include <functional>
30#include <string>
31#include <vector>
32#include <unordered_map>
33#include <stdexcept>
34#include "map_key.hh"
36namespace PureScript {
38using string = std::string;
39using runtime_error = std::runtime_error;
40using nullptr_t = std::nullptr_t;
42const bool undefined = false;
44// A variant data class designed to provide some features of dynamic typing.
45//
46class any {
48 public:
49 enum class Type {
50 Unknown,
51 Integer,
52 Double,
53 Character,
54 Boolean,
55 String,
56 Map,
57 Vector,
58 Function,
59 Closure,
60 EffFunction,
61 Thunk,
62 Pointer
63 };
65 mutable Type type = Type::Unknown;
67 struct as_thunk {
68 };
69 static constexpr as_thunk unthunk = as_thunk{};
71 using map = std::unordered_map<const map_key_t, const any, map_key_t::hasher, map_key_t::equal>;
72 using vector = std::vector<any>;
73 using fn = auto (*)(const any&) -> any;
74 using closure = std::function<any(const any&)>;
75 using eff_fn = std::function<any()>;
76 using thunk = auto (*)(const as_thunk) -> const any&;
78 template <typename T>
79 using shared = std::shared_ptr<T>;
81 template <typename T, typename... Args>
82 inline static auto make_shared(Args&&... args) -> decltype(std::make_shared<T>(std::forward<Args>(args)...)) {
83 return std::make_shared<T>(std::forward<Args>(args)...);
84 }
86 private:
87 union {
88 mutable long i;
89 mutable double d;
90 mutable char c;
91 mutable bool b;
92 mutable shared<string> s;
93 mutable shared<map> m;
94 mutable shared<vector> v;
95 mutable fn f;
96 mutable shared<closure> l;
97 mutable shared<eff_fn> e;
98 mutable thunk t;
99 mutable shared<void> p;
100 };
102 public:
104 any(const long val) : type(Type::Integer), i(val) {}
105 any(const int val) : type(Type::Integer), i(val) {}
106 any(const unsigned int val) : type(Type::Integer), i(val) {}
107 any(const double val) : type(Type::Double), d(val) {}
108 any(const char val) : type(Type::Character), c(val) {}
110 template <typename T, typename = typename std::enable_if<std::is_same<bool,T>::value>::type>
111 any(const T val) : type(Type::Boolean), b(val) {}
113 any(const string& val) : type(Type::String), s(make_shared<string>(val)) {}
114 any(string&& val) noexcept : type(Type::String), s(make_shared<string>(std::move(val))) {}
115 any(const char val[]) : type(Type::String), s(make_shared<string>(val)) {}
117 any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
118 any(map&& val) noexcept : type(Type::Map), m(make_shared<map>(std::move(val))) {}
120 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
121 any(vector&& val) noexcept : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
123 template <typename T>
124 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0)
125 : type(Type::Function), f(val) {}
127 template <typename T, typename = typename std::enable_if<!std::is_same<any,T>::value &&
128 !std::is_convertible<T,fn>::value>::type>
129 any(const T& val, typename std::enable_if<std::is_assignable<closure,T>::value>::type* = 0)
130 : type(Type::Closure), l(make_shared<closure>(val)) {}
132 template <typename T>
133 any(const T& val, typename std::enable_if<std::is_assignable<eff_fn,T>::value>::type* = 0)
134 : type(Type::EffFunction), e(make_shared<eff_fn>(val)) {}
136 template <typename T>
137 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0)
138 : type(Type::Thunk), t(val) {}
140 template <typename T>
141 any(const T& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0)
142 : type(Type::Pointer), p(val) {}
144 template <typename T>
145 any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0) noexcept
146 : type(Type::Pointer), p(std::move(val)) {}
148 any(std::nullptr_t) : type(Type::Pointer), p(nullptr) {}
150 any(const any&);
151 any(any&&) noexcept;
153 auto operator=(const any&) -> any&;
154 auto operator=(any&) noexcept -> any&;
155 auto operator=(any&&) noexcept -> any&;
157 any() = delete;
158 ~any();
160 template <typename T>
161 auto cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type;
163 template <typename T>
164 auto cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type;
166 template <typename T>
167 auto cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type;
169 template <typename T>
170 auto cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type;
172 template <typename T>
173 auto cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type;
175 template <typename T>
176 auto cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type;
178 template <typename T>
179 auto cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type;
181 template <typename T>
182 auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type;
184 template <typename T>
185 auto cast() const -> typename std::enable_if<std::is_assignable<shared<void>,T>::value, typename T::element_type*>::type {
186 return static_cast<typename T::element_type*>(extractPointer());
187 }
189 auto operator()(const any&) const -> any;
191 auto operator()(const as_thunk) const -> const any&;
193 auto operator()() const -> any;
195 operator long() const;
196 operator double() const;
197 operator bool() const;
199 operator const string&() const;
200 operator const map&() const;
201 operator const vector&() const;
203 auto operator[](const map_key_t&) const -> const any&;
204 auto operator[](const vector::size_type) const -> const any&;
205 auto operator[](const any&) const -> const any&;
207 auto extractPointer() const -> void*;
209 static auto extract_value(const any&) -> const any&;
211 auto operator==(const any&) const -> bool;
212 auto operator==(const long) const -> bool;
213 auto operator==(const double) const -> bool;
214 auto operator==(const char) const -> bool;
215 auto operator==(const bool) const -> bool;
216 auto operator==(const string&) const -> bool;
217 auto operator==(const char * const) const -> bool;
219 auto operator!=(const any&) const -> bool;
220 auto operator!=(const long) const -> bool;
221 auto operator!=(const double) const -> bool;
222 auto operator!=(const char) const -> bool;
223 auto operator!=(const bool) const -> bool;
224 auto operator!=(const string&) const -> bool;
225 auto operator!=(const char * const) const -> bool;
227 auto operator<(const any&) const -> bool;
228 auto operator<(const long) const -> bool;
229 auto operator<(const double) const -> bool;
230 auto operator<(const char) const -> bool;
231 auto operator<(const bool) const -> bool;
232 auto operator<(const string&) const -> bool;
233 auto operator<(const char * const) const -> bool;
235 auto operator<=(const any&) const -> bool;
236 auto operator<=(const long) const -> bool;
237 auto operator<=(const double) const -> bool;
238 auto operator<=(const char) const -> bool;
239 auto operator<=(const bool) const -> bool;
240 auto operator<=(const string&) const -> bool;
241 auto operator<=(const char * const) const -> bool;
243 auto operator>(const any&) const -> bool;
244 auto operator>(const long) const -> bool;
245 auto operator>(const double) const -> bool;
246 auto operator>(const char) const -> bool;
247 auto operator>(const bool) const -> bool;
248 auto operator>(const string&) const -> bool;
249 auto operator>(const char * const) const -> bool;
251 auto operator>=(const any&) const -> bool;
252 auto operator>=(const long) const -> bool;
253 auto operator>=(const double) const -> bool;
254 auto operator>=(const char) const -> bool;
255 auto operator>=(const bool) const -> bool;
256 auto operator>=(const string&) const -> bool;
257 auto operator>=(const char * const) const -> bool;
259 auto operator+(const any&) const -> any;
260 auto operator+(const long) const -> long;
261 auto operator+(const double) const -> double;
262 auto operator+(const char) const -> char;
263 auto operator+(const string&) const -> string;
264 auto operator+(const char * const) const -> string;
266 auto operator-(const any&) const -> any;
267 auto operator-(const long) const -> long;
268 auto operator-(const double) const -> double;
269 auto operator-(const char) const -> char;
271 auto operator*(const any&) const -> any;
272 auto operator*(const long) const -> long;
273 auto operator*(const double) const -> double;
275 auto operator/(const any&) const -> any;
276 auto operator/(const long) const -> long;
277 auto operator/(const double) const -> double;
279 auto operator%(const any&) const -> any;
280 auto operator%(const long) const -> long;
282 auto operator-() const -> any; // unary negate
284 friend auto operator==(const long, const any&) -> bool;
285 friend auto operator!=(const long, const any&) -> bool;
286 friend auto operator< (const long, const any&) -> bool;
287 friend auto operator<=(const long, const any&) -> bool;
288 friend auto operator> (const long, const any&) -> bool;
289 friend auto operator>=(const long, const any&) -> bool;
291 friend auto operator==(const double, const any&) -> bool;
292 friend auto operator!=(const double, const any&) -> bool;
293 friend auto operator< (const double, const any&) -> bool;
294 friend auto operator<=(const double, const any&) -> bool;
295 friend auto operator> (const double, const any&) -> bool;
296 friend auto operator>=(const double, const any&) -> bool;
298 friend auto operator==(const char, const any&) -> bool;
299 friend auto operator!=(const char, const any&) -> bool;
300 friend auto operator< (const char, const any&) -> bool;
301 friend auto operator<=(const char, const any&) -> bool;
302 friend auto operator> (const char, const any&) -> bool;
303 friend auto operator>=(const char, const any&) -> bool;
305 friend auto operator==(const bool, const any&) -> bool;
306 friend auto operator!=(const bool, const any&) -> bool;
307 friend auto operator< (const bool, const any&) -> bool;
308 friend auto operator<=(const bool, const any&) -> bool;
309 friend auto operator> (const bool, const any&) -> bool;
310 friend auto operator>=(const bool, const any&) -> bool;
312 friend auto operator==(const string&, const any&) -> bool;
313 friend auto operator!=(const string&, const any&) -> bool;
314 friend auto operator< (const string&, const any&) -> bool;
315 friend auto operator<=(const string&, const any&) -> bool;
316 friend auto operator> (const string&, const any&) -> bool;
317 friend auto operator>=(const string&, const any&) -> bool;
319 friend auto operator==(const char* const, const any&) -> bool;
320 friend auto operator!=(const char* const, const any&) -> bool;
321 friend auto operator< (const char* const, const any&) -> bool;
322 friend auto operator<=(const char* const, const any&) -> bool;
323 friend auto operator> (const char* const, const any&) -> bool;
324 friend auto operator>=(const char* const, const any&) -> bool;
326 friend auto operator+(const long, const any&) -> long;
327 friend auto operator-(const long, const any&) -> long;
328 friend auto operator*(const long, const any&) -> long;
329 friend auto operator/(const long, const any&) -> long;
330 friend auto operator%(const long, const any&) -> long;
332 friend auto operator+(const double, const any&) -> double;
333 friend auto operator-(const double, const any&) -> double;
334 friend auto operator*(const double, const any&) -> double;
335 friend auto operator/(const double, const any&) -> double;
337 friend auto operator+(const char, const any&) -> char;
338 friend auto operator-(const char, const any&) -> char;
340 friend auto operator+(const string&, const any&) -> string;
341 friend auto operator+(const char* const, const any&) -> string;
343};
345} // namespace PureScript
347#endif // PureScript_HH