/** @file DGlobalEnv.hpp * * @author Roland Conybeare, Feb 2026 **/ #pragma once #include #include #include namespace xo { namespace scm { /** @brief runtime bindings for global variabels * * Implementation here uses a DArenaHashMap to hold pairs. * The hash map has its own memory outside GC space. * Keys are DUniqueStrings, also outside GC space. * Values are regular gc-aware objects, generally will be in GC space. * * We need collector to traverse all the values in a global env * on each cycle. Arrange that by having DGlobalEnv itself * in GC space. * **/ class DGlobalEnv { public: using TypeDescr = xo::reflect::TypeDescr; using AGCObject = xo::mm::AGCObject; using AGCObjectVisitor = xo::mm::AGCObjectVisitor; using VisitReason = xo::mm::VisitReason; using AAllocator = xo::mm::AAllocator; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using ppindentinfo = xo::print::ppindentinfo; using size_type = std::uint32_t; public: /** @defgroup scm-globalenv-ctors constructors **/ ///@{ DGlobalEnv(DGlobalSymtab * symtab, DArray * values); static DGlobalEnv * _make(obj mm, DGlobalSymtab * symtab); ///@} /** @defgroup scm-globalenv-methods methods **/ ///@{ /** symbol-table size. Is the number of distinct global variables **/ size_type n_vars() const noexcept { return symtab_->n_vars(); } /** lookup current value associated with binding @p ix **/ obj lookup_value(Binding ix) const noexcept; /** assign value associated with binding @p to @p x. * If need to expand size of this env, use memory from @p mm **/ void assign_value(obj mm, Binding ix, obj x); /** create/establish global for symbol @p sym with resolved type @p td * and associate with @p value. **/ DVariable * _upsert_value(obj mm, const DUniqueString * sym, TypeDescr td, obj value); ///@} /** @defgroup scm-globalenv-gcobject-facet **/ ///@{ DGlobalEnv * gco_shallow_move(obj gc) noexcept; void visit_gco_children(VisitReason reason, obj gc) noexcept; ///@} /** @defgroup scm-globalenv-printable-facet **/ ///@{ bool pretty(const ppindentinfo & ppii) const; ///@} private: /** symbol table assigns a unique index for each symbol **/ DGlobalSymtab * symtab_; /** value for a symbol S will be in values_[symtab->lookup_binding(S)] **/ DArray * values_ = nullptr; }; } }