git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: handle non-closure eff funcs
8d452c1Andy Arvanitis
pcc/include/purescript.cc+3
@@ -38,6 +38,9 @@ auto any::operator()(const as_thunk) const -> const any& {
38
38
39auto any::operator()() const -> any {
39auto any::operator()() const -> any {
40 const any& variant = unthunkVariant(*this);
40 const any& variant = unthunkVariant(*this);
41+ if (variant.type == Type::EffClosure) {
42+ return (*variant.el)();
43+ }
41 assert(variant.type == Type::EffFunction);
44 assert(variant.type == Type::EffFunction);
42 return (*variant.e)();
45 return (*variant.e)();
43}
46}
pcc/include/purescript.hh+15−6
@@ -61,13 +61,14 @@ class any {
61 Boolean = 0x04,
61 Boolean = 0x04,
62 StringLiteral = 0x05,
62 StringLiteral = 0x05,
63 Function = 0x06,
63 Function = 0x06,
64+ EffFunction = 0x07,
64 Shared = 0x08,
65 Shared = 0x08,
65 String = 0x08,
66 String = 0x08,
66 Map = 0x09,
67 Map = 0x09,
67 Data = 0x0A,
68 Data = 0x0A,
68 Array = 0x0B,
69 Array = 0x0B,
69 Closure = 0x0C,
70 Closure = 0x0C,
70− EffFunction = 0x0D,
71+ EffClosure = 0x0D,
71 Pointer = 0x0E
72 Pointer = 0x0E
72 };
73 };
73
74
@@ -83,6 +84,7 @@ class any {
83 using data = std::vector<any>;
84 using data = std::vector<any>;
84 using array = std::deque<any>;
85 using array = std::deque<any>;
85 using fn = auto (*)(const any&) -> any;
86 using fn = auto (*)(const any&) -> any;
87+ using eff_fn = auto (*)() -> any;
86 using thunk = auto (*)(const as_thunk) -> const any&;
88 using thunk = auto (*)(const as_thunk) -> const any&;
87
89
88 private:
90 private:
@@ -102,16 +104,16 @@ class any {
102 }
104 }
103 };
105 };
104
106
105− class eff_fn {
107+ class eff_closure {
106 public:
108 public:
107 virtual auto operator()() const -> any = 0;
109 virtual auto operator()() const -> any = 0;
108 };
110 };
109
111
110 template <typename T>
112 template <typename T>
111− class _eff_fn : public eff_fn {
113+ class _eff_closure : public eff_closure {
112 const T lambda;
114 const T lambda;
113 public:
115 public:
114− _eff_fn(const T& l) noexcept : lambda(l) {}
116+ _eff_closure(const T& l) noexcept : lambda(l) {}
115 auto operator()() const -> any {
117 auto operator()() const -> any {
116 return lambda();
118 return lambda();
117 }
119 }
@@ -135,12 +137,13 @@ class any {
135 mutable bool b;
137 mutable bool b;
136 mutable cstring r;
138 mutable cstring r;
137 mutable fn f;
139 mutable fn f;
140+ mutable eff_fn e;
138 mutable shared<std::string> s;
141 mutable shared<std::string> s;
139 mutable shared<map> m;
142 mutable shared<map> m;
140 mutable shared<data> v;
143 mutable shared<data> v;
141 mutable shared<array> a;
144 mutable shared<array> a;
142 mutable shared<closure> l;
145 mutable shared<closure> l;
143− mutable shared<eff_fn> e;
146+ mutable shared<eff_closure> el;
144 mutable shared<void> p;
147 mutable shared<void> p;
145 };
148 };
146
149
@@ -184,8 +187,14 @@ class any {
184 : type(Type::Closure), l(make_shared<_closure<T>>(val)) {}
187 : type(Type::Closure), l(make_shared<_closure<T>>(val)) {}
185
188
186 template <typename T>
189 template <typename T>
190+ any(const T& val, typename std::enable_if<std::is_convertible<T,eff_fn>::value>::type* = 0) noexcept
191+ : type(Type::EffFunction), e(val) {}
192+
193+ template <typename T,
194+ typename = typename std::enable_if<!std::is_same<any,T>::value &&
195+ !std::is_convertible<T,eff_fn>::value>::type>
187 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
196 any(const T& val, typename std::enable_if<std::is_assignable<std::function<any()>,T>::value>::type* = 0)
188− : type(Type::EffFunction), e(make_shared<_eff_fn<T>>(val)) {}
197+ : type(Type::EffClosure), el(make_shared<_eff_closure<T>>(val)) {}
189
198
190 template <typename T>
199 template <typename T>
191 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0) noexcept
200 any(const T& val, typename std::enable_if<std::is_convertible<T,thunk>::value>::type* = 0) noexcept