diff --git a/include/cpp/jank/prelude.hpp b/include/cpp/jank/prelude.hpp index cf24402e2..826880123 100644 --- a/include/cpp/jank/prelude.hpp +++ b/include/cpp/jank/prelude.hpp @@ -28,4 +28,5 @@ #include #include #include +#include #include diff --git a/include/cpp/jank/runtime/behavior/associatively_writable.hpp b/include/cpp/jank/runtime/behavior/associatively_writable.hpp index b0099eaa6..4dd9a1b12 100644 --- a/include/cpp/jank/runtime/behavior/associatively_writable.hpp +++ b/include/cpp/jank/runtime/behavior/associatively_writable.hpp @@ -14,7 +14,11 @@ namespace jank::runtime::behavior template concept associatively_writable_in_place = requires(T * const t) { { - t->assoc_in_place(object_ptr{}, object_ptr{}), t->dissoc_in_place(object_ptr{}) + t->assoc_in_place(object_ptr{}, object_ptr{}) + } -> std::convertible_to; + + { + t->dissoc_in_place(object_ptr{}) } -> std::convertible_to; }; } diff --git a/include/cpp/jank/runtime/obj/transient_vector.hpp b/include/cpp/jank/runtime/obj/transient_vector.hpp index efe9e70c5..11632bdb1 100644 --- a/include/cpp/jank/runtime/obj/transient_vector.hpp +++ b/include/cpp/jank/runtime/obj/transient_vector.hpp @@ -23,8 +23,6 @@ namespace jank::runtime return ret; } - native_box pop_in_place(); - /* behavior::objectable */ native_bool equal(object const &) const; native_persistent_string to_string() const; @@ -49,6 +47,8 @@ namespace jank::runtime object_ptr get_entry(object_ptr const idx) const; native_bool contains(object_ptr const elem) const; + native_box pop_in_place(); + void assert_active() const; object base{ object_type::transient_vector }; diff --git a/src/cpp/jank/runtime/obj/transient_vector.cpp b/src/cpp/jank/runtime/obj/transient_vector.cpp index 0d312acbf..86cb302e1 100644 --- a/src/cpp/jank/runtime/obj/transient_vector.cpp +++ b/src/cpp/jank/runtime/obj/transient_vector.cpp @@ -40,16 +40,6 @@ namespace jank::runtime return static_cast(reinterpret_cast(this)); } - obj::transient_vector_ptr obj::transient_vector::pop_in_place() - { - assert_active(); - if(data.empty()) - { throw std::runtime_error{ "Can't pop empty vector" }; } - - data.take(data.size() - 1); - return this; - } - size_t obj::transient_vector::count() const { assert_active(); @@ -164,6 +154,18 @@ namespace jank::runtime } } + obj::transient_vector_ptr obj::transient_vector::pop_in_place() + { + assert_active(); + if(data.empty()) + { + throw std::runtime_error{ "Can't pop empty vector" }; + } + + data.take(data.size() - 1); + return this; + } + void obj::transient_vector::assert_active() const { if(!active) diff --git a/src/jank/clojure/core.jank b/src/jank/clojure/core.jank index 1e9035dd7..f12c5216e 100644 --- a/src/jank/clojure/core.jank +++ b/src/jank/clojure/core.jank @@ -408,9 +408,9 @@ if constexpr(behavior::transientable) { return typed_o->to_transient(); } else - { throw #{ (ex-info :not-transientable {:o o}) }#; } + { throw ~{ (ex-info :not-transientable {:o o}) }; } }, - #{ o }# + ~{ o } );")) ; Returns a new, persistent version of the transient collection, in @@ -426,9 +426,9 @@ if constexpr(behavior::persistentable) { return typed_o->to_persistent(); } else - { throw #{ (ex-info :not-persistentable {:o o}) }#; } + { throw ~{ (ex-info :not-persistentable {:o o}) }; } }, - #{ o }# + ~{ o } );")) (defn conj! @@ -439,17 +439,17 @@ ([coll x] (native/raw "__value = visit_object ( - [=](auto const typed_t, auto const head) -> object_ptr + [=](auto const typed_coll, auto const head) -> object_ptr { - using T = typename decltype(typed_t)::value_type; + using T = typename decltype(typed_coll)::value_type; - if constexpr(behavior::persistentable) - { return typed_t->cons_in_place(head); } + if constexpr(behavior::consable_in_place) + { return typed_coll->cons_in_place(head); } else - { throw #{ (ex-info :not-persistentable {:o coll}) }#; } + { throw ~{ (ex-info :not-persistentable {:o coll}) }; } }, - #{ coll }#, - #{ x }# + ~{ coll }, + ~{ x } ); "))) @@ -464,11 +464,11 @@ if constexpr(behavior::associatively_writable_in_place) { return typed_t->assoc_in_place(key, val); } else - { throw #{ (ex-info :not-associatively_writable_in_place {:o coll}) }#; } + { throw ~{ (ex-info :not-associatively_writable_in_place {:o coll}) }; } }, - #{ coll }#, - #{ k }#, - #{ v }# + ~{ coll }, + ~{ k }, + ~{ v } ); ")) ([coll k v & kvs] @@ -488,10 +488,10 @@ if constexpr(behavior::associatively_writable_in_place) { return typed_t->dissoc_in_place(key); } else - { throw #{ (ex-info :not-associatively_writable_in_place {:o coll}) }#; } + { throw ~{ (ex-info :not-associatively_writable_in_place {:o coll}) }; } }, - #{ coll }#, - #{ k }# + ~{ coll }, + ~{ k } ); ")) ([coll k & ks] @@ -502,19 +502,13 @@ (defn pop! ([coll] - (native/raw "__value = visit_object - ( - [=](auto const typed_t) -> object_ptr - { - using T = typename decltype(typed_t)::value_type; - - if constexpr(std::same_as) - { return typed_t->pop_in_place(); } - else - { throw #{ (ex-info :not-transient-vector {:o coll}) }#; } - }, - #{ coll }# - ); + (native/raw "if( ~{ coll }->type == object_type::transient_vector ) + { + auto typed_coll = expect_object(~{ coll }); + __value = typed_coll->pop_in_place(); + } + else + { throw ~{ (ex-info :not-transient-vector {:o coll}) }; } "))) ; Functions.