/** @file DClosure.hpp * * @author Roland Conybeare, Feb 2026 **/ #pragma once #include "LocalEnv.hpp" #include #include namespace xo { namespace scm { /** @brief runtime representation for a procedure * * Maintains lambda + captured lexical context **/ class DClosure { public: using ARuntimeContext = xo::scm::ARuntimeContext; using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using ppindentinfo = xo::print::ppindentinfo; using size_type = std::int32_t; public: DClosure(const DLambdaExpr * lm, const DLocalEnv * env); /** create instance using memory from @p mm * for lambda @p lm with captured environment @p env. **/ static DClosure * make(obj mm, const DLambdaExpr * lm, const DLocalEnv * env); /** @defgroup scm-closure-general-methods **/ ///@{ const DLambdaExpr * lambda() const noexcept { return lambda_; } const DLocalEnv * env() const noexcept { return env_; } ///@} /** @defgroup scm-closure-procedure-facet **/ ///@{ /** for now, support just fixed-arity procedures **/ bool is_nary() const noexcept { return false; } /** number of arguments expected by this procedure (-1 if nary) **/ size_type n_args() const noexcept { return lambda_->n_args(); } obj apply_nocheck(obj rcx, const DArray * args); ///@} /** @defgroup scm-closure-gcobject-facet **/ ///@{ std::size_t shallow_size() const noexcept; DClosure * shallow_copy(obj mm) const noexcept; std::size_t forward_children(obj gc) noexcept; ///@} /** @defgroup scm-closure-printable-facet **/ ///@{ bool pretty(const ppindentinfo & ppii) const; ///@} private: /** lambda expression **/ const DLambdaExpr * lambda_ = nullptr; /** bindings for captured variables * (from lexical context where lambda evaluated) **/ const DLocalEnv * env_ = nullptr; }; } /*namespace scm*/ } /*namespace xo*/ /* end DClosure.hpp */