Skip to content

Sequence equality #249

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

Merged
merged 71 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
1fc35d5
wip range equality
frenchy64 Feb 7, 2025
bbc06d0
wip
frenchy64 Feb 7, 2025
a059c68
test core::equal
frenchy64 Feb 7, 2025
701d79f
wip
frenchy64 Feb 7, 2025
8a1472e
[skip ci]
frenchy64 Feb 7, 2025
cbd354f
[skip ci] rm
frenchy64 Feb 7, 2025
3727186
[skip ci]
frenchy64 Feb 7, 2025
ddd82ac
tests
frenchy64 Feb 7, 2025
c2da550
wip
frenchy64 Feb 7, 2025
c035ee8
[skip ci]
frenchy64 Feb 7, 2025
4dc1d92
[skip ci]
frenchy64 Feb 7, 2025
b6d8889
wip
frenchy64 Feb 7, 2025
408ed65
wip
frenchy64 Feb 7, 2025
4529d26
fix
frenchy64 Feb 7, 2025
c227006
[skip ci]
frenchy64 Feb 7, 2025
f1d6e2c
fix
frenchy64 Feb 10, 2025
ca229f8
[skip ci]
frenchy64 Feb 10, 2025
3afba55
wip
frenchy64 Feb 10, 2025
c5f2e33
[skip ci]
frenchy64 Feb 10, 2025
2dbbca6
fmt
frenchy64 Feb 10, 2025
d081d74
Merge branch 'main' into sequence-equality
frenchy64 Feb 10, 2025
4819593
Merge branch 'main' into sequence-equality
frenchy64 Feb 13, 2025
fe6f1dd
assert
frenchy64 Feb 13, 2025
2deb82d
Merge branch 'main' into sequence-equality
frenchy64 Feb 22, 2025
c36ca8d
[skip ci]
frenchy64 Feb 22, 2025
acb06a4
wip
frenchy64 Feb 22, 2025
4a1620f
[skip ci]
frenchy64 Feb 22, 2025
b3ffc63
[skip ci]
frenchy64 Feb 22, 2025
8bf2c34
[skip ci] undo
frenchy64 Feb 22, 2025
6b760d1
[skip ci]
frenchy64 Feb 22, 2025
0bbcbc1
[skip ci]
frenchy64 Feb 22, 2025
5a08204
[skip ci]
frenchy64 Feb 22, 2025
e9c761f
[skip ci]
frenchy64 Feb 22, 2025
a695a90
[skip ci]
frenchy64 Feb 22, 2025
31216fc
[skip ci]
frenchy64 Feb 22, 2025
e8fc0b5
[skip ci]
frenchy64 Feb 22, 2025
6e26023
[skip ci]
frenchy64 Feb 22, 2025
02d217d
[skip ci]
frenchy64 Feb 22, 2025
4979e26
[skip ci]
frenchy64 Feb 22, 2025
5e1e9c3
[skip ci]
frenchy64 Feb 22, 2025
fc1ff00
[skip ci]
frenchy64 Feb 22, 2025
6a1919f
[skip ci]
frenchy64 Feb 22, 2025
10f4798
[skip ci]
frenchy64 Feb 22, 2025
bdecaf0
[skip ci]
frenchy64 Feb 22, 2025
2dc83fe
wip
frenchy64 Feb 22, 2025
99728fa
[skip ci] fmt
frenchy64 Feb 22, 2025
0b8c535
wip
frenchy64 Feb 22, 2025
dd3649e
wip
frenchy64 Feb 22, 2025
674a8e9
[skip ci] revert equal null check
frenchy64 Feb 22, 2025
d754b74
[skip ci] fix first half of chunked cons
frenchy64 Feb 22, 2025
6132099
[skip ci] add bang to next-in-place, fix comments
frenchy64 Feb 22, 2025
7c16d3a
[skip ci] assert
frenchy64 Feb 23, 2025
d9d6281
asserts
frenchy64 Feb 23, 2025
e562511
[skip ci] -else
frenchy64 Feb 23, 2025
0d27f83
add sequence_equal tests
frenchy64 Feb 23, 2025
64a74a2
apply-to
frenchy64 Feb 23, 2025
eee2c29
[skip ci]
frenchy64 Feb 23, 2025
cea8422
tests
frenchy64 Feb 23, 2025
2e08987
fmt
frenchy64 Feb 23, 2025
35a8643
wip
frenchy64 Feb 23, 2025
5aecb6e
[skip ci] undo equal changes
frenchy64 Feb 23, 2025
0da1002
[skip ci] revert callable
frenchy64 Feb 23, 2025
5df808d
[skip ci] rm assertions
frenchy64 Feb 23, 2025
bf75688
[skip ci] remove assert
frenchy64 Feb 23, 2025
201560b
fix #283
frenchy64 Feb 24, 2025
f2e9a29
[skip ci] smaller fix
frenchy64 Feb 24, 2025
4b405bf
[skip ci] try again
frenchy64 Feb 24, 2025
4246bd8
[skip ci] again
frenchy64 Feb 24, 2025
24ca1fc
[skip ci] -assert
frenchy64 Feb 24, 2025
aaacb2c
[skip ci] use correct ctor for infinite repeat
frenchy64 Feb 24, 2025
9f05135
fmt
frenchy64 Feb 24, 2025
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
7 changes: 7 additions & 0 deletions compiler+runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -449,11 +449,18 @@ if(jank_tests)
test/cpp/jank/read/lex.cpp
test/cpp/jank/read/parse.cpp
test/cpp/jank/analyze/box.cpp
test/cpp/jank/runtime/behavior/callable.cpp
test/cpp/jank/runtime/core.cpp
test/cpp/jank/runtime/core/seq.cpp
test/cpp/jank/runtime/detail/native_persistent_list.cpp
test/cpp/jank/runtime/obj/persistent_string.cpp
test/cpp/jank/runtime/obj/ratio.cpp
test/cpp/jank/runtime/obj/persistent_list.cpp
test/cpp/jank/runtime/obj/persistent_string.cpp
test/cpp/jank/runtime/obj/persistent_vector.cpp
test/cpp/jank/runtime/obj/range.cpp
test/cpp/jank/runtime/obj/integer_range.cpp
test/cpp/jank/runtime/obj/repeat.cpp
test/cpp/jank/jit/processor.cpp
)
add_executable(jank::test_exe ALIAS jank_test_exe)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace jank::runtime::obj

using bounds_check_t = native_bool (*)(integer_ptr, integer_ptr);

/* Constructors are only to be used within integer_range.cpp. Prefer integer_range::create. */
integer_range() = default;
integer_range(integer_range &&) noexcept = default;
integer_range(integer_range const &) = default;
Expand Down
1 change: 1 addition & 0 deletions compiler+runtime/include/cpp/jank/runtime/obj/range.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace jank::runtime::obj

using bounds_check_t = native_bool (*)(object_ptr, object_ptr);

/* Constructors are only to be used within range.cpp. Prefer range::create. */
range() = default;
range(range &&) noexcept = default;
range(range const &) = default;
Expand Down
2 changes: 1 addition & 1 deletion compiler+runtime/include/cpp/jank/runtime/obj/symbol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ namespace std
}
else if(!rhs)
{
return !lhs;
return false;
}
return lhs->equal(*rhs);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler+runtime/include/cpp/jank/runtime/var.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ namespace std
}
else if(!rhs)
{
return !lhs;
return false;
}
return lhs->equal(*rhs);
}
Expand Down
9 changes: 6 additions & 3 deletions compiler+runtime/src/cpp/clojure/core_native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,8 @@ jank_object_ptr jank_load_clojure_core_native()
return obj::boolean::false_const();
}

for(auto it(fresh_seq(rest)); it != nullptr; it = next_in_place(it))
for(auto it(fresh_seq(rest)); it != nullptr && it != obj::nil::nil_const();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, here, it cannot be nullptr. That's not part of the contract. Everything returned from runtime:: fns should be non-null.

The one exception is the next_in_place and fresh_seq templates. Ultimately, we can remove those (not in this PR); they're only there for a historical partial refactor which never panned out.

There should never be a case, right now, where we need to check for nullptr and nil.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should never be a case, right now, where we need to check for nullptr and nil.

There's a few more in multi_function.cpp.

it = next_in_place(it))
{
if(!is_equiv(l, first(it)))
{
Expand Down Expand Up @@ -798,8 +799,10 @@ jank_object_ptr jank_load_clojure_core_native()
{
auto const fn(
make_box<obj::jit_function>(behavior::callable::build_arity_flags(2, false, false)));
fn->arity_1 = [](object * const val) -> object * { return repeat(val); };
fn->arity_2 = [](object * const n, object * const val) -> object * { return repeat(n, val); };
fn->arity_1 = [](object * const val) -> object * { return obj::repeat::create(val); };
fn->arity_2 = [](object * const n, object * const val) -> object * {
return obj::repeat::create(n, val);
};
intern_fn_obj("repeat", fn);
}

Expand Down
4 changes: 1 addition & 3 deletions compiler+runtime/src/cpp/jank/read/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ namespace jank::read::parse
auto const jank_keyword(__rt_ctx->intern_keyword("", "jank").expect_ok());
auto const default_keyword(__rt_ctx->intern_keyword("", "default").expect_ok());

for(auto it(list->fresh_seq()); it != nullptr;)
for(auto it(list->fresh_seq()); it != nullptr; it = next_in_place(next_in_place(it)))
{
auto const kw(it->first());
/* We take the first match, checking for :jank first. If there are duplicates, it doesn't
Expand Down Expand Up @@ -829,8 +829,6 @@ namespace jank::read::parse
return object_source_info{ next_in_place(it)->first(), start_token, list_end };
}
}

it = next_in_place(next_in_place(it));
}

return ok(none);
Expand Down
2 changes: 1 addition & 1 deletion compiler+runtime/src/cpp/jank/runtime/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ namespace jank::runtime
}
else if(!rhs)
{
return !lhs;
return false;
}

return visit_object([&](auto const typed_lhs) { return typed_lhs->equal(*rhs); }, lhs);
Expand Down
45 changes: 8 additions & 37 deletions compiler+runtime/src/cpp/jank/runtime/core/seq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,21 +478,13 @@ namespace jank::runtime
{
return make_box<obj::persistent_list>(std::in_place, o);
}
else if constexpr(behavior::conjable_in_place<T>)
{
return typed_s->conj_in_place(o);
}
else if constexpr(behavior::conjable<T>)
{
return typed_s->conj(o);
}
else if constexpr(behavior::seqable<T>)
{
return typed_s->seq()->conj(o);
}
else
{
throw std::runtime_error{ fmt::format("not seqable: {}", typed_s->to_string()) };
throw std::runtime_error{ fmt::format("not conjable: {}", typed_s->to_string()) };
}
},
s);
Expand Down Expand Up @@ -521,11 +513,7 @@ namespace jank::runtime
[&](auto const typed_m) -> object_ptr {
using T = typename decltype(typed_m)::value_type;

if constexpr(behavior::associatively_writable_in_place<T>)
{
return typed_m->assoc_in_place(k, v);
}
else if constexpr(behavior::associatively_writable<T>)
if constexpr(behavior::associatively_writable<T>)
{
return typed_m->assoc(k, v);
}
Expand All @@ -544,11 +532,7 @@ namespace jank::runtime
[&](auto const typed_m) -> object_ptr {
using T = typename decltype(typed_m)::value_type;

if constexpr(behavior::associatively_writable_in_place<T>)
{
return typed_m->dissoc_in_place(k);
}
else if constexpr(behavior::associatively_writable<T>)
if constexpr(behavior::associatively_writable<T>)
{
return typed_m->dissoc(k);
}
Expand Down Expand Up @@ -1025,23 +1009,10 @@ namespace jank::runtime
return visit_seqable(
[](auto const typed_r, auto const typed_l) -> native_bool {
auto r_it(typed_r->fresh_seq());
auto l_it(typed_l->fresh_seq());
if(!r_it)
for(auto l_it(typed_l->fresh_seq()); l_it != nullptr;
l_it = l_it->next_in_place(), r_it = r_it->next_in_place())
{
return l_it == nullptr;
}
if(!l_it)
{
return r_it == nullptr;
}

for(; l_it != nullptr; l_it = l_it->next_in_place(), r_it = r_it->next_in_place())
{
if(!r_it)
{
return false;
}
if(!runtime::equal(l_it->first(), r_it->first()))
if(!r_it || !runtime::equal(l_it->first(), r_it->first()))
{
return false;
}
Expand Down Expand Up @@ -1178,12 +1149,12 @@ namespace jank::runtime

object_ptr repeat(object_ptr const val)
{
return make_box<obj::repeat>(val);
return obj::repeat::create(val);
}

object_ptr repeat(object_ptr const n, object_ptr const val)
{
return make_box<obj::repeat>(n, val);
return obj::repeat::create(n, val);
}

object_ptr sort(object_ptr const coll)
Expand Down
4 changes: 2 additions & 2 deletions compiler+runtime/src/cpp/jank/runtime/obj/chunked_cons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,12 @@ namespace jank::runtime::obj
for(auto it(fresh_seq()); it != nullptr;
it = runtime::next_in_place(it), seq = runtime::next_in_place(seq))
{
if(seq == nullptr || !runtime::equal(it, seq->first()))
if(seq == nullptr || !runtime::equal(it->first(), seq->first()))
{
return false;
}
}
return true;
return seq == nullptr;
},
[]() { return false; },
&o);
Expand Down
4 changes: 2 additions & 2 deletions compiler+runtime/src/cpp/jank/runtime/obj/cons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ namespace jank::runtime::obj
for(auto it(fresh_seq()); it != nullptr;
it = runtime::next_in_place(it), seq = runtime::next_in_place(seq))
{
if(seq == nullptr || !runtime::equal(it, seq->first()))
if(seq == nullptr || !runtime::equal(it->first(), seq->first()))
{
return false;
}
}
return true;
return seq == nullptr;
},
[]() { return false; },
&o);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace jank::runtime::obj::detail
for(auto it(fresh_seq()); it != nullptr;
it = it->next_in_place(), seq = seq->next_in_place())
{
if(seq == nullptr || !runtime::equal(it, seq->first()))
if(seq == nullptr || !runtime::equal(it->first(), seq->first()))
{
return false;
}
}
return true;
return seq == nullptr;
},
[]() { return false; },
&o);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace jank::runtime::obj::detail
return false;
}
}
return true;
return seq == nullptr;
},
[]() { return false; },
&o);
Expand Down
6 changes: 3 additions & 3 deletions compiler+runtime/src/cpp/jank/runtime/obj/integer_range.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace jank::runtime::obj
}
else if(is_zero(step))
{
return make_box<repeat>(make_box<integer>(start));
return repeat::create(make_box<integer>(start));
}
return make_box<integer_range>(start,
end,
Expand Down Expand Up @@ -137,12 +137,12 @@ namespace jank::runtime::obj
for(auto it(fresh_seq()); it != nullptr;
it = it->next_in_place(), seq = seq->next_in_place())
{
if(seq == nullptr || !runtime::equal(it, seq->first()))
if(seq == nullptr || !runtime::equal(it->first(), seq->first()))
{
return false;
}
}
return true;
return seq == nullptr;
},
[]() { return false; },
&o);
Expand Down
4 changes: 2 additions & 2 deletions compiler+runtime/src/cpp/jank/runtime/obj/iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ namespace jank::runtime::obj
for(auto it(fresh_seq()); it != nullptr;
it = runtime::next_in_place(it), seq = runtime::next_in_place(seq))
{
if(seq == nullptr || !runtime::equal(it, seq->first()))
if(seq == nullptr || !runtime::equal(it->first(), seq->first()))
{
return false;
}
}
return true;
return seq == nullptr;
},
[]() { return false; },
&o);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace jank::runtime::obj
assert(size > 0);
}

/* behavior::objectable */
/* behavior::object_like */
native_bool native_array_sequence::equal(object const &o) const
{
return runtime::equal(o, arr + index, arr + size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace jank::runtime::obj
{
}

/* behavior::objectable */
/* behavior::object_like */
native_bool native_vector_sequence::equal(object const &o) const
{
return runtime::equal(o, data.begin(), data.end());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,7 @@ namespace jank::runtime::obj

persistent_list_sequence_ptr persistent_list::seq() const
{
if(data.empty())
{
return nullptr;
}
return make_box<persistent_list_sequence>(this, data.begin(), data.end(), data.size());
return fresh_seq();
}

persistent_list_sequence_ptr persistent_list::fresh_seq() const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,7 @@ namespace jank::runtime::obj

persistent_string_sequence_ptr persistent_string::seq() const
{
if(data.empty())
{
return nullptr;
}
return make_box<persistent_string_sequence>(const_cast<persistent_string *>(this));
return fresh_seq();
}

persistent_string_sequence_ptr persistent_string::fresh_seq() const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace jank::runtime::obj
assert(!s->data.empty() && i < s->data.size());
}

/* behavior::objectable */
/* behavior::object_like */
native_bool persistent_string_sequence::equal(object const &o) const
{
return runtime::equal(o, str->data.begin() + index, str->data.end());
Expand Down
14 changes: 2 additions & 12 deletions compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,12 @@ namespace jank::runtime::obj
{
size_t i{};
auto e(typed_o->fresh_seq());
for(; e != nullptr; e = e->next_in_place())
for(; e != nullptr && i < data.size(); e = e->next_in_place(), ++i)
{
if(!runtime::equal(data[i], e->first()))
{
return false;
}

if(++i == data.size())
{
e = e->next_in_place();
break;
}
}
return e == nullptr && i == data.size();
}
Expand Down Expand Up @@ -184,11 +178,7 @@ namespace jank::runtime::obj

persistent_vector_sequence_ptr persistent_vector::seq() const
{
if(data.empty())
{
return nullptr;
}
return make_box<persistent_vector_sequence>(const_cast<persistent_vector *>(this));
return fresh_seq();
}

persistent_vector_sequence_ptr persistent_vector::fresh_seq() const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace jank::runtime::obj
assert(0 < v->data.size() - index);
}

/* behavior::objectable */
/* behavior::object_like */
native_bool persistent_vector_sequence::equal(object const &o) const
{
return runtime::equal(
Expand Down
Loading