Skip to content

Commit

Permalink
Add #' reader macro support
Browse files Browse the repository at this point in the history
  • Loading branch information
jeaye committed Mar 23, 2024
1 parent 571d247 commit 88ecf09
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/cpp/jank/read/parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ namespace jank::read::parse
object_result parse_reader_macro();
object_result parse_reader_macro_set();
object_result parse_reader_macro_fn();
object_result parse_reader_macro_var_quote();
object_result parse_reader_macro_comment();
object_result parse_reader_macro_conditional(native_bool splice);
object_result parse_syntax_quote();
Expand Down
2 changes: 1 addition & 1 deletion src/cpp/jank/analyze/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ namespace jank::analyze
auto const found_var(rt_ctx.find_var(qualified_sym));
if(found_var.is_none())
{
return err(error{ "invalid var reference: var not found" });
return err(error{ fmt::format("unable to resolve var: {}", qualified_sym->to_string()) });
}

return make_box<expression>(expr::var_ref<expression>{
Expand Down
33 changes: 33 additions & 0 deletions src/cpp/jank/read/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ namespace jank::read::parse
return parse_reader_macro_set();
case lex::token_kind::open_paren:
return parse_reader_macro_fn();
case lex::token_kind::single_quote:
return parse_reader_macro_var_quote();
default:
return err(
error{ start_token.pos, native_persistent_string{ "unsupported reader macro" } });
Expand Down Expand Up @@ -544,6 +546,37 @@ namespace jank::read::parse
return object_source_info{ wrapped, start_token, call_end };
}

processor::object_result processor::parse_reader_macro_var_quote()
{
auto const start_token(token_current.latest.unwrap().expect_ok());
++token_current;

auto sym_result(next());
if(sym_result.is_err())
{
return sym_result;
}
else if(sym_result.expect_ok().is_none())
{
return err(
error{ start_token.pos, native_persistent_string{ "value after #' must be present" } });
}
else if(sym_result.expect_ok().unwrap().ptr->type != runtime::object_type::symbol)
{
return err(
error{ start_token.pos, native_persistent_string{ "value after #' must be a symbol" } });
}

auto const sym(
runtime::expect_object<runtime::obj::symbol>(sym_result.expect_ok().unwrap().ptr));
auto const sym_end(sym_result.expect_ok().unwrap().end);

auto const wrapped(
make_box<runtime::obj::list>(std::in_place, make_box<runtime::obj::symbol>("var"), sym));

return object_source_info{ wrapped, start_token, sym_end };
}

processor::object_result processor::parse_reader_macro_comment()
{
auto const start_token(token_current.latest.unwrap().expect_ok());
Expand Down
4 changes: 4 additions & 0 deletions src/jank/clojure/core.jank
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
(fn* unquote [_]
(throw "~@ cannot be used outside of syntax quote")))

(def type
(fn* type [o]
(native/raw "__value = make_box(magic_enum::enum_name(~{ o }->type));")))

; Exceptions
(def ex-info
(fn* ex-info [msg map]
Expand Down
1 change: 1 addition & 0 deletions test/jank/reader-macro/function/fail-eof.jank
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#(
1 change: 1 addition & 0 deletions test/jank/reader-macro/var-quote/fail-eof.jank
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#'
3 changes: 3 additions & 0 deletions test/jank/reader-macro/var-quote/fail-not-a-symbol.jank
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#'"str"

:success
3 changes: 3 additions & 0 deletions test/jank/reader-macro/var-quote/fail-unresolved.jank
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#'no-way-this-exists

:success
3 changes: 3 additions & 0 deletions test/jank/reader-macro/var-quote/pass-qualified.jank
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(assert (= (var clojure.core/str) #'clojure.core/str))

:success
3 changes: 3 additions & 0 deletions test/jank/reader-macro/var-quote/pass-unqualified.jank
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(assert (= (var clojure.core/str) #'str))

:success

0 comments on commit 88ecf09

Please sign in to comment.