@@ -30,7 +30,6 @@
31#include <functional>
31#include <functional>
32#include <string>
32#include <string>
34#include <array>
33#include <array>
35#include <deque>
34#include <deque>
36#include <utility>
35#include <utility>
@@ -43,6 +42,18 @@ namespace PureScript {
43using cstring = const char *;
42using cstring = const char *;
44using std::nullptr_t;
43using std::nullptr_t;
45+struct symbol_generator_anchor {};
46+using symbol_t = const symbol_generator_anchor *;
49+struct symbol_generator {
50+ constexpr static symbol_generator_anchor anchor = symbol_generator_anchor{};
53+constexpr symbol_generator_anchor symbol_generator<T>::anchor;
55+#define SYMBOL(S) &symbol_generator<symbol::S>::anchor
46// Workaround for missing C++11 version in gcc
57// Workaround for missing C++11 version in gcc
47class runtime_error : public std::runtime_error {
58class runtime_error : public std::runtime_error {
@@ -84,11 +95,13 @@ class any {
85 static constexpr as_thunk unthunk = as_thunk{};
96 static constexpr as_thunk unthunk = as_thunk{};
87− using map_pair = std::pair<const char * const, const any>;
98+ using map_pair = std::pair<const symbol_t, const any>;
88− using map = std::vector<map_pair WITH_ALLOCATOR(map_pair)>;
101+ using map = std::array<const map_pair, N>;
90 template <size_t N>
103 template <size_t N>
91− using data = std::array<any, N>;
104+ using data = std::array<const any, N>;
93 using array = std::deque<any WITH_ALLOCATOR(any)>;
106 using array = std::deque<any WITH_ALLOCATOR(any)>;
94 using fn = auto (*)(const any&) -> any;
107 using fn = auto (*)(const any&) -> any;
@@ -140,7 +153,6 @@ class any {
140 mutable eff_fn e;
153 mutable eff_fn e;
141 mutable void * u;
154 mutable void * u;
142 mutable managed<std::string> s;
155 mutable managed<std::string> s;
143− mutable managed<map> m;
144 mutable managed<array> a;
156 mutable managed<array> a;
145 mutable managed<closure> l;
157 mutable managed<closure> l;
146 mutable managed<eff_closure> k;
158 mutable managed<eff_closure> k;
@@ -170,8 +182,8 @@ class any {
170 any(const managed<std::string>& val) noexcept : type(Type::String), s(val) {}
182 any(const managed<std::string>& val) noexcept : type(Type::String), s(val) {}
171 any(managed<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
183 any(managed<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
173− any(const map& val) : type(Type::Map), m(make_managed<map>(val)) {}
185+ template <size_t N>
174− any(map&& val) noexcept : type(Type::Map), m(make_managed<map>(std::move(val))) {}
186+ any(map<N>&& val) noexcept : type(Type::Map), p(make_managed<map<N>>(std::move(val))) {}
176 template <size_t N>
188 template <size_t N>
177 any(data<N>&& val) noexcept : type(Type::Data), p(make_managed<data<N>>(std::move(val))) {}
189 any(data<N>&& val) noexcept : type(Type::Data), p(make_managed<data<N>>(std::move(val))) {}
@@ -216,7 +228,7 @@ class any {
216 any(const T& val, typename std::enable_if<std::is_same<T,void*>::value>::type* = 0) noexcept
228 any(const T& val, typename std::enable_if<std::is_same<T,void*>::value>::type* = 0) noexcept
217 : type(Type::RawPointer), u(val) {}
229 : type(Type::RawPointer), u(val) {}
219− any(std::nullptr_t) noexcept : type(Type::Pointer), p(nullptr) {}
231+ any(std::nullptr_t) noexcept : type(Type::RawPointer), u(nullptr) {}
222#if !defined(USE_GC)
234#if !defined(USE_GC)
@@ -249,10 +261,10 @@ class any {
249 case Type::RawPointer: u = other.u; break;
261 case Type::RawPointer: u = other.u; break;
251 case Type::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
263 case Type::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
252− case Type::Map: new (&m) managed<map>(move_if_rvalue<T>(other.m)); break;
253 case Type::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
264 case Type::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
254 case Type::Closure: new (&l) managed<closure>(move_if_rvalue<T>(other.l)); break;
265 case Type::Closure: new (&l) managed<closure>(move_if_rvalue<T>(other.l)); break;
255 case Type::EffClosure: new (&k) managed<eff_closure>(move_if_rvalue<T>(other.k)); break;
266 case Type::EffClosure: new (&k) managed<eff_closure>(move_if_rvalue<T>(other.k)); break;
256 case Type::Data:
268 case Type::Data:
257 case Type::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
269 case Type::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
@@ -263,10 +275,10 @@ class any {
263 auto destruct() -> void {
275 auto destruct() -> void {
264 switch (type) {
276 switch (type) {
265 case Type::String: s.~managed<std::string>(); break;
277 case Type::String: s.~managed<std::string>(); break;
266− case Type::Map: m.~managed<map>(); break;
267 case Type::Array: a.~managed<array>(); break;
278 case Type::Array: a.~managed<array>(); break;
268 case Type::Closure: l.~managed<closure>(); break;
279 case Type::Closure: l.~managed<closure>(); break;
269 case Type::EffClosure: k.~managed<eff_closure>(); break;
280 case Type::EffClosure: k.~managed<eff_closure>(); break;
270 case Type::Data:
282 case Type::Data:
271 case Type::Pointer: p.~managed<void>(); break;
283 case Type::Pointer: p.~managed<void>(); break;
@@ -314,14 +326,13 @@ class any {
314 operator bool() const;
326 operator bool() const;
315 operator char() const;
327 operator char() const;
316 operator cstring() const;
328 operator cstring() const;
317− operator const map&() const;
318 operator const array&() const;
329 operator const array&() const;
320− auto operator[](const char[]) const -> const any&;
331+ auto operator[](const symbol_t) const -> const any&;
321 auto operator[](const size_t) const -> const any&;
332 auto operator[](const size_t) const -> const any&;
322 auto operator[](const any&) const -> const any&;
333 auto operator[](const any&) const -> const any&;
324− auto contains(const char[]) const -> bool;
335+ auto contains(const symbol_t) const -> bool;
326 auto extractPointer(IF_DEBUG(const Type)) const -> void*;
337 auto extractPointer(IF_DEBUG(const Type)) const -> void*;
@@ -389,19 +400,25 @@ class any {
389 DEFINE_OPERATOR(%, char, char)
400 DEFINE_OPERATOR(%, char, char)
391 friend auto operator-(const any&) -> any; // unary negate
402 friend auto operator-(const any&) -> any; // unary negate
394template <typename T, typename U=void>
406template <typename T, typename U=void>
395−struct TypeTag {};
407+struct tag_helper {};
410+struct tag_helper<any::map<N>> {
411+ static constexpr any::Type tag = any::Type::Map;
397template <size_t N>
414template <size_t N>
398−struct TypeTag<any::data<N>> {
415+struct tag_helper<any::data<N>> {
399− static constexpr any::Type TypeId = any::Type::Data;
416+ static constexpr any::Type tag = any::Type::Data;
402template <typename T>
419template <typename T>
403−struct TypeTag<T> {
420+struct tag_helper<T> {
404− static constexpr any::Type TypeId = any::Type::Pointer;
421+ static constexpr any::Type tag = any::Type::Pointer;
407template <typename T>
424template <typename T>
@@ -413,16 +430,14 @@ inline auto cast(const any& a) ->
414template <typename T>
431template <typename T>
415inline auto cast(const any& a) ->
432inline auto cast(const any& a) ->
416− typename std::enable_if<std::is_same<T, any::map>::value ||
433+ typename std::enable_if<std::is_same<T, any::array>::value, const T&>::type {
417− std::is_same<T, any::array>::value, const T&>::type {
418 return a;
434 return a;
421template <typename T, typename = typename std::enable_if<std::is_class<T>::value>::type>
437template <typename T, typename = typename std::enable_if<std::is_class<T>::value>::type>
422inline auto cast(const any& a) ->
438inline auto cast(const any& a) ->
423− typename std::enable_if<!std::is_same<T, any::map>::value &&
439+ typename std::enable_if<!std::is_same<T, any::array>::value, T&>::type {
424− !std::is_same<T, any::array>::value, T&>::type {
425− return *static_cast<T*>(a.extractPointer(IF_DEBUG(TypeTag<T>::TypeId)));
440+ return *static_cast<T*>(a.extractPointer(IF_DEBUG(tag_helper<T>::tag)));
428template <typename T>
443template <typename T>