From bb56d6399f8437eca60074a5feee2635bd22873b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 25 Aug 2023 16:02:49 -0600 Subject: [PATCH] Add helpers for SExpr->lambda --- include/cons_expr/cons_expr.hpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/include/cons_expr/cons_expr.hpp b/include/cons_expr/cons_expr.hpp index a6604bc..483e941 100644 --- a/include/cons_expr/cons_expr.hpp +++ b/include/cons_expr/cons_expr.hpp @@ -1333,23 +1333,34 @@ struct cons_expr // take a string_view and return a C++ function object // of unspecified type. template - [[nodiscard]] constexpr auto make_callable(std::basic_string_view function) noexcept + [[nodiscard]] constexpr auto make_callable(SExpr callable) noexcept requires std::is_function_v { - auto impl = [this, function](Ret (*)(Params...)) { - // this is fragile, we need to check parsing better - - return [callable = eval(global_scope, values[std::get(parse(function).first.value)][0])]( - cons_expr &engine, Params... params) { + auto impl = [this, callable](Ret (*)(Params...)) { + return [callable](cons_expr &engine, Params... params) { std::array args{ SExpr{ Atom{ params } }... }; - return engine.eval_to(engine.global_scope, - engine.invoke_function(engine.global_scope, callable, engine.values.insert_or_find(args))); + if constexpr (std::is_same_v) { + engine.eval(engine.global_scope, engine.invoke_function(engine.global_scope, callable, engine.values.insert_or_find(args))); + + } else { + return engine.eval_to(engine.global_scope, + engine.invoke_function(engine.global_scope, callable, engine.values.insert_or_find(args))); + } }; }; return impl(std::add_pointer_t{ nullptr }); } + template + [[nodiscard]] constexpr auto make_callable(std::basic_string_view function) noexcept + requires std::is_function_v + { + // this is fragile, we need to check parsing better + return make_callable(eval(global_scope, values[std::get(parse(function).first.value)][0])); + } + + template [[nodiscard]] constexpr auto eval_transform(LexicalScope &scope) { return std::ranges::views::transform([&scope, this](const SExpr param) { return eval_to(scope, param); });