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 2 commits
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
1 change: 1 addition & 0 deletions include/cpp/jank/prelude.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@
#include <jank/runtime/behavior/numberable.hpp>
#include <jank/runtime/behavior/nameable.hpp>
#include <jank/runtime/behavior/transientable.hpp>
#include <jank/runtime/behavior/associatively_writable.hpp>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace jank::runtime::behavior
template <typename T>
concept associatively_writable_in_place = requires(T * const t) {
{
t->assoc_in_place(object_ptr{}, object_ptr{})
t->assoc_in_place(object_ptr{}, object_ptr{}), t->dissoc_in_place(object_ptr{})
Samy-33 marked this conversation as resolved.
Show resolved Hide resolved
} -> std::convertible_to<object_ptr>;
};
}
3 changes: 2 additions & 1 deletion include/cpp/jank/runtime/obj/transient_hash_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ namespace jank::runtime
native_bool contains(object_ptr key) const;

/* behavior::associatively_writable_in_place */
native_box<static_object> assoc_in_place(object_ptr key, object_ptr val);
native_box<static_object> assoc_in_place(object_ptr const key, object_ptr const val);
native_box<static_object> dissoc_in_place(object_ptr const key);

/* behavior::consable_in_place */
native_box<static_object> cons_in_place(object_ptr head);
Expand Down
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
7 changes: 7 additions & 0 deletions src/cpp/jank/runtime/obj/transient_hash_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,135 +22,142 @@
native_bool obj::transient_hash_map::equal(object const &o) const
{
/* Transient equality, in Clojure, is based solely on identity. */
return &base == &o;

Check warning on line 25 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L25

Added line #L25 was not covered by tests
}

void obj::transient_hash_map::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 31 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L30-L31

Added lines #L30 - L31 were not covered by tests
}

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

Check warning on line 38 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L36-L38

Added lines #L36 - L38 were not covered by tests
}

native_hash obj::transient_hash_map::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 44 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L44

Added line #L44 was not covered by tests
}

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

Check warning on line 50 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L49-L50

Added lines #L49 - L50 were not covered by tests
}

object_ptr obj::transient_hash_map::get(object_ptr const key) const
{
assert_active();
auto const res(data.find(key));
if(res)

Check warning on line 57 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L55-L57

Added lines #L55 - L57 were not covered by tests
{
return *res;

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

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L59

Added line #L59 was not covered by tests
}
return obj::nil::nil_const();

Check warning on line 61 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L61

Added line #L61 was not covered by tests
}

object_ptr obj::transient_hash_map::get(object_ptr const key, object_ptr const fallback) const
{
assert_active();
auto const res(data.find(key));
if(res)

Check warning on line 68 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L66-L68

Added lines #L66 - L68 were not covered by tests
{
return *res;

Check warning on line 70 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L70

Added line #L70 was not covered by tests
}
return fallback;

Check warning on line 72 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L72

Added line #L72 was not covered by tests
}

object_ptr obj::transient_hash_map::get_entry(object_ptr const key) const
{
assert_active();
auto const res(data.find(key));
if(res)

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

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L77-L79

Added lines #L77 - L79 were not covered by tests
{
return make_box<obj::persistent_vector>(key, *res);

Check warning on line 81 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L81

Added line #L81 was not covered by tests
}
return obj::nil::nil_const();

Check warning on line 83 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L83

Added line #L83 was not covered by tests
}

native_bool obj::transient_hash_map::contains(object_ptr const key) const
{
assert_active();
return data.find(key);

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

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L88-L89

Added lines #L88 - L89 were not covered by tests
}

obj::transient_hash_map_ptr
obj::transient_hash_map::assoc_in_place(object_ptr const key, object_ptr const val)
{
assert_active();
data.set(key, val);
return this;

Check warning on line 97 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L95-L97

Added lines #L95 - L97 were not covered by tests
}

obj::transient_hash_map_ptr obj::transient_hash_map::dissoc_in_place(object_ptr const key)
{
assert_active();
data.erase(key);
return this;

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

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L102-L104

Added lines #L102 - L104 were not covered by tests
}

obj::transient_hash_map_ptr obj::transient_hash_map::cons_in_place(object_ptr const head)
{
assert_active();
if(head->type != object_type::persistent_vector)

Check warning on line 110 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L109-L110

Added lines #L109 - L110 were not covered by tests
{
throw std::runtime_error{ fmt::format("invalid map entry: {}",
runtime::detail::to_string(head)) };

Check warning on line 113 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L112-L113

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

auto const vec(expect_object<obj::persistent_vector>(head));
if(vec->count() != 2)

Check warning on line 117 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L116-L117

Added lines #L116 - L117 were not covered by tests
{
throw std::runtime_error{ fmt::format("invalid map entry: {}",
runtime::detail::to_string(head)) };

Check warning on line 120 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L119-L120

Added lines #L119 - L120 were not covered by tests
}

data.set(vec->data[0], vec->data[1]);
return this;

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

View check run for this annotation

Codecov / codecov/patch

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

Added lines #L123 - L124 were not covered by tests
}

native_box<obj::transient_hash_map::persistent_type> obj::transient_hash_map::to_persistent()
{
assert_active();
active = false;
return make_box<obj::persistent_hash_map>(std::move(data));

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

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L129-L131

Added lines #L129 - L131 were not covered by tests
}

object_ptr obj::transient_hash_map::call(object_ptr const o) const
{
assert_active();
auto const found(data.find(o));
if(!found)

Check warning on line 138 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L136-L138

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

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

View check run for this annotation

Codecov / codecov/patch

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

Added line #L140 was not covered by tests
}
return *found;

Check warning on line 142 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L142

Added line #L142 was not covered by tests
}

object_ptr obj::transient_hash_map::call(object_ptr const o, object_ptr const fallback) const
{
assert_active();
auto const found(data.find(o));
if(!found)

Check warning on line 149 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L147-L149

Added lines #L147 - L149 were not covered by tests
{
return fallback;

Check warning on line 151 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L151

Added line #L151 was not covered by tests
}
return *found;

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

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L153

Added line #L153 was not covered by tests
}

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

Check warning on line 158 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L158

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

Check warning on line 160 in src/cpp/jank/runtime/obj/transient_hash_map.cpp

View check run for this annotation

Codecov / codecov/patch

src/cpp/jank/runtime/obj/transient_hash_map.cpp#L160

Added line #L160 was not covered by tests
}
}
}
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
}
}
}
102 changes: 102 additions & 0 deletions src/jank/clojure/core.jank
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,108 @@
#{ o }#
);"))

(def conj!)
(def conj!
(fn* conj!
([]
(transient []))
([coll]
coll)
([coll x]
(native/raw "__value = visit_object
(
[&](auto const typed_t, auto const head) -> object_ptr
{
using T = typename decltype(typed_t)::value_type;

if constexpr(behavior::persistentable<T>)
{
return typed_t->cons_in_place(head);
}
Samy-33 marked this conversation as resolved.
Show resolved Hide resolved
else
{ throw #{ (ex-info :not-persistentable {:o coll}) }#; }
},
#{ coll }#,
#{ x }#
);
"))))

(def assoc!)
(def assoc!
(fn* assoc!
([coll k v]
(native/raw "__value = visit_object
(
[&](auto const typed_t, auto const key, auto const val) -> object_ptr
Samy-33 marked this conversation as resolved.
Show resolved Hide resolved
{
using T = typename decltype(typed_t)::value_type;

if constexpr(behavior::associatively_writable_in_place<T>)
{
return typed_t->assoc_in_place(key, val);
}
else
{ throw #{ (ex-info :not-associatively_writable_in_place {:o coll}) }#; }
},
#{ coll }#,
#{ k }#,
#{ v }#
);
"))
([coll k v & kvs]
(let* [ret (assoc! coll k v)]
(if kvs
(recur ret (first kvs) (second kvs) (nnext kvs))
ret)))))

(def dissoc!)
(def dissoc!
(fn* dissoc!
([coll k]
(native/raw "__value = visit_object
(
[&](auto const typed_t, auto const key) -> object_ptr
{
using T = typename decltype(typed_t)::value_type;

if constexpr(behavior::associatively_writable_in_place<T>)
{
return typed_t->dissoc_in_place(key);
}
else
{ throw #{ (ex-info :not-associatively_writable_in_place {:o coll}) }#; }
},
#{ coll }#,
#{ k }#
);
"))
([coll k & ks]
(let* [ret (dissoc! coll k)]
(if ks
(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