Skip to content

Commit

Permalink
Merge branch 'main' of github.com:jank-lang/jank into error-reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
jeaye committed Feb 13, 2025
2 parents 004e566 + 3d53442 commit 9be7cbb
Show file tree
Hide file tree
Showing 33 changed files with 1,614 additions and 281 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@
[submodule "compiler+runtime/third-party/ftxui"]
path = compiler+runtime/third-party/ftxui
url = https://github.com/jank-lang/FTXUI.git
[submodule "compiler+runtime/test/bash/clojure-test-suite/clojure-test-suite"]
path = compiler+runtime/test/bash/clojure-test-suite/clojure-test-suite
url = https://github.com/jank-lang/clojure-test-suite
1 change: 1 addition & 0 deletions bin/jank/check_everything.clj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
(util/log-warning "Skipping dependency install, since we don't have apt-get")
(do
; Install deps required for running our tests.
(util/quiet-shell {} "sudo apt-get update -y")
(util/quiet-shell {} "sudo apt-get install -y default-jdk software-properties-common lsb-release npm lcov leiningen")
; TODO: Enable once we're linting Clojure/jank again.
;(util/quiet-shell {} "sudo npm install --global @chrisoakman/standard-clojure-style")
Expand Down
7 changes: 5 additions & 2 deletions compiler+runtime/include/cpp/jank/analyze/expr/try.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,17 @@ namespace jank::analyze::expr
struct try_ : expression_base
{
do_<E> body{};
catch_<E> catch_body{};
option<catch_<E>> catch_body{};
option<do_<E>> finally_body{};

void propagate_position(expression_position const pos)
{
position = pos;
body.propagate_position(pos);
catch_body.propagate_position(pos);
if(catch_body)
{
catch_body.unwrap().propagate_position(pos);
}
if(finally_body)
{
finally_body.unwrap().propagate_position(pos);
Expand Down
1 change: 1 addition & 0 deletions compiler+runtime/include/cpp/jank/runtime/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ namespace jank::runtime
var_ptr current_ns_var{};
var_ptr in_ns_var{};
var_ptr compile_files_var{};
var_ptr loaded_libs_var{};
var_ptr current_module_var{};
var_ptr assert_var{};
var_ptr no_recur_var{};
Expand Down
11 changes: 6 additions & 5 deletions compiler+runtime/include/cpp/jank/runtime/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace jank::runtime

native_bool is_named(object_ptr o);
native_persistent_string name(object_ptr o);
native_persistent_string namespace_(object_ptr o);
object_ptr namespace_(object_ptr o);

object_ptr keyword(object_ptr ns, object_ptr name);
native_bool is_keyword(object_ptr o);
Expand All @@ -60,10 +60,11 @@ namespace jank::runtime

object_ptr atom(object_ptr o);
object_ptr deref(object_ptr o);
object_ptr swap(object_ptr atom, object_ptr fn);
object_ptr swap(object_ptr atom, object_ptr fn, object_ptr a1);
object_ptr swap(object_ptr atom, object_ptr fn, object_ptr a1, object_ptr a2);
object_ptr swap(object_ptr atom, object_ptr fn, object_ptr a1, object_ptr a2, object_ptr rest);
object_ptr swap_atom(object_ptr atom, object_ptr fn);
object_ptr swap_atom(object_ptr atom, object_ptr fn, object_ptr a1);
object_ptr swap_atom(object_ptr atom, object_ptr fn, object_ptr a1, object_ptr a2);
object_ptr
swap_atom(object_ptr atom, object_ptr fn, object_ptr a1, object_ptr a2, object_ptr rest);
object_ptr swap_vals(object_ptr atom, object_ptr fn);
object_ptr swap_vals(object_ptr atom, object_ptr fn, object_ptr a1);
object_ptr swap_vals(object_ptr atom, object_ptr fn, object_ptr a1, object_ptr a2);
Expand Down
2 changes: 2 additions & 0 deletions compiler+runtime/include/cpp/jank/runtime/core/seq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,6 @@ namespace jank::runtime
object_ptr repeat(object_ptr n, object_ptr val);

object_ptr sort(object_ptr coll);

object_ptr shuffle(object_ptr coll);
}
2 changes: 2 additions & 0 deletions compiler+runtime/include/cpp/jank/runtime/module/loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ namespace jank::runtime::module
loader(context &rt_ctx, native_persistent_string_view const &ps);

string_result<find_result> find(native_persistent_string_view const &module, origin const ori);
native_bool is_loaded(native_persistent_string_view const &module);
void set_is_loaded(native_persistent_string_view const &module);
string_result<void> load(native_persistent_string_view const &module, origin const ori);

string_result<void>
Expand Down
1 change: 1 addition & 0 deletions compiler+runtime/src/cpp/clojure/core_native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ jank_object_ptr jank_load_clojure_core_native()
intern_fn("tagged-literal?", &is_tagged_literal);
intern_fn("sorted?", &is_sorted);
intern_fn("sort", &sort);
intern_fn("shuffle", &shuffle);

/* TODO: jank.math? */
intern_fn("sqrt", static_cast<native_real (*)(object_ptr)>(&runtime::sqrt));
Expand Down
12 changes: 4 additions & 8 deletions compiler+runtime/src/cpp/jank/analyze/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1212,16 +1212,12 @@ namespace jank::analyze
}
}

if(!has_catch)
{
return make_error(error::kind::analysis_invalid_try,
"Each 'try' must have a 'catch' clause",
meta_source(list));
}

ret.body.frame = try_frame;
ret.body.propagate_position(position);
ret.catch_body.body.frame = catch_frame;
if(ret.catch_body.is_some())
{
ret.catch_body.unwrap().body.frame = catch_frame;
}
if(ret.finally_body.is_some())
{
ret.finally_body.unwrap().frame = finally_frame;
Expand Down
4 changes: 2 additions & 2 deletions compiler+runtime/src/cpp/jank/analyze/step/force_boxed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ namespace jank::analyze::step
{
boost::apply_visitor(f, typed_expr.body.values.back()->data);
}
if(!typed_expr.catch_body.body.values.empty())
if(typed_expr.catch_body && !typed_expr.catch_body.unwrap().body.values.empty())
{
boost::apply_visitor(f, typed_expr.catch_body.body.values.back()->data);
boost::apply_visitor(f, typed_expr.catch_body.unwrap().body.values.back()->data);
}
}
else
Expand Down
8 changes: 6 additions & 2 deletions compiler+runtime/src/cpp/jank/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,14 +850,18 @@ extern "C"
}
} };

auto const try_fn_obj(reinterpret_cast<object *>(try_fn));
auto const catch_fn_obj(reinterpret_cast<object *>(catch_fn));
if(catch_fn_obj == obj::nil::nil_const())
{
return dynamic_call(try_fn_obj);
}
try
{
auto const try_fn_obj(reinterpret_cast<object *>(try_fn));
return dynamic_call(try_fn_obj);
}
catch(object_ptr const e)
{
auto const catch_fn_obj(reinterpret_cast<object *>(catch_fn));
return dynamic_call(catch_fn_obj, e);
}
}
Expand Down
20 changes: 12 additions & 8 deletions compiler+runtime/src/cpp/jank/codegen/llvm_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -923,15 +923,18 @@ namespace jank::codegen
{
auto const wrapped_body(
evaluate::wrap_expression(make_box<expression>(expr.body), "try_body", {}));
auto const wrapped_catch(evaluate::wrap_expression(make_box<expression>(expr.catch_body.body),
"catch",
{ expr.catch_body.sym }));
auto const wrapped_catch(expr.catch_body.map([](auto const &catch_body) {
return evaluate::wrap_expression(make_box<expression>(catch_body.body),
"catch",
{ catch_body.sym });
}));
auto const wrapped_finally(expr.finally_body.map([](auto const &finally) {
return evaluate::wrap_expression(make_box<expression>(finally), "finally", {});
}));

auto const body(gen(wrapped_body, arity));
auto const catch_(gen(wrapped_catch, arity));
auto const catch_(
wrapped_catch.map([&](auto const &catch_body) { return gen(catch_body, arity); }));
auto const finally(
wrapped_finally.map([&](auto const &finally) { return gen(finally, arity); }));

Expand All @@ -941,10 +944,11 @@ namespace jank::codegen
false));
auto const fn(ctx->module->getOrInsertFunction("jank_try", fn_type));

llvm::SmallVector<llvm::Value *, 3> const args{ body,
catch_,
finally.unwrap_or(
gen_global(obj::nil::nil_const())) };
llvm::SmallVector<llvm::Value *, 3> const args{
body,
catch_.unwrap_or(gen_global(obj::nil::nil_const())),
finally.unwrap_or(gen_global(obj::nil::nil_const()))
};
auto const call(ctx->builder->CreateCall(fn, args));

if(expr.position == expression_position::tail)
Expand Down
13 changes: 10 additions & 3 deletions compiler+runtime/src/cpp/jank/evaluate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ namespace jank::evaluate
else if constexpr(std::same_as<T, expr::try_<expression>>)
{
walk(expr.body, f);
walk(expr.catch_body.body, f);
if(expr.catch_body.is_some())
{
walk(expr.catch_body.unwrap().body, f);
}
if(expr.finally_body.is_some())
{
walk(expr.finally_body.unwrap(), f);
Expand Down Expand Up @@ -627,15 +630,19 @@ namespace jank::evaluate
}
} };

if(!expr.catch_body)
{
return eval(expr.body);
}
try
{
return eval(expr.body);
}
catch(object_ptr const e)
{
return dynamic_call(eval(wrap_expression(make_box<expression>(expr.catch_body.body),
return dynamic_call(eval(wrap_expression(make_box<expression>(expr.catch_body.unwrap().body),
"catch",
{ expr.catch_body.sym })),
{ expr.catch_body.unwrap().sym })),
e);
}
}
Expand Down
31 changes: 31 additions & 0 deletions compiler+runtime/src/cpp/jank/read/lex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,37 @@ namespace jank::read::lex
return ok(token{ token_start, pos, token_kind::reader_macro_conditional });
}
}
case '!':
{
while(true)
{
auto const oc(peek());
if(oc.is_err())
{
break;
}
auto const c(oc.expect_ok().character);
if(c == '\n')
{
break;
}

++pos;
}

++pos;
if(pos == token_start + 2zu)
{
return ok(token{ token_start, 1, token_kind::comment, ""sv });
}
else
{
auto const length{ pos - token_start - 2 };
native_persistent_string_view const comment{ file.data() + token_start + 2,
length };
return ok(token{ token_start, length, token_kind::comment, comment });
}
}
default:
break;
}
Expand Down
5 changes: 5 additions & 0 deletions compiler+runtime/src/cpp/jank/runtime/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ namespace jank::runtime
compile_files_var->bind_root(obj::boolean::false_const());
compile_files_var->dynamic.store(true);

auto const loaded_libs_sym(make_box<obj::symbol>("clojure.core/*loaded-libs*"));
loaded_libs_var = core->intern_var(loaded_libs_sym);
loaded_libs_var->bind_root(make_box<obj::atom>(obj::persistent_sorted_set::empty()));
loaded_libs_var->dynamic.store(true);

auto const assert_sym(make_box<obj::symbol>("clojure.core/*assert*"));
assert_var = core->intern_var(assert_sym);
assert_var->bind_root(obj::boolean::true_const());
Expand Down
23 changes: 12 additions & 11 deletions compiler+runtime/src/cpp/jank/runtime/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,15 +387,16 @@ namespace jank::runtime
o);
}

native_persistent_string namespace_(object_ptr const o)
object_ptr namespace_(object_ptr const o)
{
return visit_object(
[](auto const typed_o) -> native_persistent_string {
[](auto const typed_o) -> object_ptr {
using T = typename decltype(typed_o)::value_type;

if constexpr(behavior::nameable<T>)
{
return typed_o->get_namespace();
auto const ns(typed_o->get_namespace());
return (ns.empty() ? obj::nil::nil_const() : make_box<obj::persistent_string>(ns));
}
else
{
Expand Down Expand Up @@ -461,27 +462,27 @@ namespace jank::runtime
return make_box<obj::atom>(o);
}

object_ptr swap(object_ptr const atom, object_ptr const fn)
object_ptr swap_atom(object_ptr const atom, object_ptr const fn)
{
return try_object<obj::atom>(atom)->swap(fn);
}

object_ptr swap(object_ptr const atom, object_ptr const fn, object_ptr const a1)
object_ptr swap_atom(object_ptr const atom, object_ptr const fn, object_ptr const a1)
{
return try_object<obj::atom>(atom)->swap(fn, a1);
}

object_ptr
swap(object_ptr const atom, object_ptr const fn, object_ptr const a1, object_ptr const a2)
swap_atom(object_ptr const atom, object_ptr const fn, object_ptr const a1, object_ptr const a2)
{
return try_object<obj::atom>(atom)->swap(fn, a1, a2);
}

object_ptr swap(object_ptr const atom,
object_ptr const fn,
object_ptr const a1,
object_ptr const a2,
object_ptr const rest)
object_ptr swap_atom(object_ptr const atom,
object_ptr const fn,
object_ptr const a1,
object_ptr const a2,
object_ptr const rest)
{
return try_object<obj::atom>(atom)->swap(fn, a1, a2, rest);
}
Expand Down
23 changes: 23 additions & 0 deletions compiler+runtime/src/cpp/jank/runtime/core/seq.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <algorithm>
#include <random>
#include <fmt/core.h>

#include <jank/native_persistent_string/fmt.hpp>
Expand Down Expand Up @@ -1207,4 +1209,25 @@ namespace jank::runtime
},
coll);
}

object_ptr shuffle(object_ptr const coll)
{
return visit_seqable(
[](auto const typed_coll) -> object_ptr {
native_vector<object_ptr> vec;
for(auto it(typed_coll->fresh_seq()); it != nullptr; it = it->next_in_place())
{
vec.push_back(it->first());
}

static std::random_device rd;
std::mt19937 g(rd());
std::shuffle(vec.begin(), vec.end(), g);

return make_box<obj::persistent_vector>(
runtime::detail::native_persistent_vector{ vec.begin(), vec.end() });
},
coll);
}

}
Loading

0 comments on commit 9be7cbb

Please sign in to comment.