/** @file DApplyExpr.hpp * * @author Roland Conybeare, Jan 2026 **/ #pragma once #include "Expression.hpp" #include "TypeRef.hpp" #include "exprtype.hpp" #include #include #include #include namespace xo { namespace scm { /** @class DApplyExpr * @brief syntax for a procedure/function call **/ class DApplyExpr { public: using AGCObjectVisitor = xo::mm::AGCObjectVisitor; using VisitReason = xo::mm::VisitReason; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; using size_type = std::uint32_t; public: /** @defgroup scm-applyexpr-constructors **/ ///@{ /** construct empty instance, but with argument expressions empty **/ DApplyExpr(TypeRef typeref, obj fn_expr, size_type n_args); /** create apply for function with 2 arguments **/ static obj make2(obj mm, TypeRef typeref, obj fn_expr, obj arg1, obj arg2); /** create apply for function with 2 arguments **/ static DApplyExpr * _make2(obj mm, TypeRef typeref, obj fn_expr, obj arg1, obj arg2); /** scaffold incomplete instance. * apply-expr using memory from @p mm. * will construct instance with space for @p n_args arguments * but expressions left empty. * use @ref assign_arg for all arguments to complete. **/ static DApplyExpr * scaffold(obj mm, TypeRef typeref, obj fn_expr, size_type n_args); void assign_arg(size_type i_arg, obj expr); ///@} /** @defgroup scm-applyexpr-access-methods **/ ///@{ obj fn() const noexcept { return fn_; } size_type n_args() const noexcept { return n_args_; } obj arg(size_type i) const; ///@} /** @defgroup scm-applyexpr-expression-facet **/ ///@{ exprtype extype() const noexcept { return exprtype::apply; } TypeRef typeref() const noexcept { return typeref_; } TypeDescr valuetype() const noexcept { return typeref_.td(); } void assign_valuetype(TypeDescr td) noexcept; ///@} /** @defgroup scm-applyexpr-gcobject-facet **/ ///@{ DApplyExpr * gco_shallow_move(obj gc) noexcept; void visit_gco_children(VisitReason reason, obj gc) noexcept; ///@} /** @defgroup scm-applyexpr-printable-facet **/ ///@{ bool pretty(const ppindentinfo & ppii) const; ///@} private: /** expression value always has type consistent * with this description **/ TypeRef typeref_; /** expression for function/procedure to invoke **/ obj fn_; /** number of arguments (not counting @ref fn_ **/ size_type n_args_ = 0; /** args_[i] is expression for i'th argument to @ref fn_ **/ obj args_[]; }; } } /* end DApplyExpr.hpp */