From edd6c50e10b5e2cf9ea4accf83e914fe3d2a7d9b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Mar 2026 01:27:25 -0500 Subject: [PATCH] xo-interpreter2 stack: + stringtable() in RuntimeContext api --- .../include/xo/interpreter2/DVsmRcx.hpp | 3 +++ .../interpreter2/VirtualSchematikaMachine.hpp | 2 ++ .../detail/IRuntimeContext_DVsmRcx.hpp | 2 ++ xo-interpreter2/src/interpreter2/DVsmRcx.cpp | 6 ++++++ .../interpreter2/IRuntimeContext_DVsmRcx.cpp | 6 ++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 6 ++++++ xo-procedure2/idl/RuntimeContext.json5 | 10 +++++++++ .../include/xo/procedure2/DPrimitive.hpp | 21 +++++++++++++------ .../include/xo/procedure2/DSimpleRcx.hpp | 6 +++++- .../xo/procedure2/detail/ARuntimeContext.hpp | 3 +++ .../procedure2/detail/IRuntimeContext_Any.hpp | 1 + .../detail/IRuntimeContext_DSimpleRcx.hpp | 2 ++ .../detail/IRuntimeContext_Xfer.hpp | 4 ++++ .../xo/procedure2/detail/RRuntimeContext.hpp | 3 +++ .../src/procedure2/ObjectPrimitives.cpp | 2 ++ .../facet/IRuntimeContext_DSimpleRcx.cpp | 6 ++++++ xo-procedure2/utest/DSimpleRcx.test.cpp | 13 ++++++++++-- .../include/xo/reader2/ParserStateMachine.hpp | 1 + .../include/xo/reader2/SchematikaParser.hpp | 1 + .../include/xo/reader2/SchematikaReader.hpp | 3 +++ xo-reader2/src/reader2/SchematikaReader.cpp | 6 ++++++ .../include/xo/stringtable2/StringTable.hpp | 1 + 22 files changed, 99 insertions(+), 9 deletions(-) diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp index 3323f7d7..1f3a8f57 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include #include @@ -19,6 +20,7 @@ namespace xo { **/ class DVsmRcx { public: + using StringTable = xo::scm::StringTable; using AAllocator = xo::mm::AAllocator; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; @@ -26,6 +28,7 @@ namespace xo { DVsmRcx(VirtualSchematikaMachine * vsm); obj allocator() const noexcept; + StringTable * stringtable() const noexcept; obj error_allocator() const noexcept; void visit_pools(const MemorySizeVisitor & visitor) const; diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 290eaf09..382dbc5d 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -91,6 +91,8 @@ namespace xo { obj allocator() const noexcept; /** allocator for runtime errors **/ obj error_allocator() const noexcept; + /** global unique-string table **/ + StringTable * stringtable() noexcept; /** true iff parser is at top-level -> does not contain * state for a incomplete/partial expression diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IRuntimeContext_DVsmRcx.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IRuntimeContext_DVsmRcx.hpp index 0305e3e5..1b4c1567 100644 --- a/xo-interpreter2/include/xo/interpreter2/detail/IRuntimeContext_DVsmRcx.hpp +++ b/xo-interpreter2/include/xo/interpreter2/detail/IRuntimeContext_DVsmRcx.hpp @@ -49,6 +49,8 @@ namespace xo { // const methods /** default allocator to use for objects **/ static obj allocator(const DVsmRcx & self) noexcept; + /** stringtable for unique symbols **/ + static StringTable * stringtable(const DVsmRcx & self) noexcept; /** invoke visitor for each distinct memory pool **/ static void visit_pools(const DVsmRcx & self, MemorySizeVisitor visitor); diff --git a/xo-interpreter2/src/interpreter2/DVsmRcx.cpp b/xo-interpreter2/src/interpreter2/DVsmRcx.cpp index fa81b9c8..b7ea4112 100644 --- a/xo-interpreter2/src/interpreter2/DVsmRcx.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmRcx.cpp @@ -25,6 +25,12 @@ namespace xo { return vsm_->error_allocator(); } + StringTable * + DVsmRcx::stringtable() const noexcept + { + return vsm_->stringtable(); + } + void DVsmRcx::visit_pools(const MemorySizeVisitor & visitor) const { diff --git a/xo-interpreter2/src/interpreter2/IRuntimeContext_DVsmRcx.cpp b/xo-interpreter2/src/interpreter2/IRuntimeContext_DVsmRcx.cpp index d201051a..e879d4ed 100644 --- a/xo-interpreter2/src/interpreter2/IRuntimeContext_DVsmRcx.cpp +++ b/xo-interpreter2/src/interpreter2/IRuntimeContext_DVsmRcx.cpp @@ -21,6 +21,12 @@ namespace xo { return self.allocator(); } + auto + IRuntimeContext_DVsmRcx::stringtable(const DVsmRcx & self) noexcept -> StringTable * + { + return self.stringtable(); + } + auto IRuntimeContext_DVsmRcx::visit_pools(const DVsmRcx & self, MemorySizeVisitor visitor) -> void { diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index d459622a..5633c7d0 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -100,6 +100,12 @@ namespace xo { return error_mm_.to_op(); } + StringTable * + VirtualSchematikaMachine::stringtable() noexcept + { + return reader_.stringtable(); + } + bool VirtualSchematikaMachine::is_at_toplevel() const noexcept { diff --git a/xo-procedure2/idl/RuntimeContext.json5 b/xo-procedure2/idl/RuntimeContext.json5 index 46623b45..fe1254b0 100644 --- a/xo-procedure2/idl/RuntimeContext.json5 +++ b/xo-procedure2/idl/RuntimeContext.json5 @@ -5,6 +5,7 @@ output_impl_subdir: "detail", // includes in ARuntimeContext.hpp includes: [ + "", "", "" ], @@ -46,6 +47,15 @@ noexcept: true, attributes: [], }, + { + name: "stringtable", + doc: [ "stringtable for unique symbols" ], + return_type: "StringTable *", + args: [], + const: true, + noexcept: true, + attributes: [], + }, { name: "visit_pools", doc: [ "invoke visitor for each distinct memory pool" ], diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp index 07c19c4f..43310575 100644 --- a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp +++ b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp @@ -87,27 +87,36 @@ namespace xo { /** @defgroup scm-primitive-ctors constructors **/ ///@{ - Primitive(std::string_view name, Fn fn) + Primitive(std::string_view name, obj type, Fn fn) : name_{name}, + type_{type}, fn_td_{Reflect::require()}, fn_{fn} {} static Primitive * _make(obj mm, std::string_view name, Fn fn) { void * mem = mm.alloc_for(); - return new (mem) Primitive(name, fn); + return new (mem) Primitive(name, obj(), fn); } + static Primitive * _make(obj mm, + std::string_view name, + obj type, + Fn fn) + { + void * mem = mm.alloc_for(); + + return new (mem) Primitive(name, type, fn); + } + ///@} /** @defgroup scm-primitive-methods general methods **/ ///@{ - TypeDescr fn_td() const noexcept { return fn_td_; } - - std::string_view name() const noexcept { return name_; } - static constexpr std::int32_t n_args() noexcept { return Traits::n_args; } + TypeDescr fn_td() const noexcept { return fn_td_; } + std::string_view name() const noexcept { return name_; } bool is_nary() const noexcept { return false; } obj apply_nocheck(obj rcx, const DArray * args) { diff --git a/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp b/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp index 1efb802e..6a7163d1 100644 --- a/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp +++ b/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include namespace xo { @@ -21,13 +22,16 @@ namespace xo { using MemorySizeVisitor = xo::mm::MemorySizeVisitor; public: - DSimpleRcx(obj mm) : allocator_{mm} {} + DSimpleRcx(obj mm, StringTable * st) + : allocator_{mm}, stringtable_{st} {} obj allocator() const noexcept { return allocator_; } + StringTable * stringtable() const noexcept { return stringtable_; } void visit_pools(const MemorySizeVisitor & visitor) const; private: obj allocator_; + StringTable * stringtable_ = nullptr; }; } /*namespace scm*/ diff --git a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp index 820dd8dd..716463d2 100644 --- a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp @@ -14,6 +14,7 @@ #pragma once // includes (via {facet_includes}) +#include #include #include #include @@ -54,6 +55,8 @@ public: virtual void _drop(Opaque d) const noexcept = 0; /** default allocator to use for objects **/ virtual obj allocator(Copaque data) const noexcept = 0; + /** stringtable for unique symbols **/ + virtual StringTable * stringtable(Copaque data) const noexcept = 0; /** invoke visitor for each distinct memory pool **/ virtual void visit_pools(Copaque data, MemorySizeVisitor visitor) const = 0; diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp index 2caa9d34..b72f934f 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp @@ -61,6 +61,7 @@ namespace scm { // const methods [[noreturn]] obj allocator(Copaque) const noexcept override { _fatal(); } + [[noreturn]] StringTable * stringtable(Copaque) const noexcept override { _fatal(); } [[noreturn]] void visit_pools(Copaque, MemorySizeVisitor) const override { _fatal(); } // nonconst methods diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp index 62d3e12d..82ab5219 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp @@ -49,6 +49,8 @@ namespace xo { // const methods /** default allocator to use for objects **/ static obj allocator(const DSimpleRcx & self) noexcept; + /** stringtable for unique symbols **/ + static StringTable * stringtable(const DSimpleRcx & self) noexcept; /** invoke visitor for each distinct memory pool **/ static void visit_pools(const DSimpleRcx & self, MemorySizeVisitor visitor); diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp index 6257abb4..5dc9de5f 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp @@ -13,6 +13,7 @@ #pragma once +#include #include #include @@ -49,6 +50,9 @@ namespace scm { obj allocator(Copaque data) const noexcept override { return I::allocator(_dcast(data)); } + StringTable * stringtable(Copaque data) const noexcept override { + return I::stringtable(_dcast(data)); + } void visit_pools(Copaque data, MemorySizeVisitor visitor) const override { return I::visit_pools(_dcast(data), visitor); } diff --git a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp index 5840743e..6553648c 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp @@ -57,6 +57,9 @@ public: obj allocator() const noexcept { return O::iface()->allocator(O::data()); } + StringTable * stringtable() const noexcept { + return O::iface()->stringtable(O::data()); + } void visit_pools(MemorySizeVisitor visitor) const { return O::iface()->visit_pools(O::data(), visitor); } diff --git a/xo-procedure2/src/procedure2/ObjectPrimitives.cpp b/xo-procedure2/src/procedure2/ObjectPrimitives.cpp index fcb8ba20..c247ab8c 100644 --- a/xo-procedure2/src/procedure2/ObjectPrimitives.cpp +++ b/xo-procedure2/src/procedure2/ObjectPrimitives.cpp @@ -75,6 +75,8 @@ namespace xo { auto cdr_list = obj::from(cdr); + //auto T = DTypeVarRef::_make(rcx.allocator(), "T"); + return DList::cons(rcx.allocator(), car, cdr_list.data()); diff --git a/xo-procedure2/src/procedure2/facet/IRuntimeContext_DSimpleRcx.cpp b/xo-procedure2/src/procedure2/facet/IRuntimeContext_DSimpleRcx.cpp index 2331b7c1..82dd310e 100644 --- a/xo-procedure2/src/procedure2/facet/IRuntimeContext_DSimpleRcx.cpp +++ b/xo-procedure2/src/procedure2/facet/IRuntimeContext_DSimpleRcx.cpp @@ -21,6 +21,12 @@ namespace xo { return self.allocator(); } + auto + IRuntimeContext_DSimpleRcx::stringtable(const DSimpleRcx & self) noexcept -> StringTable * + { + return self.stringtable(); + } + auto IRuntimeContext_DSimpleRcx::visit_pools(const DSimpleRcx & self, MemorySizeVisitor visitor) -> void { diff --git a/xo-procedure2/utest/DSimpleRcx.test.cpp b/xo-procedure2/utest/DSimpleRcx.test.cpp index cab1362d..365bd3f6 100644 --- a/xo-procedure2/utest/DSimpleRcx.test.cpp +++ b/xo-procedure2/utest/DSimpleRcx.test.cpp @@ -6,12 +6,14 @@ #include #include #include +#include #include #include namespace xo { using xo::scm::DSimpleRcx; using xo::scm::ARuntimeContext; + using xo::scm::StringTable; using xo::mm::AAllocator; using xo::mm::DArena; using xo::mm::ArenaConfig; @@ -30,12 +32,17 @@ namespace xo { { ArenaConfig cfg { .name_ = "testarena", .size_ = 4*1024 }; + DArena arena = DArena::map(cfg); auto alloc = with_facet::mkobj(&arena); - DSimpleRcx rcx(alloc); + auto stbl = StringTable(1024 /*hint_max_capacity*/, + false /*!debug_flag*/); + + DSimpleRcx rcx(alloc, &stbl); REQUIRE((void*)rcx.allocator().data() == (void*)alloc.data()); + REQUIRE(rcx.stringtable() == &stbl); } TEST_CASE("DSimpleRcx-as-ARuntimeContext", "[procedure2][DSimpleRcx]") @@ -44,8 +51,10 @@ namespace xo { .size_ = 4*1024 }; DArena arena = DArena::map(cfg); auto alloc = with_facet::mkobj(&arena); + auto stbl = StringTable(1024 /*hint_max_capacity*/, + false /*!debug_flag*/); - DSimpleRcx rcx(alloc); + DSimpleRcx rcx(alloc, &stbl); obj rcx_obj = with_facet::mkobj(&rcx); // verify we can recover allocator from obj diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index a7726c35..2ea90466 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -88,6 +88,7 @@ namespace xo { bool debug_flag() const noexcept { return debug_flag_; } ParserStack * stack() const noexcept { return stack_; } obj expr_alloc() const noexcept { return expr_alloc_; } + StringTable * stringtable() noexcept { return &stringtable_; } DGlobalSymtab * global_symtab() const noexcept { return global_symtab_.data(); } DLocalSymtab * local_symtab() const noexcept { return local_symtab_; } DGlobalEnv * global_env() const noexcept { return global_env_.data(); } diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index dd6ae341..ce83dd8a 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -185,6 +185,7 @@ namespace xo { DGlobalSymtab * global_symtab() const noexcept; DGlobalEnv * global_env() const noexcept; + StringTable * stringtable() noexcept { return psm_.stringtable(); } bool debug_flag() const { return debug_flag_; } diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index 0761b6e3..8b24f775 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -60,6 +60,9 @@ namespace xo { /** top-level global environment (e.g. contains built-in primitives) **/ DGlobalEnv * global_env() const noexcept; + /** global unique-string table **/ + StringTable * stringtable() noexcept; + /** visit reader-owned memory pools; call visitor(info) for each. * Specifically exclude expr_alloc, since we don't consider * that reader-owned diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index de815f97..388c5266 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -38,6 +38,12 @@ namespace xo { return parser_.global_env(); } + StringTable * + SchematikaReader::stringtable() noexcept + { + return parser_.stringtable(); + } + void SchematikaReader::visit_pools(const MemorySizeVisitor & visitor) const { diff --git a/xo-stringtable2/include/xo/stringtable2/StringTable.hpp b/xo-stringtable2/include/xo/stringtable2/StringTable.hpp index 8d0354c8..2a0d5705 100644 --- a/xo-stringtable2/include/xo/stringtable2/StringTable.hpp +++ b/xo-stringtable2/include/xo/stringtable2/StringTable.hpp @@ -27,6 +27,7 @@ namespace xo { using size_type = StringMap::size_type; public: + /** hint_max_capacity in bytes = capacity for strings **/ StringTable(size_type hint_max_capacity, bool debug_flag = false);