git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Rework recursive let mechanism
421f9deAndy Arvanitis
runtime/purescript.h+34−18
@@ -82,19 +82,6 @@ namespace purescript {
82 : std::shared_ptr<void>(std::make_shared<eff_fn_t>(f)) {
82 : std::shared_ptr<void>(std::make_shared<eff_fn_t>(f)) {
83 }
83 }
84
84
85− template <typename T,
86− typename = typename std::enable_if<!std::is_same<boxed,T>::value &&
87− std::is_convertible<T,fn_t>::value>::type>
88− auto operator=(const T& right) -> boxed& {
89− if (std::shared_ptr<void>::operator bool()) {
90− auto& f = *static_cast<fn_t*>(get());
91− f = right;
92− } else {
93− reset(new fn_t(right));
94− }
95− return *this;
96− }
97−
98 auto operator()(const boxed& arg) const -> boxed {
85 auto operator()(const boxed& arg) const -> boxed {
99 auto& f = *static_cast<fn_t*>(get());
86 auto& f = *static_cast<fn_t*>(get());
100 return f(arg);
87 return f(arg);
@@ -133,6 +120,40 @@ namespace purescript {
133
120
134 }; // class boxed
121 }; // class boxed
135
122
123+ using fn_t = boxed::fn_t;
124+ using eff_fn_t = boxed::eff_fn_t;
125+ using dict_t = boxed::dict_t;
126+ using array_t = boxed::array_t;
127+
128+ class boxed_r : private std::shared_ptr<void> {
129+ public:
130+ boxed_r() : std::shared_ptr<void>(std::make_shared<boxed>()) {}
131+
132+ operator const boxed&() const {
133+ return *static_cast<const boxed*>(get());
134+ }
135+
136+ auto operator()(const boxed& arg) const -> boxed {
137+ auto& b = *static_cast<boxed*>(get());
138+ auto& f = *static_cast<fn_t*>(b.get());
139+ return f(arg);
140+ }
141+
142+ auto operator()() const -> boxed {
143+ auto& b = *static_cast<boxed*>(get());
144+ auto& f = *static_cast<eff_fn_t*>(b.get());
145+ return f();
146+ }
147+
148+ template <typename T>
149+ auto operator=(T&& right) -> boxed_r& {
150+ auto& b = *static_cast<boxed*>(get());
151+ b = std::forward<T>(right);
152+ return *this;
153+ }
154+
155+ }; // class boxed_r
156+
136 template <typename T, typename... Args>
157 template <typename T, typename... Args>
137 inline auto box(Args&&... args) -> boxed {
158 inline auto box(Args&&... args) -> boxed {
138 return std::make_shared<T>(std::forward<Args>(args)...);
159 return std::make_shared<T>(std::forward<Args>(args)...);
@@ -163,11 +184,6 @@ namespace purescript {
163 return unbox<boxed::array_t>(a).size();
184 return unbox<boxed::array_t>(a).size();
164 }
185 }
165
186
166− using fn_t = boxed::fn_t;
167− using eff_fn_t = boxed::eff_fn_t;
168− using dict_t = boxed::dict_t;
169− using array_t = boxed::array_t;
170−
171 constexpr auto undefined = nullptr;
187 constexpr auto undefined = nullptr;
172
188
173} // namespace purescript
189} // namespace purescript
src/CodeGen/Cpp.hs+1−2
@@ -240,8 +240,7 @@ moduleToCpp (Module _ coms mn _ imps _ foreigns decls) _ =
240 bindersToCpp ss binders vals
240 bindersToCpp ss binders vals
241 valueToCpp (Let _ ds val) = do
241 valueToCpp (Let _ ds val) = do
242 let recurs = concatMap getNames $ filter isRec ds
242 let recurs = concatMap getNames $ filter isRec ds
243− recurDs = (\v -> AST.VariableIntroduction Nothing (identToCpp v) (Just (AST.Var Nothing "box<fn_t>()"))) <$> recurs
243+ recurDs = (\v -> AST.Var Nothing $ "boxed_r " <> identToCpp v) <$> recurs
244− -- recurDsWeak = (\v -> AST.VariableIntroduction Nothing ("__unsafe_unretained " <> identToCpp v <> unretainedSuffix) Nothing) <$> recurs
245 ds' <- concat <$> mapM (bindToCpp LetDecl) ds
244 ds' <- concat <$> mapM (bindToCpp LetDecl) ds
246 ret <- valueToCpp val
245 ret <- valueToCpp val
247 return $
246 return $