/** @file ParserStack.cpp * * @author Roland Conybeare, Jan 2026 **/ #include "ParserStack.hpp" #include "SyntaxStateMachine.hpp" #include #include namespace xo { using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::facet::typeseq; namespace scm { ParserStack::ParserStack(DArena::Checkpoint ckp, obj ssm, ParserStack * parent) : ckp_{ckp}, ssm_{ssm}, parent_{parent} {} ParserStack * ParserStack::push(ParserStack * stack, DArena::Checkpoint ckp, DArena & mm, obj ssm) { //DArena::Checkpoint ckp = mm.checkpoint(); // wrong, must precede allocation of ssm void * mem = mm.alloc(typeseq::id(), sizeof(ParserStack)); return new (mem) ParserStack(ckp, ssm, stack); } ParserStack * ParserStack::pop(ParserStack * stack, DArena & mm) { assert(stack); mm.restore(stack->ckp()); return stack->parent(); } void ParserStack::print(std::ostream & os) const { os << ""; os << xtag("ssm", "*placeholder*"); os << xtag("parent", "*placeholder*"); os << ">"; } bool ParserStack::pretty(const ppindentinfo & ppii) const { auto * pps = ppii.pps(); /* always use multiple lines */ if (ppii.upto()) return false; pps->write(" (frame->top())); assert(ssm.data()); pps->newline_pretty_tag(ppii.ci1(), buf, ssm); ++i_frame; frame = frame->parent_; } pps->write(">"); return false; } void ParserStack::visit_gco_children(VisitReason reason, obj gc) noexcept { for (ParserStack * target = this; target; target = target->parent_) { // ParserStack::ckp: skip, POD if (target->ssm_) target->ssm_.visit_gco_children(reason, gc); } } } /*namespace scm*/ } /*namespace xo*/ /* end ParserStack.cpp */