/** @file DLocalSymtab.cpp * * @author Roland Conybeare, Jan 2026 **/ #include "LocalSymtab.hpp" #include "Variable.hpp" #include "Typename.hpp" #include "DUniqueString.hpp" #include #include #include #include namespace xo { using xo::mm::AGCObject; using xo::print::APrintable; //using xo::facet::typeseq; using xo::print::ppstate; namespace scm { DLocalSymtab::DLocalSymtab(DLocalSymtab * p, DArray * vars, DArray * types) : parent_{p}, vars_{vars}, types_{types} { } DLocalSymtab * DLocalSymtab::_make_empty(obj mm, DLocalSymtab * p, size_type nv, size_type nt) { void * mem = mm.alloc_for(); DArray * vars = DArray::empty(mm, nv); DArray * types = DArray::empty(mm, nt); return new (mem) DLocalSymtab(p, vars, types); } DVariable * DLocalSymtab::lookup_var(Binding ix) noexcept { assert(ix.i_link() == 0); assert(ix.j_slot() < static_cast(vars_->size())); auto var = obj::from((*vars_)[ix.j_slot()]); assert(var); return var.data(); } Binding DLocalSymtab::append_var(obj mm, const DUniqueString * name, TypeRef typeref) { assert(name); if (vars_->size() >= vars_->capacity() || !name) { assert(false); return Binding::null(); } else { //size_type i_slot = (this->size_)++; Binding binding = Binding::local(vars_->size()); DVariable * var = DVariable::make(mm, name, typeref, binding); vars_->push_back(obj(var)); return binding; } } void DLocalSymtab::append_type(obj mm, const DUniqueString * name, obj type) { assert(name); if (types_->size() >= types_->capacity() || !name) { assert(false); } else { obj tname = DTypename::make(mm, name, type); types_->push_back(tname); } } Binding DLocalSymtab::lookup_binding(const DUniqueString * sym) const noexcept { assert(sym); if (sym) { for (size_type i = 0, n = vars_->size(); i < n; ++i) { auto var_i = obj::from((*vars_)[i]); assert(var_i); if (*sym == *(var_i->name())) return var_i->path(); } } return Binding(); } // ----- gcobject facet ----- std::size_t DLocalSymtab::shallow_size() const noexcept { return sizeof(DLocalSymtab); } DLocalSymtab * DLocalSymtab::shallow_copy(obj mm) noexcept { return mm.std_copy_for(this); } std::size_t DLocalSymtab::forward_children(obj gc) noexcept { gc.forward_inplace(&parent_); gc.forward_inplace(&vars_); gc.forward_inplace(&types_); return shallow_size(); } // ----- printable facet ----- bool DLocalSymtab::pretty(const ppindentinfo & ppii) const { ppstate * pps = ppii.pps(); (void)pps; if (ppii.upto()) { /* perhaps print on one line */ if (!pps->print_upto("print_upto(xrefrtag("nvars", vars_->size()))) return false; for (size_type i = 0, n = vars_->size(); i arg_pr = (*vars_)[i].to_facet(); if (!pps->print_upto(xrefrtag(buf, arg_pr))) return false; } if (!pps->print_upto(xrefrtag("ntypes", types_->size()))) return false; for (size_type i = 0, n = types_->size(); i < n; ++i) { char buf[32]; snprintf(buf, sizeof(buf), "[%u]", i); obj type_pr = (*types_)[i].to_facet(); if (!pps->print_upto(xrefrtag(buf, type_pr))) return false; } pps->write(">"); return true; } else { /* with line breaks */ pps->write("newline_pretty_tag(ppii.ci1(), "nvars", vars_->size()); for (size_type i = 0, n = vars_->size(); i < n; ++i) { char buf[32]; snprintf(buf, sizeof(buf), "[%u]", i); obj arg_pr = (*vars_)[i].to_facet(); pps->newline_pretty_tag(ppii.ci1(), buf, arg_pr); } pps->newline_pretty_tag(ppii.ci1(), "ntypes", types_->size()); for (size_type i = 0, n = types_->size(); i < n; ++i) { char buf[32]; snprintf(buf, sizeof(buf), "[%u]", i); obj type_pr = (*types_)[i].to_facet(); pps->newline_pretty_tag(ppii.ci1(), buf, type_pr); } pps->write(">"); return false; } } } /*namespace scm*/ } /*namespace xo*/ /* end DLocalSymtab.cpp */