Skip to content

Commit

Permalink
Merge pull request #123 from jianlingzhong/delay
Browse files Browse the repository at this point in the history
Add support for delay
  • Loading branch information
jeaye authored Nov 6, 2024
2 parents a20bd8a + ed94dce commit 3afd224
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ CMakeUserPresets.json

# Rust
rust/jank

# secrets
.github_access_token
1 change: 1 addition & 0 deletions compiler+runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ add_library(
src/cpp/jank/runtime/obj/native_vector_sequence.cpp
src/cpp/jank/runtime/obj/atom.cpp
src/cpp/jank/runtime/obj/volatile.cpp
src/cpp/jank/runtime/obj/delay.cpp
src/cpp/jank/runtime/obj/reduced.cpp
src/cpp/jank/runtime/behavior/callable.cpp
src/cpp/jank/runtime/behavior/metadatable.cpp
Expand Down
2 changes: 2 additions & 0 deletions compiler+runtime/include/cpp/jank/runtime/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ namespace jank::runtime
native_persistent_string namespace_(object_ptr o);

native_bool is_callable(object_ptr o);

object_ptr force(object_ptr o);
}
6 changes: 6 additions & 0 deletions compiler+runtime/include/cpp/jank/runtime/erasure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <jank/runtime/obj/native_vector_sequence.hpp>
#include <jank/runtime/obj/atom.hpp>
#include <jank/runtime/obj/volatile.hpp>
#include <jank/runtime/obj/delay.hpp>
#include <jank/runtime/obj/reduced.hpp>
#include <jank/runtime/ns.hpp>
#include <jank/runtime/var.hpp>
Expand Down Expand Up @@ -382,6 +383,11 @@ namespace jank::runtime
return fn(expect_object<obj::volatile_>(erased), std::forward<Args>(args)...);
}
break;
case object_type::delay:
{
return fn(expect_object<obj::delay>(erased), std::forward<Args>(args)...);
}
break;
case object_type::ns:
{
return fn(expect_object<ns>(erased), std::forward<Args>(args)...);
Expand Down
35 changes: 35 additions & 0 deletions compiler+runtime/include/cpp/jank/runtime/obj/delay.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

namespace jank::runtime
{
template <>
struct static_object<object_type::delay> : gc
{
static constexpr native_bool pointer_free{ false };

static_object() = default;
static_object(object_ptr fn);

/* behavior::object_like */
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 */
object_ptr deref();

object base{ object_type::delay };
object_ptr val{};
object_ptr fn{};
object_ptr error{};
std::mutex mutex;
};

namespace obj
{
using delay = static_object<object_type::delay>;
using delay_ptr = native_box<delay>;
}
}
1 change: 1 addition & 0 deletions compiler+runtime/include/cpp/jank/runtime/object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ namespace jank::runtime
atom,
volatile_,
reduced,
delay,
ns,

var,
Expand Down
9 changes: 9 additions & 0 deletions compiler+runtime/src/cpp/jank/runtime/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,13 @@ namespace jank::runtime
},
o);
}

object_ptr force(object_ptr const o)
{
if(o->type == object_type::delay)
{
return expect_object<obj::delay>(o)->deref();
}
return o;
}
}
69 changes: 69 additions & 0 deletions compiler+runtime/src/cpp/jank/runtime/obj/delay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <jank/runtime/obj/delay.hpp>

namespace jank::runtime
{
obj::delay::static_object(object_ptr const fn)
: fn{ fn }
{
}

native_bool obj::delay::equal(object const &o) const
{
return &o == &base;
}

native_persistent_string obj::delay::to_string() const
{
fmt::memory_buffer buff;
to_string(buff);
return native_persistent_string{ buff.data(), buff.size() };
}

void obj::delay::to_string(fmt::memory_buffer &buff) const
{
fmt::format_to(std::back_inserter(buff),
"{}@{}",
magic_enum::enum_name(base.type),
fmt::ptr(&base));
}

native_persistent_string obj::delay::to_code_string() const
{
return to_string();
}

native_hash obj::delay::to_hash() const
{
return static_cast<native_hash>(reinterpret_cast<uintptr_t>(this));
}

object_ptr obj::delay::deref()
{
std::lock_guard<std::mutex> const lock{ mutex };
if(val != nullptr)
{
return val;
}

if(error != nullptr)
{
throw error;
}

try
{
val = dynamic_call(fn);
}
catch(std::exception const &e)
{
error = make_box(e.what());
throw;
}
catch(object_ptr const e)
{
error = e;
throw;
}
return val;
}
}
9 changes: 9 additions & 0 deletions compiler+runtime/src/jank/clojure/core.jank
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,15 @@
[x]
(native/raw "__value = make_box(~{ x }->type == object_type::volatile_);"))

(defn delay* [f]
(native/raw "__value = make_box<obj::delay>(~{ f });"))

(defmacro delay [& body]
(list 'delay* (cons 'fn (cons '[] body))))

(defn force [o]
(native/raw "__value = runtime::force(~{ o });"))

; Primitives.
;; Arithmetic.
(defn
Expand Down

0 comments on commit 3afd224

Please sign in to comment.