Skip to content

Commit 7a48f60

Browse files
authored
feat: set parsing syntax quotes (#392)
* Set parsing syntax quotes * update commit sha * Lint * Try again
1 parent a348ef6 commit 7a48f60

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

compiler+runtime/include/cpp/jank/read/parse.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ namespace jank::read::parse
9696
private:
9797
jtl::result<runtime::object_ref, error_ref> syntax_quote(runtime::object_ref form);
9898
jtl::result<runtime::object_ref, error_ref> syntax_quote_expand_seq(runtime::object_ref seq);
99+
jtl::result<runtime::object_ref, error_ref> syntax_quote_expand_set(runtime::object_ref seq);
99100
static jtl::result<runtime::object_ref, error_ref>
100101
syntax_quote_flatten_map(runtime::object_ref seq);
101102
static bool syntax_quote_is_unquote(runtime::object_ref form, bool splice);

compiler+runtime/src/cpp/jank/read/parse.cpp

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,51 @@ namespace jank::read::parse
983983
seq);
984984
}
985985

986+
jtl::result<object_ref, error_ref> processor::syntax_quote_expand_set(object_ref const seq)
987+
{
988+
if(seq.is_nil())
989+
{
990+
return seq;
991+
}
992+
993+
return visit_seqable(
994+
[this](auto const typed_seq) -> jtl::result<object_ref, error_ref> {
995+
runtime::detail::native_transient_vector ret;
996+
for(auto const item : make_sequence_range(typed_seq))
997+
{
998+
if(syntax_quote_is_unquote(item, false))
999+
{
1000+
ret.push_back(
1001+
make_box<obj::persistent_list>(std::in_place,
1002+
make_box<obj::symbol>("clojure.core", "list"),
1003+
second(item)));
1004+
}
1005+
else if(syntax_quote_is_unquote(item, true))
1006+
{
1007+
ret.push_back(second(item));
1008+
}
1009+
else
1010+
{
1011+
auto quoted_item(syntax_quote(item));
1012+
if(quoted_item.is_err())
1013+
{
1014+
return quoted_item;
1015+
}
1016+
ret.push_back(
1017+
make_box<obj::persistent_list>(std::in_place,
1018+
make_box<obj::symbol>("clojure.core", "list"),
1019+
quoted_item.expect_ok()));
1020+
}
1021+
}
1022+
auto const vec(make_box<obj::persistent_vector>(ret.persistent())->seq());
1023+
return vec;
1024+
},
1025+
[]() -> jtl::result<object_ref, error_ref> {
1026+
return err(error::internal_parse_failure("syntax_quote_expand_seq arg not seqable."));
1027+
},
1028+
seq);
1029+
}
1030+
9861031
bool processor::syntax_quote_is_unquote(object_ref const form, bool const splice)
9871032
{
9881033
return visit_seqable(
@@ -1118,7 +1163,27 @@ namespace jank::read::parse
11181163
}
11191164
if constexpr(behavior::set_like<T>)
11201165
{
1121-
return err(error::internal_parse_failure("nyi: set"));
1166+
auto const seq(typed_form->seq());
1167+
if(seq.is_nil())
1168+
{
1169+
return make_box<obj::persistent_list>(
1170+
std::in_place,
1171+
make_box<obj::symbol>("clojure.core", "hash-set"));
1172+
}
1173+
auto expanded(syntax_quote_expand_seq(seq));
1174+
if(expanded.is_err())
1175+
{
1176+
return expanded;
1177+
}
1178+
1179+
return make_box<obj::persistent_list>(
1180+
std::in_place,
1181+
make_box<obj::symbol>("clojure.core", "apply*"),
1182+
make_box<obj::symbol>("clojure.core", "hash-set"),
1183+
make_box<obj::persistent_list>(
1184+
std::in_place,
1185+
make_box<obj::symbol>("clojure.core", "seq"),
1186+
cons(make_box<obj::symbol>("clojure.core", "concat*"), expanded.expect_ok())));
11221187
}
11231188
if constexpr(behavior::sequenceable<T>)
11241189
{

compiler+runtime/test/jank/syntax-quote/pass-unaffected.jank

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
(assert (= :syntax-quote.pass-unaffected/bar `::c/bar) `::c/bar)
1414
(assert (= [] `[]) `[])
1515
(assert (= {} `{}) `{})
16+
(assert (= #{} `#{}) `#{})
1617
(assert (= '() `()) `())
1718
(assert (= "meow" `"meow") `"meow")
1819
(assert (= 'foo/meow `foo/meow) `foo/meow)

compiler+runtime/test/jank/syntax-quote/unquote-splice/pass-values.jank

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
a [1 2 3]]
44
(assert (= '(clojure.core/str) `(str ~@e)))
55
(assert (= '(clojure.core/str 1 2 3) `(str ~@a)))
6-
(assert (= [1 2 3 0 1 2 3] `[~@e ~@a ~@b ~@a ~@e])))
6+
(assert (= [1 2 3 0 1 2 3] `[~@e ~@a ~@b ~@a ~@e]))
7+
(assert (= #{1 2 3 0} `#{~@e ~@a ~@b})))
78

89
:success

0 commit comments

Comments
 (0)