Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(transient): adds conj!, assoc!, dissoc! and pop! for transients #62

Merged
merged 7 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/cpp/jank/runtime/obj/transient_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ namespace jank::runtime
return ret;
}

native_box<static_object> pop();

/* behavior::objectable */
native_bool equal(object const &) const;
native_persistent_string to_string() const;
Expand Down
13 changes: 13 additions & 0 deletions src/cpp/jank/runtime/obj/transient_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,147 +18,160 @@
native_bool obj::transient_vector::equal(object const &o) const
{
/* Transient equality, in Clojure, is based solely on identity. */
return &base == &o;

Check warning on line 21 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L21

Added line #L21 was not covered by tests
}

native_persistent_string obj::transient_vector::to_string() const
{
fmt::memory_buffer buff;
to_string(buff);
return native_persistent_string{ buff.data(), buff.size() };

Check warning on line 28 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L26-L28

Added lines #L26 - L28 were not covered by tests
}

void obj::transient_vector::to_string(fmt::memory_buffer &buff) const
{
auto inserter(std::back_inserter(buff));
fmt::format_to(inserter, "{}@{}", magic_enum::enum_name(base.type), fmt::ptr(&base));

Check warning on line 34 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L33-L34

Added lines #L33 - L34 were not covered by tests
}

native_hash obj::transient_vector::to_hash() const
{
/* Hash is also based only on identity. Clojure uses default hashCode, which does the same. */
return static_cast<native_hash>(reinterpret_cast<uintptr_t>(this));

Check warning on line 40 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L40

Added line #L40 was not covered by tests
}

obj::transient_vector_ptr obj::transient_vector::pop()
{
assert_active();
if(data.empty())

Check warning on line 46 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L45-L46

Added lines #L45 - L46 were not covered by tests
{
throw std::runtime_error{ "Can't pop empty vector" };

Check warning on line 48 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L48

Added line #L48 was not covered by tests
}

data.take(data.size() - 1);

Check warning on line 51 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L51

Added line #L51 was not covered by tests

return this;

Check warning on line 53 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L53

Added line #L53 was not covered by tests
}

size_t obj::transient_vector::count() const
{
assert_active();
return data.size();

Check warning on line 59 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L58-L59

Added lines #L58 - L59 were not covered by tests
}

obj::transient_vector_ptr obj::transient_vector::cons_in_place(object_ptr const head)
{
assert_active();
data.push_back(head);
return this;

Check warning on line 66 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L64-L66

Added lines #L64 - L66 were not covered by tests
}

native_box<obj::transient_vector::persistent_type> obj::transient_vector::to_persistent()
{
assert_active();
active = false;
return make_box<obj::persistent_vector>(data.persistent());

Check warning on line 73 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L71-L73

Added lines #L71 - L73 were not covered by tests
}

object_ptr obj::transient_vector::call(object_ptr const idx) const
{
assert_active();
if(idx->type == object_type::integer)

Check warning on line 79 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L78-L79

Added lines #L78 - L79 were not covered by tests
{
auto const i(expect_object<obj::integer>(idx)->data);
if(i < 0 || data.size() <= static_cast<size_t>(i))

Check warning on line 82 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L81-L82

Added lines #L81 - L82 were not covered by tests
{
throw std::runtime_error{
fmt::format("Index out of bound; index = {}, count = {}", i, count())
};

Check warning on line 86 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L84-L86

Added lines #L84 - L86 were not covered by tests
}

return data[i];

Check warning on line 89 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L89

Added line #L89 was not covered by tests
}
else

Check warning on line 91 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L91

Added line #L91 was not covered by tests
{
throw std::runtime_error{ fmt::format("key must be an integer; found {}",
runtime::detail::to_string(idx)) };

Check warning on line 94 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L93-L94

Added lines #L93 - L94 were not covered by tests
}
}

object_ptr obj::transient_vector::get(object_ptr const idx) const
{
assert_active();
if(idx->type == object_type::integer)

Check warning on line 101 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L100-L101

Added lines #L100 - L101 were not covered by tests
{
auto const i(expect_object<obj::integer>(idx)->data);
if(i < 0 || data.size() <= static_cast<size_t>(i))

Check warning on line 104 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L103-L104

Added lines #L103 - L104 were not covered by tests
{
return obj::nil::nil_const();

Check warning on line 106 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L106

Added line #L106 was not covered by tests
}

return data[i];

Check warning on line 109 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L109

Added line #L109 was not covered by tests
}
else

Check warning on line 111 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L111

Added line #L111 was not covered by tests
{
throw std::runtime_error{ fmt::format("key must be an integer; found {}",
runtime::detail::to_string(idx)) };

Check warning on line 114 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L113-L114

Added lines #L113 - L114 were not covered by tests
}
}

object_ptr obj::transient_vector::get(object_ptr const idx, object_ptr const fallback) const
{
assert_active();
if(idx->type == object_type::integer)

Check warning on line 121 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L120-L121

Added lines #L120 - L121 were not covered by tests
{
auto const i(expect_object<obj::integer>(idx)->data);
if(i < 0 || data.size() <= static_cast<size_t>(i))

Check warning on line 124 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L123-L124

Added lines #L123 - L124 were not covered by tests
{
return fallback;

Check warning on line 126 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L126

Added line #L126 was not covered by tests
}

return data[i];

Check warning on line 129 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L129

Added line #L129 was not covered by tests
}
else

Check warning on line 131 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L131

Added line #L131 was not covered by tests
{
throw std::runtime_error{ fmt::format("key must be an integer; found {}",
runtime::detail::to_string(idx)) };

Check warning on line 134 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L133-L134

Added lines #L133 - L134 were not covered by tests
}
}

object_ptr obj::transient_vector::get_entry(object_ptr const idx) const
{
if(idx->type == object_type::integer)

Check warning on line 140 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L140

Added line #L140 was not covered by tests
{
auto const i(expect_object<obj::integer>(idx)->data);
if(i < 0 || data.size() <= static_cast<size_t>(i))

Check warning on line 143 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L142-L143

Added lines #L142 - L143 were not covered by tests
{
return obj::nil::nil_const();

Check warning on line 145 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L145

Added line #L145 was not covered by tests
}
/* TODO: Map entry type? */
return make_box<obj::persistent_vector>(idx, data[i]);

Check warning on line 148 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L148

Added line #L148 was not covered by tests
}
else

Check warning on line 150 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L150

Added line #L150 was not covered by tests
{
throw std::runtime_error{ fmt::format("get_entry on a vector must be an integer; found {}",
runtime::detail::to_string(idx)) };

Check warning on line 153 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L152-L153

Added lines #L152 - L153 were not covered by tests
}
}

native_bool obj::transient_vector::contains(object_ptr const elem) const
{
if(elem->type == object_type::integer)

Check warning on line 159 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L159

Added line #L159 was not covered by tests
{
auto const i(expect_object<obj::integer>(elem)->data);
return i >= 0 && static_cast<size_t>(i) < data.size();

Check warning on line 162 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L161-L162

Added lines #L161 - L162 were not covered by tests
}
else

Check warning on line 164 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L164

Added line #L164 was not covered by tests
{
return false;

Check warning on line 166 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L166

Added line #L166 was not covered by tests
}
}

void obj::transient_vector::assert_active() const
{
if(!active)

Check warning on line 172 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L172

Added line #L172 was not covered by tests
{
throw std::runtime_error{ "transient used after it's been made persistent" };

Check warning on line 174 in src/cpp/jank/runtime/obj/transient_vector.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_vector.cpp#L174

Added line #L174 was not covered by tests
}
}
}
21 changes: 21 additions & 0 deletions src/jank/clojure/core.jank
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,27 @@
(recur ret (first ks) (next ks))
ret)))))

(def pop!)
Samy-33 marked this conversation as resolved.
Show resolved Hide resolved
(def pop!
(fn* 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<T, obj::transient_vector>)
{
return typed_t->pop();
Samy-33 marked this conversation as resolved.
Show resolved Hide resolved
}
else
{ throw #{ (ex-info :not-transient-vector {:o coll}) }#; }
},
#{ coll }#
);
"))))

; Functions.

(defn- spread [arglist]
Expand Down
Loading