xo-reader2: adopt DSchematikaParser as gc-aware object
Use as virtual GC root.
This commit is contained in:
parent
48d5c323b4
commit
4304892a7c
9 changed files with 570 additions and 268 deletions
|
|
@ -110,7 +110,7 @@ namespace xo {
|
|||
/** parser converts a stream of tokens
|
||||
* to a stream of expressions
|
||||
**/
|
||||
SchematikaParser parser_;
|
||||
DSchematikaParser parser_;
|
||||
|
||||
/** current output from reader **/
|
||||
ReaderResult result_;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ set(SELF_SRCS
|
|||
SchematikaReader.cpp
|
||||
ReaderConfig.cpp
|
||||
|
||||
SchematikaParser.cpp
|
||||
DSchematikaParser.cpp
|
||||
facet/IGCObject_DSchematikaParser.cpp
|
||||
|
||||
ParserStateMachine.cpp
|
||||
ParserStack.cpp
|
||||
ParserResult.cpp
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/** @file SchematikaParser.cpp
|
||||
/** @file DSchematikaParser.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Jan 2026
|
||||
**/
|
||||
|
|
@ -12,7 +12,9 @@
|
|||
#include <stdexcept>
|
||||
|
||||
namespace xo {
|
||||
using xo::mm::ACollector;
|
||||
using xo::mm::AAllocator;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::mm::MemorySizeInfo;
|
||||
using xo::tostr;
|
||||
using xo::xtag;
|
||||
|
|
@ -20,9 +22,9 @@ namespace xo {
|
|||
namespace scm {
|
||||
// ----- SchematikaParser -----
|
||||
|
||||
SchematikaParser::SchematikaParser(const ParserConfig & cfg,
|
||||
obj<AAllocator> expr_alloc,
|
||||
obj<AAllocator> aux_alloc)
|
||||
DSchematikaParser::DSchematikaParser(const ParserConfig & cfg,
|
||||
obj<AAllocator> expr_alloc,
|
||||
obj<AAllocator> aux_alloc)
|
||||
: psm_{
|
||||
cfg.parser_arena_config_,
|
||||
cfg.symtab_var_config_,
|
||||
|
|
@ -36,74 +38,94 @@ namespace xo {
|
|||
{
|
||||
}
|
||||
|
||||
DSchematikaParser *
|
||||
DSchematikaParser::_make(obj<AAllocator> mm,
|
||||
const ParserConfig & cfg,
|
||||
obj<AAllocator> expr_alloc,
|
||||
obj<AAllocator> aux_alloc)
|
||||
{
|
||||
void * mem = mm.alloc_for<DSchematikaParser>();
|
||||
|
||||
return new (mem) DSchematikaParser(cfg, expr_alloc, aux_alloc);
|
||||
}
|
||||
|
||||
obj<AGCObject,DSchematikaParser>
|
||||
DSchematikaParser::make(obj<AAllocator> mm,
|
||||
const ParserConfig & cfg,
|
||||
obj<AAllocator> expr_alloc,
|
||||
obj<AAllocator> aux_alloc)
|
||||
{
|
||||
return obj<AGCObject,DSchematikaParser>(_make(mm, cfg, expr_alloc, aux_alloc));
|
||||
}
|
||||
|
||||
DGlobalSymtab *
|
||||
SchematikaParser::global_symtab() const noexcept
|
||||
DSchematikaParser::global_symtab() const noexcept
|
||||
{
|
||||
return psm_.global_symtab();
|
||||
}
|
||||
|
||||
DGlobalEnv *
|
||||
SchematikaParser::global_env() const noexcept
|
||||
DSchematikaParser::global_env() const noexcept
|
||||
{
|
||||
return psm_.global_env();
|
||||
}
|
||||
|
||||
bool
|
||||
SchematikaParser::is_at_toplevel() const
|
||||
DSchematikaParser::is_at_toplevel() const
|
||||
{
|
||||
return psm_.is_at_toplevel();
|
||||
}
|
||||
|
||||
bool
|
||||
SchematikaParser::has_incomplete_expr() const
|
||||
DSchematikaParser::has_incomplete_expr() const
|
||||
{
|
||||
return psm_.has_incomplete_expr();
|
||||
}
|
||||
|
||||
obj<ASyntaxStateMachine>
|
||||
SchematikaParser::top_ssm() const
|
||||
DSchematikaParser::top_ssm() const
|
||||
{
|
||||
return psm_.top_ssm();
|
||||
}
|
||||
|
||||
const ParserResult &
|
||||
SchematikaParser::result() const
|
||||
DSchematikaParser::result() const
|
||||
{
|
||||
return psm_.result();
|
||||
}
|
||||
|
||||
void
|
||||
SchematikaParser::visit_pools(const MemorySizeVisitor & visitor) const
|
||||
DSchematikaParser::visit_pools(const MemorySizeVisitor & visitor) const
|
||||
{
|
||||
return psm_.visit_pools(visitor);
|
||||
}
|
||||
|
||||
void
|
||||
SchematikaParser::begin_interactive_session()
|
||||
DSchematikaParser::begin_interactive_session()
|
||||
{
|
||||
DToplevelSeqSsm::establish_interactive(psm_.parser_alloc(), &psm_);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
SchematikaParser::begin_batch_session()
|
||||
DSchematikaParser::begin_batch_session()
|
||||
{
|
||||
DToplevelSeqSsm::establish_batch(psm_.parser_alloc(), &psm_);
|
||||
}
|
||||
|
||||
const DUniqueString *
|
||||
SchematikaParser::intern_string(std::string_view str)
|
||||
DSchematikaParser::intern_string(std::string_view str)
|
||||
{
|
||||
return psm_.intern_string(str);
|
||||
}
|
||||
|
||||
const ParserResult &
|
||||
SchematikaParser::on_token(const token_type & tk)
|
||||
DSchematikaParser::on_token(const token_type & tk)
|
||||
{
|
||||
scope log(XO_DEBUG(debug_flag_), xtag("tk", tk));
|
||||
|
||||
if (psm_.stack() == nullptr) {
|
||||
throw std::runtime_error(tostr("SchematikaParser::include_token",
|
||||
throw std::runtime_error(tostr("DSchematikaParser::include_token",
|
||||
": parser not expecting input"
|
||||
"(call parser.begin_translation_unit()..?)",
|
||||
xtag("token", tk)));
|
||||
|
|
@ -120,19 +142,19 @@ namespace xo {
|
|||
} /*include_token*/
|
||||
|
||||
void
|
||||
SchematikaParser::reset_result()
|
||||
DSchematikaParser::reset_result()
|
||||
{
|
||||
psm_.reset_result();
|
||||
}
|
||||
|
||||
void
|
||||
SchematikaParser::reset_to_idle_toplevel()
|
||||
DSchematikaParser::reset_to_idle_toplevel()
|
||||
{
|
||||
psm_.clear_error_reset();
|
||||
} /*reset_to_idle_toplevel*/
|
||||
|
||||
void
|
||||
SchematikaParser::print(std::ostream & os) const {
|
||||
DSchematikaParser::print(std::ostream & os) const {
|
||||
os << "<SchematikaParser"
|
||||
<< xtag("debug", debug_flag_)
|
||||
<< xtag("has_stack", (psm_.stack() != nullptr))
|
||||
|
|
@ -140,7 +162,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
bool
|
||||
SchematikaParser::pretty(const ppindentinfo & ppii) const {
|
||||
DSchematikaParser::pretty(const ppindentinfo & ppii) const {
|
||||
auto * pps = ppii.pps();
|
||||
|
||||
if (ppii.upto())
|
||||
|
|
@ -161,6 +183,30 @@ namespace xo {
|
|||
refrtag("stack", psm_.stack())
|
||||
);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
DSchematikaParser::shallow_size() const noexcept
|
||||
{
|
||||
return sizeof(DSchematikaParser);
|
||||
}
|
||||
|
||||
DSchematikaParser *
|
||||
DSchematikaParser::shallow_copy(obj<AAllocator> mm) const noexcept
|
||||
{
|
||||
(void)mm;
|
||||
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
DSchematikaParser::forward_children(obj<ACollector> gc) noexcept
|
||||
{
|
||||
psm_.forward_children(gc);
|
||||
|
||||
return this->shallow_size();
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
**/
|
||||
|
||||
#include "ParserResult.hpp"
|
||||
#include <xo/stringtable2/String.hpp>
|
||||
#include <xo/printable2/Printable.hpp>
|
||||
#include <xo/alloc2/GCObject.hpp>
|
||||
#include <xo/facet/FacetRegistry.hpp>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -102,6 +104,15 @@ namespace xo {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ParserResult::forward_children(obj<ACollector> gc) noexcept
|
||||
{
|
||||
// {result_type_, error_src_fn_}: pod, ignore
|
||||
|
||||
gc.forward_pivot_inplace(&result_expr_);
|
||||
gc.forward_inplace(const_cast<DString **>(&error_description_));
|
||||
}
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,18 @@ namespace xo {
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ParserStack::forward_children(obj<ACollector> gc) noexcept
|
||||
{
|
||||
|
||||
for (ParserStack * target = this; target; target = target->parent_) {
|
||||
// ParserStack::ckp: skip, POD
|
||||
|
||||
if (target->ssm_)
|
||||
target->ssm_.forward_children(gc);
|
||||
}
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace xo {
|
|||
DGlobalSymtab * global_symtab,
|
||||
InstallFlags pm_install_flags)
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
scope log(XO_DEBUG(false));
|
||||
|
||||
DGlobalEnv * env = DGlobalEnv::_make(mm,
|
||||
global_symtab);
|
||||
|
|
@ -102,10 +102,9 @@ namespace xo {
|
|||
pm_install_flags)},
|
||||
debug_flag_{config.debug_flag_}
|
||||
{
|
||||
obj<ACollector> gc = expr_alloc_.try_to_facet<ACollector>();
|
||||
if (gc) {
|
||||
gc.add_gc_root(&global_env_);
|
||||
}
|
||||
// see xo-numeric/ {SetupNumeric.cpp, NumericPrimitives.cpp}
|
||||
// for setup of {_mul, _div, _sub, ...}
|
||||
//
|
||||
|
||||
{
|
||||
const DUniqueString * name = stringtable_.lookup("_mul");
|
||||
|
|
@ -175,6 +174,8 @@ namespace xo {
|
|||
if (gc) {
|
||||
scope log(XO_DEBUG(true), "remove_gc_root not implemented");
|
||||
|
||||
gc.remove_gc_root(&global_symtab_);
|
||||
gc.remove_gc_root(&local_symtab_);
|
||||
gc.remove_gc_root(&global_env_);
|
||||
}
|
||||
}
|
||||
|
|
@ -404,7 +405,7 @@ namespace xo {
|
|||
//
|
||||
|
||||
if (local_symtab_) {
|
||||
DLocalSymtab * symtab = local_symtab_;
|
||||
DLocalSymtab * symtab = local_symtab_.data();
|
||||
|
||||
// count #of nested scopes to cross, to reach symbol
|
||||
//
|
||||
|
|
@ -450,7 +451,7 @@ namespace xo {
|
|||
void
|
||||
ParserStateMachine::push_local_symtab(DLocalSymtab * symtab)
|
||||
{
|
||||
this->local_symtab_ = symtab;
|
||||
this->local_symtab_ = obj<AGCObject,DLocalSymtab>(symtab);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -458,7 +459,7 @@ namespace xo {
|
|||
{
|
||||
assert(local_symtab_);
|
||||
|
||||
this->local_symtab_ = local_symtab_->parent();
|
||||
this->local_symtab_ = obj<AGCObject,DLocalSymtab>(local_symtab_->parent());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -879,6 +880,45 @@ namespace xo {
|
|||
this->capture_error(ssm_name, errmsg);
|
||||
}
|
||||
|
||||
// ----- gc support -----
|
||||
|
||||
#ifdef OBSOLETE
|
||||
std::size_t
|
||||
ParserStateMachine::shallow_size() const noexcept
|
||||
{
|
||||
return sizeof(ParserStateMachine);
|
||||
}
|
||||
|
||||
ParserStateMachine *
|
||||
ParserStateMachine::shallow_copy(obj<AAllocator> mm) const noexcept
|
||||
{
|
||||
(void)mm;
|
||||
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ParserStateMachine::forward_children(obj<ACollector> gc) noexcept
|
||||
{
|
||||
static_assert(!stringtable_.is_gc_eligible());
|
||||
static_assert(!parser_alloc_.is_gc_eligible());
|
||||
|
||||
if (stack_) {
|
||||
stack_->forward_children(gc);
|
||||
}
|
||||
|
||||
// static_assert(!expr_alloc_.is_gc_eligible());
|
||||
// static_assert(!aux_alloc_.is_gc_eligible());
|
||||
|
||||
gc.forward_inplace(&global_symtab_);
|
||||
gc.forward_inplace(&local_symtab_);
|
||||
gc.forward_inplace(&global_env_);
|
||||
|
||||
result_.forward_children(gc);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/** @file SchematikaReader.cpp
|
||||
*
|
||||
*
|
||||
* @author Roland Conybeare, Jan 2026
|
||||
**/
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ namespace xo {
|
|||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
// SchematikParser
|
||||
|
||||
FacetRegistry::register_impl<AGCObject, DSchematikaParser>();
|
||||
|
||||
// GlobalEnv
|
||||
|
||||
FacetRegistry::register_impl<AGCObject, DGlobalEnv>();
|
||||
|
|
@ -114,11 +118,11 @@ namespace xo {
|
|||
FacetRegistry::register_impl<ASyntaxStateMachine, DExpectQArraySsm>();
|
||||
FacetRegistry::register_impl<APrintable, DExpectQArraySsm>();
|
||||
|
||||
// misc types showing up in aux arena
|
||||
TypeRegistry::register_type<SchematikaParser>();
|
||||
// misc types showing up in parser stack arena
|
||||
TypeRegistry::register_type<ParserStack>();
|
||||
|
||||
log && log(xtag("DSchematikaParser.tseq", typeseq::id<DSchematikaParser>()));
|
||||
|
||||
log && log(xtag("DGlobalEnv.tseq", typeseq::id<DGlobalEnv>()));
|
||||
log && log(xtag("DToplevelSeqSsm.tseq", typeseq::id<DToplevelSeqSsm>()));
|
||||
log && log(xtag("DDefineSsm.tseq", typeseq::id<DDefineSsm>()));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue