Skip to content

Commit

Permalink
Make maps, sets, and keywords callable
Browse files Browse the repository at this point in the history
  • Loading branch information
jeaye committed Dec 11, 2023
1 parent 2171819 commit 38d7b06
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 14 deletions.
4 changes: 4 additions & 0 deletions include/cpp/jank/runtime/obj/keyword.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ namespace jank::runtime
native_string const& get_name() const;
native_string const& get_namespace() const;

/* behavior::callable */
object_ptr call(object_ptr) const;
object_ptr call(object_ptr, object_ptr) const;

bool operator ==(static_object const &rhs) const;

object base{ object_type::keyword };
Expand Down
4 changes: 4 additions & 0 deletions include/cpp/jank/runtime/obj/persistent_array_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ namespace jank::runtime
/* behavior::consable */
native_box<static_object> cons(object_ptr head) const;

/* behavior::callable */
object_ptr call(object_ptr) const;
object_ptr call(object_ptr, object_ptr) const;

value_type data{};
};

Expand Down
4 changes: 4 additions & 0 deletions include/cpp/jank/runtime/obj/persistent_hash_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ namespace jank::runtime
/* behavior::consable */
native_box<static_object> cons(object_ptr head) const;

/* behavior::callable */
object_ptr call(object_ptr) const;
object_ptr call(object_ptr, object_ptr) const;

value_type data{};
};

Expand Down
3 changes: 3 additions & 0 deletions include/cpp/jank/runtime/obj/set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ namespace jank::runtime
/* behavior::consable */
native_box<static_object> cons(object_ptr head) const;

/* behavior::callable */
object_ptr call(object_ptr) const;

native_bool contains(object_ptr o) const;

object base{ object_type::set };
Expand Down
32 changes: 31 additions & 1 deletion src/cpp/jank/evaluate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,38 @@ namespace jank::evaluate
}
}
}
else if constexpr(std::same_as<T, runtime::obj::set>)
{
auto const s(expr.arg_exprs.size());
if(s != 1)
{ throw std::runtime_error{ fmt::format("invalid call with {} args to: {}", s, typed_source->to_string()) }; }
return typed_source->call(eval(rt_ctx, jit_prc, expr.arg_exprs[0]));
}
else if constexpr
(
std::same_as<T, runtime::obj::keyword>
|| std::same_as<T, runtime::obj::persistent_hash_map>
|| std::same_as<T, runtime::obj::persistent_array_map>
)
{
auto const s(expr.arg_exprs.size());
switch(s)
{
case 1:
return typed_source->call(eval(rt_ctx, jit_prc, expr.arg_exprs[0]));
case 2:
return typed_source->call
(
eval(rt_ctx, jit_prc, expr.arg_exprs[0]),
eval(rt_ctx, jit_prc, expr.arg_exprs[1])
);
default:
throw std::runtime_error
{ fmt::format("invalid call with {} args to: {}", s, typed_source->to_string()) };
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 0 args to: {}", expr.arg_exprs.size(), typed_source->to_string()) }; }
},
source
);
Expand Down
49 changes: 37 additions & 12 deletions src/cpp/jank/runtime/behavior/callable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 0 args to {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -66,8 +66,16 @@ namespace jank::runtime
return typed_source->call(a1);
}
}
else if constexpr
(
std::same_as<T, obj::set>
|| std::same_as<T, obj::persistent_hash_map>
|| std::same_as<T, obj::persistent_array_map>
|| std::same_as<T, obj::keyword>
)
{ return typed_source->call(a1); }
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 1 arg to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -98,8 +106,15 @@ namespace jank::runtime
return typed_source->call(a1, a2);
}
}
else if constexpr
(
std::same_as<T, obj::persistent_hash_map>
|| std::same_as<T, obj::persistent_array_map>
|| std::same_as<T, obj::keyword>
)
{ return typed_source->call(a1, a2); }
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 2 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -133,7 +148,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 3 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -169,7 +184,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 4 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -207,7 +222,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 5 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -247,7 +262,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 6 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -289,7 +304,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 7 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -333,7 +348,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 8 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -379,7 +394,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 9 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -427,7 +442,7 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{ throw std::runtime_error{ fmt::format("invalid call with 10 args to: {}", typed_source->to_string()) }; }
},
source
);
Expand Down Expand Up @@ -532,7 +547,17 @@ namespace jank::runtime
}
}
else
{ throw std::runtime_error{ fmt::format("not callable: {}", typed_source->to_string()) }; }
{
throw std::runtime_error
{
fmt::format
(
"invalid call with {} args to: {}",
10 + runtime::detail::sequence_length(rest),
typed_source->to_string()
)
};
}
},
source
);
Expand Down
6 changes: 6 additions & 0 deletions src/cpp/jank/runtime/obj/keyword.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ namespace jank::runtime
native_string const& obj::keyword::get_namespace() const
{ return sym.ns; }

object_ptr obj::keyword::call(object_ptr const m) const
{ return runtime::get(m, this); }

object_ptr obj::keyword::call(object_ptr const m, object_ptr const fallback) const
{ return runtime::get(m, this, fallback); }

bool obj::keyword::operator ==(obj::keyword const &rhs) const
{ return sym == rhs.sym; }
}
16 changes: 16 additions & 0 deletions src/cpp/jank/runtime/obj/persistent_array_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,20 @@ namespace jank::runtime
copy.insert_or_assign(vec->data[0], vec->data[1]);
return make_box<obj::persistent_array_map>(std::move(copy));
}

object_ptr obj::persistent_array_map::call(object_ptr const o) const
{
auto const found(data.find(o));
if(!found)
{ return obj::nil::nil_const(); }
return found;
}

object_ptr obj::persistent_array_map::call(object_ptr const o, object_ptr const fallback) const
{
auto const found(data.find(o));
if(!found)
{ return fallback; }
return found;
}
}
16 changes: 16 additions & 0 deletions src/cpp/jank/runtime/obj/persistent_hash_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,20 @@ namespace jank::runtime
auto copy(data.set(vec->data[0], vec->data[1]));
return make_box<obj::persistent_hash_map>(std::move(copy));
}

object_ptr obj::persistent_hash_map::call(object_ptr const o) const
{
auto const found(data.find(o));
if(!found)
{ return obj::nil::nil_const(); }
return *found;
}

object_ptr obj::persistent_hash_map::call(object_ptr const o, object_ptr const fallback) const
{
auto const found(data.find(o));
if(!found)
{ return fallback; }
return *found;
}
}
8 changes: 8 additions & 0 deletions src/cpp/jank/runtime/obj/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ namespace jank::runtime
return ret;
}

object_ptr obj::set::call(object_ptr const o) const
{
auto const found(data.find(o));
if(!found)
{ return obj::nil::nil_const(); }
return *found;
}

native_bool obj::set::contains(object_ptr const o) const
{ return data.find(o); }
}
2 changes: 1 addition & 1 deletion src/jank/clojure/core.jank
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,7 @@
(concat acc [flag true]))
[]
flags)
args (filter (complement keyword?) args)]
args (remove keyword? args)]
; TODO: Set syntax.
(let [supported (set [:as :reload :reload-all :require :use :verbose :refer :as-alias])
unsupported (seq (remove supported flags))]
Expand Down

0 comments on commit 38d7b06

Please sign in to comment.