diff --git a/compiler+runtime/include/cpp/jank/runtime/core/to_string.hpp b/compiler+runtime/include/cpp/jank/runtime/core/to_string.hpp index ff839827..9252be32 100644 --- a/compiler+runtime/include/cpp/jank/runtime/core/to_string.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/core/to_string.hpp @@ -6,6 +6,10 @@ namespace jank::runtime void to_string(char ch, fmt::memory_buffer &buff); void to_string(object_ptr o, fmt::memory_buffer &buff); + native_persistent_string to_code_string(object const *o); + void to_code_string(char ch, fmt::memory_buffer &buff); + void to_code_string(object_ptr o, fmt::memory_buffer &buff); + template void to_string(It const &begin, It const &end, @@ -63,4 +67,62 @@ namespace jank::runtime runtime::to_string(s, buff); return native_persistent_string{ buff.data(), buff.size() }; } + + template + void to_code_string(It const &begin, + It const &end, + native_persistent_string_view const open, + char const close, + fmt::memory_buffer &buff) + { + auto inserter(std::back_inserter(buff)); + for(auto const c : open) + { + inserter = c; + } + for(auto i(begin); i != end; ++i) + { + runtime::to_code_string(*i, buff); + auto n(i); + if(++n != end) + { + inserter = ' '; + } + } + inserter = close; + } + + template + requires behavior::sequenceable + void to_code_string(native_box const s, fmt::memory_buffer &buff) + { + auto inserter(std::back_inserter(buff)); + if(!s) + { + fmt::format_to(inserter, "()"); + return; + } + + fmt::format_to(inserter, "("); + native_bool needs_space{}; + for(auto i(s->fresh_seq()); i != nullptr; i = i->next_in_place()) + { + if(needs_space) + { + fmt::format_to(inserter, " "); + } + runtime::to_code_string(i->first(), buff); + needs_space = true; + } + fmt::format_to(inserter, ")"); + } + + template + requires behavior::sequenceable + native_persistent_string to_code_string(native_box const s) + { + fmt::memory_buffer buff; + runtime::to_code_string(s, buff); + return native_persistent_string{ buff.data(), buff.size() }; + } } diff --git a/compiler+runtime/include/cpp/jank/runtime/ns.hpp b/compiler+runtime/include/cpp/jank/runtime/ns.hpp index 8eb25661..31589dfc 100644 --- a/compiler+runtime/include/cpp/jank/runtime/ns.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/ns.hpp @@ -36,6 +36,7 @@ namespace jank::runtime /* behavior::object_like */ native_bool equal(object const &) const; native_persistent_string to_string() const; + native_persistent_string to_code_string() const; void to_string(fmt::memory_buffer &buff) const; native_hash to_hash() const; diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/array_chunk.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/array_chunk.hpp index eaa64175..3d11bcde 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/array_chunk.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/array_chunk.hpp @@ -18,6 +18,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::chunk_like */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/atom.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/atom.hpp index 427c4c2b..cbcb3491 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/atom.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/atom.hpp @@ -14,6 +14,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::derefable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/character.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/character.hpp index 5381e5aa..618933a0 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/character.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/character.hpp @@ -17,7 +17,8 @@ namespace jank::runtime /* behavior::object_like */ native_bool equal(object const &) const; - native_persistent_string const &to_string() const; + native_persistent_string to_string() const; + native_persistent_string to_code_string() const; void to_string(fmt::memory_buffer &buff) const; native_hash to_hash() const; diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/chunk_buffer.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/chunk_buffer.hpp index a716293f..d4689235 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/chunk_buffer.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/chunk_buffer.hpp @@ -23,6 +23,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::countable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/chunked_cons.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/chunked_cons.hpp index 3b6097ac..e6035f55 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/chunked_cons.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/chunked_cons.hpp @@ -17,6 +17,7 @@ namespace jank::runtime native_bool equal(object const &) const; void to_string(fmt::memory_buffer &buff) const; native_persistent_string to_string() const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::metadatable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/cons.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/cons.hpp index 2ce1f4e8..a8bb3ffb 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/cons.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/cons.hpp @@ -16,6 +16,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::metadatable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/detail/base_persistent_map.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/detail/base_persistent_map.hpp index a6bee457..cc7a1c4e 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/detail/base_persistent_map.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/detail/base_persistent_map.hpp @@ -46,16 +46,32 @@ namespace jank::runtime::obj::detail static void to_string_impl(typename V::const_iterator const &begin, typename V::const_iterator const &end, - fmt::memory_buffer &buff) + fmt::memory_buffer &buff, + native_bool const to_code) { auto inserter(std::back_inserter(buff)); inserter = '{'; for(auto i(begin); i != end; ++i) { auto const pair(*i); - runtime::to_string(pair.first, buff); + if(to_code) + { + runtime::to_code_string(pair.first, buff); + } + else + { + runtime::to_string(pair.first, buff); + } inserter = ' '; - runtime::to_string(pair.second, buff); + + if(to_code) + { + runtime::to_code_string(pair.second, buff); + } + else + { + runtime::to_string(pair.second, buff); + } auto n(i); if(++n != end) { @@ -70,7 +86,8 @@ namespace jank::runtime::obj::detail { to_string_impl(static_cast(this)->data.begin(), static_cast(this)->data.end(), - buff); + buff, + false); } native_persistent_string to_string() const @@ -78,7 +95,18 @@ namespace jank::runtime::obj::detail fmt::memory_buffer buff; to_string_impl(static_cast(this)->data.begin(), static_cast(this)->data.end(), - buff); + buff, + false); + return native_persistent_string{ buff.data(), buff.size() }; + } + + native_persistent_string to_code_string() const + { + fmt::memory_buffer buff; + to_string_impl(static_cast(this)->data.begin(), + static_cast(this)->data.end(), + buff, + true); return native_persistent_string{ buff.data(), buff.size() }; } diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/detail/base_persistent_map_sequence.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/detail/base_persistent_map_sequence.hpp index 54946041..622bad07 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/detail/base_persistent_map_sequence.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/detail/base_persistent_map_sequence.hpp @@ -52,16 +52,30 @@ namespace jank::runtime::obj::detail &o); } - void to_string_impl(fmt::memory_buffer &buff) const + void to_string_impl(fmt::memory_buffer &buff, native_bool const to_code) const { auto inserter(std::back_inserter(buff)); fmt::format_to(inserter, "("); for(auto i(begin); i != end; ++i) { fmt::format_to(inserter, "["); - runtime::to_string((*i).first, buff); + if(to_code) + { + runtime::to_code_string((*i).first, buff); + } + else + { + runtime::to_string((*i).first, buff); + } fmt::format_to(inserter, " "); - runtime::to_string((*i).second, buff); + if(to_code) + { + runtime::to_code_string((*i).second, buff); + } + else + { + runtime::to_string((*i).second, buff); + } fmt::format_to(inserter, "]"); auto n(i); if(++n != end) @@ -74,13 +88,20 @@ namespace jank::runtime::obj::detail void to_string(fmt::memory_buffer &buff) const { - return to_string_impl(buff); + return to_string_impl(buff, false); } native_persistent_string to_string() const { fmt::memory_buffer buff; - to_string_impl(buff); + to_string_impl(buff, false); + return native_persistent_string{ buff.data(), buff.size() }; + } + + native_persistent_string to_code_string() const + { + fmt::memory_buffer buff; + to_string_impl(buff, true); return native_persistent_string{ buff.data(), buff.size() }; } diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/detail/iterator_sequence.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/detail/iterator_sequence.hpp index 252e6370..5583dc5e 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/detail/iterator_sequence.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/detail/iterator_sequence.hpp @@ -61,6 +61,13 @@ namespace jank::runtime::obj::detail return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string(begin, end, "(", ')', buff); + return native_persistent_string{ buff.data(), buff.size() }; + } + native_hash to_hash() const { return hash::ordered(begin, end); diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/iterator.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/iterator.hpp index 4f087abf..802a4e50 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/iterator.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/iterator.hpp @@ -24,6 +24,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string(); void to_string(fmt::memory_buffer &buff); + native_persistent_string to_code_string(); native_hash to_hash() const; /* behavior::seqable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/jit_function.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/jit_function.hpp index 3d216290..2ef6dc23 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/jit_function.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/jit_function.hpp @@ -21,6 +21,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string(); void to_string(fmt::memory_buffer &buff); + native_persistent_string to_code_string(); native_hash to_hash() const; /* behavior::metadatable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/keyword.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/keyword.hpp index 6d32c5ac..3b337d60 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/keyword.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/keyword.hpp @@ -31,6 +31,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::comparable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/lazy_sequence.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/lazy_sequence.hpp index 35ef1475..ecd09bb0 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/lazy_sequence.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/lazy_sequence.hpp @@ -26,6 +26,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::seqable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/multi_function.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/multi_function.hpp index 4a497a08..f0b92d69 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/multi_function.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/multi_function.hpp @@ -29,6 +29,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string(); void to_string(fmt::memory_buffer &buff); + native_persistent_string to_code_string(); native_hash to_hash() const; /* behavior::callable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/native_array_sequence.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/native_array_sequence.hpp index 479b4a51..cf37afe4 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/native_array_sequence.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/native_array_sequence.hpp @@ -25,6 +25,7 @@ namespace jank::runtime native_bool equal(object const &o) const; void to_string(fmt::memory_buffer &buff) const; native_persistent_string to_string() const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::seqable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/native_function_wrapper.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/native_function_wrapper.hpp index c31b8659..c44f9b5f 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/native_function_wrapper.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/native_function_wrapper.hpp @@ -76,6 +76,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::callable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/native_vector_sequence.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/native_vector_sequence.hpp index 39362331..2e7ec883 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/native_vector_sequence.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/native_vector_sequence.hpp @@ -19,6 +19,7 @@ namespace jank::runtime native_bool equal(object const &o) const; void to_string(fmt::memory_buffer &buff) const; native_persistent_string to_string() const; + native_persistent_string to_code_string() const; native_hash to_hash(); /* behavior::seqable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/nil.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/nil.hpp index cdc8d056..fd202736 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/nil.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/nil.hpp @@ -24,6 +24,7 @@ namespace jank::runtime /* behavior::object_like */ native_bool equal(object const &) const; native_persistent_string const &to_string() const; + native_persistent_string const &to_code_string() const; void to_string(fmt::memory_buffer &buff) const; native_hash to_hash() const; diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/number.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/number.hpp index 0877dc52..dd3ffab3 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/number.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/number.hpp @@ -19,6 +19,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::comparable */ @@ -45,6 +46,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::comparable */ @@ -75,6 +77,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::comparable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_hash_set.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_hash_set.hpp index d151bad4..0e58d734 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_hash_set.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_hash_set.hpp @@ -50,6 +50,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::metadatable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_list.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_list.hpp index 07eb3467..fa55592c 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_list.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_list.hpp @@ -51,6 +51,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::metadatable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_sorted_set.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_sorted_set.hpp index d2036fd3..78265ad5 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_sorted_set.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_sorted_set.hpp @@ -50,6 +50,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::metadatable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_string.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_string.hpp index 11c92100..1aa5675d 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_string.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_string.hpp @@ -27,6 +27,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string const &to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::comparable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_string_sequence.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_string_sequence.hpp index 2577edea..3c6e57cf 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_string_sequence.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_string_sequence.hpp @@ -23,6 +23,7 @@ namespace jank::runtime native_bool equal(object const &) const; void to_string(fmt::memory_buffer &buff) const; native_persistent_string to_string() const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::countable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_vector.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_vector.hpp index 26ae8c82..9f8bc301 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_vector.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_vector.hpp @@ -52,6 +52,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::comparable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_vector_sequence.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_vector_sequence.hpp index 0227e755..c38f0db7 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/persistent_vector_sequence.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/persistent_vector_sequence.hpp @@ -24,6 +24,7 @@ namespace jank::runtime native_bool equal(object const &) const; void to_string(fmt::memory_buffer &buff) const; native_persistent_string to_string() const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::countable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/range.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/range.hpp index 9c77bac4..b675caa5 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/range.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/range.hpp @@ -38,6 +38,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string(); void to_string(fmt::memory_buffer &buff); + native_persistent_string to_code_string(); native_hash to_hash() const; /* behavior::seqable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/reduced.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/reduced.hpp index f2f56a5d..c6a3eb89 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/reduced.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/reduced.hpp @@ -14,6 +14,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::derefable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/symbol.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/symbol.hpp index 44316004..a8c742c6 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/symbol.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/symbol.hpp @@ -33,6 +33,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::object_like extended */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/transient_hash_map.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/transient_hash_map.hpp index 8d0c5f93..0a7f81be 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/transient_hash_map.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/transient_hash_map.hpp @@ -28,6 +28,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::countable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/transient_hash_set.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/transient_hash_set.hpp index b5e24db8..7481f775 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/transient_hash_set.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/transient_hash_set.hpp @@ -26,6 +26,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::countable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/transient_sorted_map.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/transient_sorted_map.hpp index de1990b4..5f3e61e1 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/transient_sorted_map.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/transient_sorted_map.hpp @@ -28,6 +28,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::countable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/transient_sorted_set.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/transient_sorted_set.hpp index ac497c9a..d6a4bee6 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/transient_sorted_set.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/transient_sorted_set.hpp @@ -26,6 +26,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::countable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/transient_vector.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/transient_vector.hpp index 781dd94d..f3fd961a 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/transient_vector.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/transient_vector.hpp @@ -26,6 +26,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::countable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/volatile.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/volatile.hpp index 135e1f82..04106323 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/volatile.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/volatile.hpp @@ -14,6 +14,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; /* behavior::derefable */ diff --git a/compiler+runtime/include/cpp/jank/runtime/object.hpp b/compiler+runtime/include/cpp/jank/runtime/object.hpp index dff0eba6..701b141a 100644 --- a/compiler+runtime/include/cpp/jank/runtime/object.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/object.hpp @@ -108,6 +108,9 @@ namespace jank::runtime { t->to_string() } -> std::convertible_to; { t->to_string(std::declval()) } -> std::same_as; + /* Returns the code representation of the object. */ + { t->to_code_string() } -> std::convertible_to; + /* Returns a deterministic hash value for the object. For some objects, like functions * and transients, the hash is actually just the object's address. For others, it's * based on the value, or values, within the object. There are a set of hash functions diff --git a/compiler+runtime/include/cpp/jank/runtime/var.hpp b/compiler+runtime/include/cpp/jank/runtime/var.hpp index cf34b2d4..cde3da1e 100644 --- a/compiler+runtime/include/cpp/jank/runtime/var.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/var.hpp @@ -29,6 +29,7 @@ namespace jank::runtime /* behavior::object_like */ native_bool equal(object const &) const; native_persistent_string to_string() const; + native_persistent_string to_code_string() const; void to_string(fmt::memory_buffer &buff) const; native_hash to_hash() const; @@ -87,6 +88,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; object base{ object_type::var_thread_binding }; @@ -113,6 +115,7 @@ namespace jank::runtime native_bool equal(object const &) const; native_persistent_string to_string() const; void to_string(fmt::memory_buffer &buff) const; + native_persistent_string to_code_string() const; native_hash to_hash() const; object base{ object_type::var_unbound_root }; diff --git a/compiler+runtime/src/cpp/jank/read/lex.cpp b/compiler+runtime/src/cpp/jank/read/lex.cpp index efd1272c..d922a7fa 100644 --- a/compiler+runtime/src/cpp/jank/read/lex.cpp +++ b/compiler+runtime/src/cpp/jank/read/lex.cpp @@ -310,18 +310,18 @@ namespace jank::read pos++; } - native_persistent_string_view const data{ file.data() + token_start, - ++pos - token_start }; + native_persistent_string_view const data{ file.data() + token_start + 1, + ++pos - token_start - 1}; - if(data.size() == 2 || data == "\\newline" || data == "\\backspace" || data == "\\space" - || data == "\\formfeed" || data == "\\return" || data == "\\tab") + if(data.size() == 1 || data == "newline" || data == "backspace" || data == "space" + || data == "formfeed" || data == "return" || data == "tab") { return ok(token{ token_start, pos - token_start, token_kind::character, data }); } return err(error{ token_start, pos - token_start, - fmt::format("Invalid character literal `{}` \nNote: Jank " + fmt::format("Invalid character literal `\\{}` \nNote: Jank " "doesn't support unicode characters yet!", data) }); } diff --git a/compiler+runtime/src/cpp/jank/runtime/core/to_string.cpp b/compiler+runtime/src/cpp/jank/runtime/core/to_string.cpp index dabc5248..7ad72bfd 100644 --- a/compiler+runtime/src/cpp/jank/runtime/core/to_string.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/core/to_string.cpp @@ -16,4 +16,21 @@ namespace jank::runtime { visit_object([&](auto const typed_o) { typed_o->to_string(buff); }, o); } + + native_persistent_string to_code_string(object const * const o) + { + return visit_object([](auto const typed_o) { return typed_o->to_code_string(); }, o); + } + + void to_code_string(char const ch, fmt::memory_buffer &buff) + { + fmt::format_to(std::back_inserter(buff), "{}", obj::character{ ch }.to_code_string()); + } + + void to_code_string(object_ptr const o, fmt::memory_buffer &buff) + { + auto const value{ visit_object([](auto const typed_o) { return typed_o->to_code_string(); }, + o) }; + fmt::format_to(std::back_inserter(buff), "{}", value); + } } diff --git a/compiler+runtime/src/cpp/jank/runtime/ns.cpp b/compiler+runtime/src/cpp/jank/runtime/ns.cpp index 99f53498..704dcdc9 100644 --- a/compiler+runtime/src/cpp/jank/runtime/ns.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/ns.cpp @@ -124,6 +124,11 @@ namespace jank::runtime return name->to_string(); } + native_persistent_string ns::to_code_string() const + { + return to_string(); + } + void ns::to_string(fmt::memory_buffer &buff) const { name->to_string(buff); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/array_chunk.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/array_chunk.cpp index 55a19620..3b2f11d2 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/array_chunk.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/array_chunk.cpp @@ -39,6 +39,11 @@ namespace jank::runtime fmt::ptr(&base)); } + native_persistent_string obj::array_chunk::to_code_string() const + { + return to_string(); + } + native_hash obj::array_chunk::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/atom.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/atom.cpp index 107bc816..a6484f8e 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/atom.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/atom.cpp @@ -28,6 +28,11 @@ namespace jank::runtime fmt::ptr(&base)); } + native_persistent_string obj::atom::to_code_string() const + { + return to_string(); + } + native_hash obj::atom::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/character.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/character.cpp index 355fbfef..015e8f0b 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/character.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/character.cpp @@ -1,34 +1,35 @@ #include +#include namespace jank::runtime { - static option get_char_from_repr(native_persistent_string const &sv) + static option get_char_from_literal(native_persistent_string const &sv) { - if(sv.size() == 2) + if(sv.size() == 1) { - return sv[1]; + return sv[0]; } - else if(sv == "\\newline") + else if(sv == "newline") { return '\n'; } - else if(sv == "\\space") + else if(sv == "space") { return ' '; } - else if(sv == "\\tab") + else if(sv == "tab") { return '\t'; } - else if(sv == "\\backspace") + else if(sv == "backspace") { return '\b'; } - else if(sv == "\\formfeed") + else if(sv == "formfeed") { return '\f'; } - else if(sv == "\\return") + else if(sv == "return") { return '\r'; } @@ -36,24 +37,24 @@ namespace jank::runtime return none; } - static native_persistent_string get_repr_from_char(char const ch) + static native_persistent_string get_literal_from_char(char const ch) { switch(ch) { case '\n': - return "\\newline"; + return "newline"; case ' ': - return "\\space"; + return "space"; case '\t': - return "\\tab"; + return "tab"; case '\b': - return "\\backspace"; + return "backspace"; case '\f': - return "\\formfeed"; + return "formfeed"; case '\r': - return "\\return"; + return "return"; default: - return fmt::format("\\{}", ch); + return fmt::format("{}", ch); } } @@ -63,7 +64,7 @@ namespace jank::runtime } obj::character::static_object(char const ch) - : data{ get_repr_from_char(ch) } + : data{ get_literal_from_char(ch) } { } @@ -81,16 +82,22 @@ namespace jank::runtime void obj::character::to_string(fmt::memory_buffer &buff) const { /* TODO: This is actually to_representation, since the string version of \a is just a. */ - fmt::format_to(std::back_inserter(buff), "{}", data); + fmt::format_to(std::back_inserter(buff), "{}", get_char_from_literal(data).unwrap()); } - native_persistent_string const &obj::character::to_string() const + native_persistent_string obj::character::to_string() const { - return data; + auto const char_repr{get_char_from_literal(data).unwrap()}; + return native_persistent_string{1, char_repr}; + } + + native_persistent_string obj::character::to_code_string() const + { + return fmt::format("\\{}", data); } native_hash obj::character::to_hash() const { - return hash::visit(get_char_from_repr(data).unwrap()); + return hash::visit(get_char_from_literal(data).unwrap()); } } diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/chunk_buffer.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/chunk_buffer.cpp index e7cc1194..e142d102 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/chunk_buffer.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/chunk_buffer.cpp @@ -39,6 +39,11 @@ namespace jank::runtime fmt::ptr(&base)); } + native_persistent_string obj::chunk_buffer::to_code_string() const + { + return to_string(); + } + native_hash obj::chunk_buffer::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/chunked_cons.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/chunked_cons.cpp index a0ad05ce..a0928a61 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/chunked_cons.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/chunked_cons.cpp @@ -186,6 +186,11 @@ namespace jank::runtime return runtime::to_string(seq()); } + native_persistent_string obj::chunked_cons::to_code_string() const + { + return runtime::to_code_string(seq()); + } + native_hash obj::chunked_cons::to_hash() const { return hash::ordered(&base); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/cons.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/cons.cpp index 1a096707..8edaf7e3 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/cons.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/cons.cpp @@ -102,6 +102,11 @@ namespace jank::runtime return runtime::to_string(seq()); } + native_persistent_string obj::cons::to_code_string() const + { + return runtime::to_code_string(seq()); + } + native_hash obj::cons::to_hash() const { if(hash != 0) diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/iterator.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/iterator.cpp index 7672c274..2012eba3 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/iterator.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/iterator.cpp @@ -90,6 +90,11 @@ namespace jank::runtime return runtime::to_string(seq()); } + native_persistent_string obj::iterator::to_code_string() + { + return runtime::to_code_string(seq()); + } + native_hash obj::iterator::to_hash() const { return hash::ordered(&base); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/jit_function.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/jit_function.cpp index b744f870..76b1f7c8 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/jit_function.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/jit_function.cpp @@ -32,6 +32,11 @@ namespace jank::runtime fmt::ptr(&base)); } + native_persistent_string obj::jit_function::to_code_string() + { + return to_string(); + } + native_hash obj::jit_function::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/keyword.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/keyword.cpp index 609e78f8..02f17b64 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/keyword.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/keyword.cpp @@ -41,6 +41,11 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::keyword::to_code_string() const + { + return to_string(); + } + native_hash obj::keyword::to_hash() const { return sym.to_hash() + 0x9e3779b9; diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/lazy_sequence.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/lazy_sequence.cpp index e6ac61aa..50781b65 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/lazy_sequence.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/lazy_sequence.cpp @@ -106,6 +106,11 @@ namespace jank::runtime return runtime::to_string(seq()); } + native_persistent_string obj::lazy_sequence::to_code_string() const + { + return runtime::to_code_string(seq()); + } + native_hash obj::lazy_sequence::to_hash() const { auto const s(seq()); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/multi_function.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/multi_function.cpp index 9ff9aae1..da8b9177 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/multi_function.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/multi_function.cpp @@ -37,6 +37,11 @@ namespace jank::runtime fmt::ptr(&base)); } + native_persistent_string obj::multi_function::to_code_string() + { + return to_string(); + } + native_hash obj::multi_function::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/native_array_sequence.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/native_array_sequence.cpp index 7f753dbc..9c17925e 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/native_array_sequence.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/native_array_sequence.cpp @@ -39,6 +39,13 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::native_array_sequence::to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string(arr + index, arr + size, "(", ')', buff); + return native_persistent_string{ buff.data(), buff.size() }; + } + native_hash obj::native_array_sequence::to_hash() const { return hash::ordered(arr + index, arr + size); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/native_function_wrapper.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/native_function_wrapper.cpp index af2d5bd0..cdc10a5a 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/native_function_wrapper.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/native_function_wrapper.cpp @@ -34,6 +34,11 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::native_function_wrapper::to_code_string() const + { + return to_string(); + } + native_hash obj::native_function_wrapper::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/native_vector_sequence.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/native_vector_sequence.cpp index bde7f902..e3db689e 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/native_vector_sequence.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/native_vector_sequence.cpp @@ -40,6 +40,13 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::native_vector_sequence::to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string(data.begin(), data.end(), "(", ')', buff); + return native_persistent_string{ buff.data(), buff.size() }; + } + native_hash obj::native_vector_sequence::to_hash() { return hash::ordered(data.begin(), data.end()); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/nil.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/nil.cpp index 1ae8d26a..060117ca 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/nil.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/nil.cpp @@ -19,6 +19,11 @@ namespace jank::runtime return s; } + native_persistent_string const &obj::nil::to_code_string() const + { + return to_string(); + } + void obj::nil::to_string(fmt::memory_buffer &buff) const { fmt::format_to(std::back_inserter(buff), "nil"); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/number.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/number.cpp index e591f156..d5ab70b9 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/number.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/number.cpp @@ -54,6 +54,11 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::boolean::to_code_string() const + { + return to_string(); + } + native_hash obj::boolean::to_hash() const { return data ? 1231 : 1237; @@ -103,6 +108,11 @@ namespace jank::runtime fmt::format_to(std::back_inserter(buff), FMT_COMPILE("{}"), data); } + native_persistent_string obj::integer::to_code_string() const + { + return to_string(); + } + native_hash obj::integer::to_hash() const { return hash::integer(data); @@ -163,6 +173,11 @@ namespace jank::runtime fmt::format_to(std::back_inserter(buff), FMT_COMPILE("{}"), data); } + native_persistent_string obj::real::to_code_string() const + { + return to_string(); + } + native_hash obj::real::to_hash() const { return hash::real(data); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_hash_set.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_hash_set.cpp index e17eb54b..b8edb050 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_hash_set.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_hash_set.cpp @@ -59,6 +59,13 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::persistent_hash_set::to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string(data.begin(), data.end(), "#{", '}', buff); + return native_persistent_string{ buff.data(), buff.size() }; + } + /* TODO: Cache this. */ native_hash obj::persistent_hash_set::to_hash() const { diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_list.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_list.cpp index ac894d32..f0e15f7e 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_list.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_list.cpp @@ -63,6 +63,13 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::persistent_list::to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string(data.begin(), data.end(), "(", ')', buff); + return native_persistent_string{ buff.data(), buff.size() }; + } + /* TODO: Cache this. */ native_hash obj::persistent_list::to_hash() const { diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_sorted_set.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_sorted_set.cpp index 952ba074..60d9fc25 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_sorted_set.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_sorted_set.cpp @@ -59,6 +59,13 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::persistent_sorted_set::to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string(data.begin(), data.end(), "#{", '}', buff); + return native_persistent_string{ buff.data(), buff.size() }; + } + /* TODO: Cache this. */ native_hash obj::persistent_sorted_set::to_hash() const { diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_string.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_string.cpp index 4b9583d2..0978e2ba 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_string.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_string.cpp @@ -1,6 +1,3 @@ -#include -#include - #include #include @@ -39,6 +36,11 @@ namespace jank::runtime fmt::format_to(std::back_inserter(buff), FMT_COMPILE("{}"), data); } + native_persistent_string obj::persistent_string::to_code_string() const + { + return fmt::format(R"("{}")", util::escape(to_string())); + } + native_hash obj::persistent_string::to_hash() const { return data.to_hash(); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_string_sequence.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_string_sequence.cpp index dfbf31a6..120a7c50 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_string_sequence.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_string_sequence.cpp @@ -33,6 +33,13 @@ namespace jank::runtime return { buff.data(), buff.size() }; } + native_persistent_string obj::persistent_string_sequence::to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string(str->data.begin() + index, str->data.end(), "(", ')', buff); + return { buff.data(), buff.size() }; + } + native_hash obj::persistent_string_sequence::to_hash() const { return hash::ordered(str->data.begin() + index, str->data.end()); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector.cpp index dc1d586e..bb3bc75e 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector.cpp @@ -65,6 +65,13 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::persistent_vector::to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string(data.begin(), data.end(), "[", ']', buff); + return native_persistent_string{ buff.data(), buff.size() }; + } + native_hash obj::persistent_vector::to_hash() const { if(hash != 0) diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector_sequence.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector_sequence.cpp index 1d96cb1f..b4314b2c 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector_sequence.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/persistent_vector_sequence.cpp @@ -50,6 +50,19 @@ namespace jank::runtime return { buff.data(), buff.size() }; } + native_persistent_string obj::persistent_vector_sequence::to_code_string() const + { + fmt::memory_buffer buff; + runtime::to_code_string( + vec->data.begin() + + static_cast(index), + vec->data.end(), + "(", + ')', + buff); + return { buff.data(), buff.size() }; + } + native_hash obj::persistent_vector_sequence::to_hash() const { return hash::ordered( diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/range.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/range.cpp index 51b47471..2a789dc7 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/range.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/range.cpp @@ -234,6 +234,11 @@ namespace jank::runtime return runtime::to_string(seq()); } + native_persistent_string obj::range::to_code_string() + { + return runtime::to_code_string(seq()); + } + native_hash obj::range::to_hash() const { return hash::ordered(&base); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/reduced.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/reduced.cpp index b253048a..249031fb 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/reduced.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/reduced.cpp @@ -28,6 +28,11 @@ namespace jank::runtime fmt::ptr(&base)); } + native_persistent_string obj::reduced::to_code_string() const + { + return to_string(); + } + native_hash obj::reduced::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/symbol.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/symbol.cpp index b9ff2863..bade0765 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/symbol.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/symbol.cpp @@ -126,6 +126,11 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::symbol::to_code_string() const + { + return to_string(); + } + native_hash obj::symbol::to_hash() const { if(hash) diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/transient_hash_map.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/transient_hash_map.cpp index f2dce956..91c7e462 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/transient_hash_map.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/transient_hash_map.cpp @@ -36,6 +36,11 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::transient_hash_map::to_code_string() const + { + return to_string(); + } + native_hash obj::transient_hash_map::to_hash() const { /* Hash is also based only on identity. Clojure uses default hashCode, which does the same. */ diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/transient_hash_set.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/transient_hash_set.cpp index 5df82261..88f99085 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/transient_hash_set.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/transient_hash_set.cpp @@ -34,6 +34,11 @@ namespace jank::runtime fmt::format_to(inserter, "{}@{}", magic_enum::enum_name(base.type), fmt::ptr(&base)); } + native_persistent_string obj::transient_hash_set::to_code_string() const + { + return to_string(); + } + native_hash obj::transient_hash_set::to_hash() const { /* Hash is also based only on identity. Clojure uses default hashCode, which does the same. */ diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/transient_sorted_map.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/transient_sorted_map.cpp index 05bb6709..dc3e1adb 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/transient_sorted_map.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/transient_sorted_map.cpp @@ -36,6 +36,11 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string obj::transient_sorted_map::to_code_string() const + { + return to_string(); + } + native_hash obj::transient_sorted_map::to_hash() const { /* Hash is also based only on identity. Clojure uses default hashCode, which does the same. */ diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/transient_sorted_set.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/transient_sorted_set.cpp index be7f338b..9622d863 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/transient_sorted_set.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/transient_sorted_set.cpp @@ -34,6 +34,11 @@ namespace jank::runtime fmt::format_to(inserter, "{}@{}", magic_enum::enum_name(base.type), fmt::ptr(&base)); } + native_persistent_string obj::transient_sorted_set::to_code_string() const + { + return to_string(); + } + native_hash obj::transient_sorted_set::to_hash() const { /* Hash is also based only on identity. Clojure uses default hashCode, which does the same. */ diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/transient_vector.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/transient_vector.cpp index 7d0f4c74..57fa26b5 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/transient_vector.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/transient_vector.cpp @@ -34,6 +34,11 @@ namespace jank::runtime fmt::format_to(inserter, "{}@{}", magic_enum::enum_name(base.type), fmt::ptr(&base)); } + native_persistent_string obj::transient_vector::to_code_string() const + { + return to_string(); + } + native_hash obj::transient_vector::to_hash() const { /* Hash is also based only on identity. Clojure uses default hashCode, which does the same. */ diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/volatile.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/volatile.cpp index 34fcccfc..f0034573 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/volatile.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/volatile.cpp @@ -28,6 +28,11 @@ namespace jank::runtime fmt::ptr(&base)); } + native_persistent_string obj::volatile_::to_code_string() const + { + return to_string(); + } + native_hash obj::volatile_::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/jank/runtime/var.cpp b/compiler+runtime/src/cpp/jank/runtime/var.cpp index 14848e23..9e132e90 100644 --- a/compiler+runtime/src/cpp/jank/runtime/var.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/var.cpp @@ -66,6 +66,11 @@ namespace jank::runtime return native_persistent_string{ buff.data(), buff.size() }; } + native_persistent_string var::to_code_string() const + { + return to_string(); + } + native_hash var::to_hash() const { if(hash) @@ -190,6 +195,11 @@ namespace jank::runtime return runtime::to_string(value); } + native_persistent_string var_thread_binding::to_code_string() const + { + return var_thread_binding::to_string(); + } + void var_thread_binding::to_string(fmt::memory_buffer &buff) const { runtime::to_string(value, buff); @@ -225,6 +235,11 @@ namespace jank::runtime var->to_string()); } + native_persistent_string var_unbound_root::to_code_string() const + { + return var_unbound_root::to_string(); + } + native_hash var_unbound_root::to_hash() const { return static_cast(reinterpret_cast(this)); diff --git a/compiler+runtime/src/cpp/main.cpp b/compiler+runtime/src/cpp/main.cpp index 7cc70c78..b93b7540 100644 --- a/compiler+runtime/src/cpp/main.cpp +++ b/compiler+runtime/src/cpp/main.cpp @@ -145,8 +145,7 @@ namespace jank try { auto const res(__rt_ctx->eval_string(line)); - fmt::println(""); - fmt::println("{}", runtime::to_string(res)); + fmt::println("{}", runtime::to_code_string(res)); } /* TODO: Unify error handling. JEEZE! */ catch(std::exception const &e) diff --git a/compiler+runtime/src/jank/clojure/core.jank b/compiler+runtime/src/jank/clojure/core.jank index 5f94aaee..edba65e8 100644 --- a/compiler+runtime/src/jank/clojure/core.jank +++ b/compiler+runtime/src/jank/clojure/core.jank @@ -184,8 +184,9 @@ res))))) ;; Strings. -; TODO: Proper version. -(def pr-str) +(def pr-str + (fn* pr-str [o] + (native/raw "__value = make_box(runtime::to_code_string(~{ o }))"))) (def string? (fn* string? [o] @@ -1132,9 +1133,6 @@ ; Strings. -; TODO: Proper version. -(def pr-str str) - (defn subs ([s start] (native/raw "__value = runtime::subs(~{ s }, ~{ start });")) @@ -1828,10 +1826,6 @@ (defn print [o] (native/raw "__value = jank::runtime::context::print(~{ o });")) -(defn pr-str [o] - ; TODO: Representation printing. - (str o)) - (defn prn [o] ; TODO: Representation printing. (println o)) diff --git a/compiler+runtime/test/cpp/jank/read/lex.cpp b/compiler+runtime/test/cpp/jank/read/lex.cpp index 240a04a4..d0544f27 100644 --- a/compiler+runtime/test/cpp/jank/read/lex.cpp +++ b/compiler+runtime/test/cpp/jank/read/lex.cpp @@ -606,7 +606,7 @@ namespace jank::read::lex native_vector> tokens(p.begin(), p.end()); CHECK(tokens == make_tokens({ - { 0, 2, token_kind::character, "\\a"sv } + { 0, 2, token_kind::character, "a"sv } })); } @@ -616,7 +616,7 @@ namespace jank::read::lex native_vector> tokens(p.begin(), p.end()); CHECK(tokens == make_tokens({ - { 0, 2, token_kind::character, "\\1"sv } + { 0, 2, token_kind::character, "1"sv } })); } @@ -637,7 +637,7 @@ namespace jank::read::lex native_vector> tokens(p.begin(), p.end()); CHECK(tokens == make_results({ - token{ 0, 2, token_kind::character, "\\1"sv }, + token{ 0, 2, token_kind::character, "1"sv }, error{ 2, "invalid keyword: expected non-whitespace character after :" } })); } @@ -648,10 +648,10 @@ namespace jank::read::lex native_vector> tokens(p.begin(), p.end()); CHECK(tokens == make_tokens({ - { 0, 2, token_kind::character, "\\1"sv }, - { 3, 8, token_kind::character, "\\newline"sv }, - { 11, 2, token_kind::character, "\\'"sv }, - { 14, 2, token_kind::character, "\\\\"sv } + { 0, 2, token_kind::character, "1"sv }, + { 3, 8, token_kind::character, "newline"sv }, + { 11, 2, token_kind::character, "'"sv }, + { 14, 2, token_kind::character, "\\"sv } })); } @@ -661,7 +661,7 @@ namespace jank::read::lex native_vector> tokens(p.begin(), p.end()); CHECK(tokens == make_results({ - token{ 0, 2, token_kind::character, "\\a"sv }, + token{ 0, 2, token_kind::character, "a"sv }, token{ 2, token_kind::syntax_quote }, token{ 3, 3, token_kind::keyword, "kw"sv } })); diff --git a/compiler+runtime/test/cpp/jank/read/parse.cpp b/compiler+runtime/test/cpp/jank/read/parse.cpp index 158ca8ff..ce44d38f 100644 --- a/compiler+runtime/test/cpp/jank/read/parse.cpp +++ b/compiler+runtime/test/cpp/jank/read/parse.cpp @@ -92,7 +92,7 @@ namespace jank::read::parse processor p{ lp.begin(), lp.end() }; size_t offset{}; - for(native_persistent_string const &ch : { "\\a", "\\1", "\\`", "\\:", "\\#" }) + for(native_persistent_string const &ch : { "a", "1", "`", ":", "#" }) { auto const r(p.next()); CHECK(equal(r.expect_ok().unwrap().ptr, make_box(ch))); @@ -113,12 +113,12 @@ namespace jank::read::parse size_t offset{}; for(native_persistent_string const &ch : - { "\\newline", "\\backspace", "\\return", "\\formfeed", "\\tab", "\\space" }) + { "newline", "backspace", "return", "formfeed", "tab", "space" }) { auto const r(p.next()); CHECK(equal(r.expect_ok().unwrap().ptr, make_box(ch))); - auto const len(ch.size()); + auto const len(ch.size() + 1); CHECK(r.expect_ok().unwrap().start == lex::token{ offset, len, lex::token_kind::character, ch }); CHECK(r.expect_ok().unwrap().end == r.expect_ok().unwrap().start); @@ -134,12 +134,12 @@ namespace jank::read::parse processor p{ lp.begin(), lp.end() }; size_t offset{}; - for(native_persistent_string const &ch : { "\\newline", "\\a", "\\tab", "\\`", "\\space" }) + for(native_persistent_string const &ch : { "newline", "a", "tab", "`", "space" }) { auto const r(p.next()); CHECK(equal(r.expect_ok().unwrap().ptr, make_box(ch))); - auto const len(ch.size()); + auto const len(ch.size() + 1); CHECK(r.expect_ok().unwrap().start == lex::token{ offset, len, lex::token_kind::character, ch }); CHECK(r.expect_ok().unwrap().end == r.expect_ok().unwrap().start);