From f4e5261a729058cbe6db735f4403c647cc3c04a6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 17 Jan 2026 18:20:51 -0500 Subject: [PATCH 001/258] xo-indentlog: bugfix: lazy lpos b/c state may be stale. This is because xputc() only *might* be called. ostream may update streambuf's buffer without calling streambuf virtual methods --- .../include/xo/indentlog/log_streambuf.hpp | 215 ++++++++++++++---- xo-indentlog/utest/log_streambuf.test.cpp | 77 ++++++- 2 files changed, 243 insertions(+), 49 deletions(-) diff --git a/xo-indentlog/include/xo/indentlog/log_streambuf.hpp b/xo-indentlog/include/xo/indentlog/log_streambuf.hpp index b6e9305d..36166fce 100644 --- a/xo-indentlog/include/xo/indentlog/log_streambuf.hpp +++ b/xo-indentlog/include/xo/indentlog/log_streambuf.hpp @@ -19,7 +19,7 @@ namespace xo { public: struct rewind_state { explicit rewind_state(std::size_t solpos, std::size_t color_esc, std::uint32_t p) - : solpos{solpos}, color_escape_chars{color_esc}, pos{p} {} + : solpos{solpos}, color_escape_chars{color_esc}, pos{p} {} std::size_t solpos = 0; std::size_t color_escape_chars = 0; @@ -33,17 +33,39 @@ namespace xo { } /*ctor*/ std::streamsize capacity() const { return this->buf_v_.size(); } - char const * lo() const { return this->pbase(); } - char const * hi() const { return this->lo() + this->capacity(); } + const char * lo() const { return this->pbase(); } + const char * hi() const { return this->lo() + this->capacity(); } std::uint32_t pos() const { return this->pptr() - this->pbase(); } + /** output position (relative to pbase) when local state last computed. Exposed here for unit tests **/ + const char * _local_ppos() const { return local_ppos_; } + /** position (relative to pbase) one character after last \n or \r. For unit tests **/ + std::uint32_t _solpos() const { return solpos_; } + /** start of incomplete color-escape sequence **/ + const char * _color_escape_start() const { return color_escape_start_; } + /** number of non-printing chars after @ref solpos_ from completed color-escape sequences **/ + std::uint32_t _color_escape_chars() const { return color_escape_chars_; } + /** number of visible characters since start of line (last \n or \r) **/ std::uint32_t lpos() const { - assert(pos() >= solpos_ + color_escape_chars_); + if (debug_flag_) { + std::cerr << "log_streambuf::lpos: enter" << std::endl; + } + + // logically-const. lazy implementation + log_streambuf * self = const_cast(this); + + self->_check_update_local_state(); + return pos() - solpos_ - color_escape_chars_; } rewind_state checkpoint() const { + // logically-const. lazy implementation + log_streambuf * self = const_cast(this); + + self->_check_update_local_state(); + return rewind_state(solpos_, color_escape_chars_, pos()); } @@ -56,6 +78,7 @@ namespace xo { /* tells parent our buffer extent */ this->setp(p_lo, p_hi); + this->local_ppos_ = 0; this->solpos_ = 0; this->color_escape_chars_ = 0; this->color_escape_start_ = nullptr; @@ -69,12 +92,16 @@ namespace xo { << std::endl; } - /* .setp(): using for side effect: sets .pptr to .pbase */ + /* .setp(): using just for side effect: sets .pptr to .pbase */ this->setp(this->pbase(), this->epptr()); + /* advance pptr to saved position */ this->pbump(s.pos); + this->local_ppos_ = this->pptr() - this->pbase(); this->solpos_ = s.solpos; this->color_escape_chars_ = s.color_escape_chars; + /* assuming we never try to capture rewind state with incomplete color escape */ + this->color_escape_start_ = nullptr; } protected: @@ -87,6 +114,8 @@ namespace xo { assert(old_n <= static_cast(buf_v_.size())); assert(new_z > buf_v_.capacity()); + /* note: local_ppos_ invariant across expand_to() */ + this->buf_v_.resize(new_z); char * p_base = &(this->buf_v_[0]); @@ -132,51 +161,21 @@ namespace xo { std::memcpy(this->pptr(), s, ncopied); - /* scan range [pptr, pptr+n] for: - * 1. completed color escape sequences \033..m - * - account for chars in these sequences, since non-printing - * 2. newlines (and carriage returns) - * - remember position of last {newline or carriage return) - */ - for (char const * p_lo = this->pptr(), * p_hi = p_lo + n, * p = p_lo; p < p_hi; ++p) { - if (*p == '\n' || *p == '\r') { - this->solpos_ = (p+1 - this->pbase()); - /* reset, since these chars relevant as correction to solpos */ - this->color_escape_chars_ = 0; - /* -> incomplete color escape, broken by newline */ - this->color_escape_start_ = nullptr; - } else if (*p == '\033') { - if (debug_flag_) { - std::cout << "xsputn: \\033 at p-p_lo=" << (p - p_lo) << std::endl; - } - this->color_escape_start_ = p; - } else if (this->color_escape_start_ != nullptr) { - if (*p == 'm') { - /* escape seq non-printing including both endpoints */ - std::int64_t esc_chars = (p+1 - color_escape_start_); - this->color_escape_chars_ += esc_chars; - - if (debug_flag_) { - std::cout << "xsputn: m at p-p_lo" << (p - p_lo) << " +" << esc_chars - << " -> color_escape_chars=" << color_escape_chars_ << std::endl; - } - this->color_escape_start_ = nullptr; - } else if (!isdigit(*p) && (*p != '[') && (*p != ';')) { - /* not color escape after all */ - this->color_escape_start_ = nullptr; - } - } - } - this->pbump(ncopied); + /* now {pbase, pptr} consistent with new input */ + + this->_check_update_local_state(); + return ncopied; } /*xsputn*/ virtual int_type overflow(int_type new_ch) override { + char * old_base = this->pbase(); char * old_pptr = this->pptr(); - std::streamsize old_n = old_pptr - this->pbase(); + /* #of chars buffered */ + std::streamsize old_n = old_pptr - old_base; assert(old_n <= static_cast(this->buf_v_.size())); @@ -184,6 +183,7 @@ namespace xo { std::cout << "overflow: new_ch=" << quoted_char(new_ch) << std::endl; } + /* increase buffer size */ this->expand_to(2 * buf_v_.size()); this->buf_v_[old_n] = new_ch; @@ -191,6 +191,8 @@ namespace xo { if ((new_ch == static_cast('\n')) || (new_ch == static_cast('\r'))) { this->solpos_ = this->pos(); + + // what if new_ch starts color escape ? } if (new_ch == Traits::eof()) { @@ -235,8 +237,130 @@ namespace xo { } /*seekoff*/ private: + void _update_local_state_char(const char * p_lo, const char * p) + { + if ((*p == '\n') || (*p == '\r')) { + this->solpos_ = (p+1 - this->pbase()); + /* reset, since these chars relevant as correction to solpos */ + this->color_escape_chars_ = 0; + /* -> incomplete color escape, broken by newline */ + this->color_escape_start_ = nullptr; + } else if (*p == '\033') { + if (debug_flag_) [[unlikely]] { + std::cout << "xsputn: \\033 at p-p_lo=" << (p - p_lo) << std::endl; + } + this->color_escape_start_ = p; + } else if (this->color_escape_start_ != nullptr) { + if (*p == 'm') { + /* escape seq non-printing including both endpoints */ + std::int64_t esc_chars = (p+1 - color_escape_start_); + + this->color_escape_chars_ += esc_chars; + + if (debug_flag_) [[unlikely]] { + std::cout << "xsputn: m at p-p_lo" << (p - p_lo) << " +" << esc_chars + << " -> color_escape_chars=" << color_escape_chars_ << std::endl; + } + this->color_escape_start_ = nullptr; + } else if (!isdigit(*p) && (*p != '[') && (*p != ';')) { + /* not color escape after all */ + this->color_escape_start_ = nullptr; + } + } + } + + /** recognize stale local state vars: + * @ref solpos_, @ref color_escape_chars_, @ref color_escape_start_. + * + * Require: + * - {pbase, pptr} in consistent state + * Promise: + * - @c local_ppos_ + @c pbase = @c pptr + * - @c solpos_, @c color_escape_chars_, @c color_escape_start_ all up-to-date + **/ + void _check_update_local_state() { + const char * p0 = this->pbase(); + const char * pn = this->pptr(); + + if (debug_flag_) { + std::cerr << "_check_update_local_state:" << std::endl; + std::cerr << " buf: (p0=" << (void*)p0 << ", pn=" << (void*)pn << ")" << std::endl; + std::cerr << " solpos_=" << solpos_ << ", color_escape_chars_=" << color_escape_chars_ << std::endl; + } + + if (p0 + local_ppos_ == pn) [[likely]] { + // solpos_, color_escape_chars_, color_escape_start_ all up-to-date + } else { + // [pnew, pn): input that hasn't been incorporated into + // {solpos_, color_escape_chars_, color_escape_start_) + + const char * pnew = this->pbase() + this->local_ppos_; + + if (debug_flag_) { + std::cerr << "_check_update_local_state: range: (pnew=" << (void*)pnew << ", pn=" << (void*)pn << ")" << std::endl; + } + + for(const char * p = pnew; p < pn; ++p) { + this->_update_local_state_char(p0, p); + } + } + + // solpos_, color_escape_chars_, color_escape_start_ all up-to-date + // for current buffered contents + + this->local_ppos_ = pn - p0; + + if (debug_flag_) { + std::cerr << "_check_update_local_state: pos=" << pos(); + std::cerr << ", solpos=" << solpos_; + std::cerr << ", color_escape_chars=" << color_escape_chars_ << std::endl; + } + + assert(pos() >= solpos_ + color_escape_chars_); + } + + private: + /* + * pbase: start of buffered text. Thils will be address of buf_v_[0] + * + * + * pbase pptr epptr + * v >e1< >e2< v v + * |xx\xxEEExxx\xxxxxxxEExxxxEExxxxxxxEExxx\xEExxxxxx..................| + * ^ ^<------new-------> + * solpos local_ppos + * + * solpos : first character after newline (stale) + * color_escape_pos : e1+e2+.. (stale) + * new : new characters not reflected + * in local_ppos_, color_escape_chars_ etc. + * + * Legend: + * [\] newline + * [x] visible character + * [E] color escape chars + * + * + * after _check_update_local_state(): + * + * + * pbase pptr epptr + * v >e1< v v + * |xx\xxEEExxx\xxxxxxxEExxxxEExxxxxxxEExxx\xEExxxxxx..................| + * ^ ^ + * solpos local_ppos + * + */ + + /** @defgroup logstreambuf-instance-vars **/ + ///@{ + + /** value of pptr (relative to pbase) when _check_update_local_state() last ran **/ + std::size_t local_ppos_ = 0; /** position (relative to pbase) one character after last \n or \r. - * Use to drive @ref lpos + * Use to drive @ref lpos. This _has_ to be lazy, since + * xsputn() isn'g guaranteed to be called when there's room in + * in buffer. **/ std::size_t solpos_ = 0; /** number of non-printing chars after @ref solpos_, from @@ -245,11 +369,14 @@ namespace xo { **/ std::size_t color_escape_chars_ = 0; /** non-null: start of incomplete color escape sequence **/ - char const * color_escape_start_ = nullptr; + const char * color_escape_start_ = nullptr; + /** buffered output stored here **/ std::vector buf_v_; /** true to debug log_streambuf itself **/ bool debug_flag_ = false; + + ///@} }; /*log_streambuf*/ } /*namespace xo*/ diff --git a/xo-indentlog/utest/log_streambuf.test.cpp b/xo-indentlog/utest/log_streambuf.test.cpp index 8098d881..656d8b97 100644 --- a/xo-indentlog/utest/log_streambuf.test.cpp +++ b/xo-indentlog/utest/log_streambuf.test.cpp @@ -1,30 +1,97 @@ /* @file log_streambuf.test.cpp */ -#include "xo/indentlog/log_streambuf.hpp" -#include "xo/indentlog/print/tag.hpp" -#include "xo/indentlog/print/quoted.hpp" +#include "scope.hpp" +#include "log_streambuf.hpp" +#include "print/tag.hpp" +#include "print/quoted.hpp" #include //#include namespace ut { + using xo::xtag; + using xo::scope; using xo::log_streambuf; + using std::cerr; + using std::endl; + + TEST_CASE("log_streamhuf", "[log_streambuf]") + { + constexpr bool c_debug_flag = false; + //scope log(XO_DEBUG(c_debug_flag), "log_streambuf test"); - TEST_CASE("log_streamhuf", "[log_streambuf]") { std::size_t z = 16; - log_streambuf> sbuf(z); + log_streambuf> sbuf(z, c_debug_flag); std::ostream ss(&sbuf); + REQUIRE(sbuf.debug_flag() == c_debug_flag); + + if (c_debug_flag) { + cerr << "empty log_streambuf" << endl; + cerr << "sbuf.lo=" << (void*)sbuf.lo() << endl; + cerr << "sbuf.hi=" << (void*)sbuf.hi() << endl; + cerr << "sbuf._color_escape_chars=" << sbuf._color_escape_chars() << endl; + } + + //REQUIRE(sbuf.lo() == sbuf.pbase()); + REQUIRE(sbuf.capacity() == z); REQUIRE(sbuf.pos() == 0); + REQUIRE(sbuf._solpos() == 0); REQUIRE(sbuf.lpos() == 0); + // note: log_streambuf doesn't get control on every character + ss << '\n'; + if (c_debug_flag) { + cerr << "after single newline" << endl; + cerr << "sbuf.lo=" << (void*)sbuf.lo() << endl; + cerr << "sbuf.hi=" << (void*)sbuf.hi() << endl; + cerr << "sbuf._color_escape_chars=" << sbuf._color_escape_chars() << endl; + } + REQUIRE(sbuf.capacity() == z); REQUIRE(sbuf.pos() == 1); + // we don't know what sbuf._solpos is. Could be 0 or 1 depending on + // ostream implementation + bool ok = (sbuf._solpos() == 0) || (sbuf._solpos() == 1); + REQUIRE(ok); REQUIRE(sbuf.lpos() == 0); // at least on OSX } + TEST_CASE("log_streambuf_xtag", "[log_streambuf][xtag]") + { + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), "log_streambuf_xtag test"); + + std::size_t z = 16; + log_streambuf> sbuf(z, false); + std::ostream ss(&sbuf); + + ss <<"empty log_streambuf"; + ss << xtag("sbuf.lo", (void*)sbuf.lo()); + ss << xtag("sbuf.hi", (void*)sbuf.hi()); + ss << xtag("sbuf.color_escape_chars", sbuf._color_escape_chars()); + + //REQUIRE(sbuf.lo() == sbuf.pbase()); + + /* sbuf size will have been expanded */ + REQUIRE(sbuf.capacity() == 128); + REQUIRE(sbuf.pos() == 82); + REQUIRE(sbuf._solpos() == 0); + REQUIRE(sbuf.lpos() == 82); + + // note: log_streambuf doesn't get control on every character + + ss << '\n'; + + REQUIRE(sbuf.capacity() == 128); + REQUIRE(sbuf.pos() == 83); + REQUIRE(sbuf.lpos() == 0); + // note: solpos: updated b/c of call to lazy sbuf.lpos() + REQUIRE(sbuf._solpos() == 83); + } + // write test cases with some random strings. // for each string a list of tuples {ch,pos,lpos} From 15d9448d03c9cf80bdc31baabde85c1a84197534 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Jan 2026 17:59:46 -0500 Subject: [PATCH 002/258] xo-reader2 scaffold (fomo+arena version of xo-reader/) [WIP] --- CMakeLists.txt | 1 + xo-expression2/CMakeLists.txt | 13 +- xo-reader2/CMakeLists.txt | 42 ++++-- xo-reader2/DESIGN.md | 12 ++ xo-reader2/cmake/xo_reader2Config.cmake.in | 4 +- .../ISyntaxStateMachine_DExprSeqState.json5 | 13 ++ xo-reader2/idl/SyntaxStateMachine.json5 | 56 ++++++++ .../include/xo/reader2/DExprSeqState.hpp | 76 ++++++++++ .../include/xo/reader2/ExpressionParser.hpp | 80 +++++++++++ .../include/xo/reader2/ParserResult.hpp | 52 +++++++ xo-reader2/include/xo/reader2/ParserStack.hpp | 47 ++++++ .../include/xo/reader2/ParserStateMachine.hpp | 115 +++++++++++++++ xo-reader2/include/xo/reader2/Reader.hpp | 25 ++++ .../include/xo/reader2/SyntaxStateMachine.hpp | 22 +++ .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 78 ++++++++++ .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 87 ++++++++++++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 64 +++++++++ .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 88 ++++++++++++ .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 85 +++++++++++ .../include/xo/reader2/syntaxstatetype.hpp | 38 +++++ xo-reader2/src/reader2/CMakeLists.txt | 30 ++++ xo-reader2/src/reader2/DExprSeqState.cpp | 101 +++++++++++++ .../src/reader2/ISyntaxStateMachine_Any.cpp | 47 ++++++ .../ISyntaxStateMachine_DExprSeqState.cpp | 39 +++++ xo-reader2/src/reader2/ParserResult.cpp | 32 +++++ xo-reader2/src/reader2/ParserStack.cpp | 28 ++++ xo-reader2/src/reader2/ParserStateMachine.cpp | 134 ++++++++++++++++++ .../include/xo/tokenizer2/tokentype.hpp | 4 +- xo-tokenizer2/src/tokenizer2/tokentype.cpp | 2 +- 29 files changed, 1389 insertions(+), 26 deletions(-) create mode 100644 xo-reader2/DESIGN.md create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DExprSeqState.json5 create mode 100644 xo-reader2/idl/SyntaxStateMachine.json5 create mode 100644 xo-reader2/include/xo/reader2/DExprSeqState.hpp create mode 100644 xo-reader2/include/xo/reader2/ExpressionParser.hpp create mode 100644 xo-reader2/include/xo/reader2/ParserResult.hpp create mode 100644 xo-reader2/include/xo/reader2/ParserStack.hpp create mode 100644 xo-reader2/include/xo/reader2/ParserStateMachine.hpp create mode 100644 xo-reader2/include/xo/reader2/Reader.hpp create mode 100644 xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp create mode 100644 xo-reader2/include/xo/reader2/syntaxstatetype.hpp create mode 100644 xo-reader2/src/reader2/CMakeLists.txt create mode 100644 xo-reader2/src/reader2/DExprSeqState.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp create mode 100644 xo-reader2/src/reader2/ParserResult.cpp create mode 100644 xo-reader2/src/reader2/ParserStack.cpp create mode 100644 xo-reader2/src/reader2/ParserStateMachine.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 62046f0d..075c25e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,7 @@ add_subdirectory(xo-ordinaltree) # add_subdirectory(xo-tokenizer2) # schematika tokenizer (fomo) add_subdirectory(xo-expression2) # schematika expressions (fomo) +add_subdirectory(xo-reader2) # schematika expression parser (fomo) add_subdirectory(xo-interpreter2) # schematika interpreter (fomo) # add_subdirectory(xo-webutil) diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 28982fba..fe5cd540 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -91,18 +91,13 @@ xo_add_genfacetimpl( ) # ---------------------------------------------------------------- -# header-only library +# shared library add_subdirectory(src/expression2) +# ---------------------------------------------------------------- +# cmake helper (for external xo-expression2 users) + xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) -# ---------------------------------------------------------------- -# input dependencies -# -# NOTE: dependency set here must be kept consistent with -# xo-expression2/cmake/xo_expression2Config.cmake.in - -#xo_headeronly_dependency(${SELF_LIB} xo_flatstring) - # end CMakeLists.txt diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index a8508472..30732417 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -22,20 +22,36 @@ add_definitions(${PROJECT_CXX_FLAGS}) #add_subdirectory(utest) -# ---------------------------------------------------------------- -# header-only library +# note: manual target; generated code committed to git +xo_add_genfacet( + TARGET xo-reader2-facet-syntaxstatemachine + FACET SyntaxStateMachine + INPUT idl/SyntaxStateMachine.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 + ) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-exprseqstate + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExprSeqState + INPUT idl/ISyntaxStateMachine_DExprSeqState.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- +# shared library + +add_subdirectory(src/reader2) + +# ---------------------------------------------------------------- +# cmake helper (for external xo-reader2 users) -set(SELF_LIB xo_reader2) -xo_add_headeronly_library(${SELF_LIB}) -xo_install_library4(${SELF_LIB} ${PROJECT_NAME}Targets) xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) -# ---------------------------------------------------------------- -# input dependencies -# -# NOTE: dependency set here must be kept consistent with -# xo-reader2/cmake/xo_reader2Config.cmake.in - -#xo_headeronly_dependency(${SELF_LIB} xo_flatstring) - # end CMakeLists.txt diff --git a/xo-reader2/DESIGN.md b/xo-reader2/DESIGN.md new file mode 100644 index 00000000..69596c44 --- /dev/null +++ b/xo-reader2/DESIGN.md @@ -0,0 +1,12 @@ +Uses arena allocators for fast+efficient parsing. + +Composition of nested state machines. + +## SyntaxStateMachine + +a state machine dedicated to some particular Schematika syntax. +Examples: if-expression, type declaration, function call + +## DExprSeqState + +top-level expression sequence diff --git a/xo-reader2/cmake/xo_reader2Config.cmake.in b/xo-reader2/cmake/xo_reader2Config.cmake.in index b5c3cd5c..2b36efff 100644 --- a/xo-reader2/cmake/xo_reader2Config.cmake.in +++ b/xo-reader2/cmake/xo_reader2Config.cmake.in @@ -6,7 +6,9 @@ include(CMakeFindDependencyMacro) # must coordinate with xo_dependency() calls # in CMakeLists.txt # -#find_dependency(xo_flatstring) +find_dependency(xo_gc) +find_dependency(xo_tokenizer2) +find_dependency(xo_expression2) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") check_required_components("@PROJECT_NAME@") diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExprSeqState.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExprSeqState.json5 new file mode 100644 index 00000000..0d0cdcac --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExprSeqState.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExprSeqState", + using_doxygen: true, + repr: "DExprSeqState", + doc: [ "implement ASyntaxStateMachine for DExprSeqState" ], +} diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 new file mode 100644 index 00000000..0023a16e --- /dev/null +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -0,0 +1,56 @@ +{ + mode: "facet", + // includes in ASyntaxStateMachine.hpp + includes: [ + "\"ParserStateMachine.hpp\"", + "\"syntaxstatetype.hpp\"", + "", + ], + // extra includes in SyntaxStateMachine.hpp, if any + user_hpp_includes: [], + namespace1: "xo", + namespace2: "scm", + // text after includes, before ASyntaxStateMachine + pretext: ["// {pretex} here"], + facet: "SyntaxStateMachine", + detail_subdir: "ssm", + brief: "specialized state machine for parsing some particular schematika syntax", + using_doxygen: true, + doc: [ + "Assistant to schematika parser dedicated to particular syntax" + ], + types: [ + // { name: string, doc: [ string ], definition: string }, + ], + const_methods: [ + { + name: "ssm_type", + doc: ["identify a type of syntax state machine"], + return_type: "syntaxstatetype", + args: [], + const: true, + noexcept: true, + attributes: [], + }, + { + name: "get_expect_str", + doc: ["text describing expected/allowed input to this ssm in current state"], + return_type: "std::string_view", + args: [], + const: true, + noexcept: true, + attributes: [], + }, + ], + nonconst_methods: [ + { + name: "on_if_token", + doc: ["update state machine for incoming if-keyword-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, + ], +} diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp new file mode 100644 index 00000000..f1faed86 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -0,0 +1,76 @@ +/** @file DExprSeqState.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ParserStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include + +namespace xo { + namespace scm { + enum class exprseqtype { + /** toplevel interactive sequence. + * allows: rvalue expressions + **/ + toplevel_interactive, + /** toplevel non-interactive sequence. + * allows: + **/ + toplevel_batch, + /** counts number of valid enums **/ + N + }; + + /** @class DExprSeqState + * @brief state machine for parsing a sequence of expression + * + * Similar to exprseq_xs in xo-expresion + **/ + class DExprSeqState { + public: + using AAllocator = xo::mm::AAllocator; + + public: + explicit DExprSeqState(exprseqtype ty); + + /** start interactive top-level session **/ + static void start_interactive(obj mm, + ParserStateMachine * p_psm); + /** start non-interactive top-level session **/ + static void start_batch(obj mm, + ParserStateMachine * p_psm); + + public: + /** @defgroup scm-exprseq-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error mesages + **/ + std::string_view get_expect_str() const noexcept; + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_if_token(const Token & tk, ParserStateMachine * p_psm); + + ///@} + + private: + /** sequence type. accept rvalue expressions when + * this is toplevel_interactive. + * Always accept definitions and declarations. + **/ + exprseqtype seqtype_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExprSeqState.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpressionParser.hpp b/xo-reader2/include/xo/reader2/ExpressionParser.hpp new file mode 100644 index 00000000..e59464b5 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpressionParser.hpp @@ -0,0 +1,80 @@ +/** @file ExpressionParser.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ExprState.hpp" +#include +#include +#include + +namespace xo { + namespace scm { + /** @class ExpressionParser + * @brief Assemble Schematika expressions from token sequences + * + * Parser represents Each partially assembled expression by + * an ExprState object. + * Expreesions form a tree: + * each expression belongs to at most one parent. + * + **/ + class ExpressionParser { + public: + void push_exprstate(obj xstate); + + private: + /* TODO: + * ASymbolTable + * DLocalSymtab + * DGlobalSymtab + * + * Will also need + * DVariable + * DLambda + * + * For DGlobalSymtab perhaps use DArenaHashMap. + * May also want to use DArenaHashMap+DArena to intern strings + * + * Also: + * TypeUnifier + */ + + /** Arena for internal parsing stack. + * Must be owned exclusively because destructively + * modified as parser completes parsing of each sub-expression + * + * Contents will be a stack of ExprState instances + **/ + DArena parser_alloc_; + +#ifdef NOT_YET + /** Arena for internal environment stack. + * This represents just nesting for environments. + * Details for each frame survive parsing and are + * stored in @ref expr_alloc_. + * Maybe that means we don't need env_alloc_ + **/ + DArena env_alloc_; +#endif + + /** Allocator for parsed expressions. + * Information available during subsequent execution + * (whether compiling or interpreting) must be stored here. + * + * Also use this allocator for error messages arising + * during parsing + * + * Memory use patterns for executions are not predictable, + * and require garbage collection, e.g. DX1Collector. + * + * May alternatively be able to use DArena in a compile-only + * scenario, where top-level Expressions can be discarded + * once compiled. + **/ + obj expr_alloc_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ExpressionParser.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserResult.hpp b/xo-reader2/include/xo/reader2/ParserResult.hpp new file mode 100644 index 00000000..3aadbdae --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -0,0 +1,52 @@ +/** @file ParserResult.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include +#include +#include + +namespace xo { + namespace scm { + enum class parser_result_type { + /** no result yet (no input or incomplete expression) **/ + none, + /** emit expression **/ + expression, + /** emit parsing error **/ + error, + N + }; + + class ParserResult { + public: + ParserResult() = default; + ParserResult(parser_result_type type, + obj expr, + std::string_view error_src_fn, + const DString * error_description); + + /** create ParserResult for a parsing error. + * Reporting detailed message @p errmsg + * from syntax state machine @p ssm + **/ + static ParserResult error(std::string_view ssm, + const DString * errmsg); + + parser_result_type result_type() const { return result_type_; } + obj result_expr() const { return result_expr_; } + const DString * error_description() const { return error_description_; } + + private: + parser_result_type result_type_ = parser_result_type::none; + obj result_expr_; + std::string_view error_src_fn_; + const DString * error_description_ = nullptr; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ParserResult.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserStack.hpp b/xo-reader2/include/xo/reader2/ParserStack.hpp new file mode 100644 index 00000000..424be42b --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParserStack.hpp @@ -0,0 +1,47 @@ +/** @file ParserStack.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include +#include + +namespace xo { + namespace scm { + + /** @brief A stack of expression state machines + * + * Each state machine is dedicated to a particular syntax instance. + * The innermost machine is in xsm; machines for surrounding expressions + * are in progressively removed frames reached via parent links. + **/ + class ParserStack { + public: + using AAllocator = xo::mm::AAllocator; + + public: + ParserStack(obj ssm, ParserStack * parent); + + /** create new top of stack for syntax @p ssm, using memory from @p mm. + * previous stack given by @p parent + **/ + ParserStack * push(obj mm, + obj ssm); + + obj top() const noexcept { return ssm_; } + ParserStack * parent() const noexcept { return parent_; } + + private: + /** top of parsing stack: always non-null **/ + obj ssm_; + /** remainder of parsing stack excluding top **/ + ParserStack * parent_ = nullptr; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ParserStack.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp new file mode 100644 index 00000000..339fa029 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -0,0 +1,115 @@ +/** @file ParserStateMachine.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ParserResult.hpp" +#include +#include +#include + +namespace xo { + namespace scm { + // defined in ssm/ASyntaxStateMachine.hpp, but + // including here would create include cycle + // + class ASyntaxStateMachine; + + // note: load-bearing to forward-declare ParserStack, + // because ASyntaxStateMachine.hpp includes ParserStateMachine.hpp; + // before obj is defined. + class ParserStack; + + /** @brief State machine embodying Schematika parser + **/ + class ParserStateMachine { + public: + using AAllocator = xo::mm::AAllocator; + using ArenaConfig = xo::mm::ArenaConfig; + using DArena = xo::mm::DArena; + + public: + ParserStateMachine(const ArenaConfig & config); + + /** @defgroup scm-parserstatemachine-bookkeeping bookkeeping methods **/ + ///@{ + + /** push syntax @p ssm onto @ref stack_ **/ + void push_ssm(obj ssm); + + ///@} + + /** @defgroup scm-parserstatemachine-inputmethods input methods **/ + ///@{ + + /** update state to respond to input token @p tk. + * record output (if any) in @ref result_ + **/ + void on_token(const Token & tk); + + /** update state for incoming if-token @p tk **/ + void on_if_token(const Token & tk); + + ///@} + + /** @defgroup scm-parserstatemachine-error-entrypoints error entry points **/ + ///@{ + + /** capture error message @p errmsg from @p ssm_name, + * as current state machine output. + * + * @p errmsg will have been allocated from the @p expr_alloc_ allocator + **/ + void capture_error(std::string_view ssm_name, + const DString * errmsg); + + /** report illegal input from syntax state machine @p ssm_name + * recognized on input token @p tk. @p expect_str describes + * expected input in that state + **/ + void illegal_input_on_token(std::string_view ssm_name, + const Token & tk, + std::string_view expect_str); + + ///@} + + private: + /** Arena for internal parsing stack. + * Must be owned exclusively because destructively + * modified as parser completes parsing of each sub-expression + * + * Contents will be a stack of ExprState instances + **/ + DArena parser_alloc_; + + /** parser stack. Memory from @ref parser_alloc_ **/ + ParserStack * stack_ = nullptr; + + /** Allocator for parsed expressions. + * Information available during subsequent execution + * (whether compiling or interpreting) must be stored here. + * + * Also use this allocator for error messages arising + * during parsing + * + * Memory use patterns for executions are not predictable, + * and benefit from garbage collection, e.g. DX1Collector. + * + * May alternatively be able to use DArena in a compile-only + * scenario, where top-level Expressions can be discarded + * once compiled. + **/ + obj expr_alloc_; + + /** current output from parser **/ + ParserResult result_; + + /** true to enable debug output **/ + bool debug_flag_ = false; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ParserStateMachine.hpp */ diff --git a/xo-reader2/include/xo/reader2/Reader.hpp b/xo-reader2/include/xo/reader2/Reader.hpp new file mode 100644 index 00000000..9ae65d61 --- /dev/null +++ b/xo-reader2/include/xo/reader2/Reader.hpp @@ -0,0 +1,25 @@ +/** @file Reader.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include + +namespace xo { + namespace scm { + /** @class Reader + * @brief Assemble Schematika expressions from lexical tokens + **/ + class Reader { + public: + private: + /** tokenizer: assembles Schematika tokens from text **/ + Tokenizer tokenizer_; + + /** parser: assemble Schematika expressions from token sequences **/ + ExpressionParser parser_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end Reader.hpp */ diff --git a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp new file mode 100644 index 00000000..deda9e1d --- /dev/null +++ b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp @@ -0,0 +1,22 @@ +/** @file SyntaxStateMachine.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SyntaxStateMachine.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/SyntaxStateMachine.json5] + **/ + +#pragma once + +#include "ssm/ASyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Any.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "ssm/RSyntaxStateMachine.hpp" + + +/* end SyntaxStateMachine.hpp */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp new file mode 100644 index 00000000..a519b246 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -0,0 +1,78 @@ +/** @file ASyntaxStateMachine.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SyntaxStateMachine.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/SyntaxStateMachine.json5] + **/ + +#pragma once + +// includes (via {facet_includes}) +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include +#include +#include + +// {pretex} here + +namespace xo { +namespace scm { + +using Copaque = const void *; +using Opaque = void *; + +/** +Assistant to schematika parser dedicated to particular syntax +**/ +class ASyntaxStateMachine { +public: + /** @defgroup scm-syntaxstatemachine-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; + ///@} + + /** @defgroup scm-syntaxstatemachine-methods **/ + ///@{ + // const methods + /** RTTI: unique id# for actual runtime data representation **/ + virtual typeseq _typeseq() const noexcept = 0; + /** identify a type of syntax state machine **/ + virtual syntaxstatetype ssm_type(Copaque data) const noexcept = 0; + /** text describing expected/allowed input to this ssm in current state **/ + virtual std::string_view get_expect_str(Copaque data) const noexcept = 0; + + // nonconst methods + /** update state machine for incoming if-keyword-token @p tk **/ + virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + ///@} +}; /*ASyntaxStateMachine*/ + +/** Implementation ISyntaxStateMachine_DRepr of ASyntaxStateMachine for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = ISyntaxStateMachine_DRepr; + * }; + * + * then ISyntaxStateMachine_ImplType --> ISyntaxStateMachine_DRepr + **/ +template +using ISyntaxStateMachine_ImplType = xo::facet::FacetImplType; + +} /*namespace scm*/ +} /*namespace xo*/ + +/* ASyntaxStateMachine.hpp */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp new file mode 100644 index 00000000..2d5dd0c3 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -0,0 +1,87 @@ +/** @file ISyntaxStateMachine_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SyntaxStateMachine.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/SyntaxStateMachine.json5] + **/ + +#pragma once + +#include "ASyntaxStateMachine.hpp" +#include + +namespace xo { namespace scm { class ISyntaxStateMachine_Any; } } + +namespace xo { +namespace facet { + +template <> +struct FacetImplementation +{ + using ImplType = xo::scm::ISyntaxStateMachine_Any; +}; + +} +} + +namespace xo { +namespace scm { + + /** @class ISyntaxStateMachine_Any + * @brief ASyntaxStateMachine implementation for empty variant instance + **/ + class ISyntaxStateMachine_Any : public ASyntaxStateMachine { + public: + /** @defgroup scm-syntaxstatemachine-any-type-traits **/ + ///@{ + + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + + ///@} + /** @defgroup scm-syntaxstatemachine-any-methods **/ + ///@{ + + const ASyntaxStateMachine * iface() const { return std::launder(this); } + + // from ASyntaxStateMachine + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] syntaxstatetype ssm_type(Copaque) const noexcept override { _fatal(); } + [[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); } + + // nonconst methods + [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; + + ///@} + + private: + /** @defgraoup scm-syntaxstatemachine-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup scm-syntaxstatemachine-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace scm */ +} /*namespace xo */ + +/* ISyntaxStateMachine_Any.hpp */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp new file mode 100644 index 00000000..b1d889b1 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -0,0 +1,64 @@ +/** @file ISyntaxStateMachine_DExprSeqState.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExprSeqState.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExprSeqState.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExprSeqState; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExprSeqState + **/ + class ISyntaxStateMachine_DExprSeqState { + public: + /** @defgroup scm-syntaxstatemachine-dexprseqstate-type-traits **/ + ///@{ + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexprseqstate-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExprSeqState & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExprSeqState & self) noexcept; + + // non-const methods + /** update state machine for incoming if-keyword-token @p tk **/ + static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp new file mode 100644 index 00000000..c3aec83e --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SyntaxStateMachine.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/SyntaxStateMachine.json5] + **/ + +#pragma once + +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include + +namespace xo { +namespace scm { + /** @class ISyntaxStateMachine_Xfer + **/ + template + class ISyntaxStateMachine_Xfer : public ASyntaxStateMachine { + public: + /** @defgroup scm-syntaxstatemachine-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = ISyntaxStateMachine_DRepr; + /** integer identifying a type **/ + using typeseq = ASyntaxStateMachine::typeseq; + ///@} + + /** @defgroup scm-syntaxstatemachine-xfer-methods **/ + ///@{ + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + + // from ASyntaxStateMachine + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + syntaxstatetype ssm_type(Copaque data) const noexcept override { + return I::ssm_type(_dcast(data)); + } + std::string_view get_expect_str(Copaque data) const noexcept override { + return I::get_expect_str(_dcast(data)); + } + + // non-const methods + void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_if_token(_dcast(data), tk, p_psm); + } + + ///@} + + private: + using I = Impl; + + public: + /** @defgroup scm-syntaxstatemachine-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + xo::facet::typeseq + ISyntaxStateMachine_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + ISyntaxStateMachine_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace scm */ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_Xfer.hpp */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp new file mode 100644 index 00000000..5f920614 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -0,0 +1,85 @@ +/** @file RSyntaxStateMachine.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SyntaxStateMachine.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/SyntaxStateMachine.json5] + **/ + +#pragma once + +#include "ASyntaxStateMachine.hpp" + +namespace xo { +namespace scm { + +/** @class RSyntaxStateMachine + **/ +template +class RSyntaxStateMachine : public Object { +private: + using O = Object; + +public: + /** @defgroup scm-syntaxstatemachine-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; + ///@} + + /** @defgroup scm-syntaxstatemachine-router-ctors **/ + ///@{ + RSyntaxStateMachine() {} + RSyntaxStateMachine(Object::DataPtr data) : Object{std::move(data)} {} + RSyntaxStateMachine(const ASyntaxStateMachine * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} + + ///@} + /** @defgroup scm-syntaxstatemachine-router-methods **/ + ///@{ + + // const methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + syntaxstatetype ssm_type() const noexcept { + return O::iface()->ssm_type(O::data()); + } + std::string_view get_expect_str() const noexcept { + return O::iface()->get_expect_str(O::data()); + } + + // non-const methods (still const in router!) + void on_if_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_if_token(O::data(), tk, p_psm); + } + + ///@} + /** @defgroup scm-syntaxstatemachine-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RSyntaxStateMachine::_valid = xo::facet::valid_object_router(); + +} /*namespace scm*/ +} /*namespace xo*/ + +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::scm::RSyntaxStateMachine; + }; +} } + +/* end RSyntaxStateMachine.hpp */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp new file mode 100644 index 00000000..913cd118 --- /dev/null +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -0,0 +1,38 @@ +/** @file syntaxstatetype.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + /** @enum syntaxstatemachine + * @brief Label a specialized parsing state machine + * + * Label for a schematika syntax state machine + * dedicated to some particular piece of syntax + **/ + enum class syntaxstatetype { + invalid = -1, + + /** toplevel of some translation unit. See @ref DExprSeqState **/ + expect_toplevel_expression_sequence, + + /** comes lasts, counts number of valid enums **/ + N + }; + + const char * syntaxstatetype_descr(syntaxstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, syntaxstatetype x) { + os << syntaxstatetype_descr(x); + return os; + } + } +} /*namespace xo*/ + +/* end syntaxstatetype.hpp */ diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt new file mode 100644 index 00000000..e8bfb1d7 --- /dev/null +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -0,0 +1,30 @@ +# reader2/CMakeLists.txt + +set(SELF_LIB xo_reader2) +set(SELF_SRCS + #init_reader2.cpp + + ParserStateMachine.cpp + ParserStack.cpp + ParserResult.cpp + + ISyntaxStateMachine_Any.cpp + + DExprSeqState.cpp + ISyntaxStateMachine_DExprSeqState.cpp + + #reader2_register_facets.cpp + #reader2_register_types.cpp + ) + +xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) +# note: deps here must also appear in cmake/xo_expression2Config.cmake.in +xo_dependency(${SELF_LIB} xo_gc) +xo_dependency(${SELF_LIB} xo_tokenizer2) +xo_dependency(${SELF_LIB} xo_expression2) +#xo_dependency(${SELF_LIB} reflect) +#xo_dependency(${SELF_LIB} xo_object2) +#xo_dependency(${SELF_LIB} xo_printable2) +#xo_dependency(${SELF_LIB} xo_flatstring) +#xo_dependency(${SELF_LIB} subsys) +#xo_dependency(${SELF_LIB} indentlog) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp new file mode 100644 index 00000000..7d2368e5 --- /dev/null +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -0,0 +1,101 @@ +/** @file DExprSeqState.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DExprSeqState.hpp" +#include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" + +namespace xo { + using xo::mm::AAllocator; + using xo::facet::with_facet; + using xo::reflect::typeseq; + + namespace scm { + DExprSeqState::DExprSeqState(exprseqtype ty) : seqtype_{ty} + {} + + namespace { + obj + make_exprseq_ssm(obj mm, + exprseqtype seqtype) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DExprSeqState)); + + DExprSeqState * ssm = new (mem) DExprSeqState(seqtype); + + return with_facet::mkobj(ssm); + } + } + + void + DExprSeqState::start_interactive(obj mm, + ParserStateMachine * p_psm) + { + + + p_psm->push_ssm(make_exprseq_ssm(mm, + exprseqtype::toplevel_interactive)); + } + + void + DExprSeqState::start_batch(obj mm, + ParserStateMachine * p_psm) + { + (void)mm; + (void)p_psm; +#ifdef NOT_YET + p_psm->push_ssm(make_exprseq_ssm(mm, + exprseqtype::toplevel_batch)); +#endif + } + + // SyntaxStateMachine facet methods + + syntaxstatetype + DExprSeqState::ssm_type() const noexcept + { + return syntaxstatetype::expect_toplevel_expression_sequence; + } + + std::string_view + DExprSeqState::get_expect_str() const noexcept + { + // TODO: provisional. Will expand as more syntax implemented + + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + return "def|expression|..."; + case exprseqtype::toplevel_batch: + return "def|..."; + case exprseqtype::N: + break; + } + + assert(false); + return "impossible-DExprSeqState::get_expr_str"; + } + + void + DExprSeqState::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + assert(false); // DfElseState::start(p_psm); + break; + case exprseqtype::toplevel_batch: + p_psm->illegal_input_on_token("DExprSeqState::on_if_token", + tk, + this->get_expect_str()); + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExprSeqState.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp new file mode 100644 index 00000000..8c4c0b42 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -0,0 +1,47 @@ +/** @file ISyntaxStateMachine_Any.cpp + * + **/ + +#include "ssm/ISyntaxStateMachine_Any.hpp" +#include + +namespace xo { +namespace scm { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +ISyntaxStateMachine_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " ISyntaxStateMachine_Any method" + << std::endl; + std::terminate(); +} + +typeseq +ISyntaxStateMachine_Any::s_typeseq = typeseq::id(); + +bool +ISyntaxStateMachine_Any::_valid + = valid_facet_implementation(); + +// nonconst methods + +auto +ISyntaxStateMachine_Any::on_if_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + + +} /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_Any.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp new file mode 100644 index 00000000..87f4f2d8 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -0,0 +1,39 @@ +/** @file ISyntaxStateMachine_DExprSeqState.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExprSeqState.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExprSeqState::ssm_type(const DExprSeqState & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExprSeqState::get_expect_str(const DExprSeqState & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExprSeqState::on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_if_token(tk, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExprSeqState.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ParserResult.cpp b/xo-reader2/src/reader2/ParserResult.cpp new file mode 100644 index 00000000..28553228 --- /dev/null +++ b/xo-reader2/src/reader2/ParserResult.cpp @@ -0,0 +1,32 @@ +/** @file ParserResult.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ParserResult.hpp" + +namespace xo { + namespace scm { + ParserResult::ParserResult(parser_result_type type, + obj expr, + std::string_view error_src_fn, + const DString * error_description) + : result_type_{type}, + result_expr_{expr}, + error_src_fn_{error_src_fn}, + error_description_{error_description} + {} + + ParserResult + ParserResult::error(std::string_view ssm_name, + const DString * errmsg) + { + return ParserResult(parser_result_type::error, + obj(), + ssm_name, + errmsg); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ParserResult.cpp */ diff --git a/xo-reader2/src/reader2/ParserStack.cpp b/xo-reader2/src/reader2/ParserStack.cpp new file mode 100644 index 00000000..7e8f6b1b --- /dev/null +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -0,0 +1,28 @@ +/** @file ParserStack.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ParserStack.hpp" +#include "SyntaxStateMachine.hpp" + +namespace xo { + using xo::facet::typeseq; + + namespace scm { + + ParserStack * + ParserStack::push(obj mm, + obj ssm) + + { + void * mem = mm.alloc(typeseq::id(), + sizeof(ParserStack)); + + return new (mem) ParserStack(ssm, parent_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ParserStack.cpp */ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp new file mode 100644 index 00000000..a691bb57 --- /dev/null +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -0,0 +1,134 @@ +/** @file ParserStateMachine.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ParserStateMachine.hpp" +#include "ParserStack.hpp" +#include "SyntaxStateMachine.hpp" +#include +#include +#include +#include +#include + +namespace xo { + using xo::facet::with_facet; + + namespace scm { + void + ParserStateMachine::push_ssm(obj ssm) + { + scope log(XO_DEBUG(debug_flag_)); + + // note: using parser_alloc_ for parser stack, since stacklike behavior + + auto alloc = with_facet::mkobj(&parser_alloc_); + + this->stack_ = stack_->push(alloc, ssm); + } + + void + ParserStateMachine::on_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + if (!stack_) { + // parsing stack should always have toplevel expression sequence + throw std::runtime_error(tostr("unexpected empty parsing stack", + xtag("token", tk), + xtag("help", "do it the same. but better!") + )); + } + + switch (tk.tk_type()) { + case tokentype::tk_if: + this->on_if_token(tk); + break; + + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_bool: + case tokentype::tk_i64: + case tokentype::tk_f64: + case tokentype::tk_string: + case tokentype::tk_symbol: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_colon: + case tokentype::tk_doublecolon: + case tokentype::tk_semicolon: + case tokentype::tk_singleassign: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_def: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + throw std::runtime_error(tostr("NOT IMPLEMENTED", + xtag("token", tk))); + + } + } + + void + ParserStateMachine::on_if_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_if_token(tk, this); + } + + void + ParserStateMachine::capture_error(std::string_view ssm_name, + const DString * errmsg) + { + this->result_ = ParserResult::error(ssm_name, errmsg); + } + + void + ParserStateMachine::illegal_input_on_token(std::string_view ssm_name, + const Token & tk, + std::string_view expect_str) + { + // TODO: + // - want to write error message using DArena + // - need something like log_streambuf and/or tostr() that's arena-aware + + auto errmsg_string = tostr("Unexpected token for parsing state", + xtag("token", tk), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_input_on_token")); + + auto errmsg = DString::from_view(expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ParserStateMachine.cpp */ diff --git a/xo-tokenizer2/include/xo/tokenizer2/tokentype.hpp b/xo-tokenizer2/include/xo/tokenizer2/tokentype.hpp index eeeb7dd0..91cb3622 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/tokentype.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/tokentype.hpp @@ -164,8 +164,8 @@ namespace xo { /** keyword @c 'end' **/ tk_end, - /** counts number of entries **/ - n_tokentype + /** comes last, counts number of entries **/ + N }; /*tokentype*/ /** String representation for enum value. diff --git a/xo-tokenizer2/src/tokenizer2/tokentype.cpp b/xo-tokenizer2/src/tokenizer2/tokentype.cpp index 33d683de..40c2dbfb 100644 --- a/xo-tokenizer2/src/tokenizer2/tokentype.cpp +++ b/xo-tokenizer2/src/tokenizer2/tokentype.cpp @@ -60,7 +60,7 @@ namespace xo { CASE(tk_end); case tokentype::tk_invalid: - case tokentype::n_tokentype: + case tokentype::N: return "?tokentype"; } From 74db591328b716f19e64fad6cdc2e9e8fd9015e6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Jan 2026 18:57:33 -0500 Subject: [PATCH 003/258] xo-reader2: + regression2_register_facets() --- .../xo/reader2/reader2_register_facets.hpp | 15 +++++++++ xo-reader2/src/reader2/CMakeLists.txt | 2 +- xo-reader2/src/reader2/ParserStack.cpp | 4 +++ .../src/reader2/reader2_register_facets.cpp | 33 +++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 xo-reader2/include/xo/reader2/reader2_register_facets.hpp create mode 100644 xo-reader2/src/reader2/reader2_register_facets.cpp diff --git a/xo-reader2/include/xo/reader2/reader2_register_facets.hpp b/xo-reader2/include/xo/reader2/reader2_register_facets.hpp new file mode 100644 index 00000000..6e606e40 --- /dev/null +++ b/xo-reader2/include/xo/reader2/reader2_register_facets.hpp @@ -0,0 +1,15 @@ +/** @file reader2_register_facets.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +namespace xo { + namespace scm { + /** Register reader2 (facet,impl) combinations with FacetRegistry **/ + bool reader2_register_facets(); + } +} + +/* end reader2_register_facets.hpp */ diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index e8bfb1d7..ee214f56 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -13,7 +13,7 @@ set(SELF_SRCS DExprSeqState.cpp ISyntaxStateMachine_DExprSeqState.cpp - #reader2_register_facets.cpp + reader2_register_facets.cpp #reader2_register_types.cpp ) diff --git a/xo-reader2/src/reader2/ParserStack.cpp b/xo-reader2/src/reader2/ParserStack.cpp index 7e8f6b1b..3648cb4d 100644 --- a/xo-reader2/src/reader2/ParserStack.cpp +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -10,6 +10,10 @@ namespace xo { using xo::facet::typeseq; namespace scm { + ParserStack::ParserStack(obj ssm, + ParserStack * parent) + : ssm_{ssm}, parent_{parent} + {} ParserStack * ParserStack::push(obj mm, diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp new file mode 100644 index 00000000..e5b1d157 --- /dev/null +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -0,0 +1,33 @@ +/** @file reader2_register_facets.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "reader2_register_facets.hpp" + +#include + +#include +#include +#include + +namespace xo { + using xo::facet::FacetRegistry; + using xo::facet::typeseq; + + namespace scm { + bool + reader2_register_facets() + { + scope log(XO_DEBUG(true)); + + FacetRegistry::register_impl(); + + log && log(xtag("DExprSeqState.tseq", typeseq::id())); + + return true; + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end reader2_register_facets.cpp */ From 15028cbe92dd88b25b261fb360970cfdf61636e4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Jan 2026 19:09:48 -0500 Subject: [PATCH 004/258] xo-reader2: + init_reader2 + reader2_register_types --- .../include/xo/reader2/init_reader2.hpp | 21 ++++++++++ .../xo/reader2/reader2_register_types.hpp | 17 ++++++++ xo-reader2/src/reader2/CMakeLists.txt | 6 +-- xo-reader2/src/reader2/init_reader2.cpp | 41 +++++++++++++++++++ .../src/reader2/reader2_register_types.cpp | 29 +++++++++++++ 5 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 xo-reader2/include/xo/reader2/init_reader2.hpp create mode 100644 xo-reader2/include/xo/reader2/reader2_register_types.hpp create mode 100644 xo-reader2/src/reader2/init_reader2.cpp create mode 100644 xo-reader2/src/reader2/reader2_register_types.cpp diff --git a/xo-reader2/include/xo/reader2/init_reader2.hpp b/xo-reader2/include/xo/reader2/init_reader2.hpp new file mode 100644 index 00000000..e0bf18b4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/init_reader2.hpp @@ -0,0 +1,21 @@ +/** @file init_reader2.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + /* tag to represent the xo-reader2/ subsystem within ordered initialization */ + enum S_reader2_tag {}; + + template <> + struct InitSubsys { + static void init(); + static InitEvidence require(); + }; +} /*namespace xo*/ + +/* end init_reader2.hpp */ diff --git a/xo-reader2/include/xo/reader2/reader2_register_types.hpp b/xo-reader2/include/xo/reader2/reader2_register_types.hpp new file mode 100644 index 00000000..a7e6c0e1 --- /dev/null +++ b/xo-reader2/include/xo/reader2/reader2_register_types.hpp @@ -0,0 +1,17 @@ +/** @file reader2_register_types.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + /** Register reader2 gc-aware types with collector **/ + bool reader2_register_types(obj gc); + } +} + +/* end reader2_register_types.hpp */ diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index ee214f56..f6fc817f 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -2,7 +2,7 @@ set(SELF_LIB xo_reader2) set(SELF_SRCS - #init_reader2.cpp + init_reader2.cpp ParserStateMachine.cpp ParserStack.cpp @@ -14,7 +14,7 @@ set(SELF_SRCS ISyntaxStateMachine_DExprSeqState.cpp reader2_register_facets.cpp - #reader2_register_types.cpp + reader2_register_types.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) @@ -26,5 +26,5 @@ xo_dependency(${SELF_LIB} xo_expression2) #xo_dependency(${SELF_LIB} xo_object2) #xo_dependency(${SELF_LIB} xo_printable2) #xo_dependency(${SELF_LIB} xo_flatstring) -#xo_dependency(${SELF_LIB} subsys) +xo_dependency(${SELF_LIB} subsys) #xo_dependency(${SELF_LIB} indentlog) diff --git a/xo-reader2/src/reader2/init_reader2.cpp b/xo-reader2/src/reader2/init_reader2.cpp new file mode 100644 index 00000000..aa7e291c --- /dev/null +++ b/xo-reader2/src/reader2/init_reader2.cpp @@ -0,0 +1,41 @@ +/** @file init_reader2.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_reader2.hpp" +#include "reader2_register_facets.hpp" +#include "reader2_register_types.hpp" + +#include +#include + +namespace xo { + using xo::scm::reader2_register_facets; + using xo::scm::reader2_register_types; + using xo::mm::CollectorTypeRegistry; + + void + InitSubsys::init() + { + reader2_register_facets(); + + CollectorTypeRegistry::instance().register_types(&reader2_register_types); + } + + InitEvidence + InitSubsys::require() + { + InitEvidence retval; + + /* direct subsystem deps for xo-reader2/ */ + retval ^= InitSubsys::require(); + + /* xo-reader2/'s own initialization code */ + retval ^= Subsystem::provide("reader2", &init); + + return retval; + } +} /*namespace xo*/ + +/* end init_reader2.cpp */ diff --git a/xo-reader2/src/reader2/reader2_register_types.cpp b/xo-reader2/src/reader2/reader2_register_types.cpp new file mode 100644 index 00000000..3720752d --- /dev/null +++ b/xo-reader2/src/reader2/reader2_register_types.cpp @@ -0,0 +1,29 @@ +/** @file reader2_register_types.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "reader2_register_types.hpp" + +#include + +namespace xo { + using xo::mm::ACollector; + using xo::scope; + + namespace scm { + bool + reader2_register_types(obj /*gc*/) + { + scope log(XO_DEBUG(true)); + + bool ok = true; + + /* no gc-aware types yet; scaffold for future use */ + + return ok; + } + } +} /*namespace xo*/ + +/* end reader2_register_types.cpp */ From 64b165766f3813c062b26febfc010d2fc9e31039 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Jan 2026 19:17:54 -0500 Subject: [PATCH 005/258] xo-arena: + DArena methods {checkpoint, restore} --- xo-arena/include/xo/arena/DArena.hpp | 45 ++++++++++------------------ 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/xo-arena/include/xo/arena/DArena.hpp b/xo-arena/include/xo/arena/DArena.hpp index 8eb6125c..8d9372a0 100644 --- a/xo-arena/include/xo/arena/DArena.hpp +++ b/xo-arena/include/xo/arena/DArena.hpp @@ -62,6 +62,12 @@ namespace xo { sub_complete, }; + /** @brief Checkpoint for unwinding arena state **/ + struct Checkpoint { + explicit Checkpoint(std::byte * x) : free_{x} {} + std::byte * free_; + }; + ///@} /** @defgroup mm-arena-ctors arena constructors and destructors **/ @@ -115,34 +121,6 @@ namespace xo { **/ bool contains(const void * addr) const noexcept { return (lo_ <= addr) && (addr < hi_); } -#ifdef OBSOLETE - /** obtain uncommitted contiguous memory range comprising - * a whole multiple of @p align_z bytes, of at least size @p req_z, - * aligned on a @p align_z boundary. Uncommitted memory is not (yet) - * backed by physical memory. - * - * If @p enable_hugepage_flag is true and THP - * (transparent huge pages) are available, use THP for arena memory. - * This relieves TLB and page table memory when @p req_z is a lot larger than - * page size (likely 4KB). Cost is that arena will consum physical memory in unit - * of @p align_z. Arena may waste up to @p align_z bytes of memory as a result. - * - * If @p enable_hugepage_flag is true, @p align_z should be huge page size - * (probably 2MB) for optimal performance. - * - * At present the THP feature is not supported on OSX. - * May be supportable through mach_vm_allocate(). - * - * Note that we reject MAP_HUGETLB|MAP_HUGE_2MB flags to mmap here, - * since requires previously-reserved memory in /proc/sys/vm/nr_hugepages. - * - * @return pair giving reserved memory address range [lo,hi) - **/ - static range_type map_aligned_range(size_type req_z, - size_type align_z, - bool enable_hugepage_flag); -#endif - /** true if arena is mapped i.e. has a reserved address range **/ bool is_mapped() const noexcept { return (lo_ != nullptr) && (hi_ != nullptr); } @@ -165,7 +143,8 @@ namespace xo { * * Require: * 1. @p mem is address returned by allocation on this arena - * i.e. by @ref IAllocator_DArena::alloc() or @ref IAllocator_DArena::alloc_super() + * i.e. by @ref IAllocator_DArena::alloc() or + * @ref IAllocator_DArena::alloc_super() * 2. @p mem has not been invalidated since it was allocated * i.e. by call to @ref DArena::clear * @@ -218,6 +197,14 @@ namespace xo { /** create initial guard **/ void establish_initial_guard() noexcept; + /** checkpoint arena state. Revert to the same state with + * @ref rstore + **/ + Checkpoint checkpoint() noexcept { return Checkpoint(free_); } + + /** restore arena state to previously-established checkpoint **/ + void restore(Checkpoint ckp) noexcept { free_ = ckp.free_; } + /** discard all allocated memory, return to empty state * Promise: * - committed memory unchanged From 6e2a2bbcd0375a54a389d3bc93d3babc6e6cde7b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Jan 2026 19:25:43 -0500 Subject: [PATCH 006/258] xo-result2: + SchematikaParser --- .../include/xo/reader2/ParserStateMachine.hpp | 13 + .../include/xo/reader2/SchematikaParser.hpp | 231 ++++++++++++++++++ xo-reader2/src/reader2/CMakeLists.txt | 1 + xo-reader2/src/reader2/ParserStateMachine.cpp | 7 + xo-reader2/src/reader2/SchematikaParser.cpp | 92 +++++++ 5 files changed, 344 insertions(+) create mode 100644 xo-reader2/include/xo/reader2/SchematikaParser.hpp create mode 100644 xo-reader2/src/reader2/SchematikaParser.cpp diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 339fa029..cae4a551 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -33,12 +33,25 @@ namespace xo { public: ParserStateMachine(const ArenaConfig & config); + /** @defgroup scm-parserstatemachine-accessors accessor methods **/ + ///@{ + + bool debug_flag() const noexcept { return debug_flag_; } + ParserStack * stack() const noexcept { return stack_; } + const ParserResult & result() const noexcept { return result_; } + obj expr_alloc() const noexcept { return expr_alloc_; } + + ///@} + /** @defgroup scm-parserstatemachine-bookkeeping bookkeeping methods **/ ///@{ /** push syntax @p ssm onto @ref stack_ **/ void push_ssm(obj ssm); + /** reset result to none **/ + void reset_result() { result_ = ParserResult(); } + ///@} /** @defgroup scm-parserstatemachine-inputmethods input methods **/ diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp new file mode 100644 index 00000000..8b4688ce --- /dev/null +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -0,0 +1,231 @@ +/** @file SchematikaParser.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ParserStateMachine.hpp" +#include "ParserResult.hpp" +#include + +namespace xo { + namespace scm { + /** schematica parser + * + * Examples: + * + * decltype point + * + * // forward declarations + * decl pi : f64; + * decl fib(n : i32) -> i32; + * + * def pi = 3.14159265; // constant. = is single assignment + * + * def fib(n : i32) -> i32 { + * // nested defs ok + * def aux(n : i32, s1 : i32, s2 : i32) -> i32 { + * // or: + * // (n == 0) ? s1 : aux(n - 1, s1 + s2, s1) + * // + * if (n == 0) { + * s1; + * } else { + * aux(n - 1, s1 + s2, s1); + * } + * + * // or: + * // if (n == 0) ? s1 : aux(n - 1, s1 + s2, s1) + * } + * + * aux(n=n, s1=1, s2=0); + * } + * + * def x := "fu"; // non-constant + * x += "bar"; + * + * def anotherfib = lambda(n : i32) { fib(n) }; + * + * def any : object; + * def l : list = '(); + * + * deftype point :: {x : f64, y : f64}; + * deftype polar :: {arg : f64, mag : f64}; + * deftype converter :: (point -> polar); + * + * def polar2rect(pt : polar) -> point { + * point(x = pt.mag * cos(arg), + * y = pt.mag * sin(arg)); + * } + * + * Grammar: + * toplevel-program = $toplevel-expression(1); ..; $toplevel-expression(n) + * + * if interactive: + * toplevel-expression = expression + * else + * toplevel-expression = type-decl | define-expr + * + * type-decl = decltype $typename [<$tp1 .. $tpn>] + * expression = type-decl + * | define-expr + * | literal-expr + * | variable-expr + * | apply-expr + * | if-expr + * | lambda-expr + * | arithmetic-expr + * | block + * + * define-expr = type-decl + * | type-def + * | variable-def + * | function-decl + * | function-def + * + * type-def = deftype $typename [<$tp1 .. $tpn>] :: type-def-rhs + * type-def-rhs = object + * | bool + * | i128 | i64 | i32 | i16 | i8 + * | f128 | f64 | f32 | f16 + * | struct $typename { ($membername(i) : $typename(i))* } + * [end $typename] + * | tuple $typename { $typename(1), .., $typename(n) } + * [end $typename] + * | copytype $typename + * | subtype $typename { ($member(i) : $typename(i))* } + * + * variable-def = decl $varname [: $typename] [= expression] + * function-decl = decl $functionname($varname(1) : $typename(1), + * .., + * $varname(n) : $typename(n)) -> $typename[ret] + * function-def = def $functionname($varname(1) : $typename(1), + * .., + * $varname(n) : $typename(n)) [-> $typename[ret]] + * body-expr + * [ end $functionname ] + * literal-expr = boolean-literal + * | integer-literal + * | fp-literal + * | string-literal + * | symbol-literal + * | struct-literal + * + * + * boolean-literal = true | false + * + * variable-expr = $varname + * apply-expr = fn-expr(arg-expr(1), .., arg-expr(n)) + * fn-expr = expression + * arg-expr(i) = expression + * + * if-expr = if (test-expr) then-block else else-block + * | ((test-expr) ? then-expr : else-expr) + * test-expr = expression + * then-block = block + * else-block = block + * + * block = { (definition | expression)* } + * + * lambda-expr = lambda ($paramname(1) : $type(1), + * .., + * $paramname(n) : $type(n)) body-expr + * body-expr = expression + * + * arithmetic-expr = expression binop expression + * + * binop = + + * | - + * | * + * | / + * | | + * | & + * | ^ + * | == + * | != + * | < + * | <= + * | => + * | > + * + **/ + class SchematikaParser { + public: + using ArenaConfig = xo::mm::ArenaConfig; + using token_type = Token; + + public: + /** create parser in initial state; + * parser is ready to receive tokens via @ref include_token + * + * @p config arena configuration for parser memory + * @p debug_flag true to enable debug logging + **/ + SchematikaParser(const ArenaConfig & config, bool debug_flag); + + bool debug_flag() const { return debug_flag_; } + + /** true if parser is at top-level, + * i.e. ready for next top-level expression + **/ + bool is_at_toplevel() const; + + /** true iff parser contains state for an incomplete expression. + * For this to be true, parser must have consumed at least one token + * since end of last toplevel expression + **/ + bool has_incomplete_expr() const; + + /** put parser into state for beginning an interactive session. + **/ + void begin_interactive_session(); + + /** put parser into state for beginning of a translation unit + * (i.e. input stream) + **/ + void begin_translation_unit(); + + /** include next token @p tk and increment parser state. + * + * @param tk next input token + * @return parsed expression, if @p tk completes an expression. + * otherwise nullptr + **/ + const ParserResult & include_token(const token_type & tk); + + /** reset parsed result expression; use using return value from + * @ref include_token. Complicating api here to avoid copying ParserResult + * on each token + **/ + void reset_result(); + + /** reset to starting parsing state. + * use this after encountering an error, to avoid cascade of + * spurious secondary errors. particularly important when + * invoked as part of a REPL. + **/ + void reset_to_idle_toplevel(); + + /** print human-readable representation on stream @p os **/ + void print(std::ostream & os) const; + + private: + /** state machine **/ + ParserStateMachine psm_; + + /** debug flag (also stored in psm_) **/ + bool debug_flag_ = false; + }; /*SchematikaParser*/ + + inline std::ostream & + operator<< (std::ostream & os, + const SchematikaParser & x) { + x.print(os); + return os; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end SchematikaParser.hpp */ diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index f6fc817f..f3eaace2 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -4,6 +4,7 @@ set(SELF_LIB xo_reader2) set(SELF_SRCS init_reader2.cpp + SchematikaParser.cpp ParserStateMachine.cpp ParserStack.cpp ParserResult.cpp diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index a691bb57..c2297da4 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -16,6 +16,13 @@ namespace xo { using xo::facet::with_facet; namespace scm { + ParserStateMachine::ParserStateMachine(const ArenaConfig & config) + : parser_alloc_{DArena::map(config)}, + expr_alloc_{with_facet::mkobj(&parser_alloc_)}, + debug_flag_{config.debug_flag_} + { + } + void ParserStateMachine::push_ssm(obj ssm) { diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp new file mode 100644 index 00000000..712c55d8 --- /dev/null +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -0,0 +1,92 @@ +/** @file SchematikaParser.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "SchematikaParser.hpp" +#include "ParserStateMachine.hpp" +#include "ParserStack.hpp" +#include "DExprSeqState.hpp" +#include +#include + +namespace xo { + using xo::tostr; + using xo::xtag; + + namespace scm { + // ----- SchematikaParser ----- + + SchematikaParser::SchematikaParser(const ArenaConfig & config, bool debug_flag) + : psm_{config}, + debug_flag_{debug_flag} + { + } + + bool + SchematikaParser::is_at_toplevel() const { + return psm_.stack() == nullptr; + } + + bool + SchematikaParser::has_incomplete_expr() const { + /* (don't count toplevel exprseq) */ + ParserStack * stack = psm_.stack(); + if (!stack) + return false; + return stack->parent() != nullptr; + } + + void + SchematikaParser::begin_interactive_session() { + DExprSeqState::start_interactive(psm_.expr_alloc(), &psm_); + } + + void + SchematikaParser::begin_translation_unit() { + DExprSeqState::start_batch(psm_.expr_alloc(), &psm_); + } + + const ParserResult & + SchematikaParser::include_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", + ": parser not expecting input" + "(call parser.begin_translation_unit()..?)", + xtag("token", tk))); + } + + /* stack is non-empty */ + + psm_.on_token(tk); + + return psm_.result(); + } /*include_token*/ + + void + SchematikaParser::reset_result() + { + psm_.reset_result(); + } + + void + SchematikaParser::reset_to_idle_toplevel() + { + psm_.reset_stack(); + psm_.reset_result(); + } /*reset_to_idle_toplevel*/ + + void + SchematikaParser::print(std::ostream & os) const { + os << "" << std::endl; + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end SchematikaParser.cpp */ From 846071a4fb864ab0825d283522492c63bc64596a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Jan 2026 20:23:00 -0500 Subject: [PATCH 007/258] xo-reader2: corrections to toplevel SchematikaParser setup --- xo-arena/include/xo/arena/DArena.hpp | 3 +- .../include/xo/reader2/DExprSeqState.hpp | 8 ++-- xo-reader2/include/xo/reader2/ParserStack.hpp | 5 +- .../include/xo/reader2/ParserStateMachine.hpp | 21 +++++++- xo-reader2/src/reader2/DExprSeqState.cpp | 24 ++++------ xo-reader2/src/reader2/ParserStack.cpp | 5 +- xo-reader2/src/reader2/ParserStateMachine.cpp | 48 ++++++++++++++++++- xo-reader2/src/reader2/SchematikaParser.cpp | 16 +++---- 8 files changed, 95 insertions(+), 35 deletions(-) diff --git a/xo-arena/include/xo/arena/DArena.hpp b/xo-arena/include/xo/arena/DArena.hpp index 8d9372a0..ffd710f0 100644 --- a/xo-arena/include/xo/arena/DArena.hpp +++ b/xo-arena/include/xo/arena/DArena.hpp @@ -64,8 +64,9 @@ namespace xo { /** @brief Checkpoint for unwinding arena state **/ struct Checkpoint { + Checkpoint() = default; explicit Checkpoint(std::byte * x) : free_{x} {} - std::byte * free_; + std::byte * free_ = nullptr; }; ///@} diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index f1faed86..f081691a 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -38,11 +38,11 @@ namespace xo { explicit DExprSeqState(exprseqtype ty); /** start interactive top-level session **/ - static void start_interactive(obj mm, - ParserStateMachine * p_psm); + static void establish_interactive(obj mm, + ParserStateMachine * p_psm); /** start non-interactive top-level session **/ - static void start_batch(obj mm, - ParserStateMachine * p_psm); + static void establish_batch(obj mm, + ParserStateMachine * p_psm); public: /** @defgroup scm-exprseq-ssm-facet syntaxstatemachine facet methods **/ diff --git a/xo-reader2/include/xo/reader2/ParserStack.hpp b/xo-reader2/include/xo/reader2/ParserStack.hpp index 424be42b..4a87de7f 100644 --- a/xo-reader2/include/xo/reader2/ParserStack.hpp +++ b/xo-reader2/include/xo/reader2/ParserStack.hpp @@ -28,8 +28,9 @@ namespace xo { /** create new top of stack for syntax @p ssm, using memory from @p mm. * previous stack given by @p parent **/ - ParserStack * push(obj mm, - obj ssm); + static ParserStack * push(ParserStack * stack, + obj mm, + obj ssm); obj top() const noexcept { return ssm_; } ParserStack * parent() const noexcept { return parent_; } diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index cae4a551..c3c179ad 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -41,16 +41,28 @@ namespace xo { const ParserResult & result() const noexcept { return result_; } obj expr_alloc() const noexcept { return expr_alloc_; } + /** true iff state machine is currently idle (at top-level) **/ + bool is_at_toplevel() const noexcept; + + /** true iff state machine currently has incomplete expression **/ + bool has_incomplete_expr() const noexcept; + ///@} /** @defgroup scm-parserstatemachine-bookkeeping bookkeeping methods **/ ///@{ + /** establish toplevel @p ssm. Must have empty stack **/ + void establish_toplevel_ssm(obj ssm); + /** push syntax @p ssm onto @ref stack_ **/ void push_ssm(obj ssm); /** reset result to none **/ - void reset_result() { result_ = ParserResult(); } + void reset_result(); + + /** reset after reporting error **/ + void clear_error_reset(); ///@} @@ -89,6 +101,7 @@ namespace xo { ///@} private: + /** Arena for internal parsing stack. * Must be owned exclusively because destructively * modified as parser completes parsing of each sub-expression @@ -97,6 +110,12 @@ namespace xo { **/ DArena parser_alloc_; + /** Checkpoint of toplevel parser allocator. + * Retore parser_alloc to this checkpoint to proceed + * after encountering a parsing error. + **/ + DArena::Checkpoint parser_alloc_ckp_; + /** parser stack. Memory from @ref parser_alloc_ **/ ParserStack * stack_ = nullptr; diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 7d2368e5..4d6ae613 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -30,25 +30,21 @@ namespace xo { } void - DExprSeqState::start_interactive(obj mm, - ParserStateMachine * p_psm) + DExprSeqState::establish_interactive(obj mm, + ParserStateMachine * p_psm) { - - - p_psm->push_ssm(make_exprseq_ssm(mm, - exprseqtype::toplevel_interactive)); + p_psm->establish_toplevel_ssm(make_exprseq_ssm + (mm, + exprseqtype::toplevel_interactive)); } void - DExprSeqState::start_batch(obj mm, - ParserStateMachine * p_psm) + DExprSeqState::establish_batch(obj mm, + ParserStateMachine * p_psm) { - (void)mm; - (void)p_psm; -#ifdef NOT_YET - p_psm->push_ssm(make_exprseq_ssm(mm, - exprseqtype::toplevel_batch)); -#endif + p_psm->establish_toplevel_ssm(make_exprseq_ssm + (mm, + exprseqtype::toplevel_batch)); } // SyntaxStateMachine facet methods diff --git a/xo-reader2/src/reader2/ParserStack.cpp b/xo-reader2/src/reader2/ParserStack.cpp index 3648cb4d..5b416c54 100644 --- a/xo-reader2/src/reader2/ParserStack.cpp +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -16,14 +16,15 @@ namespace xo { {} ParserStack * - ParserStack::push(obj mm, + ParserStack::push(ParserStack * stack, + obj mm, obj ssm) { void * mem = mm.alloc(typeseq::id(), sizeof(ParserStack)); - return new (mem) ParserStack(ssm, parent_); + return new (mem) ParserStack(ssm, stack); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index c2297da4..4f54a584 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -23,6 +23,35 @@ namespace xo { { } + bool + ParserStateMachine::is_at_toplevel() const noexcept + { + return ((stack_ == nullptr) + || (stack_->parent() == nullptr)); + } + + bool + ParserStateMachine::has_incomplete_expr() const noexcept + { + // don't count toplevel expression + + return !(this->is_at_toplevel()); + } + + void + ParserStateMachine::establish_toplevel_ssm(obj ssm) + { + scope log(XO_DEBUG(debug_flag_)); + + assert(stack_ == nullptr); + + auto alloc = with_facet::mkobj(&parser_alloc_); + + this->stack_ = ParserStack::push(nullptr /*stack*/, + alloc, ssm); + this->parser_alloc_ckp_ = parser_alloc_.checkpoint(); + } + void ParserStateMachine::push_ssm(obj ssm) { @@ -32,7 +61,24 @@ namespace xo { auto alloc = with_facet::mkobj(&parser_alloc_); - this->stack_ = stack_->push(alloc, ssm); + this->stack_ = ParserStack::push(stack_, alloc, ssm); + } + + void + ParserStateMachine::reset_result() + { + this->result_ = ParserResult(); + } + + void + ParserStateMachine::clear_error_reset() + { + this->reset_result(); + + while (stack_ && stack_->parent()) + stack_ = stack_->parent(); + + this->parser_alloc_.restore(parser_alloc_ckp_); } void diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 712c55d8..2e607e77 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -25,26 +25,23 @@ namespace xo { bool SchematikaParser::is_at_toplevel() const { - return psm_.stack() == nullptr; + return psm_.is_at_toplevel(); } bool SchematikaParser::has_incomplete_expr() const { - /* (don't count toplevel exprseq) */ - ParserStack * stack = psm_.stack(); - if (!stack) - return false; - return stack->parent() != nullptr; + return !(this->is_at_toplevel()); } void SchematikaParser::begin_interactive_session() { - DExprSeqState::start_interactive(psm_.expr_alloc(), &psm_); + DExprSeqState::establish_interactive(psm_.expr_alloc(), &psm_); + } void SchematikaParser::begin_translation_unit() { - DExprSeqState::start_batch(psm_.expr_alloc(), &psm_); + DExprSeqState::establish_batch(psm_.expr_alloc(), &psm_); } const ParserResult & @@ -75,8 +72,7 @@ namespace xo { void SchematikaParser::reset_to_idle_toplevel() { - psm_.reset_stack(); - psm_.reset_result(); + psm_.clear_error_reset(); } /*reset_to_idle_toplevel*/ void From 39fa1f7c9f9004585d4c04fd43692b32db5422e2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 18 Jan 2026 20:37:15 -0500 Subject: [PATCH 008/258] xo-reader2: ParserStateMachine w/ separate allocator --- xo-reader2/include/xo/reader2/ParserStateMachine.hpp | 7 ++++--- xo-reader2/include/xo/reader2/SchematikaParser.hpp | 8 +++++++- xo-reader2/src/reader2/ParserStateMachine.cpp | 9 ++++++--- xo-reader2/src/reader2/SchematikaParser.cpp | 11 +++++++---- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index c3c179ad..466e07f8 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -31,15 +31,16 @@ namespace xo { using DArena = xo::mm::DArena; public: - ParserStateMachine(const ArenaConfig & config); + ParserStateMachine(const ArenaConfig & config, + obj * expr_alloc); /** @defgroup scm-parserstatemachine-accessors accessor methods **/ ///@{ bool debug_flag() const noexcept { return debug_flag_; } ParserStack * stack() const noexcept { return stack_; } + obj * expr_alloc() const noexcept { return expr_alloc_; } const ParserResult & result() const noexcept { return result_; } - obj expr_alloc() const noexcept { return expr_alloc_; } /** true iff state machine is currently idle (at top-level) **/ bool is_at_toplevel() const noexcept; @@ -133,7 +134,7 @@ namespace xo { * scenario, where top-level Expressions can be discarded * once compiled. **/ - obj expr_alloc_; + obj * expr_alloc_ = nullptr; /** current output from parser **/ ParserResult result_; diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 8b4688ce..7d5f36d2 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -8,6 +8,7 @@ #include "ParserStateMachine.hpp" #include "ParserResult.hpp" #include +#include namespace xo { namespace scm { @@ -153,6 +154,7 @@ namespace xo { class SchematikaParser { public: using ArenaConfig = xo::mm::ArenaConfig; + using AAllocator = xo::mm::AAllocator; using token_type = Token; public: @@ -160,9 +162,13 @@ namespace xo { * parser is ready to receive tokens via @ref include_token * * @p config arena configuration for parser memory + * @p expr_alloc allocator for schematika expressions. + * Probably shared with execution. * @p debug_flag true to enable debug logging **/ - SchematikaParser(const ArenaConfig & config, bool debug_flag); + SchematikaParser(const ArenaConfig & config, + obj * expr_alloc, + bool debug_flag); bool debug_flag() const { return debug_flag_; } diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 4f54a584..4756975a 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -16,9 +16,10 @@ namespace xo { using xo::facet::with_facet; namespace scm { - ParserStateMachine::ParserStateMachine(const ArenaConfig & config) + ParserStateMachine::ParserStateMachine(const ArenaConfig & config, + obj * expr_alloc) : parser_alloc_{DArena::map(config)}, - expr_alloc_{with_facet::mkobj(&parser_alloc_)}, + expr_alloc_{expr_alloc}, debug_flag_{config.debug_flag_} { } @@ -176,7 +177,9 @@ namespace xo { xtag("ssm", ssm_name), xtag("via", "ParserStateMachine::illegal_input_on_token")); - auto errmsg = DString::from_view(expr_alloc_, + assert(expr_alloc_); + + auto errmsg = DString::from_view(*expr_alloc_, std::string_view(errmsg_string)); this->capture_error(ssm_name, errmsg); diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 2e607e77..67af915f 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -11,14 +11,17 @@ #include namespace xo { + using xo::mm::AAllocator; using xo::tostr; using xo::xtag; namespace scm { // ----- SchematikaParser ----- - SchematikaParser::SchematikaParser(const ArenaConfig & config, bool debug_flag) - : psm_{config}, + SchematikaParser::SchematikaParser(const ArenaConfig & config, + obj * expr_alloc, + bool debug_flag) + : psm_{config, expr_alloc}, debug_flag_{debug_flag} { } @@ -35,13 +38,13 @@ namespace xo { void SchematikaParser::begin_interactive_session() { - DExprSeqState::establish_interactive(psm_.expr_alloc(), &psm_); + DExprSeqState::establish_interactive(*(psm_.expr_alloc()), &psm_); } void SchematikaParser::begin_translation_unit() { - DExprSeqState::establish_batch(psm_.expr_alloc(), &psm_); + DExprSeqState::establish_batch(*(psm_.expr_alloc()), &psm_); } const ParserResult & From d3066ef88d3d9897fa2fc72290dae93fbf37e3c6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 00:38:43 -0500 Subject: [PATCH 009/258] xo-reader2: + DDefineSsm + utest --- xo-reader2/CMakeLists.txt | 2 +- .../idl/ISyntaxStateMachine_DDefineSsm.json5 | 13 + xo-reader2/include/xo/reader2/DDefineSsm.hpp | 97 +++++ .../include/xo/reader2/SchematikaParser.hpp | 2 +- .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 66 +++ .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 2 + xo-reader2/src/reader2/DDefineSsm.cpp | 395 ++++++++++++++++++ .../ISyntaxStateMachine_DDefineSsm.cpp | 50 +++ xo-reader2/src/reader2/SchematikaParser.cpp | 2 +- xo-reader2/utest/CMakeLists.txt | 11 + xo-reader2/utest/SchematikaParser.test.cpp | 95 +++++ xo-reader2/utest/reader2_utest_main.cpp | 27 ++ 13 files changed, 762 insertions(+), 3 deletions(-) create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/DDefineSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp create mode 100644 xo-reader2/src/reader2/DDefineSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp create mode 100644 xo-reader2/utest/CMakeLists.txt create mode 100644 xo-reader2/utest/SchematikaParser.test.cpp create mode 100644 xo-reader2/utest/reader2_utest_main.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 30732417..1f3a4520 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -20,7 +20,7 @@ add_definitions(${PROJECT_CXX_FLAGS}) # ---------------------------------------------------------------- # output targets -#add_subdirectory(utest) +add_subdirectory(utest) # note: manual target; generated code committed to git xo_add_genfacet( diff --git a/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 new file mode 100644 index 00000000..11d2c5f7 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DDefineSsm", + using_doxygen: true, + repr: "DDefineSsm", + doc: [ "implement ASyntaxStateMachine for DDefineSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp new file mode 100644 index 00000000..10ec3097 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -0,0 +1,97 @@ +/** @file DDefineSsm.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ParserStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include + +namespace xo { + namespace scm { + /** + * @pre + * + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | (done) + * | | | | | | def_6:expect_rhs_expression:expr_progress + * | | | | | def_5:expect_rhs_expression + * | | | | def_4 + * | | | def_3:expect_type + * | | def_2 + * | def_1:expect_symbol + * def_0 + * expect_toplevel_expression_sequence + * + * def_0 --on_def_token()--> def_1 + * def_1 --on_symbol()--> def_2 + * def_2 --on_colon_token()--> def_3 + * --on_singleassign_token()--> def_5 + * def_3 --on_typedescr()--> def_4 + * def_4 --on_singleassign_token()--> def_5 + * def_5 --on_expr()--> def_6 + * def_6 --on_semicolon_token()--> (done) + * + * def_1:expect_symbol: got 'def' keyword, symbol to follow + * def_1: got symbol name + * def_3:expect_symbol got (optional) colon, type name to follow + * def_4: got symbol type + * def_6:expect_rhs_expression got (optional) equal sign, value to follow + * (done): definition complete, pop exprstate from stack + * + * @endpre + **/ + enum class defexprstatetype { + invalid = -1, + + def_0, + def_1, + def_2, + def_3, + def_4, + def_5, + def_6, + + n_defexprstatetype, + }; + + extern const char * defexprstatetype_descr(defexprstatetype x); + + std::ostream & + operator<<(std::ostream & os, defexprstatetype x); + + /** @class DDefineSsm + * @brief state machine for parsing a define expression + **/ + class DDefineSsm { + public: + + public: + /** @defgroup scm-define-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error mesages + **/ + std::string_view get_expect_str() const noexcept; + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_if_token(const Token & tk, ParserStateMachine * p_psm); + + ///@} + + private: + /** identify define-expression state **/ + defexprstatetype defstate_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 7d5f36d2..b0f78bff 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -198,7 +198,7 @@ namespace xo { * @return parsed expression, if @p tk completes an expression. * otherwise nullptr **/ - const ParserResult & include_token(const token_type & tk); + const ParserResult & on_token(const token_type & tk); /** reset parsed result expression; use using return value from * @ref include_token. Complicating api here to avoid copying ParserResult diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp new file mode 100644 index 00000000..adb39c48 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -0,0 +1,66 @@ +/** @file ISyntaxStateMachine_DDefineSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DDefineSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DDefineSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DDefineSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DDefineSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DDefineSsm + **/ + class ISyntaxStateMachine_DDefineSsm { + public: + /** @defgroup scm-syntaxstatemachine-ddefinessm-type-traits **/ + ///@{ + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-ddefinessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DDefineSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DDefineSsm & self) noexcept; + + // non-const methods + /** update state machine for incoming define-keyworkd-token @p tk **/ + static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * ps_psm); + /** update state machine for incoming if-keyword-token @p tk **/ + static void on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 913cd118..ae02cad4 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -21,6 +21,9 @@ namespace xo { /** toplevel of some translation unit. See @ref DExprSeqState **/ expect_toplevel_expression_sequence, + /** handle define-expression. See @ref DDefineSsm **/ + defexpr, + /** comes lasts, counts number of valid enums **/ N }; diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index f3eaace2..ff8eb418 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -14,6 +14,8 @@ set(SELF_SRCS DExprSeqState.cpp ISyntaxStateMachine_DExprSeqState.cpp + DDefineSsm.cpp + reader2_register_facets.cpp reader2_register_types.cpp ) diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp new file mode 100644 index 00000000..609ec0db --- /dev/null +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -0,0 +1,395 @@ +/** @file DDefineSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DDefineSsm.hpp" +#ifdef NOT_YET +#include "parserstatemachine.hpp" +#include "expect_symbol_xs.hpp" +#include "expect_expr_xs.hpp" +#include "expect_type_xs.hpp" +#include "pretty_expression.hpp" +#endif + +namespace xo { + namespace scm { + // ----- defexprstatetype ----- + + const char * + defexprstatetype_descr(defexprstatetype x) { + switch (x) { + case defexprstatetype::invalid: return "invalid"; + case defexprstatetype::def_0: return "def_0"; + case defexprstatetype::def_1: return "def_1"; + case defexprstatetype::def_2: return "def_2"; + case defexprstatetype::def_3: return "def_3"; + case defexprstatetype::def_4: return "def_4"; + case defexprstatetype::def_5: return "def_5"; + case defexprstatetype::def_6: return "def_6"; + case defexprstatetype::n_defexprstatetype: break; + } + + return "???defexprstatetype"; + } + + std::ostream & + operator<<(std::ostream & os, defexprstatetype x) { + os << defexprstatetype_descr(x); + return os; + } + + // ----- define_xs ----- + +#ifdef NOT_YET + std::unique_ptr + define_xs::make() { + return std::make_unique(define_xs(DefineExprAccess::make_empty())); + } + + void + define_xs::start(parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + p_psm->push_exprstate(define_xs::make()); + p_psm->top_exprstate().on_def_token(token_type::def(), p_psm); + } + + define_xs::define_xs(rp def_expr) + : exprstate(exprstatetype::defexpr), + defxs_type_{defexprstatetype::def_0}, + def_expr_{std::move(def_expr)} + {} + + // const char * + // define_xs::get_expect_str() const { ... } + + void + define_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("defxs_type", defxs_type_)); + + if (this->defxs_type_ == defexprstatetype::def_5) { + /* have all the ingredients to create an expression + * representing a definition + * + * 1. if ir_type is a symbol, interpret as variable name. + * Need to be able to locate variable by type + * 2. if ir_type is an expression, adopt as rhs + */ + rp rhs_value = expr.promote(); + + if (this->cvt_expr_) { + this->cvt_expr_->assign_arg(rhs_value); + } else { + /* note: establishes .def_expr_ valuetype */ + this->def_expr_->assign_rhs(rhs_value); + } + + rp def_expr = this->def_expr_; + + this->defxs_type_ = defexprstatetype::def_6; + return; + } + + constexpr const char * c_self_name = "define_xs::on_expr"; + const char * exp = get_expect_str(); + + this->illegal_input_on_expr(c_self_name, expr, exp, p_psm); + } + + void + define_xs::on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("defxs_type", defxs_type_)); + + this->on_expr(expr, p_psm); + /* semicolon is allowed to terminate def expr */ + this->on_semicolon_token(token_type::semicolon(), p_psm); + } + + void + define_xs::on_symbol(const std::string & symbol_name, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("defxs_type", defxs_type_), xtag("env_stack_size", p_psm->env_stack_size())); + + if (this->defxs_type_ == defexprstatetype::def_1) { + this->defxs_type_ = defexprstatetype::def_2; + this->def_expr_->assign_lhs_name(symbol_name); + + // if this is a genuine top-level define (i.e. nesting level = 0), + // then we need to upsert so we can refer to rhs later. + // + // In other contexts (e.g. body-of-lambda) will be rewriting + // { + // def y = foo(x,x); + // bar(y,y); + // } + // into something like + // { + // (lambda (y123) bar(y123,y123))(foo(x,x)); + // } + // + // This works in the body of lambda, because we don't evaluate anything + // until lambda definition is complete. + // + // For interactive top-level defs we want to evaluate as we go, + // so need incremental bindings. + + if (p_psm->env_stack_size() == 1) { + /* remember variable binding in lexical context, + * so we can refer to it later + */ + p_psm->upsert_var(this->def_expr_->lhs_variable()); + } + + return; + } + + constexpr const char * c_self_name = "define_xs::on_symbol"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_symbol(c_self_name, symbol_name, exp, p_psm); + } + + void + define_xs::on_typedescr(TypeDescr td, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("defxs_type", defxs_type_); + + if (this->defxs_type_ == defexprstatetype::def_3) { + this->defxs_type_ = defexprstatetype::def_4; + this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/, + nullptr /*source_expr*/); + /* note: establishes .def_expr_ valuetype */ + this->def_expr_->assign_rhs(this->cvt_expr_); + return; + } + + constexpr const char * c_self_name = "define_xs::on_symbol"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_type(c_self_name, td, exp, p_psm); + } + + void + define_xs::on_def_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log("defxs_type", defxs_type_); + + if (this->defxs_type_ == defexprstatetype::def_0) { + this->defxs_type_ = defexprstatetype::def_1; + + expect_symbol_xs::start(p_psm); + return; + } + + constexpr const char * c_self_name = "define_xs::on_def_token"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + define_xs::on_colon_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log("defxs_type", defxs_type_); + + if (this->defxs_type_ == defexprstatetype::def_2) { + this->defxs_type_ = defexprstatetype::def_3; + + expect_type_xs::start(p_psm); + return; + } + + constexpr const char * c_self_name = "define_xs::on_symbol"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + define_xs::on_semicolon_token(const token_type & tk, + parserstatemachine * p_psm) + { + /* def expr consumes semicolon */ + + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("defxs_type", defxs_type_); + + if (this->defxs_type_ == defexprstatetype::def_6) { + rp def_expr = this->def_expr_; + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->top_exprstate().on_expr(def_expr, p_psm); + return; + } + + constexpr const char * c_self_name = "define_xs::on_symbol"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + define_xs::on_singleassign_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log("defxs_type", defxs_type_); + + if ((this->defxs_type_ == defexprstatetype::def_2) + || (this->defxs_type_ == defexprstatetype::def_4)) + { + this->defxs_type_ = defexprstatetype::def_5; + expect_expr_xs::start(p_psm); + return; + } + + constexpr const char * c_self_name = "define_xs::on_singleassign_token"; + const char * exp = get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + define_xs::on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * c_self_name = "define_xs::on_rightparen"; + const char * exp = get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + define_xs::on_i64_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * c_self_name = "define_xs::on_i64"; + const char * exp = get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + define_xs::on_f64_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * c_self_name = "define_xs::on_f64"; + const char * exp = get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + define_xs::print(std::ostream & os) const { + os << ""; + } + + bool + define_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, "define_xs", + refrtag("defxs_type", defxs_type_)); + } +#endif + + //////////////////////////////////////////////////////////////// + + syntaxstatetype + DDefineSsm::ssm_type() const noexcept + { + return syntaxstatetype::defexpr; + } + + std::string_view + DDefineSsm::get_expect_str() const noexcept + { + /* + * def foo = 1 ; + * def foo : f64 = 1 ; + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | (done) + * | | | | | | def_6 + * | | | | | def_5:expect_rhs_expression + * | | | | def_4 + * | | | def_3:expect_type + * | | def_2 + * | def_1:expect_symbol + * expect_toplevel_expression_sequence + * + * note that we skip from def_2 -> def_5 if '=' instead of ':' + */ + switch (this->defstate_) { + case defexprstatetype::invalid: + case defexprstatetype::def_0: + case defexprstatetype::n_defexprstatetype: + assert(false); // impossible + return nullptr; + case defexprstatetype::def_1: + return "symbol"; + case defexprstatetype::def_2: + return "singleassign|colon"; + case defexprstatetype::def_4: + return "singleassign"; + case defexprstatetype::def_3: + return "type"; + case defexprstatetype::def_5: + return "expression"; + case defexprstatetype::def_6: + return "semicolon"; + } + + return "?expect"; + } + + void + DDefineSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DDefineSsm::on_if_token", + tk, + this->get_expect_str()); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp new file mode 100644 index 00000000..bf17c9b5 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -0,0 +1,50 @@ +/** @file ISyntaxStateMachine_DDefineSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DDefineSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DDefineSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DDefineSsm::ssm_type(const DDefineSsm & self) noexcept + -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DDefineSsm::get_expect_str(const DDefineSsm & self) noexcept + -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DDefineSsm::on_def_token(DDefineSsm & self, + const Token & tk, + ParserStateMachine * ps_psm) -> void + { + self.on_def_token(tk, ps_psm); + } + auto + ISyntaxStateMachine_DDefineSsm::on_if_token(DDefineSsm & self, + const Token & tk, + ParserStateMachine * p_psm) -> void + { + self.on_if_token(tk, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DDefineSsm.cpp */ diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 67af915f..f9f0b482 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -48,7 +48,7 @@ namespace xo { } const ParserResult & - SchematikaParser::include_token(const token_type & tk) + SchematikaParser::on_token(const token_type & tk) { scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); diff --git a/xo-reader2/utest/CMakeLists.txt b/xo-reader2/utest/CMakeLists.txt new file mode 100644 index 00000000..f6de05ed --- /dev/null +++ b/xo-reader2/utest/CMakeLists.txt @@ -0,0 +1,11 @@ +# build unittest xo-reader2/utest + +set(UTEST_EXE utest.reader2) +set(UTEST_SRCS + reader2_utest_main.cpp + SchematikaParser.test.cpp +) + +xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) +xo_self_dependency(${UTEST_EXE} xo_reader2) +xo_external_target_dependency(${UTEST_EXE} Catch2 Catch2::Catch2) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp new file mode 100644 index 00000000..1f066f3e --- /dev/null +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -0,0 +1,95 @@ +/** @file SchematikaParser.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include +#include +#include + +namespace xo { + using xo::scm::SchematikaParser; + using xo::scm::ParserResult; + using xo::scm::parser_result_type; + using xo::scm::Token; + using xo::mm::ArenaConfig; + using xo::mm::AAllocator; + using xo::mm::DArena; + using xo::facet::with_facet; + + namespace ut { + TEST_CASE("SchematikaParser-ctor", "[reader2][SchematikaParser]") + { + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + + REQUIRE(parser.debug_flag() == false); + REQUIRE(parser.is_at_toplevel() == true); + } + + TEST_CASE("SchematikaParser-begin-interactive", "[reader2][SchematikaParser]") + { + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + // after begin_interactive_session, parser has toplevel exprseq + // but is still "at toplevel" in the sense of ready for input + REQUIRE(parser.has_incomplete_expr() == false); + } + + TEST_CASE("SchematikaParser-begin-batch", "[reader2][SchematikaParser]") + { + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + + parser.begin_translation_unit(); + + // after begin_translation_unit, parser has toplevel exprseq + // but is still "at toplevel" in the sense of ready for input + REQUIRE(parser.has_incomplete_expr() == false); + } + + TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") + { + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + parser.on_token(Token::if_token()); + + // after begin_interactive_session, parser has toplevel exprseq + // but is still "at toplevel" in the sense of ready for input + REQUIRE(parser.has_incomplete_expr() == false); + } + + } /*namespace ut*/ +} /*namespace xo*/ + +/* end SchematikaParser.test.cpp */ diff --git a/xo-reader2/utest/reader2_utest_main.cpp b/xo-reader2/utest/reader2_utest_main.cpp new file mode 100644 index 00000000..cccb0e64 --- /dev/null +++ b/xo-reader2/utest/reader2_utest_main.cpp @@ -0,0 +1,27 @@ +/** @file reader2_utest_main.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include + +#define CATCH_CONFIG_RUNNER +#include "catch2/catch.hpp" + +int +main(int argc, char* argv[]) +{ + using xo::Subsystem; + + // initialize subsystems + Subsystem::initialize_all(); + + // Run Catch2's test session + int result = Catch::Session().run(argc, argv); + + // cleanup here, if any + + return result; +} + +/* end reader2_utest_main.cpp */ From e252a9f4e72e5e8251b6df470c2c7f6ca9097f46 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 00:39:16 -0500 Subject: [PATCH 010/258] xo-reader: + DDefineSsm + utest --- xo-reader2/CMakeLists.txt | 12 ++++ xo-reader2/idl/SyntaxStateMachine.json5 | 9 +++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 27 +++++++- .../include/xo/reader2/DExprSeqState.hpp | 5 ++ .../include/xo/reader2/ParserResult.hpp | 4 ++ .../include/xo/reader2/ParserStateMachine.hpp | 6 ++ .../include/xo/reader2/SchematikaParser.hpp | 2 +- .../include/xo/reader2/SyntaxStateMachine.hpp | 2 +- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 4 +- .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 3 +- .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 4 +- .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 5 +- .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 5 +- xo-reader2/src/reader2/CMakeLists.txt | 1 + xo-reader2/src/reader2/DDefineSsm.cpp | 61 ++++++++++++++++--- xo-reader2/src/reader2/DExprSeqState.cpp | 20 +++++- .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 ++ .../ISyntaxStateMachine_DExprSeqState.cpp | 15 ++++- xo-reader2/src/reader2/ParserStateMachine.cpp | 20 ++++-- xo-reader2/src/reader2/SchematikaParser.cpp | 2 +- xo-reader2/utest/SchematikaParser.test.cpp | 34 ++++++++++- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 22 files changed, 220 insertions(+), 29 deletions(-) diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 1f3a4520..a00bc2c1 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -44,6 +44,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-definessm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR DefineSsm + INPUT idl/ISyntaxStateMachine_DDefineSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + # ---------------------------------------------------------------- # shared library diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 0023a16e..f2058e9d 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -43,6 +43,15 @@ }, ], nonconst_methods: [ + { + name: "on_def_token", + doc: ["update state machine for incoming define-keyworkd-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "ps_psm"}, + ], + }, { name: "on_if_token", doc: ["update state machine for incoming if-keyword-token @p tk"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 10ec3097..3a34d0a3 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -3,6 +3,8 @@ * @author Roland Conybeare, Jan 2026 **/ +#pragma once + #include "ParserStateMachine.hpp" #include "SyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" @@ -67,8 +69,24 @@ namespace xo { **/ class DDefineSsm { public: + using DArena = xo::mm::DArena; public: + /** @defgroup scm-define-ssm-facet constructors **/ + ///@{ + + DDefineSsm(); + + /** create instance using memory from @p parser_mm **/ + static DDefineSsm * make(DArena & parser_mm); + + /** start nested parser for a define-expression, + * on top of parser state machine @p p_psm + **/ + static void start(DArena & parser_mm, + ParserStateMachine * p_psm); + + ///@} /** @defgroup scm-define-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -83,7 +101,14 @@ namespace xo { /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm **/ - void on_if_token(const Token & tk, ParserStateMachine * p_psm); + void on_def_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); ///@} diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index f081691a..c0e0d8af 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -56,6 +56,11 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_def_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/ParserResult.hpp b/xo-reader2/include/xo/reader2/ParserResult.hpp index 3aadbdae..e179d4bd 100644 --- a/xo-reader2/include/xo/reader2/ParserResult.hpp +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -40,6 +40,10 @@ namespace xo { obj result_expr() const { return result_expr_; } const DString * error_description() const { return error_description_; } + bool is_incomplete() const { return result_type_ == parser_result_type::none; } + bool is_expression() const { return result_type_ == parser_result_type::expression; } + bool is_error() const { return result_type_ == parser_result_type::error; } + private: parser_result_type result_type_ = parser_result_type::none; obj result_expr_; diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 466e07f8..63d761c0 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -53,6 +53,9 @@ namespace xo { /** @defgroup scm-parserstatemachine-bookkeeping bookkeeping methods **/ ///@{ + /** allocator for parsing stack and ssm's **/ + DArena & parser_alloc() noexcept { return parser_alloc_; } + /** establish toplevel @p ssm. Must have empty stack **/ void establish_toplevel_ssm(obj ssm); @@ -75,6 +78,9 @@ namespace xo { **/ void on_token(const Token & tk); + /** update state for incoming define-token @p tk **/ + void on_def_token(const Token & tk); + /** update state for incoming if-token @p tk **/ void on_if_token(const Token & tk); diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index b0f78bff..075fb4fc 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -190,7 +190,7 @@ namespace xo { /** put parser into state for beginning of a translation unit * (i.e. input stream) **/ - void begin_translation_unit(); + void begin_batch_session(); /** include next token @p tk and increment parser state. * diff --git a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp index deda9e1d..56a8271b 100644 --- a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index a519b246..a6586263 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -54,6 +54,8 @@ public: virtual std::string_view get_expect_str(Copaque data) const noexcept = 0; // nonconst methods + /** update state machine for incoming define-keyworkd-token @p tk **/ + virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * ps_psm) = 0; /** update state machine for incoming if-keyword-token @p tk **/ virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 2d5dd0c3..35efd49e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -59,6 +59,7 @@ namespace scm { [[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); } // nonconst methods + [[noreturn]] void on_def_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index b1d889b1..c3a540a8 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -53,6 +53,8 @@ namespace xo { static std::string_view get_expect_str(const DExprSeqState & self) noexcept; // non-const methods + /** update state machine for incoming define-keyworkd-token @p tk **/ + static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * ps_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index c3aec83e..ad48c7af 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -50,6 +50,9 @@ namespace scm { } // non-const methods + void on_def_token(Opaque data, const Token & tk, ParserStateMachine * ps_psm) override { + return I::on_def_token(_dcast(data), tk, ps_psm); + } void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_if_token(_dcast(data), tk, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 5f920614..8841e242 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -55,6 +55,9 @@ public: } // non-const methods (still const in router!) + void on_def_token(const Token & tk, ParserStateMachine * ps_psm) { + return O::iface()->on_def_token(O::data(), tk, ps_psm); + } void on_if_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_if_token(O::data(), tk, p_psm); } diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index ff8eb418..290f75cc 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -15,6 +15,7 @@ set(SELF_SRCS ISyntaxStateMachine_DExprSeqState.cpp DDefineSsm.cpp + ISyntaxStateMachine_DDefineSsm.cpp reader2_register_facets.cpp reader2_register_types.cpp diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 609ec0db..87d1af35 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -4,6 +4,8 @@ **/ #include "DDefineSsm.hpp" +#include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" + #ifdef NOT_YET #include "parserstatemachine.hpp" #include "expect_symbol_xs.hpp" @@ -13,6 +15,9 @@ #endif namespace xo { + using xo::facet::with_facet; + using xo::facet::typeseq; + namespace scm { // ----- defexprstatetype ----- @@ -46,16 +51,11 @@ namespace xo { define_xs::make() { return std::make_unique(define_xs(DefineExprAccess::make_empty())); } +#endif - void - define_xs::start(parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - p_psm->push_exprstate(define_xs::make()); - p_psm->top_exprstate().on_def_token(token_type::def(), p_psm); - } + // DDefineSsm::start +#ifdef NOT_YET define_xs::define_xs(rp def_expr) : exprstate(exprstatetype::defexpr), defxs_type_{defexprstatetype::def_0}, @@ -333,6 +333,36 @@ namespace xo { //////////////////////////////////////////////////////////////// + DDefineSsm::DDefineSsm() + : defstate_{defexprstatetype::def_0} + {} + + DDefineSsm * + DDefineSsm::make(DArena & mm) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DDefineSsm)); + + return new (mem) DDefineSsm(); + } + + void + DDefineSsm::start(DArena & mm, + ParserStateMachine * p_psm) + { + //scope log(XO_DEBUG(p_psm->debug_flag())); + + assert(p_psm->stack()); + + DDefineSsm * define_ssm = DDefineSsm::make(mm); + + obj ssm + = with_facet::mkobj(define_ssm); + + p_psm->push_ssm(ssm); + p_psm->on_def_token(Token::def_token()); + } + syntaxstatetype DDefineSsm::ssm_type() const noexcept { @@ -380,6 +410,21 @@ namespace xo { return "?expect"; } + void + DDefineSsm::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (this->defstate_ == defexprstatetype::def_0) { + this->defstate_ = defexprstatetype::def_1; + + // expect_symbol_xs::start(p_psm->parser_alloc(), p_psm); + } + + p_psm->illegal_input_on_token("DDefineSsm::on_define_token", + tk, + this->get_expect_str()); + } + void DDefineSsm::on_if_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 4d6ae613..2922dd7f 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -4,6 +4,7 @@ **/ #include "DExprSeqState.hpp" +#include "DDefineSsm.hpp" #include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" namespace xo { @@ -73,13 +74,30 @@ namespace xo { return "impossible-DExprSeqState::get_expr_str"; } + void + DExprSeqState::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DDefineSsm::start(p_psm->parser_alloc(), p_psm); + + /* keyword 'def' introduces a definition: + * def pi : f64 = 3.14159265 + * def sq(x : f64) -> f64 { (x * x) } + */ + } + void DExprSeqState::on_if_token(const Token & tk, ParserStateMachine * p_psm) { switch (seqtype_) { case exprseqtype::toplevel_interactive: - assert(false); // DfElseState::start(p_psm); + p_psm->illegal_input_on_token("DExprSeqState::on_if_token", + tk, + this->get_expect_str()); + //assert(false); // DfElseState::start(p_psm); break; case exprseqtype::toplevel_batch: p_psm->illegal_input_on_token("DExprSeqState::on_if_token", diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 8c4c0b42..ce85a9e0 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -34,6 +34,12 @@ ISyntaxStateMachine_Any::_valid // nonconst methods +auto +ISyntaxStateMachine_Any::on_def_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_if_token(Opaque, const Token &, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 87f4f2d8..a3abc520 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,7 +28,16 @@ namespace xo { } auto - ISyntaxStateMachine_DExprSeqState::on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_def_token(DExprSeqState & self, + const Token & tk, + ParserStateMachine * p_psm) -> void + { + self.on_def_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExprSeqState::on_if_token(DExprSeqState & self, + const Token & tk, + ParserStateMachine * p_psm) -> void { self.on_if_token(tk, p_psm); } @@ -36,4 +45,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISyntaxStateMachine_DExprSeqState.cpp */ \ No newline at end of file +/* end ISyntaxStateMachine_DExprSeqState.cpp */ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 4756975a..25765466 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -48,8 +48,7 @@ namespace xo { auto alloc = with_facet::mkobj(&parser_alloc_); - this->stack_ = ParserStack::push(nullptr /*stack*/, - alloc, ssm); + this->stack_ = ParserStack::push(nullptr /*stack*/, alloc, ssm); this->parser_alloc_ckp_ = parser_alloc_.checkpoint(); } @@ -96,11 +95,14 @@ namespace xo { } switch (tk.tk_type()) { + case tokentype::tk_def: + this->on_def_token(tk); + break; + case tokentype::tk_if: this->on_if_token(tk); break; - // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_bool: @@ -133,7 +135,6 @@ namespace xo { case tokentype::tk_cmpeq: case tokentype::tk_cmpne: case tokentype::tk_type: - case tokentype::tk_def: case tokentype::tk_lambda: case tokentype::tk_then: case tokentype::tk_else: @@ -141,12 +142,21 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: case tokentype::N: - throw std::runtime_error(tostr("NOT IMPLEMENTED", + throw std::runtime_error(tostr("ParserStateMachin::on_token:", + "NOT IMPLEMENTED", xtag("token", tk))); } } + void + ParserStateMachine::on_def_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_def_token(tk, this); + } + void ParserStateMachine::on_if_token(const Token & tk) { diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index f9f0b482..47f6918b 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -43,7 +43,7 @@ namespace xo { } void - SchematikaParser::begin_translation_unit() { + SchematikaParser::begin_batch_session() { DExprSeqState::establish_batch(*(psm_.expr_alloc()), &psm_); } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 1f066f3e..b333ff0c 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -62,13 +62,38 @@ namespace xo { SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); - parser.begin_translation_unit(); + parser.begin_batch_session(); // after begin_translation_unit, parser has toplevel exprseq // but is still "at toplevel" in the sense of ready for input REQUIRE(parser.has_incomplete_expr() == false); } + TEST_CASE("SchematikaParser-batch-def", "[reader2][SchematikaParser]") + { + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + + parser.begin_batch_session(); + + auto & result = parser.on_token(Token::def_token()); + + // define-expressions not properly implemented + + // after begin_interactive_session, parser has toplevel exprseq + // but is still "at toplevel" in the sense of ready for input + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(result.is_error()); + + REQUIRE(result.error_description()); + } + TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") { ArenaConfig config; @@ -82,11 +107,16 @@ namespace xo { parser.begin_interactive_session(); - parser.on_token(Token::if_token()); + auto & result = parser.on_token(Token::if_token()); // after begin_interactive_session, parser has toplevel exprseq // but is still "at toplevel" in the sense of ready for input REQUIRE(parser.has_incomplete_expr() == false); + + REQUIRE(result.is_error()); + + // illegal input on token + REQUIRE(result.error_description()); } } /*namespace ut*/ diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index 0994e3b8..7ed490cc 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -132,7 +132,7 @@ namespace xo { /** token representing keyword @c type **/ static Token type() { return Token(tokentype::tk_type); } /** token representing keyword @c def **/ - static Token def() { return Token(tokentype::tk_def); } + static Token def_token() { return Token(tokentype::tk_def); } /** token representing keyword @c lambda **/ static Token lambda() { return Token(tokentype::tk_lambda); } /** token representing keyword @c if **/ From 83ef04c250e4154c4423ddf75d2e8f3a0f4bf258 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 11:32:39 -0500 Subject: [PATCH 011/258] xo-reader2: + ExpectSymbolSsm + SyntaxStateMachine.on_parsed_symbol --- xo-reader2/CMakeLists.txt | 12 ++ xo-reader2/doc/README.md | 6 + xo-reader2/doc/glossary.rst | 3 + ...ISyntaxStateMachine_DExpectSymbolSsm.json5 | 13 +++ xo-reader2/idl/SyntaxStateMachine.json5 | 13 ++- xo-reader2/include/xo/reader2/DDefineSsm.hpp | 8 +- .../include/xo/reader2/DExpectSymbolSsm.hpp | 91 +++++++++++++++ .../include/xo/reader2/DExprSeqState.hpp | 6 + xo-reader2/include/xo/reader2/ParserStack.hpp | 17 ++- .../include/xo/reader2/ParserStateMachine.hpp | 15 ++- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 6 +- .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 6 +- .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 68 +++++++++++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 6 +- .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 7 +- .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 7 +- .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 3 + xo-reader2/src/reader2/DDefineSsm.cpp | 16 ++- xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 109 ++++++++++++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 9 ++ .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 + .../ISyntaxStateMachine_DDefineSsm.cpp | 23 ++-- .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 49 ++++++++ .../ISyntaxStateMachine_DExprSeqState.cpp | 15 +-- xo-reader2/src/reader2/ParserStack.cpp | 22 +++- xo-reader2/src/reader2/ParserStateMachine.cpp | 49 +++++++- 28 files changed, 537 insertions(+), 52 deletions(-) create mode 100644 xo-reader2/doc/README.md create mode 100644 xo-reader2/doc/glossary.rst create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp create mode 100644 xo-reader2/src/reader2/DExpectSymbolSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index a00bc2c1..17c3aac7 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -56,6 +56,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectsymbolssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExpectSymbolSsm + INPUT idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + # ---------------------------------------------------------------- # shared library diff --git a/xo-reader2/doc/README.md b/xo-reader2/doc/README.md new file mode 100644 index 00000000..01b5c555 --- /dev/null +++ b/xo-reader2/doc/README.md @@ -0,0 +1,6 @@ +diagram for parsing stack. +stack growing down for nested ssm's + +`on_if_token` etc going to same state + +`on_parsed_xxx` going back up the stack diff --git a/xo-reader2/doc/glossary.rst b/xo-reader2/doc/glossary.rst new file mode 100644 index 00000000..67b04538 --- /dev/null +++ b/xo-reader2/doc/glossary.rst @@ -0,0 +1,3 @@ +ssm = syntax state machine +psm = parser state machine +ckp = checkpoint diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 new file mode 100644 index 00000000..24b754e4 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectSymbolSsm", + using_doxygen: true, + repr: "DExpectSymbolSsm", + doc: [ "implement ASyntaxStateMachine for DExpectSymbolSsm" ], +} diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index f2058e9d..2be2a98d 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -45,11 +45,11 @@ nonconst_methods: [ { name: "on_def_token", - doc: ["update state machine for incoming define-keyworkd-token @p tk"], + doc: ["update state machine for incoming define-keyword-token @p tk"], return_type: "void", args: [ {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "ps_psm"}, + {type: "ParserStateMachine *", name: "p_psm"}, ], }, { @@ -61,5 +61,14 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_symbol", + doc: ["update stat machine for incoming parsed symbol @p sym"], + return_type: "void", + args: [ + {type: "std::string_view", name: "sym"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, ], } diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 3a34d0a3..37ccc23d 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -6,7 +6,7 @@ #pragma once #include "ParserStateMachine.hpp" -#include "SyntaxStateMachine.hpp" +//#include "SyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" #include @@ -110,6 +110,12 @@ namespace xo { void on_if_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; + * overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + ///@} private: diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp new file mode 100644 index 00000000..dadd1300 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -0,0 +1,91 @@ +/* file DExpectSymbolSsm.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "ParserStateMachine.hpp" +//#include "SyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include + +namespace xo { + namespace scm { + /** @class DExpectSymbolSsm + * @brief state machine to expect + capture a symbol + * + * For example: + * - lhs in a define-expression + **/ + class DExpectSymbolSsm { + public: + using DArena = xo::mm::DArena; + + public: + DExpectSymbolSsm(); + + /** create instance using memory from @p parser_mm **/ + static DExpectSymbolSsm * make(DArena & parser_mm); + + /** start nested parser expecting a symbol, + * on top of parser state machine @p p_psm. + * On success will deliver symbol by invoking + * .on_symbol(sym, p_psm) + * to the state machine on top of the stack + * as of when this start() method invoked + **/ + static void start(DArena & parser_mm, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming token @p tk, + * with overall parser state in @p p_psm + **/ + static void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + + /** @defgroup scm-expectsymbol-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error mesages + **/ + std::string_view get_expect_str() const noexcept; + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_def_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a symbol @p sym; + * overall parser state in @p p_psm. + * + * NOTE: + * might not be obvious that this is unreachable. + * DExpectSymbolSsm converts a symbol token, + * and delivers it to parent ssm using this entry point. + * This method would only be called if consecutive + * DExpectSymbolSsm instances on parser stack; + * which scenario never occurs in Schematika syntax + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + + ///@} + + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectSymbolSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index c0e0d8af..1b611aaf 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -66,6 +66,12 @@ namespace xo { **/ void on_if_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on parsed symbol @p sym + * from immediately-downstream ssm. + * overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); + ///@} private: diff --git a/xo-reader2/include/xo/reader2/ParserStack.hpp b/xo-reader2/include/xo/reader2/ParserStack.hpp index 4a87de7f..b63be044 100644 --- a/xo-reader2/include/xo/reader2/ParserStack.hpp +++ b/xo-reader2/include/xo/reader2/ParserStack.hpp @@ -6,7 +6,7 @@ #pragma once #include "SyntaxStateMachine.hpp" -#include +#include #include namespace xo { @@ -20,22 +20,31 @@ namespace xo { **/ class ParserStack { public: - using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; public: - ParserStack(obj ssm, ParserStack * parent); + ParserStack(DArena::Checkpoint ckp, + obj ssm, + ParserStack * parent); /** create new top of stack for syntax @p ssm, using memory from @p mm. * previous stack given by @p parent **/ static ParserStack * push(ParserStack * stack, - obj mm, + DArena & mm, obj ssm); + /** unwind effect of last call to @ref push **/ + static ParserStack * pop(ParserStack * stack, + DArena & mm); + + DArena::Checkpoint ckp() const noexcept { return ckp_; } obj top() const noexcept { return ssm_; } ParserStack * parent() const noexcept { return parent_; } private: + /** stack pointer: top of stack just before this instance created **/ + DArena::Checkpoint ckp_; /** top of parsing stack: always non-null **/ obj ssm_; /** remainder of parsing stack excluding top **/ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 63d761c0..f5293bff 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -62,6 +62,9 @@ namespace xo { /** push syntax @p ssm onto @ref stack_ **/ void push_ssm(obj ssm); + /** pop syntax state machine from top of @ref stack_ **/ + void pop_ssm(); + /** reset result to none **/ void reset_result(); @@ -73,6 +76,9 @@ namespace xo { /** @defgroup scm-parserstatemachine-inputmethods input methods **/ ///@{ + /** update state to respond to prsed symbol @p sym **/ + void on_parsed_symbol(std::string_view sym); + /** update state to respond to input token @p tk. * record output (if any) in @ref result_ **/ @@ -99,12 +105,19 @@ namespace xo { /** report illegal input from syntax state machine @p ssm_name * recognized on input token @p tk. @p expect_str describes - * expected input in that state + * expected input in current ssm state **/ void illegal_input_on_token(std::string_view ssm_name, const Token & tk, std::string_view expect_str); + /** report illegal input from syntax state machine @p ssm_name + * receiving parsed symbol @p sym. @p expect_str describes + * expected input in current ssm state + **/ + void illegal_input_on_symbol(std::string_view ssm_name, + std::string_view sym, + std::string_view expect_str); ///@} private: diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index a6586263..b181fd8d 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -54,8 +54,10 @@ public: virtual std::string_view get_expect_str(Copaque data) const noexcept = 0; // nonconst methods - /** update state machine for incoming define-keyworkd-token @p tk **/ - virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * ps_psm) = 0; + /** update stat machine for incoming parsed symbol @p sym **/ + virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming define-keyword-token @p tk **/ + virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming if-keyword-token @p tk **/ virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 35efd49e..046adacb 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -59,6 +59,7 @@ namespace scm { [[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); } // nonconst methods + [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_def_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index adb39c48..cfb38fa7 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -53,8 +53,10 @@ namespace xo { static std::string_view get_expect_str(const DDefineSsm & self) noexcept; // non-const methods - /** update state machine for incoming define-keyworkd-token @p tk **/ - static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * ps_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp new file mode 100644 index 00000000..44cb6de4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -0,0 +1,68 @@ +/** @file ISyntaxStateMachine_DExpectSymbolSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectSymbolSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectSymbolSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectSymbolSsm + **/ + class ISyntaxStateMachine_DExpectSymbolSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectsymbolssm-type-traits **/ + ///@{ + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectsymbolssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectSymbolSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectSymbolSsm & self) noexcept; + + // non-const methods + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming if-keyword-token @p tk **/ + static void on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index c3a540a8..4da00f95 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -53,8 +53,10 @@ namespace xo { static std::string_view get_expect_str(const DExprSeqState & self) noexcept; // non-const methods - /** update state machine for incoming define-keyworkd-token @p tk **/ - static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * ps_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index ad48c7af..7de32e25 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -50,8 +50,11 @@ namespace scm { } // non-const methods - void on_def_token(Opaque data, const Token & tk, ParserStateMachine * ps_psm) override { - return I::on_def_token(_dcast(data), tk, ps_psm); + void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { + return I::on_parsed_symbol(_dcast(data), sym, p_psm); + } + void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_def_token(_dcast(data), tk, p_psm); } void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_if_token(_dcast(data), tk, p_psm); diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 8841e242..f35f4e72 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -55,8 +55,11 @@ public: } // non-const methods (still const in router!) - void on_def_token(const Token & tk, ParserStateMachine * ps_psm) { - return O::iface()->on_def_token(O::data(), tk, ps_psm); + void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); + } + void on_def_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_def_token(O::data(), tk, p_psm); } void on_if_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_if_token(O::data(), tk, p_psm); diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index ae02cad4..bf3e03f1 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -21,6 +21,9 @@ namespace xo { /** toplevel of some translation unit. See @ref DExprSeqState **/ expect_toplevel_expression_sequence, + /** expecting a s symbol. See @ref DExpectSymbolSsm **/ + expect_symbol, + /** handle define-expression. See @ref DDefineSsm **/ defexpr, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 290f75cc..655ac7e9 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -17,6 +17,9 @@ set(SELF_SRCS DDefineSsm.cpp ISyntaxStateMachine_DDefineSsm.cpp + DExpectSymbolSsm.cpp + ISyntaxStateMachine_DExpectSymbolSsm.cpp + reader2_register_facets.cpp reader2_register_types.cpp ) diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 87d1af35..8ac919e4 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -46,12 +46,7 @@ namespace xo { // ----- define_xs ----- -#ifdef NOT_YET - std::unique_ptr - define_xs::make() { - return std::make_unique(define_xs(DefineExprAccess::make_empty())); - } -#endif + // DDefineSsm::make // DDefineSsm::start @@ -410,6 +405,15 @@ namespace xo { return "?expect"; } + void + DDefineSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DDefineSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + void DDefineSsm::on_def_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp new file mode 100644 index 00000000..6afe337c --- /dev/null +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -0,0 +1,109 @@ +/** @file DExpectSymbolSsm.cpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#include "DExpectSymbolSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp" +#include "SyntaxStateMachine.hpp" +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +//#include + +namespace xo { + using xo::facet::with_facet; + using xo::facet::typeseq; + + namespace scm { + DExpectSymbolSsm::DExpectSymbolSsm() + {} + + DExpectSymbolSsm * + DExpectSymbolSsm::make(DArena & mm) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DExpectSymbolSsm)); + + return new (mem) DExpectSymbolSsm(); + } + + void + DExpectSymbolSsm::start(DArena & parser_alloc, + ParserStateMachine * p_psm) + { + DExpectSymbolSsm * sym_ssm + = DExpectSymbolSsm::make(parser_alloc); + + // note: + // relying on [ISyntaxStateMachine_DExpectedSymbolSsm.hpp] + // + obj ssm + = with_facet::mkobj(sym_ssm); + + p_psm->push_ssm(ssm); + } + + syntaxstatetype + DExpectSymbolSsm::ssm_type() const noexcept + { + return syntaxstatetype::expect_symbol; + } + + std::string_view + DExpectSymbolSsm::get_expect_str() const noexcept + { + return "symbol"; + } + + void + DExpectSymbolSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { +#ifdef NOT_YET + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("tk", tk)); + + assert(&p_psm->top_exprstate() == this); +#endif + + /* have to do pop first, before sending symbol to + * the o.g. symbol-requester + */ + p_psm->pop_ssm(); + + p_psm->on_parsed_symbol(std::string_view(tk.text())); + } + + void + DExpectSymbolSsm::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_def_token", + tk, + this->get_expect_str()); + } + + void + DExpectSymbolSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_if_token", + tk, + this->get_expect_str()); + } + + void + DExpectSymbolSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExpectSymbolSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectSymbolSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 2922dd7f..cca208f6 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -109,6 +109,15 @@ namespace xo { break; } } + + void + DExprSeqState::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExprSeqState::on_parsed_symbol", + sym, + this->get_expect_str()); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index ce85a9e0..2076aa5f 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -34,6 +34,12 @@ ISyntaxStateMachine_Any::_valid // nonconst methods +auto +ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_def_token(Opaque, const Token &, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index bf17c9b5..96020a95 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -16,30 +16,29 @@ namespace xo { namespace scm { auto - ISyntaxStateMachine_DDefineSsm::ssm_type(const DDefineSsm & self) noexcept - -> syntaxstatetype + ISyntaxStateMachine_DDefineSsm::ssm_type(const DDefineSsm & self) noexcept -> syntaxstatetype { return self.ssm_type(); } auto - ISyntaxStateMachine_DDefineSsm::get_expect_str(const DDefineSsm & self) noexcept - -> std::string_view + ISyntaxStateMachine_DDefineSsm::get_expect_str(const DDefineSsm & self) noexcept -> std::string_view { return self.get_expect_str(); } auto - ISyntaxStateMachine_DDefineSsm::on_def_token(DDefineSsm & self, - const Token & tk, - ParserStateMachine * ps_psm) -> void + ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { - self.on_def_token(tk, ps_psm); + self.on_parsed_symbol(sym, p_psm); } auto - ISyntaxStateMachine_DDefineSsm::on_if_token(DDefineSsm & self, - const Token & tk, - ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DDefineSsm::on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_def_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DDefineSsm::on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_if_token(tk, p_psm); } @@ -47,4 +46,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISyntaxStateMachine_DDefineSsm.cpp */ +/* end ISyntaxStateMachine_DDefineSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp new file mode 100644 index 00000000..b2efaab5 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -0,0 +1,49 @@ +/** @file ISyntaxStateMachine_DExpectSymbolSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectSymbolSsm::ssm_type(const DExpectSymbolSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectSymbolSsm::get_expect_str(const DExpectSymbolSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_def_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_if_token(tk, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectSymbolSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index a3abc520..2279ea88 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -28,16 +28,17 @@ namespace xo { } auto - ISyntaxStateMachine_DExprSeqState::on_def_token(DExprSeqState & self, - const Token & tk, - ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExprSeqState::on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_def_token(tk, p_psm); } auto - ISyntaxStateMachine_DExprSeqState::on_if_token(DExprSeqState & self, - const Token & tk, - ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_if_token(tk, p_psm); } @@ -45,4 +46,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISyntaxStateMachine_DExprSeqState.cpp */ +/* end ISyntaxStateMachine_DExprSeqState.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ParserStack.cpp b/xo-reader2/src/reader2/ParserStack.cpp index 5b416c54..ba39517d 100644 --- a/xo-reader2/src/reader2/ParserStack.cpp +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -10,21 +10,35 @@ namespace xo { using xo::facet::typeseq; namespace scm { - ParserStack::ParserStack(obj ssm, + ParserStack::ParserStack(DArena::Checkpoint ckp, + obj ssm, ParserStack * parent) - : ssm_{ssm}, parent_{parent} + : ckp_{ckp}, ssm_{ssm}, parent_{parent} {} ParserStack * ParserStack::push(ParserStack * stack, - obj mm, + DArena & mm, obj ssm) { + DArena::Checkpoint ckp = mm.checkpoint(); + void * mem = mm.alloc(typeseq::id(), sizeof(ParserStack)); - return new (mem) ParserStack(ssm, stack); + return new (mem) ParserStack(ckp, ssm, stack); + } + + ParserStack * + ParserStack::pop(ParserStack * stack, + DArena & mm) + { + assert(stack); + + mm.restore(stack->ckp()); + + return stack->parent(); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 25765466..c05ab217 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -46,9 +46,7 @@ namespace xo { assert(stack_ == nullptr); - auto alloc = with_facet::mkobj(&parser_alloc_); - - this->stack_ = ParserStack::push(nullptr /*stack*/, alloc, ssm); + this->stack_ = ParserStack::push(nullptr /*stack*/, parser_alloc_, ssm); this->parser_alloc_ckp_ = parser_alloc_.checkpoint(); } @@ -59,9 +57,17 @@ namespace xo { // note: using parser_alloc_ for parser stack, since stacklike behavior - auto alloc = with_facet::mkobj(&parser_alloc_); + this->stack_ = ParserStack::push(stack_, parser_alloc_, ssm); + } - this->stack_ = ParserStack::push(stack_, alloc, ssm); + void + ParserStateMachine::pop_ssm() + { + scope log(XO_DEBUG(debug_flag_)); + + assert(this->stack_); + + this->stack_ = ParserStack::pop(stack_, parser_alloc_); } void @@ -81,6 +87,16 @@ namespace xo { this->parser_alloc_.restore(parser_alloc_ckp_); } + void + ParserStateMachine::on_parsed_symbol(std::string_view sym) + { + scope log(XO_DEBUG(debug_flag_), xtag("sym", sym)); + + assert(stack_); + + this->stack_->top().on_parsed_symbol(sym, this); + } + void ParserStateMachine::on_token(const Token & tk) { @@ -194,6 +210,29 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + + void + ParserStateMachine::illegal_input_on_symbol(std::string_view ssm_name, + std::string_view sym, + std::string_view expect_str) + { + // TODO: + // - want to write error message using DArena + // - need something like log_streambuf and/or tostr() that's arena-aware + + auto errmsg_string = tostr("Unexpected symbol for parsing state", + xtag("symbol", sym), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_input_on_symbol")); + + assert(expr_alloc_); + + auto errmsg = DString::from_view(*expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } } /*namespace scm*/ } /*namespace xo*/ From 42e2276e971255e001b1a195a571b6ec17a3a0f9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 11:33:14 -0500 Subject: [PATCH 012/258] xo-tokenizer2: cosmetic / minor --- xo-tokenizer2/src/tokenizer2/Tokenizer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp index 4fa98a97..7076a95d 100644 --- a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp +++ b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp @@ -595,10 +595,13 @@ namespace xo { tk_text.clear(); } + // TOOD: report tk_text as span, + // but must pin / unpin + /* input.prefix(0): * require caller preserves current input line until it's entirely exhausted */ - return result_type(token_type(tk_type, std::move(tk_text)), + return result_type(Token(tk_type, std::move(tk_text)), p_input_state->current_line().prefix(0)); } /*assemble_token*/ From 8bae2128a1b9c22b25906f13bb1dd237b1c8dd0b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 11:33:27 -0500 Subject: [PATCH 013/258] xo-reader2: register DDefineSsm + DExpectSymbolSsm facets --- xo-reader2/src/reader2/reader2_register_facets.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index e5b1d157..988f41ab 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -6,6 +6,8 @@ #include "reader2_register_facets.hpp" #include +#include +#include #include #include @@ -22,8 +24,12 @@ namespace xo { scope log(XO_DEBUG(true)); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); log && log(xtag("DExprSeqState.tseq", typeseq::id())); + log && log(xtag("DDefineSsm.tseq", typeseq::id())); + log && log(xtag("DExpectSymbolSsm.tseq", typeseq::id())); return true; } From 516b0932eeefe518d491d7a2e59bc17dab2e031b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 21:25:30 -0500 Subject: [PATCH 014/258] xo-reader2 xo-expresion2: work on define-expressions [WIP] --- xo-expression2/CMakeLists.txt | 16 ++++ .../idl/IExpression_DDefineExpr.json5 | 12 +++ .../include/xo/expression2/Binding.hpp | 2 + .../include/xo/expression2/DDefineExpr.hpp | 75 +++++++++++++++++++ .../include/xo/expression2/DGlobalSymtab.hpp | 39 ++++++++++ .../include/xo/expression2/DVariable.hpp | 26 ++++++- .../detail/IExpression_DDefineExpr.hpp | 66 ++++++++++++++++ .../include/xo/expression2/exprtype.hpp | 4 + xo-expression2/src/expression2/CMakeLists.txt | 5 ++ .../src/expression2/DDefineExpr.cpp | 71 ++++++++++++++++++ .../src/expression2/DGlobalSymtab.cpp | 27 +++++++ .../src/expression2/DLocalSymtab.cpp | 25 +++++++ xo-expression2/src/expression2/DVariable.cpp | 22 ++++++ .../expression2/IExpression_DDefineExpr.cpp | 45 +++++++++++ .../include/xo/facet/facet_implementation.hpp | 2 +- .../interpreter2/VirtualSchematikaMachine.hpp | 6 ++ .../interpreter2/VirtualSchematikaMachine.cpp | 10 +++ xo-reader2/idl/SyntaxStateMachine.json5 | 9 +++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 27 ++++++- .../include/xo/reader2/DExprSeqState.hpp | 5 ++ .../include/xo/reader2/ParserResult.hpp | 2 + .../include/xo/reader2/ParserStateMachine.hpp | 17 +++-- .../include/xo/reader2/SchematikaParser.hpp | 2 +- .../include/xo/reader2/SyntaxStateMachine.hpp | 2 +- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 8 +- .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 5 +- .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 8 +- .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 8 +- .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 8 +- .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 9 ++- .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 9 ++- xo-reader2/src/reader2/DDefineSsm.cpp | 69 +++++++++++++++-- xo-reader2/src/reader2/DExprSeqState.cpp | 37 ++++++++- .../src/reader2/ISyntaxStateMachine_Any.cpp | 8 +- .../ISyntaxStateMachine_DDefineSsm.cpp | 11 ++- .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 11 ++- .../ISyntaxStateMachine_DExprSeqState.cpp | 11 ++- xo-reader2/src/reader2/ParserStateMachine.cpp | 26 ++++++- xo-reader2/src/reader2/SchematikaParser.cpp | 6 +- xo-reader2/utest/SchematikaParser.test.cpp | 32 +++++--- 40 files changed, 711 insertions(+), 72 deletions(-) create mode 100644 xo-expression2/idl/IExpression_DDefineExpr.json5 create mode 100644 xo-expression2/include/xo/expression2/DDefineExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/DGlobalSymtab.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp create mode 100644 xo-expression2/src/expression2/DDefineExpr.cpp create mode 100644 xo-expression2/src/expression2/DGlobalSymtab.cpp create mode 100644 xo-expression2/src/expression2/DLocalSymtab.cpp create mode 100644 xo-expression2/src/expression2/IExpression_DDefineExpr.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index fe5cd540..678e5eca 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -32,6 +32,8 @@ xo_add_genfacet( OUTPUT_CPP_DIR src/expression2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacet( TARGET xo-expression2-facet-expression @@ -66,6 +68,20 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-expression-defineexpr + FACET_PKG xo_expression2 + FACET Expression + REPR DefineExpr + INPUT idl/IExpression_DDefineExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-uniquestring diff --git a/xo-expression2/idl/IExpression_DDefineExpr.json5 b/xo-expression2/idl/IExpression_DDefineExpr.json5 new file mode 100644 index 00000000..ff35d6d6 --- /dev/null +++ b/xo-expression2/idl/IExpression_DDefineExpr.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ "\"Expression.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Expression.json5", + brief: "provide AExpression interface for DDefineExpr state", + using_doxygen: true, + repr: "DDefineExpr", + doc: ["doc for IExpression+DDefineExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/Binding.hpp b/xo-expression2/include/xo/expression2/Binding.hpp index 455c1538..5f0f7e27 100644 --- a/xo-expression2/include/xo/expression2/Binding.hpp +++ b/xo-expression2/include/xo/expression2/Binding.hpp @@ -15,6 +15,7 @@ namespace xo { static constexpr int32_t s_link_global = -1; public: + Binding() : i_link_{-2}, j_slot_{-1} {} Binding(int32_t i_link, int32_t j_slot) : i_link_{i_link}, j_slot_{j_slot} {} @@ -32,6 +33,7 @@ namespace xo { * >= 0: number of parent links to traverse * to a fixed-size frame * -1: resolve globally + * -2: sentinel (binding info not computed) **/ int32_t i_link_ = s_link_sentinel; /** if @ref i_link_ >= 0, frame offset diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp new file mode 100644 index 00000000..94a37197 --- /dev/null +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -0,0 +1,75 @@ +/** @file DDefineExpr.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Expression.hpp" +#include "DVariable.hpp" +#include + +namespace xo { + namespace scm { + class DUniqueString; // see DUniqueString.hpp + + /** @class DDefineExpr + * @brief an expression that introduces a variable. + * + * Variable may optionally be declared with a type, + * and may come with an expression specifying an initial value + **/ + class DDefineExpr { + public: + using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; + + public: + /** create instance: define-expr using memory from @p mm + * with lhs name @p lhs_name and rhs expression @p rhs_expr + **/ + static DDefineExpr * make(obj mm, + const DUniqueString * lhs_name, + obj rhs_expr); + /** create empty skeleton. Rely on this for parsing + **/ + static DDefineExpr * make_empty(obj mm); + + DVariable * lhs() const { return lhs_var_; } + obj rhs() const noexcept { return rhs_; } + + const DUniqueString * name() const noexcept; + + void assign_lhs_name(const DUniqueString * name); + /** CONCESSION. will use DUniqueString* once we have StringTable **/ + void assign_lhs_name(std::string_view name); + + /** @defgroup scm-defineexpr-expression-facet **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::define; } + TypeRef typeref() const noexcept { return lhs_var_->typeref(); } + TypeDescr valuetype() const noexcept { return lhs_var_->typeref().td(); } + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + + private: + DDefineExpr(DVariable * lhs_var, + obj rhs); + + private: + /** variable being defined by this expression. + **/ + DVariable * lhs_var_ = nullptr; + + /** expression for initial value of this expression + **/ + obj rhs_; + + // std::set free_var_set_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp new file mode 100644 index 00000000..bb668ff3 --- /dev/null +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -0,0 +1,39 @@ +/** @file DGlobalSymtab.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Binding.hpp" + +namespace xo { + namespace scm { + class DUniqueString; + + /** @class DGlobalSymtab + * @brief symbol table for toplevel environment + **/ + struct DGlobalSymtab { + public: + + + public: + /** @defgroup xo-expression2-symboltable-facet symboltable facet**/ + ///@{ + + /** true for global symbol table **/ + bool is_global_symtab() const noexcept { return true; } + + /** lookup binding for variable @p sym **/ + Binding lookup_binding(const DUniqueString * sym) const noexcept; + + ///@} + + private: + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalSymtab.hpp */ diff --git a/xo-expression2/include/xo/expression2/DVariable.hpp b/xo-expression2/include/xo/expression2/DVariable.hpp index 036d88ce..2208852e 100644 --- a/xo-expression2/include/xo/expression2/DVariable.hpp +++ b/xo-expression2/include/xo/expression2/DVariable.hpp @@ -19,15 +19,33 @@ namespace xo { **/ class DVariable { public: + using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; public: - DVariable(const DUniqueString & name, const TypeRef & typeref, Binding path) - : name_{name}, typeref_{typeref}, path_{path} {} + /** create instance + * @p mm memory allocator + * @p name variable name + * @p typeref type information for legal values + * (possibly just placeholder when relying on inference) + * @p path binding path to runtime value. + * This may be computed after parsing; + * mnust be resolved before execution. + **/ + static DVariable * make(obj mm, + const DUniqueString * name, + const TypeRef & typeref, + Binding path = Binding()); - const DUniqueString & name() const { return name_; } + DVariable(const DUniqueString * name, + const TypeRef & typeref, + Binding path); + + const DUniqueString * name() const { return name_; } Binding path() const { return path_; } + void assign_name(const DUniqueString * name) { this->name_ = name; } + /** @defgroup scm-variable-expression-facet**/ ///@{ @@ -40,7 +58,7 @@ namespace xo { private: /** symbol name **/ - const DUniqueString & name_; + const DUniqueString * name_; /** variable value always has type consistent * with this description **/ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp new file mode 100644 index 00000000..3ac7fd49 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp @@ -0,0 +1,66 @@ +/** @file IExpression_DDefineExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DDefineExpr.json5] + **/ + +#pragma once + +#include "Expression.hpp" +#include "Expression.hpp" +#include "DDefineExpr.hpp" + +namespace xo { namespace scm { class IExpression_DDefineExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IExpression_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IExpression_DDefineExpr + **/ + class IExpression_DDefineExpr { + public: + /** @defgroup scm-expression-ddefineexpr-type-traits **/ + ///@{ + using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; + ///@} + /** @defgroup scm-expression-ddefineexpr-methods **/ + ///@{ + // const methods + /** expression type (constant | apply | ..) **/ + static exprtype extype(const DDefineExpr & self) noexcept; + /** placeholder for type giving possible values for this expression **/ + static TypeRef typeref(const DDefineExpr & self) noexcept; + /** type giving possible values for this expression. Maybe null before typecheck **/ + static TypeDescr valuetype(const DDefineExpr & self) noexcept; + + // non-const methods + /** assing to valuetype member. Useful when scaffolding expressions **/ + static void assign_valuetype(DDefineExpr & self, TypeDescr td) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/exprtype.hpp b/xo-expression2/include/xo/expression2/exprtype.hpp index 0d5e8299..d64a1191 100644 --- a/xo-expression2/include/xo/expression2/exprtype.hpp +++ b/xo-expression2/include/xo/expression2/exprtype.hpp @@ -23,8 +23,10 @@ namespace xo { #ifdef NOT_YET /** a literal constant that refers to a linkable named function **/ primitive, +#endif /** variable/function definition **/ define, +#ifdef NOT_YET /** variable assignment **/ assign, /** function call **/ @@ -55,7 +57,9 @@ namespace xo { case exprtype::constant: return "constant"; #ifdef NOT_YET case exprtype::primitive: return "primitive"; +#endif case exprtype::define: return "define"; +#ifdef NOT_YET case exprtype::assign: return "assign"; case exprtype::apply: return "apply"; case exprtype::lambda: return "lambda"; diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 9194bfa5..0fcd6541 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -6,12 +6,17 @@ set(SELF_SRCS DConstant.cpp DVariable.cpp + DDefineExpr.cpp TypeRef.cpp IExpression_Any.cpp IExpression_DConstant.cpp IExpression_DVariable.cpp + IExpression_DDefineExpr.cpp + + DLocalSymtab.cpp + DGlobalSymtab.cpp ISymbolTable_Any.cpp diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp new file mode 100644 index 00000000..14d1c52e --- /dev/null +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -0,0 +1,71 @@ +/** @file DDefineExpr.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DDefineExpr.hpp" +#include + +namespace xo { + using xo::facet::typeseq; + + namespace scm { + + DDefineExpr::DDefineExpr(DVariable * lhs_var, + obj rhs) + : lhs_var_{lhs_var}, rhs_{rhs} + {} + + DDefineExpr * + DDefineExpr::make(obj mm, + const DUniqueString * lhs_name, + obj rhs_expr) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DDefineExpr)); + + auto lhs_var = DVariable::make(mm, + lhs_name, + rhs_expr.typeref()); + + return new (mem) DDefineExpr(lhs_var, rhs_expr); + } + + DDefineExpr * + DDefineExpr::make_empty(obj mm) + { + return make(mm, + nullptr /*lhs_name*/, + obj() /*rhs_expr*/); + } + + const DUniqueString * + DDefineExpr::name() const noexcept + { + return lhs_var_->name(); + } + + void + DDefineExpr::assign_lhs_name(const DUniqueString * name) + { + lhs_var_->assign_name(name); + } + + void + DDefineExpr::assign_lhs_name(std::string_view name) + { + scope log(XO_DEBUG(true), "bogus impl - will require unique string"); + log && log(xtag("name", name)); + + //lhs_var_->assign_name(name); + } + + void + DDefineExpr::assign_valuetype(TypeDescr td) noexcept + { + lhs_var_->assign_valuetype(td); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineExpr.cpp */ diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp new file mode 100644 index 00000000..c11761d9 --- /dev/null +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -0,0 +1,27 @@ +/** @file DGlobalSymtab.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DGlobalSymtab.hpp" +#include "DUniqueString.hpp" +#include + +namespace xo { + namespace scm { + + Binding + DGlobalSymtab::lookup_binding(const DUniqueString * sym) const noexcept + { + (void)sym; + + scope log(XO_DEBUG(true), "stub"); + log && log(xtag("sym", std::string_view(*sym))); + + return Binding(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalSymtab.cpp */ diff --git a/xo-expression2/src/expression2/DLocalSymtab.cpp b/xo-expression2/src/expression2/DLocalSymtab.cpp new file mode 100644 index 00000000..febd1463 --- /dev/null +++ b/xo-expression2/src/expression2/DLocalSymtab.cpp @@ -0,0 +1,25 @@ +/** @file DLocalSymtab.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DLocalSymtab.hpp" +#include "DUniqueString.hpp" +#include + +namespace xo { + namespace scm { + + Binding + DLocalSymtab::lookup_binding(const DUniqueString * sym) const noexcept + { + scope log(XO_DEBUG(true), "stub impl"); + log && log(xtag("sym", std::string_view(*sym))); + + return Binding(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLocalSymtab.cpp */ diff --git a/xo-expression2/src/expression2/DVariable.cpp b/xo-expression2/src/expression2/DVariable.cpp index f589da7b..d27c71ef 100644 --- a/xo-expression2/src/expression2/DVariable.cpp +++ b/xo-expression2/src/expression2/DVariable.cpp @@ -7,12 +7,34 @@ #include "exprtype.hpp" namespace xo { + using xo::facet::typeseq; + namespace scm { + + DVariable * + DVariable::make(obj mm, + const DUniqueString * name, + const TypeRef & typeref, + Binding path) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DVariable)); + + return new (mem) DVariable(name, typeref, path); + } + + DVariable::DVariable(const DUniqueString * name, + const TypeRef & typeref, + Binding path) + : name_{name}, typeref_{typeref}, path_{path} + {} + void DVariable::assign_valuetype(TypeDescr td) noexcept { typeref_.resolve(td); } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp new file mode 100644 index 00000000..3222eabd --- /dev/null +++ b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp @@ -0,0 +1,45 @@ +/** @file IExpression_DDefineExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DDefineExpr.json5] +**/ + +#include "detail/IExpression_DDefineExpr.hpp" + +namespace xo { + namespace scm { + auto + IExpression_DDefineExpr::extype(const DDefineExpr & self) noexcept -> exprtype + { + return self.extype(); + } + + auto + IExpression_DDefineExpr::typeref(const DDefineExpr & self) noexcept -> TypeRef + { + return self.typeref(); + } + + auto + IExpression_DDefineExpr::valuetype(const DDefineExpr & self) noexcept -> TypeDescr + { + return self.valuetype(); + } + + auto + IExpression_DDefineExpr::assign_valuetype(DDefineExpr & self, TypeDescr td) noexcept -> void + { + self.assign_valuetype(td); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IExpression_DDefineExpr.cpp */ \ No newline at end of file diff --git a/xo-facet/include/xo/facet/facet_implementation.hpp b/xo-facet/include/xo/facet/facet_implementation.hpp index 5669860a..025645e8 100644 --- a/xo-facet/include/xo/facet/facet_implementation.hpp +++ b/xo-facet/include/xo/facet/facet_implementation.hpp @@ -92,7 +92,7 @@ namespace xo { //static_assert(false && "expect specialization which should provide ImplType trait"); }; - /** Retrieve facet implementation for a (facet, datatype) pair **/ + /** Retrieve facet implementation for a (facet,datatype) pair **/ template using FacetImplType = FacetImplementation::ImplType; diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 8bbe6bb4..a149173e 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -45,6 +45,12 @@ namespace xo { **/ void _do_eval_constant_op(); + /** evaluate a define-expression + * Require: + * - expression in @ref expr_ + **/ + void _do_eval_define_op(); + /** evaluate a variable expression * Require: * - expression in @ref expr_ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index bd29e968..f7131e0a 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -45,6 +45,9 @@ namespace xo { case exprtype::constant: _do_eval_constant_op(); break; + case exprtype::define: + _do_eval_define_op(); + break; case exprtype::variable: _do_eval_variable_op(); break; @@ -61,6 +64,13 @@ namespace xo { this->pc_ = this->cont_; } + void + VirtualSchematikaMachine::_do_eval_define_op() + { + // not implemented + assert(false); + } + void VirtualSchematikaMachine::_do_eval_variable_op() { diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 2be2a98d..28811512 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -43,6 +43,15 @@ }, ], nonconst_methods: [ + { + name: "on_symbol_token", + doc: ["operate state machine for incoming symbol-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_def_token", doc: ["update state machine for incoming define-keyword-token @p tk"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 37ccc23d..3bc042c1 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -8,6 +8,8 @@ #include "ParserStateMachine.hpp" //#include "SyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" +#include +#include #include namespace xo { @@ -69,21 +71,29 @@ namespace xo { **/ class DDefineSsm { public: + using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; public: /** @defgroup scm-define-ssm-facet constructors **/ ///@{ - DDefineSsm(); + /** constructor; using @p def_expr for initial expression scaffold **/ + explicit DDefineSsm(DDefineExpr * def_expr); - /** create instance using memory from @p parser_mm **/ - static DDefineSsm * make(DArena & parser_mm); + /** create instance using memory from @p parser_mm. + * Initial expression scaffold @p def_expr + **/ + static DDefineSsm * make(DArena & parser_mm, + DDefineExpr * def_expr); /** start nested parser for a define-expression, * on top of parser state machine @p p_psm + * Use @p parser_mm to allocate syntax state machines, + * and @p expr_mm to allocate expressions **/ static void start(DArena & parser_mm, + obj expr_mm, ParserStateMachine * p_psm); ///@} @@ -98,6 +108,12 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming symbol-token @p tk + * with overall parser state in @p p_psm + **/ + void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm **/ @@ -121,6 +137,11 @@ namespace xo { private: /** identify define-expression state **/ defexprstatetype defstate_; + + /** scaffolded define-expression. + * This will eventually be the output of this ssm + **/ + obj def_expr_; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 1b611aaf..bef2bd68 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -56,6 +56,11 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming symbol token @p tk + * with overall parser state in @p p_psm + **/ + void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/ParserResult.hpp b/xo-reader2/include/xo/reader2/ParserResult.hpp index e179d4bd..39f9c2d1 100644 --- a/xo-reader2/include/xo/reader2/ParserResult.hpp +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -50,6 +50,8 @@ namespace xo { std::string_view error_src_fn_; const DString * error_description_ = nullptr; }; + + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index f5293bff..5a7a833f 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -6,6 +6,7 @@ #pragma once #include "ParserResult.hpp" +#include #include #include #include @@ -32,14 +33,14 @@ namespace xo { public: ParserStateMachine(const ArenaConfig & config, - obj * expr_alloc); + obj expr_alloc); /** @defgroup scm-parserstatemachine-accessors accessor methods **/ ///@{ bool debug_flag() const noexcept { return debug_flag_; } ParserStack * stack() const noexcept { return stack_; } - obj * expr_alloc() const noexcept { return expr_alloc_; } + obj expr_alloc() const noexcept { return expr_alloc_; } const ParserResult & result() const noexcept { return result_; } /** true iff state machine is currently idle (at top-level) **/ @@ -65,6 +66,9 @@ namespace xo { /** pop syntax state machine from top of @ref stack_ **/ void pop_ssm(); + /** add variable to current local environment (innermost lexical scope) **/ + void upsert_var(DVariable * var); + /** reset result to none **/ void reset_result(); @@ -84,10 +88,13 @@ namespace xo { **/ void on_token(const Token & tk); - /** update state for incoming define-token @p tk **/ + /** operate state machine for incoming symbol-token @p tk **/ + void on_symbol_token(const Token & tk); + + /** operate state machine for incoming define-token @p tk **/ void on_def_token(const Token & tk); - /** update state for incoming if-token @p tk **/ + /** operate state machine for incoming if-token @p tk **/ void on_if_token(const Token & tk); ///@} @@ -153,7 +160,7 @@ namespace xo { * scenario, where top-level Expressions can be discarded * once compiled. **/ - obj * expr_alloc_ = nullptr; + obj expr_alloc_; /** current output from parser **/ ParserResult result_; diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 075fb4fc..2f7d6d95 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -167,7 +167,7 @@ namespace xo { * @p debug_flag true to enable debug logging **/ SchematikaParser(const ArenaConfig & config, - obj * expr_alloc, + obj expr_alloc, bool debug_flag); bool debug_flag() const { return debug_flag_; } diff --git a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp index 56a8271b..deda9e1d 100644 --- a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index b181fd8d..4f428be5 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -54,12 +54,14 @@ public: virtual std::string_view get_expect_str(Copaque data) const noexcept = 0; // nonconst methods - /** update stat machine for incoming parsed symbol @p sym **/ - virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; + /** operate state machine for incoming symbol-token @p tk **/ + virtual void on_symbol_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming define-keyword-token @p tk **/ virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming if-keyword-token @p tk **/ virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update stat machine for incoming parsed symbol @p sym **/ + virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; ///@} }; /*ASyntaxStateMachine*/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 046adacb..23b90621 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -59,9 +59,10 @@ namespace scm { [[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); } // nonconst methods - [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; + [[noreturn]] void on_symbol_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_def_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index cfb38fa7..d420ba16 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DDefineSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -53,12 +53,14 @@ namespace xo { static std::string_view get_expect_str(const DDefineSsm & self) noexcept; // non-const methods - /** update stat machine for incoming parsed symbol @p sym **/ - static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming define-keyword-token @p tk **/ static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 44cb6de4..ba8eb0b9 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -53,12 +53,14 @@ namespace xo { static std::string_view get_expect_str(const DExpectSymbolSsm & self) noexcept; // non-const methods - /** update stat machine for incoming parsed symbol @p sym **/ - static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming define-keyword-token @p tk **/ static void on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 4da00f95..c1e61b40 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -53,12 +53,14 @@ namespace xo { static std::string_view get_expect_str(const DExprSeqState & self) noexcept; // non-const methods - /** update stat machine for incoming parsed symbol @p sym **/ - static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming define-keyword-token @p tk **/ static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 7de32e25..5a8e2fe3 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -50,8 +50,8 @@ namespace scm { } // non-const methods - void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { - return I::on_parsed_symbol(_dcast(data), sym, p_psm); + void on_symbol_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_symbol_token(_dcast(data), tk, p_psm); } void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_def_token(_dcast(data), tk, p_psm); @@ -59,6 +59,9 @@ namespace scm { void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_if_token(_dcast(data), tk, p_psm); } + void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { + return I::on_parsed_symbol(_dcast(data), sym, p_psm); + } ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index f35f4e72..786c83d0 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -55,8 +55,8 @@ public: } // non-const methods (still const in router!) - void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { - return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); + void on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_symbol_token(O::data(), tk, p_psm); } void on_def_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_def_token(O::data(), tk, p_psm); @@ -64,6 +64,9 @@ public: void on_if_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_if_token(O::data(), tk, p_psm); } + void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); + } ///@} /** @defgroup scm-syntaxstatemachine-member-vars **/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 8ac919e4..adf9f429 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -1,9 +1,10 @@ -/** @file DDefineSsm.cpp + /** @file DDefineSsm.cpp * * @author Roland Conybeare, Jan 2026 **/ #include "DDefineSsm.hpp" +#include "DExpectSymbolSsm.hpp" #include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" #ifdef NOT_YET @@ -328,28 +329,33 @@ namespace xo { //////////////////////////////////////////////////////////////// - DDefineSsm::DDefineSsm() - : defstate_{defexprstatetype::def_0} + DDefineSsm::DDefineSsm(DDefineExpr * def_expr) + : defstate_{defexprstatetype::def_0}, + def_expr_{def_expr} {} DDefineSsm * - DDefineSsm::make(DArena & mm) + DDefineSsm::make(DArena & mm, + DDefineExpr * def_expr) { void * mem = mm.alloc(typeseq::id(), sizeof(DDefineSsm)); - return new (mem) DDefineSsm(); + return new (mem) DDefineSsm(def_expr); } void DDefineSsm::start(DArena & mm, + obj expr_mm, ParserStateMachine * p_psm) { //scope log(XO_DEBUG(p_psm->debug_flag())); assert(p_psm->stack()); - DDefineSsm * define_ssm = DDefineSsm::make(mm); + DDefineExpr * def_expr = DDefineExpr::make_empty(expr_mm); + + DDefineSsm * define_ssm = DDefineSsm::make(mm, def_expr); obj ssm = with_facet::mkobj(define_ssm); @@ -387,7 +393,7 @@ namespace xo { case defexprstatetype::def_0: case defexprstatetype::n_defexprstatetype: assert(false); // impossible - return nullptr; + return "impossible!?"; case defexprstatetype::def_1: return "symbol"; case defexprstatetype::def_2: @@ -409,11 +415,57 @@ namespace xo { DDefineSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { + if (this->defstate_ == defexprstatetype::def_1) { + this->defstate_ = defexprstatetype::def_2; + + def_expr_.data()->assign_lhs_name(sym); + + // if this is a genuine top-level define (i.e. nesting level = 0), + // then we need to upsert so we can refer to rhs later. + // + // In other contexts (e.g. body-of-lambda) will be rewriting + // { + // def y = foo(x,x); + // bar(y,y); + // } + // into something like + // { + // (lambda (y123) bar(y123,y123))(foo(x,x)); + // } + // + // This works in the body of lambda, because we don't evaluate anything + // until lambda definition is complete. + // + // For interactive top-level defs we want to evaluate as we go, + // so need incremental bindings. + + if (p_psm->is_at_toplevel()) { + /** remember variable binding in current lexical context **/ + p_psm->upsert_var(def_expr_.data()->lhs()); + } + + return; + } + p_psm->illegal_input_on_symbol("DDefineSsm::on_parsed_symbol", sym, this->get_expect_str()); } + void + DDefineSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + // note: + // in state def_1, DDefineSsm learns symbol via .on_parsed_symbol(). + // symbol token arriving here means encountered symbol while + // in some other, which can't happen for valid Schematika input + + p_psm->illegal_input_on_token("DDefineSssm::on_symbol_token", + tk, + this->get_expect_str()); + } + void DDefineSsm::on_def_token(const Token & tk, ParserStateMachine * p_psm) @@ -421,7 +473,8 @@ namespace xo { if (this->defstate_ == defexprstatetype::def_0) { this->defstate_ = defexprstatetype::def_1; - // expect_symbol_xs::start(p_psm->parser_alloc(), p_psm); + DExpectSymbolSsm::start(p_psm->parser_alloc(), p_psm); + return; } p_psm->illegal_input_on_token("DDefineSsm::on_define_token", diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index cca208f6..4afb9608 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -74,13 +74,48 @@ namespace xo { return "impossible-DExprSeqState::get_expr_str"; } + void + DExprSeqState::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { +#ifdef NOT_YET + obj var = p_psm->lookup_var(tk.text()); + + if (var) { + DProgressSsm::start(var, p_psm); + } else { + p_psm->unknown_variable_error("DExprSeqState::on_symbol_token", + tk, + this->get_expect_str(), + p_psm); + } +#endif + } + break; + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + p_psm->illegal_input_on_token("DExprSeqState::on_symbol_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_def_token(const Token & tk, ParserStateMachine * p_psm) { (void)tk; - DDefineSsm::start(p_psm->parser_alloc(), p_psm); + DDefineSsm::start(p_psm->parser_alloc(), + p_psm->expr_alloc(), + p_psm); /* keyword 'def' introduces a definition: * def pi : f64 = 3.14159265 diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 2076aa5f..44effd57 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -35,7 +35,7 @@ ISyntaxStateMachine_Any::_valid // nonconst methods auto -ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void +ISyntaxStateMachine_Any::on_symbol_token(Opaque, const Token &, ParserStateMachine *) -> void { _fatal(); } @@ -52,6 +52,12 @@ ISyntaxStateMachine_Any::on_if_token(Opaque, const Token &, ParserStateMachine * _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void +{ + _fatal(); +} + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 96020a95..34bd4569 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DDefineSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,9 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DDefineSsm::on_symbol_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_symbol(sym, p_psm); + self.on_symbol_token(tk, p_psm); } auto ISyntaxStateMachine_DDefineSsm::on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void @@ -42,6 +42,11 @@ namespace xo { { self.on_if_token(tk, p_psm); } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index b2efaab5..f00b9c2f 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,9 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectSymbolSsm::on_symbol_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_symbol(sym, p_psm); + self.on_symbol_token(tk, p_psm); } auto ISyntaxStateMachine_DExpectSymbolSsm::on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void @@ -42,6 +42,11 @@ namespace xo { { self.on_if_token(tk, p_psm); } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 2279ea88..47c06ba3 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,9 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_symbol_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_symbol(sym, p_psm); + self.on_symbol_token(tk, p_psm); } auto ISyntaxStateMachine_DExprSeqState::on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void @@ -42,6 +42,11 @@ namespace xo { { self.on_if_token(tk, p_psm); } + auto + ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index c05ab217..2e61be95 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -17,7 +17,7 @@ namespace xo { namespace scm { ParserStateMachine::ParserStateMachine(const ArenaConfig & config, - obj * expr_alloc) + obj expr_alloc) : parser_alloc_{DArena::map(config)}, expr_alloc_{expr_alloc}, debug_flag_{config.debug_flag_} @@ -70,6 +70,13 @@ namespace xo { this->stack_ = ParserStack::pop(stack_, parser_alloc_); } + void + ParserStateMachine::upsert_var(DVariable * var) + { + scope log(XO_DEBUG(true), "stub impl"); + log && log(xtag("var", std::string_view(*(var->name())))); + } + void ParserStateMachine::reset_result() { @@ -111,6 +118,10 @@ namespace xo { } switch (tk.tk_type()) { + case tokentype::tk_symbol: + this->on_symbol_token(tk); + break; + case tokentype::tk_def: this->on_def_token(tk); break; @@ -125,7 +136,6 @@ namespace xo { case tokentype::tk_i64: case tokentype::tk_f64: case tokentype::tk_string: - case tokentype::tk_symbol: case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: @@ -165,6 +175,14 @@ namespace xo { } } + void + ParserStateMachine::on_symbol_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_symbol_token(tk, this); + } + void ParserStateMachine::on_def_token(const Token & tk) { @@ -205,7 +223,7 @@ namespace xo { assert(expr_alloc_); - auto errmsg = DString::from_view(*expr_alloc_, + auto errmsg = DString::from_view(expr_alloc_, std::string_view(errmsg_string)); this->capture_error(ssm_name, errmsg); @@ -228,7 +246,7 @@ namespace xo { assert(expr_alloc_); - auto errmsg = DString::from_view(*expr_alloc_, + auto errmsg = DString::from_view(expr_alloc_, std::string_view(errmsg_string)); this->capture_error(ssm_name, errmsg); diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 47f6918b..442da75e 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -19,7 +19,7 @@ namespace xo { // ----- SchematikaParser ----- SchematikaParser::SchematikaParser(const ArenaConfig & config, - obj * expr_alloc, + obj expr_alloc, bool debug_flag) : psm_{config, expr_alloc}, debug_flag_{debug_flag} @@ -38,13 +38,13 @@ namespace xo { void SchematikaParser::begin_interactive_session() { - DExprSeqState::establish_interactive(*(psm_.expr_alloc()), &psm_); + DExprSeqState::establish_interactive(psm_.expr_alloc(), &psm_); } void SchematikaParser::begin_batch_session() { - DExprSeqState::establish_batch(*(psm_.expr_alloc()), &psm_); + DExprSeqState::establish_batch(psm_.expr_alloc(), &psm_); } const ParserResult & diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index b333ff0c..6100392a 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -27,7 +27,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); REQUIRE(parser.debug_flag() == false); REQUIRE(parser.is_at_toplevel() == true); @@ -42,7 +42,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -60,7 +60,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); parser.begin_batch_session(); @@ -78,20 +78,30 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); parser.begin_batch_session(); - auto & result = parser.on_token(Token::def_token()); + { + auto & result = parser.on_token(Token::def_token()); + + // after begin_interactive_session, parser has toplevel exprseq + // but is still "at toplevel" in the sense of ready for input + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("foo")); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(result.is_error()); + } // define-expressions not properly implemented - // after begin_interactive_session, parser has toplevel exprseq - // but is still "at toplevel" in the sense of ready for input - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(result.is_error()); - REQUIRE(result.error_description()); + //REQUIRE(result.error_description()); } TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") @@ -103,7 +113,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, &expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); parser.begin_interactive_session(); From a0d021abfce2f9d43f3cfa1fdfefeaf7ffbf6a29 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 23:18:30 -0500 Subject: [PATCH 015/258] xo-reader2: bugfix in DDefineExpr --- xo-expression2/src/expression2/DDefineExpr.cpp | 6 +++++- xo-reader2/utest/SchematikaParser.test.cpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index 14d1c52e..ada633f6 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -24,9 +24,13 @@ namespace xo { void * mem = mm.alloc(typeseq::id(), sizeof(DDefineExpr)); + TypeRef rhs_tref; + if (rhs_expr) + rhs_tref = rhs_expr.typeref(); + auto lhs_var = DVariable::make(mm, lhs_name, - rhs_expr.typeref()); + rhs_tref); return new (mem) DDefineExpr(lhs_var, rhs_expr); } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 6100392a..194a6d13 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -95,7 +95,7 @@ namespace xo { auto & result = parser.on_token(Token::symbol_token("foo")); REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(result.is_error()); + REQUIRE(result.is_incomplete()); } // define-expressions not properly implemented From b29f72be5d761404d762c89e07b94fb86a335145 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 23:38:14 -0500 Subject: [PATCH 016/258] xo-reader2: + StringTable in ParserStringTable --- xo-reader2/include/xo/reader2/ParserStateMachine.hpp | 7 +++++++ xo-reader2/include/xo/reader2/SchematikaParser.hpp | 1 + xo-reader2/src/reader2/ParserStateMachine.cpp | 5 ++++- xo-reader2/src/reader2/SchematikaParser.cpp | 3 ++- xo-reader2/utest/SchematikaParser.test.cpp | 10 +++++----- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 5a7a833f..fb276bd0 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -7,6 +7,7 @@ #include "ParserResult.hpp" #include +#include #include #include #include @@ -30,9 +31,11 @@ namespace xo { using AAllocator = xo::mm::AAllocator; using ArenaConfig = xo::mm::ArenaConfig; using DArena = xo::mm::DArena; + using size_type = std::size_t; public: ParserStateMachine(const ArenaConfig & config, + size_type max_stringtable_capacity, obj expr_alloc); /** @defgroup scm-parserstatemachine-accessors accessor methods **/ @@ -129,6 +132,10 @@ namespace xo { private: + /** Table containing interned strings + symbols. + **/ + StringTable stringtable_; + /** Arena for internal parsing stack. * Must be owned exclusively because destructively * modified as parser completes parsing of each sub-expression diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 2f7d6d95..81115239 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -167,6 +167,7 @@ namespace xo { * @p debug_flag true to enable debug logging **/ SchematikaParser(const ArenaConfig & config, + size_t max_stringtable_capacity, obj expr_alloc, bool debug_flag); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 2e61be95..1766f652 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -17,11 +17,14 @@ namespace xo { namespace scm { ParserStateMachine::ParserStateMachine(const ArenaConfig & config, + size_type max_stringtable_capacity, obj expr_alloc) - : parser_alloc_{DArena::map(config)}, + : stringtable_{max_stringtable_capacity}, + parser_alloc_{DArena::map(config)}, expr_alloc_{expr_alloc}, debug_flag_{config.debug_flag_} { + } bool diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 442da75e..ac2d4520 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -19,9 +19,10 @@ namespace xo { // ----- SchematikaParser ----- SchematikaParser::SchematikaParser(const ArenaConfig & config, + size_t max_stringtable_capacity, obj expr_alloc, bool debug_flag) - : psm_{config, expr_alloc}, + : psm_{config, max_stringtable_capacity, expr_alloc}, debug_flag_{debug_flag} { } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 194a6d13..259336cf 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -27,7 +27,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); REQUIRE(parser.debug_flag() == false); REQUIRE(parser.is_at_toplevel() == true); @@ -42,7 +42,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -60,7 +60,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); parser.begin_batch_session(); @@ -78,7 +78,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); parser.begin_batch_session(); @@ -113,7 +113,7 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); - SchematikaParser parser(config, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); parser.begin_interactive_session(); From 0e62562f34c61c5a799dc6d328b9acd03a778c88 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 00:08:51 -0500 Subject: [PATCH 017/258] xo-reader2: intern for DDefineExpr lhs symbol --- .../include/xo/expression2/DDefineExpr.hpp | 22 ++++++++++++++----- .../src/expression2/DDefineExpr.cpp | 9 -------- .../include/xo/reader2/ParserStateMachine.hpp | 4 ++++ xo-reader2/src/reader2/DDefineSsm.cpp | 7 ++++-- xo-reader2/src/reader2/ParserStateMachine.cpp | 6 +++++ 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp index 94a37197..618e4161 100644 --- a/xo-expression2/include/xo/expression2/DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -25,6 +25,9 @@ namespace xo { using TypeDescr = xo::reflect::TypeDescr; public: + /** @defgroup scm-defineexpr-constructors **/ + ///@{ + /** create instance: define-expr using memory from @p mm * with lhs name @p lhs_name and rhs expression @p rhs_expr **/ @@ -35,14 +38,20 @@ namespace xo { **/ static DDefineExpr * make_empty(obj mm); + DDefineExpr(DVariable * lhs_var, + obj rhs); + + ///@} + /** @defgroup scm-definexpr-access-methods **/ + ///@{ + DVariable * lhs() const { return lhs_var_; } obj rhs() const noexcept { return rhs_; } - const DUniqueString * name() const noexcept; void assign_lhs_name(const DUniqueString * name); - /** CONCESSION. will use DUniqueString* once we have StringTable **/ - void assign_lhs_name(std::string_view name); + + ///@} /** @defgroup scm-defineexpr-expression-facet **/ ///@{ @@ -55,10 +64,9 @@ namespace xo { ///@} private: - DDefineExpr(DVariable * lhs_var, - obj rhs); + /** @defgrouop scm-defineexpr-instance-vars **/ + ///@{ - private: /** variable being defined by this expression. **/ DVariable * lhs_var_ = nullptr; @@ -68,6 +76,8 @@ namespace xo { obj rhs_; // std::set free_var_set_; + + ///@} }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index ada633f6..a5609246 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -55,15 +55,6 @@ namespace xo { lhs_var_->assign_name(name); } - void - DDefineExpr::assign_lhs_name(std::string_view name) - { - scope log(XO_DEBUG(true), "bogus impl - will require unique string"); - log && log(xtag("name", name)); - - //lhs_var_->assign_name(name); - } - void DDefineExpr::assign_valuetype(TypeDescr td) noexcept { diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index fb276bd0..b333dd51 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -69,6 +69,10 @@ namespace xo { /** pop syntax state machine from top of @ref stack_ **/ void pop_ssm(); + /** get unique string copy of @p str. Idempotent for each @p str. + **/ + const DUniqueString * intern_string(std::string_view str); + /** add variable to current local environment (innermost lexical scope) **/ void upsert_var(DVariable * var); diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index adf9f429..eabc1868 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -412,12 +412,15 @@ namespace xo { } void - DDefineSsm::on_parsed_symbol(std::string_view sym, + DDefineSsm::on_parsed_symbol(std::string_view sym_name, ParserStateMachine * p_psm) { if (this->defstate_ == defexprstatetype::def_1) { this->defstate_ = defexprstatetype::def_2; + const DUniqueString * sym + = p_psm->intern_string(sym_name); + def_expr_.data()->assign_lhs_name(sym); // if this is a genuine top-level define (i.e. nesting level = 0), @@ -448,7 +451,7 @@ namespace xo { } p_psm->illegal_input_on_symbol("DDefineSsm::on_parsed_symbol", - sym, + sym_name, this->get_expect_str()); } diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 1766f652..ca8bba8b 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -73,6 +73,12 @@ namespace xo { this->stack_ = ParserStack::pop(stack_, parser_alloc_); } + const DUniqueString * + ParserStateMachine::intern_string(std::string_view str) + { + return stringtable_.intern(str); + } + void ParserStateMachine::upsert_var(DVariable * var) { From 353c29791cef29ec06e7cb1d4ee1827a64b6f35a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 00:57:34 -0500 Subject: [PATCH 018/258] xo-reader2: + IPrintable+DExprSeqState --- xo-reader2/CMakeLists.txt | 12 ++++ xo-reader2/idl/IPrintable_DExprSeqState.json5 | 13 ++++ .../include/xo/reader2/DExprSeqState.hpp | 15 +++++ .../reader2/ssm/IPrintable_DExprSeqState.hpp | 62 +++++++++++++++++++ xo-reader2/src/reader2/CMakeLists.txt | 1 + xo-reader2/src/reader2/DExprSeqState.cpp | 24 +++++++ .../src/reader2/IPrintable_DExprSeqState.cpp | 28 +++++++++ 7 files changed, 155 insertions(+) create mode 100644 xo-reader2/idl/IPrintable_DExprSeqState.json5 create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp create mode 100644 xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 17c3aac7..7017425e 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -44,6 +44,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-exprseqstate + FACET_PKG xo_printable2 + FACET Printable + REPR ExprSeqState + INPUT idl/IPrintable_DExprSeqState.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-definessm diff --git a/xo-reader2/idl/IPrintable_DExprSeqState.json5 b/xo-reader2/idl/IPrintable_DExprSeqState.json5 new file mode 100644 index 00000000..d0315c58 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExprSeqState.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExprSeqState", + using_doxygen: true, + repr: "DExprSeqState", + doc: [ "implement APrintable for DExprSeqState" ], +} diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index bef2bd68..32eaef0f 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -25,6 +25,13 @@ namespace xo { N }; + const char * exprseqtype_descr(exprseqtype x); + + inline std::ostream & operator<<(std::ostream & os, exprseqtype x) { + os << exprseqtype_descr(x); + return os; + } + /** @class DExprSeqState * @brief state machine for parsing a sequence of expression * @@ -33,6 +40,7 @@ namespace xo { class DExprSeqState { public: using AAllocator = xo::mm::AAllocator; + using ppindentinfo = xo::print::ppindentinfo; public: explicit DExprSeqState(exprseqtype ty); @@ -78,6 +86,13 @@ namespace xo { void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); ///@} + /** @defgroup scm-exprseq-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printing driver; combine layout+printing **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} private: /** sequence type. accept rvalue expressions when diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp new file mode 100644 index 00000000..87d85fd7 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExprSeqState.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExprSeqState.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExprSeqState.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExprSeqState.hpp" + +namespace xo { namespace scm { class IPrintable_DExprSeqState; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExprSeqState + **/ + class IPrintable_DExprSeqState { + public: + /** @defgroup scm-printable-dexprseqstate-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexprseqstate-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExprSeqState & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 655ac7e9..3a04f430 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -13,6 +13,7 @@ set(SELF_SRCS DExprSeqState.cpp ISyntaxStateMachine_DExprSeqState.cpp + IPrintable_DExprSeqState.cpp DDefineSsm.cpp ISyntaxStateMachine_DDefineSsm.cpp diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 4afb9608..e994bbf1 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -13,6 +13,21 @@ namespace xo { using xo::reflect::typeseq; namespace scm { + const char * + exprseqtype_descr(exprseqtype x) + { + switch (x) { + case exprseqtype::toplevel_interactive: + return "toplevel-interactive"; + case exprseqtype::toplevel_batch: + return "toplevel-batch"; + case exprseqtype::N: + break; + } + + return "exprseqtype?"; + } + DExprSeqState::DExprSeqState(exprseqtype ty) : seqtype_{ty} {} @@ -153,6 +168,15 @@ namespace xo { sym, this->get_expect_str()); } + + bool + DExprSeqState::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DExprSeqState", + refrtag("seqtype", seqtype_)); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp b/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp new file mode 100644 index 00000000..f751b963 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExprSeqState.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExprSeqState.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExprSeqState.json5] +**/ + +#include "ssm/IPrintable_DExprSeqState.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExprSeqState::pretty(const DExprSeqState & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExprSeqState.cpp */ \ No newline at end of file From 8d7244a2148f9ff3b0d301e3d463c551b1d21dd1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 01:07:21 -0500 Subject: [PATCH 019/258] xo-reader2: + IPrintable+DExpectSymbolSsm --- xo-reader2/CMakeLists.txt | 18 ++++++ .../idl/IPrintable_DExpectSymbolSsm.json5 | 13 ++++ .../include/xo/reader2/DExpectSymbolSsm.hpp | 7 +++ .../ssm/IPrintable_DExpectSymbolSsm.hpp | 62 +++++++++++++++++++ xo-reader2/src/reader2/CMakeLists.txt | 1 + xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 10 +++ .../reader2/IPrintable_DExpectSymbolSsm.cpp | 28 +++++++++ 7 files changed, 139 insertions(+) create mode 100644 xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp create mode 100644 xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 7017425e..85dabbf3 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -32,6 +32,8 @@ xo_add_genfacet( OUTPUT_CPP_DIR src/reader2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-exprseqstate @@ -56,6 +58,8 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-definessm @@ -68,6 +72,8 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-expectsymbolssm @@ -80,6 +86,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectsymbolssm + FACET_PKG xo_printable2 + FACET Printable + REPR ExpectSymbolSsm + INPUT idl/IPrintable_DExpectSymbolSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + # ---------------------------------------------------------------- # shared library diff --git a/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 b/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 new file mode 100644 index 00000000..1d662986 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectSymbolSsm", + using_doxygen: true, + repr: "DExpectSymbolSsm", + doc: [ "implement APrintable for DExpectSymbolSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index dadd1300..2ecc556d 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -8,6 +8,7 @@ #include "ParserStateMachine.hpp" //#include "SyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" +#include #include namespace xo { @@ -21,6 +22,7 @@ namespace xo { class DExpectSymbolSsm { public: using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; public: DExpectSymbolSsm(); @@ -83,7 +85,12 @@ namespace xo { ///@} + /** @defgroup scm-expectsymbol-printable-facet printable facet methods **/ + ///@{ + bool pretty(const ppindentinfo & ppii) const; + + ///@} }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp new file mode 100644 index 00000000..6e63383b --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectSymbolSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectSymbolSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectSymbolSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectSymbolSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectSymbolSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectSymbolSsm + **/ + class IPrintable_DExpectSymbolSsm { + public: + /** @defgroup scm-printable-dexpectsymbolssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectsymbolssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectSymbolSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 3a04f430..0ad81a49 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -20,6 +20,7 @@ set(SELF_SRCS DExpectSymbolSsm.cpp ISyntaxStateMachine_DExpectSymbolSsm.cpp + IPrintable_DExpectSymbolSsm.cpp reader2_register_facets.cpp reader2_register_types.cpp diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 6afe337c..c859528f 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -103,6 +103,16 @@ namespace xo { sym, this->get_expect_str()); } + + bool + DExpectSymbolSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DExpectSymbolSsm" + //refrtag("member", member_) + ); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp new file mode 100644 index 00000000..2cef62a7 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectSymbolSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectSymbolSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectSymbolSsm.json5] +**/ + +#include "ssm/IPrintable_DExpectSymbolSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectSymbolSsm::pretty(const DExpectSymbolSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectSymbolSsm.cpp */ \ No newline at end of file From b920b775d5058eec2aff02050e3a51614bd1a138 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 01:09:56 -0500 Subject: [PATCH 020/258] xo-reader2: register printable facets --- xo-reader2/src/reader2/reader2_register_facets.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 988f41ab..67754bb6 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -6,14 +6,20 @@ #include "reader2_register_facets.hpp" #include +#include + #include + #include +#include #include +#include #include #include namespace xo { + using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::facet::typeseq; @@ -24,8 +30,12 @@ namespace xo { scope log(XO_DEBUG(true)); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); From d39dab185ad3f0588ed5630fd4efd5c25366a385 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 01:19:47 -0500 Subject: [PATCH 021/258] xo-reader2: + IPrintable+DDefineSsm --- xo-reader2/CMakeLists.txt | 12 ++++ xo-reader2/idl/IPrintable_DDefineSsm.json5 | 13 ++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 7 +++ .../xo/reader2/ssm/IPrintable_DDefineSsm.hpp | 62 +++++++++++++++++++ xo-reader2/src/reader2/CMakeLists.txt | 1 + xo-reader2/src/reader2/DDefineSsm.cpp | 8 +++ .../src/reader2/IPrintable_DDefineSsm.cpp | 28 +++++++++ .../src/reader2/reader2_register_facets.cpp | 2 + 8 files changed, 133 insertions(+) create mode 100644 xo-reader2/idl/IPrintable_DDefineSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp create mode 100644 xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 85dabbf3..e2ee946b 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -72,6 +72,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-definessm + FACET_PKG xo_printable2 + FACET Printable + REPR DefineSsm + INPUT idl/IPrintable_DDefineSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + # ---------------------------------------------------------------- # note: manual target; generated code committed to git diff --git a/xo-reader2/idl/IPrintable_DDefineSsm.json5 b/xo-reader2/idl/IPrintable_DDefineSsm.json5 new file mode 100644 index 00000000..e79017f8 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DDefineSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DDefineSsm", + using_doxygen: true, + repr: "DDefineSsm", + doc: [ "implement APrintable for DDefineSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 3bc042c1..b8444cbe 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -73,6 +73,7 @@ namespace xo { public: using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; public: /** @defgroup scm-define-ssm-facet constructors **/ @@ -133,6 +134,12 @@ namespace xo { ParserStateMachine * p_psm); ///@} + /** @defgroup scm-define-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} private: /** identify define-expression state **/ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp new file mode 100644 index 00000000..dd80b443 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DDefineSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDefineSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDefineSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DDefineSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DDefineSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DDefineSsm + **/ + class IPrintable_DDefineSsm { + public: + /** @defgroup scm-printable-ddefinessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-ddefinessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DDefineSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 0ad81a49..6b17e3d3 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -17,6 +17,7 @@ set(SELF_SRCS DDefineSsm.cpp ISyntaxStateMachine_DDefineSsm.cpp + IPrintable_DDefineSsm.cpp DExpectSymbolSsm.cpp ISyntaxStateMachine_DExpectSymbolSsm.cpp diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index eabc1868..3ae20286 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -494,6 +494,14 @@ namespace xo { this->get_expect_str()); } + bool + DDefineSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DDefineSsm", + refrtag("defstate", defstate_)); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp b/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp new file mode 100644 index 00000000..c3aa2edd --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DDefineSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDefineSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDefineSsm.json5] +**/ + +#include "ssm/IPrintable_DDefineSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DDefineSsm::pretty(const DDefineSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DDefineSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 67754bb6..ee838864 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -33,6 +34,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); From ca2be0172adabe36840a161a50b9196cd14fbb39 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 12:40:26 -0500 Subject: [PATCH 022/258] xo-reader2: + pretty-printing for ParserResult + use in utest --- xo-facet/include/xo/facet/FacetRegistry.hpp | 4 +- .../include/xo/indentlog/print/ppconfig.hpp | 15 +++++ xo-object2/include/xo/object2/DString.hpp | 9 +++ .../include/xo/reader2/ParserResult.hpp | 50 ++++++++++++++ xo-reader2/src/reader2/ParserResult.cpp | 66 +++++++++++++++++++ xo-reader2/utest/SchematikaParser.test.cpp | 6 +- 6 files changed, 147 insertions(+), 3 deletions(-) diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index 2a3aa48c..aa481a0c 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -115,7 +115,7 @@ namespace xo { * obj foo * = ...; // Foo instance with variant impl * obj bar - * = FacetRegistry::variant(foo); + * = FacetRegistry::instance().variant(foo); * * // exception thrown if bar has null data * @@ -140,7 +140,7 @@ namespace xo { * obj foo * = ...; // Foo instance with variant impl * obj bar - * = FacetRegistry::try_variant(foo); + * = FacetRegistry::instance().try_variant(foo); * if (bar) { * // success * } else { diff --git a/xo-indentlog/include/xo/indentlog/print/ppconfig.hpp b/xo-indentlog/include/xo/indentlog/print/ppconfig.hpp index 67d1831a..10c89639 100644 --- a/xo-indentlog/include/xo/indentlog/print/ppconfig.hpp +++ b/xo-indentlog/include/xo/indentlog/print/ppconfig.hpp @@ -16,6 +16,21 @@ namespace xo { * Need one read-only instance of this to invoke pretty printer **/ struct ppconfig { + /** @defgroup ppconfig-ctors ppconfig constructors **/ + ///@{ + + /** config to use pretty printer in degenerate form: + * In this form right margin is absurdly far away, + * so should not be forced to use multiple lines. + * + * Note this won't prevent a printer from returning -1 + **/ + static inline ppconfig ugly() { + return ppconfig { .right_margin_ = 99999999, .indent_width_ = 0, .assert_indent_threshold = 10 }; + } + + ///@} + /** @defgroup ppconfig-instance-vars ppconfig instance variables **/ ///@{ diff --git a/xo-object2/include/xo/object2/DString.hpp b/xo-object2/include/xo/object2/DString.hpp index f35fe44f..eea8ea5c 100644 --- a/xo-object2/include/xo/object2/DString.hpp +++ b/xo-object2/include/xo/object2/DString.hpp @@ -279,6 +279,15 @@ namespace xo { ///@} }; + inline std::ostream & operator<<(std::ostream & os, const DString * x) { + if (x) { + os << std::string_view(*x); + } else { + os << "nullptr"; + } + return os; + } + inline bool operator==(const DString & lhs, const DString & rhs) { return DString::compare(lhs, rhs) == 0; } diff --git a/xo-reader2/include/xo/reader2/ParserResult.hpp b/xo-reader2/include/xo/reader2/ParserResult.hpp index 39f9c2d1..45064d32 100644 --- a/xo-reader2/include/xo/reader2/ParserResult.hpp +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -7,6 +7,7 @@ #include #include +#include #include namespace xo { @@ -21,7 +22,18 @@ namespace xo { N }; + /** @return string representation for enum @p x **/ + const char * parser_result_type_descr(parser_result_type x); + + inline std::ostream & operator<<(std::ostream & os, parser_result_type x) { + os << parser_result_type_descr(x); + return os; + } + class ParserResult { + public: + using ppindentinfo = xo::print::ppindentinfo; + public: ParserResult() = default; ParserResult(parser_result_type type, @@ -44,15 +56,53 @@ namespace xo { bool is_expression() const { return result_type_ == parser_result_type::expression; } bool is_error() const { return result_type_ == parser_result_type::error; } + /** ordinary not-pretty printer **/ + void print(std::ostream & os) const; + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + private: + /** none|expression|error_description + * + * @text + * result_type | error_src_function | error_description + * -------------+--------------------+------------------- + * none | nullptr | empty + * expression | nullptr | empty + * error | non-null | non-empty + * @endtext + **/ parser_result_type result_type_ = parser_result_type::none; + /** non-null iff @ref result_type_ is expression **/ obj result_expr_; + /** non-null iff @ref result_type_ is error. + * In which case gives parsing function detecting this error + **/ std::string_view error_src_fn_; + /** non-null iff @ref result_type_ is error + * Human-targeted error description. + **/ const DString * error_description_ = nullptr; }; + inline std::ostream & operator<<(std::ostream & os, const ParserResult & x) { + x.print(os); + return os; + } } /*namespace scm*/ + + namespace print { + /** pretty printer in relies on this specialization + * to handle ParserResult instances + **/ + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::ParserResult & x) { + return x.pretty(ppii); + } + }; + } } /*namespace xo*/ /* end ParserResult.hpp */ diff --git a/xo-reader2/src/reader2/ParserResult.cpp b/xo-reader2/src/reader2/ParserResult.cpp index 28553228..312538b1 100644 --- a/xo-reader2/src/reader2/ParserResult.cpp +++ b/xo-reader2/src/reader2/ParserResult.cpp @@ -4,9 +4,28 @@ **/ #include "ParserResult.hpp" +#include +#include namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + namespace scm { + + const char * + parser_result_type_descr(parser_result_type x) + { + switch (x) { + case parser_result_type::none: return "none"; + case parser_result_type::expression: return "expression"; + case parser_result_type::error: return "error"; + case parser_result_type::N: break; + } + + return "parser_result_type?"; + } + ParserResult::ParserResult(parser_result_type type, obj expr, std::string_view error_src_fn, @@ -26,6 +45,53 @@ namespace xo { ssm_name, errmsg); } + + void + ParserResult::print(std::ostream & os) const + { + os << ""; + } + + bool + ParserResult::pretty(const ppindentinfo & ppii) const + { + switch (result_type_) { + case parser_result_type::none: + return ppii.pps()->pretty_struct + (ppii, + "ParserResult", + refrtag("type", result_type_)); + case parser_result_type::expression: + { + auto expr = FacetRegistry::instance().variant(result_expr_); + + return ppii.pps()->pretty_struct + (ppii, + "ParserResult", + refrtag("type", result_type_), + refrtag("expr", expr)); + } + break; + case parser_result_type::error: + return ppii.pps()->pretty_struct + (ppii, + "ParserResult", + refrtag("type", result_type_), + refrtag("src_fn", error_src_fn_), + refrtag("error", error_description_)); + case parser_result_type::N: + assert(false); + break; + } + + return false; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 259336cf..e2a9023e 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -71,6 +71,9 @@ namespace xo { TEST_CASE("SchematikaParser-batch-def", "[reader2][SchematikaParser]") { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + ArenaConfig config; config.name_ = "test-arena"; config.size_ = 16 * 1024; @@ -96,11 +99,12 @@ namespace xo { REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(result.is_incomplete()); + + log && log(xtag("result", result)); } // define-expressions not properly implemented - //REQUIRE(result.error_description()); } From 480294ae0584b14b76f2fe401f5665d44af8e359 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 15:06:58 -0500 Subject: [PATCH 023/258] xo-reader2 xo-expression2: pprint for DDefineExpr + DVariable --- xo-expression2/CMakeLists.txt | 28 +++++++++ .../idl/IPrintable_DDefineExpr.json5 | 13 ++++ xo-expression2/idl/IPrintable_DVariable.json5 | 13 ++++ .../include/xo/expression2/DDefineExpr.hpp | 8 +++ .../include/xo/expression2/DVariable.hpp | 10 ++- .../detail/IExpression_DVariable.hpp | 4 +- .../detail/IPrintable_DDefineExpr.hpp | 62 +++++++++++++++++++ .../detail/IPrintable_DVariable.hpp | 62 +++++++++++++++++++ xo-expression2/src/expression2/CMakeLists.txt | 4 ++ .../src/expression2/DDefineExpr.cpp | 29 +++++++++ xo-expression2/src/expression2/DVariable.cpp | 13 ++++ .../expression2/IPrintable_DDefineExpr.cpp | 28 +++++++++ .../src/expression2/IPrintable_DVariable.cpp | 28 +++++++++ .../expression2_register_facets.cpp | 12 ++++ xo-reader2/include/xo/reader2/ParserStack.hpp | 32 ++++++++++ .../include/xo/reader2/ParserStateMachine.hpp | 3 +- .../include/xo/reader2/SchematikaParser.hpp | 28 ++++++++- xo-reader2/src/reader2/DDefineSsm.cpp | 9 ++- xo-reader2/src/reader2/ParserStack.cpp | 46 ++++++++++++++ xo-reader2/src/reader2/SchematikaParser.cpp | 22 +++++++ xo-reader2/utest/SchematikaParser.test.cpp | 9 +++ 21 files changed, 455 insertions(+), 8 deletions(-) create mode 100644 xo-expression2/idl/IPrintable_DDefineExpr.json5 create mode 100644 xo-expression2/idl/IPrintable_DVariable.json5 create mode 100644 xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp create mode 100644 xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp create mode 100644 xo-expression2/src/expression2/IPrintable_DVariable.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 678e5eca..3de04758 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -56,6 +56,8 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-expression-variable @@ -68,6 +70,20 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-variable + FACET_PKG xo_printable2 + FACET Printable + REPR Variable + INPUT idl/IPrintable_DVariable.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-expression-defineexpr @@ -80,6 +96,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-defineexpr + FACET_PKG xo_printable2 + FACET Printable + REPR DefineExpr + INPUT idl/IPrintable_DDefineExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + # ---------------------------------------------------------------- # note: manual target; generated code committed to git diff --git a/xo-expression2/idl/IPrintable_DDefineExpr.json5 b/xo-expression2/idl/IPrintable_DDefineExpr.json5 new file mode 100644 index 00000000..351f8caf --- /dev/null +++ b/xo-expression2/idl/IPrintable_DDefineExpr.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DDefineExpr", + using_doxygen: true, + repr: "DDefineExpr", + doc: [ "implement APrintable for DDefineExpr" ], +} diff --git a/xo-expression2/idl/IPrintable_DVariable.json5 b/xo-expression2/idl/IPrintable_DVariable.json5 new file mode 100644 index 00000000..52c301b2 --- /dev/null +++ b/xo-expression2/idl/IPrintable_DVariable.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVariable", + using_doxygen: true, + repr: "DVariable", + doc: [ "implement APrintable for DVariable" ], +} diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp index 618e4161..59826aa2 100644 --- a/xo-expression2/include/xo/expression2/DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -8,6 +8,7 @@ #include "Expression.hpp" #include "DVariable.hpp" #include +#include namespace xo { namespace scm { @@ -21,6 +22,7 @@ namespace xo { **/ class DDefineExpr { public: + using ppindentinfo = xo::print::ppindentinfo; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; @@ -62,6 +64,12 @@ namespace xo { void assign_valuetype(TypeDescr td) noexcept; ///@} + /** @defgroup scm-defineexpr-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} private: /** @defgrouop scm-defineexpr-instance-vars **/ diff --git a/xo-expression2/include/xo/expression2/DVariable.hpp b/xo-expression2/include/xo/expression2/DVariable.hpp index 2208852e..ae362bf1 100644 --- a/xo-expression2/include/xo/expression2/DVariable.hpp +++ b/xo-expression2/include/xo/expression2/DVariable.hpp @@ -10,6 +10,7 @@ #include "TypeRef.hpp" #include "exprtype.hpp" #include +#include namespace xo { namespace scm { @@ -19,6 +20,7 @@ namespace xo { **/ class DVariable { public: + using ppindentinfo = xo::print::ppindentinfo; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; @@ -46,7 +48,7 @@ namespace xo { void assign_name(const DUniqueString * name) { this->name_ = name; } - /** @defgroup scm-variable-expression-facet**/ + /** @defgroup scm-variable-expression-facet **/ ///@{ exprtype extype() const noexcept { return exprtype::variable; } @@ -55,6 +57,12 @@ namespace xo { void assign_valuetype(TypeDescr td) noexcept; ///@} + /** @defgroup scm-variable-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} private: /** symbol name **/ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp index 95b1becb..b4186f55 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp @@ -55,7 +55,7 @@ namespace xo { static TypeDescr valuetype(const DVariable & self) noexcept; // non-const methods - /** assing to valuetype member. Useful when scaffolding expressions **/ + /** assign to valuetype member. Useful when scaffolding expressions **/ static void assign_valuetype(DVariable & self, TypeDescr td) noexcept; ///@} }; @@ -63,4 +63,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end */ \ No newline at end of file +/* end */ diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp new file mode 100644 index 00000000..6d727d86 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DDefineExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDefineExpr.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DDefineExpr.hpp" + +namespace xo { namespace scm { class IPrintable_DDefineExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DDefineExpr + **/ + class IPrintable_DDefineExpr { + public: + /** @defgroup scm-printable-ddefineexpr-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-ddefineexpr-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DDefineExpr & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp new file mode 100644 index 00000000..6e97451b --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVariable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVariable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVariable.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVariable.hpp" + +namespace xo { namespace scm { class IPrintable_DVariable; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVariable + **/ + class IPrintable_DVariable { + public: + /** @defgroup scm-printable-dvariable-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvariable-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVariable & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 0fcd6541..f2dfe7e7 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -12,8 +12,12 @@ set(SELF_SRCS IExpression_Any.cpp IExpression_DConstant.cpp + IExpression_DVariable.cpp + IPrintable_DVariable.cpp + IExpression_DDefineExpr.cpp + IPrintable_DDefineExpr.cpp DLocalSymtab.cpp DGlobalSymtab.cpp diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index a5609246..8afb90fe 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -4,9 +4,14 @@ **/ #include "DDefineExpr.hpp" +#include "detail/IPrintable_DVariable.hpp" +#include +#include #include namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; using xo::facet::typeseq; namespace scm { @@ -60,6 +65,30 @@ namespace xo { { lhs_var_->assign_valuetype(td); } + + bool + DDefineExpr::pretty(const ppindentinfo & ppii) const + { + auto lhs = obj(lhs_var_); + auto rhs = FacetRegistry::instance().try_variant(rhs_); + + if (rhs_) { + assert(rhs); + + return ppii.pps()->pretty_struct + (ppii, + "DDefineExpr", + refrtag("lhs", lhs), + refrtag("rhs", rhs)); + } else { + return ppii.pps()->pretty_struct + (ppii, + "DDefineExpr", + refrtag("lhs", lhs)); + } + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/DVariable.cpp b/xo-expression2/src/expression2/DVariable.cpp index d27c71ef..4adbe841 100644 --- a/xo-expression2/src/expression2/DVariable.cpp +++ b/xo-expression2/src/expression2/DVariable.cpp @@ -35,6 +35,19 @@ namespace xo { typeref_.resolve(td); } + bool + DVariable::pretty(const ppindentinfo & ppii) const + { + auto name = (name_ + ? std::string_view(*name_) + : std::string_view("")); + + return ppii.pps()->pretty_struct + (ppii, + "DVariable", + refrtag("name", name)); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp b/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp new file mode 100644 index 00000000..e8c6a799 --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DDefineExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDefineExpr.json5] +**/ + +#include "detail/IPrintable_DDefineExpr.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DDefineExpr::pretty(const DDefineExpr & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DDefineExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/IPrintable_DVariable.cpp b/xo-expression2/src/expression2/IPrintable_DVariable.cpp new file mode 100644 index 00000000..75e673ae --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DVariable.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVariable.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVariable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVariable.json5] +**/ + +#include "detail/IPrintable_DVariable.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVariable::pretty(const DVariable & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVariable.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 2d728bd3..e6715769 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -8,6 +8,10 @@ #include #include +#include + +#include + #include #include #include @@ -28,7 +32,15 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + FacetRegistry::register_impl(); + log && log(xtag("DUniqueString.tseq", typeseq::id())); + log && log(xtag("DDefineExpr.tseq", typeseq::id())); + log && log(xtag("DVariable.tseq", typeseq::id())); + + log && log(xtag("AExpression.tqseq", typeseq::id())); return true; } diff --git a/xo-reader2/include/xo/reader2/ParserStack.hpp b/xo-reader2/include/xo/reader2/ParserStack.hpp index b63be044..936c57e5 100644 --- a/xo-reader2/include/xo/reader2/ParserStack.hpp +++ b/xo-reader2/include/xo/reader2/ParserStack.hpp @@ -8,6 +8,7 @@ #include "SyntaxStateMachine.hpp" #include #include +#include namespace xo { namespace scm { @@ -21,6 +22,7 @@ namespace xo { class ParserStack { public: using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; public: ParserStack(DArena::Checkpoint ckp, @@ -42,6 +44,11 @@ namespace xo { obj top() const noexcept { return ssm_; } ParserStack * parent() const noexcept { return parent_; } + /** regular printing **/ + void print(std::ostream & os) const; + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; + private: /** stack pointer: top of stack just before this instance created **/ DArena::Checkpoint ckp_; @@ -51,7 +58,32 @@ namespace xo { ParserStack * parent_ = nullptr; }; + inline std::ostream & operator<< (std::ostream & os, const ParserStack * x) { + if (x) { + x->print(os); + } else { + os << "nullptr"; + } + return os; + } + } /*namespace scm*/ + + namespace print { + /** pretty printer in relies on this specialization + * to handle ParserResult instances + **/ + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::ParserStack * p) { + if (p) + return p->pretty(ppii); + else + return ppii.pps()->print_upto("nullptr"); + } + }; + } + } /*namespace xo*/ /* end ParserStack.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index b333dd51..fbef2393 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -19,7 +19,8 @@ namespace xo { // class ASyntaxStateMachine; - // note: load-bearing to forward-declare ParserStack, + // note: it's load-bearing here to forward-declare ParserStack, + // see ParserStack.hpp for impl // because ASyntaxStateMachine.hpp includes ParserStateMachine.hpp; // before obj is defined. class ParserStack; diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 81115239..300980fb 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -153,9 +153,10 @@ namespace xo { **/ class SchematikaParser { public: + using token_type = Token; using ArenaConfig = xo::mm::ArenaConfig; using AAllocator = xo::mm::AAllocator; - using token_type = Token; + using ppindentinfo = xo::print::ppindentinfo; public: /** create parser in initial state; @@ -216,6 +217,8 @@ namespace xo { /** print human-readable representation on stream @p os **/ void print(std::ostream & os) const; + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; private: /** state machine **/ @@ -227,12 +230,31 @@ namespace xo { inline std::ostream & operator<< (std::ostream & os, - const SchematikaParser & x) { - x.print(os); + const SchematikaParser * x) { + if (x) { + x->print(os); + } else { + os << "nullptr"; + } return os; } } /*namespace scm*/ + + namespace print { + /** pretty printer in relies on this specialization + * to handle ParserResult instances + **/ + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::SchematikaParser* p) { + if (p) + return p->pretty(ppii); + else + return ppii.pps()->print_upto("nullptr"); + } + }; + } } /*namespace xo*/ /* end SchematikaParser.hpp */ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 3ae20286..c1e3f6a9 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -6,6 +6,9 @@ #include "DDefineSsm.hpp" #include "DExpectSymbolSsm.hpp" #include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" +#include "ssm/IPrintable_DDefineSsm.hpp" +#include +#include #ifdef NOT_YET #include "parserstatemachine.hpp" @@ -16,6 +19,7 @@ #endif namespace xo { + using xo::print::APrintable; using xo::facet::with_facet; using xo::facet::typeseq; @@ -497,10 +501,13 @@ namespace xo { bool DDefineSsm::pretty(const ppindentinfo & ppii) const { + auto expr = with_facet::mkobj(def_expr_.data()); + return ppii.pps()->pretty_struct (ppii, "DDefineSsm", - refrtag("defstate", defstate_)); + refrtag("defstate", defstate_), + refrtag("def_expr", expr)); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ParserStack.cpp b/xo-reader2/src/reader2/ParserStack.cpp index ba39517d..91d8bca9 100644 --- a/xo-reader2/src/reader2/ParserStack.cpp +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -5,8 +5,12 @@ #include "ParserStack.hpp" #include "SyntaxStateMachine.hpp" +#include +#include namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; using xo::facet::typeseq; namespace scm { @@ -41,6 +45,48 @@ namespace xo { 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()); + + pps->newline_pretty_tag(ppii.ci1(), buf, ssm); + + ++i_frame; + frame = frame->parent_; + } + + pps->write(">"); + + return false; + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index ac2d4520..d243de51 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -86,6 +86,28 @@ namespace xo { << xtag("has_stack", (psm_.stack() != nullptr)) << ">" << std::endl; } + + bool + SchematikaParser::pretty(const ppindentinfo & ppii) const { + auto * pps = ppii.pps(); + + if (ppii.upto()) + return false; + + // TODO: consider printing: + // psm.stringtable_ + // psm.parser_alloc_ + // psm.parser_alloc_ckp_ + // psm.expr_alloc_ + // psm.result_ + // psm.debug_flag_ + // + + return pps->pretty_struct + (ppii, + "SchematikaParser", + refrtag("stack", psm_.stack())); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index e2a9023e..8cccfd7b 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -4,6 +4,7 @@ **/ #include +#include #include #include @@ -17,6 +18,8 @@ namespace xo { using xo::mm::DArena; using xo::facet::with_facet; + static InitEvidence s_init = (InitSubsys::require()); + namespace ut { TEST_CASE("SchematikaParser-ctor", "[reader2][SchematikaParser]") { @@ -92,6 +95,10 @@ namespace xo { // but is still "at toplevel" in the sense of ready for input REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(result.is_incomplete()); + + log && log("after def token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); } { @@ -100,6 +107,8 @@ namespace xo { REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(result.is_incomplete()); + log && log("after lhs symbol token:"); + log && log(xtag("parser", &parser)); log && log(xtag("result", result)); } From 67beec4ee460f806acfe0097f509f6536885b31f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 16:40:23 -0500 Subject: [PATCH 024/258] xo-indentlog: fix log_streambuf unit test + string_view operator --- .../include/xo/indentlog/log_streambuf.hpp | 3 +++ xo-indentlog/utest/log_streambuf.test.cpp | 20 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/xo-indentlog/include/xo/indentlog/log_streambuf.hpp b/xo-indentlog/include/xo/indentlog/log_streambuf.hpp index 36166fce..e9672f47 100644 --- a/xo-indentlog/include/xo/indentlog/log_streambuf.hpp +++ b/xo-indentlog/include/xo/indentlog/log_streambuf.hpp @@ -4,6 +4,7 @@ #include "print/quoted_char.hpp" #include +#include #include #include // e.g. for std::memcpy() #include @@ -71,6 +72,8 @@ namespace xo { bool debug_flag() const { return debug_flag_; } + operator std::basic_string_view () const { return std::basic_string_view(this->pbase(), this->pptr()); } + void reset_stream() { char * p_lo = &(this->buf_v_[0]); char * p_hi = p_lo + this->capacity(); diff --git a/xo-indentlog/utest/log_streambuf.test.cpp b/xo-indentlog/utest/log_streambuf.test.cpp index 656d8b97..fc3968be 100644 --- a/xo-indentlog/utest/log_streambuf.test.cpp +++ b/xo-indentlog/utest/log_streambuf.test.cpp @@ -5,12 +5,14 @@ #include "print/tag.hpp" #include "print/quoted.hpp" #include +#include //#include namespace ut { using xo::xtag; using xo::scope; using xo::log_streambuf; + using std::string_view; using std::cerr; using std::endl; @@ -68,28 +70,32 @@ namespace ut { log_streambuf> sbuf(z, false); std::ostream ss(&sbuf); - ss <<"empty log_streambuf"; - ss << xtag("sbuf.lo", (void*)sbuf.lo()); - ss << xtag("sbuf.hi", (void*)sbuf.hi()); + ss << "empty log_streambuf"; + ss << xtag("sbuf.lo", (void*)nullptr); + ss << xtag("sbuf.hi", (void*)nullptr); ss << xtag("sbuf.color_escape_chars", sbuf._color_escape_chars()); //REQUIRE(sbuf.lo() == sbuf.pbase()); + auto expected = string_view("empty log_streambuf :sbuf.lo 0 :sbuf.hi 0 :sbuf.color_escape_chars 0"); + + REQUIRE(string_view(sbuf) == expected); + /* sbuf size will have been expanded */ REQUIRE(sbuf.capacity() == 128); - REQUIRE(sbuf.pos() == 82); + REQUIRE(sbuf.pos() == expected.size()); REQUIRE(sbuf._solpos() == 0); - REQUIRE(sbuf.lpos() == 82); + REQUIRE(sbuf.lpos() == expected.size()); // note: log_streambuf doesn't get control on every character ss << '\n'; REQUIRE(sbuf.capacity() == 128); - REQUIRE(sbuf.pos() == 83); + REQUIRE(sbuf.pos() == expected.size() + 1); REQUIRE(sbuf.lpos() == 0); // note: solpos: updated b/c of call to lazy sbuf.lpos() - REQUIRE(sbuf._solpos() == 83); + REQUIRE(sbuf._solpos() == expected.size() + 1); } // write test cases with some random strings. From 39a938cc20d267f6623901d2d559ec881e654d55 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 16:40:43 -0500 Subject: [PATCH 025/258] xo-indentlog: + cond feature --- .../include/xo/indentlog/print/cond.hpp | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 xo-indentlog/include/xo/indentlog/print/cond.hpp diff --git a/xo-indentlog/include/xo/indentlog/print/cond.hpp b/xo-indentlog/include/xo/indentlog/print/cond.hpp new file mode 100644 index 00000000..de3a13e7 --- /dev/null +++ b/xo-indentlog/include/xo/indentlog/print/cond.hpp @@ -0,0 +1,92 @@ +/** @file cond.hpp + * + * author: Roland Conybeare + **/ + +#pragma once + +#include "ppdetail_atomic.hpp" +#include +#include + +namespace xo { + + /** @class cond_impl + * @brief conditional stream inserter implementation + * + * @tparam T type printed when condition is true + * @tparam U type printed when condition is false + **/ + template + struct cond_impl { + public: + cond_impl(bool condition, T const & then_value, U const & else_value) + : condition_{condition}, + then_value_{then_value}, + else_value_{else_value} {} + + bool condition() const { return condition_; } + T const & then_value() const { return then_value_; } + U const & else_value() const { return else_value_; } + + private: + bool condition_; + T then_value_; + U else_value_; + }; + + /** Create conditional stream inserter. + * + * @param condition when true, print @p then_value; otherwise print @p else_value + * @param then_value value to print when condition is true + * @param else_value value to print when condition is false + * + * Example: + * @code + * std::cout << cond(ptr != nullptr, xtag("ptr", *ptr), "nullptr"); + * @endcode + **/ + template + auto + cond(bool condition, T && then_value, U && else_value) + { + return cond_impl, std::decay_t> + (condition, + std::forward(then_value), + std::forward(else_value)); + } + + /** Stream insertion operator for cond_impl **/ + template + inline std::ostream & + operator<<(std::ostream & os, cond_impl const & c) + { + if (c.condition()) + os << c.then_value(); + else + os << c.else_value(); + return os; + } + +#ifndef ppdetail_atomic + namespace print { + /** Pretty-printing support for cond_impl **/ + template + struct ppdetail> { + using target_type = cond_impl; + + static bool print_pretty(const ppindentinfo & ppii, + const target_type & c) + { + if (c.condition()) + return ppdetail::print_pretty(ppii, c.then_value()); + else + return ppdetail::print_pretty(ppii, c.else_value()); + } + }; + } +#endif + +} + +/* end cond.hpp */ From 1c2073128d18d770bcc2d7046c6f2503d8c13c57 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 16:44:28 -0500 Subject: [PATCH 026/258] xo-indentlog: tidy: cosmetic adj in cond.hpp --- xo-expression2/src/expression2/DDefineExpr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index 8afb90fe..83ee9188 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -85,7 +85,8 @@ namespace xo { return ppii.pps()->pretty_struct (ppii, "DDefineExpr", - refrtag("lhs", lhs)); + refrtag("lhs", lhs), + refrtag("rhs", "nullptr")); } } From 048a190f513e510f63f7eeadbb805c8b5ef170d4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 16:45:40 -0500 Subject: [PATCH 027/258] xo-indentlog: cosmetic adj in cond.hpp --- .../include/xo/indentlog/print/cond.hpp | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/xo-indentlog/include/xo/indentlog/print/cond.hpp b/xo-indentlog/include/xo/indentlog/print/cond.hpp index de3a13e7..47883bfa 100644 --- a/xo-indentlog/include/xo/indentlog/print/cond.hpp +++ b/xo-indentlog/include/xo/indentlog/print/cond.hpp @@ -20,51 +20,51 @@ namespace xo { template struct cond_impl { public: - cond_impl(bool condition, T const & then_value, U const & else_value) + cond_impl(bool condition, const T & if_true, const U & if_false) : condition_{condition}, - then_value_{then_value}, - else_value_{else_value} {} + if_true_{if_true}, + if_false_{if_false} {} bool condition() const { return condition_; } - T const & then_value() const { return then_value_; } - U const & else_value() const { return else_value_; } + const T & if_true() const { return if_true_; } + const U & if_false() const { return if_false_; } private: bool condition_; - T then_value_; - U else_value_; + T if_true_; + U if_false_; }; /** Create conditional stream inserter. * - * @param condition when true, print @p then_value; otherwise print @p else_value - * @param then_value value to print when condition is true - * @param else_value value to print when condition is false + * @param condition when true, print @p if_true; otherwise print @p if_false + * @param if_true value to print when condition is true + * @param if_false value to print when condition is false * * Example: * @code - * std::cout << cond(ptr != nullptr, xtag("ptr", *ptr), "nullptr"); + * std::cout << cond(ptr, xtag("ptr", *ptr), "nullptr"); * @endcode **/ template auto - cond(bool condition, T && then_value, U && else_value) + cond(bool condition, T && if_true, U && if_false) { return cond_impl, std::decay_t> (condition, - std::forward(then_value), - std::forward(else_value)); + std::forward(if_true), + std::forward(if_false)); } /** Stream insertion operator for cond_impl **/ template inline std::ostream & - operator<<(std::ostream & os, cond_impl const & c) + operator<<(std::ostream & os, const cond_impl & c) { if (c.condition()) - os << c.then_value(); + os << c.if_true(); else - os << c.else_value(); + os << c.if_false(); return os; } @@ -79,9 +79,9 @@ namespace xo { const target_type & c) { if (c.condition()) - return ppdetail::print_pretty(ppii, c.then_value()); + return ppdetail::print_pretty(ppii, c.if_true()); else - return ppdetail::print_pretty(ppii, c.else_value()); + return ppdetail::print_pretty(ppii, c.if_false()); } }; } From 487f7b8195cb9132cba0ae0f992ee60238528038 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 16:49:52 -0500 Subject: [PATCH 028/258] xo-indentlog: + cond utest --- xo-indentlog/utest/CMakeLists.txt | 2 +- xo-indentlog/utest/cond.test.cpp | 47 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 xo-indentlog/utest/cond.test.cpp diff --git a/xo-indentlog/utest/CMakeLists.txt b/xo-indentlog/utest/CMakeLists.txt index c8ea729c..5fa2bf1b 100644 --- a/xo-indentlog/utest/CMakeLists.txt +++ b/xo-indentlog/utest/CMakeLists.txt @@ -4,7 +4,7 @@ set(SELF_EXECUTABLE_NAME utest.indentlog) set(SELF_SOURCE_FILES fixed.test.cpp quoted.test.cpp vector.test.cpp array.test.cpp timeutil.test.cpp tag.test.cpp filename.test.cpp code_location.test.cpp function.test.cpp pretty_vector.test.cpp - indentlog_utest_main.cpp log_streambuf.test.cpp toppstr.test.cpp) + indentlog_utest_main.cpp log_streambuf.test.cpp toppstr.test.cpp cond.test.cpp) xo_add_utest_executable(${SELF_EXECUTABLE_NAME} ${SELF_SOURCE_FILES}) diff --git a/xo-indentlog/utest/cond.test.cpp b/xo-indentlog/utest/cond.test.cpp new file mode 100644 index 00000000..e421c642 --- /dev/null +++ b/xo-indentlog/utest/cond.test.cpp @@ -0,0 +1,47 @@ +/* @file cond.test.cpp */ + +#include "xo/indentlog/print/cond.hpp" +#include "xo/indentlog/print/tag.hpp" +#include +#include + +using namespace xo; + +namespace ut { + TEST_CASE("cond", "[cond]") { + tag_config::tag_color = color_spec_type::none(); + + { + std::stringstream ss; + ss << cond(true, "yes", "no"); + REQUIRE(ss.str() == "yes"); + } + + { + std::stringstream ss; + ss << cond(false, "yes", "no"); + REQUIRE(ss.str() == "no"); + } + + { + std::stringstream ss; + ss << cond(true, 42, "none"); + REQUIRE(ss.str() == "42"); + } + + { + std::stringstream ss; + ss << cond(false, 42, "none"); + REQUIRE(ss.str() == "none"); + } + + { + std::stringstream ss; + int * ptr = nullptr; + ss << cond(ptr != nullptr, xtag("ptr", 123), xtag("ptr", "null")); + REQUIRE(ss.str() == " :ptr null"); + } + } +} + +/* end cond.test.cpp */ From 1b6775d0329a0edbb8886b9d3038851290322c2e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 16:51:25 -0500 Subject: [PATCH 029/258] xo-indentlog: +1 more cond utest --- xo-indentlog/utest/cond.test.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/xo-indentlog/utest/cond.test.cpp b/xo-indentlog/utest/cond.test.cpp index e421c642..d360a449 100644 --- a/xo-indentlog/utest/cond.test.cpp +++ b/xo-indentlog/utest/cond.test.cpp @@ -37,8 +37,21 @@ namespace ut { { std::stringstream ss; + int * ptr = nullptr; - ss << cond(ptr != nullptr, xtag("ptr", 123), xtag("ptr", "null")); + + ss << cond(ptr, xtag("ptr", 123), xtag("ptr", "null")); + + REQUIRE(ss.str() == " :ptr null"); + } + + { + std::stringstream ss; + + int * ptr = nullptr; + + ss << xtag("ptr", cond(ptr, 123, "null")); + REQUIRE(ss.str() == " :ptr null"); } } From e69db9eb8d1dcdfcf2d69934b0c4e2edcc91ef79 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 16:54:27 -0500 Subject: [PATCH 030/258] xo-reader2: streamline DDefineExpr printing using xo::print::cond --- .../src/expression2/DDefineExpr.cpp | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index 83ee9188..c8785415 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace xo { using xo::print::APrintable; @@ -73,21 +74,11 @@ namespace xo { auto rhs = FacetRegistry::instance().try_variant(rhs_); - if (rhs_) { - assert(rhs); - - return ppii.pps()->pretty_struct - (ppii, - "DDefineExpr", - refrtag("lhs", lhs), - refrtag("rhs", rhs)); - } else { - return ppii.pps()->pretty_struct - (ppii, - "DDefineExpr", - refrtag("lhs", lhs), - refrtag("rhs", "nullptr")); - } + return ppii.pps()->pretty_struct + (ppii, + "DDefineExpr", + refrtag("lhs", lhs), + refrtag("rhs", cond(rhs_, rhs, "nullptr"))); } } /*namespace scm*/ From f804d4f1e949124064db2496751d5730a1af14c9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 22:10:59 -0500 Subject: [PATCH 031/258] xo-cmake: + xo_add_genfacet_all() cmake function --- xo-cmake/cmake/xo_macros/xo_cxx.cmake | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xo-cmake/cmake/xo_macros/xo_cxx.cmake b/xo-cmake/cmake/xo_macros/xo_cxx.cmake index c071f061..dde3c081 100644 --- a/xo-cmake/cmake/xo_macros/xo_cxx.cmake +++ b/xo-cmake/cmake/xo_macros/xo_cxx.cmake @@ -1735,6 +1735,8 @@ function(xo_add_genfacet) # Create a target for this generation add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles}) + + set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET}) endfunction() function(xo_add_genfacetimpl) @@ -1815,4 +1817,16 @@ function(xo_add_genfacetimpl) # Create a target for this generation add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles}) + + set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET}) +endfunction() + +# create umbrella target for all genfacet targets in current directory +function(xo_add_genfacet_all target_name) + get_property(genfacet_targets DIRECTORY PROPERTY XO_GENFACET_TARGETS) + if(genfacet_targets) + add_custom_target(${target_name} DEPENDS ${genfacet_targets}) + else() + message(WARNING "xo_add_genfacet_all: no genfacet targets found") + endif() endfunction() From 10d3a49a527c70ffa23d6e0e2ad58a0b70a02cda Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 22:11:19 -0500 Subject: [PATCH 032/258] xo-object2: bugfix: subdir structure in CMakeLists.txt genfacet --- xo-object2/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index c7962ed7..9c2671e0 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -119,8 +119,8 @@ xo_add_genfacetimpl( FACET Printable REPR String INPUT idl/IPrintable_DString.json5 - OUTPUT_HPP_DIR include/xo/object2/string - OUTPUT_IMPL_SUBDIR . + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR string OUTPUT_CPP_DIR src/object2 ) @@ -131,8 +131,8 @@ xo_add_genfacetimpl( FACET GCObject REPR String INPUT idl/IGCObject_DString.json5 - OUTPUT_HPP_DIR include/xo/object2/string - OUTPUT_IMPL_SUBDIR . + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR string OUTPUT_CPP_DIR src/object2 ) From e24a6bbdfda687031c0db629184853cd86d13e57 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 22:12:17 -0500 Subject: [PATCH 033/258] xo-reader2: print TypeRef belonging to DVariabe --- .../include/xo/expression2/TypeRef.hpp | 17 +++++++++++++++++ xo-expression2/src/expression2/DVariable.cpp | 6 +++++- xo-expression2/src/expression2/TypeRef.cpp | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/xo-expression2/include/xo/expression2/TypeRef.hpp b/xo-expression2/include/xo/expression2/TypeRef.hpp index 01401d28..7ec6e388 100644 --- a/xo-expression2/include/xo/expression2/TypeRef.hpp +++ b/xo-expression2/include/xo/expression2/TypeRef.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace xo { namespace scm { @@ -22,6 +23,7 @@ namespace xo { using TypeDescr = xo::reflect::TypeDescr; using type_var = flatstring<20>; using prefix_type = flatstring<8>; + using ppindentinfo = xo::print::ppindentinfo; public: TypeRef() = default; @@ -54,6 +56,9 @@ namespace xo { /** resolve TypeRef by supplying final type-description **/ void resolve(TypeDescr td) noexcept { td_ = td; } + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; + private: /** unique (probably generated) name for type at this location **/ type_var id_; @@ -64,6 +69,18 @@ namespace xo { TypeDescr td_; }; } /*namespace scm*/ + + namespace print { + /** pretty printer in relies on this specialization + * to handle TypeRef instances + **/ + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::TypeRef x) { + return x.pretty(ppii); + } + }; + } } /*namespace xo*/ /* end TypeRef.hpp */ diff --git a/xo-expression2/src/expression2/DVariable.cpp b/xo-expression2/src/expression2/DVariable.cpp index 4adbe841..4550a102 100644 --- a/xo-expression2/src/expression2/DVariable.cpp +++ b/xo-expression2/src/expression2/DVariable.cpp @@ -5,6 +5,7 @@ #include "DVariable.hpp" #include "exprtype.hpp" +#include namespace xo { using xo::facet::typeseq; @@ -38,6 +39,8 @@ namespace xo { bool DVariable::pretty(const ppindentinfo & ppii) const { + using xo::print::quot; + auto name = (name_ ? std::string_view(*name_) : std::string_view("")); @@ -45,7 +48,8 @@ namespace xo { return ppii.pps()->pretty_struct (ppii, "DVariable", - refrtag("name", name)); + refrtag("name", quot(name)), + refrtag("typeref", typeref_)); } } /*namespace scm*/ diff --git a/xo-expression2/src/expression2/TypeRef.cpp b/xo-expression2/src/expression2/TypeRef.cpp index 7b187ecd..01cb043c 100644 --- a/xo-expression2/src/expression2/TypeRef.cpp +++ b/xo-expression2/src/expression2/TypeRef.cpp @@ -4,6 +4,8 @@ **/ #include "TypeRef.hpp" +#include +#include namespace xo { namespace scm { @@ -62,6 +64,18 @@ namespace xo { return (td_ != nullptr); } + bool + TypeRef::pretty(const ppindentinfo & ppii) const + { + using xo::print::quot; + + return ppii.pps()->pretty_struct + (ppii, + "TypeRef", + refrtag("id", quot(id_)), + refrtag("td", td_)); + } + } /*namespace scm*/ } /*namespace xo*/ From 00117840d02e7e6e8e7180e5d2aa10c47cc64520 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 22:13:01 -0500 Subject: [PATCH 034/258] xo-reader2 xo-object2: regenerate facets from idl --- xo-object2/CMakeLists.txt | 2 ++ xo-object2/include/xo/object2/Sequence.hpp | 2 +- xo-object2/include/xo/object2/list/IGCObject_DList.hpp | 2 +- xo-object2/include/xo/object2/list/IPrintable_DList.hpp | 2 +- xo-object2/include/xo/object2/list/ISequence_DList.hpp | 2 +- .../include/xo/object2/number/IGCObject_DFloat.hpp | 2 +- .../include/xo/object2/number/IGCObject_DInteger.hpp | 2 +- .../include/xo/object2/number/IPrintable_DFloat.hpp | 2 +- .../include/xo/object2/number/IPrintable_DInteger.hpp | 2 +- xo-object2/include/xo/object2/sequence/ASequence.hpp | 2 +- xo-object2/include/xo/object2/sequence/ISequence_Any.hpp | 2 +- .../include/xo/object2/sequence/ISequence_Xfer.hpp | 2 +- xo-object2/include/xo/object2/sequence/RSequence.hpp | 2 +- .../include/xo/object2/string/IGCObject_DString.hpp | 3 ++- .../include/xo/object2/string/IPrintable_DString.hpp | 3 ++- xo-object2/src/object2/IGCObject_DFloat.cpp | 2 +- xo-object2/src/object2/IGCObject_DInteger.cpp | 2 +- xo-object2/src/object2/IGCObject_DList.cpp | 2 +- xo-object2/src/object2/IGCObject_DString.cpp | 2 +- xo-object2/src/object2/IPrintable_DFloat.cpp | 2 +- xo-object2/src/object2/IPrintable_DInteger.cpp | 2 +- xo-object2/src/object2/IPrintable_DList.cpp | 2 +- xo-object2/src/object2/IPrintable_DString.cpp | 2 +- xo-object2/src/object2/ISequence_DList.cpp | 2 +- xo-reader2/CMakeLists.txt | 2 ++ xo-reader2/idl/SyntaxStateMachine.json5 | 9 +++++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExprSeqState.hpp | 5 +++++ xo-reader2/src/reader2/DDefineSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 9 +++++++++ 32 files changed, 82 insertions(+), 23 deletions(-) diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index 9c2671e0..ee93bf7e 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -160,6 +160,8 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +xo_add_genfacet_all(xo-object2-genfacet-all) + # ---------------------------------------------------------------- # must complete definition of expression lib before configuring examples diff --git a/xo-object2/include/xo/object2/Sequence.hpp b/xo-object2/include/xo/object2/Sequence.hpp index fc934084..7866f91b 100644 --- a/xo-object2/include/xo/object2/Sequence.hpp +++ b/xo-object2/include/xo/object2/Sequence.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-object2/include/xo/object2/list/IGCObject_DList.hpp b/xo-object2/include/xo/object2/list/IGCObject_DList.hpp index e87cdd96..19000df6 100644 --- a/xo-object2/include/xo/object2/list/IGCObject_DList.hpp +++ b/xo-object2/include/xo/object2/list/IGCObject_DList.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/list/IPrintable_DList.hpp b/xo-object2/include/xo/object2/list/IPrintable_DList.hpp index 4371fdfb..d068bda1 100644 --- a/xo-object2/include/xo/object2/list/IPrintable_DList.hpp +++ b/xo-object2/include/xo/object2/list/IPrintable_DList.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/list/ISequence_DList.hpp b/xo-object2/include/xo/object2/list/ISequence_DList.hpp index 81289db9..d7c44e3b 100644 --- a/xo-object2/include/xo/object2/list/ISequence_DList.hpp +++ b/xo-object2/include/xo/object2/list/ISequence_DList.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISequence_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp b/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp index c57c89ea..b27163c2 100644 --- a/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp +++ b/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DFloat.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/number/IGCObject_DInteger.hpp b/xo-object2/include/xo/object2/number/IGCObject_DInteger.hpp index 10a5c685..6aa3c9fc 100644 --- a/xo-object2/include/xo/object2/number/IGCObject_DInteger.hpp +++ b/xo-object2/include/xo/object2/number/IGCObject_DInteger.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DInteger.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/number/IPrintable_DFloat.hpp b/xo-object2/include/xo/object2/number/IPrintable_DFloat.hpp index 17eab5d2..2bcaf1d2 100644 --- a/xo-object2/include/xo/object2/number/IPrintable_DFloat.hpp +++ b/xo-object2/include/xo/object2/number/IPrintable_DFloat.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DFloat.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/number/IPrintable_DInteger.hpp b/xo-object2/include/xo/object2/number/IPrintable_DInteger.hpp index 95a9e108..a13334d6 100644 --- a/xo-object2/include/xo/object2/number/IPrintable_DInteger.hpp +++ b/xo-object2/include/xo/object2/number/IPrintable_DInteger.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DInteger.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/sequence/ASequence.hpp b/xo-object2/include/xo/object2/sequence/ASequence.hpp index 99687473..5281e0ea 100644 --- a/xo-object2/include/xo/object2/sequence/ASequence.hpp +++ b/xo-object2/include/xo/object2/sequence/ASequence.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp b/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp index 9f5901f2..0e7c5c10 100644 --- a/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp +++ b/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp b/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp index 60abc5aa..f3dc8b35 100644 --- a/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp +++ b/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/sequence/RSequence.hpp b/xo-object2/include/xo/object2/sequence/RSequence.hpp index 26ec1735..be4fafb0 100644 --- a/xo-object2/include/xo/object2/sequence/RSequence.hpp +++ b/xo-object2/include/xo/object2/sequence/RSequence.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/string/IGCObject_DString.hpp b/xo-object2/include/xo/object2/string/IGCObject_DString.hpp index ad12cb80..95a19483 100644 --- a/xo-object2/include/xo/object2/string/IGCObject_DString.hpp +++ b/xo-object2/include/xo/object2/string/IGCObject_DString.hpp @@ -6,13 +6,14 @@ * arguments: * --input [idl/IGCObject_DString.json5] * 2. jinja2 template for abstract facet .hpp file: - * [iface_facet_any.hpp.j2] + * [iface_facet_repr.hpp.j2] * 3. idl for facet methods * [idl/IGCObject_DString.json5] **/ #pragma once +#include "GCObject.hpp" #include #include #include "DString.hpp" diff --git a/xo-object2/include/xo/object2/string/IPrintable_DString.hpp b/xo-object2/include/xo/object2/string/IPrintable_DString.hpp index d1d3f22a..f1be1374 100644 --- a/xo-object2/include/xo/object2/string/IPrintable_DString.hpp +++ b/xo-object2/include/xo/object2/string/IPrintable_DString.hpp @@ -6,13 +6,14 @@ * arguments: * --input [idl/IPrintable_DString.json5] * 2. jinja2 template for abstract facet .hpp file: - * [iface_facet_any.hpp.j2] + * [iface_facet_repr.hpp.j2] * 3. idl for facet methods * [idl/IPrintable_DString.json5] **/ #pragma once +#include "Printable.hpp" #include #include #include "DString.hpp" diff --git a/xo-object2/src/object2/IGCObject_DFloat.cpp b/xo-object2/src/object2/IGCObject_DFloat.cpp index ef4214a7..3c44db5d 100644 --- a/xo-object2/src/object2/IGCObject_DFloat.cpp +++ b/xo-object2/src/object2/IGCObject_DFloat.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DFloat.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/src/object2/IGCObject_DInteger.cpp b/xo-object2/src/object2/IGCObject_DInteger.cpp index 8b8a0112..91d8e4a1 100644 --- a/xo-object2/src/object2/IGCObject_DInteger.cpp +++ b/xo-object2/src/object2/IGCObject_DInteger.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DInteger.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/src/object2/IGCObject_DList.cpp b/xo-object2/src/object2/IGCObject_DList.cpp index 06584687..b9d36cc5 100644 --- a/xo-object2/src/object2/IGCObject_DList.cpp +++ b/xo-object2/src/object2/IGCObject_DList.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/src/object2/IGCObject_DString.cpp b/xo-object2/src/object2/IGCObject_DString.cpp index d411686a..1eff4da5 100644 --- a/xo-object2/src/object2/IGCObject_DString.cpp +++ b/xo-object2/src/object2/IGCObject_DString.cpp @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DString.cpp */ +/* end IGCObject_DString.cpp */ \ No newline at end of file diff --git a/xo-object2/src/object2/IPrintable_DFloat.cpp b/xo-object2/src/object2/IPrintable_DFloat.cpp index b83613e5..0c0a6789 100644 --- a/xo-object2/src/object2/IPrintable_DFloat.cpp +++ b/xo-object2/src/object2/IPrintable_DFloat.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DFloat.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/src/object2/IPrintable_DInteger.cpp b/xo-object2/src/object2/IPrintable_DInteger.cpp index 889cfa8c..8924a72c 100644 --- a/xo-object2/src/object2/IPrintable_DInteger.cpp +++ b/xo-object2/src/object2/IPrintable_DInteger.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DInteger.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/src/object2/IPrintable_DList.cpp b/xo-object2/src/object2/IPrintable_DList.cpp index 384d8b60..095b323d 100644 --- a/xo-object2/src/object2/IPrintable_DList.cpp +++ b/xo-object2/src/object2/IPrintable_DList.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/src/object2/IPrintable_DString.cpp b/xo-object2/src/object2/IPrintable_DString.cpp index f47aa3fa..86d4565e 100644 --- a/xo-object2/src/object2/IPrintable_DString.cpp +++ b/xo-object2/src/object2/IPrintable_DString.cpp @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DString.cpp */ +/* end IPrintable_DString.cpp */ \ No newline at end of file diff --git a/xo-object2/src/object2/ISequence_DList.cpp b/xo-object2/src/object2/ISequence_DList.cpp index b216b7e5..3c9c2437 100644 --- a/xo-object2/src/object2/ISequence_DList.cpp +++ b/xo-object2/src/object2/ISequence_DList.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISequence_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index e2ee946b..ac780154 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -110,6 +110,8 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +xo_add_genfacet_all(xo-reader2-genfacet-all) + # ---------------------------------------------------------------- # shared library diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 28811512..f1b74111 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -70,6 +70,15 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_colon_token", + doc: ["update state machine for incoming colon-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_parsed_symbol", doc: ["update stat machine for incoming parsed symbol @p sym"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index b8444cbe..468d1a22 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -127,6 +127,12 @@ namespace xo { void on_if_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming colon token @p tk, + * overall parser state in @p p_psm + **/ + void on_colon_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 2ecc556d..1854486e 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -69,6 +69,12 @@ namespace xo { void on_if_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming colon token @p tk, + * overall parser state in @p p_psm + **/ + void on_colon_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; * overall parser state in @p p_psm. * diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 32eaef0f..90c69c5f 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -79,6 +79,11 @@ namespace xo { **/ void on_if_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming colon token @p tk, + * overall parser state in @p p_psm + **/ + void on_colon_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on parsed symbol @p sym * from immediately-downstream ssm. * overall parser state in @p p_psm diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index c1e3f6a9..13b99028 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -498,6 +498,15 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DDefineSsm::on_colon_token", + tk, + this->get_expect_str()); + } + bool DDefineSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index c859528f..1eccc454 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -95,6 +95,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_colon_token", + tk, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index e994bbf1..6744c77d 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -160,6 +160,15 @@ namespace xo { } } + void + DExprSeqState::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExprSeqState::on_colon_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) From 121fba491f606a698fe8a13eb686f7a6e48ad6ef Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 22:15:32 -0500 Subject: [PATCH 035/258] xo-reader2: regen ssm facet files + on_colon_token --- xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 ++ xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp | 2 +- .../include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp | 2 +- .../include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp | 2 +- .../include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 ++ .../xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 ++ .../xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 ++ .../include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 +++ xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 +++ xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp | 2 +- xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp | 2 +- xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp | 2 +- xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp | 6 ++++++ xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp | 5 +++++ .../src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 +++++ .../src/reader2/ISyntaxStateMachine_DExprSeqState.cpp | 5 +++++ 17 files changed, 42 insertions(+), 6 deletions(-) diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index 4f428be5..f3ccb709 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -60,6 +60,8 @@ public: virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming if-keyword-token @p tk **/ virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming colon-token @p tk **/ + virtual void on_colon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update stat machine for incoming parsed symbol @p sym **/ virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp index dd80b443..44b3165f 100644 --- a/xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DDefineSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp index 6e63383b..f0dc79b6 100644 --- a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectSymbolSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp index 87d85fd7..6d542a07 100644 --- a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 23b90621..03ab1fa7 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -62,6 +62,7 @@ namespace scm { [[noreturn]] void on_symbol_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_def_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_colon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index d420ba16..85d6d70b 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -59,6 +59,8 @@ namespace xo { static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming colon-token @p tk **/ + static void on_colon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index ba8eb0b9..75125e5c 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -59,6 +59,8 @@ namespace xo { static void on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming colon-token @p tk **/ + static void on_colon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index c1e61b40..e0689f69 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -59,6 +59,8 @@ namespace xo { static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming colon-token @p tk **/ + static void on_colon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 5a8e2fe3..ac6975ba 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -59,6 +59,9 @@ namespace scm { void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_if_token(_dcast(data), tk, p_psm); } + void on_colon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_colon_token(_dcast(data), tk, p_psm); + } void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { return I::on_parsed_symbol(_dcast(data), sym, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 786c83d0..78bbfb18 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -64,6 +64,9 @@ public: void on_if_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_if_token(O::data(), tk, p_psm); } + void on_colon_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_colon_token(O::data(), tk, p_psm); + } void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); } diff --git a/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp b/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp index c3aa2edd..bb3c2096 100644 --- a/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp index 2cef62a7..e58d15f9 100644 --- a/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectSymbolSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp b/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp index f751b963..71997ede 100644 --- a/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 44effd57..edac8279 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -52,6 +52,12 @@ ISyntaxStateMachine_Any::on_if_token(Opaque, const Token &, ParserStateMachine * _fatal(); } +auto +ISyntaxStateMachine_Any::on_colon_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 34bd4569..425032e3 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_if_token(tk, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_colon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_colon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index f00b9c2f..2188d50d 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_if_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_colon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_colon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 47c06ba3..7ad8fb50 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_if_token(tk, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_colon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_colon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); From 3cca1b8255511dfcab34e1367429be7e4afbf3dd Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 22:22:45 -0500 Subject: [PATCH 036/258] xo-reader2: DefineSsm handles colon token after lhs var example: def foo : f64 = 3.14; --- .../include/xo/reader2/ParserStateMachine.hpp | 3 +++ xo-reader2/src/reader2/DDefineSsm.cpp | 9 ++++++++- xo-reader2/src/reader2/ParserStateMachine.cpp | 13 ++++++++++++- xo-reader2/utest/SchematikaParser.test.cpp | 11 +++++++++++ xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index fbef2393..31b664c0 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -105,6 +105,9 @@ namespace xo { /** operate state machine for incoming if-token @p tk **/ void on_if_token(const Token & tk); + /** operate state machine for incoming colon-token @p tk **/ + void on_colon_token(const Token & tk); + ///@} /** @defgroup scm-parserstatemachine-error-entrypoints error entry points **/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 13b99028..8941a20d 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -477,7 +477,7 @@ namespace xo { DDefineSsm::on_def_token(const Token & tk, ParserStateMachine * p_psm) { - if (this->defstate_ == defexprstatetype::def_0) { + if (defstate_ == defexprstatetype::def_0) { this->defstate_ = defexprstatetype::def_1; DExpectSymbolSsm::start(p_psm->parser_alloc(), p_psm); @@ -502,6 +502,13 @@ namespace xo { DDefineSsm::on_colon_token(const Token & tk, ParserStateMachine * p_psm) { + if (defstate_ == defexprstatetype::def_2) { + this->defstate_ = defexprstatetype::def_3; + + // expect_type_xs::start(p_psm); + return; + } + p_psm->illegal_input_on_token("DDefineSsm::on_colon_token", tk, this->get_expect_str()); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index ca8bba8b..5c9cc413 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -139,6 +139,10 @@ namespace xo { this->on_if_token(tk); break; + case tokentype::tk_colon: + this->on_colon_token(tk); + break; + // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_bool: @@ -157,7 +161,6 @@ namespace xo { case tokentype::tk_greatequal: case tokentype::tk_dot: case tokentype::tk_comma: - case tokentype::tk_colon: case tokentype::tk_doublecolon: case tokentype::tk_semicolon: case tokentype::tk_singleassign: @@ -208,6 +211,14 @@ namespace xo { stack_->top().on_if_token(tk, this); } + void + ParserStateMachine::on_colon_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_colon_token(tk, this); + } + void ParserStateMachine::capture_error(std::string_view ssm_name, const DString * errmsg) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 8cccfd7b..4e4b778f 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -112,6 +112,17 @@ namespace xo { log && log(xtag("result", result)); } + { + auto & result = parser.on_token(Token::colon_token()); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(result.is_incomplete()); + + log && log("after colon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + } + // define-expressions not properly implemented //REQUIRE(result.error_description()); diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index 7ed490cc..fc448106 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -108,7 +108,7 @@ namespace xo { /** token representing comma @c "," **/ static Token comma() { return Token(tokentype::tk_comma); } /** token representing colon @c ":" **/ - static Token colon() { return Token(tokentype::tk_colon); } + static Token colon_token() { return Token(tokentype::tk_colon); } /** token representing double-colo @c "::" **/ static Token doublecolon() { return Token(tokentype::tk_doublecolon); } /** token representing semicolon @c ";" **/ From 823e3d7fb3f531077b97c83dcf65c3df9b9493aa Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 20 Jan 2026 22:39:01 -0500 Subject: [PATCH 037/258] xo-reader2: + DExpectTypeSsm [WIP] [NOBUILD] --- .../include/xo/reader2/DExpectTypeSsm.hpp | 64 +++++++++++++++++++ .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/DExpectTypeSsm.cpp | 44 +++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp create mode 100644 xo-reader2/src/reader2/DExpectTypeSsm.cpp diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp new file mode 100644 index 00000000..84654f83 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -0,0 +1,64 @@ +/** @file expect_type_xs.hpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" + +namespace xo { + namespace scm { + /** @class DExpectTypeSsm + * @brief syntax state-machine for accepting a Schemtika typename-expression + * + * Jan 2026 + * Placeholder implementation at present. + * Only types are a handful of baked-in values + * + * @pre + * + * @endpre + **/ + class DExpectTypeSsm { + public: + DExpectTypeSsm(); + + static DExpectTypeSsm * make(DArena & parser_mm); + + static void start(DArena & parser_mm, + //obj expr_mm, + ParserStateMachine * p_psm); + + virtual const char * get_expect_str() const override; + + virtual void on_symbol_token(const token_type & tk, + parserstatemachine * p_psm) override; + + /** @defgroup scm-expecttype-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error messages. + **/ + std::string_view get_expect_str() const noexcept; + + /** operate state machien for this syntax on incoming symbol-token @p tk + * with overall parser state in @p p_psm + **/ + void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + + private: + static std::unique_ptr make(); + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_type_xs.hpp */ diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index bf3e03f1..8cb48938 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -24,6 +24,9 @@ namespace xo { /** expecting a s symbol. See @ref DExpectSymbolSsm **/ expect_symbol, + /** expecting a type. See @ref DExpectTypeSsm **/ + expect_type, + /** handle define-expression. See @ref DDefineSsm **/ defexpr, diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp new file mode 100644 index 00000000..b034ae23 --- /dev/null +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -0,0 +1,44 @@ +/** @file DExpectTypeSsm.cpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#include "DExpectTypeSsm.hpp" + +namespace xo { + namespace scm { + DExpectTypeSsm::DExpectTypeSsm() + {} + + DExpectTypeSsm * + DExpectTypeSsm::make(DArena & mm) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DArena)); + + return new (mem) DExpectTypeSsm(); + } + + void + DExpectTypeSsm::start(DArena & mm, + //obj expr_mm, + PArserStateMachine * p_psm) + { + DExpectTypeSsm * expect_type_ssm = DExpectTypeSsm::make(mm); + + auto ssm + = with_facet::mkobj(expect_type_ssm); + + p_psm->push_ssm(ssm); + } + + syntaxstatetype + DExpectTypeSsm::ssm_type() const noexcept + { + return syntaxstatetype::expect_type; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectTypeSsm.cpp */ From 319c7537f3f125cd186ec253663da19f2aed4342 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 21 Jan 2026 01:24:17 -0500 Subject: [PATCH 038/258] xo-reader2: + DExpectTypeSsm + extend DDefineSsm [WIP] --- xo-reader2/CMakeLists.txt | 28 +++++ .../idl/IPrintable_DExpectTypeSsm.json5 | 13 +++ .../ISyntaxStateMachine_DExpectTypeSsm.json5 | 13 +++ .../include/xo/reader2/DExpectTypeSsm.hpp | 48 +++++++-- .../reader2/ssm/IPrintable_DExpectTypeSsm.hpp | 62 +++++++++++ .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 72 +++++++++++++ xo-reader2/src/reader2/CMakeLists.txt | 4 + xo-reader2/src/reader2/DDefineSsm.cpp | 5 +- xo-reader2/src/reader2/DExpectTypeSsm.cpp | 102 +++++++++++++++++- .../src/reader2/IPrintable_DExpectTypeSsm.cpp | 28 +++++ .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 59 ++++++++++ .../src/reader2/reader2_register_facets.cpp | 7 ++ xo-reader2/utest/SchematikaParser.test.cpp | 11 ++ 13 files changed, 442 insertions(+), 10 deletions(-) create mode 100644 xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp create mode 100644 xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index ac780154..d8c82e1d 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -110,6 +110,34 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expecttypessm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExpectTypeSsm + INPUT idl/ISyntaxStateMachine_DExpectTypeSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expecttypessm + FACET_PKG xo_printable2 + FACET Printable + REPR ExpectTypeSsm + INPUT idl/IPrintable_DExpectTypeSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-reader2-genfacet-all) # ---------------------------------------------------------------- diff --git a/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 b/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 new file mode 100644 index 00000000..1a4ddca2 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectTypeSsm", + using_doxygen: true, + repr: "DExpectTypeSsm", + doc: [ "implement APrintable for DExpectTypeSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 new file mode 100644 index 00000000..d46aaff4 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectTypeSsm", + using_doxygen: true, + repr: "DExpectTypeSsm", + doc: [ "implement ASyntaxStateMachine for DExpectTypeSsm" ], +} \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 84654f83..aebec716 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -6,6 +6,7 @@ #pragma once #include "SyntaxStateMachine.hpp" +#include namespace xo { namespace scm { @@ -21,6 +22,10 @@ namespace xo { * @endpre **/ class DExpectTypeSsm { + public: + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + public: DExpectTypeSsm(); @@ -30,11 +35,6 @@ namespace xo { //obj expr_mm, ParserStateMachine * p_psm); - virtual const char * get_expect_str() const override; - - virtual void on_symbol_token(const token_type & tk, - parserstatemachine * p_psm) override; - /** @defgroup scm-expecttype-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -52,13 +52,45 @@ namespace xo { void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); + /** operate state machine for this syntax on incoming define-token @p tk + * with overall parser state in @p p_psm + **/ + void on_def_token(const Token & tk, + ParserStateMachine * p_psm); + + /** operate state machine for this syntax on incoming if-token @p tk + * with overall parser state in @p p_psm + **/ + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); + + /** operate state machine for this syntax on incoming colon-token @p tk + * with overall parser state in @p p_psm + **/ + void on_colon_token(const Token & tk, + ParserStateMachine * p_psm); + + /** Never called. + * Operate state machine for this syntax after symbol + * emitted from nested ssm. + * Impossible path for DExpectTypeSsm until such time as it relies + * on nested ssms. Currently using on_symbol_token + * entry point instead. + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expecttype-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + ///@} - private: - static std::unique_ptr make(); }; } /*namespace scm*/ } /*namespace xo*/ -/* end expect_type_xs.hpp */ +/* end DExpectTypeSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp new file mode 100644 index 00000000..271df307 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectTypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectTypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectTypeSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectTypeSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectTypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectTypeSsm + **/ + class IPrintable_DExpectTypeSsm { + public: + /** @defgroup scm-printable-dexpecttypessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpecttypessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectTypeSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp new file mode 100644 index 00000000..c56f21d5 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -0,0 +1,72 @@ +/** @file ISyntaxStateMachine_DExpectTypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectTypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectTypeSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectTypeSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectTypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectTypeSsm + **/ + class ISyntaxStateMachine_DExpectTypeSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpecttypessm-type-traits **/ + ///@{ + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpecttypessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectTypeSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectTypeSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming if-keyword-token @p tk **/ + static void on_if_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming colon-token @p tk **/ + static void on_colon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 6b17e3d3..b09f015a 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -23,6 +23,10 @@ set(SELF_SRCS ISyntaxStateMachine_DExpectSymbolSsm.cpp IPrintable_DExpectSymbolSsm.cpp + DExpectTypeSsm.cpp + ISyntaxStateMachine_DExpectTypeSsm.cpp + IPrintable_DExpectTypeSsm.cpp + reader2_register_facets.cpp reader2_register_types.cpp ) diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 8941a20d..98a9fa4a 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -5,6 +5,7 @@ #include "DDefineSsm.hpp" #include "DExpectSymbolSsm.hpp" +#include "DExpectTypeSsm.hpp" #include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" #include "ssm/IPrintable_DDefineSsm.hpp" #include @@ -505,7 +506,9 @@ namespace xo { if (defstate_ == defexprstatetype::def_2) { this->defstate_ = defexprstatetype::def_3; - // expect_type_xs::start(p_psm); + DExpectTypeSsm::start(p_psm->parser_alloc(), + p_psm); + return; } diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index b034ae23..ce38473e 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -4,8 +4,20 @@ **/ #include "DExpectTypeSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp" +#include "SyntaxStateMachine.hpp" +#include +#include +#include +#include +#include namespace xo { + using xo::facet::with_facet; + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; + using xo::reflect::typeseq; + namespace scm { DExpectTypeSsm::DExpectTypeSsm() {} @@ -22,7 +34,7 @@ namespace xo { void DExpectTypeSsm::start(DArena & mm, //obj expr_mm, - PArserStateMachine * p_psm) + ParserStateMachine * p_psm) { DExpectTypeSsm * expect_type_ssm = DExpectTypeSsm::make(mm); @@ -38,6 +50,94 @@ namespace xo { return syntaxstatetype::expect_type; } + std::string_view + DExpectTypeSsm::get_expect_str() const noexcept + { + return "typename"; + } + + void + DExpectTypeSsm::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectTypeSsm", + tk, + this->get_expect_str()); + } + + void + DExpectTypeSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DxpectTypeSsm", + tk, + this->get_expect_str()); + } + + void + DExpectTypeSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DxpectTypeSsm", + tk, + this->get_expect_str()); + } + + void + DExpectTypeSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(true)); + + TypeDescr td = nullptr; + + /* TODO: replace with typetable lookup */ + + if (tk.text() == "bool") + td = Reflect::require(); + else if (tk.text() == "str") + td = Reflect::require(); + else if (tk.text() == "f64") + td = Reflect::require(); + else if(tk.text() == "f32") + td = Reflect::require(); + else if(tk.text() == "i16") + td = Reflect::require(); + else if(tk.text() == "i32") + td = Reflect::require(); + else if(tk.text() == "i64") + td = Reflect::require(); + + if (!td) { + p_psm->illegal_input_on_token("DExpectTypeSsm", + tk, + this->get_expect_str()); + } + + p_psm->pop_ssm(); + + log && log("STUB: missing on_typedescr() call"); + + //p_psm->on_typedescr(td); + } + + void + DExpectTypeSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("ExpectTypeSsm", + sym, + this->get_expect_str()); + } + + bool + DExpectTypeSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DExpectTypeSsm"); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp new file mode 100644 index 00000000..c82d726e --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectTypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectTypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectTypeSsm.json5] +**/ + +#include "ssm/IPrintable_DExpectTypeSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectTypeSsm::pretty(const DExpectTypeSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectTypeSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp new file mode 100644 index 00000000..c520aea8 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -0,0 +1,59 @@ +/** @file ISyntaxStateMachine_DExpectTypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectTypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectTypeSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectTypeSsm::ssm_type(const DExpectTypeSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectTypeSsm::get_expect_str(const DExpectTypeSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectTypeSsm::on_symbol_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_symbol_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_def_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_def_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_if_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_if_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_colon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_colon_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectTypeSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index ee838864..a393eead 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -14,6 +14,9 @@ #include #include +#include +#include + #include #include #include @@ -39,9 +42,13 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); log && log(xtag("DExpectSymbolSsm.tseq", typeseq::id())); + log && log(xtag("DExpectTypeSsm.tseq", typeseq::id())); return true; } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 4e4b778f..af9b8303 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -123,6 +123,17 @@ namespace xo { log && log(xtag("result", result)); } + { + auto & result = parser.on_token(Token::symbol_token("f64")); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(result.is_incomplete()); + + log && log("after typename symbol token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + } + // define-expressions not properly implemented //REQUIRE(result.error_description()); From 3cbd4224b1406e2e461790e5124e0962dd3a75a6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 21 Jan 2026 12:14:35 -0500 Subject: [PATCH 039/258] xo-reader2: handle parsed typedescr + use in DDefineSsm --- .../include/xo/expression2/DDefineExpr.hpp | 5 ++- xo-reader2/idl/SyntaxStateMachine.json5 | 11 ++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 7 ++++ .../include/xo/reader2/DExpectSymbolSsm.hpp | 39 +++++++++++-------- .../include/xo/reader2/DExpectTypeSsm.hpp | 11 +++++- .../include/xo/reader2/DExprSeqState.hpp | 7 ++++ .../include/xo/reader2/ParserStateMachine.hpp | 20 +++++++++- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 5 +++ .../reader2/ssm/IPrintable_DExpectTypeSsm.hpp | 2 +- .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 2 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 3 ++ .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 3 ++ .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 5 ++- .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 3 ++ .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 5 +++ .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 4 ++ xo-reader2/src/reader2/DDefineSsm.cpp | 28 ++++++++++++- xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 27 ++++++++----- xo-reader2/src/reader2/DExpectTypeSsm.cpp | 14 +++++-- xo-reader2/src/reader2/DExprSeqState.cpp | 9 +++++ .../src/reader2/IPrintable_DExpectTypeSsm.cpp | 2 +- .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 +++ .../ISyntaxStateMachine_DDefineSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 7 +++- .../ISyntaxStateMachine_DExprSeqState.cpp | 5 +++ xo-reader2/src/reader2/ParserStateMachine.cpp | 33 ++++++++++++++++ 27 files changed, 235 insertions(+), 38 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp index 59826aa2..1056dbb7 100644 --- a/xo-expression2/include/xo/expression2/DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -51,10 +51,13 @@ namespace xo { obj rhs() const noexcept { return rhs_; } const DUniqueString * name() const noexcept; + ///@} + /** @defgroup scm-definexpr-bookkeeping-methods **/ + ///@{ + void assign_lhs_name(const DUniqueString * name); ///@} - /** @defgroup scm-defineexpr-expression-facet **/ ///@{ diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index f1b74111..c207022f 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -5,6 +5,7 @@ "\"ParserStateMachine.hpp\"", "\"syntaxstatetype.hpp\"", "", + "", ], // extra includes in SyntaxStateMachine.hpp, if any user_hpp_includes: [], @@ -20,6 +21,7 @@ "Assistant to schematika parser dedicated to particular syntax" ], types: [ + { name: "TypeDescr", doc: [ "reflected c++ type" ], definition: "xo::reflect::TypeDescr" }, // { name: string, doc: [ string ], definition: string }, ], const_methods: [ @@ -88,5 +90,14 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_typedescr", + doc: ["operate state machine for incoming type description @p td"], + return_type: "void", + args: [ + {type: "TypeDescr", name: "td"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, ], } diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 468d1a22..d9aea54f 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -71,6 +71,7 @@ namespace xo { **/ class DDefineSsm { public: + using TypeDescr = xo::reflect::TypeDescr; using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; @@ -139,6 +140,12 @@ namespace xo { void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); + /** update state for this syntax after parsing a type-description @p td, + * overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 1854486e..7421c0f7 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -22,6 +22,7 @@ namespace xo { class DExpectSymbolSsm { public: using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; public: @@ -57,8 +58,29 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** update state for this syntax after parsing a symbol @p sym; + * overall parser state in @p p_psm. + * + * NOTE: + * might not be obvious that this is unreachable. + * DExpectSymbolSsm converts a symbol token, + * and delivers it to parent ssm using this entry point. + * This method would only be called if consecutive + * DExpectSymbolSsm instances on parser stack; + * which scenario never occurs in Schematika syntax + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a type-description @p td + * in nested state machine. + * (provided to satisfy ASyntaxStateMachine api. not reachable) + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, - * overall parser state in @p p_psm + * overall parser state in @p p_psm. **/ void on_def_token(const Token & tk, ParserStateMachine * p_psm); @@ -75,21 +97,6 @@ namespace xo { void on_colon_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax after parsing a symbol @p sym; - * overall parser state in @p p_psm. - * - * NOTE: - * might not be obvious that this is unreachable. - * DExpectSymbolSsm converts a symbol token, - * and delivers it to parent ssm using this entry point. - * This method would only be called if consecutive - * DExpectSymbolSsm instances on parser stack; - * which scenario never occurs in Schematika syntax - **/ - void on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm); - - ///@} /** @defgroup scm-expectsymbol-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index aebec716..f98b8767 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -23,6 +23,7 @@ namespace xo { **/ class DExpectTypeSsm { public: + using TypeDescr = xo::reflect::TypeDescr; using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; @@ -70,7 +71,7 @@ namespace xo { void on_colon_token(const Token & tk, ParserStateMachine * p_psm); - /** Never called. + /** (Never called). * Operate state machine for this syntax after symbol * emitted from nested ssm. * Impossible path for DExpectTypeSsm until such time as it relies @@ -80,6 +81,14 @@ namespace xo { void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for this syntax on receiving type-description + * from nested parser. + * Currently (jan 2026) impossible path for DExpectTypeSsm. + * Active path is via on_symbol_token() + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expecttype-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 90c69c5f..942afedd 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -39,6 +39,7 @@ namespace xo { **/ class DExprSeqState { public: + using TypeDescr = xo::reflect::TypeDescr; using AAllocator = xo::mm::AAllocator; using ppindentinfo = xo::print::ppindentinfo; @@ -90,6 +91,12 @@ namespace xo { **/ void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); + /** update state for this syntax on parsed type-description @p td + * from nested ssm. + * overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + ///@} /** @defgroup scm-exprseq-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 31b664c0..e17ff39d 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -29,6 +29,7 @@ namespace xo { **/ class ParserStateMachine { public: + using TypeDescr = xo::reflect::TypeDescr; using AAllocator = xo::mm::AAllocator; using ArenaConfig = xo::mm::ArenaConfig; using DArena = xo::mm::DArena; @@ -88,9 +89,16 @@ namespace xo { /** @defgroup scm-parserstatemachine-inputmethods input methods **/ ///@{ - /** update state to respond to prsed symbol @p sym **/ + /** update state to respond to parsed symbol @p sym + * (from nested parsing state) + **/ void on_parsed_symbol(std::string_view sym); + /** update state to respond to parsed type-description @p td + * (from nested parsing state) + **/ + void on_parsed_typedescr(TypeDescr td); + /** update state to respond to input token @p tk. * record output (if any) in @ref result_ **/ @@ -109,7 +117,6 @@ namespace xo { void on_colon_token(const Token & tk); ///@} - /** @defgroup scm-parserstatemachine-error-entrypoints error entry points **/ ///@{ @@ -136,6 +143,15 @@ namespace xo { void illegal_input_on_symbol(std::string_view ssm_name, std::string_view sym, std::string_view expect_str); + + /** report illegal input arriving in syntax state machine (ssm) @p ssm_name + * receiving assembled type-description @p td. + * @p expect_str sketches expected input in current ssm state + **/ + void illegal_input_on_typedescr(std::string_view ssm_name, + TypeDescr td, + std::string_view expect_str); + ///@} private: diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index f3ccb709..6aefa1f7 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -17,6 +17,7 @@ #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" #include +#include #include #include #include @@ -41,6 +42,8 @@ public: using typeseq = xo::facet::typeseq; using Copaque = const void *; using Opaque = void *; + /** reflected c++ type **/ + using TypeDescr = xo::reflect::TypeDescr; ///@} /** @defgroup scm-syntaxstatemachine-methods **/ @@ -64,6 +67,8 @@ public: virtual void on_colon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update stat machine for incoming parsed symbol @p sym **/ virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; + /** operate state machine for incoming type description @p td **/ + virtual void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) = 0; ///@} }; /*ASyntaxStateMachine*/ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp index 271df307..7b7785e9 100644 --- a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectTypeSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 03ab1fa7..1a6705d2 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -44,6 +44,7 @@ namespace scm { /** integer identifying a type **/ using typeseq = xo::facet::typeseq; + using TypeDescr = ASyntaxStateMachine::TypeDescr; ///@} /** @defgroup scm-syntaxstatemachine-any-methods **/ @@ -64,6 +65,7 @@ namespace scm { [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_colon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; + [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index 85d6d70b..65627a03 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -41,6 +41,7 @@ namespace xo { public: /** @defgroup scm-syntaxstatemachine-ddefinessm-type-traits **/ ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; using Copaque = xo::scm::ASyntaxStateMachine::Copaque; using Opaque = xo::scm::ASyntaxStateMachine::Opaque; ///@} @@ -63,6 +64,8 @@ namespace xo { static void on_colon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 75125e5c..91ff08b6 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -41,6 +41,7 @@ namespace xo { public: /** @defgroup scm-syntaxstatemachine-dexpectsymbolssm-type-traits **/ ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; using Copaque = xo::scm::ASyntaxStateMachine::Copaque; using Opaque = xo::scm::ASyntaxStateMachine::Opaque; ///@} @@ -63,6 +64,8 @@ namespace xo { static void on_colon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index c56f21d5..64622261 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectTypeSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -41,6 +41,7 @@ namespace xo { public: /** @defgroup scm-syntaxstatemachine-dexpecttypessm-type-traits **/ ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; using Copaque = xo::scm::ASyntaxStateMachine::Copaque; using Opaque = xo::scm::ASyntaxStateMachine::Opaque; ///@} @@ -63,6 +64,8 @@ namespace xo { static void on_colon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index e0689f69..64fd4ed7 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -41,6 +41,7 @@ namespace xo { public: /** @defgroup scm-syntaxstatemachine-dexprseqstate-type-traits **/ ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; using Copaque = xo::scm::ASyntaxStateMachine::Copaque; using Opaque = xo::scm::ASyntaxStateMachine::Opaque; ///@} @@ -63,6 +64,8 @@ namespace xo { static void on_colon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index ac6975ba..7b2c721f 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -16,6 +16,7 @@ #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" #include +#include namespace xo { namespace scm { @@ -30,6 +31,7 @@ namespace scm { using Impl = ISyntaxStateMachine_DRepr; /** integer identifying a type **/ using typeseq = ASyntaxStateMachine::typeseq; + using TypeDescr = ASyntaxStateMachine::TypeDescr; ///@} /** @defgroup scm-syntaxstatemachine-xfer-methods **/ @@ -65,6 +67,9 @@ namespace scm { void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { return I::on_parsed_symbol(_dcast(data), sym, p_psm); } + void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) override { + return I::on_parsed_typedescr(_dcast(data), td, p_psm); + } ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 78bbfb18..4a63e377 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -31,6 +31,7 @@ public: using ObjectType = Object; using DataPtr = Object::DataPtr; using typeseq = xo::reflect::typeseq; + using TypeDescr = ASyntaxStateMachine::TypeDescr; ///@} /** @defgroup scm-syntaxstatemachine-router-ctors **/ @@ -70,6 +71,9 @@ public: void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); } + void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_typedescr(O::data(), td, p_psm); + } ///@} /** @defgroup scm-syntaxstatemachine-member-vars **/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 98a9fa4a..21435a83 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -420,7 +420,7 @@ namespace xo { DDefineSsm::on_parsed_symbol(std::string_view sym_name, ParserStateMachine * p_psm) { - if (this->defstate_ == defexprstatetype::def_1) { + if (defstate_ == defexprstatetype::def_1) { this->defstate_ = defexprstatetype::def_2; const DUniqueString * sym @@ -460,6 +460,32 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(true), xtag("td", td)); + + if (defstate_ == defexprstatetype::def_3) { + this->defstate_ = defexprstatetype::def_4; + + // note: not present in x0-reader/ version + def_expr_.assign_valuetype(td); + +#ifdef NOT_YET + this->cvt_expr_ = ConvertExpr::make(td, nullptr); + def_expr_->assign_rhs(cvt_expr_); +#endif + log && log("STUB: ConvertExpr not implemented, TypeDescr not captured"); + + return; + } + + p_psm->illegal_input_on_typedescr("DDefineSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + void DDefineSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 1eccc454..877c6a50 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -56,6 +56,24 @@ namespace xo { return "symbol"; } + void + DExpectSymbolSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExpectSymbolSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + + void + DExpectSymbolSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DExpectSymbolSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) @@ -104,15 +122,6 @@ namespace xo { this->get_expect_str()); } - void - DExpectSymbolSsm::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("DExpectSymbolSsm::on_parsed_symbol", - sym, - this->get_expect_str()); - } - bool DExpectSymbolSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index ce38473e..62ccdf22 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -115,10 +115,7 @@ namespace xo { } p_psm->pop_ssm(); - - log && log("STUB: missing on_typedescr() call"); - - //p_psm->on_typedescr(td); + p_psm->on_parsed_typedescr(td); } void @@ -130,6 +127,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("ExpectTypeSsm", + td, + this->get_expect_str()); + } + bool DExpectTypeSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 6744c77d..6f9d877a 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -178,6 +178,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DExprSeqState::on_parsed_typedescr", + td, + this->get_expect_str()); + } + bool DExprSeqState::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp index c82d726e..3fc75136 100644 --- a/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectTypeSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index edac8279..24775dfd 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -64,6 +64,12 @@ ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateM _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) -> void +{ + _fatal(); +} + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 425032e3..8cc9c858 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -52,6 +52,11 @@ namespace xo { { self.on_parsed_symbol(sym, p_psm); } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 2188d50d..e4716ef8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -52,6 +52,11 @@ namespace xo { { self.on_parsed_symbol(sym, p_psm); } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index c520aea8..893cb0dd 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectTypeSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -52,6 +52,11 @@ namespace xo { { self.on_parsed_symbol(sym, p_psm); } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 7ad8fb50..911e825e 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -52,6 +52,11 @@ namespace xo { { self.on_parsed_symbol(sym, p_psm); } + auto + ISyntaxStateMachine_DExprSeqState::on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 5c9cc413..79f23eb5 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -113,6 +113,16 @@ namespace xo { this->stack_->top().on_parsed_symbol(sym, this); } + void + ParserStateMachine::on_parsed_typedescr(TypeDescr td) + { + scope log(XO_DEBUG(debug_flag_), xtag("td", td)); + + assert(stack_); + + this->stack_->top().on_parsed_typedescr(td, this); + } + void ParserStateMachine::on_token(const Token & tk) { @@ -271,6 +281,29 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + + void + ParserStateMachine::illegal_input_on_typedescr(std::string_view ssm_name, + TypeDescr td, + std::string_view expect_str) + { + // TODO: + // - want to write error message using DArena + // - need something like log_streambuf and/or tostr() that's arena-aware + + auto errmsg_string = tostr("Unexpected type-description for parsing state", + xtag("td", td), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_input_on_typedescr")); + + assert(expr_alloc_); + + auto errmsg = DString::from_view(expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } } /*namespace scm*/ } /*namespace xo*/ From 29609e6dfd59989f0608159447bff152f0b0f9a6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 21 Jan 2026 12:59:06 -0500 Subject: [PATCH 040/258] xo-reader2: scaffold on_singleassign_token() in PSM --- xo-reader2/idl/SyntaxStateMachine.json5 | 9 ++++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 +++++ .../include/xo/reader2/DExpectSymbolSsm.hpp | 6 +++++ .../include/xo/reader2/DExpectTypeSsm.hpp | 6 +++++ .../include/xo/reader2/DExprSeqState.hpp | 5 +++++ .../include/xo/reader2/ParserStateMachine.hpp | 3 +++ .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 ++ .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 ++ .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 +++ .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 +++ xo-reader2/src/reader2/DDefineSsm.cpp | 22 +++++++++++++++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 ++++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 ++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 9 ++++++++ .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 +++++ .../ISyntaxStateMachine_DDefineSsm.cpp | 5 +++++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 +++++ .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 +++++ .../ISyntaxStateMachine_DExprSeqState.cpp | 5 +++++ xo-reader2/src/reader2/ParserStateMachine.cpp | 13 ++++++++++- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 6 ++--- 25 files changed, 142 insertions(+), 4 deletions(-) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index c207022f..2fcbd796 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -81,6 +81,15 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_singleassign_token", + doc: ["update state machine for incoming singleassign-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_parsed_symbol", doc: ["update stat machine for incoming parsed symbol @p sym"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index d9aea54f..5308f77a 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -134,6 +134,12 @@ namespace xo { void on_colon_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming singleassign token @p tk, + * overall parser state in @p p_psm + **/ + void on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 7421c0f7..7bbcec91 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -97,6 +97,12 @@ namespace xo { void on_colon_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming singleassign token @p tk, + * overall parser state in @p p_psm + **/ + void on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectsymbol-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index f98b8767..c5d8ef5b 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -71,6 +71,12 @@ namespace xo { void on_colon_token(const Token & tk, ParserStateMachine * p_psm); + /** operate state machine for this syntax on incoming singleassign-token @p tk + * with overall parser state in @p p_psm + **/ + void on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm); + /** (Never called). * Operate state machine for this syntax after symbol * emitted from nested ssm. diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 942afedd..01fdfc16 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -85,6 +85,11 @@ namespace xo { **/ void on_colon_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming single-assign token @p tk, + * overall parser state in @p p_psm + **/ + void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on parsed symbol @p sym * from immediately-downstream ssm. * overall parser state in @p p_psm diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index e17ff39d..bcd8f557 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -116,6 +116,9 @@ namespace xo { /** operate state machine for incoming colon-token @p tk **/ void on_colon_token(const Token & tk); + /** operate state machine for incoming singleassign-token @p tk **/ + void on_singleassign_token(const Token & tk); + ///@} /** @defgroup scm-parserstatemachine-error-entrypoints error entry points **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index 6aefa1f7..f8f23f2a 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -65,6 +65,8 @@ public: virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming colon-token @p tk **/ virtual void on_colon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming singleassign-token @p tk **/ + virtual void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update stat machine for incoming parsed symbol @p sym **/ virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 1a6705d2..51e5cff0 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -64,6 +64,7 @@ namespace scm { [[noreturn]] void on_def_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_colon_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_singleassign_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index 65627a03..dd2bdc29 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming colon-token @p tk **/ static void on_colon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming singleassign-token @p tk **/ + static void on_singleassign_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 91ff08b6..114208f6 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming colon-token @p tk **/ static void on_colon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming singleassign-token @p tk **/ + static void on_singleassign_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 64622261..7bf0d312 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_if_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming colon-token @p tk **/ static void on_colon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming singleassign-token @p tk **/ + static void on_singleassign_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 64fd4ed7..73e8a1cc 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming colon-token @p tk **/ static void on_colon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming singleassign-token @p tk **/ + static void on_singleassign_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 7b2c721f..d86e9763 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -64,6 +64,9 @@ namespace scm { void on_colon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_colon_token(_dcast(data), tk, p_psm); } + void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_singleassign_token(_dcast(data), tk, p_psm); + } void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { return I::on_parsed_symbol(_dcast(data), sym, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 4a63e377..921da301 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -68,6 +68,9 @@ public: void on_colon_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_colon_token(O::data(), tk, p_psm); } + void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_singleassign_token(O::data(), tk, p_psm); + } void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); } diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 21435a83..78667376 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -543,6 +543,28 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(true), xtag("defstate", defstate_)); + + if ((defstate_ == defexprstatetype::def_2) + || (defstate_ == defexprstatetype::def_4)) + { + this->defstate_ = defexprstatetype::def_5; + + // TODO: DExpectExprSsm::start(...) + log && log("STUB: DExpectExprSsm not implemented"); + + return; + } + + p_psm->illegal_input_on_token("DDefineSsm::on_singleassign_token", + tk, + this->get_expect_str()); + } + bool DDefineSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 877c6a50..e9b93cc5 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -122,6 +122,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_singleassign_token", + tk, + this->get_expect_str()); + } + bool DExpectSymbolSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 62ccdf22..b40916a9 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -83,6 +83,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectTypeSsm::on_singleassign_token", + tk, + this->get_expect_str()); + } + void DExpectTypeSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 6f9d877a..75e711cd 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -169,6 +169,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExprSeqState::on_singleassign_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 24775dfd..fb9e7a53 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -58,6 +58,12 @@ ISyntaxStateMachine_Any::on_colon_token(Opaque, const Token &, ParserStateMachin _fatal(); } +auto +ISyntaxStateMachine_Any::on_singleassign_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 8cc9c858..ae2d6601 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_colon_token(tk, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_singleassign_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_singleassign_token(tk, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index e4716ef8..5eb40180 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_colon_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_singleassign_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_singleassign_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 893cb0dd..d8621b20 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_colon_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_singleassign_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_singleassign_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 911e825e..d81e066c 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_colon_token(tk, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_singleassign_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_singleassign_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 79f23eb5..b74de542 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -153,6 +153,10 @@ namespace xo { this->on_colon_token(tk); break; + case tokentype::tk_singleassign: + this->on_singleassign_token(tk); + break; + // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_bool: @@ -173,7 +177,6 @@ namespace xo { case tokentype::tk_comma: case tokentype::tk_doublecolon: case tokentype::tk_semicolon: - case tokentype::tk_singleassign: case tokentype::tk_assign: case tokentype::tk_yields: case tokentype::tk_plus: @@ -229,6 +232,14 @@ namespace xo { stack_->top().on_colon_token(tk, this); } + void + ParserStateMachine::on_singleassign_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_singleassign_token(tk, this); + } + void ParserStateMachine::capture_error(std::string_view ssm_name, const DString * errmsg) diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index fc448106..d47b311d 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -101,7 +101,7 @@ namespace xo { static Token rightbracket() { return Token(tokentype::tk_rightbracket); } /** token representing left brace @c "{" **/ static Token leftbrace() { return Token(tokentype::tk_leftbrace); } - /** token representing right brace @c "}' **/ + /** token representing right brace @c "}" **/ static Token rightbrace() { return Token(tokentype::tk_rightbrace); } /** token representing period @c "." **/ static Token dot() { return Token(tokentype::tk_dot); } @@ -113,8 +113,8 @@ namespace xo { static Token doublecolon() { return Token(tokentype::tk_doublecolon); } /** token representing semicolon @c ";" **/ static Token semicolon() { return Token(tokentype::tk_semicolon); } - /** token representing single-assignment @c "=" **/ - static Token singleassign() { return Token(tokentype::tk_singleassign); } + /** token representing single-assignment @c "=" (editor bait: equal_token) **/ + static Token singleassign_token() { return Token(tokentype::tk_singleassign); } /** token representing unrestricted assignment @c ":=" **/ static Token assign_token() { return Token(tokentype::tk_assign); } /** token representing indirection @c "->" **/ From 8189197d63fd5fde4a17fc90bd0817c73b40ef6f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 21 Jan 2026 17:35:01 -0500 Subject: [PATCH 041/258] xo-reader2: DefineSsm: respond to = token --- xo-facet/include/xo/facet/obj.hpp | 7 +++- xo-reader2/include/xo/reader2/DDefineSsm.hpp | 7 ++++ .../include/xo/reader2/ParserStateMachine.hpp | 3 ++ .../include/xo/reader2/SchematikaParser.hpp | 16 +++++++++ xo-reader2/src/reader2/CMakeLists.txt | 1 + xo-reader2/src/reader2/ParserStateMachine.cpp | 6 ++++ xo-reader2/src/reader2/SchematikaParser.cpp | 18 +++++++--- xo-reader2/src/reader2/syntaxstatetype.cpp | 34 +++++++++++++++++++ xo-reader2/utest/SchematikaParser.test.cpp | 24 +++++++++++++ 9 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 xo-reader2/src/reader2/syntaxstatetype.cpp diff --git a/xo-facet/include/xo/facet/obj.hpp b/xo-facet/include/xo/facet/obj.hpp index b50bf65e..3983cecf 100644 --- a/xo-facet/include/xo/facet/obj.hpp +++ b/xo-facet/include/xo/facet/obj.hpp @@ -103,7 +103,12 @@ namespace xo { return *this; } - /** safe downcast from variant. null if downcast fails **/ + /** safe downcast from variant. null if downcast fails + * + * Use: + * obj x = ...; + * obj quux = obj::from(x); + **/ static obj from(const OObject & other) { return obj(other.template downcast()); } diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 5308f77a..ed17a1b2 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -98,6 +98,13 @@ namespace xo { obj expr_mm, ParserStateMachine * p_psm); + ///@} + /** @defgroup scm-definessm-access-methods **/ + ///@{ + + /** identify define-expression state **/ + defexprstatetype defstate() const noexcept { return defstate_; } + ///@} /** @defgroup scm-define-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index bcd8f557..7e3bcabb 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -54,6 +54,9 @@ namespace xo { /** true iff state machine currently has incomplete expression **/ bool has_incomplete_expr() const noexcept; + /** top of parser stack **/ + obj top_ssm() const; + ///@} /** @defgroup scm-parserstatemachine-bookkeeping bookkeeping methods **/ diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 300980fb..aecc3c9a 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -172,6 +172,9 @@ namespace xo { obj expr_alloc, bool debug_flag); + /** scm-schematikaparser-access-methods **/ + ///@{ + bool debug_flag() const { return debug_flag_; } /** true if parser is at top-level, @@ -185,6 +188,13 @@ namespace xo { **/ bool has_incomplete_expr() const; + /** top of parser stack **/ + obj top_ssm() const; + + ///@} + /** scm-schematikaparser-general-methods **/ + ///@{ + /** put parser into state for beginning an interactive session. **/ void begin_interactive_session(); @@ -215,11 +225,17 @@ namespace xo { **/ void reset_to_idle_toplevel(); + ///@} + /** scm-schematikaparser-pretty-methods **/ + ///@{ + /** print human-readable representation on stream @p os **/ void print(std::ostream & os) const; /** pretty-printer support **/ bool pretty(const ppindentinfo & ppii) const; + ///@} + private: /** state machine **/ ParserStateMachine psm_; diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index b09f015a..5ce73d67 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -9,6 +9,7 @@ set(SELF_SRCS ParserStack.cpp ParserResult.cpp + syntaxstatetype.cpp ISyntaxStateMachine_Any.cpp DExprSeqState.cpp diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index b74de542..dbed93d9 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -42,6 +42,12 @@ namespace xo { return !(this->is_at_toplevel()); } + obj + ParserStateMachine::top_ssm() const + { + return this->stack_->top(); + } + void ParserStateMachine::establish_toplevel_ssm(obj ssm) { diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index d243de51..fea573c7 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -28,23 +28,33 @@ namespace xo { } bool - SchematikaParser::is_at_toplevel() const { + SchematikaParser::is_at_toplevel() const + { return psm_.is_at_toplevel(); } bool - SchematikaParser::has_incomplete_expr() const { + SchematikaParser::has_incomplete_expr() const + { return !(this->is_at_toplevel()); } + obj + SchematikaParser::top_ssm() const + { + return psm_.top_ssm(); + } + void - SchematikaParser::begin_interactive_session() { + SchematikaParser::begin_interactive_session() + { DExprSeqState::establish_interactive(psm_.expr_alloc(), &psm_); } void - SchematikaParser::begin_batch_session() { + SchematikaParser::begin_batch_session() + { DExprSeqState::establish_batch(psm_.expr_alloc(), &psm_); } diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp new file mode 100644 index 00000000..cf8a9784 --- /dev/null +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -0,0 +1,34 @@ +/** @file syntaxstatetype.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "syntaxstatetype.hpp" + +namespace xo { + namespace scm { + + const char * + syntaxstatetype_descr(syntaxstatetype x) { + switch (x) { + case syntaxstatetype::invalid: + break; + case syntaxstatetype::expect_toplevel_expression_sequence: + return "expect-toplevel-expression-sequence"; + case syntaxstatetype::expect_symbol: + return "expect-symbol"; + case syntaxstatetype::expect_type: + return "expect-type"; + case syntaxstatetype::defexpr: + return "defexpr"; + case syntaxstatetype::N: + break; + } + + return "syntaxstatetype?"; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end syntaxstatetype.cpp */ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index af9b8303..203f2eaa 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -4,12 +4,18 @@ **/ #include +#include +#include #include #include #include namespace xo { using xo::scm::SchematikaParser; + using xo::scm::ASyntaxStateMachine; + using xo::scm::syntaxstatetype; + using xo::scm::DDefineSsm; + using xo::scm::defexprstatetype; using xo::scm::ParserResult; using xo::scm::parser_result_type; using xo::scm::Token; @@ -134,6 +140,24 @@ namespace xo { log && log(xtag("result", result)); } + { + auto & result = parser.on_token(Token::singleassign_token()); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(result.is_incomplete()); + + log && log("after typename symbol token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + auto def_ssm + = obj::from(parser.top_ssm()); + + REQUIRE(def_ssm); + REQUIRE(def_ssm.data()->ssm_type() == syntaxstatetype::defexpr); + REQUIRE(def_ssm.data()->defstate() == defexprstatetype::def_5); + } + // define-expressions not properly implemented //REQUIRE(result.error_description()); From b84447e4f81d58084cd45890a3d1937f4b97f098 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 21 Jan 2026 18:39:53 -0500 Subject: [PATCH 042/258] xo-reader2: skeleton DExpectExprSsm.* --- .../include/xo/reader2/DExpectExprSsm.hpp | 113 +++++++ xo-reader2/src/reader2/CMakeLists.txt | 2 + xo-reader2/src/reader2/DExpectExprSsm.cpp | 301 ++++++++++++++++++ 3 files changed, 416 insertions(+) create mode 100644 xo-reader2/include/xo/reader2/DExpectExprSsm.hpp create mode 100644 xo-reader2/src/reader2/DExpectExprSsm.cpp diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp new file mode 100644 index 00000000..788f04e8 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -0,0 +1,113 @@ +/** @file DExpectExprSsm.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +//#include +#include +#include + +namespace xo { + namespace scm { + + class DExpectExprSsm { + public: + using TypeDescr = xo::reflect::TypeDescr; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + explicit DExpectExprSsm(bool allow_defs, + bool cxl_on_rightparen); + + static DExpectExprSsm * make(DArena & parser_mm, + bool allow_defs, + bool cxl_on_rightparen); + + static void start(DArena & parser_mm, + bool allow_defs, + bool cxl_on_rightparen, + ParserStateMachine * p_psm); + + /** @defgroup scm-expectexpr-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error mesages + **/ + std::string_view get_expect_str() const noexcept; + + /** operate state machine for this syntax on incoming symbol-token @p tk + * with overall parser state in @p p_psm + **/ + void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_def_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming colon token @p tk, + * overall parser state in @p p_psm + **/ + void on_colon_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming singleassign token @p tk, + * overall parser state in @p p_psm + **/ + void on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a symbol @p sym; + * overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a type-description @p td, + * overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-define-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** if true: allow a define-expression here; otherwise reject **/ + bool allow_defs_ = false; + /** if true: expecting either: + * 1a. expression + * 1b. right brace '}', in which case no expression + * if false: expecting only: + * 2a. expression + **/ + bool cxl_on_rightbrace_ = false; + + + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectExprSsm.hpp */ diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 5ce73d67..661aae2e 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -28,6 +28,8 @@ set(SELF_SRCS ISyntaxStateMachine_DExpectTypeSsm.cpp IPrintable_DExpectTypeSsm.cpp + DExpectExprSsm.cpp + reader2_register_facets.cpp reader2_register_types.cpp ) diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp new file mode 100644 index 00000000..696aa790 --- /dev/null +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -0,0 +1,301 @@ +/** @file DExpectExprSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DExpectExprSsm.hpp" +#include "ParserStateMachine.hpp" + +#ifdef NOT_YET +#include "exprstatestack.hpp" +#include "define_xs.hpp" +#include "lambda_xs.hpp" +#include "if_else_xs.hpp" +#include "paren_xs.hpp" +#include "sequence_xs.hpp" +#include "progress_xs.hpp" +#include "xo/expression/Lambda.hpp" +#include "xo/expression/Constant.hpp" +#include "xo/expression/pretty_expression.hpp" +#endif + +namespace xo { +#ifdef NOT_YET + using xo::scm::Constant; +#endif + + namespace scm { + +#ifdef NOT_YET + std::unique_ptr + expect_expr_xs::make(bool allow_defs, + bool cxl_on_rightbrace) + { + return std::make_unique(expect_expr_xs(allow_defs, + cxl_on_rightbrace)); + + } + + void + expect_expr_xs::start(bool allow_defs, + bool cxl_on_rightbrace, + parserstatemachine * p_psm) + { + p_psm->push_exprstate(expect_expr_xs::make(allow_defs, + cxl_on_rightbrace)); + } + + void + expect_expr_xs::start(parserstatemachine * p_psm) { + start(false /*!allow_defs*/, + false /*!cxl_on_rightbrace*/, + p_psm); + } + + expect_expr_xs::expect_expr_xs(bool allow_defs, + bool cxl_on_rightbrace) + : exprstate(exprstatetype::expect_rhs_expression), + allow_defs_{allow_defs}, + cxl_on_rightbrace_{cxl_on_rightbrace} + {} + + const char * + expect_expr_xs::get_expect_str() const + { + if (allow_defs_) { + return "def|lambda|lparen|lbrace|literal|var"; + } else { + return "lambda|lparen|lbrace|literal|var"; + } + } + + void + expect_expr_xs::on_def_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + if (allow_defs_) { + define_xs::start(p_psm); + } else { + exprstate::on_def_token(tk, p_psm); + } + } + + void + expect_expr_xs::on_lambda_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + //constexpr const char * self_name = "exprstate::on_leftparen"; + + lambda_xs::start(p_psm); + } + + void + expect_expr_xs::on_if_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + if_else_xs::start(p_psm); + } + + void + expect_expr_xs::on_leftparen_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + //constexpr const char * self_name = "exprstate::on_leftparen"; + + /* push lparen_0 to remember to look for subsequent rightparen. */ + paren_xs::start(p_psm); + } + + void + expect_expr_xs::on_leftbrace_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + /* push lparen_0 to remember to look for subsequent rightparen. */ + sequence_xs::start(p_psm); + } + + void + expect_expr_xs::on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + if (cxl_on_rightbrace_) { + auto self = p_psm->pop_exprstate(); + + /* do not call .on_expr(), since '}' cancelled */ + + p_psm->on_rightbrace_token(tk); + } else { + exprstate::on_rightbrace_token(tk, p_psm); + } + } + + void + expect_expr_xs::on_symbol_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("tk", tk)); + + constexpr const char * c_self_name = "expect_expr_xs::on_symbol_token"; + + /* various possibilities when looking for rhs expression: + * + * x := y // (1) + * x := f(a) // (2) + * x := f(a,b) // (3) + * + * need lookahead token following symbol to distinguish + * between (1) (symbol completes rhs expression) + * and {(2), (3)} (symbol is function call) + */ + + bp var = p_psm->lookup_var(tk.text()); + + if (!var) { + this->unknown_variable_error(c_self_name, tk, p_psm); + return; + } + + /* e.g. + * def pi = 3.14159265; + * def mypi = pi; + * ^ + * def pi2 = pi * 2; + * ^ + * def y = foo(pi2); + * ^ + */ + progress_xs::start(var.promote(), p_psm); + + #ifdef NOT_YET + p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, + Variable::make(name, type))); +#endif + +#ifdef LATER + p_psm->pop_exprstate(); + p_psm->top_exprstate().on_symbol(tk.text(), + p_stack, p_emit_expr); +#endif + return; + } + + void + expect_expr_xs::on_bool_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + progress_xs::start + (Constant::make(tk.bool_value()), + p_psm); + } + + void + expect_expr_xs::on_i64_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), + xtag("tk", tk), + xtag("do", "push progress xs w/ tk value")); + + progress_xs::start + (Constant::make(tk.i64_value()), + p_psm); + } + + void + expect_expr_xs::on_f64_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + //constexpr const char * self_name = "exprstate::on_f64_token"; + + /* e.g. + * def pi = 3.14159265; + * \---tk---/ + */ + progress_xs::start + (Constant::make(tk.f64_value()), + p_psm); + } + + void + expect_expr_xs::on_string_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + /* e.g. + * def msg = "hello, world"; + * \----tk----/ + */ + progress_xs::start + (Constant::make(tk.text()), + p_psm); + } + + void + expect_expr_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr.promote())); + log && log("pop expect_expr_xs, forward to parent"); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr(expr); + } /*on_expr*/ + + void + expect_expr_xs::on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr.promote())); + log && log("pop expect_expr_xs, forward to parent"); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr_with_semicolon(expr); + } /*on_expr_with_semicolon*/ + + void + expect_expr_xs::print(std::ostream & os) const { + os << ""; + } + + bool + expect_expr_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, "expect_expr_xs", + refrtag("allow_defs", allow_defs_), + refrtag("cxl_on_rightbrace", cxl_on_rightbrace_)); + } +#endif + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectExprSsm.cpp */ From 8b148285b1881eb2165340684dc0257afa8b2b6d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 10:54:36 -0500 Subject: [PATCH 043/258] xo-reader2: + DExpectExprSsm + use from DDefineSsm --- xo-reader2/CMakeLists.txt | 26 ++++ .../idl/IPrintable_DExpectExprSsm.json5 | 13 ++ .../ISyntaxStateMachine_DExpectExprSsm.json5 | 13 ++ .../include/xo/reader2/DExpectExprSsm.hpp | 9 ++ .../reader2/ssm/IPrintable_DExpectExprSsm.hpp | 62 ++++++++ .../ISyntaxStateMachine_DExpectExprSsm.hpp | 77 ++++++++++ .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 2 + xo-reader2/src/reader2/DDefineSsm.cpp | 6 +- xo-reader2/src/reader2/DExpectExprSsm.cpp | 137 +++++++++++++++--- .../src/reader2/IPrintable_DExpectExprSsm.cpp | 28 ++++ .../ISyntaxStateMachine_DExpectExprSsm.cpp | 69 +++++++++ .../src/reader2/reader2_register_facets.cpp | 7 + xo-reader2/src/reader2/syntaxstatetype.cpp | 2 + xo-reader2/utest/SchematikaParser.test.cpp | 35 ++++- 15 files changed, 465 insertions(+), 24 deletions(-) create mode 100644 xo-reader2/idl/IPrintable_DExpectExprSsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectExprSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp create mode 100644 xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index d8c82e1d..11ce1f07 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -138,6 +138,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectexprssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExpectExprSsm + INPUT idl/ISyntaxStateMachine_DExpectExprSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectexprssm + FACET_PKG xo_printable2 + FACET Printable + REPR ExpectExprSsm + INPUT idl/IPrintable_DExpectExprSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-reader2-genfacet-all) # ---------------------------------------------------------------- diff --git a/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 b/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 new file mode 100644 index 00000000..72d19cd7 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectExprSsm", + using_doxygen: true, + repr: "DExpectExprSsm", + doc: [ "implement APrintable for DExpectExprSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 new file mode 100644 index 00000000..068ac481 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectExprSsm", + using_doxygen: true, + repr: "DExpectExprSsm", + doc: [ "implement ASyntaxStateMachine for DExpectExprSsm" ], +} \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 788f04e8..07456d76 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -32,7 +32,16 @@ namespace xo { bool allow_defs, bool cxl_on_rightparen, ParserStateMachine * p_psm); + static void start(DArena & parser_mm, + ParserStateMachine * p_psm); + /** @defgroup scm-expectexpr-access-methods access methods **/ + ///@{ + + bool allow_defs() const noexcept { return allow_defs_; } + bool cxl_on_rightbrace() const noexcept { return cxl_on_rightbrace_; } + + ///@} /** @defgroup scm-expectexpr-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectExprSsm.hpp new file mode 100644 index 00000000..c3f9abc0 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectExprSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectExprSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectExprSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectExprSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectExprSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectExprSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectExprSsm + **/ + class IPrintable_DExpectExprSsm { + public: + /** @defgroup scm-printable-dexpectexprssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectexprssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectExprSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp new file mode 100644 index 00000000..5921f615 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -0,0 +1,77 @@ +/** @file ISyntaxStateMachine_DExpectExprSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectExprSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectExprSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectExprSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectExprSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectExprSsm + **/ + class ISyntaxStateMachine_DExpectExprSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectexprssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectexprssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectExprSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectExprSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming if-keyword-token @p tk **/ + static void on_if_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming colon-token @p tk **/ + static void on_colon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming singleassign-token @p tk **/ + static void on_singleassign_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 8cb48938..312ec07c 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -27,6 +27,9 @@ namespace xo { /** expecting a type. See @ref DExpectTypeSsm **/ expect_type, + /** expecting a rhs expression. See @ref DExpectExprSsm **/ + expect_rhs_expression, + /** handle define-expression. See @ref DDefineSsm **/ defexpr, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 661aae2e..ecf8f297 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -29,6 +29,8 @@ set(SELF_SRCS IPrintable_DExpectTypeSsm.cpp DExpectExprSsm.cpp + ISyntaxStateMachine_DExpectExprSsm.cpp + IPrintable_DExpectExprSsm.cpp reader2_register_facets.cpp reader2_register_types.cpp diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 78667376..ea0d976a 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -6,6 +6,7 @@ #include "DDefineSsm.hpp" #include "DExpectSymbolSsm.hpp" #include "DExpectTypeSsm.hpp" +#include "DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" #include "ssm/IPrintable_DDefineSsm.hpp" #include @@ -554,9 +555,8 @@ namespace xo { { this->defstate_ = defexprstatetype::def_5; - // TODO: DExpectExprSsm::start(...) - log && log("STUB: DExpectExprSsm not implemented"); - + DExpectExprSsm::start(p_psm->parser_alloc(), + p_psm); return; } diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 696aa790..235f4b19 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -5,6 +5,10 @@ #include "DExpectExprSsm.hpp" #include "ParserStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" +#include "syntaxstatetype.hpp" +#include #ifdef NOT_YET #include "exprstatestack.hpp" @@ -24,43 +28,64 @@ namespace xo { using xo::scm::Constant; #endif + using xo::reflect::typeseq; + using xo::facet::with_facet; + namespace scm { -#ifdef NOT_YET - std::unique_ptr - expect_expr_xs::make(bool allow_defs, + DExpectExprSsm::DExpectExprSsm(bool allow_defs, + bool cxl_on_rightbrace) + : allow_defs_{allow_defs}, + cxl_on_rightbrace_{cxl_on_rightbrace} + { + } + + DExpectExprSsm * + DExpectExprSsm::make(DArena & mm, + bool allow_defs, bool cxl_on_rightbrace) { - return std::make_unique(expect_expr_xs(allow_defs, - cxl_on_rightbrace)); + void * mem = mm.alloc(typeseq::id(), + sizeof(DExpectExprSsm)); + return new (mem) DExpectExprSsm(allow_defs, + cxl_on_rightbrace); } void - expect_expr_xs::start(bool allow_defs, + DExpectExprSsm::start(DArena & mm, + bool allow_defs, bool cxl_on_rightbrace, - parserstatemachine * p_psm) + ParserStateMachine * p_psm) { - p_psm->push_exprstate(expect_expr_xs::make(allow_defs, - cxl_on_rightbrace)); + DExpectExprSsm * exp_expr + = DExpectExprSsm::make(mm, + allow_defs, + cxl_on_rightbrace); + obj ssm + = with_facet::mkobj(exp_expr); + + p_psm->push_ssm(ssm); } void - expect_expr_xs::start(parserstatemachine * p_psm) { - start(false /*!allow_defs*/, + DExpectExprSsm::start(DArena & mm, + ParserStateMachine * p_psm) + { + start(mm, + false /*!allow_defs*/, false /*!cxl_on_rightbrace*/, p_psm); } - expect_expr_xs::expect_expr_xs(bool allow_defs, - bool cxl_on_rightbrace) - : exprstate(exprstatetype::expect_rhs_expression), - allow_defs_{allow_defs}, - cxl_on_rightbrace_{cxl_on_rightbrace} - {} + syntaxstatetype + DExpectExprSsm::ssm_type() const noexcept + { + return syntaxstatetype::expect_rhs_expression; + } - const char * - expect_expr_xs::get_expect_str() const + std::string_view + DExpectExprSsm::get_expect_str() const noexcept { if (allow_defs_) { return "def|lambda|lparen|lbrace|literal|var"; @@ -69,6 +94,80 @@ namespace xo { } } + void + DExpectExprSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm", + tk, + this->get_expect_str()); + } + + void + DExpectExprSsm::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm", + tk, + this->get_expect_str()); + } + + void + DExpectExprSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm", + tk, + this->get_expect_str()); + } + + void + DExpectExprSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm", + tk, + this->get_expect_str()); + } + + void + DExpectExprSsm::on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm", + tk, + this->get_expect_str()); + } + + void + DExpectExprSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExpectExprSsm", + sym, + this->get_expect_str()); + } + + void + DExpectExprSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DExpectExprSsm", + td, + this->get_expect_str()); + } + + bool + DExpectExprSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DExpectExprSsm", + refrtag("allow_defs", allow_defs_), + refrtag("cxl_on_rightbrace", cxl_on_rightbrace_)); + } + +#ifdef NOT_YET void expect_expr_xs::on_def_token(const token_type & tk, parserstatemachine * p_psm) diff --git a/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp new file mode 100644 index 00000000..2b656fb2 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectExprSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectExprSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectExprSsm.json5] +**/ + +#include "ssm/IPrintable_DExpectExprSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectExprSsm::pretty(const DExpectExprSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectExprSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp new file mode 100644 index 00000000..de751479 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -0,0 +1,69 @@ +/** @file ISyntaxStateMachine_DExpectExprSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectExprSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectExprSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectExprSsm::ssm_type(const DExpectExprSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectExprSsm::get_expect_str(const DExpectExprSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectExprSsm::on_symbol_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_symbol_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_def_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_def_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_if_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_if_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_colon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_colon_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_singleassign_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_singleassign_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectExprSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index a393eead..cdade07b 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -17,6 +17,9 @@ #include #include +#include +#include + #include #include #include @@ -45,10 +48,14 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); log && log(xtag("DExpectSymbolSsm.tseq", typeseq::id())); log && log(xtag("DExpectTypeSsm.tseq", typeseq::id())); + log && log(xtag("DExpectExprSsm.tseq", typeseq::id())); return true; } diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index cf8a9784..ac09b92e 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -19,6 +19,8 @@ namespace xo { return "expect-symbol"; case syntaxstatetype::expect_type: return "expect-type"; + case syntaxstatetype::expect_rhs_expression: + return "expect-rhs-expression"; case syntaxstatetype::defexpr: return "defexpr"; case syntaxstatetype::N: diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 203f2eaa..e0f813e4 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include #include @@ -15,10 +17,12 @@ namespace xo { using xo::scm::ASyntaxStateMachine; using xo::scm::syntaxstatetype; using xo::scm::DDefineSsm; + using xo::scm::DExpectExprSsm; using xo::scm::defexprstatetype; - using xo::scm::ParserResult; - using xo::scm::parser_result_type; + //using xo::scm::ParserResult; + //using xo::scm::parser_result_type; using xo::scm::Token; + using xo::scm::DString; using xo::mm::ArenaConfig; using xo::mm::AAllocator; using xo::mm::DArena; @@ -150,12 +154,39 @@ namespace xo { log && log(xtag("parser", &parser)); log && log(xtag("result", result)); + auto exp_ssm + = obj::from(parser.top_ssm()); + + REQUIRE(exp_ssm); + REQUIRE(exp_ssm.data()->ssm_type() == syntaxstatetype::expect_rhs_expression); + REQUIRE(exp_ssm.data()->allow_defs() == false); + REQUIRE(exp_ssm.data()->cxl_on_rightbrace() == false); + } + +#ifdef NOT_YET + { + // future-proofing for Token only holding a string_view + const DString * str = DString::from_cstr(expr_alloc, "3.141593"); + + auto & result = parser.on_token(Token::f64_token(std::string(*str))); + + REQUIRE(parser.has_incomplete_expr() == true); + + log && log("after typename symbol token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + } +#endif + + { +#ifdef NOT_YET auto def_ssm = obj::from(parser.top_ssm()); REQUIRE(def_ssm); REQUIRE(def_ssm.data()->ssm_type() == syntaxstatetype::defexpr); REQUIRE(def_ssm.data()->defstate() == defexprstatetype::def_5); +#endif } // define-expressions not properly implemented From 5bd78b8f4e8006c2e1b1bea1adc98829e400b0b8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 15:18:35 -0500 Subject: [PATCH 044/258] xo-reader2: + on_f64_token() + handle in DDefineSsm+DProgressSsm --- xo-expression2/CMakeLists.txt | 4 + .../include/xo/expression2/DConstant.hpp | 8 + .../include/xo/expression2/Expression.hpp | 2 +- .../include/xo/expression2/SymbolTable.hpp | 2 +- .../xo/expression2/detail/AExpression.hpp | 2 +- .../xo/expression2/detail/IExpression_Any.hpp | 2 +- .../{ => detail}/IExpression_DConstant.hpp | 5 +- .../detail/IExpression_DVariable.hpp | 6 +- .../expression2/detail/IExpression_Xfer.hpp | 2 +- .../xo/expression2/detail/RExpression.hpp | 2 +- .../xo/expression2/symtab/ASymbolTable.hpp | 2 +- .../expression2/symtab/ISymbolTable_Any.hpp | 2 +- .../expression2/symtab/ISymbolTable_Xfer.hpp | 2 +- .../xo/expression2/symtab/RSymbolTable.hpp | 2 +- xo-expression2/src/expression2/DConstant.cpp | 10 + .../src/expression2/IExpression_DConstant.cpp | 2 +- .../src/expression2/IExpression_DVariable.cpp | 2 +- .../interpreter2/VirtualSchematikaMachine.cpp | 2 +- xo-reader2/CMakeLists.txt | 26 + xo-reader2/idl/IPrintable_DProgressSsm.json5 | 13 + .../ISyntaxStateMachine_DProgressSsm.json5 | 13 + xo-reader2/idl/SyntaxStateMachine.json5 | 9 + xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 + .../include/xo/reader2/DExpectExprSsm.hpp | 6 + .../include/xo/reader2/DExpectSymbolSsm.hpp | 6 + .../include/xo/reader2/DExpectTypeSsm.hpp | 6 + .../include/xo/reader2/DExprSeqState.hpp | 5 + .../include/xo/reader2/DProgressSsm.hpp | 220 +++++ .../include/xo/reader2/ParserStateMachine.hpp | 3 + .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 + .../reader2/ssm/IPrintable_DExpectExprSsm.hpp | 2 +- .../reader2/ssm/IPrintable_DProgressSsm.hpp | 62 ++ .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectExprSsm.hpp | 4 +- .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 + .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 79 ++ .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 + .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 + .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 4 + xo-reader2/src/reader2/DDefineSsm.cpp | 9 + xo-reader2/src/reader2/DExpectExprSsm.cpp | 31 + xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 + xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 + xo-reader2/src/reader2/DExprSeqState.cpp | 9 + xo-reader2/src/reader2/DProgressSsm.cpp | 932 ++++++++++++++++++ .../src/reader2/IPrintable_DExpectExprSsm.cpp | 2 +- .../src/reader2/IPrintable_DProgressSsm.cpp | 28 + .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 + .../ISyntaxStateMachine_DDefineSsm.cpp | 5 + .../ISyntaxStateMachine_DExpectExprSsm.cpp | 7 +- .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 + .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 + .../ISyntaxStateMachine_DExprSeqState.cpp | 5 + .../ISyntaxStateMachine_DProgressSsm.cpp | 74 ++ xo-reader2/src/reader2/ParserStateMachine.cpp | 13 +- .../src/reader2/reader2_register_facets.cpp | 7 + xo-reader2/src/reader2/syntaxstatetype.cpp | 2 + xo-reader2/utest/SchematikaParser.test.cpp | 4 +- 62 files changed, 1680 insertions(+), 25 deletions(-) rename xo-expression2/include/xo/expression2/{ => detail}/IExpression_DConstant.hpp (91%) create mode 100644 xo-reader2/idl/IPrintable_DProgressSsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/DProgressSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DProgressSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp create mode 100644 xo-reader2/src/reader2/DProgressSsm.cpp create mode 100644 xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 3de04758..f286f2ad 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -134,6 +134,10 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# ---------------------------------------------------------------- + +xo_add_genfacet_all(xo-expression2-genfacet-all) + # ---------------------------------------------------------------- # shared library diff --git a/xo-expression2/include/xo/expression2/DConstant.hpp b/xo-expression2/include/xo/expression2/DConstant.hpp index 9d2014b9..a73ea2df 100644 --- a/xo-expression2/include/xo/expression2/DConstant.hpp +++ b/xo-expression2/include/xo/expression2/DConstant.hpp @@ -19,12 +19,20 @@ namespace xo { public: using TaggedPtr = xo::reflect::TaggedPtr; using TypeDescr = xo::reflect::TypeDescr; + using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using typeseq = xo::reflect::typeseq; public: explicit DConstant(obj value) noexcept; + /** create instance + * @p mm memory allocator + * @p value literal constant + **/ + static DConstant * make(obj mm, + obj value); + bool is_resolved() const noexcept { return typeref_.is_resolved(); } exprtype extype() const noexcept { return exprtype::constant; } diff --git a/xo-expression2/include/xo/expression2/Expression.hpp b/xo-expression2/include/xo/expression2/Expression.hpp index 60e8a402..df4161a1 100644 --- a/xo-expression2/include/xo/expression2/Expression.hpp +++ b/xo-expression2/include/xo/expression2/Expression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/SymbolTable.hpp b/xo-expression2/include/xo/expression2/SymbolTable.hpp index 09fc04a8..26576ed6 100644 --- a/xo-expression2/include/xo/expression2/SymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/SymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/AExpression.hpp b/xo-expression2/include/xo/expression2/detail/AExpression.hpp index 10375114..e080ece8 100644 --- a/xo-expression2/include/xo/expression2/detail/AExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/AExpression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp index c92c2c4a..17545afb 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/IExpression_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp similarity index 91% rename from xo-expression2/include/xo/expression2/IExpression_DConstant.hpp rename to xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp index b08d8814..61b92e12 100644 --- a/xo-expression2/include/xo/expression2/IExpression_DConstant.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp @@ -6,13 +6,14 @@ * arguments: * --input [idl/IExpression_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: - * [iface_facet_any.hpp.j2] + * [iface_facet_repr.hpp.j2] * 3. idl for facet methods * [idl/IExpression_DConstant.json5] **/ #pragma once +#include "Expression.hpp" #include "Expression.hpp" #include "DConstant.hpp" @@ -40,6 +41,8 @@ namespace xo { /** @defgroup scm-expression-dconstant-type-traits **/ ///@{ using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; ///@} /** @defgroup scm-expression-dconstant-methods **/ ///@{ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp index b4186f55..6b9b702f 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -55,7 +55,7 @@ namespace xo { static TypeDescr valuetype(const DVariable & self) noexcept; // non-const methods - /** assign to valuetype member. Useful when scaffolding expressions **/ + /** assing to valuetype member. Useful when scaffolding expressions **/ static void assign_valuetype(DVariable & self, TypeDescr td) noexcept; ///@} }; @@ -63,4 +63,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end */ +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp index 9f7356bc..fac8c541 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/RExpression.hpp b/xo-expression2/include/xo/expression2/detail/RExpression.hpp index caf69fe0..4d717640 100644 --- a/xo-expression2/include/xo/expression2/detail/RExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/RExpression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp index 36d4c812..f0c6e10f 100644 --- a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp index 6a119832..b642adb7 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp index 2333bb05..3d5f7221 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp index c72503cc..600ea4f8 100644 --- a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/DConstant.cpp b/xo-expression2/src/expression2/DConstant.cpp index fcb38f54..5bf98bfc 100644 --- a/xo-expression2/src/expression2/DConstant.cpp +++ b/xo-expression2/src/expression2/DConstant.cpp @@ -34,6 +34,16 @@ namespace xo { } } + DConstant * + DConstant::make(obj mm, + obj value) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DConstant)); + + return new (mem) DConstant(value); + } + TypeDescr DConstant::_lookup_td(typeseq tseq) { diff --git a/xo-expression2/src/expression2/IExpression_DConstant.cpp b/xo-expression2/src/expression2/IExpression_DConstant.cpp index 39f8135c..2d39c36d 100644 --- a/xo-expression2/src/expression2/IExpression_DConstant.cpp +++ b/xo-expression2/src/expression2/IExpression_DConstant.cpp @@ -11,7 +11,7 @@ * [idl/IExpression_DConstant.json5] **/ -#include "IExpression_DConstant.hpp" +#include "detail/IExpression_DConstant.hpp" namespace xo { namespace scm { diff --git a/xo-expression2/src/expression2/IExpression_DVariable.cpp b/xo-expression2/src/expression2/IExpression_DVariable.cpp index ca657c36..2b4a007b 100644 --- a/xo-expression2/src/expression2/IExpression_DVariable.cpp +++ b/xo-expression2/src/expression2/IExpression_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index f7131e0a..4dccce34 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -4,7 +4,7 @@ **/ #include "VirtualSchematikaMachine.hpp" -#include +#include #include #include diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 11ce1f07..bc35b6a9 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -164,6 +164,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-progressssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ProgressSsm + INPUT idl/ISyntaxStateMachine_DProgressSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-progressssm + FACET_PKG xo_printable2 + FACET Printable + REPR ProgressSsm + INPUT idl/IPrintable_DProgressSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-reader2-genfacet-all) # ---------------------------------------------------------------- diff --git a/xo-reader2/idl/IPrintable_DProgressSsm.json5 b/xo-reader2/idl/IPrintable_DProgressSsm.json5 new file mode 100644 index 00000000..cc5a8dda --- /dev/null +++ b/xo-reader2/idl/IPrintable_DProgressSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DProgressSsm", + using_doxygen: true, + repr: "DProgressSsm", + doc: [ "implement APrintable for DProgressSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 new file mode 100644 index 00000000..807e5ec3 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DProgressSsm", + using_doxygen: true, + repr: "DProgressSsm", + doc: [ "implement ASyntaxStateMachine for DProgressSsm" ], +} diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 2fcbd796..291108b3 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -90,6 +90,15 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_f64_token", + doc: ["update state machine for incoming f64-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_parsed_symbol", doc: ["update stat machine for incoming parsed symbol @p sym"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index ed17a1b2..5718606d 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -147,6 +147,12 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_f64_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 07456d76..36ae3c47 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -83,6 +83,12 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_f64_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 7bbcec91..6584d1e4 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -103,6 +103,12 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_f64_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectsymbol-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index c5d8ef5b..6f88615c 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -77,6 +77,12 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_f64_token(const Token & tk, + ParserStateMachine * p_psm); + /** (Never called). * Operate state machine for this syntax after symbol * emitted from nested ssm. diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 01fdfc16..1c62ced6 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -90,6 +90,11 @@ namespace xo { **/ void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on parsed symbol @p sym * from immediately-downstream ssm. * overall parser state in @p p_psm diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp new file mode 100644 index 00000000..0e22726c --- /dev/null +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -0,0 +1,220 @@ +/** @file DProgressSsm.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +//#include +#include + +#ifdef NOT_YET +#include "exprstate.hpp" +#include "xo/reflect/TypeDescr.hpp" +#include +//#include +#endif + +namespace xo { + namespace scm { + /** represent an infix operator. + * + * See @ref progress_xs::assemble_expr() for translation + * to Expression + **/ + enum class optype { + invalid = -1, + + /** op:= **/ + op_assign, + + /** op< **/ + op_less, + /** op<= **/ + op_less_equal, + /** op== **/ + op_equal, + /** op!= **/ + op_not_equal, + /** op> **/ + op_great, + /** op>= **/ + op_great_equal, + + /** op+ **/ + op_add, + /** op- **/ + op_subtract, + + /** op* **/ + op_multiply, + /** op/ **/ + op_divide, + + n_optype + }; + + extern const char * + optype_descr(optype x); + + /** report operator precedence. + * lowest operator precedence is 1 + **/ + extern int + precedence(optype x); + + inline std::ostream & + operator<< (std::ostream & os, optype x) { + os << optype_descr(x); + return os; + } + + /** @class DProgressSsm + * @brief syntax state machine for parsing a schematica rhs-value-expression + * + * Handles an expression that produces a value, for example appearing on the + * right-hand side of a definition. + * + * Deals with: + * 1. infix operators including operator precedence. + * 2. generates argument-type-specific arithmetic expressions, + * for example using ``Apply::make_add2_f64()`` when adding floating-point numbers + * + * One reason for this to exist is to simulate one-token lookahead. + * To look at but not consume a token T, can push a progress_xs instance P, + * then send T to P. + **/ + class DProgressSsm { + public: + using TypeDescr = xo::reflect::TypeDescr; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + DProgressSsm(obj lhs, optype op); + + static DProgressSsm * make(DArena & parser_mm, + obj lhs, + optype op); + + static void start(DArena & parser_mm, + obj valex, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + static void start(rp valex, + optype optype, + parserstatemachine * p_psm); +#endif + + syntaxstatetype ssm_type() const noexcept; + +#ifdef NOT_YET + bool admits_f64() const; + + void apply_type_error(const char * self_name, + optype op, + bp expr1, + bp expr2, + parserstatemachine * p_psm) const; +#endif + + std::string_view get_expect_str() const noexcept; + +#ifdef NOT_YET + void on_expr(bp expr, + parserstatemachine * p_psm) override; + void on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) override; +#endif + void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + void on_def_token(const Token & tk, + ParserStateMachine * p_psm); + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); + void on_colon_token(const Token & tk, + ParserStateMachine * p_psm); + void on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm); + void on_f64_token(const Token & tk, + ParserStateMachine * p_psm); + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + + ///@{ + + /** @defgroup scm-progressssm-printable-facet printable facet methods **/ + bool pretty(const ppindentinfo & ppii) const; + +#ifdef NOT_YET + void on_comma_token(const token_type & tk, + parserstatemachine * p_psm) final override; + void on_typedescr(TypeDescr td, + parserstatemachine * p_psm) override; + + void on_semicolon_token(const token_type & tk, + parserstatemachine * p_psm) override; + void on_assign_token(const token_type & tk, + parserstatemachine * p_psm) final override; + void on_leftparen_token(const token_type & tk, + parserstatemachine * p_psm) override; + void on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) override; + void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + void on_then_token(const token_type & tk, + parserstatemachine * p_psm) override; + void on_else_token(const token_type & tk, + parserstatemachine * p_psm) override; + + /* entry point for an infix operator token */ + void on_operator_token(const token_type & tk, + parserstatemachine * p_psm) final override; + + void on_bool_token(const token_type & tk, + parserstatemachine * p_psm) override; + + void on_i64_token(const token_type & tk, + parserstatemachine * p_psm) override; + + + void print(std::ostream & os) const override; + + private: + /** assemble expression representing + * value of + * @code + * f(lhs_, rhs_) + * @endcode + * + * where f determined by @ref op_type_ + **/ + obj assemble_expr(ParserStateMachine * p_psm); +#endif + + private: + /** populate an expression here, may be followed by an operator **/ + obj lhs_; + + /** infix operator, if supplied **/ + optype op_type_ = optype::invalid; + + /** populate an expression here, following infix operator */ + obj rhs_; + }; + } /*namespace scm*/ + +#ifndef ppdetail_atomic + namespace print { + PPDETAIL_ATOMIC(xo::scm::optype); + } +#endif +} /*namespace xo*/ + + +/* end DProgressSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 7e3bcabb..8a019e8c 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -122,6 +122,9 @@ namespace xo { /** operate state machine for incoming singleassign-token @p tk **/ void on_singleassign_token(const Token & tk); + /** operate state machine for incoming f64-token @p tk **/ + void on_f64_token(const Token & tk); + ///@} /** @defgroup scm-parserstatemachine-error-entrypoints error entry points **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index f8f23f2a..8eba08fe 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -67,6 +67,8 @@ public: virtual void on_colon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming singleassign-token @p tk **/ virtual void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming f64-token @p tk **/ + virtual void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update stat machine for incoming parsed symbol @p sym **/ virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectExprSsm.hpp index c3f9abc0..add5e046 100644 --- a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectExprSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectExprSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DProgressSsm.hpp new file mode 100644 index 00000000..f9417bba --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DProgressSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DProgressSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DProgressSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DProgressSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DProgressSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DProgressSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DProgressSsm + **/ + class IPrintable_DProgressSsm { + public: + /** @defgroup scm-printable-dprogressssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dprogressssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DProgressSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 51e5cff0..86c180dd 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -65,6 +65,7 @@ namespace scm { [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_colon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_singleassign_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_f64_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index dd2bdc29..06035486 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -64,6 +64,8 @@ namespace xo { static void on_colon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming singleassign-token @p tk **/ static void on_singleassign_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming f64-token @p tk **/ + static void on_f64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 5921f615..ec80e8c8 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectExprSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -64,6 +64,8 @@ namespace xo { static void on_colon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming singleassign-token @p tk **/ static void on_singleassign_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming f64-token @p tk **/ + static void on_f64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 114208f6..b76b4d61 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -64,6 +64,8 @@ namespace xo { static void on_colon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming singleassign-token @p tk **/ static void on_singleassign_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming f64-token @p tk **/ + static void on_f64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 7bf0d312..16c37fac 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -64,6 +64,8 @@ namespace xo { static void on_colon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming singleassign-token @p tk **/ static void on_singleassign_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming f64-token @p tk **/ + static void on_f64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 73e8a1cc..59bf00b4 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -64,6 +64,8 @@ namespace xo { static void on_colon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming singleassign-token @p tk **/ static void on_singleassign_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming f64-token @p tk **/ + static void on_f64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp new file mode 100644 index 00000000..4c4fade2 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -0,0 +1,79 @@ +/** @file ISyntaxStateMachine_DProgressSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DProgressSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DProgressSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DProgressSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DProgressSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DProgressSsm + **/ + class ISyntaxStateMachine_DProgressSsm { + public: + /** @defgroup scm-syntaxstatemachine-dprogressssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dprogressssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DProgressSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DProgressSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming symbol-token @p tk **/ + static void on_symbol_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming if-keyword-token @p tk **/ + static void on_if_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming colon-token @p tk **/ + static void on_colon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming singleassign-token @p tk **/ + static void on_singleassign_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming f64-token @p tk **/ + static void on_f64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DProgressSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index d86e9763..ef37f26d 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -67,6 +67,9 @@ namespace scm { void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_singleassign_token(_dcast(data), tk, p_psm); } + void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_f64_token(_dcast(data), tk, p_psm); + } void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { return I::on_parsed_symbol(_dcast(data), sym, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 921da301..3c933117 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -71,6 +71,9 @@ public: void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_singleassign_token(O::data(), tk, p_psm); } + void on_f64_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_f64_token(O::data(), tk, p_psm); + } void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); } diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 312ec07c..d7340b25 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -33,6 +33,9 @@ namespace xo { /** handle define-expression. See @ref DDefineSsm **/ defexpr, + /** rhs expression. state exists to achieve 1-token lookahead **/ + progress, + /** comes lasts, counts number of valid enums **/ N }; diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index ecf8f297..232174ef 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -32,6 +32,10 @@ set(SELF_SRCS ISyntaxStateMachine_DExpectExprSsm.cpp IPrintable_DExpectExprSsm.cpp + DProgressSsm.cpp + ISyntaxStateMachine_DProgressSsm.cpp + IPrintable_DProgressSsm.cpp + reader2_register_facets.cpp reader2_register_types.cpp ) diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index ea0d976a..5ba71d93 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -565,6 +565,15 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DDefineSsm::on_f64_token", + tk, + this->get_expect_str()); + } + bool DDefineSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 235f4b19..abb5d076 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -7,7 +7,13 @@ #include "ParserStateMachine.hpp" #include "SyntaxStateMachine.hpp" #include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" +#include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" #include "syntaxstatetype.hpp" +#include +#include +#include +#include +#include #include #ifdef NOT_YET @@ -27,6 +33,8 @@ namespace xo { #ifdef NOT_YET using xo::scm::Constant; #endif + using xo::scm::DFloat; + using xo::mm::AGCObject; using xo::reflect::typeseq; using xo::facet::with_facet; @@ -139,6 +147,29 @@ namespace xo { this->get_expect_str()); } + void + DExpectExprSsm::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + auto f64o = DFloat::box(p_psm->expr_alloc(), + tk.f64_value()); + + auto expr = with_facet::mkobj(DConstant::make(p_psm->expr_alloc(), f64o)); + + // DProgressSsm responsible for resolving cases like + // 1.9, + // 1.9; + // 1.9 + 2; + // 1.9 + 2 .. // could be followed by infix + // 1.9 + 2 * 3; + // 1.9 + 2 * 3 .. // could be followed by infix + // 1.9 * (2 + 3) + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + } + void DExpectExprSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index e9b93cc5..6915ced4 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -131,6 +131,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_f64_token", + tk, + this->get_expect_str()); + } + bool DExpectSymbolSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index b40916a9..44bdbdb0 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -92,6 +92,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectTypeSsm", + tk, + this->get_expect_str()); + } + void DExpectTypeSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 75e711cd..354f06fb 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -178,6 +178,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExprSeqState::on_f64_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp new file mode 100644 index 00000000..a811dda9 --- /dev/null +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -0,0 +1,932 @@ +/** @file DProgressSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DProgressSsm.hpp" +#include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" +#include + +#ifdef NOT_YET +#include "apply_xs.hpp" +#include "exprstatestack.hpp" +#include "expect_expr_xs.hpp" +#include "parserstatemachine.hpp" +#include "pretty_exprstatestack.hpp" +#include "xo/expression/AssignExpr.hpp" +#include "xo/expression/Apply.hpp" +#include "xo/expression/pretty_expression.hpp" +#endif + +namespace xo { +#ifdef NOT_YET + using xo::scm::Expression; + using xo::scm::AssignExpr; + using xo::scm::Variable; + using xo::scm::Apply; +#endif + using xo::facet::with_facet; + using xo::reflect::typeseq; + + namespace scm { + const char * + optype_descr(optype x) { + switch (x) { + case optype::invalid: + return "?optype"; + case optype::op_assign: + return "op:="; + case optype::op_less: + return "op<"; + case optype::op_less_equal: + return "op<="; + case optype::op_equal: + return "op=="; + case optype::op_not_equal: + return "op!="; + case optype::op_great: + return "op>"; + case optype::op_great_equal: + return "op>="; + case optype::op_add: + return "op+"; + case optype::op_subtract: + return "op-"; + case optype::op_multiply: + return "op*"; + case optype::op_divide: + return "op/"; + case optype::n_optype: + break; + } + return "???"; + } + + int + precedence(optype x) { + switch (x) { + case optype::invalid: + case optype::n_optype: + return 0; + + case optype::op_assign: + return 1; + + case optype::op_less: + case optype::op_less_equal: + case optype::op_equal: + case optype::op_not_equal: + case optype::op_great: + case optype::op_great_equal: + return 2; + + case optype::op_add: + case optype::op_subtract: + return 3; + + case optype::op_multiply: + case optype::op_divide: + return 4; + } + + return 0; + } + + DProgressSsm * + DProgressSsm::make(DArena & mm, + obj lhs, + optype op) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DProgressSsm)); + + return new (mem) DProgressSsm(lhs, op); + + //return std::make_unique(progress_xs(std::move(valex), op)); + } + + void + DProgressSsm::start(DArena & parser_mm, + obj valex, + ParserStateMachine * p_psm) + { + DProgressSsm * progress_ssm + = DProgressSsm::make(parser_mm, valex, optype::invalid); + + obj ssm + = with_facet::mkobj(progress_ssm); + + p_psm->push_ssm(ssm); + } + +#ifdef NOT_YET + void + progress_xs::start(rp valex, optype op, parserstatemachine * p_psm) { + p_psm->push_exprstate(progress_xs::make(valex, op)); + } + +#endif + + DProgressSsm::DProgressSsm(obj valex, + optype op) + : lhs_{valex}, + op_type_{op} + {} + + syntaxstatetype + DProgressSsm::ssm_type() const noexcept + { + return syntaxstatetype::progress; + } + +#ifdef NOT_YET + bool + progress_xs::admits_f64() const { return false; } +#endif + + std::string_view + DProgressSsm::get_expect_str() const noexcept { + if (op_type_ == optype::invalid) { + return "oper|semicolon|rightparen"; + } else { + return "expr|leftparen"; + } + } + + void + DProgressSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_symbol_token", + tk, + this->get_expect_str()); + } + + void + DProgressSsm::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_def_token", + tk, + this->get_expect_str()); + } + + void + DProgressSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_if_token", + tk, + this->get_expect_str()); + } + + void + DProgressSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_colon_token", + tk, + this->get_expect_str()); + } + + void + DProgressSsm::on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_singleassign_token", + tk, + this->get_expect_str()); + } + + void + DProgressSsm::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_f64_token", + tk, + this->get_expect_str()); + } + + void + DProgressSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DProgressSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + + void + DProgressSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DProgressSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + +#ifdef NOT_YET + void + progress_xs::apply_type_error(const char * self_name, + optype op, + bp expr1, + bp expr2, + parserstatemachine * p_psm) const + { + std::string errmsg = tostr("incompatible argument types T1,T2 to op", + xtag("op", op), + xtag("T1", expr1->valuetype()), + xtag("T2", expr2->valuetype())); + + p_psm->on_error(self_name, std::move(errmsg)); + } + + rp + progress_xs::assemble_expr(parserstatemachine * p_psm) { + /* need to defer building Apply incase expr followed by higher-precedence operator: + * consider input like + * 3.14 + 2.0 * ... + */ + + constexpr const char * c_self_name = "progress_xs::assemble_expr"; + + if ((op_type_ != optype::invalid) && (rhs_.get() == nullptr)) { + std::string errmsg = tostr("expected expression on rhs of operator op", + xtag("lhs", lhs_), + xtag("op", op_type_)); + + p_psm->on_error(c_self_name, errmsg); + } + + /* consecutive expressions not legal, e.g: + * 3.14 6.28 + * but expressions surrounding an infix operators is: + * 3.14 / 6.28 + */ + switch (op_type_) { + case optype::invalid: + return this->lhs_; + + case optype::op_assign: + { + bp lhs = Variable::from(this->lhs_); + + if (!lhs) { + throw std::runtime_error + (tostr("progress_xs::assemble_expr", + " expect variable on lhs of assignment operator :=", + xtag("lhs", lhs_), + xtag("rhs", rhs_))); + } + + return AssignExpr::make(lhs.promote(), + this->rhs_); + } + + case optype::op_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_eq_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + + case optype::op_not_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_ne_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + + case optype::op_less: + // TODO: floating-point less-than + + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_lt_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + + case optype::op_less_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_le_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + + case optype::op_great: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_gt_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + + case optype::op_great_equal: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_ge_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + + assert(false); + + case optype::op_add: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_add2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_add2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + case optype::op_subtract: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_sub2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_sub2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + + case optype::op_multiply: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_mul2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_mul2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + + break; + + case optype::op_divide: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_div2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_div2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + + case optype::n_optype: + /* unreachable */ + assert(false); + return nullptr; + } + + return nullptr; + } + + void + progress_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("expr", expr)); + + /* note: previous token probably an operator, + * handled from progress_xs::on_operator_token(), + * which pushes expect_expr_xs::expect_rhs_expression() + */ + + constexpr const char * c_self_name = "progress_xs::on_expr"; + const char * exp = get_expect_str(); + + if (lhs_) { + if (op_type_ == optype::invalid) { + /* two consecutive expression without an operator */ + this->illegal_input_on_expr(c_self_name, expr, exp, p_psm); + } + +#ifdef NOT_QUITE + assert(result.get()); + + /* this expression complete.. */ + std::unique_ptr self = p_psm->pop_exprstate(); + + /* ..but more operators could follow, so don't commit yet */ + p_stack->push_exprstate(progress_xs::make(result)); +#endif + + this->rhs_ = expr.promote(); + } else { + /* control here on input like + * add(1,2)... + * + * add(1,2) needs to be handled inside a progress_xs + * instance because may be followed by an operator: + * add(1,2) + ... + */ + this->lhs_ = expr.promote(); + } + } + + void + progress_xs::on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("lhs", lhs_), xtag("op", op_type_), xtag("expr", expr)); + + constexpr const char * c_self_name = "progress_xs::on_expr_with_semicolon"; + const char * exp = get_expect_str(); + + if (op_type_ == optype::invalid) { + this->illegal_input_on_expr(c_self_name, expr, exp, p_psm); + } + + this->rhs_ = expr.promote(); + + // FORBIDDEN, because .on_semicolon_token() destroys *this before returning + // this->on_semicolon_token(token_type::semicolon(), p_psm); + // INSTEAD, spell out the body + + rp expr2 = this->assemble_expr(p_psm); + + if (expr2) { + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr_with_semicolon(expr2); + } + } +#endif + +#ifdef NOT_YET + void + progress_xs::on_comma_token(const token_type & tk, + parserstatemachine * p_psm) + { + /* note: implementation parllels .on_semicolon_token(), .on_rightparen_token() */ + + scope log(XO_DEBUG(p_psm->debug_flag())); + + constexpr const char * self_name = "progress::xs::on_comma_token"; + + auto & xs_stack = p_psm->xs_stack_; + + /* stack may be something like + * + * applyexpr + * expect_expr_xs + * progress_xs + * <-- comma + * + * 1. comma completes expression-in-progress + */ + + /* comma confirms stack expression */ + rp expr = this->assemble_expr(p_psm); + + std::unique_ptr self = p_psm->pop_exprstate(); + + if (xs_stack.empty()) { + throw std::runtime_error(tostr(self_name, + ": expected non-empty parsing state")); + } + + log && log(xtag("stack", &xs_stack)); + + p_psm->top_exprstate().on_expr(expr, p_psm); + + /* now deliver comma */ + p_psm->top_exprstate().on_comma_token(tk, p_psm); + } + + void + progress_xs::on_typedescr(TypeDescr /*td*/, + parserstatemachine * /*p_psm*/) + { + /* unreachable */ + assert(false); + } + + void + progress_xs::on_semicolon_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + /* note: implementation parallels .on_rightparen_token() */ + + scope log(XO_DEBUG(p_psm->debug_flag())); + + rp expr = this->assemble_expr(p_psm); + + log && log(xtag("assembled-expr", expr)); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr_with_semicolon(expr); + + /* control here on input like: + * (1.234; + * + * a. '(' sets up stack [lparen_0:expect_rhs_expression] + * (see exprstate::on_leftparen()) + * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] + * (see exprstate::on_f64()) + * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] + * deliver expresssion to expect_rhs_expression.on_expr_with_semicolon() + * (see exprstate::on_expr_with_semicolon()) + * d. expr_rhs_expression forwards expression to [lparen_0] + * e. lparen_0 would advance to [lparen_1], but rejects semicolon + */ + } + + void + progress_xs::on_assign_token(const token_type & tk, + parserstatemachine * p_psm) + { + this->on_operator_token(tk, p_psm); + } + + /* editor bait: on_lparen */ + void + progress_xs::on_leftparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + /* input like: + * 'foo(' -> expect function call. might continue 'foo(a,b,c)' + * 'foo+(' -> expect parenthesized expression. might continue 'foo+(bar/2)' + */ + + if (op_type_ == optype::invalid) { + /* start function call */ + assert(rhs_.get() == nullptr); + + rp fn_expr = lhs_; + + /* reset this progress_xs back to empty state; + * apply_xs will be responsible for lhs_. + */ + lhs_ = nullptr; + +#ifdef OBSOLETE + /* don't unwind! want to handle input like + * f(x,y)+g(z) + */ + /* unwind this progress_xs + replace with function call */ + std::unique_ptr self = p_psm->pop_exprstate(); +#endif + + apply_xs::start(fn_expr, p_psm); + + /* control will reenter progress_xs via .on_expr() */ + return; + } + + constexpr const char * c_self_name = "exprstate::on_leftparen"; + const char * exp = get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + progress_xs::on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + /* note: implementation parallels .on_semicolon_token() */ + + scope log(XO_DEBUG(p_psm->debug_flag())); + + constexpr const char * self_name = "progress_xs::on_rightparen"; + + auto & xs_stack = p_psm->xs_stack_; + + /* stack may be something like: + * + * lparen_0 + * expect_expr_xs + * expr_progress + * <-- rightparen + * + * 1. rightparen completes expression-in-progress + * 2. rightparen must then match innermost waiting lparen_0 + */ + + /* right paren confirms stack expression */ + rp expr = this->assemble_expr(p_psm); + + log && log(xtag("expr", expr), + xtag("do", "pop self + send {expr, rparen} -> parent")); + + std::unique_ptr self = p_psm->pop_exprstate(); + + if (xs_stack.empty()) { + throw std::runtime_error(tostr(self_name, + ": expected non-empty parsing stack")); + } + + log && log(xtag("stack", &xs_stack)); + + p_psm->top_exprstate().on_expr(expr, p_psm); + + /* now deliver rightparen */ + p_psm->top_exprstate().on_rightparen_token(tk, p_psm); + } + + void + progress_xs::on_then_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + rp expr = this->assemble_expr(p_psm); + + log && log(xtag("assembled-expr", expr)); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr(expr); + p_psm->on_then_token(tk); + + /* control here on input like: + * + * if a > b then.. + * + */ + } + + void + progress_xs::on_else_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + rp expr = this->assemble_expr(p_psm); + + log && log(xtag("assembled-expr", expr)); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr(expr); + p_psm->on_else_token(tk); + + /* control here on input like: + * + * if a > b then c else.. + */ + } + + void + progress_xs::on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + rp expr = this->assemble_expr(p_psm); + + log && log(xtag("assembled-expr", expr)); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_expr(expr); + p_psm->on_rightbrace_token(tk); + + /* control here on input like: + * + * { n * n } + */ + } + + namespace { + optype + tk2op(const tokentype & tktype) { + switch (tktype) { + case tokentype::tk_assign: + return optype::op_assign; + case tokentype::tk_plus: + return optype::op_add; + case tokentype::tk_minus: + return optype::op_subtract; + case tokentype::tk_star: + return optype::op_multiply; + case tokentype::tk_slash: + return optype::op_divide; + case tokentype::tk_cmpeq: + return optype::op_equal; + case tokentype::tk_cmpne: + return optype::op_not_equal; + case tokentype::tk_leftangle: + return optype::op_less; + case tokentype::tk_lessequal: + return optype::op_less_equal; + case tokentype::tk_rightangle: + return optype::op_great; + case tokentype::tk_greatequal: + return optype::op_great_equal; + default: + assert(false); + return optype::invalid; + } + return optype::invalid; + } + } + + void + progress_xs::on_operator_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + constexpr const char * c_self_name = "progress_xs::on_operator_token"; + + if (op_type_ == optype::invalid) { + this->op_type_ = tk2op(tk.tk_type()); + + /* infix operator must be followed by non-empty expression */ + expect_expr_xs::start(p_psm); + } else if (rhs_) { + /* already have complete expression stashed. + * behavior depends on operator precedence for tk with stored operator + * this->op_type_ + */ + optype op2 = tk2op(tk.tk_type()); + + if (precedence(op2) <= precedence(this->op_type_)) { + /* e.g. + * 6.2 * 4.9 + ... + * + * in stack: + * 1. progress_xs lhs=6.2, op=*, rhs=4.9 + * + * out stack + * 1. progress_xs lhs=apply(*,6.2,4.9), op=+ + */ + + /* 1. instantiate expression for *this */ + auto expr = this->assemble_expr(p_psm); + + /* 2. remove from stack */ + std::unique_ptr self = p_psm->pop_exprstate(); + + /* 3. replace with new progress_xs: */ + progress_xs::start(expr, op2, p_psm); + + /* infix operator must be followed by non-empty expression */ + expect_expr_xs::start(p_psm); + } else { + /* e.g. + * 6.2 + 4.9 * ... + * + * in stack: + * 1. progress_xs lhs=6.2, op=+, rhs=4.9 + * + * out stack: + * 1. progress_xs lhs=6.2, op=+ + * 2. expect_rhs_expression + * 3. progress_xs lhs=4.9, op=* + * 4. expect_rhs_expression + */ + + std::unique_ptr self = p_psm->pop_exprstate(); + + /* 1. replace with nested incomplete infix exprs */ + progress_xs::start(lhs_, op_type_, p_psm); + expect_expr_xs::start(p_psm); + progress_xs::start(rhs_, op2, p_psm); + expect_expr_xs::start(p_psm); + } + + } else { + throw std::runtime_error(tostr(c_self_name, + ": expected expression following operator", + xtag("tk", tk))); + } + } + + void + progress_xs::on_bool_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + constexpr const char * c_self_name = "progress_xs::on_bool_token"; + const char * exp = get_expect_str(); + + if (this->op_type_ == optype::invalid) { + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } else { + exprstate::on_bool_token(tk, p_psm); + } + } + + void + progress_xs::on_i64_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * c_self_name = "progress_xs::on_i64_token"; + const char * exp = get_expect_str(); + + if (this->op_type_ == optype::invalid) { + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } else { + exprstate::on_i64_token(tk, p_psm); + } + } + + void + progress_xs::print(std::ostream & os) const { + os << ""; + } + + bool + progress_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + if (ppii.upto()) { + return (ppii.pps()->print_upto("print_upto(refrtag("lhs", lhs_)) : true) + && (op_type_ != optype::invalid ? ppii.pps()->print_upto(refrtag("op", op_type_)) : true) + && (rhs_ ? ppii.pps()->print_upto(refrtag("rhs", rhs_)) : true) + && ppii.pps()->print_upto(">")); + } else { + ppii.pps()->write("pretty(refrtag("lhs", lhs_)); + if (op_type_ != optype::invalid) + ppii.pps()->pretty(refrtag("op", op_type_)); + if (rhs_) + ppii.pps()->pretty(refrtag("rhs", rhs_)); + ppii.pps()->write(">"); + return false; + } + } + +#endif + bool + DProgressSsm::pretty(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DProgressSsm", + refrtag("lhs", lhs_), + refrtag("op", op_type_), + refrtag("rhs", rhs_)); + +#ifdef NOPE + if (ppii.upto()) { + return (ppii.pps()->print_upto("print_upto(refrtag("lhs", lhs_)) : true) + && (op_type_ != optype::invalid ? ppii.pps()->print_upto(refrtag("op", op_type_)) : true) + && (rhs_ ? ppii.pps()->print_upto(refrtag("rhs", rhs_)) : true) + && ppii.pps()->print_upto(">")); + } else { + ppii.pps()->write("pretty(refrtag("lhs", lhs_)); + if (op_type_ != optype::invalid) + ppii.pps()->pretty(refrtag("op", op_type_)); + if (rhs_) + ppii.pps()->pretty(refrtag("rhs", rhs_)); + ppii.pps()->write(">"); + return false; + } +#endif + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DProgressSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp index 2b656fb2..bfeaccd1 100644 --- a/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectExprSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp b/xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp new file mode 100644 index 00000000..c72399c9 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DProgressSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DProgressSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DProgressSsm.json5] +**/ + +#include "ssm/IPrintable_DProgressSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DProgressSsm::pretty(const DProgressSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DProgressSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index fb9e7a53..0e95dd2d 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -64,6 +64,12 @@ ISyntaxStateMachine_Any::on_singleassign_token(Opaque, const Token &, ParserStat _fatal(); } +auto +ISyntaxStateMachine_Any::on_f64_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index ae2d6601..a758178e 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -53,6 +53,11 @@ namespace xo { self.on_singleassign_token(tk, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_f64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_f64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index de751479..426e4c40 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectExprSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -53,6 +53,11 @@ namespace xo { self.on_singleassign_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectExprSsm::on_f64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_f64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectExprSsm::on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 5eb40180..586f492f 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -53,6 +53,11 @@ namespace xo { self.on_singleassign_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_f64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_f64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index d8621b20..f0360bbf 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -53,6 +53,11 @@ namespace xo { self.on_singleassign_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_f64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_f64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index d81e066c..98a3009f 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -53,6 +53,11 @@ namespace xo { self.on_singleassign_token(tk, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_f64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_f64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp new file mode 100644 index 00000000..901dba21 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -0,0 +1,74 @@ +/** @file ISyntaxStateMachine_DProgressSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DProgressSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DProgressSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DProgressSsm::ssm_type(const DProgressSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DProgressSsm::get_expect_str(const DProgressSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DProgressSsm::on_symbol_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_symbol_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_def_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_def_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_if_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_if_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_colon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_colon_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_singleassign_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_singleassign_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_f64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_f64_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_parsed_symbol(DProgressSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DProgressSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index dbed93d9..33e3a6c2 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -163,11 +163,14 @@ namespace xo { this->on_singleassign_token(tk); break; + case tokentype::tk_f64: + this->on_f64_token(tk); + break; + // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_bool: case tokentype::tk_i64: - case tokentype::tk_f64: case tokentype::tk_string: case tokentype::tk_leftparen: case tokentype::tk_rightparen: @@ -246,6 +249,14 @@ namespace xo { stack_->top().on_singleassign_token(tk, this); } + void + ParserStateMachine::on_f64_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_f64_token(tk, this); + } + void ParserStateMachine::capture_error(std::string_view ssm_name, const DString * errmsg) diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index cdade07b..ab0ebe43 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include + #include #include #include @@ -51,11 +54,15 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); log && log(xtag("DExpectSymbolSsm.tseq", typeseq::id())); log && log(xtag("DExpectTypeSsm.tseq", typeseq::id())); log && log(xtag("DExpectExprSsm.tseq", typeseq::id())); + log && log(xtag("DProgressSsm.tseq", typeseq::id())); return true; } diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index ac09b92e..716c3d7d 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -23,6 +23,8 @@ namespace xo { return "expect-rhs-expression"; case syntaxstatetype::defexpr: return "defexpr"; + case syntaxstatetype::progress: + return "progress"; case syntaxstatetype::N: break; } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index e0f813e4..e70f449b 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -163,7 +163,6 @@ namespace xo { REQUIRE(exp_ssm.data()->cxl_on_rightbrace() == false); } -#ifdef NOT_YET { // future-proofing for Token only holding a string_view const DString * str = DString::from_cstr(expr_alloc, "3.141593"); @@ -172,11 +171,10 @@ namespace xo { REQUIRE(parser.has_incomplete_expr() == true); - log && log("after typename symbol token:"); + log && log("after f64 token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); } -#endif { #ifdef NOT_YET From 0163c16771bd433dd2eced7e43c2a90506d4cf9c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 15:32:12 -0500 Subject: [PATCH 045/258] xo-reader2: + on_semicolon_token() method in SyntaxStateMachine --- xo-reader2/idl/SyntaxStateMachine.json5 | 9 +++++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectExprSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExprSeqState.hpp | 5 +++++ xo-reader2/include/xo/reader2/DProgressSsm.hpp | 2 ++ .../include/xo/reader2/ParserStateMachine.hpp | 3 +++ .../include/xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 ++ .../xo/reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectExprSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 ++ .../xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 +++ .../include/xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 +++ xo-reader2/src/reader2/DDefineSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 9 +++++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp | 6 ++++++ .../src/reader2/ISyntaxStateMachine_DDefineSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExpectExprSsm.cpp | 5 +++++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExprSeqState.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DProgressSsm.cpp | 5 +++++ xo-reader2/src/reader2/ParserStateMachine.cpp | 13 ++++++++++++- 32 files changed, 166 insertions(+), 1 deletion(-) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 291108b3..d1229bb5 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -99,6 +99,15 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_semicolon_token", + doc: ["update state machine for incoming semicolon-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_parsed_symbol", doc: ["update stat machine for incoming parsed symbol @p sym"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 5718606d..753571c0 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -153,6 +153,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, + * overall parser state in @p p_psm + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 36ae3c47..50c1e5a4 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -89,6 +89,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, + * overall parser state in @p p_psm + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 6584d1e4..8f25661e 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -109,6 +109,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, + * overall parser state in @p p_psm + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectsymbol-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 6f88615c..ae2a4512 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -83,6 +83,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, + * overall parser state in @p p_psm + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + /** (Never called). * Operate state machine for this syntax after symbol * emitted from nested ssm. diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 1c62ced6..90ad3891 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -95,6 +95,11 @@ namespace xo { **/ void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, + * overall parser state in @p p_psm + **/ + void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on parsed symbol @p sym * from immediately-downstream ssm. * overall parser state in @p p_psm diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 0e22726c..25ba8a45 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -141,6 +141,8 @@ namespace xo { ParserStateMachine * p_psm); void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); void on_parsed_typedescr(TypeDescr td, diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 8a019e8c..e43546d3 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -125,6 +125,9 @@ namespace xo { /** operate state machine for incoming f64-token @p tk **/ void on_f64_token(const Token & tk); + /** operate state machine for incoming semicolon-token @p tk **/ + void on_semicolon_token(const Token & tk); + ///@} /** @defgroup scm-parserstatemachine-error-entrypoints error entry points **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index 8eba08fe..687722ae 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -69,6 +69,8 @@ public: virtual void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming f64-token @p tk **/ virtual void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming semicolon-token @p tk **/ + virtual void on_semicolon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update stat machine for incoming parsed symbol @p sym **/ virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 86c180dd..a5d4ed08 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -66,6 +66,7 @@ namespace scm { [[noreturn]] void on_colon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_singleassign_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_f64_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_semicolon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index 06035486..fca6e193 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming semicolon-token @p tk **/ + static void on_semicolon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index ec80e8c8..7d4416f9 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming semicolon-token @p tk **/ + static void on_semicolon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index b76b4d61..acf7ceea 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming semicolon-token @p tk **/ + static void on_semicolon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 16c37fac..a6a3edba 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming semicolon-token @p tk **/ + static void on_semicolon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 59bf00b4..4e73286c 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming semicolon-token @p tk **/ + static void on_semicolon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index 4c4fade2..e830bf99 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming semicolon-token @p tk **/ + static void on_semicolon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DProgressSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index ef37f26d..231fa222 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -70,6 +70,9 @@ namespace scm { void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_f64_token(_dcast(data), tk, p_psm); } + void on_semicolon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_semicolon_token(_dcast(data), tk, p_psm); + } void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { return I::on_parsed_symbol(_dcast(data), sym, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 3c933117..03772439 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -74,6 +74,9 @@ public: void on_f64_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_f64_token(O::data(), tk, p_psm); } + void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_semicolon_token(O::data(), tk, p_psm); + } void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); } diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 5ba71d93..cc380568 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -574,6 +574,15 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DDefineSsm::on_semicolon_token", + tk, + this->get_expect_str()); + } + bool DDefineSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index abb5d076..2420b7c2 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -170,6 +170,15 @@ namespace xo { p_psm); } + void + DExpectExprSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm::on_semicolon_token", + tk, + this->get_expect_str()); + } + void DExpectExprSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 6915ced4..91cc3584 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -140,6 +140,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_semicolon_token", + tk, + this->get_expect_str()); + } + bool DExpectSymbolSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 44bdbdb0..96fc0ceb 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -101,6 +101,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectTypeSsm::on_semicolon_token", + tk, + this->get_expect_str()); + } + void DExpectTypeSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 354f06fb..32b9089c 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -187,6 +187,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExprSeqState::on_semicolon_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index a811dda9..cfc6c10c 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -207,6 +207,15 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_semicolon_token", + tk, + this->get_expect_str()); + } + void DProgressSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 0e95dd2d..b19b5ea0 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -70,6 +70,12 @@ ISyntaxStateMachine_Any::on_f64_token(Opaque, const Token &, ParserStateMachine _fatal(); } +auto +ISyntaxStateMachine_Any::on_semicolon_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index a758178e..723b910d 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_semicolon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_semicolon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index 426e4c40..cf8d0969 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectExprSsm::on_semicolon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_semicolon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectExprSsm::on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 586f492f..dfc56402 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_semicolon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_semicolon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index f0360bbf..6126db55 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_semicolon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_semicolon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 98a3009f..947060a8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_semicolon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_semicolon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 901dba21..73546dc3 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DProgressSsm::on_semicolon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_semicolon_token(tk, p_psm); + } + auto ISyntaxStateMachine_DProgressSsm::on_parsed_symbol(DProgressSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { self.on_parsed_symbol(sym, p_psm); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 33e3a6c2..596b5e13 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -167,6 +167,10 @@ namespace xo { this->on_f64_token(tk); break; + case tokentype::tk_semicolon: + this->on_semicolon_token(tk); + break; + // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_bool: @@ -185,7 +189,6 @@ namespace xo { case tokentype::tk_dot: case tokentype::tk_comma: case tokentype::tk_doublecolon: - case tokentype::tk_semicolon: case tokentype::tk_assign: case tokentype::tk_yields: case tokentype::tk_plus: @@ -257,6 +260,14 @@ namespace xo { stack_->top().on_f64_token(tk, this); } + void + ParserStateMachine::on_semicolon_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_semicolon_token(tk, this); + } + void ParserStateMachine::capture_error(std::string_view ssm_name, const DString * errmsg) From 164b09a3d7e17ab81e259e398a94972b94c925af Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 15:37:20 -0500 Subject: [PATCH 046/258] xo-reader2: cosmetic: non-executable content --- xo-reader2/src/reader2/DProgressSsm.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index cfc6c10c..c13e1799 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -211,6 +211,29 @@ namespace xo { DProgressSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { + /* note: implementation should parallel .on_rightparen_token() */ + +#ifdef NOT_YET + obj expr = this->assemble_expr(p_psm); + + p_psm->pop_ssm(); + p_psm->on_expr_with_semicolon(expr); + + /* control here on input like: + * (1.234; + * + * a. '(' sets up stack [lparen_0:expect_rhs_expression] + * (see exprstate::on_leftparen()) + * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] + * (see exprstate::on_f64()) + * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] + * deliver expresssion to expect_rhs_expression.on_expr_with_semicolon() + * (see exprstate::on_expr_with_semicolon()) + * d. expr_rhs_expression forwards expression to [lparen_0] + * e. lparen_0 would advance to [lparen_1], but rejects semicolon + */ +#endif + p_psm->illegal_input_on_token("DProgressSsm::on_semicolon_token", tk, this->get_expect_str()); From 538cc4aa4a025954c3bfbcb0f97e736fe70dcf20 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 15:49:07 -0500 Subject: [PATCH 047/258] xo-reader2: + SyntaxStateMachine.on_parsed_expression() --- xo-reader2/idl/SyntaxStateMachine.json5 | 9 ++++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 +++++ .../include/xo/reader2/DExpectExprSsm.hpp | 6 +++++ .../include/xo/reader2/DExpectSymbolSsm.hpp | 7 ++++++ .../include/xo/reader2/DExpectTypeSsm.hpp | 7 ++++++ .../include/xo/reader2/DExprSeqState.hpp | 6 +++++ .../include/xo/reader2/DProgressSsm.hpp | 2 ++ .../include/xo/reader2/ParserStateMachine.hpp | 8 +++++++ .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 ++ .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectExprSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 ++ .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 +++ .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 +++ xo-reader2/src/reader2/DDefineSsm.cpp | 9 ++++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 9 ++++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 ++++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 ++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 9 ++++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 9 ++++++++ .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 +++++ .../ISyntaxStateMachine_DDefineSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DExpectExprSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DExprSeqState.cpp | 5 ++++ .../ISyntaxStateMachine_DProgressSsm.cpp | 5 ++++ xo-reader2/src/reader2/ParserStateMachine.cpp | 23 +++++++++++++++++++ 32 files changed, 185 insertions(+) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index d1229bb5..74843096 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -126,5 +126,14 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_expression", + doc: ["update state machine for incoming parsed expression @p expr"], + return_type: "void", + args: [ + {type: "obj", name: "expr"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, ], } diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 753571c0..3496b5c8 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -171,6 +171,12 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr, + * overall parser state in @p p_psm + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 50c1e5a4..6ed81bff 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -107,6 +107,12 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr, + * overall parser state in @p p_psm + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 8f25661e..6f9a568c 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -79,6 +79,13 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr + * in nested state machine. + * (provided to satisfy ASyntaxStateMachine api. not reachable) + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm. **/ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index ae2a4512..49bd1aa9 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -107,6 +107,13 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for this syntax on receiving expression + * from nested parser. + * (provided to satisfy ASyntaxStateMachine api. not reachable) + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expecttype-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 90ad3891..a3989200 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -112,6 +112,12 @@ namespace xo { **/ void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state for this syntax on parsed expression @p expr + * from nested ssm. + * overall parser state in @p p_psm + **/ + void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + ///@} /** @defgroup scm-exprseq-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 25ba8a45..f1e15fba 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -147,6 +147,8 @@ namespace xo { ParserStateMachine * p_psm); void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + void on_parsed_expression(obj, + ParserStateMachine * p_psm); ///@{ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index e43546d3..e5c0ab68 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -164,6 +164,14 @@ namespace xo { TypeDescr td, std::string_view expect_str); + /** report illegal parsed expression from nested ssm. + * Introducing as placeholder; not clear if this will be reachable + * in full parser + **/ + void illegal_parsed_expression(std::string_view ssm_name, + obj, + std::string_view expect_str); + ///@} private: diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index 687722ae..a5cf677f 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -75,6 +75,8 @@ public: virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; /** operate state machine for incoming type description @p td **/ virtual void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming parsed expression @p expr **/ + virtual void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; ///@} }; /*ASyntaxStateMachine*/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index a5d4ed08..1098b86e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -69,6 +69,7 @@ namespace scm { [[noreturn]] void on_semicolon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; + [[noreturn]] void on_parsed_expression(Opaque, obj, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index fca6e193..a65f47d5 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -72,6 +72,8 @@ namespace xo { static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 7d4416f9..28beddcd 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -72,6 +72,8 @@ namespace xo { static void on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index acf7ceea..a38306ed 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -72,6 +72,8 @@ namespace xo { static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index a6a3edba..aefe5afa 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -72,6 +72,8 @@ namespace xo { static void on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 4e73286c..cc0d918d 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -72,6 +72,8 @@ namespace xo { static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index e830bf99..c305cf80 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -72,6 +72,8 @@ namespace xo { static void on_parsed_symbol(DProgressSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 231fa222..a0a832b5 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -79,6 +79,9 @@ namespace scm { void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) override { return I::on_parsed_typedescr(_dcast(data), td, p_psm); } + void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) override { + return I::on_parsed_expression(_dcast(data), expr, p_psm); + } ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 03772439..187a32c7 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -83,6 +83,9 @@ public: void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm) { return O::iface()->on_parsed_typedescr(O::data(), td, p_psm); } + void on_parsed_expression(obj expr, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_expression(O::data(), expr, p_psm); + } ///@} /** @defgroup scm-syntaxstatemachine-member-vars **/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index cc380568..3e91a480 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -583,6 +583,15 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DDefineSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + bool DDefineSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 2420b7c2..3f817763 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -197,6 +197,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectExprSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectExprSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + bool DExpectExprSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 91cc3584..a1db308c 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -74,6 +74,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectSymbolSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 96fc0ceb..9a97ef2d 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -163,6 +163,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectTypeSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + bool DExpectTypeSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 32b9089c..a5b7edd6 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -214,6 +214,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExprSeqState::on_parsed_expression", + expr, + this->get_expect_str()); + } + bool DExprSeqState::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index c13e1799..d141daf6 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -257,6 +257,15 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DProgressSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + #ifdef NOT_YET void progress_xs::apply_type_error(const char * self_name, diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index b19b5ea0..c953b1e1 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -88,6 +88,12 @@ ISyntaxStateMachine_Any::on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachi _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_expression(Opaque, obj, ParserStateMachine *) -> void +{ + _fatal(); +} + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 723b910d..cab18818 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -72,6 +72,11 @@ namespace xo { { self.on_parsed_typedescr(td, p_psm); } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index cf8d0969..feb2d13a 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -72,6 +72,11 @@ namespace xo { { self.on_parsed_typedescr(td, p_psm); } + auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index dfc56402..714ef041 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -72,6 +72,11 @@ namespace xo { { self.on_parsed_typedescr(td, p_psm); } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 6126db55..2dd5a9ca 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -72,6 +72,11 @@ namespace xo { { self.on_parsed_typedescr(td, p_psm); } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 947060a8..6d42b86b 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -72,6 +72,11 @@ namespace xo { { self.on_parsed_typedescr(td, p_psm); } + auto + ISyntaxStateMachine_DExprSeqState::on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 73546dc3..62dd2ce0 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -72,6 +72,11 @@ namespace xo { { self.on_parsed_typedescr(td, p_psm); } + auto + ISyntaxStateMachine_DProgressSsm::on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 596b5e13..262db2df 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -343,6 +343,29 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + + void + ParserStateMachine::illegal_parsed_expression(std::string_view ssm_name, + obj expr, + std::string_view expect_str) + { + // TODO: + // - want to write error message using DArena + // - need something like log_streambuf and/or tostr() that's arena-aware + + auto errmsg_string = tostr("Unexpected expression", + xtag("expr", expr), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_parsed_expression")); + + assert(expr_alloc_); + + auto errmsg = DString::from_view(expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } } /*namespace scm*/ } /*namespace xo*/ From 56aceac9e8cf601a481b4796de13d195a1b092e4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 17:15:05 -0500 Subject: [PATCH 048/258] xo-reader2: + on_parsed_expression_with_semicolon + DefineSsm works --- .../include/xo/expression2/DDefineExpr.hpp | 1 + .../src/expression2/DDefineExpr.cpp | 5 + xo-reader2/idl/SyntaxStateMachine.json5 | 9 + xo-reader2/include/xo/reader2/DDefineSsm.hpp | 7 + .../include/xo/reader2/DExpectExprSsm.hpp | 7 + .../include/xo/reader2/DExpectSymbolSsm.hpp | 7 + .../include/xo/reader2/DExpectTypeSsm.hpp | 7 + .../include/xo/reader2/DExprSeqState.hpp | 6 + .../include/xo/reader2/DProgressSsm.hpp | 21 +- .../include/xo/reader2/ParserStateMachine.hpp | 16 ++ .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 + .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectExprSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 + .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 + .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 + .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 + xo-reader2/src/reader2/DDefineSsm.cpp | 22 ++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 11 + xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 + xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 + xo-reader2/src/reader2/DExprSeqState.cpp | 9 + xo-reader2/src/reader2/DProgressSsm.cpp | 205 +++++++++++++++++- .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 + .../ISyntaxStateMachine_DDefineSsm.cpp | 5 + .../ISyntaxStateMachine_DExpectExprSsm.cpp | 5 + .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 + .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 + .../ISyntaxStateMachine_DExprSeqState.cpp | 5 + .../ISyntaxStateMachine_DProgressSsm.cpp | 5 + xo-reader2/src/reader2/ParserStateMachine.cpp | 20 ++ xo-reader2/utest/SchematikaParser.test.cpp | 13 +- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 36 files changed, 425 insertions(+), 18 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp index 1056dbb7..6b7716e3 100644 --- a/xo-expression2/include/xo/expression2/DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -56,6 +56,7 @@ namespace xo { ///@{ void assign_lhs_name(const DUniqueString * name); + void assign_rhs(obj rhs); ///@} /** @defgroup scm-defineexpr-expression-facet **/ diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index c8785415..e193c4d4 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -67,6 +67,11 @@ namespace xo { lhs_var_->assign_valuetype(td); } + void + DDefineExpr::assign_rhs(obj x) { + this->rhs_ = x; + } + bool DDefineExpr::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 74843096..c12d3736 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -135,5 +135,14 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_expression_with_semicolon", + doc: ["update state machine for incoming parsed expression @p expr followed by semicolon"], + return_type: "void", + args: [ + {type: "obj", name: "expr"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, ], } diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 3496b5c8..1d94f3ad 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -177,6 +177,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr + * followed by semicolon, + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 6ed81bff..7bf48dea 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -113,6 +113,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr + * followed by semicolon, + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 6f9a568c..1083b454 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -86,6 +86,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr + * followed by semicolon in nested state machine. + * (provided to satisfy ASyntaxStateMachine api. not reachable) + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm. **/ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 49bd1aa9..cf28fedf 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -114,6 +114,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** operate state machine for this syntax on receiving expression + * followed by semicolon from nested parser. + * (provided to satisfy ASyntaxStateMachine api. not reachable) + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expecttype-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index a3989200..eefcb15d 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -118,6 +118,12 @@ namespace xo { **/ void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update state for this syntax on parsed expression @p expr + * followed by semicolon from nested ssm. + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm); + ///@} /** @defgroup scm-exprseq-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index f1e15fba..2b4121c3 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -123,12 +123,14 @@ namespace xo { std::string_view get_expect_str() const noexcept; -#ifdef NOT_YET - void on_expr(bp expr, - parserstatemachine * p_psm) override; - void on_expr_with_semicolon(bp expr, - parserstatemachine * p_psm) override; -#endif + /** assemble expression from collected inputs. + * Usually triggered by syntax like ';' or ')' + **/ + obj assemble_expr(ParserStateMachine * p_psm); + + /** @defgroup scm-progressssm-ssm-facet syntaxstatemachine facet methods **/ + /// @{ + void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); void on_def_token(const Token & tk, @@ -149,12 +151,17 @@ namespace xo { ParserStateMachine * p_psm); void on_parsed_expression(obj, ParserStateMachine * p_psm); + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + ///@} + /** @defgroup scm-progressssm-printable-facet printable facet methods **/ ///@{ - /** @defgroup scm-progressssm-printable-facet printable facet methods **/ bool pretty(const ppindentinfo & ppii) const; + ///@} + #ifdef NOT_YET void on_comma_token(const token_type & tk, parserstatemachine * p_psm) final override; diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index e5c0ab68..42c8af64 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -102,6 +102,22 @@ namespace xo { **/ void on_parsed_typedescr(TypeDescr td); + /** update state to respond to parsed expression @p expr + * (from nested parsing state) + **/ + void on_parsed_expression(obj expr); + + /** update state to respond to parsed expression @p expr + * (from nested parsing state), with trailing semicolon. + * + * Need to distinguish cases like: + * 6 // ; allowed + * f(6 // ) allowed ; forbidden + * 6 + // ) forbidden ; forbidden + * + **/ + void on_parsed_expression_with_semicolon(obj expr); + /** update state to respond to input token @p tk. * record output (if any) in @ref result_ **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index a5cf677f..b68a1289 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -77,6 +77,8 @@ public: virtual void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) = 0; /** update state machine for incoming parsed expression @p expr **/ virtual void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + virtual void on_parsed_expression_with_semicolon(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; ///@} }; /*ASyntaxStateMachine*/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 1098b86e..52dc4059 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -70,6 +70,7 @@ namespace scm { [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression(Opaque, obj, ParserStateMachine *) override; + [[noreturn]] void on_parsed_expression_with_semicolon(Opaque, obj, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index a65f47d5..3084631c 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DDefineSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 28beddcd..efebe9c7 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index a38306ed..d870667a 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index aefe5afa..23eb8af0 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index cc0d918d..020e7552 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index c305cf80..1735b2b1 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DProgressSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index a0a832b5..da16f766 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -82,6 +82,9 @@ namespace scm { void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) override { return I::on_parsed_expression(_dcast(data), expr, p_psm); } + void on_parsed_expression_with_semicolon(Opaque data, obj expr, ParserStateMachine * p_psm) override { + return I::on_parsed_expression_with_semicolon(_dcast(data), expr, p_psm); + } ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 187a32c7..cfa354b9 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -86,6 +86,9 @@ public: void on_parsed_expression(obj expr, ParserStateMachine * p_psm) { return O::iface()->on_parsed_expression(O::data(), expr, p_psm); } + void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_expression_with_semicolon(O::data(), expr, p_psm); + } ///@} /** @defgroup scm-syntaxstatemachine-member-vars **/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 3e91a480..6de3bd93 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -578,6 +578,12 @@ namespace xo { DDefineSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { + if (defstate_ == defexprstatetype::def_6) { + p_psm->pop_ssm(); + p_psm->on_parsed_expression_with_semicolon(def_expr_); + return; + } + p_psm->illegal_input_on_token("DDefineSsm::on_semicolon_token", tk, this->get_expect_str()); @@ -587,11 +593,27 @@ namespace xo { DDefineSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { + if (defstate_ == defexprstatetype::def_5) + { + this->defstate_ = defexprstatetype::def_6; + + def_expr_.data()->assign_rhs(expr); + return; + } + p_psm->illegal_parsed_expression("DDefineSsm::on_parsed_expression", expr, this->get_expect_str()); } + void + DDefineSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + this->on_parsed_expression(expr, p_psm); + this->on_semicolon_token(Token::semicolon_token(), p_psm); + } + bool DDefineSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 3f817763..cea683c4 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -206,6 +206,17 @@ namespace xo { this->get_expect_str()); } + void + DExpectExprSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + // expression (reported by nested ProgressSsm) + // completes this DExpectExprSsm's assignment + + p_psm->pop_ssm(); + p_psm->on_parsed_expression_with_semicolon(expr); + } + bool DExpectExprSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index a1db308c..e55d35be 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -83,6 +83,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectSymbolSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 9a97ef2d..30520811 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -172,6 +172,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectTypeSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + bool DExpectTypeSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index a5b7edd6..e67790d5 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -223,6 +223,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExprSeqState::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + bool DExprSeqState::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index d141daf6..f202728e 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -213,11 +213,12 @@ namespace xo { { /* note: implementation should parallel .on_rightparen_token() */ -#ifdef NOT_YET + (void)tk; + obj expr = this->assemble_expr(p_psm); p_psm->pop_ssm(); - p_psm->on_expr_with_semicolon(expr); + p_psm->on_parsed_expression_with_semicolon(expr); /* control here on input like: * (1.234; @@ -232,11 +233,12 @@ namespace xo { * d. expr_rhs_expression forwards expression to [lparen_0] * e. lparen_0 would advance to [lparen_1], but rejects semicolon */ -#endif +#ifdef OBSOLETE p_psm->illegal_input_on_token("DProgressSsm::on_semicolon_token", tk, this->get_expect_str()); +#endif } void @@ -266,6 +268,15 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DProgressSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + #ifdef NOT_YET void progress_xs::apply_type_error(const char * self_name, @@ -967,6 +978,194 @@ namespace xo { } #endif } + + obj + DProgressSsm::assemble_expr(ParserStateMachine * p_psm) + { + /* need to defer building Apply incase expr followed by higher-precedence operator: + * consider input like + * 3.14 + 2.0 * ... + */ + + constexpr const char * c_self_name = "DProgressSsm::assemble_expr"; + + if ((op_type_ != optype::invalid) && rhs_) { + std::string errmsg_string = tostr("expected expression on rhs of operator op", + xtag("lhs", lhs_), + xtag("op", op_type_)); + + auto errmsg = DString::from_view(p_psm->expr_alloc(), + std::string_view(errmsg_string)); + + p_psm->capture_error(c_self_name, errmsg); + } + + /* consecutive expressions not legal, e.g: + * 3.14 6.28 + * but expressions surrounding an infix operators is: + * 3.14 / 6.28 + */ + switch (op_type_) { + case optype::invalid: + return this->lhs_; + + case optype::op_assign: + case optype::op_equal: + case optype::op_not_equal: + case optype::op_less: + case optype::op_less_equal: + case optype::op_great: + case optype::op_great_equal: + case optype::op_add: + case optype::op_subtract: + case optype::op_multiply: + case optype::op_divide: + // TODO: implement binary operator expression assembly + break; + +#ifdef NOT_YET +case optype::op_assign: + { + bp lhs = Variable::from(this->lhs_); + + if (!lhs) { + throw std::runtime_error + (tostr("progress_xs::assemble_expr", + " expect variable on lhs of assignment operator :=", + xtag("lhs", lhs_), + xtag("rhs", rhs_))); + } + + return AssignExpr::make(lhs.promote(), + this->rhs_); + } + +case optype::op_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_eq_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_not_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_ne_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_less: + // TODO: floating-point less-than + + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_lt_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_less_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_le_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_great: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_gt_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_great_equal: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_ge_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + + assert(false); + +case optype::op_add: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_add2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_add2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; +case optype::op_subtract: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_sub2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_sub2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_multiply: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_mul2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_mul2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + + break; + +case optype::op_divide: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_div2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_div2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; +#endif + + case optype::n_optype: + /* unreachable */ + assert(false); + break; + } + + return obj(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index c953b1e1..a789bce9 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -94,6 +94,12 @@ ISyntaxStateMachine_Any::on_parsed_expression(Opaque, obj, ParserSt _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_expression_with_semicolon(Opaque, obj, ParserStateMachine *) -> void +{ + _fatal(); +} + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index cab18818..89589841 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_expression_with_semicolon(DDefineSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index feb2d13a..858ce1ab 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression_with_semicolon(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 714ef041..1982212c 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression_with_semicolon(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 2dd5a9ca..eb66f8db 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression_with_semicolon(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 6d42b86b..cfd419b9 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DExprSeqState::on_parsed_expression_with_semicolon(DExprSeqState & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 62dd2ce0..53c8706c 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DProgressSsm::on_parsed_expression_with_semicolon(DProgressSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 262db2df..66e4703e 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -129,6 +129,26 @@ namespace xo { this->stack_->top().on_parsed_typedescr(td, this); } + void + ParserStateMachine::on_parsed_expression(obj expr) + { + scope log(XO_DEBUG(debug_flag_), xtag("expr", expr)); + + assert(stack_); + + this->top_ssm().on_parsed_expression(expr, this); + } + + void + ParserStateMachine::on_parsed_expression_with_semicolon(obj expr) + { + scope log(XO_DEBUG(debug_flag_), xtag("expr", expr)); + + assert(stack_); + + this->top_ssm().on_parsed_expression_with_semicolon(expr, this); + } + void ParserStateMachine::on_token(const Token & tk) { diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index e70f449b..a8544687 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -177,14 +177,13 @@ namespace xo { } { -#ifdef NOT_YET - auto def_ssm - = obj::from(parser.top_ssm()); + auto & result = parser.on_token(Token::semicolon_token()); - REQUIRE(def_ssm); - REQUIRE(def_ssm.data()->ssm_type() == syntaxstatetype::defexpr); - REQUIRE(def_ssm.data()->defstate() == defexprstatetype::def_5); -#endif + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); } // define-expressions not properly implemented diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index d47b311d..cc6e13d9 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -112,7 +112,7 @@ namespace xo { /** token representing double-colo @c "::" **/ static Token doublecolon() { return Token(tokentype::tk_doublecolon); } /** token representing semicolon @c ";" **/ - static Token semicolon() { return Token(tokentype::tk_semicolon); } + static Token semicolon_token() { return Token(tokentype::tk_semicolon); } /** token representing single-assignment @c "=" (editor bait: equal_token) **/ static Token singleassign_token() { return Token(tokentype::tk_singleassign); } /** token representing unrestricted assignment @c ":=" **/ From 8452ef040c185c7e63ef727ff64d590d21b12288 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 17:41:40 -0500 Subject: [PATCH 049/258] xo-reader2: accept parsed expression at top level.. --- xo-reader2/include/xo/reader2/ParserResult.hpp | 6 ++++++ xo-reader2/include/xo/reader2/ParserStateMachine.hpp | 4 ++++ xo-reader2/src/reader2/DExprSeqState.cpp | 12 +++++------- xo-reader2/src/reader2/ParserResult.cpp | 10 ++++++++++ xo-reader2/src/reader2/ParserStateMachine.cpp | 9 ++++++++- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/xo-reader2/include/xo/reader2/ParserResult.hpp b/xo-reader2/include/xo/reader2/ParserResult.hpp index 45064d32..6592c7da 100644 --- a/xo-reader2/include/xo/reader2/ParserResult.hpp +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -41,6 +41,12 @@ namespace xo { std::string_view error_src_fn, const DString * error_description); + /** create ParserResult for parsing success; + * parsing yields expression @p expr + **/ + static ParserResult expression(std::string_view ssm, + obj expr); + /** create ParserResult for a parsing error. * Reporting detailed message @p errmsg * from syntax state machine @p ssm diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 42c8af64..b838efe5 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -148,6 +148,10 @@ namespace xo { /** @defgroup scm-parserstatemachine-error-entrypoints error entry points **/ ///@{ + /** capture result expression @p expr **/ + void capture_result(std::string_view ssm_anme, + obj expr); + /** capture error message @p errmsg from @p ssm_name, * as current state machine output. * diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index e67790d5..33a68c15 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -218,18 +218,16 @@ namespace xo { DExprSeqState::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_expression("DExprSeqState::on_parsed_expression", - expr, - this->get_expect_str()); + // toplevel expr sequence accepts an arbitrary number of expressions. + + p_psm->capture_result("DExprSeqState::on_parsed_expression", expr); } void DExprSeqState::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + ParserStateMachine * p_psm) { - p_psm->illegal_parsed_expression("DExprSeqState::on_parsed_expression_with_semicolon", - expr, - this->get_expect_str()); + p_psm->capture_result("DExprSeqState::on_parsed_expression_with_semicolon", expr); } bool diff --git a/xo-reader2/src/reader2/ParserResult.cpp b/xo-reader2/src/reader2/ParserResult.cpp index 312538b1..974724d9 100644 --- a/xo-reader2/src/reader2/ParserResult.cpp +++ b/xo-reader2/src/reader2/ParserResult.cpp @@ -36,6 +36,16 @@ namespace xo { error_description_{error_description} {} + ParserResult + ParserResult::expression(std::string_view ssm_name, + obj expr) + { + return ParserResult(parser_result_type::expression, + expr, + ssm_name, + nullptr); + } + ParserResult ParserResult::error(std::string_view ssm_name, const DString * errmsg) diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 66e4703e..80841fd8 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -288,6 +288,13 @@ namespace xo { stack_->top().on_semicolon_token(tk, this); } + void + ParserStateMachine::capture_result(std::string_view ssm_name, + obj expr) + { + this->result_ = ParserResult::expression(ssm_name, expr); + } + void ParserStateMachine::capture_error(std::string_view ssm_name, const DString * errmsg) @@ -321,7 +328,7 @@ namespace xo { void ParserStateMachine::illegal_input_on_symbol(std::string_view ssm_name, std::string_view sym, - std::string_view expect_str) + std::string_view expect_str) { // TODO: // - want to write error message using DArena From 2bf23b41a98972263f03f8c4b6499a1a016df3c3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 18:40:42 -0500 Subject: [PATCH 050/258] xo-reader2 xo-expression2: define example working and printing def foo : f64 = 3.141593; --- xo-expression2/CMakeLists.txt | 14 +++++ xo-expression2/idl/IPrintable_DConstant.json5 | 13 ++++ .../include/xo/expression2/DConstant.hpp | 3 + .../detail/IPrintable_DConstant.hpp | 62 +++++++++++++++++++ xo-expression2/src/expression2/CMakeLists.txt | 2 + xo-expression2/src/expression2/DConstant.cpp | 18 ++++++ .../src/expression2/DDefineExpr.cpp | 20 ++++-- .../src/expression2/IPrintable_DConstant.cpp | 28 +++++++++ .../expression2_register_facets.cpp | 18 +++++- xo-facet/include/xo/facet/FacetRegistry.hpp | 3 +- xo-reader2/src/reader2/DDefineSsm.cpp | 4 +- xo-reader2/src/reader2/DProgressSsm.cpp | 31 +++++++++- 12 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 xo-expression2/idl/IPrintable_DConstant.json5 create mode 100644 xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp create mode 100644 xo-expression2/src/expression2/IPrintable_DConstant.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index f286f2ad..52e9d380 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -44,6 +44,8 @@ xo_add_genfacet( OUTPUT_CPP_DIR src/expression2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-expression-constant @@ -56,6 +58,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-constant + FACET_PKG xo_printable2 + FACET Printable + REPR Constant + INPUT idl/IPrintable_DConstant.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + # ---------------------------------------------------------------- # note: manual target; generated code committed to git diff --git a/xo-expression2/idl/IPrintable_DConstant.json5 b/xo-expression2/idl/IPrintable_DConstant.json5 new file mode 100644 index 00000000..1d955d79 --- /dev/null +++ b/xo-expression2/idl/IPrintable_DConstant.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DConstant", + using_doxygen: true, + repr: "DConstant", + doc: [ "implement APrintable for DConstant" ], +} diff --git a/xo-expression2/include/xo/expression2/DConstant.hpp b/xo-expression2/include/xo/expression2/DConstant.hpp index a73ea2df..81561e68 100644 --- a/xo-expression2/include/xo/expression2/DConstant.hpp +++ b/xo-expression2/include/xo/expression2/DConstant.hpp @@ -22,6 +22,7 @@ namespace xo { using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using typeseq = xo::reflect::typeseq; + using ppindentinfo = xo::print::ppindentinfo; public: explicit DConstant(obj value) noexcept; @@ -45,6 +46,8 @@ namespace xo { void assign_valuetype(TypeDescr td) noexcept { typeref_.resolve(td); } + bool pretty(const ppindentinfo & ppii) const; + private: static TypeDescr _lookup_td(typeseq tseq); diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp new file mode 100644 index 00000000..a1e31382 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DConstant.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DConstant.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DConstant.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DConstant.hpp" + +namespace xo { namespace scm { class IPrintable_DConstant; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DConstant + **/ + class IPrintable_DConstant { + public: + /** @defgroup scm-printable-dconstant-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dconstant-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DConstant & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index f2dfe7e7..17c34275 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -11,7 +11,9 @@ set(SELF_SRCS TypeRef.cpp IExpression_Any.cpp + IExpression_DConstant.cpp + IPrintable_DConstant.cpp IExpression_DVariable.cpp IPrintable_DVariable.cpp diff --git a/xo-expression2/src/expression2/DConstant.cpp b/xo-expression2/src/expression2/DConstant.cpp index 5bf98bfc..a0b255a6 100644 --- a/xo-expression2/src/expression2/DConstant.cpp +++ b/xo-expression2/src/expression2/DConstant.cpp @@ -7,12 +7,16 @@ #include "TypeDescr.hpp" #include #include +#include #include +#include #include namespace xo { using xo::scm::DFloat; using xo::scm::DInteger; + using xo::print::APrintable; + using xo::facet::FacetRegistry; using xo::reflect::Reflect; using xo::reflect::TypeDescr; using xo::reflect::typeseq; @@ -57,6 +61,20 @@ namespace xo { return nullptr; } + + bool + DConstant::pretty(const ppindentinfo & ppii) const + { + obj value + = FacetRegistry::instance().variant(value_); + + return ppii.pps()->pretty_struct + (ppii, + "DConstant", + refrtag("value_.tseq", value_._typeseq()), + refrtag("value.tseq", value._typeseq()), + refrtag("value", value)); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index e193c4d4..47465c0e 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -79,11 +79,21 @@ namespace xo { auto rhs = FacetRegistry::instance().try_variant(rhs_); - return ppii.pps()->pretty_struct - (ppii, - "DDefineExpr", - refrtag("lhs", lhs), - refrtag("rhs", cond(rhs_, rhs, "nullptr"))); + // note: xo::print::cond() doesn't resolve the way we want here + + if (rhs) { + return ppii.pps()->pretty_struct + (ppii, + "DDefineExpr", + refrtag("lhs", lhs), + refrtag("rhs", rhs)); + } else { + return ppii.pps()->pretty_struct + (ppii, + "DDefineExpr", + refrtag("lhs", lhs)); + + } } } /*namespace scm*/ diff --git a/xo-expression2/src/expression2/IPrintable_DConstant.cpp b/xo-expression2/src/expression2/IPrintable_DConstant.cpp new file mode 100644 index 00000000..1bacfb9d --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DConstant.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DConstant.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DConstant.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DConstant.json5] +**/ + +#include "detail/IPrintable_DConstant.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DConstant::pretty(const DConstant & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DConstant.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index e6715769..1854f3eb 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -8,10 +8,15 @@ #include #include +#include #include +#include #include +#include +#include + #include #include #include @@ -32,13 +37,24 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); - FacetRegistry::register_impl(); + // Expression + // +- Constant + // +- Variable + // \- DefineExpr + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DUniqueString.tseq", typeseq::id())); log && log(xtag("DDefineExpr.tseq", typeseq::id())); log && log(xtag("DVariable.tseq", typeseq::id())); + log && log(xtag("DConstant.tseq", typeseq::id())); log && log(xtag("AExpression.tqseq", typeseq::id())); diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index aa481a0c..da3a6676 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -128,7 +128,8 @@ namespace xo { if (!retval) throw std::runtime_error(tostr("FacetRegistry::try_variant failed", xtag("AFrom.tseq", typeseq::id()), - xtag("ATo.tseq", typeseq::id()))); + xtag("ATo.tseq", typeseq::id()), + xtag("DRepr", from._typeseq()))); return retval; } diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 6de3bd93..21ff70f0 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -11,6 +11,7 @@ #include "ssm/IPrintable_DDefineSsm.hpp" #include #include +#include #ifdef NOT_YET #include "parserstatemachine.hpp" @@ -22,6 +23,7 @@ namespace xo { using xo::print::APrintable; + using xo::facet::FacetRegistry; using xo::facet::with_facet; using xo::facet::typeseq; @@ -617,7 +619,7 @@ namespace xo { bool DDefineSsm::pretty(const ppindentinfo & ppii) const { - auto expr = with_facet::mkobj(def_expr_.data()); + auto expr = FacetRegistry::instance().variant(def_expr_); return ppii.pps()->pretty_struct (ppii, diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index f202728e..ec19e994 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -5,7 +5,10 @@ #include "DProgressSsm.hpp" #include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" +#include +#include #include +#include #ifdef NOT_YET #include "apply_xs.hpp" @@ -25,6 +28,8 @@ namespace xo { using xo::scm::Variable; using xo::scm::Apply; #endif + using xo::print::APrintable; + using xo::facet::FacetRegistry; using xo::facet::with_facet; using xo::reflect::typeseq; @@ -211,12 +216,23 @@ namespace xo { DProgressSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + /* note: implementation should parallel .on_rightparen_token() */ (void)tk; obj expr = this->assemble_expr(p_psm); + { + obj expr_pr = FacetRegistry::instance().variant(expr); + + assert(expr_pr); + + log && log(xtag("expr", expr_pr)); + } + p_psm->pop_ssm(); p_psm->on_parsed_expression_with_semicolon(expr); @@ -951,12 +967,23 @@ namespace xo { bool DProgressSsm::pretty(const xo::print::ppindentinfo & ppii) const { + scope log(XO_DEBUG(true)); + log && log(xtag("lhs_.tseq", lhs_._typeseq())); + log && log(xtag("rhs_.tseq", rhs_._typeseq())); + + obj lhs + = FacetRegistry::instance().variant(lhs_); + + obj rhs; + if (rhs_) + rhs = FacetRegistry::instance().variant(rhs_); + return ppii.pps()->pretty_struct (ppii, "DProgressSsm", - refrtag("lhs", lhs_), + refrtag("lhs", lhs), refrtag("op", op_type_), - refrtag("rhs", rhs_)); + cond(rhs, refrtag("rhs", rhs), "nullptr")); #ifdef NOPE if (ppii.upto()) { From dc9f29275a2d7fe484cbdface0be86a24245ac7d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 22 Jan 2026 21:03:40 -0500 Subject: [PATCH 051/258] xo-reader2: working on example parser repl --- .../example/readerreplxx/readerreplxx.cpp | 146 ++++++++++++++++++ .../include/xo/reader2/ParserResult.hpp | 2 +- .../include/xo/reader2/ReaderConfig.hpp | 54 +++++++ .../include/xo/reader2/SchematikaParser.hpp | 2 +- .../include/xo/reader2/SchematikaReader.hpp | 70 +++++++++ xo-reader2/src/reader2/CMakeLists.txt | 3 + xo-reader2/src/reader2/ReaderConfig.cpp | 13 ++ xo-reader2/src/reader2/SchematikaReader.cpp | 105 +++++++++++++ .../include/xo/tokenizer2/TokenizerError.hpp | 2 +- .../include/xo/tokenizer2/scan_result.hpp | 4 +- 10 files changed, 396 insertions(+), 5 deletions(-) create mode 100644 xo-reader2/example/readerreplxx/readerreplxx.cpp create mode 100644 xo-reader2/include/xo/reader2/ReaderConfig.hpp create mode 100644 xo-reader2/include/xo/reader2/SchematikaReader.hpp create mode 100644 xo-reader2/src/reader2/ReaderConfig.cpp create mode 100644 xo-reader2/src/reader2/SchematikaReader.cpp diff --git a/xo-reader2/example/readerreplxx/readerreplxx.cpp b/xo-reader2/example/readerreplxx/readerreplxx.cpp new file mode 100644 index 00000000..e30ab047 --- /dev/null +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -0,0 +1,146 @@ +/** @file readerreplxx.cpp **/ + +#include "xo/reader/reader.hpp" +#include +#include +#include // for isatty + +// presumeably replxx assumes input is a tty +// +bool replxx_getline(bool interactive, + std::size_t parser_stack_size, + replxx::Replxx & rx, + const char ** p_input) +{ + using namespace std; + + char const * prompt = ""; + + if (interactive) { + if (parser_stack_size <= 1) + prompt = "> "; + else + prompt = ". "; + } + + const char * input_cstr = rx.input(prompt); + + bool retval = (input_cstr != nullptr); + + if (retval) { + //cerr << "got reval->true" << endl; + + input = input_cstr; + + } else { + //cerr << "got retval->false" << endl; + } + + rx.history_add(input); + + return retval; +} + +void +welcome(std::ostream& os) +{ + using namespace std; + + os << "read-eval-print loop for schematika expressions" << endl; + os << " ctrl-a/ctrl-e beginning/end of line" << endl; + os << " ctrl-u delete entire line" << endl; + os << " ctrl-k delete to end of line" << endl; + os << " meta- backward delete word" << endl; + os << " |meta-p previous command from history" << endl; + os << " |meta-n next command from history" << endl; + os << " / page through history faster" << endl; + os << " ctrl-s/ctrl-r forward/backward history search" << endl; + os << endl; +} + +int +main() +{ + using namespace replxx; + using namespace xo::scm; + using xo::scm::Expression; + using xo::print::ppconfig; + using xo::print::ppstate_standalone; + using xo::rp; + using namespace std; + + using span_type = xo::scm::span; + + bool interactive = isatty(STDIN_FILENO); + + Replxx rx; + rx.set_max_history_size(1000); + rx.history_load("repl_history.txt"); +// rx.bind_key_internal(Replxx::KEY::control('p'), "history_previous"); +// rx.bind_key_internal(Replxx::KEY::control('n'), "history_next"); + + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag)); + + DArena expr_arena = DArena::map(ArenaConfig{ .name_ = "expr-arena", .size_ = 2*1024*1024; }); + obj expr_alloc = with_facet::mkobj(&expr_arena); + constexpr size_t c_max_stringtable_cap = 1024*1024; + SchematikaParser parser(expr_arena.config_, c_max_stringtable_cap, expr_alloc, c_debug_flag); + + parser.begin_interactive_session(); + + string input_str; + + bool eof = false; + + span_type input; + std::size_t parser_stack_size = 0; + + welcome(cerr); + + while (replxx_getline(interactive, parser_stack_size, rx, input_str)) { + input = span_type::from_string(input_str); + + while (!input.empty()) { + auto [expr, consumed, psz, error] = rdr.read_expr(input, eof); + + if (expr) { + ppconfig ppc; + ppstate_standalone pps(&cout, 0, &ppc); + + pps.prettyn(expr); + } else if (error.is_error()) { + cout << "parsing error (detected in " << error.src_function() << "): " << endl; + error.report(cout); + + /* discard stashed remainder of input line + * (for nicely-formatted errors) + */ + rdr.reset_to_idle_toplevel(); + break; + } + + input = input.after_prefix(consumed); + parser_stack_size = psz; + } + + /* here: input.empty() or error encountered */ + + } + + auto [expr, _1, _2, error] = rdr.read_expr(input, true /*eof*/); + + if (expr) { + ppconfig ppc; + ppstate_standalone pps(&cout, 0, &ppc); + + pps.prettyn>(rp(expr)); + } else if (error.is_error()) { + cout << "parsing error (detected in " << error.src_function() << "): " << endl; + error.report(cout); + } + + rx.history_save("repl_history.txt"); +} + +/* end readerreplxx.cpp */ diff --git a/xo-reader2/include/xo/reader2/ParserResult.hpp b/xo-reader2/include/xo/reader2/ParserResult.hpp index 6592c7da..492b78b0 100644 --- a/xo-reader2/include/xo/reader2/ParserResult.hpp +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -67,7 +67,7 @@ namespace xo { /** pretty-printing support **/ bool pretty(const ppindentinfo & ppii) const; - private: + public: /** none|expression|error_description * * @text diff --git a/xo-reader2/include/xo/reader2/ReaderConfig.hpp b/xo-reader2/include/xo/reader2/ReaderConfig.hpp new file mode 100644 index 00000000..e7f0d7a6 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ReaderConfig.hpp @@ -0,0 +1,54 @@ +/** @file ReaderConfig.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include +#include + +namespace xo { + namespace scm { + + /** @brief Configuration for SchemtikaReader + **/ + struct ReaderConfig { + using CircularBufferConfig = xo::mm::CircularBufferConfig; + using ArenaConfig = xo::mm::ArenaConfig; + using size_t = std::size_t; + + /** tokenizer circular buffer config **/ + CircularBufferConfig tk_buffer_config_ {.name_ = "tk-buffer", + .max_capacity_ = 2*1024*1024, + .hugepage_z_ = 2*1024*1024, + .threshold_move_efficiency_ = 50.0, + .max_captured_span_ = 128 }; + /** debug flag for schematika tokenizer **/ + bool tk_debug_flag_ = false; + /** arena configuration for parser stack **/ + ArenaConfig parser_arena_config_ { .name_ = "parer-arena", + .size_ = 2*1024*1024, + .hugepage_z_ = 2*1024*1024, + .store_header_flag_ = false, + .header_{}, + .debug_flag_ = false }; + /** max size (in bytes) of stringtable **/ + size_t max_stringtable_cap_ = 64*1024; + /** debug flag for schematika parser **/ + bool parser_debug_flag_ = false; +#ifdef NOT_YET + /** arena configuration for output expressions **/ + ArenaConfig expr_arena_config_ { .name_ = "expr-arena", + .size_ = 2*1024*1024, + .hugepage_z_ = 2*1024*1024, + .store_header_flag_ = false, + .header_{}, + .debug_flag_ = false }; +#endif + }; + + } /*namespace scm*/ +} /*namepspace xo*/ + +/* end ReaderConfig.hpp */ diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index aecc3c9a..e2667b5f 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -162,7 +162,7 @@ namespace xo { /** create parser in initial state; * parser is ready to receive tokens via @ref include_token * - * @p config arena configuration for parser memory + * @p config arena configuration for parser stack * @p expr_alloc allocator for schematika expressions. * Probably shared with execution. * @p debug_flag true to enable debug logging diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp new file mode 100644 index 00000000..c60612a2 --- /dev/null +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -0,0 +1,70 @@ +/** @file SchematikaReader.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ReaderConfig.hpp" +#include "SchematikaParser.hpp" +#include + +namespace xo { + namespace scm { + struct ReaderResult { + using span_type = xo::mm::span; + + bool is_tk_error() const { return tk_error_.is_error(); } + + /** schematika expression parsed from input **/ + obj expr_; + /** input span up to end of expression. + * only relevant when result type is expression. + * (otherwise treat entire input as consumed) + **/ + span_type consumed_; + + /** {src_function, error_description, input_state, error_pos} **/ + TokenizerError tk_error_; + }; + + /** @class SchematikaReader + * @brief Pipeline comprising Schematika tokenizer and parser + * + * Consumes text; produces expressions + **/ + class SchematikaReader { + public: + using AAllocator = xo::mm::AAllocator; + + public: + SchematikaReader(const ReaderConfig & config, + obj expr_alloc); + + /** prepare interactive session + * (allows rvalue expressions at toplevel) + **/ + void begin_interactive_session(); + + /** consume input @p input_cstr **/ + const ReaderResult & read_expr(const char * input_cstr, bool eof); + + private: + /** tokenizer converts a stream of chars + * to a stream of lexical tokens + **/ + Tokenizer tokenizer_; + + /** parser converts a stream of tokens + * to a stream of expressions + **/ + SchematikaParser parser_; + + /** current output from reader **/ + ReaderResult result_; + + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end SchematikaReader.hpp */ diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 232174ef..97c46c6a 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -4,6 +4,9 @@ set(SELF_LIB xo_reader2) set(SELF_SRCS init_reader2.cpp + SchematikaReader.cpp + ReaderConfig.cpp + SchematikaParser.cpp ParserStateMachine.cpp ParserStack.cpp diff --git a/xo-reader2/src/reader2/ReaderConfig.cpp b/xo-reader2/src/reader2/ReaderConfig.cpp new file mode 100644 index 00000000..7db5fe59 --- /dev/null +++ b/xo-reader2/src/reader2/ReaderConfig.cpp @@ -0,0 +1,13 @@ +/** @file ReaderConfig.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ReaderConfig.hpp" + +namespace xo { + namespace scm { + } +} /*namespace xo*/ + +/* end ReaderConfig.cpp */ diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp new file mode 100644 index 00000000..f8c6a152 --- /dev/null +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -0,0 +1,105 @@ +/** @file SchematikaReader.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "SchematikaReader.hpp" + +namespace xo { + namespace scm { + SchematikaReader::SchematikaReader(const ReaderConfig & config, + obj expr_alloc) + : tokenizer_{config.tk_buffer_config_, config.tk_debug_flag_}, + parser_{config.parser_arena_config_, + config.max_stringtable_cap_, + expr_alloc, + config.parser_debug_flag_} + { + } + + void + SchematikaReader::begin_interactive_session() + { + parser_.begin_interactive_session(); + } + + // TODO: + // Schematika::end_interactive_session() + + const ReaderResult & + SchematikaReader::read_expr(const char * input_cstr, bool eof) + { + if (input_cstr && *input_cstr) { + auto [error, input] + = tokenizer_.buffer_input_line(input_cstr, + false /*!eof*/); + // log && log(xtag("msg", "buffered input line")); + // log && log(xtag("input", input)); + + + + while (!input.empty()) { + auto [tk, consumed, error] = tkz.scan(input); + + if (!tk.is_valid() && error.is_error()) { + this->result_ = ReaderResult { .expr_ = obj(), + .tk_error_ = std::move(error), + .consumed_ = nullptr }; + return result_; + } + + // log && log(xtag("consumed", consumed), xtag("tk", tk)); + + if (tk.is_valid()) { + // presult { + // result_type :: parser_result_type = none|expression|error + // result_expr :: obj + // error_src_function :: string_view + // error_description :: const DString * + // } + // + const ParserResult & presult = parser_include_token(tk); + + if (presult.is_error()) { + // tk_error { + // src_function :: const char * + // error_description :: string + // input_state { + // current_line :: span + // tk_start :: size_t + // current_pos :: size_t + // whitespace :: size_t + // debug_flag :: bool + // } + // error_pos :: size_t + // } + // + // tk_error.report(cout); + + this->result_ = ReaderResult { .expr = obj(), + .tk_error_ = std::move(error), + .consumed_ = nullptr }; + + // carefully created error description, maybe + this->result.tk_error_.error_description_ = presult.error_description_; + + } + + xxxx; + } else if (error.is_error()) { + xxxx; + // error.report(cout); + break; + } + + input = input.after_prefix(consumed); + } + } + + ++line_no; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end SchematikaReader.cpp */ diff --git a/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp b/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp index a1cb99ee..b8a50988 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp @@ -99,7 +99,7 @@ namespace xo { size_t error_pos_ = 0; ///@} - }; /*error_token*/ + }; inline std::ostream & operator<< (std::ostream & os, diff --git a/xo-tokenizer2/include/xo/tokenizer2/scan_result.hpp b/xo-tokenizer2/include/xo/tokenizer2/scan_result.hpp index 249154f1..45718c5c 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/scan_result.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/scan_result.hpp @@ -28,9 +28,9 @@ namespace xo { **/ class scan_result { public: - using CharT = char; + //using CharT = char; using token_type = Token; - using span_type = xo::mm::span; + using span_type = xo::mm::span; using error_type = TokenizerError; using input_state_type = TkInputState; From 258d0823f59fbcbc4a2caf18554c9a1b92d93962 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 11:54:32 -0500 Subject: [PATCH 052/258] xo-reader2: + example app 'readerreplxx' --- xo-arena/include/xo/arena/ArenaConfig.hpp | 8 + xo-gc/include/xo/gc/DX1Collector.hpp | 11 ++ xo-gc/src/gc/DX1Collector.cpp | 9 + xo-reader2/CMakeLists.txt | 5 + xo-reader2/example/CMakeLists.txt | 1 + .../example/readerreplxx/CMakeLists.txt | 14 ++ .../example/readerreplxx/readerreplxx.cpp | 159 ++++++++++-------- .../include/xo/reader2/SchematikaParser.hpp | 1 + .../include/xo/reader2/SchematikaReader.hpp | 22 ++- xo-reader2/src/reader2/CMakeLists.txt | 4 +- xo-reader2/src/reader2/SchematikaParser.cpp | 1 + xo-reader2/src/reader2/SchematikaReader.cpp | 77 ++++++--- xo-tokenizer2/example/tokenrepl/tokenrepl.cpp | 45 ++--- .../include/xo/tokenizer2/Tokenizer.hpp | 5 +- .../include/xo/tokenizer2/TokenizerError.hpp | 16 +- xo-tokenizer2/src/tokenizer2/Tokenizer.cpp | 17 +- 16 files changed, 261 insertions(+), 134 deletions(-) create mode 100644 xo-reader2/example/CMakeLists.txt create mode 100644 xo-reader2/example/readerreplxx/CMakeLists.txt diff --git a/xo-arena/include/xo/arena/ArenaConfig.hpp b/xo-arena/include/xo/arena/ArenaConfig.hpp index 4d79637b..db5a4400 100644 --- a/xo-arena/include/xo/arena/ArenaConfig.hpp +++ b/xo-arena/include/xo/arena/ArenaConfig.hpp @@ -17,6 +17,14 @@ namespace xo { * @brief configuration for a @ref DArena instance **/ struct ArenaConfig { + /** @defgroup mm-arenaconfig-ctors **/ + + ArenaConfig with_size(std::size_t z) { + ArenaConfig copy(*this); + copy.size_ = z; + return copy; + } + /** @defgroup mm-arenaconfig-instance-vars ArenaConfig members **/ ///@{ diff --git a/xo-gc/include/xo/gc/DX1Collector.hpp b/xo-gc/include/xo/gc/DX1Collector.hpp index 33c9f56d..78b55d20 100644 --- a/xo-gc/include/xo/gc/DX1Collector.hpp +++ b/xo-gc/include/xo/gc/DX1Collector.hpp @@ -69,6 +69,12 @@ namespace xo { constexpr std::uint64_t tseq_mask_shifted() const; #endif + + /** copy of this config, + * with @c arena_config_.size_ set to @p gen_z + **/ + CollectorConfig with_size(std::size_t gen_z); + generation age2gen(object_age age) const noexcept { return generation(age % n_survive_threshold_); } @@ -169,6 +175,11 @@ namespace xo { /** Create X1 collector instance. **/ explicit DX1Collector(const CollectorConfig & cfg); + /** create instance with default configuration, + * generation size @p gen_z + **/ + DX1Collector make_std(std::size_t gen_z); + std::string_view name() const { return config_.name_; } const DArena * get_object_types() const noexcept { return &object_types_; } diff --git a/xo-gc/src/gc/DX1Collector.cpp b/xo-gc/src/gc/DX1Collector.cpp index 263e5b8e..3a77e15f 100644 --- a/xo-gc/src/gc/DX1Collector.cpp +++ b/xo-gc/src/gc/DX1Collector.cpp @@ -24,6 +24,15 @@ namespace xo { using xo::facet::with_facet; namespace mm { + + CollectorConfig + CollectorConfig::with_size(std::size_t gen_z) + { + CollectorConfig copy = *this; + copy.arena_config_ = arena_config_.with_size(gen_z); + return copy; + } + #ifdef NOT_USING constexpr std::uint64_t CollectorConfig::gen_mult() const { diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index bc35b6a9..43c747f6 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -197,6 +197,11 @@ xo_add_genfacet_all(xo-reader2-genfacet-all) add_subdirectory(src/reader2) +# ---------------------------------------------------------------- +# example programs + +add_subdirectory(example) + # ---------------------------------------------------------------- # cmake helper (for external xo-reader2 users) diff --git a/xo-reader2/example/CMakeLists.txt b/xo-reader2/example/CMakeLists.txt new file mode 100644 index 00000000..fbb01ff0 --- /dev/null +++ b/xo-reader2/example/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(readerreplxx) diff --git a/xo-reader2/example/readerreplxx/CMakeLists.txt b/xo-reader2/example/readerreplxx/CMakeLists.txt new file mode 100644 index 00000000..37ecd45e --- /dev/null +++ b/xo-reader2/example/readerreplxx/CMakeLists.txt @@ -0,0 +1,14 @@ +# xo-reader2/example/readerreplxx/CMakeLists.txt + +set(SELF_EXE xo_reader2_readereplxx) +set(SELF_SRCS readerreplxx.cpp) + +if (XO_ENABLE_EXAMPLES) + xo_add_executable(${SELF_EXE} ${SELF_SRCS}) + xo_self_dependency(${SELF_EXE} xo_reader2) + xo_external_target_dependency(${SELF_EXE} replxx replxx::replxx) + + # replxx requires this + find_package(Threads REQUIRED) + target_link_libraries(${SELF_EXE} PUBLIC Threads::Threads) +endif() diff --git a/xo-reader2/example/readerreplxx/readerreplxx.cpp b/xo-reader2/example/readerreplxx/readerreplxx.cpp index e30ab047..76bd0520 100644 --- a/xo-reader2/example/readerreplxx/readerreplxx.cpp +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -1,6 +1,11 @@ /** @file readerreplxx.cpp **/ -#include "xo/reader/reader.hpp" +#include +#include +#include +#include +//#include +#include #include #include #include // for isatty @@ -8,7 +13,7 @@ // presumeably replxx assumes input is a tty // bool replxx_getline(bool interactive, - std::size_t parser_stack_size, + bool is_at_toplevel, replxx::Replxx & rx, const char ** p_input) { @@ -17,32 +22,23 @@ bool replxx_getline(bool interactive, char const * prompt = ""; if (interactive) { - if (parser_stack_size <= 1) - prompt = "> "; - else - prompt = ". "; + prompt = ((is_at_toplevel) ? "> " : ". "); } const char * input_cstr = rx.input(prompt); bool retval = (input_cstr != nullptr); - if (retval) { - //cerr << "got reval->true" << endl; + if (retval) + *p_input = input_cstr; - input = input_cstr; - - } else { - //cerr << "got retval->false" << endl; - } - - rx.history_add(input); + rx.history_add(input_cstr); return retval; } void -welcome(std::ostream& os) +welcome(std::ostream & os) { using namespace std; @@ -58,18 +54,68 @@ welcome(std::ostream& os) os << endl; } +namespace { + using xo::scm::SchematikaReader; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; + using std::cout; + using std::endl; + + /** body of read-parse-print loop + * + * true -> no errors; + * false -> reader encountered error + **/ + bool + reader_seq(SchematikaReader * p_reader, + SchematikaReader::span_type * p_input, + bool eof) + { + auto [expr, remaining, error] = p_reader->read_expr(*p_input, eof); + + if (expr) { + ppconfig ppc; + ppstate_standalone pps(&cout, 0, &ppc); + + pps.prettyn(expr); + + *p_input = remaining; + + return true; + } else if (error.is_error()) { + cout << "parsing error (detected in " << error.src_function() << "): " << endl; + error.report(cout); + + /* discard stashed remainder of input line + * (for nicely-formatted errors) + */ + p_reader->reset_to_idle_toplevel(); + + return false; + } else { + /* partial expression or whitespace input, no error */ + return true; + } + } +} + int main() { using namespace replxx; - using namespace xo::scm; - using xo::scm::Expression; - using xo::print::ppconfig; - using xo::print::ppstate_standalone; - using xo::rp; - using namespace std; - using span_type = xo::scm::span; + using xo::scm::SchematikaReader; + using xo::scm::ReaderConfig; + using xo::mm::AAllocator; + using xo::mm::DX1Collector; + using xo::mm::CollectorConfig; + using xo::mm::DArena; + //using xo::print::ppconfig; + //using xo::print::ppstate_standalone; + using xo::facet::with_facet; + using xo::facet::obj; + using xo::scope; + using namespace std; bool interactive = isatty(STDIN_FILENO); @@ -82,63 +128,40 @@ main() constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag)); - DArena expr_arena = DArena::map(ArenaConfig{ .name_ = "expr-arena", .size_ = 2*1024*1024; }); - obj expr_alloc = with_facet::mkobj(&expr_arena); - constexpr size_t c_max_stringtable_cap = 1024*1024; - SchematikaParser parser(expr_arena.config_, c_max_stringtable_cap, expr_alloc, c_debug_flag); + CollectorConfig x1_config = (CollectorConfig() + .with_size(4*1024*1024)); + DX1Collector x1(x1_config); + obj expr_alloc = with_facet::mkobj(&x1); - parser.begin_interactive_session(); + // accepting defaults too + ReaderConfig rdr_config = ReaderConfig(); - string input_str; - - bool eof = false; - - span_type input; - std::size_t parser_stack_size = 0; + SchematikaReader rdr(rdr_config, expr_alloc); + using span_type = SchematikaReader::span_type; welcome(cerr); - while (replxx_getline(interactive, parser_stack_size, rx, input_str)) { - input = span_type::from_string(input_str); + rdr.begin_interactive_session(); - while (!input.empty()) { - auto [expr, consumed, psz, error] = rdr.read_expr(input, eof); + bool eof = false; + const char * input_str; + span_type input; - if (expr) { - ppconfig ppc; - ppstate_standalone pps(&cout, 0, &ppc); + while (replxx_getline(interactive, rdr.is_at_toplevel(), rx, &input_str)) { + input = span_type::from_cstr(input_str); - pps.prettyn(expr); - } else if (error.is_error()) { - cout << "parsing error (detected in " << error.src_function() << "): " << endl; - error.report(cout); - - /* discard stashed remainder of input line - * (for nicely-formatted errors) - */ - rdr.reset_to_idle_toplevel(); - break; - } - - input = input.after_prefix(consumed); - parser_stack_size = psz; + while (!input.empty() && reader_seq(&rdr, &input, false /*eof*/)) { + ; } - /* here: input.empty() or error encountered */ - + /* here: either: + * 1. input.empty() or + * 2. error encountered + */ } - auto [expr, _1, _2, error] = rdr.read_expr(input, true /*eof*/); - - if (expr) { - ppconfig ppc; - ppstate_standalone pps(&cout, 0, &ppc); - - pps.prettyn>(rp(expr)); - } else if (error.is_error()) { - cout << "parsing error (detected in " << error.src_function() << "): " << endl; - error.report(cout); - } + /* reminder: eof can complete at most one token */ + reader_seq(&rdr, &input, true /*eof*/); rx.history_save("repl_history.txt"); } diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index e2667b5f..7be74aa5 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -157,6 +157,7 @@ namespace xo { using ArenaConfig = xo::mm::ArenaConfig; using AAllocator = xo::mm::AAllocator; using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::size_t; public: /** create parser in initial state; diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index c60612a2..bad6c053 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -18,11 +18,11 @@ namespace xo { /** schematika expression parsed from input **/ obj expr_; - /** input span up to end of expression. + /** unconsumed portion of input span * only relevant when result type is expression. - * (otherwise treat entire input as consumed) + * (otherwise input consumed) **/ - span_type consumed_; + span_type remaining_input_; /** {src_function, error_description, input_state, error_pos} **/ TokenizerError tk_error_; @@ -36,18 +36,32 @@ namespace xo { class SchematikaReader { public: using AAllocator = xo::mm::AAllocator; + using span_type = xo::mm::span; + using size_type = std::size_t; public: SchematikaReader(const ReaderConfig & config, obj expr_alloc); + /** true iff parser is at top-level. + * false iff parser is working on incomplete expression + **/ + bool is_at_toplevel() const noexcept; + /** prepare interactive session * (allows rvalue expressions at toplevel) **/ void begin_interactive_session(); /** consume input @p input_cstr **/ - const ReaderResult & read_expr(const char * input_cstr, bool eof); + const ReaderResult & read_expr(span_type input_span, bool eof); + + /** reset to known starting point after encountering an error. + * - remainder of stashed current line. + * Necesary for well-formatted error reporting. + * - current parsing state + **/ + void reset_to_idle_toplevel(); private: /** tokenizer converts a stream of chars diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 97c46c6a..37dda298 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -3,6 +3,8 @@ set(SELF_LIB xo_reader2) set(SELF_SRCS init_reader2.cpp + reader2_register_facets.cpp + reader2_register_types.cpp SchematikaReader.cpp ReaderConfig.cpp @@ -39,8 +41,6 @@ set(SELF_SRCS ISyntaxStateMachine_DProgressSsm.cpp IPrintable_DProgressSsm.cpp - reader2_register_facets.cpp - reader2_register_types.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index fea573c7..13f9edff 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -7,6 +7,7 @@ #include "ParserStateMachine.hpp" #include "ParserStack.hpp" #include "DExprSeqState.hpp" +#include #include #include diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index f8c6a152..bfd14575 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -17,6 +17,12 @@ namespace xo { { } + bool + SchematikaReader::is_at_toplevel() const noexcept + { + return parser_.is_at_toplevel(); + } + void SchematikaReader::begin_interactive_session() { @@ -27,24 +33,28 @@ namespace xo { // Schematika::end_interactive_session() const ReaderResult & - SchematikaReader::read_expr(const char * input_cstr, bool eof) + SchematikaReader::read_expr(span_type input_ext, bool eof) { - if (input_cstr && *input_cstr) { + if (!input_ext.empty()) { auto [error, input] - = tokenizer_.buffer_input_line(input_cstr, - false /*!eof*/); + = tokenizer_.buffer_input_line(input_ext, eof); + // log && log(xtag("msg", "buffered input line")); // log && log(xtag("input", input)); - - while (!input.empty()) { - auto [tk, consumed, error] = tkz.scan(input); + auto [tk, consumed, error] = tokenizer_.scan(input); + + auto rem_input = input.after_prefix(consumed); if (!tk.is_valid() && error.is_error()) { - this->result_ = ReaderResult { .expr_ = obj(), - .tk_error_ = std::move(error), - .consumed_ = nullptr }; + this->result_ + = ReaderResult + { .expr_ = obj(), + .remaining_input_ = rem_input, + .tk_error_ = std::move(error) + }; + return result_; } @@ -58,7 +68,7 @@ namespace xo { // error_description :: const DString * // } // - const ParserResult & presult = parser_include_token(tk); + const ParserResult & presult = parser_.on_token(tk); if (presult.is_error()) { // tk_error { @@ -76,29 +86,50 @@ namespace xo { // // tk_error.report(cout); - this->result_ = ReaderResult { .expr = obj(), - .tk_error_ = std::move(error), - .consumed_ = nullptr }; + this->result_ + = ReaderResult + { .expr_ = obj(), + .remaining_input_ = rem_input, + .tk_error_ = std::move(error) }; + + assert(presult.error_description()); // carefully created error description, maybe - this->result.tk_error_.error_description_ = presult.error_description_; + this->result_.tk_error_ + = result_.tk_error_.with_error + (presult.error_src_fn_, + std::string + (std::string_view(*(presult.error_description())))); + return result_; + } else if (presult.is_expression()) { + this->result_ + = ReaderResult + { + .expr_ = presult.result_expr(), + .remaining_input_ = rem_input, + .tk_error_ = TokenizerError() + }; + + return result_; } - - xxxx; - } else if (error.is_error()) { - xxxx; - // error.report(cout); - break; } - input = input.after_prefix(consumed); + input = rem_input; } } - ++line_no; + this->result_ = ReaderResult(); + + return this->result_; } + void + SchematikaReader::reset_to_idle_toplevel() + { + this->tokenizer_.discard_current_line(); + this->parser_.reset_to_idle_toplevel(); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-tokenizer2/example/tokenrepl/tokenrepl.cpp b/xo-tokenizer2/example/tokenrepl/tokenrepl.cpp index 1cf02244..d8ddbd7f 100644 --- a/xo-tokenizer2/example/tokenrepl/tokenrepl.cpp +++ b/xo-tokenizer2/example/tokenrepl/tokenrepl.cpp @@ -85,32 +85,33 @@ main() { { //cout << "input: " << input << endl; + auto input_ext = Tokenizer::span_type::from_cstr(input_cstr); + // reminder: input may contain multiple tokens - if (input_cstr && *input_cstr) { - auto [error, input] = tkz.buffer_input_line(input_cstr, false /*!eof*/); + auto [error, input] = tkz.buffer_input_line(input_ext, false /*!eof*/); - if (log) { - log(xtag("msg", "buffered input line")); - log(xtag("input", input)); + if (log) { + log(xtag("msg", "buffered input line")); + log(xtag("input", input)); + } + + while (!input.empty()) + { + auto [tk, consumed, error] = tkz.scan(input); + + log && log(xtag("consumed", consumed), xtag("tk", tk)); + + if (tk.is_valid()) { + cout << tk << endl; + } else if (error.is_error()) { + cout << "tokenizer error: " << endl; + + error.report(cout); + + break; } - while (!input.empty()) - { - auto [tk, consumed, error] = tkz.scan(input); - - log && log(xtag("consumed", consumed), xtag("tk", tk)); - - if (tk.is_valid()) { - cout << tk << endl; - } else if (error.is_error()) { - cout << "tokenizer error: " << endl; - error.report(cout); - - break; - } - - input = input.after_prefix(consumed); - } + input = input.after_prefix(consumed); } /* here: input.empty() or error encountered */ diff --git a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp index 40a98cd9..69843a5a 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp @@ -129,10 +129,11 @@ namespace xo { **/ bool has_prefix() const { return !prefix_.empty(); } - /** buffer contents of input_cstr. + /** copy into buffer the contents of @p input. * May throw if buffer space exhausted **/ - std::pair buffer_input_line(const char * input_cstr, bool eof_flag); + std::pair buffer_input_line(span_type input, + bool eof_flag); /** scan for next input token, given @p input. * Note: diff --git a/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp b/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp index b8a50988..bf7702b1 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp @@ -32,7 +32,7 @@ namespace xo { * @p tk_start current position on entry to scanner * @p error_pos error location relative to token start **/ - TokenizerError(const char * src_function, + TokenizerError(std::string_view src_function, std::string error_description, const TkInputState & input_state, size_t error_pos) @@ -46,12 +46,20 @@ namespace xo { log && log(xtag("input_state.current_pos", input_state.current_pos()), xtag("error_pos", error_pos)); } + + TokenizerError with_error(std::string_view error_src_fn, + std::string error_msg) { + return TokenizerError(error_src_fn, + std::string(error_msg), + this->input_state_, + 0 /*error_pos*/); + } ///@} /** @defgroup tokenizer-error-access-methods **/ ///@{ - const char * src_function() const { return src_function_; } + std::string_view src_function() const { return src_function_; } const std::string & error_description() const { return error_description_; } #pragma GCC diagnostic push #ifndef __APPLE__ @@ -88,8 +96,8 @@ namespace xo { ///@{ /** source location (in tokenizer) at which error identified **/ - char const * src_function_ = nullptr; - /** static error description **/ + std::string_view src_function_; + /** error description **/ std::string error_description_; /** input state associated with this error. * Sufficient to precisely locate it with context. diff --git a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp index 7076a95d..2784072a 100644 --- a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp +++ b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp @@ -615,19 +615,18 @@ namespace xo { } auto - Tokenizer::buffer_input_line(const char * input_cstr, + Tokenizer::buffer_input_line(span_type input_ext, bool eof_flag) -> std::pair { scope log(XO_DEBUG(input_state_.debug_flag())); - log && log(xtag("input", input_cstr)); + log && log(xtag("input_ext", input_ext)); auto buf_input_0 = input_buffer_.input_range().hi(); - auto remainder = input_buffer_.append - (DCircularBuffer::const_span_type::from_cstr(input_cstr)); - auto remainder2 = input_buffer_.append - (DCircularBuffer::const_span_type::from_cstr("\n")); + auto remainder = input_buffer_.append(input_ext); + auto remainder2 = input_buffer_.append(span_type::from_cstr("\n")); + //(DCircularBuffer::const_span_type::from_cstr("\n")); if (!remainder.empty() || !remainder2.empty()) { throw std::runtime_error(tostr("Tokenizer::buffer_line: line too long!", @@ -636,10 +635,10 @@ namespace xo { auto buf_input_1 = input_buffer_.input_range().hi(); - span_type input = span_type(buf_input_0, - buf_input_1); + span_type input_ours = span_type(buf_input_0, + buf_input_1); - return this->input_state_.capture_current_line(input, eof_flag); + return this->input_state_.capture_current_line(input_ours, eof_flag); } auto From 610afe76779f107c7cd7ebc746549c798433371d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 14:57:43 -0500 Subject: [PATCH 053/258] xo-reader2: readerreplxx works + streamline debugging --- .../example/readerreplxx/readerreplxx.cpp | 80 +++++++++++++++---- .../include/xo/reader2/ReaderConfig.hpp | 20 ++--- .../include/xo/reader2/SchematikaReader.hpp | 2 + xo-reader2/src/reader2/DDefineSsm.cpp | 2 +- xo-reader2/src/reader2/DExpectTypeSsm.cpp | 2 +- xo-reader2/src/reader2/DProgressSsm.cpp | 3 +- xo-reader2/src/reader2/SchematikaReader.cpp | 26 +++++- .../include/xo/tokenizer2/Tokenizer.hpp | 8 +- xo-tokenizer2/src/tokenizer2/Tokenizer.cpp | 51 +++++------- 9 files changed, 123 insertions(+), 71 deletions(-) diff --git a/xo-reader2/example/readerreplxx/readerreplxx.cpp b/xo-reader2/example/readerreplxx/readerreplxx.cpp index 76bd0520..28598292 100644 --- a/xo-reader2/example/readerreplxx/readerreplxx.cpp +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -1,11 +1,14 @@ /** @file readerreplxx.cpp **/ +#include #include #include #include #include -//#include +#include +#include #include +#include #include #include #include // for isatty @@ -32,7 +35,8 @@ bool replxx_getline(bool interactive, if (retval) *p_input = input_cstr; - rx.history_add(input_cstr); + if (input_cstr) + rx.history_add(input_cstr); return retval; } @@ -56,8 +60,14 @@ welcome(std::ostream & os) namespace { using xo::scm::SchematikaReader; + using xo::scm::AExpression; + using xo::print::APrintable; using xo::print::ppstate_standalone; using xo::print::ppconfig; + using xo::facet::FacetRegistry; + using xo::facet::obj; + using xo::xtag; + using xo::scope; using std::cout; using std::endl; @@ -69,15 +79,36 @@ namespace { bool reader_seq(SchematikaReader * p_reader, SchematikaReader::span_type * p_input, - bool eof) + bool eof, + bool debug_flag) { + scope log(XO_DEBUG(debug_flag)); + + if (!p_input || p_input->empty()) + return true; + auto [expr, remaining, error] = p_reader->read_expr(*p_input, eof); + obj expr_pr; + + if (expr) { + expr_pr = FacetRegistry::instance().variant(expr); + assert(expr_pr); + } + + if (log) { + if (expr_pr) { + log(xtag("expr", expr_pr)); + } + log(xtag("remaining", remaining)); + log(xtag("error", error)); + } + if (expr) { ppconfig ppc; ppstate_standalone pps(&cout, 0, &ppc); - pps.prettyn(expr); + pps.prettyn(expr_pr); *p_input = remaining; @@ -93,6 +124,8 @@ namespace { return false; } else { + *p_input = remaining; + /* partial expression or whitespace input, no error */ return true; } @@ -110,15 +143,19 @@ main() using xo::mm::DX1Collector; using xo::mm::CollectorConfig; using xo::mm::DArena; - //using xo::print::ppconfig; - //using xo::print::ppstate_standalone; using xo::facet::with_facet; using xo::facet::obj; + using xo::S_reader2_tag; + using xo::InitSubsys; + using xo::Subsystem; using xo::scope; using namespace std; bool interactive = isatty(STDIN_FILENO); + InitSubsys::require(); + Subsystem::initialize_all(); + Replxx rx; rx.set_max_history_size(1000); rx.history_load("repl_history.txt"); @@ -134,7 +171,12 @@ main() obj expr_alloc = with_facet::mkobj(&x1); // accepting defaults too - ReaderConfig rdr_config = ReaderConfig(); + ReaderConfig rdr_config; + { + //rdr_config.reader_debug_flag_ = true; + //rdr_config.parser_debug_flag_ = true; + //rdr_config.tk_debug_flag_ = true; + } SchematikaReader rdr(rdr_config, expr_alloc); using span_type = SchematikaReader::span_type; @@ -144,24 +186,28 @@ main() rdr.begin_interactive_session(); bool eof = false; - const char * input_str; + const char * input_str = nullptr; span_type input; while (replxx_getline(interactive, rdr.is_at_toplevel(), rx, &input_str)) { - input = span_type::from_cstr(input_str); + if (input_str && *input_str) { + input = span_type::from_cstr(input_str); - while (!input.empty() && reader_seq(&rdr, &input, false /*eof*/)) { - ; + while (!input.empty() + && reader_seq(&rdr, &input, false /*eof*/, c_debug_flag)) + { + ; + } + + /* here: either: + * 1. input.empty() or + * 2. error encountered + */ } - - /* here: either: - * 1. input.empty() or - * 2. error encountered - */ } /* reminder: eof can complete at most one token */ - reader_seq(&rdr, &input, true /*eof*/); + reader_seq(&rdr, &input, true /*eof*/, c_debug_flag); rx.history_save("repl_history.txt"); } diff --git a/xo-reader2/include/xo/reader2/ReaderConfig.hpp b/xo-reader2/include/xo/reader2/ReaderConfig.hpp index e7f0d7a6..826bb215 100644 --- a/xo-reader2/include/xo/reader2/ReaderConfig.hpp +++ b/xo-reader2/include/xo/reader2/ReaderConfig.hpp @@ -11,7 +11,7 @@ namespace xo { namespace scm { - /** @brief Configuration for SchemtikaReader + /** @brief Configuration for SchematikaReader **/ struct ReaderConfig { using CircularBufferConfig = xo::mm::CircularBufferConfig; @@ -26,6 +26,7 @@ namespace xo { .max_captured_span_ = 128 }; /** debug flag for schematika tokenizer **/ bool tk_debug_flag_ = false; + /** arena configuration for parser stack **/ ArenaConfig parser_arena_config_ { .name_ = "parer-arena", .size_ = 2*1024*1024, @@ -33,19 +34,14 @@ namespace xo { .store_header_flag_ = false, .header_{}, .debug_flag_ = false }; - /** max size (in bytes) of stringtable **/ - size_t max_stringtable_cap_ = 64*1024; /** debug flag for schematika parser **/ bool parser_debug_flag_ = false; -#ifdef NOT_YET - /** arena configuration for output expressions **/ - ArenaConfig expr_arena_config_ { .name_ = "expr-arena", - .size_ = 2*1024*1024, - .hugepage_z_ = 2*1024*1024, - .store_header_flag_ = false, - .header_{}, - .debug_flag_ = false }; -#endif + + /** max size (in bytes) of stringtable **/ + size_t max_stringtable_cap_ = 64*1024; + + /** debug flag for schematika_reader **/ + bool reader_debug_flag_ = false;; }; } /*namespace scm*/ diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index bad6c053..540c19bc 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -77,6 +77,8 @@ namespace xo { /** current output from reader **/ ReaderResult result_; + /** true to enable reader debug logging **/ + bool debug_flag_ = false; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 21ff70f0..d110df35 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -550,7 +550,7 @@ namespace xo { DDefineSsm::on_singleassign_token(const Token & tk, ParserStateMachine * p_psm) { - scope log(XO_DEBUG(true), xtag("defstate", defstate_)); + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("defstate", defstate_)); if ((defstate_ == defexprstatetype::def_2) || (defstate_ == defexprstatetype::def_4)) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 30520811..e527dffa 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -114,7 +114,7 @@ namespace xo { DExpectTypeSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { - scope log(XO_DEBUG(true)); + scope log(XO_DEBUG(p_psm->debug_flag())); TypeDescr td = nullptr; diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index ec19e994..5a9a81ec 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -216,8 +216,7 @@ namespace xo { DProgressSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(p_psm->debug_flag())); /* note: implementation should parallel .on_rightparen_token() */ diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index bfd14575..8aa85bf8 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -9,11 +9,13 @@ namespace xo { namespace scm { SchematikaReader::SchematikaReader(const ReaderConfig & config, obj expr_alloc) - : tokenizer_{config.tk_buffer_config_, config.tk_debug_flag_}, + : tokenizer_{config.tk_buffer_config_, + config.tk_debug_flag_}, parser_{config.parser_arena_config_, config.max_stringtable_cap_, expr_alloc, - config.parser_debug_flag_} + config.parser_debug_flag_}, + debug_flag_{config.reader_debug_flag_} { } @@ -35,18 +37,34 @@ namespace xo { const ReaderResult & SchematikaReader::read_expr(span_type input_ext, bool eof) { + scope log(XO_DEBUG(debug_flag_)); + + if (log) { + log(xtag("input_ext", input_ext)); + log(xtag("eof", eof)); + } + if (!input_ext.empty()) { auto [error, input] = tokenizer_.buffer_input_line(input_ext, eof); - // log && log(xtag("msg", "buffered input line")); - // log && log(xtag("input", input)); + if (log) { + log(xtag("msg", "before loop: buffered input line")); + log(xtag("input", input)); + } while (!input.empty()) { + log && log(xtag("msg", "loop"), + xtag("input", input)); + auto [tk, consumed, error] = tokenizer_.scan(input); + log && log(xtag("tk", tk), xtag("consumed", consumed)); + auto rem_input = input.after_prefix(consumed); + log && log(xtag("rem_input", rem_input)); + if (!tk.is_valid() && error.is_error()) { this->result_ = ReaderResult diff --git a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp index 69843a5a..3dc6da11 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp @@ -109,19 +109,19 @@ namespace xo { static bool is_2char_punctuation(CharT ch); /** assemble token from text @p token_text. - * @p initial_whitespace Amount of whitespace input being consumed from input. + * @p ws_span whitespace preceding token * @p token_text subset of input_line representing a single token. * @p p_input_state input state containing input_line. On exit current line cleared * if error * * retval.consumed will represent some possibly-empty prefix of @p input **/ - static scan_result assemble_token(std::size_t initial_whitespace, - const span_type & token_text, + static scan_result assemble_token( span_type ws_span, + span_type token_text, TkInputState * p_input_state); /** degenerate version of assemble_token() on reaching end-of-file **/ - static scan_result assemble_final_token(const span_type & token_text, + static scan_result assemble_final_token(span_type token_text, TkInputState * p_input_state); /** true if tokenizer contains stored prefix of diff --git a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp index 2784072a..c79e10c3 100644 --- a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp +++ b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp @@ -110,8 +110,8 @@ namespace xo { } auto - Tokenizer::assemble_token(std::size_t initial_whitespace, - const span_type & token_text, + Tokenizer::assemble_token(span_type ws_span, + span_type token_text, TkInputState * p_input_state) -> result_type { /* literal|pretty|streamlined */ @@ -119,7 +119,7 @@ namespace xo { scope log(XO_DEBUG(p_input_state->debug_flag())); log && log(xtag("token_text", token_text), - xtag("initial_whitespace", initial_whitespace), + xtag("initial_whitespace", ws_span.size()), xtag("input_state", *p_input_state)); tokentype tk_type = tokentype::tk_invalid; @@ -598,18 +598,16 @@ namespace xo { // TOOD: report tk_text as span, // but must pin / unpin - /* input.prefix(0): - * require caller preserves current input line until it's entirely exhausted - */ return result_type(Token(tk_type, std::move(tk_text)), - p_input_state->current_line().prefix(0)); + span_type::concat(ws_span, + span_type(tk_start, tk_end))); } /*assemble_token*/ auto - Tokenizer::assemble_final_token(const span_type & token_text, + Tokenizer::assemble_final_token(span_type token_text, TkInputState * p_input_state) -> result_type { - return assemble_token(0 /*initial_whitespace*/, + return assemble_token(token_text.prefix(0) /*ws_span*/, token_text, p_input_state); } @@ -645,6 +643,7 @@ namespace xo { Tokenizer::scan(const span_type & input) -> result_type { scope log(XO_DEBUG(input_state_.debug_flag())); + log && log(xtag("input", input)); /* - Always at beginning of token when scan() invoked * - scan will not report any portion of line as consumed until it has @@ -659,12 +658,14 @@ namespace xo { const CharT * ix = this->input_state_.skip_leading_whitespace(); if(ix == input.hi()) { - log && log("end input -> consume current line"); + log && log("end buffered input -> consume current line"); /* entirety of current line has been tokenized * -> caller may consume it */ - return result_type::make_whitespace(this->input_state_.consume_current_line()); + this->input_state_.consume_current_line(); + + return result_type::make_whitespace(input); } /* ix: if ix < input.hi: first non-whitespace character after input_state_.current_pos_ */ @@ -697,27 +698,17 @@ namespace xo { ++ix; -#ifdef OBSOLETE // no longer a thing. either input ends in whitespace, or ends translation unit - if (ix == input.hi()) { - /* need more input to know if/when token complete */ - this->prefix_ += std::string(tk_start, input.hi()); + CharT ch2 = *ix; - log && log(xtag("captured-prefix1", this->prefix_)); - } else -#endif - { - CharT ch2 = *ix; - - if (((ch2 >= '0') && (ch2 <= '9')) - || ((ch2 >= 'A') && (ch2 <= 'Z')) - || ((ch2 >= 'a') && (ch2 <= 'z'))) + if (((ch2 >= '0') && (ch2 <= '9')) + || ((ch2 >= 'A') && (ch2 <= 'Z')) + || ((ch2 >= 'a') && (ch2 <= 'z'))) { /* treat as 1 char punctuation */ ; } else { - /* include next char */ - ++ix; - } + /* include next char */ + ++ix; } } else if (*ix == '"') { bool complete_flag = false; @@ -779,7 +770,7 @@ namespace xo { this->input_state_.advance_until(ix); - return assemble_token(whitespace_z, + return assemble_token(span_type(input.lo(), tk_start), span_type(tk_start, ix) /*token*/, &(this->input_state_)); } @@ -803,7 +794,7 @@ namespace xo { this->input_state_.advance_until(ix); /* ignore next char and complete token */ - return assemble_token(whitespace_z, + return assemble_token(span_type(input.lo(), tk_start), span_type(tk_start, ix) /*token*/, &(this->input_state_)); } @@ -854,7 +845,7 @@ namespace xo { this->input_state_.advance_until(ix); - return assemble_token(whitespace_z, + return assemble_token(span_type(input.lo(), tk_start), span_type(tk_start, ix) /*token*/, &(this->input_state_)); } /*_scan_aux*/ From 87534edb80deb47beaeea413cb13e2fbb061c249 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 15:11:36 -0500 Subject: [PATCH 054/258] xo-reader2: + f64 toplevel constant in interactive session --- .../example/readerreplxx/readerreplxx.cpp | 2 +- xo-reader2/src/reader2/DExprSeqState.cpp | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/xo-reader2/example/readerreplxx/readerreplxx.cpp b/xo-reader2/example/readerreplxx/readerreplxx.cpp index 28598292..5d74dc06 100644 --- a/xo-reader2/example/readerreplxx/readerreplxx.cpp +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -173,7 +173,7 @@ main() // accepting defaults too ReaderConfig rdr_config; { - //rdr_config.reader_debug_flag_ = true; + rdr_config.reader_debug_flag_ = true; //rdr_config.parser_debug_flag_ = true; //rdr_config.tk_debug_flag_ = true; } diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 33a68c15..65ec004c 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -6,8 +6,18 @@ #include "DExprSeqState.hpp" #include "DDefineSsm.hpp" #include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" +#include +#include +#include +#include +#include +#include namespace xo { + using xo::scm::DProgressSsm; + using xo::scm::DConstant; + using xo::scm::DFloat; + using xo::mm::AGCObject; using xo::mm::AAllocator; using xo::facet::with_facet; using xo::reflect::typeseq; @@ -182,6 +192,26 @@ namespace xo { DExprSeqState::on_f64_token(const Token & tk, ParserStateMachine * p_psm) { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { + auto f64o = DFloat::box(p_psm->expr_alloc(), + tk.f64_value()); + auto * dconst = DConstant::make(p_psm->expr_alloc(), f64o); + auto expr = with_facet::mkobj(dconst); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + p_psm->illegal_input_on_token("DExprSeqState::on_f64_token", tk, this->get_expect_str()); From 132b8d231ab9852080cf6a2d67ae49112b17ec4e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 15:25:30 -0500 Subject: [PATCH 055/258] xo-reader2: + on_bool_token scaffold in parser etc. --- xo-reader2/idl/SyntaxStateMachine.json5 | 9 +++++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectExprSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExprSeqState.hpp | 5 +++++ xo-reader2/include/xo/reader2/DProgressSsm.hpp | 2 ++ .../include/xo/reader2/ParserStateMachine.hpp | 3 +++ .../include/xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 ++ .../xo/reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectExprSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 ++ .../xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 +++ .../include/xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 +++ xo-reader2/src/reader2/DDefineSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 9 +++++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp | 6 ++++++ .../src/reader2/ISyntaxStateMachine_DDefineSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExpectExprSsm.cpp | 5 +++++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExprSeqState.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DProgressSsm.cpp | 5 +++++ xo-reader2/src/reader2/ParserStateMachine.cpp | 13 ++++++++++++- 32 files changed, 166 insertions(+), 1 deletion(-) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index c12d3736..ad68d5bc 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -99,6 +99,15 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_bool_token", + doc: ["update state machine for incoming bool-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_semicolon_token", doc: ["update state machine for incoming semicolon-token @p tk"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 1d94f3ad..912ccaf5 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -153,6 +153,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, + * overall parser state in @p p_psm + **/ + void on_bool_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 7bf48dea..8b37a901 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -89,6 +89,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, + * overall parser state in @p p_psm + **/ + void on_bool_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 1083b454..9ece9f51 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -123,6 +123,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, + * overall parser state in @p p_psm + **/ + void on_bool_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index cf28fedf..b43b6eee 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -83,6 +83,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, + * overall parser state in @p p_psm + **/ + void on_bool_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index eefcb15d..c9fe69e1 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -95,6 +95,11 @@ namespace xo { **/ void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, + * overall parser state in @p p_psm + **/ + void on_bool_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming semicolon token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 2b4121c3..2d0a4df2 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -143,6 +143,8 @@ namespace xo { ParserStateMachine * p_psm); void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + void on_bool_token(const Token & tk, + ParserStateMachine * p_psm); void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); void on_parsed_symbol(std::string_view sym, diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index b838efe5..80690c29 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -141,6 +141,9 @@ namespace xo { /** operate state machine for incoming f64-token @p tk **/ void on_f64_token(const Token & tk); + /** operate state machine for incoming bool-token @p tk **/ + void on_bool_token(const Token & tk); + /** operate state machine for incoming semicolon-token @p tk **/ void on_semicolon_token(const Token & tk); diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index b68a1289..4e9bd99f 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -69,6 +69,8 @@ public: virtual void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming f64-token @p tk **/ virtual void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming bool-token @p tk **/ + virtual void on_bool_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming semicolon-token @p tk **/ virtual void on_semicolon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 52dc4059..5d339902 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -66,6 +66,7 @@ namespace scm { [[noreturn]] void on_colon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_singleassign_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_f64_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_bool_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_semicolon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index 3084631c..cdc01066 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming bool-token @p tk **/ + static void on_bool_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index efebe9c7..8758347c 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming bool-token @p tk **/ + static void on_bool_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index d870667a..95adca39 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming bool-token @p tk **/ + static void on_bool_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 23eb8af0..81d13c47 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming bool-token @p tk **/ + static void on_bool_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 020e7552..f95989ad 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming bool-token @p tk **/ + static void on_bool_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index 1735b2b1..0362e433 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming bool-token @p tk **/ + static void on_bool_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index da16f766..fbfd99b7 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -70,6 +70,9 @@ namespace scm { void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_f64_token(_dcast(data), tk, p_psm); } + void on_bool_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_bool_token(_dcast(data), tk, p_psm); + } void on_semicolon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_semicolon_token(_dcast(data), tk, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index cfa354b9..2741dc76 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -74,6 +74,9 @@ public: void on_f64_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_f64_token(O::data(), tk, p_psm); } + void on_bool_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_bool_token(O::data(), tk, p_psm); + } void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_semicolon_token(O::data(), tk, p_psm); } diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index d110df35..063572d3 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -576,6 +576,15 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DDefineSsm::on_bool_token", + tk, + this->get_expect_str()); + } + void DDefineSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index cea683c4..a6aff620 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -170,6 +170,15 @@ namespace xo { p_psm); } + void + DExpectExprSsm::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm::on_bool_token", + tk, + this->get_expect_str()); + } + void DExpectExprSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index e55d35be..4bb3c05a 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -158,6 +158,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_bool_token", + tk, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index e527dffa..643defb5 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -101,6 +101,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectTypeSsm::on_bool_token", + tk, + this->get_expect_str()); + } + void DExpectTypeSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 65ec004c..c6e53ba2 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -217,6 +217,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExprSeqState::on_bool_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 5a9a81ec..00571edb 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -212,6 +212,15 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_bool_token", + tk, + this->get_expect_str()); + } + void DProgressSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index a789bce9..4637f4c0 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -70,6 +70,12 @@ ISyntaxStateMachine_Any::on_f64_token(Opaque, const Token &, ParserStateMachine _fatal(); } +auto +ISyntaxStateMachine_Any::on_bool_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_semicolon_token(Opaque, const Token &, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 89589841..ed07a417 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_bool_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_bool_token(tk, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_semicolon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index 858ce1ab..7ad963c8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectExprSsm::on_bool_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_bool_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectExprSsm::on_semicolon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 1982212c..0012daad 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_bool_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_bool_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_semicolon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index eb66f8db..20d930b9 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_bool_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_bool_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_semicolon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index cfd419b9..ddf20702 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_bool_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_bool_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_semicolon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 53c8706c..535ac2f6 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DProgressSsm::on_bool_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_bool_token(tk, p_psm); + } + auto ISyntaxStateMachine_DProgressSsm::on_semicolon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 80841fd8..3915aca7 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -187,13 +187,16 @@ namespace xo { this->on_f64_token(tk); break; + case tokentype::tk_bool: + this->on_bool_token(tk); + break; + case tokentype::tk_semicolon: this->on_semicolon_token(tk); break; // all the not-yet handled cases case tokentype::tk_invalid: - case tokentype::tk_bool: case tokentype::tk_i64: case tokentype::tk_string: case tokentype::tk_leftparen: @@ -280,6 +283,14 @@ namespace xo { stack_->top().on_f64_token(tk, this); } + void + ParserStateMachine::on_bool_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_bool_token(tk, this); + } + void ParserStateMachine::on_semicolon_token(const Token & tk) { From b12555067c67483443e04a763038dd6b7ef871ae Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 15:44:13 -0500 Subject: [PATCH 056/258] xo-object2: + DBoolean w/ AGCObject, APrintable facets --- xo-object2/CMakeLists.txt | 36 ++++++++++ xo-object2/idl/IGCObject_DBoolean.json5 | 15 +++++ xo-object2/idl/IPrintable_DBoolean.json5 | 13 ++++ xo-object2/include/xo/object2/DBoolean.hpp | 57 ++++++++++++++++ .../xo/object2/boolean/IGCObject_DBoolean.hpp | 67 +++++++++++++++++++ .../object2/boolean/IPrintable_DBoolean.hpp | 62 +++++++++++++++++ xo-object2/src/object2/CMakeLists.txt | 3 + xo-object2/src/object2/DBoolean.cpp | 57 ++++++++++++++++ xo-object2/src/object2/IGCObject_DBoolean.cpp | 39 +++++++++++ .../src/object2/IPrintable_DBoolean.cpp | 28 ++++++++ .../src/object2/object2_register_facets.cpp | 10 +++ .../src/object2/object2_register_types.cpp | 3 + 12 files changed, 390 insertions(+) create mode 100644 xo-object2/idl/IGCObject_DBoolean.json5 create mode 100644 xo-object2/idl/IPrintable_DBoolean.json5 create mode 100644 xo-object2/include/xo/object2/DBoolean.hpp create mode 100644 xo-object2/include/xo/object2/boolean/IGCObject_DBoolean.hpp create mode 100644 xo-object2/include/xo/object2/boolean/IPrintable_DBoolean.hpp create mode 100644 xo-object2/src/object2/DBoolean.cpp create mode 100644 xo-object2/src/object2/IGCObject_DBoolean.cpp create mode 100644 xo-object2/src/object2/IPrintable_DBoolean.cpp diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index ee93bf7e..261b59df 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -28,6 +28,8 @@ xo_add_genfacet( OUTPUT_CPP_DIR src/object2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-object2-facetimpl-sequence-list @@ -64,6 +66,34 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-printable-boolean + FACET_PKG xo_printable2 + FACET Printable + REPR Boolean + INPUT idl/IPrintable_DBoolean.json5 + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR boolean + OUTPUT_CPP_DIR src/object2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-gcobject-boolean + FACET_PKG xo_gc + FACET GCObject + REPR Boolean + INPUT idl/IGCObject_DBoolean.json5 + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR boolean + OUTPUT_CPP_DIR src/object2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-object2-facetimpl-printable-float @@ -88,6 +118,8 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-object2-facetimpl-printable-integer @@ -112,6 +144,8 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-object2-facetimpl-printable-string @@ -136,6 +170,8 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-object2-facetimpl-sequence-array diff --git a/xo-object2/idl/IGCObject_DBoolean.json5 b/xo-object2/idl/IGCObject_DBoolean.json5 new file mode 100644 index 00000000..de3663c4 --- /dev/null +++ b/xo-object2/idl/IGCObject_DBoolean.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DBoolean", + using_doxygen: true, + repr: "DBoolean", + doc: [ "implement AGCObject for DBoolean" ], +} diff --git a/xo-object2/idl/IPrintable_DBoolean.json5 b/xo-object2/idl/IPrintable_DBoolean.json5 new file mode 100644 index 00000000..599a1923 --- /dev/null +++ b/xo-object2/idl/IPrintable_DBoolean.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DBoolean", + using_doxygen: true, + repr: "DBoolean", + doc: [ "implement APrintable for DBoolean" ], +} diff --git a/xo-object2/include/xo/object2/DBoolean.hpp b/xo-object2/include/xo/object2/DBoolean.hpp new file mode 100644 index 00000000..e951cfba --- /dev/null +++ b/xo-object2/include/xo/object2/DBoolean.hpp @@ -0,0 +1,57 @@ +/** @file DBoolean.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace xo { + namespace scm { + struct DBoolean { + using AAllocator = xo::mm::AAllocator; + using ACollector = xo::mm::ACollector; + using ppindentinfo = xo::print::ppindentinfo; + using value_type = long; + + explicit DBoolean(bool x) : value_{x} {} + + /** will likely want this to default to ANumeric, once we have it **/ + template + static obj box(obj mm, bool x); + + /** allocate boxed value @p x using memory from @p mm **/ + static DBoolean * _box(obj mm, bool x); + + bool value() const noexcept { return value_; } + + bool pretty(const ppindentinfo & ppii) const; + + operator bool() const noexcept { return value_; } + + // GCObject facet + + std::size_t shallow_size() const noexcept; + DBoolean * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + private: + /** boxed boolean value **/ + bool value_; + }; + + template + obj + DBoolean::box(obj mm, bool x) { + return obj(_box(mm, x)); + } + + } /*nmaespace obj*/ +} /*namespace xo*/ + +/* end DBoolean.hpp */ diff --git a/xo-object2/include/xo/object2/boolean/IGCObject_DBoolean.hpp b/xo-object2/include/xo/object2/boolean/IGCObject_DBoolean.hpp new file mode 100644 index 00000000..e075874c --- /dev/null +++ b/xo-object2/include/xo/object2/boolean/IGCObject_DBoolean.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DBoolean.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DBoolean.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DBoolean.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DBoolean.hpp" + +namespace xo { namespace scm { class IGCObject_DBoolean; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DBoolean + **/ + class IGCObject_DBoolean { + public: + /** @defgroup scm-gcobject-dboolean-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dboolean-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DBoolean & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DBoolean & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DBoolean & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-object2/include/xo/object2/boolean/IPrintable_DBoolean.hpp b/xo-object2/include/xo/object2/boolean/IPrintable_DBoolean.hpp new file mode 100644 index 00000000..e17f169a --- /dev/null +++ b/xo-object2/include/xo/object2/boolean/IPrintable_DBoolean.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DBoolean.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DBoolean.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DBoolean.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DBoolean.hpp" + +namespace xo { namespace scm { class IPrintable_DBoolean; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DBoolean + **/ + class IPrintable_DBoolean { + public: + /** @defgroup scm-printable-dboolean-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dboolean-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DBoolean & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-object2/src/object2/CMakeLists.txt b/xo-object2/src/object2/CMakeLists.txt index a87c349b..430e50c2 100644 --- a/xo-object2/src/object2/CMakeLists.txt +++ b/xo-object2/src/object2/CMakeLists.txt @@ -4,6 +4,7 @@ set(SELF_LIB xo_object2) set(SELF_SRCS IGCObject_DArray.cpp IGCObject_DFloat.cpp + IGCObject_DBoolean.cpp IGCObject_DInteger.cpp IGCObject_DList.cpp IGCObject_DString.cpp @@ -11,6 +12,7 @@ set(SELF_SRCS ISequence_DArray.cpp ISequence_DList.cpp IPrintable_DList.cpp + IPrintable_DBoolean.cpp IPrintable_DFloat.cpp IPrintable_DInteger.cpp IPrintable_DString.cpp @@ -18,6 +20,7 @@ set(SELF_SRCS DList.cpp DFloat.cpp DInteger.cpp + DBoolean.cpp DString.cpp init_object2.cpp object2_register_types.cpp diff --git a/xo-object2/src/object2/DBoolean.cpp b/xo-object2/src/object2/DBoolean.cpp new file mode 100644 index 00000000..341e656d --- /dev/null +++ b/xo-object2/src/object2/DBoolean.cpp @@ -0,0 +1,57 @@ +/** @file DBoolean.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DBoolean.hpp" +#include +#include + +namespace xo { + using xo::facet::typeseq; + using xo::print::ppdetail_atomic; + + namespace scm { + DBoolean * + DBoolean::_box(obj mm, bool x) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DBoolean)); + + return new (mem) DBoolean(x); + } + + bool + DBoolean::pretty(const ppindentinfo & ppii) const + { + return ppdetail_atomic::print_pretty(ppii, value_); + } + + size_t + DBoolean::shallow_size() const noexcept + { + return sizeof(DBoolean); + } + + DBoolean * + DBoolean::shallow_copy(obj mm) const noexcept + { + DBoolean * copy = (DBoolean *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + size_t + DBoolean::forward_children(obj) noexcept + { + return shallow_size(); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DBoolean.cpp */ diff --git a/xo-object2/src/object2/IGCObject_DBoolean.cpp b/xo-object2/src/object2/IGCObject_DBoolean.cpp new file mode 100644 index 00000000..72aa0b1b --- /dev/null +++ b/xo-object2/src/object2/IGCObject_DBoolean.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DBoolean.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DBoolean.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DBoolean.json5] +**/ + +#include "boolean/IGCObject_DBoolean.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DBoolean::shallow_size(const DBoolean & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DBoolean::shallow_copy(const DBoolean & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DBoolean::forward_children(DBoolean & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DBoolean.cpp */ \ No newline at end of file diff --git a/xo-object2/src/object2/IPrintable_DBoolean.cpp b/xo-object2/src/object2/IPrintable_DBoolean.cpp new file mode 100644 index 00000000..d8fddd87 --- /dev/null +++ b/xo-object2/src/object2/IPrintable_DBoolean.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DBoolean.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DBoolean.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DBoolean.json5] +**/ + +#include "boolean/IPrintable_DBoolean.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DBoolean::pretty(const DBoolean & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DBoolean.cpp */ \ No newline at end of file diff --git a/xo-object2/src/object2/object2_register_facets.cpp b/xo-object2/src/object2/object2_register_facets.cpp index 93438600..ebf320c4 100644 --- a/xo-object2/src/object2/object2_register_facets.cpp +++ b/xo-object2/src/object2/object2_register_facets.cpp @@ -7,11 +7,13 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -29,9 +31,11 @@ namespace xo { using xo::mm::AAllocator; using xo::mm::AGCObject; using xo::scm::DList; + using xo::scm::DBoolean; using xo::scm::DFloat; using xo::scm::DString; using xo::scm::DArray; + using xo::facet::DVariantPlaceholder; using xo::facet::FacetRegistry; using xo::facet::typeseq; @@ -45,6 +49,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -57,7 +64,10 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + log && log(xtag("DVariantPlaceholder.tseq", typeseq::id())); + log && log(xtag("DList.tseq", typeseq::id())); + log && log(xtag("DBoolean.tseq", typeseq::id())); log && log(xtag("DFloat.tseq", typeseq::id())); log && log(xtag("DInteger.tseq", typeseq::id())); log && log(xtag("DString.tseq", typeseq::id())); diff --git a/xo-object2/src/object2/object2_register_types.cpp b/xo-object2/src/object2/object2_register_types.cpp index c2079a40..275995f8 100644 --- a/xo-object2/src/object2/object2_register_types.cpp +++ b/xo-object2/src/object2/object2_register_types.cpp @@ -5,6 +5,7 @@ #include "object2_register_types.hpp" +#include "boolean/IGCObject_DBoolean.hpp" #include "number/IGCObject_DFloat.hpp" #include "number/IGCObject_DInteger.hpp" #include "string/IGCObject_DString.hpp" @@ -33,6 +34,8 @@ namespace xo { bool ok = true; + ok &= gc.install_type(impl_for()); + ok &= gc.install_type(impl_for()); ok &= gc.install_type(impl_for()); From 0fb0f7a1bfdeb9c61dd47c17aac2c9b6e4b25674 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 16:34:33 -0500 Subject: [PATCH 057/258] xo-reader2: fix clearing result in SchematikaReader --- xo-expression2/src/expression2/DConstant.cpp | 6 ++--- xo-object2/include/xo/object2/DBoolean.hpp | 2 +- xo-object2/src/object2/DBoolean.cpp | 4 +++- .../src/object2/object2_register_facets.cpp | 2 +- .../example/readerreplxx/readerreplxx.cpp | 2 ++ .../include/xo/reader2/SchematikaReader.hpp | 3 +++ xo-reader2/src/reader2/DExprSeqState.cpp | 22 +++++++++++++++++++ xo-reader2/src/reader2/SchematikaReader.cpp | 6 +++++ 8 files changed, 41 insertions(+), 6 deletions(-) diff --git a/xo-expression2/src/expression2/DConstant.cpp b/xo-expression2/src/expression2/DConstant.cpp index a0b255a6..f65ba013 100644 --- a/xo-expression2/src/expression2/DConstant.cpp +++ b/xo-expression2/src/expression2/DConstant.cpp @@ -65,15 +65,15 @@ namespace xo { bool DConstant::pretty(const ppindentinfo & ppii) const { - obj value + obj value_pr = FacetRegistry::instance().variant(value_); return ppii.pps()->pretty_struct (ppii, "DConstant", refrtag("value_.tseq", value_._typeseq()), - refrtag("value.tseq", value._typeseq()), - refrtag("value", value)); + refrtag("value.tseq", value_pr._typeseq()), + refrtag("value", value_pr)); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-object2/include/xo/object2/DBoolean.hpp b/xo-object2/include/xo/object2/DBoolean.hpp index e951cfba..69dd1c16 100644 --- a/xo-object2/include/xo/object2/DBoolean.hpp +++ b/xo-object2/include/xo/object2/DBoolean.hpp @@ -42,7 +42,7 @@ namespace xo { private: /** boxed boolean value **/ - bool value_; + bool value_ = false; }; template diff --git a/xo-object2/src/object2/DBoolean.cpp b/xo-object2/src/object2/DBoolean.cpp index 341e656d..a926b0ec 100644 --- a/xo-object2/src/object2/DBoolean.cpp +++ b/xo-object2/src/object2/DBoolean.cpp @@ -24,7 +24,9 @@ namespace xo { bool DBoolean::pretty(const ppindentinfo & ppii) const { - return ppdetail_atomic::print_pretty(ppii, value_); + return ppdetail_atomic::print_pretty + (ppii, + (value_ ? "true" : "false")); } size_t diff --git a/xo-object2/src/object2/object2_register_facets.cpp b/xo-object2/src/object2/object2_register_facets.cpp index ebf320c4..be68e009 100644 --- a/xo-object2/src/object2/object2_register_facets.cpp +++ b/xo-object2/src/object2/object2_register_facets.cpp @@ -67,7 +67,7 @@ namespace xo { log && log(xtag("DVariantPlaceholder.tseq", typeseq::id())); log && log(xtag("DList.tseq", typeseq::id())); - log && log(xtag("DBoolean.tseq", typeseq::id())); + log && log(xtag("DBoolean.tseq", typeseq::id())); log && log(xtag("DFloat.tseq", typeseq::id())); log && log(xtag("DInteger.tseq", typeseq::id())); log && log(xtag("DString.tseq", typeseq::id())); diff --git a/xo-reader2/example/readerreplxx/readerreplxx.cpp b/xo-reader2/example/readerreplxx/readerreplxx.cpp index 5d74dc06..341893cf 100644 --- a/xo-reader2/example/readerreplxx/readerreplxx.cpp +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -110,6 +110,8 @@ namespace { pps.prettyn(expr_pr); + p_reader->reset_result(); + *p_input = remaining; return true; diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index 540c19bc..fd26a4ec 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -56,6 +56,9 @@ namespace xo { /** consume input @p input_cstr **/ const ReaderResult & read_expr(span_type input_span, bool eof); + /** reset @ref result_ to nominal value **/ + void reset_result(); + /** reset to known starting point after encountering an error. * - remainder of stashed current line. * Necesary for well-formatted error reporting. diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index c6e53ba2..1d7aea93 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include namespace xo { @@ -221,6 +223,26 @@ namespace xo { DExprSeqState::on_bool_token(const Token & tk, ParserStateMachine * p_psm) { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { + auto dvalue = DBoolean::box(p_psm->expr_alloc(), + tk.bool_value()); + auto * dconst = DConstant::make(p_psm->expr_alloc(), dvalue); + auto expr = with_facet::mkobj(dconst); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + p_psm->illegal_input_on_token("DExprSeqState::on_bool_token", tk, this->get_expect_str()); diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index 8aa85bf8..4dd8600c 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -142,6 +142,12 @@ namespace xo { return this->result_; } + void + SchematikaReader::reset_result() + { + this->parser_.reset_result(); + } + void SchematikaReader::reset_to_idle_toplevel() { From 8c6f504224e7010eefe164ce6a3e68d6e5ec9e38 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 16:45:15 -0500 Subject: [PATCH 058/258] xo-reader2: + on_i64_token in all Ssm classes. --- xo-reader2/idl/SyntaxStateMachine.json5 | 9 +++++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectExprSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp | 6 ++++++ xo-reader2/include/xo/reader2/DExprSeqState.hpp | 5 +++++ xo-reader2/include/xo/reader2/DProgressSsm.hpp | 2 ++ .../include/xo/reader2/ParserStateMachine.hpp | 3 +++ .../include/xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 ++ .../xo/reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectExprSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 ++ .../xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 +++ .../include/xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 +++ xo-reader2/src/reader2/DDefineSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 9 +++++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 9 +++++++++ xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp | 6 ++++++ .../src/reader2/ISyntaxStateMachine_DDefineSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExpectExprSsm.cpp | 5 +++++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DExprSeqState.cpp | 5 +++++ .../reader2/ISyntaxStateMachine_DProgressSsm.cpp | 5 +++++ xo-reader2/src/reader2/ParserStateMachine.cpp | 13 ++++++++++++- 32 files changed, 166 insertions(+), 1 deletion(-) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index ad68d5bc..d03808c1 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -99,6 +99,15 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_i64_token", + doc: ["update state machine for incoming i64-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_bool_token", doc: ["update state machine for incoming bool-token @p tk"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 912ccaf5..0bafe4cb 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -153,6 +153,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming i64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_i64_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 8b37a901..5a628742 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -89,6 +89,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming i64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_i64_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 9ece9f51..910c1978 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -123,6 +123,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming i64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_i64_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index b43b6eee..77a54f61 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -83,6 +83,12 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming i64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_i64_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index c9fe69e1..4ee2e177 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -95,6 +95,11 @@ namespace xo { **/ void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming i64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_i64_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming bool token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 2d0a4df2..ae3bdb85 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -143,6 +143,8 @@ namespace xo { ParserStateMachine * p_psm); void on_f64_token(const Token & tk, ParserStateMachine * p_psm); + void on_i64_token(const Token & tk, + ParserStateMachine * p_psm); void on_bool_token(const Token & tk, ParserStateMachine * p_psm); void on_semicolon_token(const Token & tk, diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 80690c29..870b1d66 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -141,6 +141,9 @@ namespace xo { /** operate state machine for incoming f64-token @p tk **/ void on_f64_token(const Token & tk); + /** operate state machine for incoming i64-token @p tk **/ + void on_i64_token(const Token & tk); + /** operate state machine for incoming bool-token @p tk **/ void on_bool_token(const Token & tk); diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index 4e9bd99f..feb4a62b 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -69,6 +69,8 @@ public: virtual void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming f64-token @p tk **/ virtual void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming i64-token @p tk **/ + virtual void on_i64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming bool-token @p tk **/ virtual void on_bool_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming semicolon-token @p tk **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 5d339902..06fd2ff9 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -66,6 +66,7 @@ namespace scm { [[noreturn]] void on_colon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_singleassign_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_f64_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_i64_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_bool_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_semicolon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index cdc01066..4c22c587 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming i64-token @p tk **/ + static void on_i64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 8758347c..6c64836e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming i64-token @p tk **/ + static void on_i64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 95adca39..0647ce38 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming i64-token @p tk **/ + static void on_i64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 81d13c47..ec3f10fc 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming i64-token @p tk **/ + static void on_i64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index f95989ad..c8205ff1 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming i64-token @p tk **/ + static void on_i64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index 0362e433..9cec85e1 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -66,6 +66,8 @@ namespace xo { static void on_singleassign_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming f64-token @p tk **/ static void on_f64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming i64-token @p tk **/ + static void on_i64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index fbfd99b7..31681b46 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -70,6 +70,9 @@ namespace scm { void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_f64_token(_dcast(data), tk, p_psm); } + void on_i64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_i64_token(_dcast(data), tk, p_psm); + } void on_bool_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_bool_token(_dcast(data), tk, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 2741dc76..4df02804 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -74,6 +74,9 @@ public: void on_f64_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_f64_token(O::data(), tk, p_psm); } + void on_i64_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_i64_token(O::data(), tk, p_psm); + } void on_bool_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_bool_token(O::data(), tk, p_psm); } diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 063572d3..eb1d5d55 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -576,6 +576,15 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DDefineSsm::on_i64_token", + tk, + this->get_expect_str()); + } + void DDefineSsm::on_bool_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index a6aff620..553973a6 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -170,6 +170,15 @@ namespace xo { p_psm); } + void + DExpectExprSsm::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm::on_i64_token", + tk, + this->get_expect_str()); + } + void DExpectExprSsm::on_bool_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 4bb3c05a..d32f3ce5 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -158,6 +158,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_i64_token", + tk, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_bool_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 643defb5..d20128c0 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -101,6 +101,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectTypeSsm::on_i64_token", + tk, + this->get_expect_str()); + } + void DExpectTypeSsm::on_bool_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 1d7aea93..6f196963 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -219,6 +219,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExprSeqState::on_i64_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_bool_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 00571edb..f6b14bc1 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -212,6 +212,15 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_i64_token", + tk, + this->get_expect_str()); + } + void DProgressSsm::on_bool_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 4637f4c0..39fcea13 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -70,6 +70,12 @@ ISyntaxStateMachine_Any::on_f64_token(Opaque, const Token &, ParserStateMachine _fatal(); } +auto +ISyntaxStateMachine_Any::on_i64_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_bool_token(Opaque, const Token &, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index ed07a417..69520cae 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_i64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_i64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_bool_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_bool_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index 7ad963c8..b247c821 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectExprSsm::on_i64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_i64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectExprSsm::on_bool_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_bool_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 0012daad..318e68cb 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_i64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_i64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_bool_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_bool_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 20d930b9..3d98c1f8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_i64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_i64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_bool_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_bool_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index ddf20702..8ec4d055 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_i64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_i64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_bool_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_bool_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 535ac2f6..45e9a566 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -58,6 +58,11 @@ namespace xo { self.on_f64_token(tk, p_psm); } auto + ISyntaxStateMachine_DProgressSsm::on_i64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_i64_token(tk, p_psm); + } + auto ISyntaxStateMachine_DProgressSsm::on_bool_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_bool_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 3915aca7..9a594340 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -187,6 +187,10 @@ namespace xo { this->on_f64_token(tk); break; + case tokentype::tk_i64: + this->on_i64_token(tk); + break; + case tokentype::tk_bool: this->on_bool_token(tk); break; @@ -197,7 +201,6 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: - case tokentype::tk_i64: case tokentype::tk_string: case tokentype::tk_leftparen: case tokentype::tk_rightparen: @@ -283,6 +286,14 @@ namespace xo { stack_->top().on_f64_token(tk, this); } + void + ParserStateMachine::on_i64_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_i64_token(tk, this); + } + void ParserStateMachine::on_bool_token(const Token & tk) { From adeef936c492748e1b482be48c0834aab5c92547 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 16:48:24 -0500 Subject: [PATCH 059/258] xo-reader2: accept i64 token in top-level interactive session --- xo-reader2/src/reader2/DExprSeqState.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 6f196963..86c98d84 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include @@ -223,6 +225,26 @@ namespace xo { DExprSeqState::on_i64_token(const Token & tk, ParserStateMachine * p_psm) { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { + auto i64o = DFloat::box(p_psm->expr_alloc(), + tk.i64_value()); + auto * dconst = DConstant::make(p_psm->expr_alloc(), i64o); + auto expr = with_facet::mkobj(dconst); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + p_psm->illegal_input_on_token("DExprSeqState::on_i64_token", tk, this->get_expect_str()); From b6ff61505766b9326e8a6e32cf918aa67f395193 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 17:23:19 -0500 Subject: [PATCH 060/258] xo-reader2: top-level string literal + on_string_token() in SSM --- xo-reader2/idl/SyntaxStateMachine.json5 | 9 ++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 ++++ .../include/xo/reader2/DExpectExprSsm.hpp | 6 ++++ .../include/xo/reader2/DExpectSymbolSsm.hpp | 6 ++++ .../include/xo/reader2/DExpectTypeSsm.hpp | 6 ++++ .../include/xo/reader2/DExprSeqState.hpp | 5 +++ .../include/xo/reader2/DProgressSsm.hpp | 2 ++ .../include/xo/reader2/ParserStateMachine.hpp | 3 ++ .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 ++ .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectExprSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 ++ .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 ++ .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 ++ xo-reader2/src/reader2/DDefineSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 32 +++++++++++++++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 9 ++++++ .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 ++++ .../ISyntaxStateMachine_DDefineSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExpectExprSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExprSeqState.cpp | 5 +++ .../ISyntaxStateMachine_DProgressSsm.cpp | 5 +++ xo-reader2/src/reader2/ParserStateMachine.cpp | 13 +++++++- 32 files changed, 189 insertions(+), 1 deletion(-) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index d03808c1..72dbbf13 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -117,6 +117,15 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_string_token", + doc: ["update state machine for incoming string-token @p tk"], + return_type: "void", + args: [ + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_semicolon_token", doc: ["update state machine for incoming semicolon-token @p tk"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 0bafe4cb..d0af630d 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -147,6 +147,12 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming string tokne @p tk, + * overall parser state in @p p_psm + **/ + void on_string_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 5a628742..c1c9ede7 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -83,6 +83,12 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming string token @p tk, + * overall parser state in @p p_psm + **/ + void on_string_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 910c1978..03dd8408 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -117,6 +117,12 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming string token @p tk, + * overall parser state in @p p_psm + **/ + void on_string_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 77a54f61..8290225f 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -77,6 +77,12 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming string token @p tk, + * overall parser state in @p p_psm + **/ + void on_string_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 4ee2e177..acfcba64 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -90,6 +90,11 @@ namespace xo { **/ void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming string token @p tk, + * overall parser state in @p p_psm + **/ + void on_string_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index ae3bdb85..33981d76 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -141,6 +141,8 @@ namespace xo { ParserStateMachine * p_psm); void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + void on_string_token(const Token & tk, + ParserStateMachine * p_psm); void on_f64_token(const Token & tk, ParserStateMachine * p_psm); void on_i64_token(const Token & tk, diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 870b1d66..eae4d663 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -138,6 +138,9 @@ namespace xo { /** operate state machine for incoming singleassign-token @p tk **/ void on_singleassign_token(const Token & tk); + /** operate state machine for incoming string-otoken @p tk **/ + void on_string_token(const Token & tk); + /** operate state machine for incoming f64-token @p tk **/ void on_f64_token(const Token & tk); diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index feb4a62b..d501232f 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -73,6 +73,8 @@ public: virtual void on_i64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming bool-token @p tk **/ virtual void on_bool_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming string-token @p tk **/ + virtual void on_string_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming semicolon-token @p tk **/ virtual void on_semicolon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 06fd2ff9..351f6a8c 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -68,6 +68,7 @@ namespace scm { [[noreturn]] void on_f64_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_i64_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_bool_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_string_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_semicolon_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index 4c22c587..432b6fac 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -70,6 +70,8 @@ namespace xo { static void on_i64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming string-token @p tk **/ + static void on_string_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 6c64836e..aa1d082e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -70,6 +70,8 @@ namespace xo { static void on_i64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming string-token @p tk **/ + static void on_string_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 0647ce38..039fcae2 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -70,6 +70,8 @@ namespace xo { static void on_i64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming string-token @p tk **/ + static void on_string_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index ec3f10fc..64106cfb 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -70,6 +70,8 @@ namespace xo { static void on_i64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming string-token @p tk **/ + static void on_string_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index c8205ff1..fbf1f317 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -70,6 +70,8 @@ namespace xo { static void on_i64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming string-token @p tk **/ + static void on_string_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index 9cec85e1..0277e1ba 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -70,6 +70,8 @@ namespace xo { static void on_i64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming bool-token @p tk **/ static void on_bool_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming string-token @p tk **/ + static void on_string_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming semicolon-token @p tk **/ static void on_semicolon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 31681b46..fccd523e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -76,6 +76,9 @@ namespace scm { void on_bool_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_bool_token(_dcast(data), tk, p_psm); } + void on_string_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_string_token(_dcast(data), tk, p_psm); + } void on_semicolon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_semicolon_token(_dcast(data), tk, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 4df02804..b91381d0 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -80,6 +80,9 @@ public: void on_bool_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_bool_token(O::data(), tk, p_psm); } + void on_string_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_string_token(O::data(), tk, p_psm); + } void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_semicolon_token(O::data(), tk, p_psm); } diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index eb1d5d55..0f4ac7e1 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -567,6 +567,15 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_string_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DDefineSsm::on_string_token", + tk, + this->get_expect_str()); + } + void DDefineSsm::on_f64_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 553973a6..a5d46052 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -147,6 +147,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectExprSsm::on_string_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectExprSsm::on_string_token", + tk, + this->get_expect_str()); + } + void DExpectExprSsm::on_f64_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index d32f3ce5..d41f08da 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -149,6 +149,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_string_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_string_token", + tk, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_f64_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index d20128c0..b8be164c 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -92,6 +92,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_string_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectTypeSsm", + tk, + this->get_expect_str()); + } + void DExpectTypeSsm::on_f64_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 86c98d84..90b9824b 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -192,6 +194,36 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_string_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { + DString * dstr = DString::from_cstr(p_psm->expr_alloc(), + tk.text().c_str()); + obj str(dstr); + auto * dconst = DConstant::make(p_psm->expr_alloc(), str); + obj expr(dconst); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + p_psm->illegal_input_on_token("DExprSeqState::on_string_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_f64_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index f6b14bc1..50ec2fbe 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -203,6 +203,15 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_string_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DProgressSsm::on_string_token", + tk, + this->get_expect_str()); + } + void DProgressSsm::on_f64_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 39fcea13..f270c352 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -82,6 +82,12 @@ ISyntaxStateMachine_Any::on_bool_token(Opaque, const Token &, ParserStateMachine _fatal(); } +auto +ISyntaxStateMachine_Any::on_string_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_semicolon_token(Opaque, const Token &, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 69520cae..c39c51b2 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -68,6 +68,11 @@ namespace xo { self.on_bool_token(tk, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_string_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_string_token(tk, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_semicolon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index b247c821..0e5efa5d 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -68,6 +68,11 @@ namespace xo { self.on_bool_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectExprSsm::on_string_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_string_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectExprSsm::on_semicolon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 318e68cb..0b47c31a 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -68,6 +68,11 @@ namespace xo { self.on_bool_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_string_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_string_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_semicolon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 3d98c1f8..515b81a8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -68,6 +68,11 @@ namespace xo { self.on_bool_token(tk, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_string_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_string_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_semicolon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 8ec4d055..04cc4516 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -68,6 +68,11 @@ namespace xo { self.on_bool_token(tk, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_string_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_string_token(tk, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_semicolon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 45e9a566..28b69cfb 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -68,6 +68,11 @@ namespace xo { self.on_bool_token(tk, p_psm); } auto + ISyntaxStateMachine_DProgressSsm::on_string_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_string_token(tk, p_psm); + } + auto ISyntaxStateMachine_DProgressSsm::on_semicolon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_semicolon_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 9a594340..adc14f1b 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -183,6 +183,10 @@ namespace xo { this->on_singleassign_token(tk); break; + case tokentype::tk_string: + this->on_string_token(tk); + break; + case tokentype::tk_f64: this->on_f64_token(tk); break; @@ -201,7 +205,6 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: - case tokentype::tk_string: case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: @@ -278,6 +281,14 @@ namespace xo { stack_->top().on_singleassign_token(tk, this); } + void + ParserStateMachine::on_string_token(const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + stack_->top().on_string_token(tk, this); + } + void ParserStateMachine::on_f64_token(const Token & tk) { From e4cfb57beff1b071eb9771fb6a5cfab1730daf5c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 23 Jan 2026 19:01:12 -0500 Subject: [PATCH 061/258] xo-reader2: refactor: push token dispatch to satellite SSMs --- xo-reader2/idl/SyntaxStateMachine.json5 | 85 +--------- xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 + .../include/xo/reader2/DExpectExprSsm.hpp | 6 + .../include/xo/reader2/DExpectSymbolSsm.hpp | 6 + .../include/xo/reader2/DExpectTypeSsm.hpp | 6 + .../include/xo/reader2/DExprSeqState.hpp | 6 + .../include/xo/reader2/DProgressSsm.hpp | 6 + .../include/xo/reader2/ParserStateMachine.hpp | 30 ---- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 22 +-- .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 11 +- .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 22 +-- .../ISyntaxStateMachine_DExpectExprSsm.hpp | 22 +-- .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 22 +-- .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 22 +-- .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 22 +-- .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 22 +-- .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 31 +--- .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 31 +--- xo-reader2/src/reader2/DDefineSsm.cpp | 90 +++++++++- xo-reader2/src/reader2/DExpectExprSsm.cpp | 86 ++++++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 86 ++++++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 86 ++++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 86 ++++++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 86 ++++++++++ .../src/reader2/ISyntaxStateMachine_Any.cpp | 56 +------ .../ISyntaxStateMachine_DDefineSsm.cpp | 49 +----- .../ISyntaxStateMachine_DExpectExprSsm.cpp | 49 +----- .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 49 +----- .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 49 +----- .../ISyntaxStateMachine_DExprSeqState.cpp | 49 +----- .../ISyntaxStateMachine_DProgressSsm.cpp | 49 +----- xo-reader2/src/reader2/ParserStateMachine.cpp | 158 +----------------- 32 files changed, 590 insertions(+), 816 deletions(-) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 72dbbf13..15a36f12 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -46,89 +46,8 @@ ], nonconst_methods: [ { - name: "on_symbol_token", - doc: ["operate state machine for incoming symbol-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_def_token", - doc: ["update state machine for incoming define-keyword-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_if_token", - doc: ["update state machine for incoming if-keyword-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_colon_token", - doc: ["update state machine for incoming colon-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_singleassign_token", - doc: ["update state machine for incoming singleassign-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_f64_token", - doc: ["update state machine for incoming f64-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_i64_token", - doc: ["update state machine for incoming i64-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_bool_token", - doc: ["update state machine for incoming bool-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_string_token", - doc: ["update state machine for incoming string-token @p tk"], - return_type: "void", - args: [ - {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "p_psm"}, - ], - }, - { - name: "on_semicolon_token", - doc: ["update state machine for incoming semicolon-token @p tk"], + name: "on_token", + doc: ["operate state machine for incoming token @p tk"], return_type: "void", args: [ {type: "const Token &", name: "tk"}, diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index d0af630d..9f707fca 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -117,6 +117,12 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + /** operate state machine for this syntax on incoming symbol-token @p tk * with overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index c1c9ede7..85d4e5e1 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -53,6 +53,12 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + /** operate state machine for this syntax on incoming symbol-token @p tk * with overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 03dd8408..4cb04019 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -93,6 +93,12 @@ namespace xo { void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm); + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm. **/ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 8290225f..346a6d6c 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -47,6 +47,12 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + /** operate state machien for this syntax on incoming symbol-token @p tk * with overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index acfcba64..72566004 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -65,6 +65,12 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + /** operate state machine for this syntax on incoming symbol token @p tk * with overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 33981d76..7258731c 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -131,6 +131,12 @@ namespace xo { /** @defgroup scm-progressssm-ssm-facet syntaxstatemachine facet methods **/ /// @{ + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); void on_def_token(const Token & tk, diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index eae4d663..a674e7e2 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -123,36 +123,6 @@ namespace xo { **/ void on_token(const Token & tk); - /** operate state machine for incoming symbol-token @p tk **/ - void on_symbol_token(const Token & tk); - - /** operate state machine for incoming define-token @p tk **/ - void on_def_token(const Token & tk); - - /** operate state machine for incoming if-token @p tk **/ - void on_if_token(const Token & tk); - - /** operate state machine for incoming colon-token @p tk **/ - void on_colon_token(const Token & tk); - - /** operate state machine for incoming singleassign-token @p tk **/ - void on_singleassign_token(const Token & tk); - - /** operate state machine for incoming string-otoken @p tk **/ - void on_string_token(const Token & tk); - - /** operate state machine for incoming f64-token @p tk **/ - void on_f64_token(const Token & tk); - - /** operate state machine for incoming i64-token @p tk **/ - void on_i64_token(const Token & tk); - - /** operate state machine for incoming bool-token @p tk **/ - void on_bool_token(const Token & tk); - - /** operate state machine for incoming semicolon-token @p tk **/ - void on_semicolon_token(const Token & tk); - ///@} /** @defgroup scm-parserstatemachine-error-entrypoints error entry points **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index d501232f..3115d692 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -57,26 +57,8 @@ public: virtual std::string_view get_expect_str(Copaque data) const noexcept = 0; // nonconst methods - /** operate state machine for incoming symbol-token @p tk **/ - virtual void on_symbol_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming define-keyword-token @p tk **/ - virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming if-keyword-token @p tk **/ - virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming colon-token @p tk **/ - virtual void on_colon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming singleassign-token @p tk **/ - virtual void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming f64-token @p tk **/ - virtual void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming i64-token @p tk **/ - virtual void on_i64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming bool-token @p tk **/ - virtual void on_bool_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming string-token @p tk **/ - virtual void on_string_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming semicolon-token @p tk **/ - virtual void on_semicolon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; + /** operate state machine for incoming token @p tk **/ + virtual void on_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update stat machine for incoming parsed symbol @p sym **/ virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 351f6a8c..45be148e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -60,16 +60,7 @@ namespace scm { [[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); } // nonconst methods - [[noreturn]] void on_symbol_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_def_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_colon_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_singleassign_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_f64_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_i64_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_bool_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_string_token(Opaque, const Token &, ParserStateMachine *) override; - [[noreturn]] void on_semicolon_token(Opaque, const Token &, ParserStateMachine *) override; + [[noreturn]] void on_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression(Opaque, obj, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index 432b6fac..dad8ff29 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -54,26 +54,8 @@ namespace xo { static std::string_view get_expect_str(const DDefineSsm & self) noexcept; // non-const methods - /** operate state machine for incoming symbol-token @p tk **/ - static void on_symbol_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming define-keyword-token @p tk **/ - static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming if-keyword-token @p tk **/ - static void on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming colon-token @p tk **/ - static void on_colon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming singleassign-token @p tk **/ - static void on_singleassign_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming f64-token @p tk **/ - static void on_f64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming i64-token @p tk **/ - static void on_i64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming bool-token @p tk **/ - static void on_bool_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming string-token @p tk **/ - static void on_string_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming semicolon-token @p tk **/ - static void on_semicolon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** operate state machine for incoming token @p tk **/ + static void on_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index aa1d082e..7250cec7 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -54,26 +54,8 @@ namespace xo { static std::string_view get_expect_str(const DExpectExprSsm & self) noexcept; // non-const methods - /** operate state machine for incoming symbol-token @p tk **/ - static void on_symbol_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming define-keyword-token @p tk **/ - static void on_def_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming if-keyword-token @p tk **/ - static void on_if_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming colon-token @p tk **/ - static void on_colon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming singleassign-token @p tk **/ - static void on_singleassign_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming f64-token @p tk **/ - static void on_f64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming i64-token @p tk **/ - static void on_i64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming bool-token @p tk **/ - static void on_bool_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming string-token @p tk **/ - static void on_string_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming semicolon-token @p tk **/ - static void on_semicolon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 039fcae2..7e83d0e4 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -54,26 +54,8 @@ namespace xo { static std::string_view get_expect_str(const DExpectSymbolSsm & self) noexcept; // non-const methods - /** operate state machine for incoming symbol-token @p tk **/ - static void on_symbol_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming define-keyword-token @p tk **/ - static void on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming if-keyword-token @p tk **/ - static void on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming colon-token @p tk **/ - static void on_colon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming singleassign-token @p tk **/ - static void on_singleassign_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming f64-token @p tk **/ - static void on_f64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming i64-token @p tk **/ - static void on_i64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming bool-token @p tk **/ - static void on_bool_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming string-token @p tk **/ - static void on_string_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming semicolon-token @p tk **/ - static void on_semicolon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 64106cfb..c8c4cc9f 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -54,26 +54,8 @@ namespace xo { static std::string_view get_expect_str(const DExpectTypeSsm & self) noexcept; // non-const methods - /** operate state machine for incoming symbol-token @p tk **/ - static void on_symbol_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming define-keyword-token @p tk **/ - static void on_def_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming if-keyword-token @p tk **/ - static void on_if_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming colon-token @p tk **/ - static void on_colon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming singleassign-token @p tk **/ - static void on_singleassign_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming f64-token @p tk **/ - static void on_f64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming i64-token @p tk **/ - static void on_i64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming bool-token @p tk **/ - static void on_bool_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming string-token @p tk **/ - static void on_string_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming semicolon-token @p tk **/ - static void on_semicolon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index fbf1f317..2a86db05 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -54,26 +54,8 @@ namespace xo { static std::string_view get_expect_str(const DExprSeqState & self) noexcept; // non-const methods - /** operate state machine for incoming symbol-token @p tk **/ - static void on_symbol_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming define-keyword-token @p tk **/ - static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming if-keyword-token @p tk **/ - static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming colon-token @p tk **/ - static void on_colon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming singleassign-token @p tk **/ - static void on_singleassign_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming f64-token @p tk **/ - static void on_f64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming i64-token @p tk **/ - static void on_i64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming bool-token @p tk **/ - static void on_bool_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming string-token @p tk **/ - static void on_string_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming semicolon-token @p tk **/ - static void on_semicolon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + /** operate state machine for incoming token @p tk **/ + static void on_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index 0277e1ba..3d70afed 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -54,26 +54,8 @@ namespace xo { static std::string_view get_expect_str(const DProgressSsm & self) noexcept; // non-const methods - /** operate state machine for incoming symbol-token @p tk **/ - static void on_symbol_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming define-keyword-token @p tk **/ - static void on_def_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming if-keyword-token @p tk **/ - static void on_if_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming colon-token @p tk **/ - static void on_colon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming singleassign-token @p tk **/ - static void on_singleassign_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming f64-token @p tk **/ - static void on_f64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming i64-token @p tk **/ - static void on_i64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming bool-token @p tk **/ - static void on_bool_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming string-token @p tk **/ - static void on_string_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); - /** update state machine for incoming semicolon-token @p tk **/ - static void on_semicolon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** operate state machine for incoming token @p tk **/ + static void on_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ static void on_parsed_symbol(DProgressSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index fccd523e..36c2ff83 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -52,35 +52,8 @@ namespace scm { } // non-const methods - void on_symbol_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_symbol_token(_dcast(data), tk, p_psm); - } - void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_def_token(_dcast(data), tk, p_psm); - } - void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_if_token(_dcast(data), tk, p_psm); - } - void on_colon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_colon_token(_dcast(data), tk, p_psm); - } - void on_singleassign_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_singleassign_token(_dcast(data), tk, p_psm); - } - void on_f64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_f64_token(_dcast(data), tk, p_psm); - } - void on_i64_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_i64_token(_dcast(data), tk, p_psm); - } - void on_bool_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_bool_token(_dcast(data), tk, p_psm); - } - void on_string_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_string_token(_dcast(data), tk, p_psm); - } - void on_semicolon_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { - return I::on_semicolon_token(_dcast(data), tk, p_psm); + void on_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_token(_dcast(data), tk, p_psm); } void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { return I::on_parsed_symbol(_dcast(data), sym, p_psm); diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index b91381d0..fb1fb496 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -56,35 +56,8 @@ public: } // non-const methods (still const in router!) - void on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_symbol_token(O::data(), tk, p_psm); - } - void on_def_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_def_token(O::data(), tk, p_psm); - } - void on_if_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_if_token(O::data(), tk, p_psm); - } - void on_colon_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_colon_token(O::data(), tk, p_psm); - } - void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_singleassign_token(O::data(), tk, p_psm); - } - void on_f64_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_f64_token(O::data(), tk, p_psm); - } - void on_i64_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_i64_token(O::data(), tk, p_psm); - } - void on_bool_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_bool_token(O::data(), tk, p_psm); - } - void on_string_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_string_token(O::data(), tk, p_psm); - } - void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { - return O::iface()->on_semicolon_token(O::data(), tk, p_psm); + void on_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_token(O::data(), tk, p_psm); } void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 0f4ac7e1..b8c5b0ae 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -369,7 +369,9 @@ namespace xo { = with_facet::mkobj(define_ssm); p_psm->push_ssm(ssm); - p_psm->on_def_token(Token::def_token()); + + // note: triggers poly dispatch + p_psm->on_token(Token::def_token()); } syntaxstatetype @@ -489,6 +491,92 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_symbol: + this->on_symbol_token(tk, p_psm); + break; + + case tokentype::tk_def: + this->on_def_token(tk, p_psm); + break; + + case tokentype::tk_if: + this->on_if_token(tk, p_psm); + break; + + case tokentype::tk_colon: + this->on_colon_token(tk, p_psm); + break; + + case tokentype::tk_singleassign: + this->on_singleassign_token(tk, p_psm); + break; + + case tokentype::tk_string: + this->on_string_token(tk, p_psm); + break; + + case tokentype::tk_f64: + this->on_f64_token(tk, p_psm); + break; + + case tokentype::tk_i64: + this->on_i64_token(tk, p_psm); + break; + + case tokentype::tk_bool: + this->on_bool_token(tk, p_psm); + break; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + break; + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + p_psm->illegal_input_on_token("DDefineSsm::on_token", + tk, + this->get_expect_str()); + } + void DDefineSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index a5d46052..fc5dbe08 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -102,6 +102,92 @@ namespace xo { } } + void + DExpectExprSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_symbol: + this->on_symbol_token(tk, p_psm); + break; + + case tokentype::tk_def: + this->on_def_token(tk, p_psm); + break; + + case tokentype::tk_if: + this->on_if_token(tk, p_psm); + break; + + case tokentype::tk_colon: + this->on_colon_token(tk, p_psm); + break; + + case tokentype::tk_singleassign: + this->on_singleassign_token(tk, p_psm); + break; + + case tokentype::tk_string: + this->on_string_token(tk, p_psm); + break; + + case tokentype::tk_f64: + this->on_f64_token(tk, p_psm); + break; + + case tokentype::tk_i64: + this->on_i64_token(tk, p_psm); + break; + + case tokentype::tk_bool: + this->on_bool_token(tk, p_psm); + break; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + break; + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + p_psm->illegal_input_on_token("DExpectExprSsm::on_token", + tk, + this->get_expect_str()); + } + void DExpectExprSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index d41f08da..cbfb1c91 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -92,6 +92,92 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_symbol: + this->on_symbol_token(tk, p_psm); + break; + + case tokentype::tk_def: + this->on_def_token(tk, p_psm); + break; + + case tokentype::tk_if: + this->on_if_token(tk, p_psm); + break; + + case tokentype::tk_colon: + this->on_colon_token(tk, p_psm); + break; + + case tokentype::tk_singleassign: + this->on_singleassign_token(tk, p_psm); + break; + + case tokentype::tk_string: + this->on_string_token(tk, p_psm); + break; + + case tokentype::tk_f64: + this->on_f64_token(tk, p_psm); + break; + + case tokentype::tk_i64: + this->on_i64_token(tk, p_psm); + break; + + case tokentype::tk_bool: + this->on_bool_token(tk, p_psm); + break; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + break; + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_token", + tk, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index b8be164c..2feaee26 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -56,6 +56,92 @@ namespace xo { return "typename"; } + void + DExpectTypeSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_symbol: + this->on_symbol_token(tk, p_psm); + break; + + case tokentype::tk_def: + this->on_def_token(tk, p_psm); + break; + + case tokentype::tk_if: + this->on_if_token(tk, p_psm); + break; + + case tokentype::tk_colon: + this->on_colon_token(tk, p_psm); + break; + + case tokentype::tk_singleassign: + this->on_singleassign_token(tk, p_psm); + break; + + case tokentype::tk_string: + this->on_string_token(tk, p_psm); + break; + + case tokentype::tk_f64: + this->on_f64_token(tk, p_psm); + break; + + case tokentype::tk_i64: + this->on_i64_token(tk, p_psm); + break; + + case tokentype::tk_bool: + this->on_bool_token(tk, p_psm); + break; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + break; + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + p_psm->illegal_input_on_token("DExpectTypeSsm::on_token", + tk, + this->get_expect_str()); + } + void DExpectTypeSsm::on_def_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 90b9824b..9691d665 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -105,6 +105,92 @@ namespace xo { return "impossible-DExprSeqState::get_expr_str"; } + void + DExprSeqState::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_symbol: + this->on_symbol_token(tk, p_psm); + break; + + case tokentype::tk_def: + this->on_def_token(tk, p_psm); + break; + + case tokentype::tk_if: + this->on_if_token(tk, p_psm); + break; + + case tokentype::tk_colon: + this->on_colon_token(tk, p_psm); + break; + + case tokentype::tk_singleassign: + this->on_singleassign_token(tk, p_psm); + break; + + case tokentype::tk_string: + this->on_string_token(tk, p_psm); + break; + + case tokentype::tk_f64: + this->on_f64_token(tk, p_psm); + break; + + case tokentype::tk_i64: + this->on_i64_token(tk, p_psm); + break; + + case tokentype::tk_bool: + this->on_bool_token(tk, p_psm); + break; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + break; + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + p_psm->illegal_input_on_token("DExprSeqState::on_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 50ec2fbe..a40b6f59 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -158,6 +158,92 @@ namespace xo { } } + void + DProgressSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_symbol: + this->on_symbol_token(tk, p_psm); + break; + + case tokentype::tk_def: + this->on_def_token(tk, p_psm); + break; + + case tokentype::tk_if: + this->on_if_token(tk, p_psm); + break; + + case tokentype::tk_colon: + this->on_colon_token(tk, p_psm); + break; + + case tokentype::tk_singleassign: + this->on_singleassign_token(tk, p_psm); + break; + + case tokentype::tk_string: + this->on_string_token(tk, p_psm); + break; + + case tokentype::tk_f64: + this->on_f64_token(tk, p_psm); + break; + + case tokentype::tk_i64: + this->on_i64_token(tk, p_psm); + break; + + case tokentype::tk_bool: + this->on_bool_token(tk, p_psm); + break; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + break; + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + p_psm->illegal_input_on_token("DProgressSsm::on_token", + tk, + this->get_expect_str()); + } + void DProgressSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index f270c352..4cfb72a7 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -35,61 +35,7 @@ ISyntaxStateMachine_Any::_valid // nonconst methods auto -ISyntaxStateMachine_Any::on_symbol_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_def_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_if_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_colon_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_singleassign_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_f64_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_i64_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_bool_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_string_token(Opaque, const Token &, ParserStateMachine *) -> void -{ - _fatal(); -} - -auto -ISyntaxStateMachine_Any::on_semicolon_token(Opaque, const Token &, ParserStateMachine *) -> void +ISyntaxStateMachine_Any::on_token(Opaque, const Token &, ParserStateMachine *) -> void { _fatal(); } diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index c39c51b2..85c2a8f0 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -28,54 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DDefineSsm::on_symbol_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DDefineSsm::on_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_symbol_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_def_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_if_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_colon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_colon_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_singleassign_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_singleassign_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_f64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_f64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_i64_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_i64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_bool_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_bool_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_string_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_string_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DDefineSsm::on_semicolon_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_semicolon_token(tk, p_psm); + self.on_token(tk, p_psm); } auto ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index 0e5efa5d..e545eedd 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -28,54 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DExpectExprSsm::on_symbol_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectExprSsm::on_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_symbol_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_def_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_def_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_if_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_if_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_colon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_colon_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_singleassign_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_singleassign_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_f64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_f64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_i64_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_i64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_bool_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_bool_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_string_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_string_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectExprSsm::on_semicolon_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_semicolon_token(tk, p_psm); + self.on_token(tk, p_psm); } auto ISyntaxStateMachine_DExpectExprSsm::on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 0b47c31a..0a35bb71 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -28,54 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DExpectSymbolSsm::on_symbol_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectSymbolSsm::on_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_symbol_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_def_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_if_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_colon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_colon_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_singleassign_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_singleassign_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_f64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_f64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_i64_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_i64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_bool_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_bool_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_string_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_string_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectSymbolSsm::on_semicolon_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_semicolon_token(tk, p_psm); + self.on_token(tk, p_psm); } auto ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 515b81a8..4b6950ab 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -28,54 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DExpectTypeSsm::on_symbol_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectTypeSsm::on_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_symbol_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_def_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_def_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_if_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_if_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_colon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_colon_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_singleassign_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_singleassign_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_f64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_f64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_i64_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_i64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_bool_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_bool_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_string_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_string_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExpectTypeSsm::on_semicolon_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_semicolon_token(tk, p_psm); + self.on_token(tk, p_psm); } auto ISyntaxStateMachine_DExpectTypeSsm::on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 04cc4516..af5d3cc9 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -28,54 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DExprSeqState::on_symbol_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_symbol_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_def_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_if_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_colon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_colon_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_singleassign_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_singleassign_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_f64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_f64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_i64_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_i64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_bool_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_bool_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_string_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_string_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_semicolon_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_semicolon_token(tk, p_psm); + self.on_token(tk, p_psm); } auto ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 28b69cfb..1fdd6c90 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -28,54 +28,9 @@ namespace xo { } auto - ISyntaxStateMachine_DProgressSsm::on_symbol_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DProgressSsm::on_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_symbol_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_def_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_def_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_if_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_if_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_colon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_colon_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_singleassign_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_singleassign_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_f64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_f64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_i64_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_i64_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_bool_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_bool_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_string_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_string_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DProgressSsm::on_semicolon_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_semicolon_token(tk, p_psm); + self.on_token(tk, p_psm); } auto ISyntaxStateMachine_DProgressSsm::on_parsed_symbol(DProgressSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index adc14f1b..2d9e4970 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -162,163 +162,7 @@ namespace xo { )); } - switch (tk.tk_type()) { - case tokentype::tk_symbol: - this->on_symbol_token(tk); - break; - - case tokentype::tk_def: - this->on_def_token(tk); - break; - - case tokentype::tk_if: - this->on_if_token(tk); - break; - - case tokentype::tk_colon: - this->on_colon_token(tk); - break; - - case tokentype::tk_singleassign: - this->on_singleassign_token(tk); - break; - - case tokentype::tk_string: - this->on_string_token(tk); - break; - - case tokentype::tk_f64: - this->on_f64_token(tk); - break; - - case tokentype::tk_i64: - this->on_i64_token(tk); - break; - - case tokentype::tk_bool: - this->on_bool_token(tk); - break; - - case tokentype::tk_semicolon: - this->on_semicolon_token(tk); - break; - - // all the not-yet handled cases - case tokentype::tk_invalid: - case tokentype::tk_leftparen: - case tokentype::tk_rightparen: - case tokentype::tk_leftbracket: - case tokentype::tk_rightbracket: - case tokentype::tk_leftbrace: - case tokentype::tk_rightbrace: - case tokentype::tk_leftangle: - case tokentype::tk_rightangle: - case tokentype::tk_lessequal: - case tokentype::tk_greatequal: - case tokentype::tk_dot: - case tokentype::tk_comma: - case tokentype::tk_doublecolon: - case tokentype::tk_assign: - case tokentype::tk_yields: - case tokentype::tk_plus: - case tokentype::tk_minus: - case tokentype::tk_star: - case tokentype::tk_slash: - case tokentype::tk_cmpeq: - case tokentype::tk_cmpne: - case tokentype::tk_type: - case tokentype::tk_lambda: - case tokentype::tk_then: - case tokentype::tk_else: - case tokentype::tk_let: - case tokentype::tk_in: - case tokentype::tk_end: - case tokentype::N: - throw std::runtime_error(tostr("ParserStateMachin::on_token:", - "NOT IMPLEMENTED", - xtag("token", tk))); - - } - } - - void - ParserStateMachine::on_symbol_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_symbol_token(tk, this); - } - - void - ParserStateMachine::on_def_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_def_token(tk, this); - } - - void - ParserStateMachine::on_if_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_if_token(tk, this); - } - - void - ParserStateMachine::on_colon_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_colon_token(tk, this); - } - - void - ParserStateMachine::on_singleassign_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_singleassign_token(tk, this); - } - - void - ParserStateMachine::on_string_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_string_token(tk, this); - } - - void - ParserStateMachine::on_f64_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_f64_token(tk, this); - } - - void - ParserStateMachine::on_i64_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_i64_token(tk, this); - } - - void - ParserStateMachine::on_bool_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_bool_token(tk, this); - } - - void - ParserStateMachine::on_semicolon_token(const Token & tk) - { - scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); - - stack_->top().on_semicolon_token(tk, this); + stack_->top().on_token(tk, this); } void From 66e666cc655ff30167cdb8e7a9fce7ab61ddf4e4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:02:58 -0500 Subject: [PATCH 062/258] xo-reflect: minor: const in TypeDriveMap.lookup method --- xo-reflect/include/xo/reflect/TypeDrivenMap.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xo-reflect/include/xo/reflect/TypeDrivenMap.hpp b/xo-reflect/include/xo/reflect/TypeDrivenMap.hpp index d972780f..2568887d 100644 --- a/xo-reflect/include/xo/reflect/TypeDrivenMap.hpp +++ b/xo-reflect/include/xo/reflect/TypeDrivenMap.hpp @@ -17,7 +17,7 @@ namespace xo { TypeDrivenMap() = default; const Value * lookup(TypeId id) const { return this->lookup_slot(id); } - const Value * lookup(TypeDescr td) { return this->lookup_slot(td->id()); } + const Value * lookup(TypeDescr td) const { return this->lookup_slot(td->id()); } Value * require(TypeId id) { return this->require_slot(id); } Value * require(TypeDescr td) { return this->require_slot(td->id()); } From 5f5469637a292fad7ea6c5d1c8735448d72167cf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:03:41 -0500 Subject: [PATCH 063/258] xo-object2: + DString.from_str() --- xo-object2/include/xo/object2/DString.hpp | 6 ++++++ xo-object2/src/object2/DString.cpp | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/xo-object2/include/xo/object2/DString.hpp b/xo-object2/include/xo/object2/DString.hpp index eea8ea5c..a6cedb00 100644 --- a/xo-object2/include/xo/object2/DString.hpp +++ b/xo-object2/include/xo/object2/DString.hpp @@ -78,6 +78,12 @@ namespace xo { static DString * from_view(obj mm, std::string_view sv); + /** create string containing a copy @p str. + * Use memory from allocator @p mm. + **/ + static DString * from_str(obj mm, + const std::string & str); + /** create string containing a copy of @p sv. * Use memory from allocator @p mm via sub_alloc. * (load-bearing for StringTable) diff --git a/xo-object2/src/object2/DString.cpp b/xo-object2/src/object2/DString.cpp index ee9885b7..69baa5d6 100644 --- a/xo-object2/src/object2/DString.cpp +++ b/xo-object2/src/object2/DString.cpp @@ -91,6 +91,15 @@ namespace xo { return _from_view_aux(mm, sv, false /*!suballoc_flag*/); } + DString * + DString::from_str(obj mm, + const std::string & str) + { + return _from_view_aux(mm, + std::string_view(str), + false /*!suballoc_flag*/); + } + DString * DString::from_view_suballoc(obj mm, std::string_view sv) From 1c4d4e63623e7c0959022b25639d45cef5f1bea6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:04:36 -0500 Subject: [PATCH 064/258] xo-object: cosmetic: formatting --- xo-object/src/object/ObjectConverter.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/xo-object/src/object/ObjectConverter.cpp b/xo-object/src/object/ObjectConverter.cpp index 8ec4c620..71ed408a 100644 --- a/xo-object/src/object/ObjectConverter.cpp +++ b/xo-object/src/object/ObjectConverter.cpp @@ -150,14 +150,19 @@ namespace xo { ObjectConverter::ObjectConverter() { - this->establish_conversion(&int_to_object, &object_to_int); - this->establish_conversion(&int_to_object, &object_to_int); + this->establish_conversion(&int_to_object, + &object_to_int); + this->establish_conversion(&int_to_object, + &object_to_int); - this->establish_conversion(&float_to_object, &object_to_float); + this->establish_conversion(&float_to_object, + &object_to_float); - this->establish_conversion(&bool_to_object, &object_to_bool); + this->establish_conversion(&bool_to_object, + &object_to_bool); - this->establish_conversion(&string_to_object, &object_to_string); + this->establish_conversion(&string_to_object, + &object_to_string); } gp From 670f5d3d91af07d284be8fea154e1c793fff66a0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:04:48 -0500 Subject: [PATCH 065/258] xo-object: cosmetic: formatting --- xo-object/src/object/ObjectConverter.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/xo-object/src/object/ObjectConverter.cpp b/xo-object/src/object/ObjectConverter.cpp index 71ed408a..a7d0ed4d 100644 --- a/xo-object/src/object/ObjectConverter.cpp +++ b/xo-object/src/object/ObjectConverter.cpp @@ -177,9 +177,10 @@ namespace xo { return (cvt->cvt_to_object_)(mm, x_tp); } else { if (throw_flag) { - throw std::runtime_error(tostr("no to-object-converter available for instance of type", - xtag("id", x_tp.td()->id()), - xtag("name", x_tp.td()->short_name()))); + throw std::runtime_error + (tostr("no to-object-converter available for instance of type", + xtag("id", x_tp.td()->id()), + xtag("name", x_tp.td()->short_name()))); } return nullptr; From 9be54387c2db28df9bd100fb7c5bf35f710631fc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:08:11 -0500 Subject: [PATCH 066/258] xo-object: cosmetic: formatting --- xo-object/include/xo/object/ObjectConversion.hpp | 4 ++-- xo-object/include/xo/object/ObjectConverter.hpp | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/xo-object/include/xo/object/ObjectConversion.hpp b/xo-object/include/xo/object/ObjectConversion.hpp index def83545..38b11a7d 100644 --- a/xo-object/include/xo/object/ObjectConversion.hpp +++ b/xo-object/include/xo/object/ObjectConversion.hpp @@ -24,7 +24,7 @@ namespace xo { * ObjectConversion * in object/Integer.hpp **/ - } -} + } /*namespace obj*/ +} /*namespace xo*/ /* end ObjectConversion.hpp */ diff --git a/xo-object/include/xo/object/ObjectConverter.hpp b/xo-object/include/xo/object/ObjectConverter.hpp index a4b337fd..a7dd6a9b 100644 --- a/xo-object/include/xo/object/ObjectConverter.hpp +++ b/xo-object/include/xo/object/ObjectConverter.hpp @@ -13,7 +13,7 @@ namespace xo { namespace obj { /* Convert between xo::reflect::TaggedPtr and xo::Object for - * a particular wrapped c++ type + * a particular wrapped c++ type. */ struct Converter { using TaggedPtr = xo::reflect::TaggedPtr; @@ -22,7 +22,9 @@ namespace xo { public: Converter() = default; - explicit Converter(ConvertToObjectFn to, ConvertFromObjectFn from) : cvt_to_object_{to}, cvt_from_object_{from} {} + explicit Converter(ConvertToObjectFn to, + ConvertFromObjectFn from) + : cvt_to_object_{to}, cvt_from_object_{from} {} /** convert tagged pointer @p tp to new object, * allocated via @p mm. @@ -58,6 +60,9 @@ namespace xo { * // cvt is a converter for T instances * gp obj = (*(cvt->cvt_to_object_))(mm, * @endcode + * + * ObjectConverter converts at run-time + * @see ObjectConversion for compile-time conversion **/ class ObjectConverter { public: From 6972363118f6fa4994436f6df7fcf87b5db292ac Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:08:32 -0500 Subject: [PATCH 067/258] xo-object2: doc: + glossary.rst --- xo-object2/doc/glossary.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 xo-object2/doc/glossary.rst diff --git a/xo-object2/doc/glossary.rst b/xo-object2/doc/glossary.rst new file mode 100644 index 00000000..4cabbbd5 --- /dev/null +++ b/xo-object2/doc/glossary.rst @@ -0,0 +1 @@ +gco = gc-aware object From 0a1aa8c0f1f04b5f94c735b39167ce8e74bcb473 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:09:53 -0500 Subject: [PATCH 068/258] xo-gc: + GCObjectConversion template --- xo-gc/include/xo/gc/GCObjectConversion.hpp | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 xo-gc/include/xo/gc/GCObjectConversion.hpp diff --git a/xo-gc/include/xo/gc/GCObjectConversion.hpp b/xo-gc/include/xo/gc/GCObjectConversion.hpp new file mode 100644 index 00000000..6e3e84df --- /dev/null +++ b/xo-gc/include/xo/gc/GCObjectConversion.hpp @@ -0,0 +1,30 @@ +/** @file GCObjectConversion.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include +#include + +namespace xo { + namespace scm { + /** @brief compile-time conversion obj <-> T + * + * Specialize for each T that participates in conversion. + * Methods here aren't implemented + **/ + template + struct GCObjectConversion { + using AGCObject = xo::mm::AGCObject; + using AAllocator = xo::mm::AAllocator; + + static obj to_gco(obj mm, const T & x); + static T from_gco(obj mm, obj gco); + }; + + } /*namespace scm */ +} /*namespace xo*/ + +/* end GCObjectConversion.hpp */ From ecf4081924f2c7ca67f8f4fbc30524921e281511 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:13:22 -0500 Subject: [PATCH 069/258] xo-object2: GCObjectConversion for double (via DFloat) --- xo-object2/cmake/xo_object2Config.cmake.in | 1 + .../number/GCObjectConversion_DFloat.hpp | 29 +++++++++++++ xo-object2/src/object2/CMakeLists.txt | 8 ++-- .../src/object2/GCObjectConversion_DFloat.cpp | 41 +++++++++++++++++++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 xo-object2/include/xo/object2/number/GCObjectConversion_DFloat.hpp create mode 100644 xo-object2/src/object2/GCObjectConversion_DFloat.cpp diff --git a/xo-object2/cmake/xo_object2Config.cmake.in b/xo-object2/cmake/xo_object2Config.cmake.in index 36d3bb62..6773adb7 100644 --- a/xo-object2/cmake/xo_object2Config.cmake.in +++ b/xo-object2/cmake/xo_object2Config.cmake.in @@ -1,6 +1,7 @@ @PACKAGE_INIT@ include(CMakeFindDependencyMacro) +find_dependency(reflect) find_dependency(xo_gc) find_dependency(xo_printable2) find_dependency(subsys) diff --git a/xo-object2/include/xo/object2/number/GCObjectConversion_DFloat.hpp b/xo-object2/include/xo/object2/number/GCObjectConversion_DFloat.hpp new file mode 100644 index 00000000..8ce4b2b6 --- /dev/null +++ b/xo-object2/include/xo/object2/number/GCObjectConversion_DFloat.hpp @@ -0,0 +1,29 @@ +/** @file GCObjectConversion_DFloat.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DFloat.hpp" +#include "number/IGCObject_DFloat.hpp" +#include + +namespace xo { + namespace scm { + + template <> + struct GCObjectConversion { + static_assert(std::is_same_v); + + using AGCObject = xo::mm::AGCObject; + using AAllocator = xo::mm::AAllocator; + + static obj to_gco(obj mm, const double & x); + static double from_gco(obj mm, obj gco); + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end GCObjectConversion_DFloat.hpp */ diff --git a/xo-object2/src/object2/CMakeLists.txt b/xo-object2/src/object2/CMakeLists.txt index 430e50c2..2902a4ee 100644 --- a/xo-object2/src/object2/CMakeLists.txt +++ b/xo-object2/src/object2/CMakeLists.txt @@ -2,6 +2,10 @@ set(SELF_LIB xo_object2) set(SELF_SRCS + init_object2.cpp + object2_register_types.cpp + object2_register_facets.cpp + GCObjectConversion_DFloat.cpp IGCObject_DArray.cpp IGCObject_DFloat.cpp IGCObject_DBoolean.cpp @@ -22,13 +26,11 @@ set(SELF_SRCS DInteger.cpp DBoolean.cpp DString.cpp - init_object2.cpp - object2_register_types.cpp - object2_register_facets.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) # note: deps here must also appear in cmake/xo_object2Config.cmake.in +xo_dependency(${SELF_LIB} reflect) xo_dependency(${SELF_LIB} xo_gc) xo_dependency(${SELF_LIB} xo_printable2) xo_dependency(${SELF_LIB} subsys) diff --git a/xo-object2/src/object2/GCObjectConversion_DFloat.cpp b/xo-object2/src/object2/GCObjectConversion_DFloat.cpp new file mode 100644 index 00000000..a99c68ce --- /dev/null +++ b/xo-object2/src/object2/GCObjectConversion_DFloat.cpp @@ -0,0 +1,41 @@ +/** @file GCObjectConversion_DFloat.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "number/GCObjectConversion_DFloat.hpp" +#include + +namespace xo { + using xo::mm::AGCObject; + + namespace scm { + + obj + GCObjectConversion::to_gco(obj mm, + const double & x) + { + return DFloat::box(mm, x); + } + + double + GCObjectConversion::from_gco(obj mm, + obj gco) + { + (void)mm; + + auto float_obj = obj::from(gco); + + if (!float_obj) { + throw std::runtime_error + (tostr("Object obj found where Float expected", + xtag("obj", gco))); + } + + return float_obj.data()->value(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end GCObjectConversion_DFloat.cpp */ From 1e55926915a827293810067ad2c30535f5c916b2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:14:00 -0500 Subject: [PATCH 070/258] xo-object2: add DFloat conversion header in gen .hpp --- xo-object2/idl/IGCObject_DFloat.json5 | 1 + 1 file changed, 1 insertion(+) diff --git a/xo-object2/idl/IGCObject_DFloat.json5 b/xo-object2/idl/IGCObject_DFloat.json5 index 6120808b..9aba2a34 100644 --- a/xo-object2/idl/IGCObject_DFloat.json5 +++ b/xo-object2/idl/IGCObject_DFloat.json5 @@ -1,6 +1,7 @@ { mode: "implementation", includes: [ + "", "", "" ], From 706eb3008107403b37843cecd74cfd3f5ed635ce Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:14:39 -0500 Subject: [PATCH 071/258] xo-gc: needs explicit xo_facet dep --- xo-gc/cmake/xo_gcConfig.cmake.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xo-gc/cmake/xo_gcConfig.cmake.in b/xo-gc/cmake/xo_gcConfig.cmake.in index c32a8368..aebd133c 100644 --- a/xo-gc/cmake/xo_gcConfig.cmake.in +++ b/xo-gc/cmake/xo_gcConfig.cmake.in @@ -1,7 +1,9 @@ @PACKAGE_INIT@ include(CMakeFindDependencyMacro) -#find_dependency(indentlog) find_dependency(xo_alloc2) +find_dependency(xo_facet) +find_dependency(indentlog) + include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") check_required_components("@PROJECT_NAME@") From 1d1024d95b518df7343c8d62e37a980db8ce8a94 Mon Sep 17 00:00:00 2001 From: Roland Date: Sun, 25 Jan 2026 10:26:22 -0500 Subject: [PATCH 072/258] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..c47415a1 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# xo-procedure2 +gc-aware function interface for Schematika From e35c85def0ac81f91b3a320f9d347d50bb0a8b8d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:31:06 -0500 Subject: [PATCH 073/258] xo-procedure2: procedure abstraction for Schematika --- xo-procedure2/CMakeLists.txt | 41 ++++++++ xo-procedure2/cmake/xo-bootstrap-macros.cmake | 41 ++++++++ .../cmake/xo_procedure2Config.cmake.in | 13 +++ xo-procedure2/idl/Procedure.json5 | 58 +++++++++++ xo-procedure2/include/xo/procedure2/.gitkeep | 0 .../include/xo/procedure2/DPrimitive.hpp | 94 ++++++++++++++++++ .../include/xo/procedure2/Procedure.hpp | 22 +++++ .../xo/procedure2/detail/AProcedure.hpp | 77 +++++++++++++++ .../xo/procedure2/detail/IProcedure_Any.hpp | 88 +++++++++++++++++ .../xo/procedure2/detail/IProcedure_Xfer.hpp | 86 +++++++++++++++++ .../xo/procedure2/detail/RProcedure.hpp | 86 +++++++++++++++++ .../include/xo/procedure2/init_primitives.hpp | 29 ++++++ .../include/xo/procedure2/init_procedure2.hpp | 21 ++++ .../include/xo/procedure2/primitives.hpp | 13 +++ xo-procedure2/src/procedure2/CMakeLists.txt | 26 +++++ xo-procedure2/src/procedure2/DPrimitive.cpp | 16 ++++ .../src/procedure2/IProcedure_Any.cpp | 47 +++++++++ .../src/procedure2/init_primitives.cpp | 95 +++++++++++++++++++ .../src/procedure2/init_procedure2.cpp | 32 +++++++ 19 files changed, 885 insertions(+) create mode 100644 xo-procedure2/CMakeLists.txt create mode 100644 xo-procedure2/cmake/xo-bootstrap-macros.cmake create mode 100644 xo-procedure2/cmake/xo_procedure2Config.cmake.in create mode 100644 xo-procedure2/idl/Procedure.json5 create mode 100644 xo-procedure2/include/xo/procedure2/.gitkeep create mode 100644 xo-procedure2/include/xo/procedure2/DPrimitive.hpp create mode 100644 xo-procedure2/include/xo/procedure2/Procedure.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp create mode 100644 xo-procedure2/include/xo/procedure2/init_primitives.hpp create mode 100644 xo-procedure2/include/xo/procedure2/init_procedure2.hpp create mode 100644 xo-procedure2/include/xo/procedure2/primitives.hpp create mode 100644 xo-procedure2/src/procedure2/CMakeLists.txt create mode 100644 xo-procedure2/src/procedure2/DPrimitive.cpp create mode 100644 xo-procedure2/src/procedure2/IProcedure_Any.cpp create mode 100644 xo-procedure2/src/procedure2/init_primitives.cpp create mode 100644 xo-procedure2/src/procedure2/init_procedure2.cpp diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt new file mode 100644 index 00000000..8d00f310 --- /dev/null +++ b/xo-procedure2/CMakeLists.txt @@ -0,0 +1,41 @@ +# xo-procedure2/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +project(xo_procedure2 VERSION 1.0) +enable_language(CXX) + +include(GNUInstallDirs) +include(cmake/xo-bootstrap-macros.cmake) + +xo_cxx_toplevel_options3() + +# ---------------------------------------------------------------- +# c++ settings + +# one-time project-specific c++ flags. usually empty +set(PROJECT_CXX_FLAGS "") +add_definitions(${PROJECT_CXX_FLAGS}) + +# ---------------------------------------------------------------- +# output targets + +# note: manual target; generated code committed to git +xo_add_genfacet( + TARGET xo-procedure2-facet-procedure + FACET Procedure + INPUT idl/Procedure.json5 + OUTPUT_HPP_DIR include/xo/procedure2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/procedure2 + ) + +add_subdirectory(src/procedure2) +#add_subdirectory(utest) + +# ---------------------------------------------------------------- +# cmake export + +#xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +# end CMakeLists.txt diff --git a/xo-procedure2/cmake/xo-bootstrap-macros.cmake b/xo-procedure2/cmake/xo-bootstrap-macros.cmake new file mode 100644 index 00000000..592272c0 --- /dev/null +++ b/xo-procedure2/cmake/xo-bootstrap-macros.cmake @@ -0,0 +1,41 @@ +# ---------------------------------------------------------------- +# for example: +# $ PREFIX=/usr/local # for example +# $ cmake -DCMAKE_MODULE_PATH=prefix -DCMAKE_INSTALL_PREFIX=$PREFIX -B .build +# +# will get +# CMAKE_MODULE_PATH +# from xo-cmake-config --cmake-module-path +# +# and expect .cmake macros in +# CMAKE_MODULE_PATH/xo_macros/xo_cxx.cmake +# ---------------------------------------------------------------- + +find_program(XO_CMAKE_CONFIG_EXECUTABLE NAMES xo-cmake-config REQUIRED) + +if ("${XO_CMAKE_CONFIG_EXECUTABLE}" STREQUAL "XO_CMAKE_CONFIG_EXECUTABLE-NOT_FOUND") + message(FATAL "could not find xo-cmake-config executable") +endif() + +message(STATUS "XO_CMAKE_CONFIG_EXECUTABLE=${XO_CMAKE_CONFIG_EXECUTABLE}") + +if (XO_SUBMODULE_BUILD) + if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) + # local version of xo-cmake macros + set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/xo-cmake/cmake") + message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") + endif() +else() + if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) + # default to typical install location for xo-project-macros + execute_process(COMMAND ${XO_CMAKE_CONFIG_EXECUTABLE} --cmake-module-path OUTPUT_VARIABLE CMAKE_MODULE_PATH) + message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") + endif() +endif() + +# needs to have been installed somewhere on CMAKE_MODULE_PATH, +# (e.g. from xo-cmake with the same value for CMAKE_INSTALL_PREFIX) +# +include(xo_macros/xo_cxx) + +xo_cxx_bootstrap_message() diff --git a/xo-procedure2/cmake/xo_procedure2Config.cmake.in b/xo-procedure2/cmake/xo_procedure2Config.cmake.in new file mode 100644 index 00000000..0229c033 --- /dev/null +++ b/xo-procedure2/cmake/xo_procedure2Config.cmake.in @@ -0,0 +1,13 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +# note: changes to find_dependency() calls here +# must coordinate with xo_dependency() calls +# in CMakeLists.txt +# +find_dependency(xo_gc) +find_dependency(subsys) + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/xo-procedure2/idl/Procedure.json5 b/xo-procedure2/idl/Procedure.json5 new file mode 100644 index 00000000..fb43f310 --- /dev/null +++ b/xo-procedure2/idl/Procedure.json5 @@ -0,0 +1,58 @@ +{ + mode: "facet", + // includes in ASyntaxStateMachine.hpp + includes: [ + ], + // extra includes in SyntaxStateMachine.hpp, if any + user_hpp_includes: [ + ], + namespace1: "xo", + namespace2: "scm", + // text after includes, before ASyntaxStateMachine + pretext: [ "// {pretex} here" ], + facet: "Procedure", + detail_subdir: "detail", + brief: "abstraction for a schematika procedure i.e. something callable", + using_doxygen: true, + doc: [ + "Abstraction for a schematika procedure" + ], + types: [ + { name: "AGCObject", + definition: "xo::mm::AGCObject", + doc: [ "a gc-aware object" ], + }, + // { name: string, doc: [ string ], definition: string }, + ], + const_methods: [ + { + name: "is_nary", + doc: [ "true iff procedure takes n arguments" ], + return_type: "bool", + args: [], + const: true, + noexcept: true, + attributes: [] + }, + { + name: "n_args", + doc: ["number of arguments. -1 for n-ary" ], + return_type: "std::int32_t", + args: [], + const: true, + noexcept: true, + attributes: [] + } + ], + nonconst_methods: [ + { + name: "apply_nocheck", + doc: ["invoke procedure; assume arguments satisfy type system" ], + return_type: "obj", + args: [ + {type: "obj", name: "mm"}, + {type: "const DArray *", name: "args"}, + ] + } + ], +} diff --git a/xo-procedure2/include/xo/procedure2/.gitkeep b/xo-procedure2/include/xo/procedure2/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp new file mode 100644 index 00000000..5e5f996c --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp @@ -0,0 +1,94 @@ +/** @file DPrimitive.hpp + * + * @author Roland Conybeare, Jan 2025 + **/ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace xo { + namespace scm { + /** @brief Extract return type and argument types from a function type. + * + * Primary template (undefined) - specializations handle specific cases + **/ + template + struct FnTraits; + + /** specialization for function pointers **/ + template + struct FnTraits { + /** function return type **/ + using return_type = R; + /** tuple type for function arguments **/ + using args_tuple = std::tuple; + /** number of arguments **/ + static constexpr std::size_t n_args = sizeof...(Args); + + /** arg_type is the type of the i'th argument to Fn **/ + template + using arg_type = std::tuple_element_t; + }; + + /** specialization for function references **/ + template + struct FnTraits : FnTraits {}; + + /** specialization for plain function types **/ + template + struct FnTraits : FnTraits {}; + + template + class Primitive { + public: + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using DArray = xo::scm::DArray; + using Traits = FnTraits; + + public: + Primitive(std::string_view name, Fn fn) : name_{name}, fn_{fn} {} + + bool is_nary() const noexcept { return false; } + static constexpr std::int32_t n_args() noexcept { return Traits::n_args; } + + obj apply_nocheck(obj mm, const DArray * args) { + return _apply_nocheck(mm, args, + std::make_index_sequence{}); + } + + private: + template + obj _apply_nocheck(obj mm, + const DArray * args, + std::index_sequence) + { + using R = typename Traits::return_type; + + R result + = fn_(GCObjectConversion>::from_gco(mm, args->at(Is))... + ); + + return GCObjectConversion::to_gco(mm, result); + } + + private: + /** name of this primitive **/ + std::string_view name_; + /** function implementation **/ + Fn fn_; + }; /*Primitive*/ + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DPrimitive.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/Procedure.hpp b/xo-procedure2/include/xo/procedure2/Procedure.hpp new file mode 100644 index 00000000..8b2cd91a --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/Procedure.hpp @@ -0,0 +1,22 @@ +/** @file Procedure.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Procedure.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/Procedure.json5] + **/ + +#pragma once + +#include "detail/AProcedure.hpp" +#include "detail/IProcedure_Any.hpp" +#include "detail/IProcedure_Xfer.hpp" +#include "detail/RProcedure.hpp" + + +/* end Procedure.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp new file mode 100644 index 00000000..c0b22f49 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp @@ -0,0 +1,77 @@ +/** @file AProcedure.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Procedure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/Procedure.json5] + **/ + +#pragma once + +// includes (via {facet_includes}) +#include +#include +#include + +// {pretex} here + +namespace xo { +namespace scm { + +using Copaque = const void *; +using Opaque = void *; + +/** +Abstraction for a schematika procedure +**/ +class AProcedure { +public: + /** @defgroup scm-procedure-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; + /** a gc-aware object **/ + using AGCObject = xo::mm::AGCObject; + ///@} + + /** @defgroup scm-procedure-methods **/ + ///@{ + // const methods + /** RTTI: unique id# for actual runtime data representation **/ + virtual typeseq _typeseq() const noexcept = 0; + /** true iff procedure takes n arguments **/ + virtual bool is_nary(Copaque data) const noexcept = 0; + /** number of arguments. -1 for n-ary **/ + virtual std::int32_t n_args(Copaque data) const noexcept = 0; + + // nonconst methods + /** invoke procedure; assume arguments satisfy type system **/ + virtual obj apply_nocheck(Opaque data, obj mm, const DArray * args) = 0; + ///@} +}; /*AProcedure*/ + +/** Implementation IProcedure_DRepr of AProcedure for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = IProcedure_DRepr; + * }; + * + * then IProcedure_ImplType --> IProcedure_DRepr + **/ +template +using IProcedure_ImplType = xo::facet::FacetImplType; + +} /*namespace scm*/ +} /*namespace xo*/ + +/* AProcedure.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp new file mode 100644 index 00000000..c1b8c9d6 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp @@ -0,0 +1,88 @@ +/** @file IProcedure_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Procedure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Procedure.json5] + **/ + +#pragma once + +#include "AProcedure.hpp" +#include + +namespace xo { namespace scm { class IProcedure_Any; } } + +namespace xo { +namespace facet { + +template <> +struct FacetImplementation +{ + using ImplType = xo::scm::IProcedure_Any; +}; + +} +} + +namespace xo { +namespace scm { + + /** @class IProcedure_Any + * @brief AProcedure implementation for empty variant instance + **/ + class IProcedure_Any : public AProcedure { + public: + /** @defgroup scm-procedure-any-type-traits **/ + ///@{ + + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using AGCObject = AProcedure::AGCObject; + + ///@} + /** @defgroup scm-procedure-any-methods **/ + ///@{ + + const AProcedure * iface() const { return std::launder(this); } + + // from AProcedure + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] bool is_nary(Copaque) const noexcept override { _fatal(); } + [[noreturn]] std::int32_t n_args(Copaque) const noexcept override { _fatal(); } + + // nonconst methods + [[noreturn]] obj apply_nocheck(Opaque, obj, const DArray *) override; + + ///@} + + private: + /** @defgraoup scm-procedure-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup scm-procedure-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace scm */ +} /*namespace xo */ + +/* IProcedure_Any.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp new file mode 100644 index 00000000..dfe8a558 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp @@ -0,0 +1,86 @@ +/** @file IProcedure_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Procedure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Procedure.json5] + **/ + +#pragma once + + +namespace xo { +namespace scm { + /** @class IProcedure_Xfer + **/ + template + class IProcedure_Xfer : public AProcedure { + public: + /** @defgroup scm-procedure-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = IProcedure_DRepr; + /** integer identifying a type **/ + using typeseq = AProcedure::typeseq; + using AGCObject = AProcedure::AGCObject; + ///@} + + /** @defgroup scm-procedure-xfer-methods **/ + ///@{ + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + + // from AProcedure + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + bool is_nary(Copaque data) const noexcept override { + return I::is_nary(_dcast(data)); + } + std::int32_t n_args(Copaque data) const noexcept override { + return I::n_args(_dcast(data)); + } + + // non-const methods + obj apply_nocheck(Opaque data, obj mm, const DArray * args) override { + return I::apply_nocheck(_dcast(data), mm, args); + } + + ///@} + + private: + using I = Impl; + + public: + /** @defgroup scm-procedure-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + xo::facet::typeseq + IProcedure_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + IProcedure_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace scm */ +} /*namespace xo*/ + +/* end IProcedure_Xfer.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp new file mode 100644 index 00000000..dc0f30d8 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp @@ -0,0 +1,86 @@ +/** @file RProcedure.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Procedure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Procedure.json5] + **/ + +#pragma once + +#include "AProcedure.hpp" + +namespace xo { +namespace scm { + +/** @class RProcedure + **/ +template +class RProcedure : public Object { +private: + using O = Object; + +public: + /** @defgroup scm-procedure-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; + using AGCObject = AProcedure::AGCObject; + ///@} + + /** @defgroup scm-procedure-router-ctors **/ + ///@{ + RProcedure() {} + RProcedure(Object::DataPtr data) : Object{std::move(data)} {} + RProcedure(const AProcedure * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} + + ///@} + /** @defgroup scm-procedure-router-methods **/ + ///@{ + + // const methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + bool is_nary() const noexcept { + return O::iface()->is_nary(O::data()); + } + std::int32_t n_args() const noexcept { + return O::iface()->n_args(O::data()); + } + + // non-const methods (still const in router!) + obj apply_nocheck(obj mm, const DArray * args) { + return O::iface()->apply_nocheck(O::data(), mm, args); + } + + ///@} + /** @defgroup scm-procedure-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RProcedure::_valid = xo::facet::valid_object_router(); + +} /*namespace scm*/ +} /*namespace xo*/ + +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::scm::RProcedure; + }; +} } + +/* end RProcedure.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/init_primitives.hpp b/xo-procedure2/include/xo/procedure2/init_primitives.hpp new file mode 100644 index 00000000..d4150d2d --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/init_primitives.hpp @@ -0,0 +1,29 @@ +/** @file init_primitives.hpp **/ + +#pragma once + +#include "DPrimitive.hpp" + +namespace xo { + namespace scm { + using Primitive_f64_1_f64 = Primitive; + using Primitive_f64_2_f64_f64 = Primitive; + + struct Primitives { + static Primitive_f64_1_f64 s_neg_f64_pm; + + static Primitive_f64_2_f64_f64 s_add_f64_f64_pm; + static Primitive_f64_2_f64_f64 s_sub_f64_f64_pm; + static Primitive_f64_2_f64_f64 s_mul_f64_f64_pm; + static Primitive_f64_2_f64_f64 s_div_f64_f64_pm; + static Primitive_f64_2_f64_f64 s_pow_f64_f64_pm; + + static Primitive_f64_1_f64 s_log_f64_pm; + static Primitive_f64_1_f64 s_sin_f64_pm; + static Primitive_f64_1_f64 s_cos_f64_pm; + static Primitive_f64_1_f64 s_tan_f64_pm; + }; + } +} + +/* end init_primitives.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/init_procedure2.hpp b/xo-procedure2/include/xo/procedure2/init_procedure2.hpp new file mode 100644 index 00000000..793cc061 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/init_procedure2.hpp @@ -0,0 +1,21 @@ +/** @file init_procedure2.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + /* tag to represent the xo-procedure2/ subsystem within ordered iniitalization */ + enum S_procedure2_tag {}; + + template <> + struct InitSubsys { + static void init(); + static InitEvidence require(); + }; +} /*namespace xo*/ + +/* end init_procedure2.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/primitives.hpp b/xo-procedure2/include/xo/procedure2/primitives.hpp new file mode 100644 index 00000000..e2e0d88a --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/primitives.hpp @@ -0,0 +1,13 @@ +/** @file primitives.hpp **/ + +#pragma once + +namespace xo { + namespace scm { + struct Primitives { + static void init_primitives(); + }; + } +} + +/* end primitives.hpp */ diff --git a/xo-procedure2/src/procedure2/CMakeLists.txt b/xo-procedure2/src/procedure2/CMakeLists.txt new file mode 100644 index 00000000..edc5d3ce --- /dev/null +++ b/xo-procedure2/src/procedure2/CMakeLists.txt @@ -0,0 +1,26 @@ +# xo-procedure2/src/CMakeLists.txt + +set(SELF_LIB xo_procedure2) +set(SELF_SRCS + init_procedure2.cpp + init_primitives.cpp + DPrimitive.cpp + # Add source files here, e.g.: + # procedure2.cpp +) + +xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) +xo_install_include_tree3(include/xo/procedure2) + +# ---------------------------------------------------------------- +# input dependencies +# +# NOTE: dependency set here must be kept consistent with +# xo-procedure2/cmake/xo_procedure2Config.cmake.in + +xo_dependency(${SELF_LIB} xo_object2) +xo_dependency(${SELF_LIB} xo_gc) +xo_dependency(${SELF_LIB} subsys) +#xo_dependency(${SELF_LIB} xo_indentlog) + +# end src/CMakeLists.txt diff --git a/xo-procedure2/src/procedure2/DPrimitive.cpp b/xo-procedure2/src/procedure2/DPrimitive.cpp new file mode 100644 index 00000000..ab335d8d --- /dev/null +++ b/xo-procedure2/src/procedure2/DPrimitive.cpp @@ -0,0 +1,16 @@ +/** @file DPrimitive.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DPrimitive.hpp" +#include + +namespace xo { + namespace scm { + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DPrimitive.cpp */ diff --git a/xo-procedure2/src/procedure2/IProcedure_Any.cpp b/xo-procedure2/src/procedure2/IProcedure_Any.cpp new file mode 100644 index 00000000..3044c104 --- /dev/null +++ b/xo-procedure2/src/procedure2/IProcedure_Any.cpp @@ -0,0 +1,47 @@ +/** @file IProcedure_Any.cpp + * + **/ + +#include "detail/IProcedure_Any.hpp" +#include + +namespace xo { +namespace scm { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +IProcedure_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " IProcedure_Any method" + << std::endl; + std::terminate(); +} + +typeseq +IProcedure_Any::s_typeseq = typeseq::id(); + +bool +IProcedure_Any::_valid + = valid_facet_implementation(); + +// nonconst methods + +auto +IProcedure_Any::apply_nocheck(Opaque, obj, const DArray *) -> obj +{ + _fatal(); +} + + +} /*namespace scm*/ +} /*namespace xo*/ + +/* end IProcedure_Any.cpp */ \ No newline at end of file diff --git a/xo-procedure2/src/procedure2/init_primitives.cpp b/xo-procedure2/src/procedure2/init_primitives.cpp new file mode 100644 index 00000000..169b660e --- /dev/null +++ b/xo-procedure2/src/procedure2/init_primitives.cpp @@ -0,0 +1,95 @@ +/** @file init_primitives.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_primitives.hpp" +#include "DPrimitive.hpp" + +namespace xo { + namespace scm { + double + neg_f64(double x) { + return -x; + } + + double + add_f64_f64(double x, double y) { + return x + y; + } + + double + sub_f64_f64(double x, double y) { + return x - y; + } + + double + mul_f64_f64(double x, double y) { + return x * y; + } + + double + div_f64_f64(double x, double y) { + return x / y; + } + + double + pow_f64_f64(double x, double y) { + return ::pow(x, y); + } + + double + log_f64(double x) { + return ::log(x); + } + + double + sin_f64(double x) { + return ::sin(x); + } + + double + cos_f64(double x) { + return ::cos(x); + } + + double + tan_f64(double x) { + return ::tan(x); + } + + Primitive_f64_1_f64 + Primitives::s_neg_f64_pm("_neg_d", + &neg_f64); + + Primitive_f64_2_f64_f64 + Primitives::s_add_f64_f64_pm("_add_d_d", &add_f64_f64); + + Primitive_f64_2_f64_f64 + Primitives::s_sub_f64_f64_pm("_sub_d_d", &sub_f64_f64); + + Primitive_f64_2_f64_f64 + Primitives::s_mul_f64_f64_pm("_mul_d_d", &mul_f64_f64); + + Primitive_f64_2_f64_f64 + Primitives::s_div_f64_f64_pm("_div_d_d", &div_f64_f64); + + Primitive_f64_2_f64_f64 + Primitives::s_pow_f64_f64_pm("_pow_d_d", &pow_f64_f64); + + Primitive_f64_1_f64 + Primitives::s_log_f64_pm("_log_d", &log_f64); + + Primitive_f64_1_f64 + Primitives::s_sin_f64_pm("_sin_d", &sin_f64); + + Primitive_f64_1_f64 + Primitives::s_cos_f64_pm("_cos_d", &cos_f64); + + Primitive_f64_1_f64 + Primitives::s_tan_f64_pm("_tan_d", &tan_f64); + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end init_primitives.cpp */ diff --git a/xo-procedure2/src/procedure2/init_procedure2.cpp b/xo-procedure2/src/procedure2/init_procedure2.cpp new file mode 100644 index 00000000..fc316653 --- /dev/null +++ b/xo-procedure2/src/procedure2/init_procedure2.cpp @@ -0,0 +1,32 @@ +/** @file init_procedure2.cpp + * + * @author Roland Conybeare, Jan 2026 +**/ + +#include "init_procedure2.hpp" +#include "init_primitives.hpp" +//#include "procedure2_register_facets.hpp" +//#include "procedure2_register_types.hpp" +#include + +namespace xo { + using xo::scm::Primitives; + + void + InitSubsys::init() + { + } + + InitEvidence + InitSubsys::require() + { + InitEvidence retval; + + /* xo-procedure2/'s own initialization code */ + retval ^= Subsystem::provide("procedure2", &init); + + return retval; + } +} /*namespace xo*/ + +/* end init_procedure2.cpp */ From 8b63fbaaa2ba2f2b994c3d3e54dd9e9c19b1f445 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 10:47:28 -0500 Subject: [PATCH 074/258] xo-reader2: bugfix: prior refactor requires switch remodel on_token --- xo-reader2/src/reader2/DDefineSsm.cpp | 29 ++++++++++----------- xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 6 ++--- xo-reader2/src/reader2/DExpectTypeSsm.cpp | 7 +++-- xo-reader2/src/reader2/DExprSeqState.cpp | 20 +++++++------- xo-reader2/src/reader2/DProgressSsm.cpp | 23 +++++++++------- 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index b8c5b0ae..0cd488e5 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -500,43 +500,43 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_symbol: this->on_symbol_token(tk, p_psm); - break; + return; case tokentype::tk_def: this->on_def_token(tk, p_psm); - break; + return; case tokentype::tk_if: this->on_if_token(tk, p_psm); - break; + return; case tokentype::tk_colon: this->on_colon_token(tk, p_psm); - break; + return; case tokentype::tk_singleassign: this->on_singleassign_token(tk, p_psm); - break; + return; case tokentype::tk_string: this->on_string_token(tk, p_psm); - break; + return; case tokentype::tk_f64: this->on_f64_token(tk, p_psm); - break; + return; case tokentype::tk_i64: this->on_i64_token(tk, p_psm); - break; + return; case tokentype::tk_bool: this->on_bool_token(tk, p_psm); - break; + return; case tokentype::tk_semicolon: this->on_semicolon_token(tk, p_psm); - break; + return; // all the not-yet handled cases case tokentype::tk_invalid: @@ -569,12 +569,11 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: case tokentype::N: - break; + p_psm->illegal_input_on_token("DDefineSsm::on_token", + tk, + this->get_expect_str()); + return; } - - p_psm->illegal_input_on_token("DDefineSsm::on_token", - tk, - this->get_expect_str()); } void diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index cbfb1c91..c10678f2 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -170,12 +170,12 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: case tokentype::N: + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_token", + tk, + this->get_expect_str()); break; } - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_token", - tk, - this->get_expect_str()); } void diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 2feaee26..d99ff817 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -134,12 +134,11 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: case tokentype::N: + p_psm->illegal_input_on_token("DExpectTypeSsm::on_token", + tk, + this->get_expect_str()); break; } - - p_psm->illegal_input_on_token("DExpectTypeSsm::on_token", - tk, - this->get_expect_str()); } void diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 9691d665..d6037908 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -114,43 +114,43 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_symbol: this->on_symbol_token(tk, p_psm); - break; + return; case tokentype::tk_def: this->on_def_token(tk, p_psm); - break; + return; case tokentype::tk_if: this->on_if_token(tk, p_psm); - break; + return; case tokentype::tk_colon: this->on_colon_token(tk, p_psm); - break; + return; case tokentype::tk_singleassign: this->on_singleassign_token(tk, p_psm); - break; + return; case tokentype::tk_string: this->on_string_token(tk, p_psm); - break; + return; case tokentype::tk_f64: this->on_f64_token(tk, p_psm); - break; + return; case tokentype::tk_i64: this->on_i64_token(tk, p_psm); - break; + return; case tokentype::tk_bool: this->on_bool_token(tk, p_psm); - break; + return; case tokentype::tk_semicolon: this->on_semicolon_token(tk, p_psm); - break; + return; // all the not-yet handled cases case tokentype::tk_invalid: diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index a40b6f59..f501d5fe 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -167,43 +167,43 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_symbol: this->on_symbol_token(tk, p_psm); - break; + return; case tokentype::tk_def: this->on_def_token(tk, p_psm); - break; + return; case tokentype::tk_if: this->on_if_token(tk, p_psm); - break; + return; case tokentype::tk_colon: this->on_colon_token(tk, p_psm); - break; + return; case tokentype::tk_singleassign: this->on_singleassign_token(tk, p_psm); - break; + return; case tokentype::tk_string: this->on_string_token(tk, p_psm); - break; + return; case tokentype::tk_f64: this->on_f64_token(tk, p_psm); - break; + return; case tokentype::tk_i64: this->on_i64_token(tk, p_psm); - break; + return; case tokentype::tk_bool: this->on_bool_token(tk, p_psm); - break; + return; case tokentype::tk_semicolon: this->on_semicolon_token(tk, p_psm); - break; + return; // all the not-yet handled cases case tokentype::tk_invalid: @@ -224,7 +224,10 @@ namespace xo { case tokentype::tk_yields: case tokentype::tk_plus: case tokentype::tk_minus: + break; case tokentype::tk_star: + this->on_operator_token(tk, p_psm); + return; case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: From c0978f5098525e2d4c7ca1846d57f2ce464b15d1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 13:14:26 -0500 Subject: [PATCH 075/258] xo-expression2: + DApplyExpr [WIP]. Builds, not used or tested --- .../include/xo/expression2/DApplyExpr.hpp | 64 +++++++++++++ .../include/xo/expression2/DVariable.hpp | 2 +- .../include/xo/expression2/exprtype.hpp | 4 + xo-expression2/src/expression2/CMakeLists.txt | 1 + xo-expression2/src/expression2/DApplyExpr.cpp | 95 +++++++++++++++++++ .../interpreter2/VirtualSchematikaMachine.hpp | 6 ++ .../interpreter2/VirtualSchematikaMachine.cpp | 10 ++ 7 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 xo-expression2/include/xo/expression2/DApplyExpr.hpp create mode 100644 xo-expression2/src/expression2/DApplyExpr.cpp diff --git a/xo-expression2/include/xo/expression2/DApplyExpr.hpp b/xo-expression2/include/xo/expression2/DApplyExpr.hpp new file mode 100644 index 00000000..882cf5cd --- /dev/null +++ b/xo-expression2/include/xo/expression2/DApplyExpr.hpp @@ -0,0 +1,64 @@ +/** @file DApplyExpr.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Expression.hpp" +#include "TypeRef.hpp" +#include "exprtype.hpp" +#include +#include +#include + +namespace xo { + namespace scm { + + /** @class DApplyExpr + * @brief syntax for a procedure/function call + **/ + class DApplyExpr { + public: + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::size_t; + + public: + + obj fn() const noexcept { return fn_; } + const DArray * args() const noexcept { return args_; } + + size_type n_arg() const noexcept { return args_->size(); } + obj arg(size_type i) const; + + /** @defgroup scm-applyexpr-expression-facet **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::apply; } + TypeRef typeref() const noexcept { return typeref_; } + TypeDescr valuetype() const noexcept { return typeref_.td(); } + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + /** @defgroup scm-applyexpr-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** expression value always has type consistent + * with this description + **/ + TypeRef typeref_; + /** expression for function/procedure to invoke **/ + obj fn_; + /** expression for each argument vector **/ + const DArray * args_; + }; + } +} + +/* end DApplyExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/DVariable.hpp b/xo-expression2/include/xo/expression2/DVariable.hpp index ae362bf1..af2eddd5 100644 --- a/xo-expression2/include/xo/expression2/DVariable.hpp +++ b/xo-expression2/include/xo/expression2/DVariable.hpp @@ -15,7 +15,7 @@ namespace xo { namespace scm { - /** @class DVariable* + /** @class DVariable * @brief syntax for a variable reference **/ class DVariable { diff --git a/xo-expression2/include/xo/expression2/exprtype.hpp b/xo-expression2/include/xo/expression2/exprtype.hpp index d64a1191..df4e3be6 100644 --- a/xo-expression2/include/xo/expression2/exprtype.hpp +++ b/xo-expression2/include/xo/expression2/exprtype.hpp @@ -29,8 +29,10 @@ namespace xo { #ifdef NOT_YET /** variable assignment **/ assign, +#endif /** function call **/ apply, +#ifdef NOT_YET /** function definition **/ lambda, #endif @@ -61,7 +63,9 @@ namespace xo { case exprtype::define: return "define"; #ifdef NOT_YET case exprtype::assign: return "assign"; +#endif case exprtype::apply: return "apply"; +#ifdef NOT_YET case exprtype::lambda: return "lambda"; case exprtype::variable: return "variable"; case exprtype::ifexpr: return "if_expr"; diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 17c34275..9dea6457 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -7,6 +7,7 @@ set(SELF_SRCS DConstant.cpp DVariable.cpp DDefineExpr.cpp + DApplyExpr.cpp TypeRef.cpp diff --git a/xo-expression2/src/expression2/DApplyExpr.cpp b/xo-expression2/src/expression2/DApplyExpr.cpp new file mode 100644 index 00000000..0c0546f3 --- /dev/null +++ b/xo-expression2/src/expression2/DApplyExpr.cpp @@ -0,0 +1,95 @@ +/** @file DApplyExpr.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DApplyExpr.hpp" +#include "Expression.hpp" +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::mm::AGCObject; + + namespace scm { + obj + DApplyExpr::arg(size_type i) const + { + if (i >= args_->size()) [[unlikely]] { + throw std::runtime_error(tostr("attempt to fetch argument i where [0..n) expected", + xtag("i", i), + xtag("n", args_->size()), + xtag("src", "DApplyExpr::arg"))); + } + + obj arg_i = args_->at(i); + + auto expr_i = FacetRegistry::instance().variant(arg_i); + + if (!expr_i) [[unlikely]] { + throw std::runtime_error(tostr("expected expression interface on argument i", + xtag("i", i), + xtag("arg[i]", arg_i))); + } + + return expr_i; + } + + void + DApplyExpr::assign_valuetype(TypeDescr td) noexcept { + typeref_.resolve(td); + } + + bool + DApplyExpr::pretty(const ppindentinfo & ppii) const { + using xo::print::ppstate; + + ppstate * pps = ppii.pps(); + + if (ppii.upto()) { + /* perhaps print on one line */ + if (!pps->print_upto(" fn + = FacetRegistry::instance().variant(fn_); + if (!pps->print_upto(refrtag("fn", fn))) + return false; + } + + for (size_t i_arg = 0, n_arg = this->n_arg(); i_arg < n_arg; ++i_arg) { + obj arg_i + = FacetRegistry::instance().variant(this->arg(i_arg)); + + if (!pps->print_upto(refrtag(concat("arg", 1+i_arg), arg_i))) + return false; + } + + return true; + } else { + pps->write(" fn + = FacetRegistry::instance().variant(fn_); + + pps->newline_indent(ppii.ci1()); + pps->pretty(refrtag("fn", fn)); + + for (size_t i_arg = 0, n_arg = this->n_arg(); i_arg < n_arg; ++i_arg) { + obj arg_i + = FacetRegistry::instance().variant(fn_); + + pps->newline_indent(ppii.ci1()); + pps->pretty(refrtag(concat("arg", 1+i_arg), arg_i)); + } + return false; + } + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DApplyExpr.cpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index a149173e..e8e58dbc 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -57,6 +57,12 @@ namespace xo { **/ void _do_eval_variable_op(); + /** evaluate an apply expression + * Require: + * - expression in @ref expr_ + **/ + void _do_eval_apply_op(); + private: /* * Some registers are preserved by evaluation: diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 4dccce34..b2789c26 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -51,6 +51,9 @@ namespace xo { case exprtype::variable: _do_eval_variable_op(); break; + case exprtype::apply: + _do_eval_apply_op(); + break; } } @@ -77,6 +80,13 @@ namespace xo { // not implemented assert(false); } + + void + VirtualSchematikaMachine::_do_eval_apply_op() + { + // not implemented + assert(false); + } } /*namespace scm*/ } /*namespace xo*/ From 65f50609f6a4e8dcadd3ec1735b3db57e440ce3d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 25 Jan 2026 19:07:23 -0500 Subject: [PATCH 076/258] xo-procedure2: work on Primitive.apply_nocheck() + ARuntimeContext [WIP] --- CMakeLists.txt | 1 + xo-procedure2/CMakeLists.txt | 27 ++++++ .../IProcedure_DPrimitive_gco_2_gco_gco.json5 | 17 ++++ xo-procedure2/idl/Procedure.json5 | 18 ++-- xo-procedure2/idl/RuntimeContext.json5 | 43 ++++++++++ .../include/xo/procedure2/DPrimitive.hpp | 15 ++-- .../procedure2/DPrimitive_gco_2_gco_gco.hpp | 15 ++++ .../include/xo/procedure2/Procedure.hpp | 2 +- .../include/xo/procedure2/RuntimeContext.hpp | 22 +++++ .../xo/procedure2/detail/AProcedure.hpp | 8 +- .../xo/procedure2/detail/ARuntimeContext.hpp | 73 ++++++++++++++++ .../xo/procedure2/detail/IProcedure_Any.hpp | 4 +- .../IProcedure_DPrimitive_gco_2_gco_gco.hpp | 67 +++++++++++++++ .../xo/procedure2/detail/IProcedure_Xfer.hpp | 8 +- .../procedure2/detail/IRuntimeContext_Any.hpp | 86 +++++++++++++++++++ .../detail/IRuntimeContext_Xfer.hpp | 81 +++++++++++++++++ .../xo/procedure2/detail/RProcedure.hpp | 6 +- .../xo/procedure2/detail/RRuntimeContext.hpp | 80 +++++++++++++++++ xo-procedure2/src/procedure2/CMakeLists.txt | 3 + .../src/procedure2/IProcedure_Any.cpp | 2 +- .../IProcedure_DPrimitive_gco_2_gco_gco.cpp | 39 +++++++++ .../src/procedure2/IRuntimeContext_Any.cpp | 41 +++++++++ .../src/procedure2/init_primitives.cpp | 35 ++++++++ 23 files changed, 668 insertions(+), 25 deletions(-) create mode 100644 xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 create mode 100644 xo-procedure2/idl/RuntimeContext.json5 create mode 100644 xo-procedure2/include/xo/procedure2/DPrimitive_gco_2_gco_gco.hpp create mode 100644 xo-procedure2/include/xo/procedure2/RuntimeContext.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp create mode 100644 xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp create mode 100644 xo-procedure2/src/procedure2/IRuntimeContext_Any.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 075c25e4..a0e0b1df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,7 @@ add_subdirectory(xo-object) add_subdirectory(xo-object2) # experiment w/ facet object model add_subdirectory(xo-ordinaltree) # +add_subdirectory(xo-procedure2) # schematika procedure abstraction + runtime context (fomo) add_subdirectory(xo-tokenizer2) # schematika tokenizer (fomo) add_subdirectory(xo-expression2) # schematika expressions (fomo) add_subdirectory(xo-reader2) # schematika expression parser (fomo) diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt index 8d00f310..acb0bad9 100644 --- a/xo-procedure2/CMakeLists.txt +++ b/xo-procedure2/CMakeLists.txt @@ -30,9 +30,36 @@ xo_add_genfacet( OUTPUT_CPP_DIR src/procedure2 ) +# note: manual target; generated code committed to git +xo_add_genfacet( + TARGET xo-procedure2-facet-runtimecontext + FACET RuntimeContext + INPUT idl/RuntimeContext.json5 + OUTPUT_HPP_DIR include/xo/procedure2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/procedure2 + ) + +# ---------------------------------------------------------------- + +xo_add_genfacetimpl( + TARGET xo-procedure2-facetimpl-procedure2-primitive_gco_2_gco_gco + FACET_PKG xo_procedure2 + FACET Procedure + REPR DPrimitive_gco_2_gco_gco + INPUT idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 + OUTPUT_HPP_DIR include/xo/procedure2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/procedure2 +) + add_subdirectory(src/procedure2) #add_subdirectory(utest) +# ---------------------------------------------------------------- + +xo_add_genfacet_all(xo-procedure2-genfacet-all) + # ---------------------------------------------------------------- # cmake export diff --git a/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 new file mode 100644 index 00000000..fb22bad5 --- /dev/null +++ b/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 @@ -0,0 +1,17 @@ +{ + mode: "implementation", + includes: [ + "", + "", + "", + "", + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Procedure.json5", + brief: "provide AProcedure interface for Primitive (gco x gco) -> gco", + using_doxygen: true, + repr: "DPrimitive_gco_2_gco_gco", + doc: [ "implement AProcedure for DPrimitive (gco x gco) -> gco" ], +} diff --git a/xo-procedure2/idl/Procedure.json5 b/xo-procedure2/idl/Procedure.json5 index fb43f310..f0eac6b5 100644 --- a/xo-procedure2/idl/Procedure.json5 +++ b/xo-procedure2/idl/Procedure.json5 @@ -2,14 +2,19 @@ mode: "facet", // includes in ASyntaxStateMachine.hpp includes: [ + "\"RuntimeContext.hpp\"", + "", ], - // extra includes in SyntaxStateMachine.hpp, if any + // extra includes in Procedure.hpp, if any user_hpp_includes: [ ], namespace1: "xo", namespace2: "scm", // text after includes, before ASyntaxStateMachine - pretext: [ "// {pretex} here" ], + pretext: [ + //"namespace xo { namespace scm { class ARuntimeContext; } }", + "namespace xo { namespace scm { class DArray; } }", + ], facet: "Procedure", detail_subdir: "detail", brief: "abstraction for a schematika procedure i.e. something callable", @@ -18,9 +23,10 @@ "Abstraction for a schematika procedure" ], types: [ - { name: "AGCObject", - definition: "xo::mm::AGCObject", - doc: [ "a gc-aware object" ], + { + name: "AGCObject", + definition: "xo::mm::AGCObject", + doc: [ "a gc-aware object" ], }, // { name: string, doc: [ string ], definition: string }, ], @@ -50,7 +56,7 @@ doc: ["invoke procedure; assume arguments satisfy type system" ], return_type: "obj", args: [ - {type: "obj", name: "mm"}, + {type: "obj", name: "rcx"}, {type: "const DArray *", name: "args"}, ] } diff --git a/xo-procedure2/idl/RuntimeContext.json5 b/xo-procedure2/idl/RuntimeContext.json5 new file mode 100644 index 00000000..8a1e125f --- /dev/null +++ b/xo-procedure2/idl/RuntimeContext.json5 @@ -0,0 +1,43 @@ +{ + mode: "facet", + // includes in ARuntimeContext.hpp + includes: [ + "" + ], + // extra includes in RuntimeContext.hpp, if any + user_hpp_includes: [ + ], + namespace1: "xo", + namespace2: "scm", + // text after includes, before ARuntimeContext + pretext: [ + //"namespace xo { namespace mm { class AAllocator; } }", + ], + facet: "RuntimeContext", + detail_subdir: "detail", + brief: "runtime context for application code. At minimum provides allocator", + using_doxygen: true, + doc: [ + "Runtime application context" + ], + types: [ + { + name: "AAllocator", + definition: "xo::mm::AAllocator", + doc: [ "xo memory allocator" ], + }, + ], + const_methods: [ + { + name: "allocator", + doc: [ "default allocator to use for objects" ], + return_type: "obj", + args: [], + const: true, + noexcept: true, + attributes: [], + }, + ], + nonconst_methods: [ + ], +} diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp index 5e5f996c..106cbed1 100644 --- a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp +++ b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp @@ -5,6 +5,7 @@ #pragma once +#include "RuntimeContext.hpp" #include #include #include @@ -61,22 +62,24 @@ namespace xo { bool is_nary() const noexcept { return false; } static constexpr std::int32_t n_args() noexcept { return Traits::n_args; } - obj apply_nocheck(obj mm, const DArray * args) { - return _apply_nocheck(mm, args, - std::make_index_sequence{}); + obj apply_nocheck(obj rcx, const DArray * args) { + return _apply_nocheck(rcx, args, + std::make_index_sequence{}); } private: template - obj _apply_nocheck(obj mm, + obj _apply_nocheck(obj rcx, const DArray * args, std::index_sequence) { using R = typename Traits::return_type; + obj mm = rcx.allocator(); + R result - = fn_(GCObjectConversion>::from_gco(mm, args->at(Is))... - ); + = fn_(rcx, + GCObjectConversion>::from_gco(mm, args->at(Is))... ); return GCObjectConversion::to_gco(mm, result); } diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive_gco_2_gco_gco.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive_gco_2_gco_gco.hpp new file mode 100644 index 00000000..24ad3b41 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/DPrimitive_gco_2_gco_gco.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include +#include "DPrimitive.hpp" + +namespace xo { + namespace scm { + using xo::mm::AGCObject; + using xo::facet::obj; + + using DPrimitive_gco_2_gco_gco = Primitive (*)(obj, + obj, + obj)>; + } +} diff --git a/xo-procedure2/include/xo/procedure2/Procedure.hpp b/xo-procedure2/include/xo/procedure2/Procedure.hpp index 8b2cd91a..784608ed 100644 --- a/xo-procedure2/include/xo/procedure2/Procedure.hpp +++ b/xo-procedure2/include/xo/procedure2/Procedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp new file mode 100644 index 00000000..3241451b --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp @@ -0,0 +1,22 @@ +/** @file RuntimeContext.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/RuntimeContext.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/RuntimeContext.json5] + **/ + +#pragma once + +#include "detail/ARuntimeContext.hpp" +#include "detail/IRuntimeContext_Any.hpp" +#include "detail/IRuntimeContext_Xfer.hpp" +#include "detail/RRuntimeContext.hpp" + + +/* end RuntimeContext.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp index c0b22f49..63a4da9b 100644 --- a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -14,11 +14,13 @@ #pragma once // includes (via {facet_includes}) +#include "RuntimeContext.hpp" +#include #include #include #include -// {pretex} here +namespace xo { namespace scm { class DArray; } } namespace xo { namespace scm { @@ -54,7 +56,7 @@ public: // nonconst methods /** invoke procedure; assume arguments satisfy type system **/ - virtual obj apply_nocheck(Opaque data, obj mm, const DArray * args) = 0; + virtual obj apply_nocheck(Opaque data, obj rcx, const DArray * args) = 0; ///@} }; /*AProcedure*/ diff --git a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp new file mode 100644 index 00000000..4e96bc8f --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp @@ -0,0 +1,73 @@ +/** @file ARuntimeContext.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/RuntimeContext.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/RuntimeContext.json5] + **/ + +#pragma once + +// includes (via {facet_includes}) +#include +#include +#include +#include + + +namespace xo { +namespace scm { + +using Copaque = const void *; +using Opaque = void *; + +/** +Runtime application context +**/ +class ARuntimeContext { +public: + /** @defgroup scm-runtimecontext-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; + /** xo memory allocator **/ + using AAllocator = xo::mm::AAllocator; + ///@} + + /** @defgroup scm-runtimecontext-methods **/ + ///@{ + // const methods + /** RTTI: unique id# for actual runtime data representation **/ + virtual typeseq _typeseq() const noexcept = 0; + /** default allocator to use for objects **/ + virtual obj allocator(Copaque data) const noexcept = 0; + + // nonconst methods + ///@} +}; /*ARuntimeContext*/ + +/** Implementation IRuntimeContext_DRepr of ARuntimeContext for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = IRuntimeContext_DRepr; + * }; + * + * then IRuntimeContext_ImplType --> IRuntimeContext_DRepr + **/ +template +using IRuntimeContext_ImplType = xo::facet::FacetImplType; + +} /*namespace scm*/ +} /*namespace xo*/ + +/* ARuntimeContext.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp index c1b8c9d6..5d711d4c 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -60,7 +60,7 @@ namespace scm { [[noreturn]] std::int32_t n_args(Copaque) const noexcept override { _fatal(); } // nonconst methods - [[noreturn]] obj apply_nocheck(Opaque, obj, const DArray *) override; + [[noreturn]] obj apply_nocheck(Opaque, obj, const DArray *) override; ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp new file mode 100644 index 00000000..11f2cd60 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp @@ -0,0 +1,67 @@ +/** @file IProcedure_DPrimitive_gco_2_gco_gco.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] + **/ + +#pragma once + +#include "Procedure.hpp" +#include +#include +#include +#include +#include "DPrimitive_gco_2_gco_gco.hpp" + +namespace xo { namespace scm { class IProcedure_DPrimitive_gco_2_gco_gco; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IProcedure_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IProcedure_DPrimitive_gco_2_gco_gco + **/ + class IProcedure_DPrimitive_gco_2_gco_gco { + public: + /** @defgroup scm-procedure-dprimitive_gco_2_gco_gco-type-traits **/ + ///@{ + using AGCObject = xo::scm::AProcedure::AGCObject; + using Copaque = xo::scm::AProcedure::Copaque; + using Opaque = xo::scm::AProcedure::Opaque; + ///@} + /** @defgroup scm-procedure-dprimitive_gco_2_gco_gco-methods **/ + ///@{ + // const methods + /** true iff procedure takes n arguments **/ + static bool is_nary(const DPrimitive_gco_2_gco_gco & self) noexcept; + /** number of arguments. -1 for n-ary **/ + static std::int32_t n_args(const DPrimitive_gco_2_gco_gco & self) noexcept; + + // non-const methods + /** invoke procedure; assume arguments satisfy type system **/ + static obj apply_nocheck(DPrimitive_gco_2_gco_gco & self, obj rcx, const DArray * args); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp index dfe8a558..4f84652e 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -13,6 +13,8 @@ #pragma once +#include "RuntimeContext.hpp" +#include namespace xo { namespace scm { @@ -48,8 +50,8 @@ namespace scm { } // non-const methods - obj apply_nocheck(Opaque data, obj mm, const DArray * args) override { - return I::apply_nocheck(_dcast(data), mm, args); + obj apply_nocheck(Opaque data, obj rcx, const DArray * args) override { + return I::apply_nocheck(_dcast(data), rcx, args); } ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp new file mode 100644 index 00000000..1e5f97c0 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp @@ -0,0 +1,86 @@ +/** @file IRuntimeContext_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/RuntimeContext.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/RuntimeContext.json5] + **/ + +#pragma once + +#include "ARuntimeContext.hpp" +#include + +namespace xo { namespace scm { class IRuntimeContext_Any; } } + +namespace xo { +namespace facet { + +template <> +struct FacetImplementation +{ + using ImplType = xo::scm::IRuntimeContext_Any; +}; + +} +} + +namespace xo { +namespace scm { + + /** @class IRuntimeContext_Any + * @brief ARuntimeContext implementation for empty variant instance + **/ + class IRuntimeContext_Any : public ARuntimeContext { + public: + /** @defgroup scm-runtimecontext-any-type-traits **/ + ///@{ + + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using AAllocator = ARuntimeContext::AAllocator; + + ///@} + /** @defgroup scm-runtimecontext-any-methods **/ + ///@{ + + const ARuntimeContext * iface() const { return std::launder(this); } + + // from ARuntimeContext + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] obj allocator(Copaque) const noexcept override { _fatal(); } + + // nonconst methods + + ///@} + + private: + /** @defgraoup scm-runtimecontext-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup scm-runtimecontext-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace scm */ +} /*namespace xo */ + +/* IRuntimeContext_Any.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp new file mode 100644 index 00000000..cd71b73e --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp @@ -0,0 +1,81 @@ +/** @file IRuntimeContext_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/RuntimeContext.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/RuntimeContext.json5] + **/ + +#pragma once + +#include + +namespace xo { +namespace scm { + /** @class IRuntimeContext_Xfer + **/ + template + class IRuntimeContext_Xfer : public ARuntimeContext { + public: + /** @defgroup scm-runtimecontext-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = IRuntimeContext_DRepr; + /** integer identifying a type **/ + using typeseq = ARuntimeContext::typeseq; + using AAllocator = ARuntimeContext::AAllocator; + ///@} + + /** @defgroup scm-runtimecontext-xfer-methods **/ + ///@{ + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + + // from ARuntimeContext + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + obj allocator(Copaque data) const noexcept override { + return I::allocator(_dcast(data)); + } + + // non-const methods + + ///@} + + private: + using I = Impl; + + public: + /** @defgroup scm-runtimecontext-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + xo::facet::typeseq + IRuntimeContext_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + IRuntimeContext_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace scm */ +} /*namespace xo*/ + +/* end IRuntimeContext_Xfer.hpp */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp index dc0f30d8..93599ae3 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -56,8 +56,8 @@ public: } // non-const methods (still const in router!) - obj apply_nocheck(obj mm, const DArray * args) { - return O::iface()->apply_nocheck(O::data(), mm, args); + obj apply_nocheck(obj rcx, const DArray * args) { + return O::iface()->apply_nocheck(O::data(), rcx, args); } ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp new file mode 100644 index 00000000..b06227c8 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp @@ -0,0 +1,80 @@ +/** @file RRuntimeContext.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/RuntimeContext.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/RuntimeContext.json5] + **/ + +#pragma once + +#include "ARuntimeContext.hpp" + +namespace xo { +namespace scm { + +/** @class RRuntimeContext + **/ +template +class RRuntimeContext : public Object { +private: + using O = Object; + +public: + /** @defgroup scm-runtimecontext-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; + using AAllocator = ARuntimeContext::AAllocator; + ///@} + + /** @defgroup scm-runtimecontext-router-ctors **/ + ///@{ + RRuntimeContext() {} + RRuntimeContext(Object::DataPtr data) : Object{std::move(data)} {} + RRuntimeContext(const ARuntimeContext * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} + + ///@} + /** @defgroup scm-runtimecontext-router-methods **/ + ///@{ + + // const methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + obj allocator() const noexcept { + return O::iface()->allocator(O::data()); + } + + // non-const methods (still const in router!) + + ///@} + /** @defgroup scm-runtimecontext-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RRuntimeContext::_valid = xo::facet::valid_object_router(); + +} /*namespace scm*/ +} /*namespace xo*/ + +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::scm::RRuntimeContext; + }; +} } + +/* end RRuntimeContext.hpp */ \ No newline at end of file diff --git a/xo-procedure2/src/procedure2/CMakeLists.txt b/xo-procedure2/src/procedure2/CMakeLists.txt index edc5d3ce..11a9c305 100644 --- a/xo-procedure2/src/procedure2/CMakeLists.txt +++ b/xo-procedure2/src/procedure2/CMakeLists.txt @@ -5,6 +5,9 @@ set(SELF_SRCS init_procedure2.cpp init_primitives.cpp DPrimitive.cpp + IRuntimeContext_Any.cpp + IProcedure_Any.cpp + IProcedure_DPrimitive_gco_2_gco_gco.cpp # Add source files here, e.g.: # procedure2.cpp ) diff --git a/xo-procedure2/src/procedure2/IProcedure_Any.cpp b/xo-procedure2/src/procedure2/IProcedure_Any.cpp index 3044c104..d28d98ee 100644 --- a/xo-procedure2/src/procedure2/IProcedure_Any.cpp +++ b/xo-procedure2/src/procedure2/IProcedure_Any.cpp @@ -35,7 +35,7 @@ IProcedure_Any::_valid // nonconst methods auto -IProcedure_Any::apply_nocheck(Opaque, obj, const DArray *) -> obj +IProcedure_Any::apply_nocheck(Opaque, obj, const DArray *) -> obj { _fatal(); } diff --git a/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp b/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp new file mode 100644 index 00000000..67e73c97 --- /dev/null +++ b/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp @@ -0,0 +1,39 @@ +/** @file IProcedure_DPrimitive_gco_2_gco_gco.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] +**/ + +#include "detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp" + +namespace xo { + namespace scm { + auto + IProcedure_DPrimitive_gco_2_gco_gco::is_nary(const DPrimitive_gco_2_gco_gco & self) noexcept -> bool + { + return self.is_nary(); + } + + auto + IProcedure_DPrimitive_gco_2_gco_gco::n_args(const DPrimitive_gco_2_gco_gco & self) noexcept -> std::int32_t + { + return self.n_args(); + } + + auto + IProcedure_DPrimitive_gco_2_gco_gco::apply_nocheck(DPrimitive_gco_2_gco_gco & self, obj rcx, const DArray * args) -> obj + { + return self.apply_nocheck(rcx, args); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IProcedure_DPrimitive_gco_2_gco_gco.cpp */ \ No newline at end of file diff --git a/xo-procedure2/src/procedure2/IRuntimeContext_Any.cpp b/xo-procedure2/src/procedure2/IRuntimeContext_Any.cpp new file mode 100644 index 00000000..a9c5b55a --- /dev/null +++ b/xo-procedure2/src/procedure2/IRuntimeContext_Any.cpp @@ -0,0 +1,41 @@ +/** @file IRuntimeContext_Any.cpp + * + **/ + +#include "detail/IRuntimeContext_Any.hpp" +#include + +namespace xo { +namespace scm { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +IRuntimeContext_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " IRuntimeContext_Any method" + << std::endl; + std::terminate(); +} + +typeseq +IRuntimeContext_Any::s_typeseq = typeseq::id(); + +bool +IRuntimeContext_Any::_valid + = valid_facet_implementation(); + +// nonconst methods + + +} /*namespace scm*/ +} /*namespace xo*/ + +/* end IRuntimeContext_Any.cpp */ \ No newline at end of file diff --git a/xo-procedure2/src/procedure2/init_primitives.cpp b/xo-procedure2/src/procedure2/init_primitives.cpp index 169b660e..35709e0f 100644 --- a/xo-procedure2/src/procedure2/init_primitives.cpp +++ b/xo-procedure2/src/procedure2/init_primitives.cpp @@ -5,6 +5,7 @@ #include "init_primitives.hpp" #include "DPrimitive.hpp" +#include namespace xo { namespace scm { @@ -23,6 +24,40 @@ namespace xo { return x - y; } +#ifdef NOT_YET + obj + mul_any_any(obj x_gco, obj y_gco) + { + // PLACEHOLDER + + // TODO: + // 1. move this to xo-numeric2/ when available + // 2. at that point will require polymorphic dispatch + // on argument representations, analogous to dispatch + // in FacetRegistry + // 3. Need concept of a 'runtime context'. + // This will need to be part of the AProcedure api + // e.g. passed to apply_nocheck + + typeseq x_tseq = x_gco._typeseq(); + typeseq y_tseq = y_gco._typeseq(); + + // FOR NOW: just test runtime values + // + if (x_tseq == typeseq::id()) { + if (y_tseq == typeseq::id()) { + // unusable placeholder allocator; + obj placeholder_mm; + + // f64 * f64. + double x = GCObjectConversion::from_gco(placeholder_mm, x_gco); + double y = GCObjectConversion::from_gco(placeholder_mm, y_gco); + + + + } +#endif + double mul_f64_f64(double x, double y) { return x * y; From 43a62354398ff94518870dac0581c7dad77305d1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 12:38:17 -0500 Subject: [PATCH 077/258] xo-procedure2 xo-object2: + polymorphic primitive support --- xo-gc/include/xo/gc/GCObjectConversion.hpp | 62 ++++++++++++++++ xo-object2/include/xo/object2/DArray.hpp | 2 +- .../number/GCObjectConversion_DFloat.hpp | 2 +- .../number/GCObjectConversion_DInteger.hpp | 29 ++++++++ xo-object2/src/object2/CMakeLists.txt | 1 + .../src/object2/GCObjectConversion_DFloat.cpp | 2 +- .../object2/GCObjectConversion_DInteger.cpp | 41 +++++++++++ xo-procedure2/doc/implementation.rst | 25 +++++++ xo-procedure2/idl/Procedure.json5 | 1 - .../include/xo/procedure2/DPrimitive.hpp | 18 +++-- .../include/xo/procedure2/Procedure.hpp | 2 +- .../include/xo/procedure2/RuntimeContext.hpp | 2 +- .../xo/procedure2/detail/AProcedure.hpp | 4 +- .../xo/procedure2/detail/ARuntimeContext.hpp | 2 +- .../xo/procedure2/detail/IProcedure_Any.hpp | 4 +- .../IProcedure_DPrimitive_gco_2_gco_gco.hpp | 4 +- .../xo/procedure2/detail/IProcedure_Xfer.hpp | 6 +- .../procedure2/detail/IRuntimeContext_Any.hpp | 2 +- .../detail/IRuntimeContext_Xfer.hpp | 2 +- .../xo/procedure2/detail/RProcedure.hpp | 6 +- .../xo/procedure2/detail/RRuntimeContext.hpp | 2 +- .../include/xo/procedure2/init_primitives.hpp | 7 ++ .../src/procedure2/IProcedure_Any.cpp | 2 +- .../IProcedure_DPrimitive_gco_2_gco_gco.cpp | 6 +- .../src/procedure2/init_primitives.cpp | 70 ++++++++++++++++--- xo-reader2/src/reader2/DProgressSsm.cpp | 3 + 26 files changed, 265 insertions(+), 42 deletions(-) create mode 100644 xo-object2/include/xo/object2/number/GCObjectConversion_DInteger.hpp create mode 100644 xo-object2/src/object2/GCObjectConversion_DInteger.cpp create mode 100644 xo-procedure2/doc/implementation.rst diff --git a/xo-gc/include/xo/gc/GCObjectConversion.hpp b/xo-gc/include/xo/gc/GCObjectConversion.hpp index 6e3e84df..8a950c82 100644 --- a/xo-gc/include/xo/gc/GCObjectConversion.hpp +++ b/xo-gc/include/xo/gc/GCObjectConversion.hpp @@ -7,6 +7,8 @@ #include #include +#include +#include namespace xo { namespace scm { @@ -20,10 +22,70 @@ namespace xo { using AGCObject = xo::mm::AGCObject; using AAllocator = xo::mm::AAllocator; + /** find gc-aware representation for @p x. + * If necessary allocate from @p mm, but may + * refer to @p x in-place + **/ static obj to_gco(obj mm, const T & x); + /** convert to native representation @tparam T from gc-aware + * @p gco. If necessary allocate from @p mm, but + * may instead refer to @p x in-place + **/ static T from_gco(obj mm, obj gco); }; + /** Motivating use-case for GCObjectConversion is to transform + * primitive function arguments and results to/from gc-aware + * representation. + * + * However: Schematika also supports runtime polymorphism + * which leads to primitives that expect obj arguments. + * + * Also, Schematika expression parser needs representation for + * expressions, before type unification. + * + * Consider a function like: + * def fact = lambda (n : i64) { if (n <= 0) then 1 else (n * fact(n - 1)); } + * During expression parsing the rhs argument to multiply has unknown type. + * To construct an expression for input to unification will use polymorphic + * binding for multiply primitive, relying on specialization here for + * its implementation. + **/ + template + struct GCObjectConversion> { + using AGCObject = xo::mm::AGCObject; + using AAllocator = xo::mm::AAllocator; + using FacetRegistry = xo::facet::FacetRegistry; + using DVariantPlaceholder = xo::facet::DVariantPlaceholder; + + static obj to_gco(obj, + obj gco) { + if constexpr (std::is_same_v) { + // trivial conversion! + return gco; + } else if constexpr (std::is_same_v) { + // runtime polymorphism + return FacetRegistry::instance().variant(gco); + } else /* DRepr != DVariantPlaceholder */ { + // known content w/ fat object pointer + return obj(gco.data()); + } + } + + static obj from_gco(obj, + obj gco) { + if constexpr (std::is_same_v) { + // trivial conversion + return gco; + } else { + // both runtime and comptime polymorphism + // use same path here, since representation of @p gco + // is type-erased here + + return FacetRegistry::instance().variant(gco); + } + } + }; } /*namespace scm */ } /*namespace xo*/ diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index 0dc13cd1..097b9a45 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -23,7 +23,7 @@ namespace xo { * fixed at construction time, but not part of type. * Can reallocate to change **/ - struct DArray { + class DArray { public: /** @defgroup darray-types type traits **/ ///@{ diff --git a/xo-object2/include/xo/object2/number/GCObjectConversion_DFloat.hpp b/xo-object2/include/xo/object2/number/GCObjectConversion_DFloat.hpp index 8ce4b2b6..959eeca0 100644 --- a/xo-object2/include/xo/object2/number/GCObjectConversion_DFloat.hpp +++ b/xo-object2/include/xo/object2/number/GCObjectConversion_DFloat.hpp @@ -19,7 +19,7 @@ namespace xo { using AGCObject = xo::mm::AGCObject; using AAllocator = xo::mm::AAllocator; - static obj to_gco(obj mm, const double & x); + static obj to_gco(obj mm, double x); static double from_gco(obj mm, obj gco); }; diff --git a/xo-object2/include/xo/object2/number/GCObjectConversion_DInteger.hpp b/xo-object2/include/xo/object2/number/GCObjectConversion_DInteger.hpp new file mode 100644 index 00000000..458312c9 --- /dev/null +++ b/xo-object2/include/xo/object2/number/GCObjectConversion_DInteger.hpp @@ -0,0 +1,29 @@ +/** @file GCObjectConversion_DInteger.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DInteger.hpp" +#include "number/IGCObject_DInteger.hpp" +#include + +namespace xo { + namespace scm { + + template <> + struct GCObjectConversion { + static_assert(std::is_same_v); + + using AGCObject = xo::mm::AGCObject; + using AAllocator = xo::mm::AAllocator; + + static obj to_gco(obj mm, long x); + static long from_gco(obj mm, obj gco); + }; + + } +} /*namespace xo*/ + +/* end GCObjectConversion_DInteger.hpp */ diff --git a/xo-object2/src/object2/CMakeLists.txt b/xo-object2/src/object2/CMakeLists.txt index 2902a4ee..2ea8a07f 100644 --- a/xo-object2/src/object2/CMakeLists.txt +++ b/xo-object2/src/object2/CMakeLists.txt @@ -6,6 +6,7 @@ set(SELF_SRCS object2_register_types.cpp object2_register_facets.cpp GCObjectConversion_DFloat.cpp + GCObjectConversion_DInteger.cpp IGCObject_DArray.cpp IGCObject_DFloat.cpp IGCObject_DBoolean.cpp diff --git a/xo-object2/src/object2/GCObjectConversion_DFloat.cpp b/xo-object2/src/object2/GCObjectConversion_DFloat.cpp index a99c68ce..794431d2 100644 --- a/xo-object2/src/object2/GCObjectConversion_DFloat.cpp +++ b/xo-object2/src/object2/GCObjectConversion_DFloat.cpp @@ -13,7 +13,7 @@ namespace xo { obj GCObjectConversion::to_gco(obj mm, - const double & x) + double x) { return DFloat::box(mm, x); } diff --git a/xo-object2/src/object2/GCObjectConversion_DInteger.cpp b/xo-object2/src/object2/GCObjectConversion_DInteger.cpp new file mode 100644 index 00000000..bdaf8a18 --- /dev/null +++ b/xo-object2/src/object2/GCObjectConversion_DInteger.cpp @@ -0,0 +1,41 @@ +/** @file GCObjectConversion_DInteger.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "number/GCObjectConversion_DInteger.hpp" +#include + +namespace xo { + using xo::mm::AGCObject; + + namespace scm { + + obj + GCObjectConversion::to_gco(obj mm, + long x) + { + return DInteger::box(mm, x); + } + + long + GCObjectConversion::from_gco(obj mm, + obj gco) + { + (void)mm; + + auto int_obj = obj::from(gco); + + if (!int_obj) { + throw std::runtime_error + (tostr("Object obj found where Integer expected", + xtag("obj", gco))); + } + + return int_obj.data()->value(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end GCObjectConversion_DFloat.cpp */ diff --git a/xo-procedure2/doc/implementation.rst b/xo-procedure2/doc/implementation.rst new file mode 100644 index 00000000..418dc759 --- /dev/null +++ b/xo-procedure2/doc/implementation.rst @@ -0,0 +1,25 @@ +.. _implementation: + +.. toctree:: + :maxdepth: 2 + +Components +========== + +Library dependency tower for *xo-procedure2* + +.. ditaa:: + + +--------------------------------+ + | xo_gc | + +--------------------------------+ + | xo_alloc2 | + +--------------------------------+ + | xo_facet | + +----------------+---------------+ + | xo_reflectutil | xo_indentlog | + +----------------+---------------+ + | xo_cmake | + +--------------------------------+ + +Expect to have xo_facet depending on xo_arena instead of using std::unordered_map diff --git a/xo-procedure2/idl/Procedure.json5 b/xo-procedure2/idl/Procedure.json5 index f0eac6b5..f26a4e56 100644 --- a/xo-procedure2/idl/Procedure.json5 +++ b/xo-procedure2/idl/Procedure.json5 @@ -56,7 +56,6 @@ doc: ["invoke procedure; assume arguments satisfy type system" ], return_type: "obj", args: [ - {type: "obj", name: "rcx"}, {type: "const DArray *", name: "args"}, ] } diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp index 106cbed1..cf913a15 100644 --- a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp +++ b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -62,24 +63,29 @@ namespace xo { bool is_nary() const noexcept { return false; } static constexpr std::int32_t n_args() noexcept { return Traits::n_args; } - obj apply_nocheck(obj rcx, const DArray * args) { - return _apply_nocheck(rcx, args, + obj apply_nocheck(const DArray * args) { + return _apply_nocheck(args, std::make_index_sequence{}); } private: template - obj _apply_nocheck(obj rcx, - const DArray * args, + obj _apply_nocheck(const DArray * args, std::index_sequence) { + using xo::facet::FacetRegistry; + using R = typename Traits::return_type; + assert(args); + assert(args->size() > 0); + + obj rcx + = FacetRegistry::instance().variant(args->at(0)); obj mm = rcx.allocator(); R result - = fn_(rcx, - GCObjectConversion>::from_gco(mm, args->at(Is))... ); + = fn_(GCObjectConversion>::from_gco(mm, args->at(Is))... ); return GCObjectConversion::to_gco(mm, result); } diff --git a/xo-procedure2/include/xo/procedure2/Procedure.hpp b/xo-procedure2/include/xo/procedure2/Procedure.hpp index 784608ed..8b2cd91a 100644 --- a/xo-procedure2/include/xo/procedure2/Procedure.hpp +++ b/xo-procedure2/include/xo/procedure2/Procedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp index 3241451b..2e8300ed 100644 --- a/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp index 63a4da9b..1be5e0d1 100644 --- a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -56,7 +56,7 @@ public: // nonconst methods /** invoke procedure; assume arguments satisfy type system **/ - virtual obj apply_nocheck(Opaque data, obj rcx, const DArray * args) = 0; + virtual obj apply_nocheck(Opaque data, const DArray * args) = 0; ///@} }; /*AProcedure*/ diff --git a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp index 4e96bc8f..42030d9d 100644 --- a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp index 5d711d4c..3f66fcd5 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -60,7 +60,7 @@ namespace scm { [[noreturn]] std::int32_t n_args(Copaque) const noexcept override { _fatal(); } // nonconst methods - [[noreturn]] obj apply_nocheck(Opaque, obj, const DArray *) override; + [[noreturn]] obj apply_nocheck(Opaque, const DArray *) override; ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp index 11f2cd60..4b4351dd 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -57,7 +57,7 @@ namespace xo { // non-const methods /** invoke procedure; assume arguments satisfy type system **/ - static obj apply_nocheck(DPrimitive_gco_2_gco_gco & self, obj rcx, const DArray * args); + static obj apply_nocheck(DPrimitive_gco_2_gco_gco & self, const DArray * args); ///@} }; diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp index 4f84652e..adf4995d 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -50,8 +50,8 @@ namespace scm { } // non-const methods - obj apply_nocheck(Opaque data, obj rcx, const DArray * args) override { - return I::apply_nocheck(_dcast(data), rcx, args); + obj apply_nocheck(Opaque data, const DArray * args) override { + return I::apply_nocheck(_dcast(data), args); } ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp index 1e5f97c0..419d45cc 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp index cd71b73e..e9f5512e 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp index 93599ae3..9fff0c6c 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -56,8 +56,8 @@ public: } // non-const methods (still const in router!) - obj apply_nocheck(obj rcx, const DArray * args) { - return O::iface()->apply_nocheck(O::data(), rcx, args); + obj apply_nocheck(const DArray * args) { + return O::iface()->apply_nocheck(O::data(), args); } ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp index b06227c8..06b093de 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/init_primitives.hpp b/xo-procedure2/include/xo/procedure2/init_primitives.hpp index d4150d2d..5e2d08e8 100644 --- a/xo-procedure2/include/xo/procedure2/init_primitives.hpp +++ b/xo-procedure2/include/xo/procedure2/init_primitives.hpp @@ -3,13 +3,19 @@ #pragma once #include "DPrimitive.hpp" +#include "DPrimitive_gco_2_gco_gco.hpp" namespace xo { namespace scm { +#ifdef NOT_YET using Primitive_f64_1_f64 = Primitive; using Primitive_f64_2_f64_f64 = Primitive; +#endif struct Primitives { + static DPrimitive_gco_2_gco_gco s_mul_gco_gco_pm; + +#ifdef NOT_YET static Primitive_f64_1_f64 s_neg_f64_pm; static Primitive_f64_2_f64_f64 s_add_f64_f64_pm; @@ -22,6 +28,7 @@ namespace xo { static Primitive_f64_1_f64 s_sin_f64_pm; static Primitive_f64_1_f64 s_cos_f64_pm; static Primitive_f64_1_f64 s_tan_f64_pm; +#endif }; } } diff --git a/xo-procedure2/src/procedure2/IProcedure_Any.cpp b/xo-procedure2/src/procedure2/IProcedure_Any.cpp index d28d98ee..79b3b778 100644 --- a/xo-procedure2/src/procedure2/IProcedure_Any.cpp +++ b/xo-procedure2/src/procedure2/IProcedure_Any.cpp @@ -35,7 +35,7 @@ IProcedure_Any::_valid // nonconst methods auto -IProcedure_Any::apply_nocheck(Opaque, obj, const DArray *) -> obj +IProcedure_Any::apply_nocheck(Opaque, const DArray *) -> obj { _fatal(); } diff --git a/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp b/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp index 67e73c97..5266477c 100644 --- a/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp +++ b/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,9 +28,9 @@ namespace xo { } auto - IProcedure_DPrimitive_gco_2_gco_gco::apply_nocheck(DPrimitive_gco_2_gco_gco & self, obj rcx, const DArray * args) -> obj + IProcedure_DPrimitive_gco_2_gco_gco::apply_nocheck(DPrimitive_gco_2_gco_gco & self, const DArray * args) -> obj { - return self.apply_nocheck(rcx, args); + return self.apply_nocheck(args); } } /*namespace scm*/ diff --git a/xo-procedure2/src/procedure2/init_primitives.cpp b/xo-procedure2/src/procedure2/init_primitives.cpp index 35709e0f..dbcb3b35 100644 --- a/xo-procedure2/src/procedure2/init_primitives.cpp +++ b/xo-procedure2/src/procedure2/init_primitives.cpp @@ -5,10 +5,23 @@ #include "init_primitives.hpp" #include "DPrimitive.hpp" +#include +#include +#include +#include +#include +#include +#include +#include #include namespace xo { + using xo::mm::AAllocator; + using xo::scm::DFloat; + using xo::facet::with_facet; + namespace scm { +#ifdef NOT_YET double neg_f64(double x) { return -x; @@ -23,11 +36,17 @@ namespace xo { sub_f64_f64(double x, double y) { return x - y; } +#endif -#ifdef NOT_YET obj - mul_any_any(obj x_gco, obj y_gco) + mul_gco_gco(obj rcx, + obj x_gco, + obj y_gco) { + using xo::reflect::typeseq; + + obj mm = rcx.allocator(); + // PLACEHOLDER // TODO: @@ -44,20 +63,45 @@ namespace xo { // FOR NOW: just test runtime values // - if (x_tseq == typeseq::id()) { - if (y_tseq == typeseq::id()) { - // unusable placeholder allocator; - obj placeholder_mm; + if (x_tseq == typeseq::id()) { + // i64 * .. + long x = GCObjectConversion::from_gco(mm, x_gco); + if (y_tseq == typeseq::id()) { + // i64 * i64 + long y = GCObjectConversion::from_gco(mm, y_gco); + + return DInteger::box(mm, x * y); + } else if (y_tseq == typeseq::id()) { + // i64 * f64 + double y = GCObjectConversion::from_gco(mm, y_gco); + + return DFloat::box(mm, x * y); + } + } else if (x_tseq == typeseq::id()) { + if (y_tseq == typeseq::id()) { + // f64 * i64. + double x = GCObjectConversion::from_gco(mm, x_gco); + long y = GCObjectConversion::from_gco(mm, y_gco); + + return DFloat::box(mm, x * y); + } else if (y_tseq == typeseq::id()) { // f64 * f64. - double x = GCObjectConversion::from_gco(placeholder_mm, x_gco); - double y = GCObjectConversion::from_gco(placeholder_mm, y_gco); - + double x = GCObjectConversion::from_gco(mm, x_gco); + double y = GCObjectConversion::from_gco(mm, y_gco); + return DFloat::box(mm, x * y); + } + } + // here: error + throw std::runtime_error(tostr("mul_gco_gco: unexpected argument types xt,yt", + xtag("x.tseq", x_tseq), + xtag("y.tseq", y_tseq))); + return obj(); } -#endif +#ifdef NOT_YET double mul_f64_f64(double x, double y) { return x * y; @@ -92,7 +136,12 @@ namespace xo { tan_f64(double x) { return ::tan(x); } +#endif + DPrimitive_gco_2_gco_gco + Primitives::s_mul_gco_gco_pm("_mul", &mul_gco_gco); + +#ifdef NOT_YET Primitive_f64_1_f64 Primitives::s_neg_f64_pm("_neg_d", &neg_f64); @@ -123,6 +172,7 @@ namespace xo { Primitive_f64_1_f64 Primitives::s_tan_f64_pm("_tan_d", &tan_f64); +#endif } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index f501d5fe..85f7b1d3 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -226,8 +226,11 @@ namespace xo { case tokentype::tk_minus: break; case tokentype::tk_star: +#ifdef NOT_YET this->on_operator_token(tk, p_psm); return; +#endif + break; case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: From bb8a140647c30b04923d4a036daae9480f95e50e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 13:42:42 -0500 Subject: [PATCH 078/258] xo-expression2 xo-procedure2: work on calling primitive for x*y --- xo-expression2/CMakeLists.txt | 26 ++ .../idl/IExpression_DApplyExpr.json5 | 12 + .../idl/IPrintable_DApplyExpr.json5 | 13 + .../include/xo/expression2/DApplyExpr.hpp | 57 +++- .../detail/IExpression_DApplyExpr.hpp | 66 +++++ .../detail/IPrintable_DApplyExpr.hpp | 62 +++++ xo-expression2/src/expression2/CMakeLists.txt | 3 + xo-expression2/src/expression2/DApplyExpr.cpp | 67 +++-- .../expression2/IExpression_DApplyExpr.cpp | 45 +++ .../src/expression2/IPrintable_DApplyExpr.cpp | 28 ++ .../expression2_register_facets.cpp | 10 +- xo-procedure2/idl/Procedure.json5 | 5 + .../include/xo/procedure2/DPrimitive.hpp | 78 +++--- .../procedure2/DPrimitive_gco_2_gco_gco.hpp | 7 + .../include/xo/procedure2/Procedure.hpp | 2 +- .../include/xo/procedure2/RuntimeContext.hpp | 2 +- .../xo/procedure2/detail/AProcedure.hpp | 4 +- .../xo/procedure2/detail/ARuntimeContext.hpp | 2 +- .../xo/procedure2/detail/IProcedure_Any.hpp | 4 +- .../IProcedure_DPrimitive_gco_2_gco_gco.hpp | 4 +- .../xo/procedure2/detail/IProcedure_Xfer.hpp | 6 +- .../procedure2/detail/IRuntimeContext_Any.hpp | 2 +- .../detail/IRuntimeContext_Xfer.hpp | 2 +- .../xo/procedure2/detail/RProcedure.hpp | 6 +- .../xo/procedure2/detail/RRuntimeContext.hpp | 2 +- .../src/procedure2/IProcedure_Any.cpp | 2 +- .../IProcedure_DPrimitive_gco_2_gco_gco.cpp | 6 +- .../include/xo/reader2/DProgressSsm.hpp | 32 +-- xo-reader2/src/reader2/DExpectExprSsm.cpp | 7 +- xo-reader2/src/reader2/DProgressSsm.cpp | 262 ++++++++++-------- 30 files changed, 603 insertions(+), 221 deletions(-) create mode 100644 xo-expression2/idl/IExpression_DApplyExpr.json5 create mode 100644 xo-expression2/idl/IPrintable_DApplyExpr.json5 create mode 100644 xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp create mode 100644 xo-expression2/src/expression2/IExpression_DApplyExpr.cpp create mode 100644 xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 52e9d380..869f891d 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -124,6 +124,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-expression-applyexpr + FACET_PKG xo_expression2 + FACET Expression + REPR ApplyExpr + INPUT idl/IExpression_DApplyExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-applyexpr + FACET_PKG xo_printable2 + FACET Printable + REPR ApplyExpr + INPUT idl/IPrintable_DApplyExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-uniquestring diff --git a/xo-expression2/idl/IExpression_DApplyExpr.json5 b/xo-expression2/idl/IExpression_DApplyExpr.json5 new file mode 100644 index 00000000..6814547c --- /dev/null +++ b/xo-expression2/idl/IExpression_DApplyExpr.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ "\"Expression.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Expression.json5", + brief: "provide AExpression interface for DApplyExpr state", + using_doxygen: true, + repr: "DApplyExpr", + doc: ["doc for IExpression+DApplyExpr" ], +} diff --git a/xo-expression2/idl/IPrintable_DApplyExpr.json5 b/xo-expression2/idl/IPrintable_DApplyExpr.json5 new file mode 100644 index 00000000..fe743b0b --- /dev/null +++ b/xo-expression2/idl/IPrintable_DApplyExpr.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DApplyExpr", + using_doxygen: true, + repr: "DApplyExpr", + doc: [ "implement APrintable for DApplyExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/DApplyExpr.hpp b/xo-expression2/include/xo/expression2/DApplyExpr.hpp index 882cf5cd..8502c62a 100644 --- a/xo-expression2/include/xo/expression2/DApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/DApplyExpr.hpp @@ -20,18 +20,55 @@ namespace xo { **/ class DApplyExpr { public: + using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; - using size_type = std::size_t; + using size_type = std::uint32_t; public: + /** @defgroup scm-applyexpr-constructors **/ + ///@{ + + /** construct empty instance, but with argument expressions empty **/ + DApplyExpr(TypeRef typeref, + obj fn_expr, + size_type n_args); + + /** create apply for function with 2 arguments **/ + static obj make2(obj mm, + TypeRef typeref, + obj fn_expr, + obj arg1, + obj arg2); + + /** create apply for function with 2 arguments **/ + static DApplyExpr * _make2(obj mm, + TypeRef typeref, + obj fn_expr, + obj arg1, + obj arg2); + + /** scaffold incomplete instance. + * apply-expr using memory from @p mm. + * will construct instance with space for @p n_args arguments + * but expressions left empty. + * use @ref assign_arg for all arguments to complete. + **/ + static DApplyExpr * scaffold(obj mm, + TypeRef typeref, + obj fn_expr, + size_type n_args); + void assign_arg(size_type i_arg, obj expr); + + ///@} + /** @defgroup scm-applyexpr-access-methods **/ + ///@{ obj fn() const noexcept { return fn_; } - const DArray * args() const noexcept { return args_; } - - size_type n_arg() const noexcept { return args_->size(); } + size_type n_args() const noexcept { return n_args_; } obj arg(size_type i) const; + ///@} /** @defgroup scm-applyexpr-expression-facet **/ ///@{ @@ -40,6 +77,12 @@ namespace xo { TypeDescr valuetype() const noexcept { return typeref_.td(); } void assign_valuetype(TypeDescr td) noexcept; + ///@} + /** @defgroup scm-applyexpr-gcobject-facet **/ + ///@{ + + // shallow_copy() etc. + ///@} /** @defgroup scm-applyexpr-printable-facet **/ ///@{ @@ -55,8 +98,10 @@ namespace xo { TypeRef typeref_; /** expression for function/procedure to invoke **/ obj fn_; - /** expression for each argument vector **/ - const DArray * args_; + /** number of arguments (not counting @ref fn_ **/ + size_type n_args_ = 0; + /** args_[i] is expression for i'th argument to @ref fn_ **/ + obj args_[]; }; } } diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp new file mode 100644 index 00000000..c8952199 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp @@ -0,0 +1,66 @@ +/** @file IExpression_DApplyExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DApplyExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DApplyExpr.json5] + **/ + +#pragma once + +#include "Expression.hpp" +#include "Expression.hpp" +#include "DApplyExpr.hpp" + +namespace xo { namespace scm { class IExpression_DApplyExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IExpression_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IExpression_DApplyExpr + **/ + class IExpression_DApplyExpr { + public: + /** @defgroup scm-expression-dapplyexpr-type-traits **/ + ///@{ + using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; + ///@} + /** @defgroup scm-expression-dapplyexpr-methods **/ + ///@{ + // const methods + /** expression type (constant | apply | ..) **/ + static exprtype extype(const DApplyExpr & self) noexcept; + /** placeholder for type giving possible values for this expression **/ + static TypeRef typeref(const DApplyExpr & self) noexcept; + /** type giving possible values for this expression. Maybe null before typecheck **/ + static TypeDescr valuetype(const DApplyExpr & self) noexcept; + + // non-const methods + /** assing to valuetype member. Useful when scaffolding expressions **/ + static void assign_valuetype(DApplyExpr & self, TypeDescr td) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp new file mode 100644 index 00000000..c05e87e2 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DApplyExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DApplyExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DApplyExpr.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DApplyExpr.hpp" + +namespace xo { namespace scm { class IPrintable_DApplyExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DApplyExpr + **/ + class IPrintable_DApplyExpr { + public: + /** @defgroup scm-printable-dapplyexpr-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dapplyexpr-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DApplyExpr & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 9dea6457..b8be9468 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -22,6 +22,9 @@ set(SELF_SRCS IExpression_DDefineExpr.cpp IPrintable_DDefineExpr.cpp + IExpression_DApplyExpr.cpp + IPrintable_DApplyExpr.cpp + DLocalSymtab.cpp DGlobalSymtab.cpp diff --git a/xo-expression2/src/expression2/DApplyExpr.cpp b/xo-expression2/src/expression2/DApplyExpr.cpp index 0c0546f3..ce5e1951 100644 --- a/xo-expression2/src/expression2/DApplyExpr.cpp +++ b/xo-expression2/src/expression2/DApplyExpr.cpp @@ -11,30 +11,62 @@ namespace xo { using xo::print::APrintable; using xo::facet::FacetRegistry; + using xo::reflect::typeseq; using xo::mm::AGCObject; namespace scm { + /* incomplete! */ + DApplyExpr::DApplyExpr(TypeRef typeref, + obj fn_expr, + size_type n_args) : typeref_{typeref}, + fn_{fn_expr}, + n_args_{n_args} + {} + + DApplyExpr * + DApplyExpr::scaffold(obj mm, + TypeRef typeref, + obj fn_expr, + size_type n_args) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DApplyExpr) + (n_args * sizeof(obj))); + + DApplyExpr * result = new (mem) DApplyExpr(typeref, + fn_expr, + n_args); + + return result; + } + + void + DApplyExpr::assign_arg(size_type i_arg, + obj expr) + { + if (i_arg < n_args_) { + this->args_[i_arg] = expr; + } else { + assert(false); + + throw std::runtime_error(tostr("assign out-of-range argument i_arg where [0..n_args) expected", + xtag("i_arg", i_arg), + xtag("expr", expr), + xtag("n_args", n_args_))); + + } + } + obj DApplyExpr::arg(size_type i) const { - if (i >= args_->size()) [[unlikely]] { + if (i >= n_args_) [[unlikely]] { throw std::runtime_error(tostr("attempt to fetch argument i where [0..n) expected", xtag("i", i), - xtag("n", args_->size()), + xtag("n", n_args_), xtag("src", "DApplyExpr::arg"))); } - obj arg_i = args_->at(i); - - auto expr_i = FacetRegistry::instance().variant(arg_i); - - if (!expr_i) [[unlikely]] { - throw std::runtime_error(tostr("expected expression interface on argument i", - xtag("i", i), - xtag("arg[i]", arg_i))); - } - - return expr_i; + return args_[i]; } void @@ -60,9 +92,9 @@ namespace xo { return false; } - for (size_t i_arg = 0, n_arg = this->n_arg(); i_arg < n_arg; ++i_arg) { + for (size_t i_arg = 0; i_arg < n_args_; ++i_arg) { obj arg_i - = FacetRegistry::instance().variant(this->arg(i_arg)); + = FacetRegistry::instance().variant(args_[i_arg]); if (!pps->print_upto(refrtag(concat("arg", 1+i_arg), arg_i))) return false; @@ -78,13 +110,14 @@ namespace xo { pps->newline_indent(ppii.ci1()); pps->pretty(refrtag("fn", fn)); - for (size_t i_arg = 0, n_arg = this->n_arg(); i_arg < n_arg; ++i_arg) { + for (size_t i_arg = 0; i_arg < n_args_; ++i_arg) { obj arg_i - = FacetRegistry::instance().variant(fn_); + = FacetRegistry::instance().variant(args_[i_arg]); pps->newline_indent(ppii.ci1()); pps->pretty(refrtag(concat("arg", 1+i_arg), arg_i)); } + return false; } } diff --git a/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp b/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp new file mode 100644 index 00000000..2098e050 --- /dev/null +++ b/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp @@ -0,0 +1,45 @@ +/** @file IExpression_DApplyExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DApplyExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DApplyExpr.json5] +**/ + +#include "detail/IExpression_DApplyExpr.hpp" + +namespace xo { + namespace scm { + auto + IExpression_DApplyExpr::extype(const DApplyExpr & self) noexcept -> exprtype + { + return self.extype(); + } + + auto + IExpression_DApplyExpr::typeref(const DApplyExpr & self) noexcept -> TypeRef + { + return self.typeref(); + } + + auto + IExpression_DApplyExpr::valuetype(const DApplyExpr & self) noexcept -> TypeDescr + { + return self.valuetype(); + } + + auto + IExpression_DApplyExpr::assign_valuetype(DApplyExpr & self, TypeDescr td) noexcept -> void + { + self.assign_valuetype(td); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IExpression_DApplyExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp b/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp new file mode 100644 index 00000000..4f4a50d3 --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DApplyExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DApplyExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DApplyExpr.json5] +**/ + +#include "detail/IPrintable_DApplyExpr.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DApplyExpr::pretty(const DApplyExpr & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DApplyExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 1854f3eb..fc6ef3c1 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -17,6 +17,9 @@ #include #include +#include +#include + #include #include #include @@ -40,7 +43,8 @@ namespace xo { // Expression // +- Constant // +- Variable - // \- DefineExpr + // +- DefineExpr + // \- ApplyExpr FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -51,10 +55,14 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DUniqueString.tseq", typeseq::id())); log && log(xtag("DDefineExpr.tseq", typeseq::id())); log && log(xtag("DVariable.tseq", typeseq::id())); log && log(xtag("DConstant.tseq", typeseq::id())); + log && log(xtag("DApplyExpr.tseq", typeseq::id())); log && log(xtag("AExpression.tqseq", typeseq::id())); diff --git a/xo-procedure2/idl/Procedure.json5 b/xo-procedure2/idl/Procedure.json5 index f26a4e56..91c8bdf3 100644 --- a/xo-procedure2/idl/Procedure.json5 +++ b/xo-procedure2/idl/Procedure.json5 @@ -1,3 +1,7 @@ +// can regenerate downstream .*pp files with either: +// cmake --build -- xo-procedure2-facet-procedure +// cmake --build -- xo-procedure2-genfacet-all + { mode: "facet", // includes in ASyntaxStateMachine.hpp @@ -56,6 +60,7 @@ doc: ["invoke procedure; assume arguments satisfy type system" ], return_type: "obj", args: [ + {type: "obj", name: "rcx"}, {type: "const DArray *", name: "args"}, ] } diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp index cf913a15..afd2ada2 100644 --- a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp +++ b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp @@ -19,43 +19,49 @@ namespace xo { namespace scm { - /** @brief Extract return type and argument types from a function type. - * - * Primary template (undefined) - specializations handle specific cases + namespace detail { + /** @brief Extract return type and argument types from a function type. + * + * Primary template (undefined) - specializations handle specific cases + **/ + template + struct PmFnTraits; + + /** specialization for function pointers **/ + template + struct PmFnTraits rcx, Args...)> { + /** function return type **/ + using return_type = R; + /** tuple type for function arguments (except for runtime context) **/ + using args_tuple = std::tuple; + /** number of arguments (except for runtime context) **/ + static constexpr std::size_t n_args = sizeof...(Args); + + /** arg_type is the type of the i'th argument to Fn. + * (starting from argument after runtime context) + **/ + template + using arg_type = std::tuple_element_t; + }; + + /** specialization for function references **/ + template + struct PmFnTraits, Args...)> : PmFnTraits, Args...)> {}; + + /** specialization for plain function types **/ + template + struct PmFnTraits, Args...)> : PmFnTraits, Args...)> {}; + } + + /** @brief Schematika primitive with fixed number of arguments **/ - template - struct FnTraits; - - /** specialization for function pointers **/ - template - struct FnTraits { - /** function return type **/ - using return_type = R; - /** tuple type for function arguments **/ - using args_tuple = std::tuple; - /** number of arguments **/ - static constexpr std::size_t n_args = sizeof...(Args); - - /** arg_type is the type of the i'th argument to Fn **/ - template - using arg_type = std::tuple_element_t; - }; - - /** specialization for function references **/ - template - struct FnTraits : FnTraits {}; - - /** specialization for plain function types **/ - template - struct FnTraits : FnTraits {}; - template class Primitive { public: using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using DArray = xo::scm::DArray; - using Traits = FnTraits; + using Traits = detail::PmFnTraits; public: Primitive(std::string_view name, Fn fn) : name_{name}, fn_{fn} {} @@ -63,14 +69,15 @@ namespace xo { bool is_nary() const noexcept { return false; } static constexpr std::int32_t n_args() noexcept { return Traits::n_args; } - obj apply_nocheck(const DArray * args) { - return _apply_nocheck(args, + obj apply_nocheck(obj rcx, const DArray * args) { + return _apply_nocheck(rcx, args, std::make_index_sequence{}); } private: template - obj _apply_nocheck(const DArray * args, + obj _apply_nocheck(obj rcx, + const DArray * args, std::index_sequence) { using xo::facet::FacetRegistry; @@ -80,12 +87,11 @@ namespace xo { assert(args); assert(args->size() > 0); - obj rcx - = FacetRegistry::instance().variant(args->at(0)); obj mm = rcx.allocator(); R result - = fn_(GCObjectConversion>::from_gco(mm, args->at(Is))... ); + = fn_(rcx, + GCObjectConversion>::from_gco(mm, args->at(Is))... ); return GCObjectConversion::to_gco(mm, result); } diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive_gco_2_gco_gco.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive_gco_2_gco_gco.hpp index 24ad3b41..78dd26b9 100644 --- a/xo-procedure2/include/xo/procedure2/DPrimitive_gco_2_gco_gco.hpp +++ b/xo-procedure2/include/xo/procedure2/DPrimitive_gco_2_gco_gco.hpp @@ -1,3 +1,8 @@ +/** @file DPrimitive_gco_2_gco_gco.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + #pragma once #include @@ -13,3 +18,5 @@ namespace xo { obj)>; } } + +/* end DPrimitive_gco_2_gco_gco.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/Procedure.hpp b/xo-procedure2/include/xo/procedure2/Procedure.hpp index 8b2cd91a..784608ed 100644 --- a/xo-procedure2/include/xo/procedure2/Procedure.hpp +++ b/xo-procedure2/include/xo/procedure2/Procedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp index 2e8300ed..3241451b 100644 --- a/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp index 1be5e0d1..63a4da9b 100644 --- a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -56,7 +56,7 @@ public: // nonconst methods /** invoke procedure; assume arguments satisfy type system **/ - virtual obj apply_nocheck(Opaque data, const DArray * args) = 0; + virtual obj apply_nocheck(Opaque data, obj rcx, const DArray * args) = 0; ///@} }; /*AProcedure*/ diff --git a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp index 42030d9d..4e96bc8f 100644 --- a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp index 3f66fcd5..5d711d4c 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -60,7 +60,7 @@ namespace scm { [[noreturn]] std::int32_t n_args(Copaque) const noexcept override { _fatal(); } // nonconst methods - [[noreturn]] obj apply_nocheck(Opaque, const DArray *) override; + [[noreturn]] obj apply_nocheck(Opaque, obj, const DArray *) override; ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp index 4b4351dd..11f2cd60 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -57,7 +57,7 @@ namespace xo { // non-const methods /** invoke procedure; assume arguments satisfy type system **/ - static obj apply_nocheck(DPrimitive_gco_2_gco_gco & self, const DArray * args); + static obj apply_nocheck(DPrimitive_gco_2_gco_gco & self, obj rcx, const DArray * args); ///@} }; diff --git a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp index adf4995d..4f84652e 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IProcedure_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -50,8 +50,8 @@ namespace scm { } // non-const methods - obj apply_nocheck(Opaque data, const DArray * args) override { - return I::apply_nocheck(_dcast(data), args); + obj apply_nocheck(Opaque data, obj rcx, const DArray * args) override { + return I::apply_nocheck(_dcast(data), rcx, args); } ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp index 419d45cc..1e5f97c0 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp index e9f5512e..cd71b73e 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp index 9fff0c6c..93599ae3 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -56,8 +56,8 @@ public: } // non-const methods (still const in router!) - obj apply_nocheck(const DArray * args) { - return O::iface()->apply_nocheck(O::data(), args); + obj apply_nocheck(obj rcx, const DArray * args) { + return O::iface()->apply_nocheck(O::data(), rcx, args); } ///@} diff --git a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp index 06b093de..b06227c8 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/src/procedure2/IProcedure_Any.cpp b/xo-procedure2/src/procedure2/IProcedure_Any.cpp index 79b3b778..d28d98ee 100644 --- a/xo-procedure2/src/procedure2/IProcedure_Any.cpp +++ b/xo-procedure2/src/procedure2/IProcedure_Any.cpp @@ -35,7 +35,7 @@ IProcedure_Any::_valid // nonconst methods auto -IProcedure_Any::apply_nocheck(Opaque, const DArray *) -> obj +IProcedure_Any::apply_nocheck(Opaque, obj, const DArray *) -> obj { _fatal(); } diff --git a/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp b/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp index 5266477c..67e73c97 100644 --- a/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp +++ b/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -28,9 +28,9 @@ namespace xo { } auto - IProcedure_DPrimitive_gco_2_gco_gco::apply_nocheck(DPrimitive_gco_2_gco_gco & self, const DArray * args) -> obj + IProcedure_DPrimitive_gco_2_gco_gco::apply_nocheck(DPrimitive_gco_2_gco_gco & self, obj rcx, const DArray * args) -> obj { - return self.apply_nocheck(args); + return self.apply_nocheck(rcx, args); } } /*namespace scm*/ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 7258731c..31b3a55d 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -100,14 +100,12 @@ namespace xo { optype op); static void start(DArena & parser_mm, - obj valex, + obj lhs, ParserStateMachine * p_psm); - -#ifdef NOT_YET - static void start(rp valex, + static void start(DArena & parsermm, + obj lhs, optype optype, - parserstatemachine * p_psm); -#endif + ParserStateMachine * p_psm); syntaxstatetype ssm_type() const noexcept; @@ -147,6 +145,8 @@ namespace xo { ParserStateMachine * p_psm); void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); + void on_operator_token(const Token & tk, + ParserStateMachine * p_psm); void on_string_token(const Token & tk, ParserStateMachine * p_psm); void on_f64_token(const Token & tk, @@ -207,17 +207,6 @@ namespace xo { void print(std::ostream & os) const override; - - private: - /** assemble expression representing - * value of - * @code - * f(lhs_, rhs_) - * @endcode - * - * where f determined by @ref op_type_ - **/ - obj assemble_expr(ParserStateMachine * p_psm); #endif private: @@ -227,7 +216,14 @@ namespace xo { /** infix operator, if supplied **/ optype op_type_ = optype::invalid; - /** populate an expression here, following infix operator */ + /** populate an expression here, that follows an infix operator. + * + * Note this may not resolve immediately. + * Consider input + * 5 + 6 + * Need to know if following token is * + * before deciding if 6 belongs to addition 5 + 6 + **/ obj rhs_; }; } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index fc5dbe08..49e95296 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -180,12 +180,11 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: case tokentype::N: + p_psm->illegal_input_on_token("DExpectExprSsm::on_token", + tk, + this->get_expect_str()); break; } - - p_psm->illegal_input_on_token("DExpectExprSsm::on_token", - tk, - this->get_expect_str()); } void diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 85f7b1d3..830dd30e 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -5,6 +5,15 @@ #include "DProgressSsm.hpp" #include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" + +#include "DExpectExprSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" + +#ifdef NOT_YET +#include "DApplySsm.hpp" +#include "ssm/ISyntaxStateMachine_DApplySsm.hpp" +#endif + #include #include #include @@ -67,6 +76,7 @@ namespace xo { return "???"; } + /** higher-precedence operators bind before lower-preference operators **/ int precedence(optype x) { switch (x) { @@ -97,6 +107,40 @@ namespace xo { return 0; } + namespace { + optype + tk2op(const tokentype & tktype) { + switch (tktype) { + case tokentype::tk_assign: + return optype::op_assign; + case tokentype::tk_plus: + return optype::op_add; + case tokentype::tk_minus: + return optype::op_subtract; + case tokentype::tk_star: + return optype::op_multiply; + case tokentype::tk_slash: + return optype::op_divide; + case tokentype::tk_cmpeq: + return optype::op_equal; + case tokentype::tk_cmpne: + return optype::op_not_equal; + case tokentype::tk_leftangle: + return optype::op_less; + case tokentype::tk_lessequal: + return optype::op_less_equal; + case tokentype::tk_rightangle: + return optype::op_great; + case tokentype::tk_greatequal: + return optype::op_great_equal; + default: + assert(false); + return optype::invalid; + } + return optype::invalid; + } + } + DProgressSsm * DProgressSsm::make(DArena & mm, obj lhs, @@ -112,26 +156,26 @@ namespace xo { void DProgressSsm::start(DArena & parser_mm, - obj valex, + obj lhs, + optype op, ParserStateMachine * p_psm) { DProgressSsm * progress_ssm - = DProgressSsm::make(parser_mm, valex, optype::invalid); + = DProgressSsm::make(parser_mm, lhs, op); - obj ssm - = with_facet::mkobj(progress_ssm); + obj ssm(progress_ssm); p_psm->push_ssm(ssm); } -#ifdef NOT_YET void - progress_xs::start(rp valex, optype op, parserstatemachine * p_psm) { - p_psm->push_exprstate(progress_xs::make(valex, op)); + DProgressSsm::start(DArena & parser_mm, + obj lhs, + ParserStateMachine * p_psm) + { + start(parser_mm, lhs, optype::invalid, p_psm); } -#endif - DProgressSsm::DProgressSsm(obj valex, optype op) : lhs_{valex}, @@ -225,12 +269,11 @@ namespace xo { case tokentype::tk_plus: case tokentype::tk_minus: break; + case tokentype::tk_star: -#ifdef NOT_YET this->on_operator_token(tk, p_psm); return; -#endif - break; + case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: @@ -295,6 +338,75 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_operator_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (op_type_ == optype::invalid) { + // tk is the operator this instance was waiting for + this->op_type_ = tk2op(tk.tk_type()); + + DExpectExprSsm::start(p_psm->parser_alloc(), p_psm); + return; + } else if (rhs_) { + optype op_type2 = tk2op(tk.tk_type()); + + /* already have {lhs_, op_type_, rhs_}, + * with incoming op_type2 operator decides whether to parse like + * (lhs_, op_type_, rhs_) op_type2 ... + * or + * (lhs_, op_type_, (rhs_ op_type2 ...)) + */ + + if (precedence(op_type_) >= precedence(op_type2)) { + /* associate to the left + * + * parse like + * a + b - ... (a + b) - ... + * a * b - ... (a * b) - ... + */ + + auto lhs2 = this->assemble_expr(p_psm); + + p_psm->pop_ssm(); + + DProgressSsm::start(p_psm->parser_alloc(), + lhs2, + op_type2, + p_psm); + return; + } else { + /* associate to the right + * + * parse like + * a + b * ... (a + (b * ...)) + */ + + p_psm->pop_ssm(); + + /* (a + ..) */ + DProgressSsm::start(p_psm->parser_alloc(), + lhs_, + op_type_, + p_psm); + DExpectExprSsm::start(p_psm->parser_alloc(), + p_psm); + /* (b * ..) */ + DProgressSsm::start(p_psm->parser_alloc(), + rhs_, + op_type2, + p_psm); + DExpectExprSsm::start(p_psm->parser_alloc(), + p_psm); + return; + } + } + + p_psm->illegal_input_on_token("DProgressSsm::on_operator_token", + tk, + this->get_expect_str()); + } + void DProgressSsm::on_string_token(const Token & tk, ParserStateMachine * p_psm) @@ -905,112 +1017,10 @@ namespace xo { * { n * n } */ } +#endif - namespace { - optype - tk2op(const tokentype & tktype) { - switch (tktype) { - case tokentype::tk_assign: - return optype::op_assign; - case tokentype::tk_plus: - return optype::op_add; - case tokentype::tk_minus: - return optype::op_subtract; - case tokentype::tk_star: - return optype::op_multiply; - case tokentype::tk_slash: - return optype::op_divide; - case tokentype::tk_cmpeq: - return optype::op_equal; - case tokentype::tk_cmpne: - return optype::op_not_equal; - case tokentype::tk_leftangle: - return optype::op_less; - case tokentype::tk_lessequal: - return optype::op_less_equal; - case tokentype::tk_rightangle: - return optype::op_great; - case tokentype::tk_greatequal: - return optype::op_great_equal; - default: - assert(false); - return optype::invalid; - } - return optype::invalid; - } - } - - void - progress_xs::on_operator_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - constexpr const char * c_self_name = "progress_xs::on_operator_token"; - - if (op_type_ == optype::invalid) { - this->op_type_ = tk2op(tk.tk_type()); - - /* infix operator must be followed by non-empty expression */ - expect_expr_xs::start(p_psm); - } else if (rhs_) { - /* already have complete expression stashed. - * behavior depends on operator precedence for tk with stored operator - * this->op_type_ - */ - optype op2 = tk2op(tk.tk_type()); - - if (precedence(op2) <= precedence(this->op_type_)) { - /* e.g. - * 6.2 * 4.9 + ... - * - * in stack: - * 1. progress_xs lhs=6.2, op=*, rhs=4.9 - * - * out stack - * 1. progress_xs lhs=apply(*,6.2,4.9), op=+ - */ - - /* 1. instantiate expression for *this */ - auto expr = this->assemble_expr(p_psm); - - /* 2. remove from stack */ - std::unique_ptr self = p_psm->pop_exprstate(); - - /* 3. replace with new progress_xs: */ - progress_xs::start(expr, op2, p_psm); - - /* infix operator must be followed by non-empty expression */ - expect_expr_xs::start(p_psm); - } else { - /* e.g. - * 6.2 + 4.9 * ... - * - * in stack: - * 1. progress_xs lhs=6.2, op=+, rhs=4.9 - * - * out stack: - * 1. progress_xs lhs=6.2, op=+ - * 2. expect_rhs_expression - * 3. progress_xs lhs=4.9, op=* - * 4. expect_rhs_expression - */ - - std::unique_ptr self = p_psm->pop_exprstate(); - - /* 1. replace with nested incomplete infix exprs */ - progress_xs::start(lhs_, op_type_, p_psm); - expect_expr_xs::start(p_psm); - progress_xs::start(rhs_, op2, p_psm); - expect_expr_xs::start(p_psm); - } - - } else { - throw std::runtime_error(tostr(c_self_name, - ": expected expression following operator", - xtag("tk", tk))); - } - } +#ifdef OBSOLETE + //void progress_xs::on_operator_token(const token_type & tk, parserstatemachine * p_psm) void progress_xs::on_bool_token(const token_type & tk, @@ -1163,7 +1173,25 @@ namespace xo { case optype::op_great_equal: case optype::op_add: case optype::op_subtract: + break; + case optype::op_multiply: +#ifdef NOT_YET + { + /* note: + * 1. don't assume we know lhs_ / rhs_ value types yet. + * perhaps have expression like + * f(..) * g(..) + * where f is the function that contains current ssm. + * 2. consequence: we need representation for + * polymorphic multiply on unknown numeric arguments. + */ + + DApplyExpr::make2(); + } +#endif + + break; case optype::op_divide: // TODO: implement binary operator expression assembly break; From 826879c517fbc82aeddc0a1274db68f2d6c7a0cf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 15:33:58 -0500 Subject: [PATCH 079/258] xo-expression2: + DConstant utest --- .../include/xo/expression2/DConstant.hpp | 12 +- xo-expression2/src/expression2/DConstant.cpp | 11 +- xo-expression2/utest/CMakeLists.txt | 1 + xo-expression2/utest/DConstant.test.cpp | 232 ++++++++++++++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 2 +- xo-reader2/src/reader2/DExprSeqState.cpp | 12 +- xo-reader2/src/reader2/DProgressSsm.cpp | 3 + 7 files changed, 261 insertions(+), 12 deletions(-) create mode 100644 xo-expression2/utest/DConstant.test.cpp diff --git a/xo-expression2/include/xo/expression2/DConstant.hpp b/xo-expression2/include/xo/expression2/DConstant.hpp index 81561e68..50f0e38f 100644 --- a/xo-expression2/include/xo/expression2/DConstant.hpp +++ b/xo-expression2/include/xo/expression2/DConstant.hpp @@ -5,6 +5,7 @@ #pragma once +#include "Expression.hpp" #include "TypeRef.hpp" #include "exprtype.hpp" #include @@ -27,12 +28,19 @@ namespace xo { public: explicit DConstant(obj value) noexcept; + /** create isntance + * @p mm memory allocator + * @p value literal constant + **/ + static obj make(obj mm, + obj value); + /** create instance * @p mm memory allocator * @p value literal constant **/ - static DConstant * make(obj mm, - obj value); + static DConstant * _make(obj mm, + obj value); bool is_resolved() const noexcept { return typeref_.is_resolved(); } diff --git a/xo-expression2/src/expression2/DConstant.cpp b/xo-expression2/src/expression2/DConstant.cpp index f65ba013..f03fe625 100644 --- a/xo-expression2/src/expression2/DConstant.cpp +++ b/xo-expression2/src/expression2/DConstant.cpp @@ -4,10 +4,12 @@ **/ #include "DConstant.hpp" +#include "detail/IExpression_DConstant.hpp" #include "TypeDescr.hpp" #include #include #include +#include #include #include #include @@ -38,9 +40,16 @@ namespace xo { } } - DConstant * + obj DConstant::make(obj mm, obj value) + { + return obj(_make(mm, value)); + } + + DConstant * + DConstant::_make(obj mm, + obj value) { void * mem = mm.alloc(typeseq::id(), sizeof(DConstant)); diff --git a/xo-expression2/utest/CMakeLists.txt b/xo-expression2/utest/CMakeLists.txt index 2b8bceec..aefc8c8c 100644 --- a/xo-expression2/utest/CMakeLists.txt +++ b/xo-expression2/utest/CMakeLists.txt @@ -5,6 +5,7 @@ set(UTEST_SRCS expression2_utest_main.cpp StringTable.test.cpp X1Collector.test.cpp + DConstant.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-expression2/utest/DConstant.test.cpp b/xo-expression2/utest/DConstant.test.cpp new file mode 100644 index 00000000..ddff5b20 --- /dev/null +++ b/xo-expression2/utest/DConstant.test.cpp @@ -0,0 +1,232 @@ +/** @file DConstant.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_expression2.hpp" +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +namespace ut { + using xo::S_expression2_tag; + using xo::scm::DConstant; + using xo::scm::DFloat; + using xo::scm::DInteger; + using xo::scm::AExpression; + using xo::mm::CollectorTypeRegistry; + using xo::mm::AAllocator; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::mm::DX1Collector; + using xo::mm::CollectorConfig; + using xo::mm::ArenaConfig; + using xo::print::APrintable; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::facet::obj; + using xo::facet::typeseq; + using xo::reflect::Reflect; + using xo::InitEvidence; + using xo::InitSubsys; + using xo::scope; + + // Ensure subsystem initialized before tests + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DConstant-init", "[expression2][DConstant]") + { + // Verify subsystem initialization succeeded + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DConstant-from-float", "[expression2][DConstant]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dconstant_float_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + // Box a float value + obj fval = DFloat::box(alloc, 3.14); + REQUIRE(fval.data() != nullptr); + + // Create DConstant from the boxed float + auto expr = DConstant::make(alloc, fval); + REQUIRE(expr.data() != nullptr); + + // Verify expression type + REQUIRE(expr.data()->extype() == xo::scm::exprtype::constant); + + // Verify valuetype is double (DFloat::value_type) + REQUIRE(expr.data()->valuetype() == Reflect::require()); + + // Verify value is accessible + REQUIRE(expr.data()->value().data() != nullptr); + } + + TEST_CASE("DConstant-from-integer", "[expression2][DConstant]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dconstant_int_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + // Box an integer value + obj ival = DInteger::box(alloc, 42); + REQUIRE(ival.data() != nullptr); + + // Create DConstant from the boxed integer + auto expr = DConstant::make(alloc, ival); + REQUIRE(expr.data() != nullptr); + + // Verify expression type + REQUIRE(expr.data()->extype() == xo::scm::exprtype::constant); + + // Verify valuetype is long (DInteger::value_type) + REQUIRE(expr.data()->valuetype() == Reflect::require()); + + // Verify value is accessible + REQUIRE(expr.data()->value().data() != nullptr); + } + + TEST_CASE("DConstant-pretty-float", "[expression2][DConstant][pp]") + { + scope log(XO_DEBUG(true)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dconstant_pp_float_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + // Box a float value + obj fval = DFloat::box(alloc, 2.718); + auto expr = DConstant::make(alloc, fval); + REQUIRE(expr.data() != nullptr); + + // Pretty print + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj expr_pr(expr.data()); + pps.pretty(expr_pr); + + std::string output = ss.str(); + + log && log(output); + + // Output should contain "DConstant" struct name + CHECK(output.find("DConstant") != std::string::npos); + } + + TEST_CASE("DConstant-pretty-integer", "[expression2][DConstant][pp]") + { + scope log(XO_DEBUG(false)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dconstant_pp_int_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + // Box an integer value + obj ival = DInteger::box(alloc, 123); + auto expr = DConstant::make(alloc, ival); + REQUIRE(expr.data() != nullptr); + + // Pretty print + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj expr_pr(expr.data()); + pps.pretty(expr_pr); + + std::string output = ss.str(); + + log && log(output); + + // Output should contain "DConstant" struct name + CHECK(output.find("DConstant") != std::string::npos); + } +} + +/* end DConstant.test.cpp */ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 49e95296..66eb41cd 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -248,7 +248,7 @@ namespace xo { auto f64o = DFloat::box(p_psm->expr_alloc(), tk.f64_value()); - auto expr = with_facet::mkobj(DConstant::make(p_psm->expr_alloc(), f64o)); + auto expr = DConstant::make(p_psm->expr_alloc(), f64o); // DProgressSsm responsible for resolving cases like // 1.9, diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index d6037908..e926565d 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -290,8 +290,7 @@ namespace xo { DString * dstr = DString::from_cstr(p_psm->expr_alloc(), tk.text().c_str()); obj str(dstr); - auto * dconst = DConstant::make(p_psm->expr_alloc(), str); - obj expr(dconst); + obj expr = DConstant::make(p_psm->expr_alloc(), str); DProgressSsm::start(p_psm->parser_alloc(), expr, @@ -319,8 +318,7 @@ namespace xo { { auto f64o = DFloat::box(p_psm->expr_alloc(), tk.f64_value()); - auto * dconst = DConstant::make(p_psm->expr_alloc(), f64o); - auto expr = with_facet::mkobj(dconst); + auto expr = DConstant::make(p_psm->expr_alloc(), f64o); DProgressSsm::start(p_psm->parser_alloc(), expr, @@ -348,8 +346,7 @@ namespace xo { { auto i64o = DFloat::box(p_psm->expr_alloc(), tk.i64_value()); - auto * dconst = DConstant::make(p_psm->expr_alloc(), i64o); - auto expr = with_facet::mkobj(dconst); + auto expr = DConstant::make(p_psm->expr_alloc(), i64o); DProgressSsm::start(p_psm->parser_alloc(), expr, @@ -377,8 +374,7 @@ namespace xo { { auto dvalue = DBoolean::box(p_psm->expr_alloc(), tk.bool_value()); - auto * dconst = DConstant::make(p_psm->expr_alloc(), dvalue); - auto expr = with_facet::mkobj(dconst); + auto expr = DConstant::make(p_psm->expr_alloc(), dvalue); DProgressSsm::start(p_psm->parser_alloc(), expr, diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 830dd30e..cfed858f 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -9,6 +9,9 @@ #include "DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" + +#include +#include #ifdef NOT_YET #include "DApplySsm.hpp" #include "ssm/ISyntaxStateMachine_DApplySsm.hpp" From d7e2ea79b87a7577ddf44e60e10e4f30479d592b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 15:34:53 -0500 Subject: [PATCH 080/258] xo-procedure2: + GCObject support for Primitive + misc --- CMakeLists.txt | 2 +- xo-procedure2/CMakeLists.txt | 12 ++++ .../cmake/xo_procedure2Config.cmake.in | 1 + .../IGCObject_DPrimitive_gco_2_gco_gco.json5 | 16 +++++ .../include/xo/procedure2/DPrimitive.hpp | 33 +++++++++ .../IGCObject_DPrimitive_gco_2_gco_gco.hpp | 67 +++++++++++++++++++ .../include/xo/procedure2/init_primitives.hpp | 7 ++ xo-procedure2/src/procedure2/CMakeLists.txt | 1 + .../IGCObject_DPrimitive_gco_2_gco_gco.cpp | 39 +++++++++++ 9 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 create mode 100644 xo-procedure2/include/xo/procedure2/detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp create mode 100644 xo-procedure2/src/procedure2/IGCObject_DPrimitive_gco_2_gco_gco.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a0e0b1df..592bf697 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,9 +102,9 @@ add_subdirectory(xo-alloc2) # experiment w/ facet object model add_subdirectory(xo-gc) add_subdirectory(xo-object) add_subdirectory(xo-object2) # experiment w/ facet object model +add_subdirectory(xo-procedure2) # schematika procedure abstraction + runtime context (fomo) add_subdirectory(xo-ordinaltree) # -add_subdirectory(xo-procedure2) # schematika procedure abstraction + runtime context (fomo) add_subdirectory(xo-tokenizer2) # schematika tokenizer (fomo) add_subdirectory(xo-expression2) # schematika expressions (fomo) add_subdirectory(xo-reader2) # schematika expression parser (fomo) diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt index acb0bad9..be7909a5 100644 --- a/xo-procedure2/CMakeLists.txt +++ b/xo-procedure2/CMakeLists.txt @@ -53,6 +53,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/procedure2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-procedure2-facetimpl-gcobject-primitive_gco_2_gco_gco + FACET_PKG xo_gc + FACET GCObject + REPR Primitive_gco_2_gco_gco + INPUT idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 + OUTPUT_HPP_DIR include/xo/procedure2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/procedure2 +) + add_subdirectory(src/procedure2) #add_subdirectory(utest) diff --git a/xo-procedure2/cmake/xo_procedure2Config.cmake.in b/xo-procedure2/cmake/xo_procedure2Config.cmake.in index 0229c033..867a3535 100644 --- a/xo-procedure2/cmake/xo_procedure2Config.cmake.in +++ b/xo-procedure2/cmake/xo_procedure2Config.cmake.in @@ -6,6 +6,7 @@ include(CMakeFindDependencyMacro) # must coordinate with xo_dependency() calls # in CMakeLists.txt # +find_dependency(xo_object2) find_dependency(xo_gc) find_dependency(subsys) diff --git a/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 new file mode 100644 index 00000000..b2fb4014 --- /dev/null +++ b/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + includes: [ + // + "", + "", + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCobject interface for Primitive (gco x gco) -> gco", + using_doxygen: true, + repr: "DPrimitive_gco_2_gco_gco", + doc: [ "implement AGCObject for DPrimitive (gco x gco) -> gco" ], +} diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp index afd2ada2..c225246d 100644 --- a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp +++ b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp @@ -58,6 +58,7 @@ namespace xo { template class Primitive { public: + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using DArray = xo::scm::DArray; @@ -74,6 +75,13 @@ namespace xo { std::make_index_sequence{}); } + /** @defgroup scm-primitive-gcobject-facet **/ + ///@{ + std::size_t shallow_size() const noexcept; + Primitive * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} + private: template obj _apply_nocheck(obj rcx, @@ -103,6 +111,31 @@ namespace xo { Fn fn_; }; /*Primitive*/ + template + std::size_t + Primitive::shallow_size() const noexcept { + return sizeof(*this); + } + + template + Primitive * + Primitive::shallow_copy(obj mm) const noexcept { + void * mem = mm.alloc_copy((std::byte *)this); + + if (mem) { + return new (mem) Primitive(*this); + } + + return nullptr; + } + + template + std::size_t + Primitive::forward_children(obj) noexcept { + // Primitive holds no GC refs (just string_view + function pointer) + return this->shallow_size(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-procedure2/include/xo/procedure2/detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp b/xo-procedure2/include/xo/procedure2/detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp new file mode 100644 index 00000000..344aa6c1 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DPrimitive_gco_2_gco_gco.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DPrimitive_gco_2_gco_gco.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DPrimitive_gco_2_gco_gco.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DPrimitive_gco_2_gco_gco.hpp" + +namespace xo { namespace scm { class IGCObject_DPrimitive_gco_2_gco_gco; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DPrimitive_gco_2_gco_gco + **/ + class IGCObject_DPrimitive_gco_2_gco_gco { + public: + /** @defgroup scm-gcobject-dprimitive_gco_2_gco_gco-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dprimitive_gco_2_gco_gco-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DPrimitive_gco_2_gco_gco & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DPrimitive_gco_2_gco_gco & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DPrimitive_gco_2_gco_gco & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-procedure2/include/xo/procedure2/init_primitives.hpp b/xo-procedure2/include/xo/procedure2/init_primitives.hpp index 5e2d08e8..48b733df 100644 --- a/xo-procedure2/include/xo/procedure2/init_primitives.hpp +++ b/xo-procedure2/include/xo/procedure2/init_primitives.hpp @@ -7,12 +7,19 @@ namespace xo { namespace scm { +/** TODO: move this into xo-reader2 ? **/ + #ifdef NOT_YET using Primitive_f64_1_f64 = Primitive; using Primitive_f64_2_f64_f64 = Primitive; #endif struct Primitives { + /** polymorphich multiply + * + * TODO: this will want to move to xo-numeric/ + * so we can dispatch on vector, matrix, function types + **/ static DPrimitive_gco_2_gco_gco s_mul_gco_gco_pm; #ifdef NOT_YET diff --git a/xo-procedure2/src/procedure2/CMakeLists.txt b/xo-procedure2/src/procedure2/CMakeLists.txt index 11a9c305..c127b760 100644 --- a/xo-procedure2/src/procedure2/CMakeLists.txt +++ b/xo-procedure2/src/procedure2/CMakeLists.txt @@ -7,6 +7,7 @@ set(SELF_SRCS DPrimitive.cpp IRuntimeContext_Any.cpp IProcedure_Any.cpp + IGCObject_DPrimitive_gco_2_gco_gco.cpp IProcedure_DPrimitive_gco_2_gco_gco.cpp # Add source files here, e.g.: # procedure2.cpp diff --git a/xo-procedure2/src/procedure2/IGCObject_DPrimitive_gco_2_gco_gco.cpp b/xo-procedure2/src/procedure2/IGCObject_DPrimitive_gco_2_gco_gco.cpp new file mode 100644 index 00000000..bd88e9ff --- /dev/null +++ b/xo-procedure2/src/procedure2/IGCObject_DPrimitive_gco_2_gco_gco.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DPrimitive_gco_2_gco_gco.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DPrimitive_gco_2_gco_gco.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DPrimitive_gco_2_gco_gco.json5] +**/ + +#include "detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DPrimitive_gco_2_gco_gco::shallow_size(const DPrimitive_gco_2_gco_gco & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DPrimitive_gco_2_gco_gco::shallow_copy(const DPrimitive_gco_2_gco_gco & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DPrimitive_gco_2_gco_gco::forward_children(DPrimitive_gco_2_gco_gco & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DPrimitive_gco_2_gco_gco.cpp */ \ No newline at end of file From 3a6992b6bd3c346285ebd3b26d63ae5038fda628 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 15:35:21 -0500 Subject: [PATCH 081/258] xo-procedure2: export cmake config --- xo-procedure2/src/procedure2/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xo-procedure2/src/procedure2/CMakeLists.txt b/xo-procedure2/src/procedure2/CMakeLists.txt index c127b760..d460e2db 100644 --- a/xo-procedure2/src/procedure2/CMakeLists.txt +++ b/xo-procedure2/src/procedure2/CMakeLists.txt @@ -27,4 +27,12 @@ xo_dependency(${SELF_LIB} xo_gc) xo_dependency(${SELF_LIB} subsys) #xo_dependency(${SELF_LIB} xo_indentlog) +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +# ---------------------------------------------------------------- +# docs targets depend on other library/utest/exec targets above, +# --> must come after them. +# +#add_subdirectory(docs) + # end src/CMakeLists.txt From 7dab46a13a359339e1686cf1eeb9763f96b5686d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 15:45:22 -0500 Subject: [PATCH 082/258] xo-reader2: + missing subsystem deps --- xo-reader2/cmake/xo_reader2Config.cmake.in | 2 ++ xo-reader2/src/reader2/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+) diff --git a/xo-reader2/cmake/xo_reader2Config.cmake.in b/xo-reader2/cmake/xo_reader2Config.cmake.in index 2b36efff..ed161c20 100644 --- a/xo-reader2/cmake/xo_reader2Config.cmake.in +++ b/xo-reader2/cmake/xo_reader2Config.cmake.in @@ -6,9 +6,11 @@ include(CMakeFindDependencyMacro) # must coordinate with xo_dependency() calls # in CMakeLists.txt # +find_dependency(xo_procedure2) find_dependency(xo_gc) find_dependency(xo_tokenizer2) find_dependency(xo_expression2) +find_dependency(subsys) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") check_required_components("@PROJECT_NAME@") diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 37dda298..e18cce73 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -45,6 +45,7 @@ set(SELF_SRCS xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) # note: deps here must also appear in cmake/xo_expression2Config.cmake.in +xo_dependency(${SELF_LIB} xo_procedure2) xo_dependency(${SELF_LIB} xo_gc) xo_dependency(${SELF_LIB} xo_tokenizer2) xo_dependency(${SELF_LIB} xo_expression2) From 0d23fa97b8d3a8661a9d6829ea14a310e02250e3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 15:45:40 -0500 Subject: [PATCH 083/258] xo-expression2: + DApplyExpr::make --- xo-expression2/src/expression2/DApplyExpr.cpp | 32 +++++++++++++++++-- xo-reader2/src/reader2/DProgressSsm.cpp | 28 ++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/xo-expression2/src/expression2/DApplyExpr.cpp b/xo-expression2/src/expression2/DApplyExpr.cpp index ce5e1951..ffc6372a 100644 --- a/xo-expression2/src/expression2/DApplyExpr.cpp +++ b/xo-expression2/src/expression2/DApplyExpr.cpp @@ -3,8 +3,9 @@ * @author Roland Conybeare, Jan 2026 **/ -#include "DApplyExpr.hpp" #include "Expression.hpp" +#include "DApplyExpr.hpp" +#include "detail/IExpression_DApplyExpr.hpp" #include #include @@ -15,7 +16,34 @@ namespace xo { using xo::mm::AGCObject; namespace scm { - /* incomplete! */ + obj + DApplyExpr::make2(obj mm, + TypeRef typeref, + obj fn_expr, + obj arg1, + obj arg2) + { + return obj + (DApplyExpr::_make2(mm, typeref, fn_expr, arg1, arg2)); + } + + DApplyExpr * + DApplyExpr::_make2(obj mm, + TypeRef typeref, + obj fn_expr, + obj arg1, + obj arg2) + { + DApplyExpr * result + = DApplyExpr::scaffold(mm, typeref, fn_expr, 2 /*n_args*/); + + result->assign_arg(0, arg1); + result->assign_arg(1, arg2); + + return result; + } + + /* incomplete, in the sense that does not populate args_[] */ DApplyExpr::DApplyExpr(TypeRef typeref, obj fn_expr, size_type n_args) : typeref_{typeref}, diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index cfed858f..cc0fc14b 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -9,9 +9,15 @@ #include "DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" +#include +#include #include #include + +#include // for xo::scm::Primitives +#include + #ifdef NOT_YET #include "DApplySsm.hpp" #include "ssm/ISyntaxStateMachine_DApplySsm.hpp" @@ -1179,20 +1185,36 @@ namespace xo { break; case optype::op_multiply: -#ifdef NOT_YET { + auto pm_obj = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + + auto fn_expr = DConstant::make(p_psm->expr_alloc(), pm_obj); + /* note: * 1. don't assume we know lhs_ / rhs_ value types yet. * perhaps have expression like * f(..) * g(..) * where f is the function that contains current ssm. + * * 2. consequence: we need representation for * polymorphic multiply on unknown numeric arguments. + * + * 3. TypeRef::dwim(..) is a placeholder. + * Plan to later provide abstract interpreter + * (ie compiler pass :) to drive type inference/unification + * + * 4. Alternatively could supply type-annotation syntax + * so human can assist inference; context here is we want + * to automate the boring stuff */ - DApplyExpr::make2(); + TypeRef tref = TypeRef::dwim + (TypeRef::prefix_type::from_chars("_mul_gco"), + nullptr); + + return DApplyExpr::make2(p_psm->expr_alloc(), + tref, fn_expr, lhs_, rhs_); } -#endif break; case optype::op_divide: From 2671def90348aa8105704c2100ad3c0071c910ff Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 16:05:37 -0500 Subject: [PATCH 084/258] init dep handling for xo-expression2 -> xo-procedure2 --- .../cmake/xo_expression2Config.cmake.in | 2 +- xo-expression2/src/expression2/CMakeLists.txt | 2 +- .../src/expression2/init_expression2.cpp | 4 +-- .../procedure2/procedure2_register_facets.hpp | 17 ++++++++++ .../procedure2/procedure2_register_types.hpp | 17 ++++++++++ xo-procedure2/src/procedure2/CMakeLists.txt | 2 ++ .../src/procedure2/init_procedure2.cpp | 16 +++++++-- .../procedure2/procedure2_register_facets.cpp | 33 +++++++++++++++++++ .../procedure2/procedure2_register_types.cpp | 33 +++++++++++++++++++ 9 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 xo-procedure2/include/xo/procedure2/procedure2_register_facets.hpp create mode 100644 xo-procedure2/include/xo/procedure2/procedure2_register_types.hpp create mode 100644 xo-procedure2/src/procedure2/procedure2_register_facets.cpp create mode 100644 xo-procedure2/src/procedure2/procedure2_register_types.cpp diff --git a/xo-expression2/cmake/xo_expression2Config.cmake.in b/xo-expression2/cmake/xo_expression2Config.cmake.in index c8cfbcad..15ff18ff 100644 --- a/xo-expression2/cmake/xo_expression2Config.cmake.in +++ b/xo-expression2/cmake/xo_expression2Config.cmake.in @@ -8,7 +8,7 @@ include(CMakeFindDependencyMacro) # find_dependency(xo_gc) find_dependency(reflect) -find_dependency(xo_object2) +find_dependency(xo_procedure2) find_dependency(xo_printable2) find_dependency(xo_flatstring) find_dependency(cmake) diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index b8be9468..7a7013de 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -44,7 +44,7 @@ xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 $ # note: deps here must also appear in cmake/xo_expression2Config.cmake.in xo_dependency(${SELF_LIB} xo_gc) xo_dependency(${SELF_LIB} reflect) -xo_dependency(${SELF_LIB} xo_object2) +xo_dependency(${SELF_LIB} xo_procedure2) xo_dependency(${SELF_LIB} xo_printable2) xo_dependency(${SELF_LIB} xo_flatstring) xo_dependency(${SELF_LIB} subsys) diff --git a/xo-expression2/src/expression2/init_expression2.cpp b/xo-expression2/src/expression2/init_expression2.cpp index e975ef99..1ee5ec9e 100644 --- a/xo-expression2/src/expression2/init_expression2.cpp +++ b/xo-expression2/src/expression2/init_expression2.cpp @@ -7,7 +7,7 @@ #include "expression2_register_facets.hpp" #include "expression2_register_types.hpp" -#include +#include #include namespace xo { @@ -29,7 +29,7 @@ namespace xo { InitEvidence retval; /* direct subsystem deps for xo-object2/ */ - retval ^= InitSubsys::require(); + retval ^= InitSubsys::require(); /* xo-expression2/'s own initialization code */ retval ^= Subsystem::provide("expression2", &init); diff --git a/xo-procedure2/include/xo/procedure2/procedure2_register_facets.hpp b/xo-procedure2/include/xo/procedure2/procedure2_register_facets.hpp new file mode 100644 index 00000000..219da3d4 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/procedure2_register_facets.hpp @@ -0,0 +1,17 @@ +/** @file procedure2_register_facets.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + /** Register procedure2 (facet,impl) combinations with FacetRegistry **/ + bool procedure2_register_facets(); + } +} + +/* end procedure2_register_facets.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/procedure2_register_types.hpp b/xo-procedure2/include/xo/procedure2/procedure2_register_types.hpp new file mode 100644 index 00000000..be0170aa --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/procedure2_register_types.hpp @@ -0,0 +1,17 @@ +/** @file procedure2_register_types.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + /** Register gc-aware (AGCObject,DRepr) combinations with garbage collector @p gc **/ + bool procedure2_register_types(obj gc); + } +} + +/* end procedure2_register_types.hpp */ diff --git a/xo-procedure2/src/procedure2/CMakeLists.txt b/xo-procedure2/src/procedure2/CMakeLists.txt index d460e2db..d1699eb0 100644 --- a/xo-procedure2/src/procedure2/CMakeLists.txt +++ b/xo-procedure2/src/procedure2/CMakeLists.txt @@ -4,6 +4,8 @@ set(SELF_LIB xo_procedure2) set(SELF_SRCS init_procedure2.cpp init_primitives.cpp + procedure2_register_types.cpp + procedure2_register_facets.cpp DPrimitive.cpp IRuntimeContext_Any.cpp IProcedure_Any.cpp diff --git a/xo-procedure2/src/procedure2/init_procedure2.cpp b/xo-procedure2/src/procedure2/init_procedure2.cpp index fc316653..aaa6a021 100644 --- a/xo-procedure2/src/procedure2/init_procedure2.cpp +++ b/xo-procedure2/src/procedure2/init_procedure2.cpp @@ -5,16 +5,23 @@ #include "init_procedure2.hpp" #include "init_primitives.hpp" -//#include "procedure2_register_facets.hpp" -//#include "procedure2_register_types.hpp" +#include "procedure2_register_facets.hpp" +#include "procedure2_register_types.hpp" + +#include #include namespace xo { - using xo::scm::Primitives; + using xo::scm::procedure2_register_facets; + using xo::scm::procedure2_register_types; + using xo::mm::CollectorTypeRegistry; void InitSubsys::init() { + procedure2_register_facets(); + + CollectorTypeRegistry::instance().register_types(&procedure2_register_types); } InitEvidence @@ -22,6 +29,9 @@ namespace xo { { InitEvidence retval; + /* recursive subsystem deps for xo-object2/ */ + retval ^= InitSubsys::require(); + /* xo-procedure2/'s own initialization code */ retval ^= Subsystem::provide("procedure2", &init); diff --git a/xo-procedure2/src/procedure2/procedure2_register_facets.cpp b/xo-procedure2/src/procedure2/procedure2_register_facets.cpp new file mode 100644 index 00000000..5e7a8755 --- /dev/null +++ b/xo-procedure2/src/procedure2/procedure2_register_facets.cpp @@ -0,0 +1,33 @@ +/** @file procedure2_register_facets.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DPrimitive_gco_2_gco_gco.hpp" +#include "detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp" + +#include +#include +#include + +namespace xo { + using xo::facet::FacetRegistry; + using xo::facet::typeseq; + + namespace scm { + bool + procedure2_register_facets() + { + scope log(XO_DEBUG(true)); + + FacetRegistry::register_impl(); + + log && log(xtag("DPrimitive_gco_2_gco_gco.tseq", typeseq::id())); + + return true; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end procedure2_register_facets.cpp */ diff --git a/xo-procedure2/src/procedure2/procedure2_register_types.cpp b/xo-procedure2/src/procedure2/procedure2_register_types.cpp new file mode 100644 index 00000000..dedceb69 --- /dev/null +++ b/xo-procedure2/src/procedure2/procedure2_register_types.cpp @@ -0,0 +1,33 @@ +/** @file procedure2_register_types.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "procedure2_register_types.hpp" + +#include "detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp" +#include + +namespace xo { + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::facet::impl_for; + using xo::facet::typeseq; + using xo::scope; + + namespace scm { + bool + procedure2_register_types(obj gc) + { + scope log(XO_DEBUG(true)); + + bool ok = true; + + ok &= gc.install_type(impl_for()); + + return ok; + } + } +} /*namespace xo*/ + +/* end procedure2_register_types.cpp */ From 19d53585fb72d18da8e3a23a1fe67f32752b4ef0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 16:51:23 -0500 Subject: [PATCH 085/258] xo-procedure2: add DSimpleRcx w/ IRuntimeContext facet --- xo-procedure2/CMakeLists.txt | 15 ++++- .../idl/IRuntimeContext_DSimpleRcx.json5 | 15 +++++ .../include/xo/procedure2/DSimpleRcx.hpp | 32 ++++++++++ .../detail/IRuntimeContext_DSimpleRcx.hpp | 59 +++++++++++++++++++ xo-procedure2/src/procedure2/CMakeLists.txt | 3 +- .../procedure2/IRuntimeContext_DSimpleRcx.cpp | 28 +++++++++ 6 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 create mode 100644 xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp create mode 100644 xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp create mode 100644 xo-procedure2/src/procedure2/IRuntimeContext_DSimpleRcx.cpp diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt index be7909a5..929c48bc 100644 --- a/xo-procedure2/CMakeLists.txt +++ b/xo-procedure2/CMakeLists.txt @@ -43,7 +43,20 @@ xo_add_genfacet( # ---------------------------------------------------------------- xo_add_genfacetimpl( - TARGET xo-procedure2-facetimpl-procedure2-primitive_gco_2_gco_gco + TARGET xo-procedure2-facetimpl-runtimecontext-simplercx + FACET_PKG xo_procedure2 + FACET RuntimeContext + REPR DSimpleRcx + INPUT idl/IRuntimeContext_DSimpleRcx.json5 + OUTPUT_HPP_DIR include/xo/procedure2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/procedure2 + ) + +# ---------------------------------------------------------------- + +xo_add_genfacetimpl( + TARGET xo-procedure2-facetimpl-procedure-primitive_gco_2_gco_gco FACET_PKG xo_procedure2 FACET Procedure REPR DPrimitive_gco_2_gco_gco diff --git a/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 b/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 new file mode 100644 index 00000000..ed838629 --- /dev/null +++ b/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + //"", + //"", + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/RuntimeContext.json5", + brief: "provide ARuntimeContext interface for DSimpleRcx", + using_doxygen: true, + repr: "DSimpleRcx", + doc: [ "implement ARuntimeContext for DSimpleRcx" ], +} diff --git a/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp b/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp new file mode 100644 index 00000000..d5060bb9 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp @@ -0,0 +1,32 @@ +/** @file DSimpleRcx.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include + +namespace xo { + namespace scm { + + /** @brief Minimal runtime context. + * + * Minimal runtime context provides an allocator, + * and nothing more. + **/ + class DSimpleRcx { + public: + using AAllocator = xo::mm::AAllocator; + + public: + DSimpleRcx(obj mm) : allocator_{mm} {} + + obj allocator() const noexcept { return allocator_; } + + private: + obj allocator_; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DSimpleRcx.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp new file mode 100644 index 00000000..06f14bc5 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp @@ -0,0 +1,59 @@ +/** @file IRuntimeContext_DSimpleRcx.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IRuntimeContext_DSimpleRcx.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IRuntimeContext_DSimpleRcx.json5] + **/ + +#pragma once + +#include "RuntimeContext.hpp" +#include "DSimpleRcx.hpp" + +namespace xo { namespace scm { class IRuntimeContext_DSimpleRcx; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IRuntimeContext_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IRuntimeContext_DSimpleRcx + **/ + class IRuntimeContext_DSimpleRcx { + public: + /** @defgroup scm-runtimecontext-dsimplercx-type-traits **/ + ///@{ + using AAllocator = xo::scm::ARuntimeContext::AAllocator; + using Copaque = xo::scm::ARuntimeContext::Copaque; + using Opaque = xo::scm::ARuntimeContext::Opaque; + ///@} + /** @defgroup scm-runtimecontext-dsimplercx-methods **/ + ///@{ + // const methods + /** default allocator to use for objects **/ + static obj allocator(const DSimpleRcx & self) noexcept; + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-procedure2/src/procedure2/CMakeLists.txt b/xo-procedure2/src/procedure2/CMakeLists.txt index d1699eb0..8ecbc329 100644 --- a/xo-procedure2/src/procedure2/CMakeLists.txt +++ b/xo-procedure2/src/procedure2/CMakeLists.txt @@ -6,9 +6,10 @@ set(SELF_SRCS init_primitives.cpp procedure2_register_types.cpp procedure2_register_facets.cpp - DPrimitive.cpp IRuntimeContext_Any.cpp + IRuntimeContext_DSimpleRcx.cpp IProcedure_Any.cpp + DPrimitive.cpp IGCObject_DPrimitive_gco_2_gco_gco.cpp IProcedure_DPrimitive_gco_2_gco_gco.cpp # Add source files here, e.g.: diff --git a/xo-procedure2/src/procedure2/IRuntimeContext_DSimpleRcx.cpp b/xo-procedure2/src/procedure2/IRuntimeContext_DSimpleRcx.cpp new file mode 100644 index 00000000..4ec8378b --- /dev/null +++ b/xo-procedure2/src/procedure2/IRuntimeContext_DSimpleRcx.cpp @@ -0,0 +1,28 @@ +/** @file IRuntimeContext_DSimpleRcx.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IRuntimeContext_DSimpleRcx.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IRuntimeContext_DSimpleRcx.json5] +**/ + +#include "detail/IRuntimeContext_DSimpleRcx.hpp" + +namespace xo { + namespace scm { + auto + IRuntimeContext_DSimpleRcx::allocator(const DSimpleRcx & self) noexcept -> obj + { + return self.allocator(); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IRuntimeContext_DSimpleRcx.cpp */ \ No newline at end of file From c3f5323cb818b21a858f24475977c6a353513845 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 16:51:58 -0500 Subject: [PATCH 086/258] xo-procedure2: + simple unit test --- xo-procedure2/CMakeLists.txt | 2 +- xo-procedure2/utest/CMakeLists.txt | 11 ++++++ xo-procedure2/utest/DPrimitive.test.cpp | 35 +++++++++++++++++++ xo-procedure2/utest/procedure2_utest_main.cpp | 20 +++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 xo-procedure2/utest/CMakeLists.txt create mode 100644 xo-procedure2/utest/DPrimitive.test.cpp create mode 100644 xo-procedure2/utest/procedure2_utest_main.cpp diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt index 929c48bc..04751f1d 100644 --- a/xo-procedure2/CMakeLists.txt +++ b/xo-procedure2/CMakeLists.txt @@ -79,7 +79,7 @@ xo_add_genfacetimpl( ) add_subdirectory(src/procedure2) -#add_subdirectory(utest) +add_subdirectory(utest) # ---------------------------------------------------------------- diff --git a/xo-procedure2/utest/CMakeLists.txt b/xo-procedure2/utest/CMakeLists.txt new file mode 100644 index 00000000..2e5f1471 --- /dev/null +++ b/xo-procedure2/utest/CMakeLists.txt @@ -0,0 +1,11 @@ +# built unittest xo-procedure2/utest + +set(UTEST_EXE utest.procedure2) +set(UTEST_SRCS + procedure2_utest_main.cpp + DPrimitive.test.cpp +) + +xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) +xo_self_dependency(${UTEST_EXE} xo_procedure2) +xo_external_target_dependency(${UTEST_EXE} Catch2 Catch2::Catch2) diff --git a/xo-procedure2/utest/DPrimitive.test.cpp b/xo-procedure2/utest/DPrimitive.test.cpp new file mode 100644 index 00000000..db501dae --- /dev/null +++ b/xo-procedure2/utest/DPrimitive.test.cpp @@ -0,0 +1,35 @@ +/** @file DPrimitive.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include +#include +#include + +namespace xo { + using xo::scm::Primitives; + + namespace ut { + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DPrimitive-init", "[procedure2][DPrimitive]") + { + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DPrimitive-n_args", "[procedure2][DPrimitive]") + { + // s_mul_gco_gco_pm takes 2 AGCObject args + REQUIRE(Primitives::s_mul_gco_gco_pm.n_args() == 2); + } + + TEST_CASE("DPrimitive-is_nary", "[procedure2][DPrimitive]") + { + REQUIRE(Primitives::s_mul_gco_gco_pm.is_nary() == false); + } + + } /*namespace ut*/ +} /*namespace xo*/ + +/* end DPrimitive.test.cpp */ diff --git a/xo-procedure2/utest/procedure2_utest_main.cpp b/xo-procedure2/utest/procedure2_utest_main.cpp new file mode 100644 index 00000000..477099bc --- /dev/null +++ b/xo-procedure2/utest/procedure2_utest_main.cpp @@ -0,0 +1,20 @@ +/* file procedure2_utest_main.cpp */ + +#include + +#define CATCH_CONFIG_RUNNER +#include "catch2/catch.hpp" + +int +main(int argc, char* argv[]) +{ + using xo::Subsystem; + + Subsystem::initialize_all(); + + int result = Catch::Session().run(argc, argv); + + return result; +} + +/* end procedure2_utest_main.cpp */ From a9de96f1a0c44af0239781d0d196310e486a0450 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 16:56:35 -0500 Subject: [PATCH 087/258] xo-procedure2: + DSimpleRcx utest --- .../include/xo/procedure2/DSimpleRcx.hpp | 2 + xo-procedure2/utest/CMakeLists.txt | 1 + xo-procedure2/utest/DSimpleRcx.test.cpp | 60 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 xo-procedure2/utest/DSimpleRcx.test.cpp diff --git a/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp b/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp index d5060bb9..bd52dcc5 100644 --- a/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp +++ b/xo-procedure2/include/xo/procedure2/DSimpleRcx.hpp @@ -3,6 +3,8 @@ * @author Roland Conybeare, Jan 2026 **/ +#pragma once + #include namespace xo { diff --git a/xo-procedure2/utest/CMakeLists.txt b/xo-procedure2/utest/CMakeLists.txt index 2e5f1471..e758d282 100644 --- a/xo-procedure2/utest/CMakeLists.txt +++ b/xo-procedure2/utest/CMakeLists.txt @@ -4,6 +4,7 @@ set(UTEST_EXE utest.procedure2) set(UTEST_SRCS procedure2_utest_main.cpp DPrimitive.test.cpp + DSimpleRcx.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-procedure2/utest/DSimpleRcx.test.cpp b/xo-procedure2/utest/DSimpleRcx.test.cpp new file mode 100644 index 00000000..cab1362d --- /dev/null +++ b/xo-procedure2/utest/DSimpleRcx.test.cpp @@ -0,0 +1,60 @@ +/** @file DSimpleRcx.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include +#include +#include +#include +#include + +namespace xo { + using xo::scm::DSimpleRcx; + using xo::scm::ARuntimeContext; + using xo::mm::AAllocator; + using xo::mm::DArena; + using xo::mm::ArenaConfig; + using xo::facet::with_facet; + using xo::facet::obj; + + namespace ut { + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DSimpleRcx-init", "[procedure2][DSimpleRcx]") + { + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DSimpleRcx-construct", "[procedure2][DSimpleRcx]") + { + ArenaConfig cfg { .name_ = "testarena", + .size_ = 4*1024 }; + DArena arena = DArena::map(cfg); + auto alloc = with_facet::mkobj(&arena); + + DSimpleRcx rcx(alloc); + + REQUIRE((void*)rcx.allocator().data() == (void*)alloc.data()); + } + + TEST_CASE("DSimpleRcx-as-ARuntimeContext", "[procedure2][DSimpleRcx]") + { + ArenaConfig cfg { .name_ = "testarena", + .size_ = 4*1024 }; + DArena arena = DArena::map(cfg); + auto alloc = with_facet::mkobj(&arena); + + DSimpleRcx rcx(alloc); + obj rcx_obj = with_facet::mkobj(&rcx); + + // verify we can recover allocator from obj + obj recovered_alloc = rcx_obj.allocator(); + + REQUIRE((void*)recovered_alloc.data() == (void*)alloc.data()); + } + + } /*namespace ut*/ +} /*namespace xo*/ + +/* end DSimpleRcx.test.cpp */ From 320e42403217ce9aeeb44e38e3a35979a451e5e1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 16:59:07 -0500 Subject: [PATCH 088/258] xo-procedure2: register DSimpleRcx --- xo-procedure2/src/procedure2/procedure2_register_facets.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xo-procedure2/src/procedure2/procedure2_register_facets.cpp b/xo-procedure2/src/procedure2/procedure2_register_facets.cpp index 5e7a8755..c22b8049 100644 --- a/xo-procedure2/src/procedure2/procedure2_register_facets.cpp +++ b/xo-procedure2/src/procedure2/procedure2_register_facets.cpp @@ -3,6 +3,9 @@ * @author Roland Conybeare, Jan 2026 **/ +#include "DSimpleRcx.hpp" +#include "detail/IRuntimeContext_DSimpleRcx.hpp" + #include "DPrimitive_gco_2_gco_gco.hpp" #include "detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp" @@ -20,8 +23,11 @@ namespace xo { { scope log(XO_DEBUG(true)); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DSimpleRcx.tseq", typeseq::id())); log && log(xtag("DPrimitive_gco_2_gco_gco.tseq", typeseq::id())); return true; From 5842b193c769a51ecf03ac297648504e39325028 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 17:08:25 -0500 Subject: [PATCH 089/258] xo-procedure2: add apply_nocheck() utest on gco multiply --- .../procedure2/procedure2_register_types.cpp | 2 + xo-procedure2/utest/DPrimitive.test.cpp | 82 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/xo-procedure2/src/procedure2/procedure2_register_types.cpp b/xo-procedure2/src/procedure2/procedure2_register_types.cpp index dedceb69..497773d2 100644 --- a/xo-procedure2/src/procedure2/procedure2_register_types.cpp +++ b/xo-procedure2/src/procedure2/procedure2_register_types.cpp @@ -23,6 +23,8 @@ namespace xo { bool ok = true; + // (note: don't currently intend to support AGCObject for DSimpleRcx) + ok &= gc.install_type(impl_for()); return ok; diff --git a/xo-procedure2/utest/DPrimitive.test.cpp b/xo-procedure2/utest/DPrimitive.test.cpp index db501dae..b3775e62 100644 --- a/xo-procedure2/utest/DPrimitive.test.cpp +++ b/xo-procedure2/utest/DPrimitive.test.cpp @@ -5,10 +5,29 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include namespace xo { using xo::scm::Primitives; + using xo::scm::DSimpleRcx; + using xo::scm::ARuntimeContext; + using xo::scm::DFloat; + using xo::scm::DInteger; + using xo::scm::DArray; + using xo::mm::AAllocator; + using xo::mm::AGCObject; + using xo::mm::DArena; + using xo::mm::ArenaConfig; + using xo::facet::with_facet; + using xo::facet::obj; namespace ut { static InitEvidence s_init = InitSubsys::require(); @@ -29,6 +48,69 @@ namespace xo { REQUIRE(Primitives::s_mul_gco_gco_pm.is_nary() == false); } + TEST_CASE("DPrimitive-apply_nocheck-float-float", "[procedure2][DPrimitive]") + { + ArenaConfig cfg { .name_ = "testarena", .size_ = 4*1024 }; + DArena arena = DArena::map(cfg); + auto alloc = with_facet::mkobj(&arena); + + DSimpleRcx rcx_data(alloc); + obj rcx = with_facet::mkobj(&rcx_data); + + // 3.0 * 7.0 = 21.0 + obj x = DFloat::box(alloc, 3.0); + obj y = DFloat::box(alloc, 7.0); + DArray * args = DArray::array(alloc, x, y); + + obj result = Primitives::s_mul_gco_gco_pm.apply_nocheck(rcx, args); + + auto result_float = obj::from(result); + REQUIRE(result_float); + REQUIRE(result_float.data()->value() == 21.0); + } + + TEST_CASE("DPrimitive-apply_nocheck-int-int", "[procedure2][DPrimitive]") + { + ArenaConfig cfg { .name_ = "testarena", .size_ = 4*1024 }; + DArena arena = DArena::map(cfg); + auto alloc = with_facet::mkobj(&arena); + + DSimpleRcx rcx_data(alloc); + obj rcx = with_facet::mkobj(&rcx_data); + + // 3 * 7 = 21 + obj x = DInteger::box(alloc, 3L); + obj y = DInteger::box(alloc, 7L); + DArray * args = DArray::array(alloc, x, y); + + obj result = Primitives::s_mul_gco_gco_pm.apply_nocheck(rcx, args); + + auto result_int = obj::from(result); + REQUIRE(result_int); + REQUIRE(result_int.data()->value() == 21L); + } + + TEST_CASE("DPrimitive-apply_nocheck-int-float", "[procedure2][DPrimitive]") + { + ArenaConfig cfg { .name_ = "testarena", .size_ = 4*1024 }; + DArena arena = DArena::map(cfg); + auto alloc = with_facet::mkobj(&arena); + + DSimpleRcx rcx_data(alloc); + obj rcx = with_facet::mkobj(&rcx_data); + + // 3 * 7.0 = 21.0 (mixed: result is float) + obj x = DInteger::box(alloc, 3L); + obj y = DFloat::box(alloc, 7.0); + DArray * args = DArray::array(alloc, x, y); + + obj result = Primitives::s_mul_gco_gco_pm.apply_nocheck(rcx, args); + + auto result_float = obj::from(result); + REQUIRE(result_float); + REQUIRE(result_float.data()->value() == 21.0); + } + } /*namespace ut*/ } /*namespace xo*/ From 31aaddb7af5ce98f074972404023a77d7ea729e1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 17:26:42 -0500 Subject: [PATCH 090/258] xo-expression2: + DVariable utest --- xo-expression2/utest/CMakeLists.txt | 1 + xo-expression2/utest/DVariable.test.cpp | 227 ++++++++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 xo-expression2/utest/DVariable.test.cpp diff --git a/xo-expression2/utest/CMakeLists.txt b/xo-expression2/utest/CMakeLists.txt index aefc8c8c..687c75ab 100644 --- a/xo-expression2/utest/CMakeLists.txt +++ b/xo-expression2/utest/CMakeLists.txt @@ -6,6 +6,7 @@ set(UTEST_SRCS StringTable.test.cpp X1Collector.test.cpp DConstant.test.cpp + DVariable.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-expression2/utest/DVariable.test.cpp b/xo-expression2/utest/DVariable.test.cpp new file mode 100644 index 00000000..8afee360 --- /dev/null +++ b/xo-expression2/utest/DVariable.test.cpp @@ -0,0 +1,227 @@ +/** @file DVariable.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_expression2.hpp" +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +namespace ut { + using xo::S_expression2_tag; + using xo::scm::DVariable; + using xo::scm::DUniqueString; + using xo::scm::StringTable; + using xo::scm::TypeRef; + using xo::scm::Binding; + using xo::scm::AExpression; + using xo::mm::CollectorTypeRegistry; + using xo::mm::AAllocator; + using xo::mm::ACollector; + using xo::mm::DX1Collector; + using xo::mm::CollectorConfig; + using xo::mm::ArenaConfig; + using xo::print::APrintable; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::facet::obj; + using xo::reflect::Reflect; + using xo::InitEvidence; + using xo::InitSubsys; + using xo::scope; + + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DVariable-init", "[expression2][DVariable]") + { + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DVariable-make", "[expression2][DVariable]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dvariable_make_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("x"); + REQUIRE(name != nullptr); + + TypeRef typeref = TypeRef::resolved(Reflect::require()); + + DVariable * var = DVariable::make(alloc, name, typeref); + REQUIRE(var != nullptr); + } + + TEST_CASE("DVariable-extype", "[expression2][DVariable]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dvariable_extype_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("y"); + TypeRef typeref = TypeRef::resolved(Reflect::require()); + + DVariable * var = DVariable::make(alloc, name, typeref); + REQUIRE(var != nullptr); + REQUIRE(var->extype() == xo::scm::exprtype::variable); + } + + TEST_CASE("DVariable-valuetype", "[expression2][DVariable]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dvariable_valuetype_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("z"); + TypeRef typeref = TypeRef::resolved(Reflect::require()); + + DVariable * var = DVariable::make(alloc, name, typeref); + REQUIRE(var != nullptr); + REQUIRE(var->valuetype() == Reflect::require()); + } + + TEST_CASE("DVariable-name", "[expression2][DVariable]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dvariable_name_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("myvar"); + TypeRef typeref = TypeRef::resolved(Reflect::require()); + + DVariable * var = DVariable::make(alloc, name, typeref); + REQUIRE(var != nullptr); + REQUIRE(var->name() == name); + REQUIRE(std::strcmp(var->name()->chars(), "myvar") == 0); + } + + TEST_CASE("DVariable-pretty", "[expression2][DVariable][pp]") + { + scope log(XO_DEBUG(false)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dvariable_pretty_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("foo"); + TypeRef typeref = TypeRef::resolved(Reflect::require()); + + DVariable * var = DVariable::make(alloc, name, typeref); + REQUIRE(var != nullptr); + + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj var_pr(var); + pps.pretty(var_pr); + + std::string output = ss.str(); + + log && log(output); + + CHECK(output.find("DVariable") != std::string::npos); + } +} + +/* end DVariable.test.cpp */ From 2f40959a01a6693b9fbd9e3aa5584f783b052684 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 18:15:17 -0500 Subject: [PATCH 091/258] xo-procedure2: + printable support for Primitive --- xo-procedure2/CMakeLists.txt | 13 ++++ .../IPrintable_DPrimitive_gco_2_gco_gco.json5 | 19 ++++++ .../include/xo/procedure2/DPrimitive.hpp | 38 +++++++++++- .../IPrintable_DPrimitive_gco_2_gco_gco.hpp | 62 +++++++++++++++++++ xo-procedure2/src/procedure2/CMakeLists.txt | 1 + .../IPrintable_DPrimitive_gco_2_gco_gco.cpp | 28 +++++++++ .../procedure2/procedure2_register_facets.cpp | 4 ++ xo-procedure2/utest/DPrimitive.test.cpp | 27 ++++++++ 8 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 create mode 100644 xo-procedure2/include/xo/procedure2/detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp create mode 100644 xo-procedure2/src/procedure2/IPrintable_DPrimitive_gco_2_gco_gco.cpp diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt index 04751f1d..ad8673d1 100644 --- a/xo-procedure2/CMakeLists.txt +++ b/xo-procedure2/CMakeLists.txt @@ -55,6 +55,7 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-procedure2-facetimpl-procedure-primitive_gco_2_gco_gco FACET_PKG xo_procedure2 @@ -78,6 +79,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/procedure2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-procedure2-facetimpl-printable-primitive_gco_2_gco_gco + FACET_PKG xo_printable2 + FACET Printable + REPR Primitive_gco_2_gco_gco + INPUT idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 + OUTPUT_HPP_DIR include/xo/procedure2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/procedure2 +) + add_subdirectory(src/procedure2) add_subdirectory(utest) diff --git a/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 new file mode 100644 index 00000000..15cff1b4 --- /dev/null +++ b/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 @@ -0,0 +1,19 @@ +{ + mode: "implementation", + includes: [ + "", + "", +// "", +// "", +// "", +// "", + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DPrimitive (gco x gco) -> gco", + using_doxygen: true, + repr: "DPrimitive_gco_2_gco_gco", + doc: [ "implement APrintable for DPrimitive (gco x gco) -> gco" ], +} diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp index c225246d..90fdba50 100644 --- a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp +++ b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -58,14 +59,22 @@ namespace xo { template class Primitive { public: + using Traits = detail::PmFnTraits; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using DArray = xo::scm::DArray; - using Traits = detail::PmFnTraits; + using Reflect = xo::reflect::Reflect; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; public: - Primitive(std::string_view name, Fn fn) : name_{name}, fn_{fn} {} + Primitive(std::string_view name, Fn fn) : name_{name}, + fn_td_{Reflect::require()}, + fn_{fn} {} + + TypeDescr fn_td() const noexcept { return fn_td_; } bool is_nary() const noexcept { return false; } static constexpr std::int32_t n_args() noexcept { return Traits::n_args; } @@ -75,6 +84,12 @@ namespace xo { std::make_index_sequence{}); } + /** @defgroup scm-primitive-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} /** @defgroup scm-primitive-gcobject-facet **/ ///@{ std::size_t shallow_size() const noexcept; @@ -107,10 +122,29 @@ namespace xo { private: /** name of this primitive **/ std::string_view name_; + + /** type description for function + * Note that this type description will have additional first argument + * for obj + **/ + TypeDescr fn_td_; + /** function implementation **/ Fn fn_; }; /*Primitive*/ + template + bool + Primitive::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "Primitive", + refrtag("name", name_), + refrtag("td", fn_td_), + refrtag("fn", fn_)); + } + template std::size_t Primitive::shallow_size() const noexcept { diff --git a/xo-procedure2/include/xo/procedure2/detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp b/xo-procedure2/include/xo/procedure2/detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp new file mode 100644 index 00000000..b6b0a9c5 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DPrimitive_gco_2_gco_gco.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DPrimitive_gco_2_gco_gco.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DPrimitive_gco_2_gco_gco.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DPrimitive_gco_2_gco_gco.hpp" + +namespace xo { namespace scm { class IPrintable_DPrimitive_gco_2_gco_gco; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DPrimitive_gco_2_gco_gco + **/ + class IPrintable_DPrimitive_gco_2_gco_gco { + public: + /** @defgroup scm-printable-dprimitive_gco_2_gco_gco-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dprimitive_gco_2_gco_gco-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DPrimitive_gco_2_gco_gco & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-procedure2/src/procedure2/CMakeLists.txt b/xo-procedure2/src/procedure2/CMakeLists.txt index 8ecbc329..92685afb 100644 --- a/xo-procedure2/src/procedure2/CMakeLists.txt +++ b/xo-procedure2/src/procedure2/CMakeLists.txt @@ -12,6 +12,7 @@ set(SELF_SRCS DPrimitive.cpp IGCObject_DPrimitive_gco_2_gco_gco.cpp IProcedure_DPrimitive_gco_2_gco_gco.cpp + IPrintable_DPrimitive_gco_2_gco_gco.cpp # Add source files here, e.g.: # procedure2.cpp ) diff --git a/xo-procedure2/src/procedure2/IPrintable_DPrimitive_gco_2_gco_gco.cpp b/xo-procedure2/src/procedure2/IPrintable_DPrimitive_gco_2_gco_gco.cpp new file mode 100644 index 00000000..2c791324 --- /dev/null +++ b/xo-procedure2/src/procedure2/IPrintable_DPrimitive_gco_2_gco_gco.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DPrimitive_gco_2_gco_gco.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DPrimitive_gco_2_gco_gco.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DPrimitive_gco_2_gco_gco.json5] +**/ + +#include "detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DPrimitive_gco_2_gco_gco::pretty(const DPrimitive_gco_2_gco_gco & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DPrimitive_gco_2_gco_gco.cpp */ \ No newline at end of file diff --git a/xo-procedure2/src/procedure2/procedure2_register_facets.cpp b/xo-procedure2/src/procedure2/procedure2_register_facets.cpp index c22b8049..5b84b4dd 100644 --- a/xo-procedure2/src/procedure2/procedure2_register_facets.cpp +++ b/xo-procedure2/src/procedure2/procedure2_register_facets.cpp @@ -8,14 +8,17 @@ #include "DPrimitive_gco_2_gco_gco.hpp" #include "detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp" +#include "detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp" #include +#include #include #include namespace xo { using xo::facet::FacetRegistry; using xo::facet::typeseq; + using xo::print::APrintable; namespace scm { bool @@ -26,6 +29,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); log && log(xtag("DSimpleRcx.tseq", typeseq::id())); log && log(xtag("DPrimitive_gco_2_gco_gco.tseq", typeseq::id())); diff --git a/xo-procedure2/utest/DPrimitive.test.cpp b/xo-procedure2/utest/DPrimitive.test.cpp index b3775e62..73e807fd 100644 --- a/xo-procedure2/utest/DPrimitive.test.cpp +++ b/xo-procedure2/utest/DPrimitive.test.cpp @@ -7,13 +7,17 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include #include +#include namespace xo { using xo::scm::Primitives; @@ -22,12 +26,17 @@ namespace xo { using xo::scm::DFloat; using xo::scm::DInteger; using xo::scm::DArray; + using xo::scm::DPrimitive_gco_2_gco_gco; using xo::mm::AAllocator; using xo::mm::AGCObject; using xo::mm::DArena; using xo::mm::ArenaConfig; + using xo::print::APrintable; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; using xo::facet::with_facet; using xo::facet::obj; + using xo::scope; namespace ut { static InitEvidence s_init = InitSubsys::require(); @@ -111,6 +120,24 @@ namespace xo { REQUIRE(result_float.data()->value() == 21.0); } + TEST_CASE("DPrimitive-pretty", "[procedure2][DPrimitive][pp]") + { + scope log(XO_DEBUG(false)); + + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj prim_pr(&Primitives::s_mul_gco_gco_pm); + pps.pretty(prim_pr); + + std::string output = ss.str(); + + log && log(output); + + CHECK(output.find("_mul") != std::string::npos); + } + } /*namespace ut*/ } /*namespace xo*/ From afc4c58cf733115058736a001afce4c67da8cbc9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 18:15:44 -0500 Subject: [PATCH 092/258] xo-expression2: utest for DApplyExpr --- xo-expression2/utest/CMakeLists.txt | 1 + xo-expression2/utest/DApplyExpr.test.cpp | 309 +++++++++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 xo-expression2/utest/DApplyExpr.test.cpp diff --git a/xo-expression2/utest/CMakeLists.txt b/xo-expression2/utest/CMakeLists.txt index 687c75ab..b1662736 100644 --- a/xo-expression2/utest/CMakeLists.txt +++ b/xo-expression2/utest/CMakeLists.txt @@ -7,6 +7,7 @@ set(UTEST_SRCS X1Collector.test.cpp DConstant.test.cpp DVariable.test.cpp + DApplyExpr.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-expression2/utest/DApplyExpr.test.cpp b/xo-expression2/utest/DApplyExpr.test.cpp new file mode 100644 index 00000000..d151b776 --- /dev/null +++ b/xo-expression2/utest/DApplyExpr.test.cpp @@ -0,0 +1,309 @@ +/** @file DApplyExpr.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_expression2.hpp" +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +namespace ut { + using xo::S_expression2_tag; + using xo::scm::DApplyExpr; + using xo::scm::DConstant; + using xo::scm::DFloat; + using xo::scm::AExpression; + using xo::scm::TypeRef; + using xo::scm::Primitives; + using xo::scm::DPrimitive_gco_2_gco_gco; + using xo::mm::CollectorTypeRegistry; + using xo::mm::AAllocator; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::mm::DX1Collector; + using xo::mm::CollectorConfig; + using xo::mm::ArenaConfig; + using xo::print::APrintable; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::facet::obj; + using xo::reflect::Reflect; + using xo::InitEvidence; + using xo::InitSubsys; + using xo::scope; + + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DApplyExpr-init", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DApplyExpr-make2", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_make2_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + // wrap primitive as GCObject, then as expression + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + REQUIRE(fn_expr.data() != nullptr); + + // create argument expressions + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + REQUIRE(arg1.data() != nullptr); + REQUIRE(arg2.data() != nullptr); + + // create apply expression: mul(3.0, 7.0) + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + REQUIRE(apply_expr.data() != nullptr); + } + + TEST_CASE("DApplyExpr-extype", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_extype_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + REQUIRE(apply_expr.data()->extype() == xo::scm::exprtype::apply); + } + + TEST_CASE("DApplyExpr-n_args", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_n_args_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + REQUIRE(apply_expr.data()->n_args() == 2); + } + + TEST_CASE("DApplyExpr-fn", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_fn_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + // verify fn() returns an expression + obj fn = apply_expr.data()->fn(); + REQUIRE(fn.data() != nullptr); + REQUIRE(fn.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DApplyExpr-arg", "[expression2][DApplyExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_arg_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + // verify arg(0) and arg(1) return expressions + obj a0 = apply_expr.data()->arg(0); + obj a1 = apply_expr.data()->arg(1); + + REQUIRE(a0.data() != nullptr); + REQUIRE(a1.data() != nullptr); + REQUIRE(a0.extype() == xo::scm::exprtype::constant); + REQUIRE(a1.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DApplyExpr-pretty", "[expression2][DApplyExpr][pp]") + { + scope log(XO_DEBUG(false)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "dapplyexpr_pretty_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj prim_gco = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); + obj fn_expr = DConstant::make(alloc, prim_gco); + + obj val1 = DFloat::box(alloc, 3.0); + obj val2 = DFloat::box(alloc, 7.0); + obj arg1 = DConstant::make(alloc, val1); + obj arg2 = DConstant::make(alloc, val2); + + TypeRef result_type = TypeRef::resolved(Reflect::require()); + auto apply_expr = DApplyExpr::make2(alloc, result_type, fn_expr, arg1, arg2); + + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj expr_pr(apply_expr.data()); + pps.pretty(expr_pr); + + std::string output = ss.str(); + + log && log(output); + + CHECK(output.find("ApplyExpr") != std::string::npos); + } +} + +/* end DApplyExpr.test.cpp */ From 1b185a3680b46a0737bd8c4107650ad507c3f821 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 19:26:54 -0500 Subject: [PATCH 093/258] xo-reflect: + pretty printing for xo::reflect::TypeDescr --- xo-alloc/include/xo/alloc/GcStatistics.hpp | 14 +++++----- xo-reflect/include/xo/reflect/TypeDescr.hpp | 30 +++++++++++++++++++-- xo-reflect/src/reflect/TypeDescr.cpp | 13 +++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/xo-alloc/include/xo/alloc/GcStatistics.hpp b/xo-alloc/include/xo/alloc/GcStatistics.hpp index b591bf22..69053457 100644 --- a/xo-alloc/include/xo/alloc/GcStatistics.hpp +++ b/xo-alloc/include/xo/alloc/GcStatistics.hpp @@ -1,16 +1,16 @@ -/* GcStatistics.hpp +/** @file GcStatistics.hpp * - * author: Roland Conybeare, Aug 2025 - */ + * @author Roland Conybeare, Aug 2025 + **/ #pragma once #include "generation.hpp" #include "CircularBuffer.hpp" -#include "xo/reflect/TypeDescr.hpp" -#include "xo/unit/quantity.hpp" -#include "xo/unit/quantity_iostream.hpp" -#include "xo/indentlog/print/pretty.hpp" +#include +#include +#include +#include #include #include diff --git a/xo-reflect/include/xo/reflect/TypeDescr.hpp b/xo-reflect/include/xo/reflect/TypeDescr.hpp index d39d64e8..4b3ca87b 100644 --- a/xo-reflect/include/xo/reflect/TypeDescr.hpp +++ b/xo-reflect/include/xo/reflect/TypeDescr.hpp @@ -3,7 +3,8 @@ #pragma once #include "TypeDescrExtra.hpp" -#include "xo/cxxutil/demangle.hpp" +#include +#include #include #include #include @@ -15,6 +16,8 @@ #include namespace xo { + namespace print { class ppindentinfo; } + namespace reflect { class TaggedPtr; /* see [reflect/TaggedPtr.hpp] */ @@ -202,6 +205,9 @@ namespace xo { /* run-time description for a native c++ type */ class TypeDescrBase { + public: + using ppindentinfo = xo::print::ppindentinfo; + public: /* type-description objects for a type T is unique, * --> can always use its address @@ -391,6 +397,9 @@ namespace xo { TypeDescr fn_arg(uint32_t i) const { return this->tdextra_->fn_arg(i); } bool fn_is_noexcept() const { return this->tdextra_->fn_is_noexcept(); } + /** pretty-printer support, using @p ppii **/ + bool pretty(const ppindentinfo & ppii) const; + void display(std::ostream & os) const; std::string display_string() const; @@ -543,7 +552,6 @@ namespace xo { return os; } - /* tag to drive overload resolution */ struct reflected_types_printer {}; @@ -567,6 +575,24 @@ namespace xo { static TypeDescrTable s_instance; }; } /*namespace reflect*/ + + namespace print { + template <> + struct ppdetail { + static bool print_pretty(const ppindentinfo & ppii, + const xo::reflect::TypeDescrBase & td) { + return td.pretty(ppii); + } + }; + + template <> + struct ppdetail { + static bool print_pretty(const ppindentinfo & ppii, + xo::reflect::TypeDescr td) { + return td ? td->pretty(ppii) : true; + } + }; + } /*namespace print*/ } /*namespace xo*/ namespace std { diff --git a/xo-reflect/src/reflect/TypeDescr.cpp b/xo-reflect/src/reflect/TypeDescr.cpp index de5f4ada..c6cb1664 100644 --- a/xo-reflect/src/reflect/TypeDescr.cpp +++ b/xo-reflect/src/reflect/TypeDescr.cpp @@ -301,6 +301,19 @@ namespace xo { return this->tdextra_->child_tp(i, object); } /*child_tp*/ + bool + TypeDescrBase::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "TypeDescr", + refrtag("id", id_), + refrtag("canonical_name", canonical_name_), + refrtag("complete", complete_flag_), + refrtag("metatype", this->metatype())); + + } + void TypeDescrBase::display(std::ostream & os) const { From 70c43e0fe54f1f265a237ab380225756da99adb8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 20:24:48 -0500 Subject: [PATCH 094/258] xo-cmake: + --enable/disable testing arg to reconfigure.in --- xo-cmake/share/xo-macros/xo-reconfigure.in | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xo-cmake/share/xo-macros/xo-reconfigure.in b/xo-cmake/share/xo-macros/xo-reconfigure.in index 3d8118bb..41d641c6 100644 --- a/xo-cmake/share/xo-macros/xo-reconfigure.in +++ b/xo-cmake/share/xo-macros/xo-reconfigure.in @@ -3,6 +3,7 @@ # Generated by cmake - rerun to reconfigure dry_run_flag=false +testing=@ENABLE_TESTING@ # Parse arguments while [[ $# -gt 0 ]]; do @@ -10,6 +11,12 @@ while [[ $# -gt 0 ]]; do -n|--dry-run) dry_run_flag=true ;; + --enable-testing) + testing=1 + ;; + --disable-testing) + testing=0 + ;; --) break; ;; @@ -35,7 +42,7 @@ CMAKE_CMD=( -DCMAKE_PREFIX_PATH=@CMAKE_PREFIX_PATH@ -DCMAKE_CXX_STANDARD=@CMAKE_CXX_STANDARD@ -DXO_CMAKE_CONFIG_EXECUTABLE=@XO_CMAKE_CONFIG_EXECUTABLE@ - -DENABLE_TESTING=@ENABLE_TESTING@ + -DENABLE_TESTING=$testing -DXO_ENABLE_DOCS=@XO_ENABLE_DOCS@ -DXO_ENABLE_ASM=@XO_ENABLE_ASM@ -DXO_ENABLE_EXAMPLES=@XO_ENABLE_EXAMPLES@ From abcbe1c84b1fbd31023fb4a4e516b4da5351c5e7 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 20:25:24 -0500 Subject: [PATCH 095/258] xo-expression2: + utest for DDefineExpr --- xo-expression2/utest/CMakeLists.txt | 1 + xo-expression2/utest/DDefineExpr.test.cpp | 317 ++++++++++++++++++++++ 2 files changed, 318 insertions(+) create mode 100644 xo-expression2/utest/DDefineExpr.test.cpp diff --git a/xo-expression2/utest/CMakeLists.txt b/xo-expression2/utest/CMakeLists.txt index b1662736..f464708e 100644 --- a/xo-expression2/utest/CMakeLists.txt +++ b/xo-expression2/utest/CMakeLists.txt @@ -8,6 +8,7 @@ set(UTEST_SRCS DConstant.test.cpp DVariable.test.cpp DApplyExpr.test.cpp + DDefineExpr.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-expression2/utest/DDefineExpr.test.cpp b/xo-expression2/utest/DDefineExpr.test.cpp new file mode 100644 index 00000000..5bb91582 --- /dev/null +++ b/xo-expression2/utest/DDefineExpr.test.cpp @@ -0,0 +1,317 @@ +/** @file DDefineExpr.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_expression2.hpp" +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +namespace ut { + using xo::S_expression2_tag; + using xo::scm::DDefineExpr; + using xo::scm::DConstant; + using xo::scm::DFloat; + using xo::scm::DVariable; + using xo::scm::DUniqueString; + using xo::scm::StringTable; + using xo::scm::AExpression; + using xo::mm::CollectorTypeRegistry; + using xo::mm::AAllocator; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::mm::DX1Collector; + using xo::mm::CollectorConfig; + using xo::mm::ArenaConfig; + using xo::print::APrintable; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::facet::obj; + using xo::reflect::Reflect; + using xo::InitEvidence; + using xo::InitSubsys; + using xo::scope; + + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DDefineExpr-init", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DDefineExpr-make", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_make_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("x"); + REQUIRE(name != nullptr); + + // Create rhs expression: constant 42.0 + obj fval = DFloat::box(alloc, 42.0); + auto rhs_expr = DConstant::make(alloc, fval); + REQUIRE(rhs_expr.data() != nullptr); + + // Create define expression: def x = 42.0 + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + } + + TEST_CASE("DDefineExpr-lhs", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_lhs_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("myvar"); + + obj fval = DFloat::box(alloc, 3.14); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + + DVariable * lhs = def->lhs(); + REQUIRE(lhs != nullptr); + REQUIRE(lhs->name() == name); + } + + TEST_CASE("DDefineExpr-rhs", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_rhs_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("y"); + + obj fval = DFloat::box(alloc, 2.718); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + + obj rhs = def->rhs(); + REQUIRE(rhs.data() != nullptr); + // Verify rhs expression type is constant + REQUIRE(rhs.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DDefineExpr-name", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_name_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("foo"); + + obj fval = DFloat::box(alloc, 1.0); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + REQUIRE(def->name() == name); + REQUIRE(std::strcmp(def->name()->chars(), "foo") == 0); + } + + TEST_CASE("DDefineExpr-extype", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_extype_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("z"); + + obj fval = DFloat::box(alloc, 0.0); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + REQUIRE(def->extype() == xo::scm::exprtype::define); + } + + TEST_CASE("DDefineExpr-valuetype", "[expression2][DDefineExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_valuetype_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("w"); + + obj fval = DFloat::box(alloc, 99.9); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + REQUIRE(def->valuetype() == Reflect::require()); + } + + TEST_CASE("DDefineExpr-pretty", "[expression2][DDefineExpr][pp]") + { + scope log(XO_DEBUG(true)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "ddefineexpr_pretty_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + StringTable table(1024); + const DUniqueString * name = table.intern("bar"); + + obj fval = DFloat::box(alloc, 123.456); + auto rhs_expr = DConstant::make(alloc, fval); + + DDefineExpr * def = DDefineExpr::make(alloc, name, rhs_expr); + REQUIRE(def != nullptr); + + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj def_pr(def); + pps.pretty(def_pr); + + std::string output = ss.str(); + + log && log(output); + + CHECK(output.find("DDefineExpr") != std::string::npos); + } +} + +/* end DDefineExpr.test.cpp */ From 3f8a57cef53582a5fbde0d686653e24a00861668 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 20:27:14 -0500 Subject: [PATCH 096/258] xo-reflect: compile nit --- xo-reflect/include/xo/reflect/TypeDescr.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/xo-reflect/include/xo/reflect/TypeDescr.hpp b/xo-reflect/include/xo/reflect/TypeDescr.hpp index 4b3ca87b..f22f96bd 100644 --- a/xo-reflect/include/xo/reflect/TypeDescr.hpp +++ b/xo-reflect/include/xo/reflect/TypeDescr.hpp @@ -16,8 +16,6 @@ #include namespace xo { - namespace print { class ppindentinfo; } - namespace reflect { class TaggedPtr; /* see [reflect/TaggedPtr.hpp] */ From 1e83e9aabae1c705cca132f690bdb16299367615 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 21:36:10 -0500 Subject: [PATCH 097/258] xo-reader2: formatting + asserts --- .../src/expression2/DDefineExpr.cpp | 23 ++++++++++++++---- xo-expression2/src/expression2/DVariable.cpp | 7 +++--- xo-expression2/src/expression2/TypeRef.cpp | 8 ++++--- xo-reader2/src/reader2/DDefineSsm.cpp | 9 +++++-- xo-reader2/src/reader2/DExpectExprSsm.cpp | 3 ++- xo-reader2/src/reader2/DProgressSsm.cpp | 24 ++++--------------- xo-reader2/src/reader2/ParserStack.cpp | 5 ++-- xo-reader2/src/reader2/SchematikaParser.cpp | 3 ++- xo-reader2/utest/SchematikaParser.test.cpp | 4 ++-- 9 files changed, 47 insertions(+), 39 deletions(-) diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index 47465c0e..ba2304ad 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -75,23 +75,36 @@ namespace xo { bool DDefineExpr::pretty(const ppindentinfo & ppii) const { + assert(lhs_var_); + auto lhs = obj(lhs_var_); auto rhs = FacetRegistry::instance().try_variant(rhs_); + if (lhs_var_) + assert(lhs.data()); + + (void)lhs; + (void)rhs; + + if (rhs_) + assert(rhs.data()); + // note: xo::print::cond() doesn't resolve the way we want here if (rhs) { return ppii.pps()->pretty_struct (ppii, - "DDefineExpr", - refrtag("lhs", lhs), - refrtag("rhs", rhs)); + "DDefineExpr" + , refrtag("lhs", lhs) + , refrtag("rhs", rhs) + ); } else { return ppii.pps()->pretty_struct (ppii, - "DDefineExpr", - refrtag("lhs", lhs)); + "DDefineExpr" + , refrtag("lhs", lhs) + ); } } diff --git a/xo-expression2/src/expression2/DVariable.cpp b/xo-expression2/src/expression2/DVariable.cpp index 4550a102..af47de00 100644 --- a/xo-expression2/src/expression2/DVariable.cpp +++ b/xo-expression2/src/expression2/DVariable.cpp @@ -47,9 +47,10 @@ namespace xo { return ppii.pps()->pretty_struct (ppii, - "DVariable", - refrtag("name", quot(name)), - refrtag("typeref", typeref_)); + "DVariable" + , refrtag("name", quot(name)) + , refrtag("typeref", typeref_) + ); } } /*namespace scm*/ diff --git a/xo-expression2/src/expression2/TypeRef.cpp b/xo-expression2/src/expression2/TypeRef.cpp index 01cb043c..5ff1d258 100644 --- a/xo-expression2/src/expression2/TypeRef.cpp +++ b/xo-expression2/src/expression2/TypeRef.cpp @@ -4,6 +4,7 @@ **/ #include "TypeRef.hpp" +#include #include #include @@ -71,9 +72,10 @@ namespace xo { return ppii.pps()->pretty_struct (ppii, - "TypeRef", - refrtag("id", quot(id_)), - refrtag("td", td_)); + "TypeRef" + , refrtag("id", quot(id_)) + , refrtag("td", cond(td_, td_, "null")) + ); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 0cd488e5..c4628c22 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -733,13 +733,18 @@ namespace xo { bool DDefineSsm::pretty(const ppindentinfo & ppii) const { - auto expr = FacetRegistry::instance().variant(def_expr_); + auto expr + = FacetRegistry::instance().variant(def_expr_); + assert(expr.data()); + (void)expr; return ppii.pps()->pretty_struct (ppii, "DDefineSsm", refrtag("defstate", defstate_), - refrtag("def_expr", expr)); + refrtag("def_expr", expr) + ); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 66eb41cd..7a82ad1c 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -336,7 +336,8 @@ namespace xo { (ppii, "DExpectExprSsm", refrtag("allow_defs", allow_defs_), - refrtag("cxl_on_rightbrace", cxl_on_rightbrace_)); + refrtag("cxl_on_rightbrace", cxl_on_rightbrace_) + ); } #ifdef NOT_YET diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index cc0fc14b..e085f8cf 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -1115,32 +1115,16 @@ namespace xo { if (rhs_) rhs = FacetRegistry::instance().variant(rhs_); + (void)lhs; + return ppii.pps()->pretty_struct (ppii, "DProgressSsm", refrtag("lhs", lhs), refrtag("op", op_type_), - cond(rhs, refrtag("rhs", rhs), "nullptr")); + cond(rhs, refrtag("rhs", rhs), "nullptr") + ); -#ifdef NOPE - if (ppii.upto()) { - return (ppii.pps()->print_upto("print_upto(refrtag("lhs", lhs_)) : true) - && (op_type_ != optype::invalid ? ppii.pps()->print_upto(refrtag("op", op_type_)) : true) - && (rhs_ ? ppii.pps()->print_upto(refrtag("rhs", rhs_)) : true) - && ppii.pps()->print_upto(">")); - } else { - ppii.pps()->write("pretty(refrtag("lhs", lhs_)); - if (op_type_ != optype::invalid) - ppii.pps()->pretty(refrtag("op", op_type_)); - if (rhs_) - ppii.pps()->pretty(refrtag("rhs", rhs_)); - ppii.pps()->write(">"); - return false; - } -#endif } obj diff --git a/xo-reader2/src/reader2/ParserStack.cpp b/xo-reader2/src/reader2/ParserStack.cpp index 91d8bca9..9af9f339 100644 --- a/xo-reader2/src/reader2/ParserStack.cpp +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -73,8 +73,9 @@ namespace xo { char buf[80]; snprintf(buf, sizeof(buf), "[%lu]", i_frame); - auto ssm = FacetRegistry::instance().variant (frame->top()); + auto ssm = (FacetRegistry::instance().variant + (frame->top())); + assert(ssm.data()); pps->newline_pretty_tag(ppii.ci1(), buf, ssm); diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 13f9edff..e584044c 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -117,7 +117,8 @@ namespace xo { return pps->pretty_struct (ppii, "SchematikaParser", - refrtag("stack", psm_.stack())); + refrtag("stack", psm_.stack()) + ); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index a8544687..895aed10 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -16,9 +16,9 @@ namespace xo { using xo::scm::SchematikaParser; using xo::scm::ASyntaxStateMachine; using xo::scm::syntaxstatetype; - using xo::scm::DDefineSsm; +// using xo::scm::DDefineSsm; using xo::scm::DExpectExprSsm; - using xo::scm::defexprstatetype; +// using xo::scm::defexprstatetype; //using xo::scm::ParserResult; //using xo::scm::parser_result_type; using xo::scm::Token; From c6290b6879c9438a01bd99eddf43f9b6c598c31f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 21:36:38 -0500 Subject: [PATCH 098/258] xo-expression2: bugfix: init for TypeRef.td_ --- xo-expression2/include/xo/expression2/TypeRef.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xo-expression2/include/xo/expression2/TypeRef.hpp b/xo-expression2/include/xo/expression2/TypeRef.hpp index 7ec6e388..eecb438d 100644 --- a/xo-expression2/include/xo/expression2/TypeRef.hpp +++ b/xo-expression2/include/xo/expression2/TypeRef.hpp @@ -66,7 +66,7 @@ namespace xo { * May be null when this TypeRef created, * but expected to be immutable once established. **/ - TypeDescr td_; + TypeDescr td_ = nullptr; }; } /*namespace scm*/ From 3bae8cbb579969e746fdbe0f9065077e6432e7c2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 26 Jan 2026 22:40:56 -0500 Subject: [PATCH 099/258] xo-reader2: + DProgressSsm.on_parser_expression_with_semicolon --- xo-reader2/src/reader2/DProgressSsm.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index e085f8cf..bd48e58c 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -527,9 +527,25 @@ namespace xo { DProgressSsm::on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_expression("DProgressSsm::on_parsed_expression_with_semicolon", - expr, - this->get_expect_str()); + scope log(XO_DEBUG(p_psm->debug_flag()), + xtag("expr", expr)); + + if (op_type_ == optype::invalid) { + p_psm->illegal_parsed_expression + ("DProgressSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + return; + } + + this->rhs_ = expr; + + obj expr2 = this->assemble_expr(p_psm); + + if (expr2) { + p_psm->pop_ssm(); + p_psm->on_parsed_expression_with_semicolon(expr2); + } } #ifdef NOT_YET From e24326451149cb48a9e98451844804b5d9d07df2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Jan 2026 10:09:26 -0500 Subject: [PATCH 100/258] xo-expression2: + DIfElseExpr + utest --- xo-expression2/CMakeLists.txt | 26 ++ .../idl/IExpression_DIfElseExpr.json5 | 12 + .../idl/IPrintable_DIfElseExpr.json5 | 13 + .../include/xo/expression2/DIfElseExpr.hpp | 230 ++++++++++++ .../detail/IExpression_DIfElseExpr.hpp | 66 ++++ .../detail/IPrintable_DIfElseExpr.hpp | 62 ++++ .../include/xo/expression2/exprtype.hpp | 2 +- xo-expression2/src/expression2/CMakeLists.txt | 4 + .../src/expression2/DDefineExpr.cpp | 2 +- .../src/expression2/DIfElseExpr.cpp | 184 ++++++++++ .../expression2/IExpression_DIfElseExpr.cpp | 45 +++ .../expression2/IPrintable_DIfElseExpr.cpp | 28 ++ .../expression2_register_facets.cpp | 10 +- xo-expression2/utest/CMakeLists.txt | 1 + xo-expression2/utest/DIfElseExpr.test.cpp | 345 ++++++++++++++++++ .../interpreter2/VirtualSchematikaMachine.hpp | 6 + .../interpreter2/VirtualSchematikaMachine.cpp | 10 + xo-reader2/src/reader2/DProgressSsm.cpp | 7 +- 18 files changed, 1047 insertions(+), 6 deletions(-) create mode 100644 xo-expression2/idl/IExpression_DIfElseExpr.json5 create mode 100644 xo-expression2/idl/IPrintable_DIfElseExpr.json5 create mode 100644 xo-expression2/include/xo/expression2/DIfElseExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp create mode 100644 xo-expression2/src/expression2/DIfElseExpr.cpp create mode 100644 xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp create mode 100644 xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp create mode 100644 xo-expression2/utest/DIfElseExpr.test.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 869f891d..5fc6d451 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -150,6 +150,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-expression-ifelseexpr + FACET_PKG xo_expression2 + FACET Expression + REPR IfElseExpr + INPUT idl/IExpression_DIfElseExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-ifelseexpr + FACET_PKG xo_printable2 + FACET Printable + REPR IfElseExpr + INPUT idl/IPrintable_DIfElseExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-uniquestring diff --git a/xo-expression2/idl/IExpression_DIfElseExpr.json5 b/xo-expression2/idl/IExpression_DIfElseExpr.json5 new file mode 100644 index 00000000..ed2fb1e8 --- /dev/null +++ b/xo-expression2/idl/IExpression_DIfElseExpr.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ "\"Expression.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Expression.json5", + brief: "provide AExpression interface for DIfElseExpr state", + using_doxygen: true, + repr: "DIfElseExpr", + doc: ["doc for IExpression+DIfElseExpr" ], +} diff --git a/xo-expression2/idl/IPrintable_DIfElseExpr.json5 b/xo-expression2/idl/IPrintable_DIfElseExpr.json5 new file mode 100644 index 00000000..a8011385 --- /dev/null +++ b/xo-expression2/idl/IPrintable_DIfElseExpr.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DIfElseExpr", + using_doxygen: true, + repr: "DIfElseExpr", + doc: [ "implement APrintable for DIfElseExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/DIfElseExpr.hpp new file mode 100644 index 00000000..4a1107ca --- /dev/null +++ b/xo-expression2/include/xo/expression2/DIfElseExpr.hpp @@ -0,0 +1,230 @@ +/** @file DIfElseExpr.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Expression.hpp" +#include "TypeRef.hpp" +#include "exprtype.hpp" +#include +//#include +#include +//#include + +namespace xo { + namespace scm { + + /** @class DIfExpr + * @brief abstract syntax tree for a function definition + **/ + class DIfElseExpr { + public: + using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-ifelseexpr-constructors **/ + ///@{ + + /** + * @p ifexpr_type type for value produced by if-expression. + * same as both when_true->valuetype() and + * when_false->valuetype(). + * @p test test-expression; always execute + * @p when_true then-branch; executes only when test succeeds + * @p when_false else-branch; executes only when test fails + **/ + DIfElseExpr(TypeRef ifexpr_type, + obj test_expr, + obj when_true, + obj when_false); + + /** create if-else expression using memory from @p mm. + * @p when_false can be null + **/ + static obj make(obj mm, + obj test, + obj when_true, + obj when_false); + + /** create expression for conditional execution of + * @p when_true or @p when_false, depending on result + * of evaluating expression @p test + **/ + static DIfElseExpr * _make(obj mm, + obj test, + obj when_true, + obj when_false); + + ///@} + /** @defgroup scm-ifelseexpr-access-methods **/ + ///@{ + + obj test() const noexcept { return test_; } + obj when_true() const noexcept { return when_true_; } + obj when_false() const noexcept { return when_false_; } + + ///@} + /** @defgroup scm-ifelseexpr-expression-facet **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::ifexpr; } + TypeRef typeref() const noexcept { return typeref_; } + TypeDescr valuetype() const noexcept { return typeref_.td(); } + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + /** @defgroup scm-ifelseexpr-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + +#ifdef NOT_YET + virtual std::set get_free_variables() const override { + std::set retval = test_->get_free_variables(); + + std::set free_vars; + free_vars = when_true_->get_free_variables(); + for (const auto & s : free_vars) + retval.insert(s); + + free_vars = when_false_->get_free_variables(); + for (const auto & s : free_vars) + retval.insert(s); + + return retval; + } + + virtual std::size_t visit_preorder(VisitFn visitor_fn) override { + std::size_t n = 1; + + visitor_fn(this); + + n += this->test_->visit_preorder(visitor_fn); + n += this->when_true_->visit_preorder(visitor_fn); + n += this->when_false_->visit_preorder(visitor_fn); + + return n; + } + + virtual std::size_t visit_layer(VisitFn visitor_fn) override { + std::size_t n = 1; + + visitor_fn(this); + + n += this->test_->visit_layer(visitor_fn); + n += this->when_true_->visit_layer(visitor_fn); + n += this->when_false_->visit_layer(visitor_fn); + + return n; + } + + virtual rp xform_layer(TransformFn xform_fn) override { + this->test_ = this->test_->xform_layer(xform_fn); + this->when_true_ = this->when_true_->xform_layer(xform_fn); + this->when_false_= this->when_false_->xform_layer(xform_fn); + + return xform_fn(this); + } + + virtual void attach_envs(bp p) override { + test_->attach_envs(p); + when_true_->attach_envs(p); + when_false_->attach_envs(p); + } +#endif + +#ifdef NOT_USING + virtual std::int32_t find_free_vars(std::set> * p_set) override { + return (test_->find_free_vars(p_set) + + when_true_->find_free_vars(p_set) + + when_false_->find_free_vars(p_set)); + } +#endif + +#ifdef NOPE + virtual void display(std::ostream & os) const override; + virtual std::uint32_t pretty_print(const ppindentinfo & ppi) const override; +#endif + + protected: +#ifdef NOT_YET + /** + * @p ifexpr_type type for value produced by if-expression. + * same as both when_true->valuetype() and + * when_false->valuetype(). + * @p test test-expression; always execute + * @p when_true then-branch; executes only when test succeeds + * @p when_false else-branch; executes only when test fails + **/ + IfExpr(TypeDescr ifexpr_type, + rp test, + rp when_true, + rp when_false) + : Expression(exprtype::ifexpr, ifexpr_type), + test_{std::move(test)}, + when_true_{std::move(when_true)}, + when_false_{std::move(when_false)} {} + + static TypeDescr check_consistent_valuetype(const rp & when_true, + const rp & when_false); + + /** determine if-expr valuetype **/ + void establish_valuetype(); +#endif + + private: + /** expression value always has type consistent + * with this description + **/ + TypeRef typeref_; + /** if: + * (if x y z) + * + * executes x; if true execute y; otherwise execute z + **/ + obj test_; + obj when_true_; + obj when_false_; + }; /*IfExpr*/ + +#ifdef NOPE + inline rp + make_ifexpr(const rp & test, + const rp & when_true, + const rp & when_false) + { + return IfExpr::make(test, when_true, when_false); + } + + class IfExprAccess : public IfExpr { + public: + static rp make(rp test, + rp when_true, + rp when_false); + static rp make_empty(); + + void assign_test(rp x) { test_ = std::move(x); } + void assign_when_true(rp x); + void assign_when_false(rp x); + + private: + IfExprAccess(TypeDescr ifexpr_type, + rp test, + rp when_true, + rp when_false) + : IfExpr(ifexpr_type, + std::move(test), + std::move(when_true), + std::move(when_false)) {} + }; +#endif + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DIfElseExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp new file mode 100644 index 00000000..03500a39 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp @@ -0,0 +1,66 @@ +/** @file IExpression_DIfElseExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DIfElseExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DIfElseExpr.json5] + **/ + +#pragma once + +#include "Expression.hpp" +#include "Expression.hpp" +#include "DIfElseExpr.hpp" + +namespace xo { namespace scm { class IExpression_DIfElseExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IExpression_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IExpression_DIfElseExpr + **/ + class IExpression_DIfElseExpr { + public: + /** @defgroup scm-expression-difelseexpr-type-traits **/ + ///@{ + using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; + ///@} + /** @defgroup scm-expression-difelseexpr-methods **/ + ///@{ + // const methods + /** expression type (constant | apply | ..) **/ + static exprtype extype(const DIfElseExpr & self) noexcept; + /** placeholder for type giving possible values for this expression **/ + static TypeRef typeref(const DIfElseExpr & self) noexcept; + /** type giving possible values for this expression. Maybe null before typecheck **/ + static TypeDescr valuetype(const DIfElseExpr & self) noexcept; + + // non-const methods + /** assing to valuetype member. Useful when scaffolding expressions **/ + static void assign_valuetype(DIfElseExpr & self, TypeDescr td) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp new file mode 100644 index 00000000..e9cf67ff --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DIfElseExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DIfElseExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DIfElseExpr.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DIfElseExpr.hpp" + +namespace xo { namespace scm { class IPrintable_DIfElseExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DIfElseExpr + **/ + class IPrintable_DIfElseExpr { + public: + /** @defgroup scm-printable-difelseexpr-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-difelseexpr-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DIfElseExpr & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/exprtype.hpp b/xo-expression2/include/xo/expression2/exprtype.hpp index df4e3be6..952051be 100644 --- a/xo-expression2/include/xo/expression2/exprtype.hpp +++ b/xo-expression2/include/xo/expression2/exprtype.hpp @@ -38,9 +38,9 @@ namespace xo { #endif /** variable reference **/ variable, -#ifdef NOT_YET /** if-then-else **/ ifexpr, +#ifdef NOT_YET /** sequence **/ sequence, /** type conversion **/ diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 7a7013de..840e7070 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -8,6 +8,7 @@ set(SELF_SRCS DVariable.cpp DDefineExpr.cpp DApplyExpr.cpp + DIfElseExpr.cpp TypeRef.cpp @@ -25,6 +26,9 @@ set(SELF_SRCS IExpression_DApplyExpr.cpp IPrintable_DApplyExpr.cpp + IExpression_DIfElseExpr.cpp + IPrintable_DIfElseExpr.cpp + DLocalSymtab.cpp DGlobalSymtab.cpp diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index ba2304ad..961fbecc 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -1,5 +1,5 @@ /** @file DDefineExpr.cpp -* + * * @author Roland Conybeare, Jan 2026 **/ diff --git a/xo-expression2/src/expression2/DIfElseExpr.cpp b/xo-expression2/src/expression2/DIfElseExpr.cpp new file mode 100644 index 00000000..0e18114e --- /dev/null +++ b/xo-expression2/src/expression2/DIfElseExpr.cpp @@ -0,0 +1,184 @@ +/** @file DIfElseExpr.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DIfElseExpr.hpp" +#include "detail/IExpression_DIfElseExpr.hpp" +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::reflect::typeseq; + using xo::facet::FacetRegistry; + + namespace scm { + DIfElseExpr::DIfElseExpr(TypeRef ifexpr_tref, + obj test_expr, + obj when_true, + obj when_false) + : typeref_{ifexpr_tref}, + test_{test_expr}, + when_true_{when_true}, + when_false_{when_false} + {} + + obj + DIfElseExpr::make(obj mm, + obj test, + obj when_true, + obj when_false) + { + return obj + (_make(mm, + test, when_true, when_false)); + } + + DIfElseExpr * + DIfElseExpr::_make(obj mm, + obj test, + obj when_true, + obj when_false) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DIfElseExpr)); + + // just crete typevar here, then rely on type checking + // later + + auto prefix = TypeRef::prefix_type::from_chars("if"); + TypeRef tref = TypeRef::dwim(prefix, nullptr); + + return new (mem) DIfElseExpr(tref, + test, + when_true, + when_false); + } + + void + DIfElseExpr::assign_valuetype(TypeDescr td) noexcept + { + typeref_.resolve(td); + } + + bool + DIfElseExpr::pretty(const ppindentinfo & ppii) const + { + auto test + = FacetRegistry::instance().try_variant(test_); + auto when_true + = FacetRegistry::instance().try_variant(when_true_); + auto when_false + = FacetRegistry::instance().try_variant(when_false_); + + + return ppii.pps()->pretty_struct + (ppii, + "DIfElseExpr", + refrtag("typeref", typeref_), + refrtag("test", test), + refrtag("when_true", when_true), + refrtag("when_false", when_false)); + } + + // ---------------------------------------------------------------- + +#ifdef NOPE + auto IfExpr::check_consistent_valuetype(const rp & when_true, + const rp & when_false) -> TypeDescr + { + if (when_true->valuetype() != when_false->valuetype()) + return nullptr; + + return when_true->valuetype(); + } + + void IfExpr::establish_valuetype() + { + if (this->when_true_.get() && this->when_false_.get()) + this->assign_valuetype(check_consistent_valuetype(this->when_true_, this->when_false_)); + } + + rp + IfExpr::make(const rp & test, + const rp & when_true, + const rp & when_false) + { + /** TODO: verify test returns _boolean_ type **/ + + if (when_true->valuetype() != when_false->valuetype()) { + throw std::runtime_error + (tostr("IfExpr::make:" + " types {T1,T2} found for branches of if-expr" + " where equal types expected", + xtag("T1", when_true->valuetype()->canonical_name()), + xtag("T2", when_false->valuetype()->canonical_name()))); + } + + /* arbitrary choice here */ + auto ifexpr_type = when_true->valuetype(); + + return new IfExpr(ifexpr_type, + test, + when_true, + when_false); + } /*make*/ + + void + IfExpr::display(std::ostream & os) const { + os << ""; + } /*display*/ + + std::uint32_t + IfExpr::pretty_print(const ppindentinfo & ppii) const { + return ppii.pps()->pretty_struct(ppii, "IfExpr", + refrtag("test", test_), + refrtag("when_true", when_true_), + refrtag("when_false", when_false_)); + } + + rp + IfExprAccess::make(rp test, + rp when_true, + rp when_false) + { + auto ifexpr_type = check_consistent_valuetype(when_true, when_false); + + return new IfExprAccess(ifexpr_type, std::move(test), std::move(when_true), std::move(when_false)); + } + + rp + IfExprAccess::make_empty() + { + return new IfExprAccess(nullptr /*ifexpr_valuetype*/, + nullptr /*test*/, + nullptr /*when_true*/, + nullptr /*when_false*/); + } + + void + IfExprAccess::assign_when_true(rp x) + { + this->when_true_ = std::move(x); + } + + void + IfExprAccess::assign_when_false(rp x) + { + this->when_false_ = std::move(x); + } +#endif + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DIfElseExpr.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp new file mode 100644 index 00000000..78680310 --- /dev/null +++ b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp @@ -0,0 +1,45 @@ +/** @file IExpression_DIfElseExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DIfElseExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DIfElseExpr.json5] +**/ + +#include "detail/IExpression_DIfElseExpr.hpp" + +namespace xo { + namespace scm { + auto + IExpression_DIfElseExpr::extype(const DIfElseExpr & self) noexcept -> exprtype + { + return self.extype(); + } + + auto + IExpression_DIfElseExpr::typeref(const DIfElseExpr & self) noexcept -> TypeRef + { + return self.typeref(); + } + + auto + IExpression_DIfElseExpr::valuetype(const DIfElseExpr & self) noexcept -> TypeDescr + { + return self.valuetype(); + } + + auto + IExpression_DIfElseExpr::assign_valuetype(DIfElseExpr & self, TypeDescr td) noexcept -> void + { + self.assign_valuetype(td); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IExpression_DIfElseExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp new file mode 100644 index 00000000..ec68b9fc --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DIfElseExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DIfElseExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DIfElseExpr.json5] +**/ + +#include "detail/IPrintable_DIfElseExpr.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DIfElseExpr::pretty(const DIfElseExpr & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DIfElseExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index fc6ef3c1..8ab2ff51 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include + #include #include #include @@ -44,7 +47,8 @@ namespace xo { // +- Constant // +- Variable // +- DefineExpr - // \- ApplyExpr + // +- ApplyExpr + // \- IfElseExpr FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -58,11 +62,15 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DUniqueString.tseq", typeseq::id())); log && log(xtag("DDefineExpr.tseq", typeseq::id())); log && log(xtag("DVariable.tseq", typeseq::id())); log && log(xtag("DConstant.tseq", typeseq::id())); log && log(xtag("DApplyExpr.tseq", typeseq::id())); + log && log(xtag("DIfElseExpr.tseq", typeseq::id())); log && log(xtag("AExpression.tqseq", typeseq::id())); diff --git a/xo-expression2/utest/CMakeLists.txt b/xo-expression2/utest/CMakeLists.txt index f464708e..deb1d25a 100644 --- a/xo-expression2/utest/CMakeLists.txt +++ b/xo-expression2/utest/CMakeLists.txt @@ -9,6 +9,7 @@ set(UTEST_SRCS DVariable.test.cpp DApplyExpr.test.cpp DDefineExpr.test.cpp + DIfElseExpr.test.cpp ) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) diff --git a/xo-expression2/utest/DIfElseExpr.test.cpp b/xo-expression2/utest/DIfElseExpr.test.cpp new file mode 100644 index 00000000..a82521a0 --- /dev/null +++ b/xo-expression2/utest/DIfElseExpr.test.cpp @@ -0,0 +1,345 @@ +/** @file DIfElseExpr.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_expression2.hpp" +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +namespace ut { + using xo::S_expression2_tag; + using xo::scm::DIfElseExpr; + using xo::scm::DConstant; + using xo::scm::DFloat; + using xo::scm::DBoolean; + using xo::scm::AExpression; + using xo::mm::CollectorTypeRegistry; + using xo::mm::AAllocator; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::mm::DX1Collector; + using xo::mm::CollectorConfig; + using xo::mm::ArenaConfig; + using xo::print::APrintable; + using xo::print::ppstate_standalone; + using xo::print::ppconfig; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::facet::obj; + using xo::reflect::Reflect; + using xo::InitEvidence; + using xo::InitSubsys; + using xo::scope; + + static InitEvidence s_init = InitSubsys::require(); + + TEST_CASE("DIfElseExpr-init", "[expression2][DIfElseExpr]") + { + REQUIRE(s_init.evidence()); + } + + TEST_CASE("DIfElseExpr-make", "[expression2][DIfElseExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "difelseexpr_make_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + // Create test expression: constant true + obj bval = DBoolean::box(alloc, true); + auto test_expr = DConstant::make(alloc, bval); + REQUIRE(test_expr.data() != nullptr); + + // Create when_true expression: constant 1.0 + obj fval1 = DFloat::box(alloc, 1.0); + auto when_true_expr = DConstant::make(alloc, fval1); + REQUIRE(when_true_expr.data() != nullptr); + + // Create when_false expression: constant 2.0 + obj fval2 = DFloat::box(alloc, 2.0); + auto when_false_expr = DConstant::make(alloc, fval2); + REQUIRE(when_false_expr.data() != nullptr); + + // Create if-else expression: if true then 1.0 else 2.0 + auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr); + REQUIRE(ifexpr.data() != nullptr); + } + + TEST_CASE("DIfElseExpr-test", "[expression2][DIfElseExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "difelseexpr_test_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj bval = DBoolean::box(alloc, true); + auto test_expr = DConstant::make(alloc, bval); + + obj fval1 = DFloat::box(alloc, 1.0); + auto when_true_expr = DConstant::make(alloc, fval1); + + obj fval2 = DFloat::box(alloc, 2.0); + auto when_false_expr = DConstant::make(alloc, fval2); + + auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr); + REQUIRE(ifexpr.data() != nullptr); + + obj test = ifexpr.data()->test(); + REQUIRE(test.data() != nullptr); + REQUIRE(test.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DIfElseExpr-when-true", "[expression2][DIfElseExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "difelseexpr_when_true_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj bval = DBoolean::box(alloc, true); + auto test_expr = DConstant::make(alloc, bval); + + obj fval1 = DFloat::box(alloc, 1.0); + auto when_true_expr = DConstant::make(alloc, fval1); + + obj fval2 = DFloat::box(alloc, 2.0); + auto when_false_expr = DConstant::make(alloc, fval2); + + auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr); + REQUIRE(ifexpr.data() != nullptr); + + obj wt = ifexpr.data()->when_true(); + REQUIRE(wt.data() != nullptr); + REQUIRE(wt.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DIfElseExpr-when-false", "[expression2][DIfElseExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "difelseexpr_when_false_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj bval = DBoolean::box(alloc, false); + auto test_expr = DConstant::make(alloc, bval); + + obj fval1 = DFloat::box(alloc, 1.0); + auto when_true_expr = DConstant::make(alloc, fval1); + + obj fval2 = DFloat::box(alloc, 2.0); + auto when_false_expr = DConstant::make(alloc, fval2); + + auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr); + REQUIRE(ifexpr.data() != nullptr); + + obj wf = ifexpr.data()->when_false(); + REQUIRE(wf.data() != nullptr); + REQUIRE(wf.extype() == xo::scm::exprtype::constant); + } + + TEST_CASE("DIfElseExpr-extype", "[expression2][DIfElseExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "difelseexpr_extype_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj bval = DBoolean::box(alloc, true); + auto test_expr = DConstant::make(alloc, bval); + + obj fval1 = DFloat::box(alloc, 1.0); + auto when_true_expr = DConstant::make(alloc, fval1); + + obj fval2 = DFloat::box(alloc, 2.0); + auto when_false_expr = DConstant::make(alloc, fval2); + + auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr); + REQUIRE(ifexpr.data() != nullptr); + REQUIRE(ifexpr.data()->extype() == xo::scm::exprtype::ifexpr); + } + + TEST_CASE("DIfElseExpr-valuetype", "[expression2][DIfElseExpr]") + { + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "difelseexpr_valuetype_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj bval = DBoolean::box(alloc, true); + auto test_expr = DConstant::make(alloc, bval); + + obj fval1 = DFloat::box(alloc, 1.0); + auto when_true_expr = DConstant::make(alloc, fval1); + + obj fval2 = DFloat::box(alloc, 2.0); + auto when_false_expr = DConstant::make(alloc, fval2); + + auto ifexpr = DIfElseExpr::make(alloc, test_expr, when_true_expr, when_false_expr); + REQUIRE(ifexpr.data() != nullptr); + + // valuetype may be null before type resolution + // just verify we can call it + ifexpr.data()->valuetype(); + } + + TEST_CASE("DIfElseExpr-pretty", "[expression2][DIfElseExpr][pp]") + { + scope log(XO_DEBUG(true)); + + REQUIRE(s_init.evidence()); + + CollectorConfig cfg{ + .name_ = "difelseexpr_pretty_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{4096, 4096}}, + .debug_flag_ = false, + }; + + DX1Collector gc(cfg); + auto alloc = with_facet::mkobj(&gc); + auto coll = with_facet::mkobj(&gc); + + bool ok = CollectorTypeRegistry::instance().install_types(coll); + REQUIRE(ok); + + obj bval = DBoolean::box(alloc, true); + auto test_expr = DConstant::make(alloc, bval); + + obj fval1 = DFloat::box(alloc, 1.0); + auto when_true_expr = DConstant::make(alloc, fval1); + + obj fval2 = DFloat::box(alloc, 2.0); + auto when_false_expr = DConstant::make(alloc, fval2); + + auto ifexpr = DIfElseExpr::make(alloc, + test_expr, + when_true_expr, when_false_expr); + REQUIRE(ifexpr.data() != nullptr); + + std::stringstream ss; + ppconfig ppc; + ppstate_standalone pps(&ss, 0, &ppc); + + obj ifexpr_pr(ifexpr.data()); + pps.pretty(ifexpr_pr); + + std::string output = ss.str(); + + log && log(output); + + CHECK(output.find("DIfElseExpr") != std::string::npos); + } +} + +/* end DIfElseExpr.test.cpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index e8e58dbc..066b7ffd 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -63,6 +63,12 @@ namespace xo { **/ void _do_eval_apply_op(); + /** evaluate an if-else expression + * Require: + * - expression in @ref expr_ + **/ + void _do_eval_if_else_op(); + private: /* * Some registers are preserved by evaluation: diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index b2789c26..11a60c64 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -54,6 +54,9 @@ namespace xo { case exprtype::apply: _do_eval_apply_op(); break; + case exprtype::ifexpr: + _do_eval_if_else_op(); + break; } } @@ -87,6 +90,13 @@ namespace xo { // not implemented assert(false); } + + void + VirtualSchematikaMachine::_do_eval_if_else_op() + { + // not implemented + assert(false); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index bd48e58c..76574c7b 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -1186,9 +1186,10 @@ namespace xo { case optype::op_multiply: { - auto pm_obj = with_facet::mkobj(&Primitives::s_mul_gco_gco_pm); - - auto fn_expr = DConstant::make(p_psm->expr_alloc(), pm_obj); + auto pm_obj = (with_facet::mkobj + (&Primitives::s_mul_gco_gco_pm)); + auto fn_expr = (DConstant::make + (p_psm->expr_alloc(), pm_obj)); /* note: * 1. don't assume we know lhs_ / rhs_ value types yet. From c052c5c509799d9dbed00f31509d5d8dcbd6a65e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Jan 2026 15:50:10 -0500 Subject: [PATCH 101/258] xo-reader2: support if-then-else expressions. + detailed utest --- .../include/xo/expression2/DIfElseExpr.hpp | 10 + .../src/expression2/DIfElseExpr.cpp | 53 +- xo-reader2/CMakeLists.txt | 26 + xo-reader2/idl/IPrintable_DIfElseSsm.json5 | 13 + .../idl/ISyntaxStateMachine_DIfElseSsm.json5 | 13 + xo-reader2/include/xo/reader2/DDefineSsm.hpp | 3 +- .../include/xo/reader2/DExpectExprSsm.hpp | 52 +- xo-reader2/include/xo/reader2/DIfElseSsm.hpp | 221 ++++++++ .../include/xo/reader2/DProgressSsm.hpp | 13 +- .../xo/reader2/ssm/IPrintable_DIfElseSsm.hpp | 62 ++ .../ssm/ISyntaxStateMachine_DIfElseSsm.hpp | 73 +++ .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 4 + xo-reader2/src/reader2/DExpectExprSsm.cpp | 132 ++--- xo-reader2/src/reader2/DExprSeqState.cpp | 17 +- xo-reader2/src/reader2/DIfElseSsm.cpp | 530 ++++++++++++++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 73 ++- .../src/reader2/IPrintable_DIfElseSsm.cpp | 28 + .../ISyntaxStateMachine_DIfElseSsm.cpp | 59 ++ .../src/reader2/reader2_register_facets.cpp | 7 + xo-reader2/src/reader2/syntaxstatetype.cpp | 2 + xo-reader2/utest/SchematikaParser.test.cpp | 108 +++- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 + 23 files changed, 1354 insertions(+), 150 deletions(-) create mode 100644 xo-reader2/idl/IPrintable_DIfElseSsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/DIfElseSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DIfElseSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp create mode 100644 xo-reader2/src/reader2/DIfElseSsm.cpp create mode 100644 xo-reader2/src/reader2/IPrintable_DIfElseSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp diff --git a/xo-expression2/include/xo/expression2/DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/DIfElseExpr.hpp index 4a1107ca..8222834a 100644 --- a/xo-expression2/include/xo/expression2/DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/DIfElseExpr.hpp @@ -59,6 +59,12 @@ namespace xo { obj when_true, obj when_false); + /** create empty if-else expression using memory from @p mm **/ + static obj make_empty(obj mm); + + /** create empty if-else expression using memory from @p mm **/ + static DIfElseExpr * _make_empty(obj mm); + ///@} /** @defgroup scm-ifelseexpr-access-methods **/ ///@{ @@ -67,6 +73,10 @@ namespace xo { obj when_true() const noexcept { return when_true_; } obj when_false() const noexcept { return when_false_; } + void assign_test(obj x) { this->test_ = x; } + void assign_when_true(obj x) { this->when_true_ = x; } + void assign_when_false(obj x) { this->when_false_ = x; } + ///@} /** @defgroup scm-ifelseexpr-expression-facet **/ ///@{ diff --git a/xo-expression2/src/expression2/DIfElseExpr.cpp b/xo-expression2/src/expression2/DIfElseExpr.cpp index 0e18114e..d858dfab 100644 --- a/xo-expression2/src/expression2/DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/DIfElseExpr.cpp @@ -57,6 +57,21 @@ namespace xo { when_false); } + obj + DIfElseExpr::make_empty(obj mm) + { + return obj(_make_empty(mm)); + } + + DIfElseExpr * + DIfElseExpr::_make_empty(obj mm) + { + return _make(mm, + obj() /*test*/, + obj() /*when_true*/, + obj() /*when_false*/); + } + void DIfElseExpr::assign_valuetype(TypeDescr td) noexcept { @@ -76,14 +91,33 @@ namespace xo { = FacetRegistry::instance().try_variant(when_false_); - - return ppii.pps()->pretty_struct - (ppii, - "DIfElseExpr", - refrtag("typeref", typeref_), - refrtag("test", test), - refrtag("when_true", when_true), - refrtag("when_false", when_false)); + if (when_false) { + return ppii.pps()->pretty_struct + (ppii, + "DIfElseExpr", + refrtag("typeref", typeref_), + refrtag("test", test), + refrtag("when_true", when_true), + refrtag("when_false", when_false)); + } else if (when_true) { + return ppii.pps()->pretty_struct + (ppii, + "DIfElseExpr", + refrtag("typeref", typeref_), + refrtag("test", test), + refrtag("when_true", when_true)); + } else if (test) { + return ppii.pps()->pretty_struct + (ppii, + "DIfElseExpr", + refrtag("typeref", typeref_), + refrtag("test", test)); + } else { + return ppii.pps()->pretty_struct + (ppii, + "DIfElseExpr", + refrtag("typeref", typeref_)); + } } // ---------------------------------------------------------------- @@ -141,10 +175,13 @@ namespace xo { std::uint32_t IfExpr::pretty_print(const ppindentinfo & ppii) const { + return ppii.pps()->pretty_struct(ppii, "IfExpr"); +#ifdef NOT_YET return ppii.pps()->pretty_struct(ppii, "IfExpr", refrtag("test", test_), refrtag("when_true", when_true_), refrtag("when_false", when_false_)); +#endif } rp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 43c747f6..a4124f45 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -86,6 +86,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-ifelsessm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR IfElseSsm + INPUT idl/ISyntaxStateMachine_DIfElseSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-ifelsessm + FACET_PKG xo_printable2 + FACET Printable + REPR Ifelsessm + INPUT idl/IPrintable_DIfElseSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-expectsymbolssm diff --git a/xo-reader2/idl/IPrintable_DIfElseSsm.json5 b/xo-reader2/idl/IPrintable_DIfElseSsm.json5 new file mode 100644 index 00000000..28fab147 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DIfElseSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DIfElseSsm", + using_doxygen: true, + repr: "DIfElseSsm", + doc: [ "implement APrintable for DIfElseSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 new file mode 100644 index 00000000..5e7e828b --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DIfElseSsm", + using_doxygen: true, + repr: "DIfElseSsm", + doc: [ "implement ASyntaxStateMachine for DIfElseSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 9f707fca..6d15c5ee 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -113,7 +113,7 @@ namespace xo { syntaxstatetype ssm_type() const noexcept; /** text describing expected/allowed input to this ssm in current state. - * Intended to drive error mesages + * Intended to drive error messages **/ std::string_view get_expect_str() const noexcept; @@ -212,6 +212,7 @@ namespace xo { /** @defgroup scm-define-printable-facet printable facet methods **/ ///@{ + /** pretty-printer support **/ bool pretty(const ppindentinfo & ppii) const; ///@} diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 85d4e5e1..b994b498 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -41,6 +41,34 @@ namespace xo { bool allow_defs() const noexcept { return allow_defs_; } bool cxl_on_rightbrace() const noexcept { return cxl_on_rightbrace_; } + ///@} + /** @defgroup scm-expectexpr-methods general methods **/ + ///@{ + + /** step state machine for this syntax on incoming boolean literal token @p tkk + * with overall parser state in @p p_psm + **/ + void on_bool_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming f64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_f64_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming i64 token @p tk, + * overall parser state in @p p_psm + **/ + void on_i64_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming string token @p tk, + * overall parser state in @p p_psm + **/ + void on_string_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectexpr-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -89,30 +117,6 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax on incoming string token @p tk, - * overall parser state in @p p_psm - **/ - void on_string_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming f64 token @p tk, - * overall parser state in @p p_psm - **/ - void on_f64_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming i64 token @p tk, - * overall parser state in @p p_psm - **/ - void on_i64_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming bool token @p tk, - * overall parser state in @p p_psm - **/ - void on_bool_token(const Token & tk, - ParserStateMachine * p_psm); - /** update state for this syntax on incoming semicolon token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp new file mode 100644 index 00000000..9b3e5d17 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp @@ -0,0 +1,221 @@ +/** @file DIfElseSsm.hpp + * + * @author Roland Conybeare, Jul 2025 + **/ + +#pragma once + +#include +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include +#include +//#include "exprstate.hpp" +//#include "xo/indentlog/print/ppdetail_atomic.hpp" + +namespace xo { + namespace scm { + /** + * if test-expr then then-expr else else-expr ; + * ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | + * | if_1 if_2 if_3 if_4 if_5 if_6 + * if_0 + * + * if_0 --on_if_token()--> if_1 + * if_1 --on_expr()--> if_2 + * if_2 --on_then_token()--> if_3 + * if_3 --on_expr()--> if_4 + * if_4 --on_else_token()--> if_5 + * --on_semicolon_token()--> (done) + * if_5 --on_expr()-->if_6 + * if_6 --on_semicolon_token()--> (done) + **/ + enum class ifexprstatetype { + invalid = -1, + + if_0, + if_1, + if_2, + if_3, + if_4, + if_5, + if_6, + + N, + }; + + extern const char * ifexprstatetype_descr(ifexprstatetype x); + + std::ostream & + operator<<(std::ostream & os, ifexprstatetype x); + + /** @class DIfElseSsm + * @brief syntax state machine for parsing a conditional expression + **/ + class DIfElseSsm { + public: + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-ifelsessm-expression-ctors constructors **/ + ///@{ + explicit DIfElseSsm(DIfElseExpr * ifelse_expr); + +#ifdef NOT_YET + /** create instance using memory from @p parser_mm + * with initial scaffold @p ifelse_expr + **/ + static obj make(DArena & parser_mm, + DIfElseExpr * ifelse_expr); +#endif + + /** create instance using memory from @p parser_mm + * with initial scaffold @p ifelse_expr. + **/ + static DIfElseSsm * _make(DArena & parser_mm, + DIfElseExpr * ifelse_expr); + + /** start nested parser for an if-else expression + * on top of parser state machine @p p_psm. + * Use @p parser_mm to allocate syntax state machines + * (i.e. temporary memory needed only during parsing) + * Use @p expr_mm to allocate expressions. + **/ + static void start(DArena & parser_mm, + obj expr_mm, + ParserStateMachine * p_psm); + ///@} + /** @defgroup scm-ifelsessm-expression-methods general methods **/ + ///@{ + + /** operate state machine on if-token input @p tk, + * with overall parser state in @p p_psm + **/ + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); + + /** operate state machine on then-token input @p tk, + * with overall parser state in @p p_psm + **/ + void on_then_token(const Token & tk, + ParserStateMachine * p_psm); + + /** operate state machine on else-token input @p tk, + * with overall parser state in @p p_psm + **/ + void on_else_token(const Token & tk, + ParserStateMachine * p_psm); + + /** victory: report completed @ref if_expr_ to parent ssm, + * after removing this ssm from parser stack + **/ + void finish_and_continue(ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-ifelsessm-expression-facet expression facet methods **/ + ///@{ + + /** identifies this state machine **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error messages + **/ + std::string_view get_expect_str() const noexcept; + + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** operate state machine for this syntax on incoming semicolon token @p tk + * with overall parser state in @p p_psm + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing an expression @p expr, + * overall parser state in @p p_psm. + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a type description @p td; + * overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing an expression @p expr, + * followed by semicolon, + * with overall parser state in @p p_psm. + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a symbol @p sym, + * with overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-ifelsessm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + +#ifdef NOT_YET + // ----- inherited from exprstate ----- + + virtual const char * get_expect_str() const override; + + virtual void on_if_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_then_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_else_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_semicolon_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + + virtual void on_expr(bp expr, + parserstatemachine * p_psm) override; + virtual void on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) override; + + virtual void print(std::ostream & os) const override; +#endif + + private: +#ifdef NOT_YET + static std::unique_ptr make(); + + /** exit this exprstate, + * and deliver @ref if_expr_ to parent exprstate + **/ + void finish_and_continue(parserstatemachine * p_psm); +#endif + + private: + ifexprstatetype ifstate_ = ifexprstatetype::invalid; + /** scaffold ifelse-expression here. + * This will eventually be the output of this ssm + **/ + obj if_expr_; + + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DIfElseSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 31b3a55d..788c10ca 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -126,6 +126,17 @@ namespace xo { **/ obj assemble_expr(ParserStateMachine * p_psm); + /** @defgroup scm-progressssm-methods general methods **/ + ///@{ + + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); + void on_then_token(const Token & tk, + ParserStateMachine * p_psm); + void on_else_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} /** @defgroup scm-progressssm-ssm-facet syntaxstatemachine facet methods **/ /// @{ @@ -139,8 +150,6 @@ namespace xo { ParserStateMachine * p_psm); void on_def_token(const Token & tk, ParserStateMachine * p_psm); - void on_if_token(const Token & tk, - ParserStateMachine * p_psm); void on_colon_token(const Token & tk, ParserStateMachine * p_psm); void on_singleassign_token(const Token & tk, diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DIfElseSsm.hpp new file mode 100644 index 00000000..e9a40c75 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DIfElseSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DIfElseSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DIfElseSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DIfElseSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DIfElseSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DIfElseSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DIfElseSsm + **/ + class IPrintable_DIfElseSsm { + public: + /** @defgroup scm-printable-difelsessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-difelsessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DIfElseSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp new file mode 100644 index 00000000..2101b8e1 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp @@ -0,0 +1,73 @@ +/** @file ISyntaxStateMachine_DIfElseSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DIfElseSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DIfElseSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DIfElseSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DIfElseSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DIfElseSsm + **/ + class ISyntaxStateMachine_DIfElseSsm { + public: + /** @defgroup scm-syntaxstatemachine-difelsessm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-difelsessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DIfElseSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DIfElseSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DIfElseSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DIfElseSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DIfElseSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index d7340b25..796743d7 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -33,6 +33,9 @@ namespace xo { /** handle define-expression. See @ref DDefineSsm **/ defexpr, + /** handle ifelse-expression. See @ref DIfElseSsm **/ + ifelseexpr, + /** rhs expression. state exists to achieve 1-token lookahead **/ progress, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index e18cce73..2ab9d917 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -25,6 +25,10 @@ set(SELF_SRCS ISyntaxStateMachine_DDefineSsm.cpp IPrintable_DDefineSsm.cpp + DIfElseSsm.cpp + ISyntaxStateMachine_DIfElseSsm.cpp + IPrintable_DIfElseSsm.cpp + DExpectSymbolSsm.cpp ISyntaxStateMachine_DExpectSymbolSsm.cpp IPrintable_DExpectSymbolSsm.cpp diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 7a82ad1c..4f61df72 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -11,8 +11,14 @@ #include "syntaxstatetype.hpp" #include #include +#include +#include +#include +#include #include #include +#include +#include #include #include @@ -233,12 +239,21 @@ namespace xo { } void - DExpectExprSsm::on_string_token(const Token & tk, - ParserStateMachine * p_psm) + DExpectExprSsm::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DExpectExprSsm::on_string_token", - tk, - this->get_expect_str()); + auto flag = DBoolean::box(p_psm->expr_alloc(), + tk.bool_value()); + + auto expr = DConstant::make(p_psm->expr_alloc(), flag); + + // DProgressSsm responsible for resolving cases like + // true; + // true && false; + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); } void @@ -268,18 +283,48 @@ namespace xo { DExpectExprSsm::on_i64_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DExpectExprSsm::on_i64_token", - tk, - this->get_expect_str()); + auto i64o = DInteger::box(p_psm->expr_alloc(), + tk.i64_value()); + + auto expr = DConstant::make(p_psm->expr_alloc(), i64o); + + // DProgressSsm responsible for resolving cases like + // 1, + // 1; + // 1 + 2; + // 1 + 2 .. // could be followed by infix + // 1 + 2 * 3; + // 1 + 2 * 3 .. // could be followed by infix + // 1 * (2 + 3) + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); } void - DExpectExprSsm::on_bool_token(const Token & tk, - ParserStateMachine * p_psm) + DExpectExprSsm::on_string_token(const Token & tk, + ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DExpectExprSsm::on_bool_token", - tk, - this->get_expect_str()); + auto str = DString::from_str(p_psm->expr_alloc(), + tk.text()); + auto str_o = obj(str); + + auto expr = DConstant::make(p_psm->expr_alloc(), str_o); + + /* e.g. + * def msg = "hello, world"; + * \----tk----/ + * + * DProgressSsm responsible for operators that apply to string + * "foo"; + * "foo" <= "bar" + * "foo" + ", she said"; + */ + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); } void @@ -313,9 +358,8 @@ namespace xo { DExpectExprSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_expression("DExpectExprSsm::on_parsed_expression", - expr, - this->get_expect_str()); + p_psm->pop_ssm(); + p_psm->on_parsed_expression(expr); } void @@ -464,62 +508,6 @@ namespace xo { return; } - void - expect_expr_xs::on_bool_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - progress_xs::start - (Constant::make(tk.bool_value()), - p_psm); - } - - void - expect_expr_xs::on_i64_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag()), - xtag("tk", tk), - xtag("do", "push progress xs w/ tk value")); - - progress_xs::start - (Constant::make(tk.i64_value()), - p_psm); - } - - void - expect_expr_xs::on_f64_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - //constexpr const char * self_name = "exprstate::on_f64_token"; - - /* e.g. - * def pi = 3.14159265; - * \---tk---/ - */ - progress_xs::start - (Constant::make(tk.f64_value()), - p_psm); - } - - void - expect_expr_xs::on_string_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - /* e.g. - * def msg = "hello, world"; - * \----tk----/ - */ - progress_xs::start - (Constant::make(tk.text()), - p_psm); - } - void expect_expr_xs::on_expr(bp expr, parserstatemachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index e926565d..cfd92683 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -7,6 +7,7 @@ #include "DDefineSsm.hpp" #include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" #include +#include #include #include #include @@ -246,20 +247,20 @@ namespace xo { { switch (seqtype_) { case exprseqtype::toplevel_interactive: - p_psm->illegal_input_on_token("DExprSeqState::on_if_token", - tk, - this->get_expect_str()); - //assert(false); // DfElseState::start(p_psm); - break; + DIfElseSsm::start(p_psm->parser_alloc(), + p_psm->expr_alloc(), + p_psm); + return; case exprseqtype::toplevel_batch: - p_psm->illegal_input_on_token("DExprSeqState::on_if_token", - tk, - this->get_expect_str()); break; case exprseqtype::N: assert(false); // unreachable break; } + + p_psm->illegal_input_on_token("DExprSeqState::on_if_token", + tk, + this->get_expect_str()); } void diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp new file mode 100644 index 00000000..eca02910 --- /dev/null +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -0,0 +1,530 @@ +/** @file DIfElseSsm.cpp + * + * @author Roland Conybeare, Jul 2025 + **/ + +#include "DIfElseSsm.hpp" +#include "ssm/ISyntaxStateMachine_DIfElseSsm.hpp" +#include "ssm/IPrintable_DDefineSsm.hpp" +#include "DExpectExprSsm.hpp" +#include +#include +#include +//#include "exprstatestack.hpp" +//#include "parserstatemachine.hpp" +//#include "expect_expr_xs.hpp" +//#include "xo/indentlog/print/ppdetail_atomic.hpp" + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::reflect::typeseq; + + namespace scm { + // ----- ifexprstatetype ----- + + const char * + ifexprstatetype_descr(ifexprstatetype x) { + switch (x) { + case ifexprstatetype::invalid: return "invalid"; + case ifexprstatetype::if_0: return "if_0"; + case ifexprstatetype::if_1: return "if_1"; + case ifexprstatetype::if_2: return "if_2"; + case ifexprstatetype::if_3: return "if_3"; + case ifexprstatetype::if_4: return "if_4"; + case ifexprstatetype::if_5: return "if_5"; + case ifexprstatetype::if_6: return "if_6"; + case ifexprstatetype::N: break; + } + + return "ifexprstatetype?"; + } + + std::ostream & + operator<<(std::ostream & os, ifexprstatetype x) { + os << ifexprstatetype_descr(x); + return os; + } + + // ----- DIfElseSsm ----- + + DIfElseSsm::DIfElseSsm(DIfElseExpr * ifelse_expr) : ifstate_{ifexprstatetype::if_0}, + if_expr_{ifelse_expr} + {} + + DIfElseSsm * + DIfElseSsm::_make(DArena & mm, + DIfElseExpr * ifelse_expr) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DIfElseSsm)); + + return new (mem) DIfElseSsm(ifelse_expr); + } + + void + DIfElseSsm::start(DArena & parser_mm, + obj expr_mm, + ParserStateMachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + DIfElseExpr * if_expr = DIfElseExpr::_make_empty(expr_mm); + DIfElseSsm * if_ssm = DIfElseSsm::_make(parser_mm, if_expr); + + obj ssm + = with_facet::mkobj(if_ssm); + + p_psm->push_ssm(ssm); + + // note: triggers poly dispatch + p_psm->on_token(Token::if_token()); + } + + syntaxstatetype + DIfElseSsm::ssm_type() const noexcept + { + return syntaxstatetype::ifelseexpr; + } + + std::string_view + DIfElseSsm::get_expect_str() const noexcept + { + /** + * if test-expr then then-expr else else-expr ; + * ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | + * | if_1 if_2 if_3 if_4 if_5 if_6 + * if_0 + * + * if_0 --on_if_token()--> if_1 + * if_1 --on_expr()--> if_2 + * if_2 --on_then_token()--> if_3 + * if_3 --on_expr()--> if_4 + * if_4 --on_else_token()--> if_5 + * --on_semicolon_token()--> (done) + * if_5 --on_expr()-->if_6 + * if_6 --on_semicolon_token()--> (done) + **/ + switch (this->ifstate_) { + case ifexprstatetype::invalid: + case ifexprstatetype::N: + assert(false); // unreachable + break; + case ifexprstatetype::if_0: + return "if"; + case ifexprstatetype::if_1: + return "expression"; + case ifexprstatetype::if_2: + return "then"; + case ifexprstatetype::if_3: + return "expression"; + case ifexprstatetype::if_4: + return "else|semicolon"; + case ifexprstatetype::if_5: + return "expression"; + case ifexprstatetype::if_6: + return "semicolon"; + } + + return "?expect"; + } + + void + DIfElseSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_symbol: + case tokentype::tk_def: + break; + case tokentype::tk_if: + this->on_if_token(tk, p_psm); + return; + case tokentype::tk_then: + this->on_then_token(tk, p_psm); + return; + case tokentype::tk_else: + this->on_else_token(tk, p_psm); + return; + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_semicolon: + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + p_psm->illegal_input_on_token("DIfElseSsm::on_token", + tk, + this->get_expect_str()); + } + +#ifdef NOT_YET + // ----- if_else_xs ----- + + if_else_xs::if_else_xs(rp if_expr) + : exprstate(exprstatetype::ifexpr), + ifxs_type_{ifexprstatetype::if_0}, + if_expr_{std::move(if_expr)} + {} +#endif + + void + DIfElseSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("ifstate", ifstate_); + + if (ifstate_ == ifexprstatetype::if_0) { + this->ifstate_ = ifexprstatetype::if_1; + + DExpectExprSsm::start(p_psm->parser_alloc(), + p_psm); + return; + } + + p_psm->illegal_input_on_token("DIfElseSsm::on_if_token", + tk, + this->get_expect_str()); + } + + void + DIfElseSsm::on_then_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("ifstate", ifstate_); + + if (ifstate_ == ifexprstatetype::if_2) { + this->ifstate_ = ifexprstatetype::if_3; + + DExpectExprSsm::start(p_psm->parser_alloc(), p_psm); + return; + } + + p_psm->illegal_input_on_token("DIfElseSsm::on_then_token", + tk, + this->get_expect_str()); + } + +#ifdef NOT_YET + void + if_else_xs::on_else_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("ifxs_type", ifxs_type_); + + if (this->ifxs_type_ == ifexprstatetype::if_4) { + this->ifxs_type_ = ifexprstatetype::if_5; + + expect_expr_xs::start(p_psm); + return; + } + + constexpr const char * c_self_name = "if_else_xs::on_else_token"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } +#endif + + void + DIfElseSsm::on_else_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("ifstate", ifstate_); + + if (ifstate_ == ifexprstatetype::if_4) { + this->ifstate_ = ifexprstatetype::if_5; + + DExpectExprSsm::start(p_psm->parser_alloc(), p_psm); + return; + } + + p_psm->illegal_input_on_token("DIfElseSsm::on_else_token", + tk, + this->get_expect_str()); + } + +#ifdef NOT_YET + void + if_else_xs::finish_and_continue(parserstatemachine * p_psm) + { + rp if_expr = this->if_expr_; + std::unique_ptr self = p_psm->pop_exprstate(); + + if (this->ifxs_type_ == ifexprstatetype::if_4) { + /* if no else-branch, then if-expr can't have valuetype */ + if_expr->assign_valuetype(nullptr); + } + + p_psm->top_exprstate().on_expr(if_expr, p_psm); + } +#endif + + void + DIfElseSsm::finish_and_continue(ParserStateMachine * p_psm) + { + p_psm->pop_ssm(); + + // rp if_expr = this->if_expr_; + // std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->on_parsed_expression(if_expr_); + } + +#ifdef NOT_YET + void + if_else_xs::on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + this->finish_and_continue(p_psm); + p_psm->on_rightbrace_token(tk); + } + + void + if_else_xs::on_semicolon_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("ifxs_type", ifxs_type_); + + const char * c_self_name = "if_else_xs::on_semicolon_token"; + + switch (this->ifxs_type_) { + case ifexprstatetype::invalid: + case ifexprstatetype::if_0: + case ifexprstatetype::n_ifexprstatetype: + // unreachable + assert(false); + break; + + case ifexprstatetype::if_1: + case ifexprstatetype::if_2: + case ifexprstatetype::if_3: + case ifexprstatetype::if_5: + this->illegal_input_on_token(c_self_name, tk, get_expect_str(), p_psm); + break; + case ifexprstatetype::if_4: + case ifexprstatetype::if_6: { + this->finish_and_continue(p_psm); + break; + } + } + } +#endif + + void + DIfElseSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("ifstate", ifstate_); + + switch (ifstate_) { + case ifexprstatetype::invalid: + case ifexprstatetype::N: + // unreachable + assert(false); + break; + + case ifexprstatetype::if_0: + case ifexprstatetype::if_1: + case ifexprstatetype::if_2: + case ifexprstatetype::if_3: + case ifexprstatetype::if_5: + break; + case ifexprstatetype::if_4: + case ifexprstatetype::if_6: + this->finish_and_continue(p_psm); + return; + } + + p_psm->illegal_input_on_token("DIfElseSsm::on_semicolon_token", + tk, this->get_expect_str()); + + } + +#ifdef NOT_YET + void + if_else_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("ifxs_type", ifxs_type_)); + + switch (this->ifxs_type_) { + case ifexprstatetype::invalid: + case ifexprstatetype::if_0: + case ifexprstatetype::n_ifexprstatetype: + assert(false); // unreachable + return; + case ifexprstatetype::if_1: + if_expr_->assign_test(expr.promote()); + ifxs_type_ = ifexprstatetype::if_2; + return; + case ifexprstatetype::if_2: + /** error: expecting 'then' **/ + break; + case ifexprstatetype::if_3: + if_expr_->assign_when_true(expr.promote()); + ifxs_type_ = ifexprstatetype::if_4; + return; + case ifexprstatetype::if_4: + /** error: expecting 'else' or ';' **/ + break; + case ifexprstatetype::if_5: + if_expr_->assign_when_false(expr.promote()); + ifxs_type_ = ifexprstatetype::if_6; + return; + case ifexprstatetype::if_6: + /** error: expecting ';' **/ + break; + } + + constexpr const char* c_self_name = "if_else_xs::on_expr"; + const char * exp = get_expect_str(); + + this->illegal_input_on_expr(c_self_name, expr, exp, p_psm); + } + +#endif + + void + DIfElseSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + log && log(xtag("ifstate", ifstate_)); + + // if (ifstate_ == ...) { .... return; } + + switch (ifstate_) { + case ifexprstatetype::invalid: + case ifexprstatetype::N: + assert(false); + break; + case ifexprstatetype::if_0: + // should be unreachable + break; + case ifexprstatetype::if_1: + if_expr_.data()->assign_test(expr); + this->ifstate_ = ifexprstatetype::if_2; + return; + case ifexprstatetype::if_2: + // error: expecting "then" token here + break; + case ifexprstatetype::if_3: + if_expr_.data()->assign_when_true(expr); + this->ifstate_ = ifexprstatetype::if_4; + return; + case ifexprstatetype::if_4: + // error: expecting "else" or ";" + break; + case ifexprstatetype::if_5: + if_expr_.data()->assign_when_false(expr); + this->ifstate_ = ifexprstatetype::if_6; + return; + case ifexprstatetype::if_6: + // error: expecting ";" + break; + } + + p_psm->illegal_parsed_expression("DIfElseSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + + void + DIfElseSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + this->on_parsed_expression(expr, p_psm); + this->on_semicolon_token(Token::semicolon_token(), p_psm); + } + + void + DIfElseSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DIfElseSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + + void + DIfElseSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DIfElseSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + + bool + DIfElseSsm::pretty(const ppindentinfo & ppii) const + { + auto expr + = FacetRegistry::instance().variant(if_expr_); + assert(expr.data()); + (void)expr; + + return ppii.pps()->pretty_struct + (ppii, + "DIfElseSsm", + refrtag("ifstate", ifstate_), + refrtag("if_expr", expr)); + } + + } /*namespace scm*/ +} /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 76574c7b..e773f9a7 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -230,6 +230,14 @@ namespace xo { this->on_if_token(tk, p_psm); return; + case tokentype::tk_then: + this->on_then_token(tk, p_psm); + return; + + case tokentype::tk_else: + this->on_else_token(tk, p_psm); + return; + case tokentype::tk_colon: this->on_colon_token(tk, p_psm); return; @@ -288,8 +296,7 @@ namespace xo { case tokentype::tk_cmpne: case tokentype::tk_type: case tokentype::tk_lambda: - case tokentype::tk_then: - case tokentype::tk_else: + break; case tokentype::tk_let: case tokentype::tk_in: case tokentype::tk_end: @@ -329,6 +336,42 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_then_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + (void)tk; + + obj expr = this->assemble_expr(p_psm); + + p_psm->pop_ssm(); // completes self + + // TODO: perhaps need to generalize on_parsed_expression_with_semicolon() ..? + p_psm->on_parsed_expression(expr); + p_psm->on_token(tk); + } + + void + DProgressSsm::on_else_token(const Token & tk, + ParserStateMachine * p_psm) + { + // note: common with .on_then_token() + + scope log(XO_DEBUG(p_psm->debug_flag())); + + (void)tk; + + obj expr = this->assemble_expr(p_psm); + + p_psm->pop_ssm(); // completes self + + // TODO: perhaps need to generalize on_parsed_expression_with_semicolon() ..? + p_psm->on_parsed_expression(expr); + p_psm->on_token(tk); + } + void DProgressSsm::on_colon_token(const Token & tk, ParserStateMachine * p_psm) @@ -466,9 +509,7 @@ namespace xo { { obj expr_pr = FacetRegistry::instance().variant(expr); - assert(expr_pr); - log && log(xtag("expr", expr_pr)); } @@ -979,28 +1020,6 @@ namespace xo { p_psm->top_exprstate().on_rightparen_token(tk, p_psm); } - void - progress_xs::on_then_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - rp expr = this->assemble_expr(p_psm); - - log && log(xtag("assembled-expr", expr)); - - std::unique_ptr self = p_psm->pop_exprstate(); - - p_psm->on_expr(expr); - p_psm->on_then_token(tk); - - /* control here on input like: - * - * if a > b then.. - * - */ - } - void progress_xs::on_else_token(const token_type & tk, parserstatemachine * p_psm) @@ -1120,7 +1139,7 @@ namespace xo { bool DProgressSsm::pretty(const xo::print::ppindentinfo & ppii) const { - scope log(XO_DEBUG(true)); + scope log(XO_DEBUG(false)); log && log(xtag("lhs_.tseq", lhs_._typeseq())); log && log(xtag("rhs_.tseq", rhs_._typeseq())); diff --git a/xo-reader2/src/reader2/IPrintable_DIfElseSsm.cpp b/xo-reader2/src/reader2/IPrintable_DIfElseSsm.cpp new file mode 100644 index 00000000..f2aebf7c --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DIfElseSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DIfElseSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DIfElseSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DIfElseSsm.json5] +**/ + +#include "ssm/IPrintable_DIfElseSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DIfElseSsm::pretty(const DIfElseSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DIfElseSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp new file mode 100644 index 00000000..66633e88 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp @@ -0,0 +1,59 @@ +/** @file ISyntaxStateMachine_DIfElseSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DIfElseSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DIfElseSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DIfElseSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DIfElseSsm::ssm_type(const DIfElseSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DIfElseSsm::get_expect_str(const DIfElseSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DIfElseSsm::on_token(DIfElseSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DIfElseSsm::on_parsed_symbol(DIfElseSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DIfElseSsm::on_parsed_typedescr(DIfElseSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DIfElseSsm::on_parsed_expression(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DIfElseSsm::on_parsed_expression_with_semicolon(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DIfElseSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index ab0ebe43..712f5998 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -11,6 +11,9 @@ #include #include +#include +#include + #include #include @@ -45,6 +48,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -59,6 +65,7 @@ namespace xo { log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); + log && log(xtag("DIfElseSsm.tseq", typeseq::id())); log && log(xtag("DExpectSymbolSsm.tseq", typeseq::id())); log && log(xtag("DExpectTypeSsm.tseq", typeseq::id())); log && log(xtag("DExpectExprSsm.tseq", typeseq::id())); diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index 716c3d7d..1100bdb3 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -23,6 +23,8 @@ namespace xo { return "expect-rhs-expression"; case syntaxstatetype::defexpr: return "defexpr"; + case syntaxstatetype::ifelseexpr: + return "ifelseexpr"; case syntaxstatetype::progress: return "progress"; case syntaxstatetype::N: diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 895aed10..0f8c1a19 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -84,7 +84,7 @@ namespace xo { TEST_CASE("SchematikaParser-batch-def", "[reader2][SchematikaParser]") { - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag)); ArenaConfig config; @@ -98,6 +98,12 @@ namespace xo { parser.begin_batch_session(); + /** Walkthrough parsing input equivalent to: + * + * def foo : f64 = 3.141593 ; + * + **/ + { auto & result = parser.on_token(Token::def_token()); @@ -193,6 +199,9 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + ArenaConfig config; config.name_ = "test-arena"; config.size_ = 16 * 1024; @@ -204,16 +213,99 @@ namespace xo { parser.begin_interactive_session(); - auto & result = parser.on_token(Token::if_token()); + /** Walkthrough parsing input equivalent to: + * + * if true then 777 else "fooey" ; + * + **/ - // after begin_interactive_session, parser has toplevel exprseq - // but is still "at toplevel" in the sense of ready for input - REQUIRE(parser.has_incomplete_expr() == false); + { + auto & result = parser.on_token(Token::if_token()); - REQUIRE(result.is_error()); + log && log("after if token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); - // illegal input on token - REQUIRE(result.error_description()); + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::bool_token("true")); + + log && log("after true token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::then_token()); + + log && log("after then token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::i64_token("777")); + + log && log("after i64 token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::else_token()); + + log && log("after else token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::string_token("fooey")); + + log && log("after string token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::semicolon_token()); + + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(!result.is_incomplete()); + } + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); } } /*namespace ut*/ diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index cc6e13d9..38e73902 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -137,6 +137,8 @@ namespace xo { static Token lambda() { return Token(tokentype::tk_lambda); } /** token representing keyword @c if **/ static Token if_token() { return Token(tokentype::tk_if); } + /** token representing keyword @c then **/ + static Token then_token() { return Token(tokentype::tk_then); } /** token representing keyword @c else **/ static Token else_token() { return Token(tokentype::tk_else); } /** token representing keyword @c let **/ From fbf88809a690ed41684b48c7da89d7118868eff4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 27 Jan 2026 22:35:22 -0500 Subject: [PATCH 102/258] xo-expression2: + LambdaExpr ++ LocalSymtab --- xo-expression2/CMakeLists.txt | 26 ++++ .../idl/IExpression_DLambdaExpr.json5 | 12 ++ .../idl/IPrintable_DLambdaExpr.json5 | 13 ++ .../include/xo/expression2/Binding.hpp | 1 + .../include/xo/expression2/DLambdaExpr.hpp | 111 +++++++++++++++ .../include/xo/expression2/DLocalSymtab.hpp | 68 ++++++++- .../detail/IExpression_DLambdaExpr.hpp | 66 +++++++++ .../detail/IPrintable_DLambdaExpr.hpp | 62 +++++++++ .../include/xo/expression2/exprtype.hpp | 4 +- xo-expression2/src/expression2/CMakeLists.txt | 4 + .../src/expression2/DLambdaExpr.cpp | 129 ++++++++++++++++++ .../src/expression2/DLocalSymtab.cpp | 53 ++++++- .../expression2/IExpression_DLambdaExpr.cpp | 45 ++++++ .../expression2/IPrintable_DLambdaExpr.cpp | 28 ++++ .../expression2_register_facets.cpp | 8 ++ .../interpreter2/VirtualSchematikaMachine.hpp | 6 + .../interpreter2/VirtualSchematikaMachine.cpp | 10 ++ 17 files changed, 637 insertions(+), 9 deletions(-) create mode 100644 xo-expression2/idl/IExpression_DLambdaExpr.json5 create mode 100644 xo-expression2/idl/IPrintable_DLambdaExpr.json5 create mode 100644 xo-expression2/include/xo/expression2/DLambdaExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp create mode 100644 xo-expression2/src/expression2/DLambdaExpr.cpp create mode 100644 xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp create mode 100644 xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 5fc6d451..3eaff32c 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -150,6 +150,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-expression-lambdaexpr + FACET_PKG xo_expression2 + FACET Expression + REPR LambdaExpr + INPUT idl/IExpression_DLambdaExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-lambdaexpr + FACET_PKG xo_printable2 + FACET Printable + REPR LambdaExpr + INPUT idl/IPrintable_DLambdaExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-expression-ifelseexpr diff --git a/xo-expression2/idl/IExpression_DLambdaExpr.json5 b/xo-expression2/idl/IExpression_DLambdaExpr.json5 new file mode 100644 index 00000000..ef1b6704 --- /dev/null +++ b/xo-expression2/idl/IExpression_DLambdaExpr.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ "\"Expression.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Expression.json5", + brief: "provide AExpression interface for DLambdaExpr state", + using_doxygen: true, + repr: "DLambdaExpr", + doc: ["doc for IExpression+DLambdaExpr" ], +} diff --git a/xo-expression2/idl/IPrintable_DLambdaExpr.json5 b/xo-expression2/idl/IPrintable_DLambdaExpr.json5 new file mode 100644 index 00000000..02a09424 --- /dev/null +++ b/xo-expression2/idl/IPrintable_DLambdaExpr.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DLambdaExpr", + using_doxygen: true, + repr: "DLambdaExpr", + doc: [ "implement APrintable for DLambdaExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/Binding.hpp b/xo-expression2/include/xo/expression2/Binding.hpp index 5f0f7e27..e97cc715 100644 --- a/xo-expression2/include/xo/expression2/Binding.hpp +++ b/xo-expression2/include/xo/expression2/Binding.hpp @@ -19,6 +19,7 @@ namespace xo { Binding(int32_t i_link, int32_t j_slot) : i_link_{i_link}, j_slot_{j_slot} {} + static Binding null() { return Binding(); } /** global bindings are located by symbol name **/ static Binding global() { return Binding(s_link_global, 0); } static Binding local(int32_t j_slot) { return Binding(0, j_slot); } diff --git a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp new file mode 100644 index 00000000..72492ffb --- /dev/null +++ b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp @@ -0,0 +1,111 @@ +/** @file DLambdaExpr.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Expression.hpp" +#include "TypeRef.hpp" +#include "exprtype.hpp" +#include "DLocalSymtab.hpp" +#include "DString.hpp" +#include + +namespace xo { + namespace scm { + /** @class DLambdaExpr + * @brief syntax tree for a function/procedure definition + * + **/ + class DLambdaExpr { + public: + using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + + public: + + /** @defgroup scm-lambdaexpr-ctors **/ + ///@{ + + DLambdaExpr(TypeRef typeref, + const DUniqueString * name, + DLocalSymtab * local_symtab, + obj body); + +#ifdef NOT_YET + /** create instance using memory from @p mm **/ + static obj make(obj mm, + TypeRef typeref, + const DUniqueString * name, + DLocalSymtab * local_symtab, + obj body); +#endif + + /** create instance, using memory from @p mm **/ + static DLambdaExpr * _make(obj mm, + TypeRef typeref, + const DUniqueString * name, + DLocalSymtab * local_symtab, + obj body); + ///@} + /** @defgroup scm-lambdaexpr-methods **/ + ///@{ + + // get_free_variables() + // visit_preorder() + // visit_layer() + // xform_layer() + // attach_envs(SymbolTable*) + + ///@} + /** @defgroup scm-lambdaexpr-expression-facet **/ + ///@{ + + exprtype extype() const noexcept; + TypeRef typeref() const noexcept; + TypeDescr valuetype() const noexcept; + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + /** @defgroup scm-lambdaexpr-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** expression value always has type consistent + * with description here + **/ + TypeRef typeref_; + + /** name for this lambda (generated if necessary) **/ + const DUniqueString * name_ = nullptr; + +#ifdef NOT_YET + /** e.g. + * i64(f64,string) + * for function of two arguments with types (f64, string) respectively, + * that returns an i64. + **/ + const DUniqueString * type_name_str_ = nullptr; +#endif + + /** symbol table for lambda arguments **/ + DLocalSymtab * local_symtab_ = nullptr;; + + /** expression for function body **/ + obj body_expr_; + + // free_var_set + // captured_var_set + // layer_var_map + // nested_lambda_map + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLambdaExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp index b60b6570..9eada176 100644 --- a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp @@ -6,6 +6,7 @@ #pragma once #include "Binding.hpp" +#include "DVariable.hpp" #include "DUniqueString.hpp" //#include "exprtype.hpp" //#include @@ -23,15 +24,61 @@ namespace xo { // using AGCObject = xo::mm::AGCObject; // using typeseq = xo::reflect::typeseq; + using ppindentinfo = xo::print::ppindentinfo; + using AAllocator = xo::mm::AAllocator; + /* note: uint16_t would be fine too */ + using size_type = std::uint32_t; + struct Slot { - // obj var_; - Binding binding_; + Slot() = default; + explicit Slot(const DVariable * var) : var_{var} {} + + /** variable representing a formal argument. + * binding will be correct only within the same layer + * as top-level lambda body + * (i.e. up to the doorstep of each and every nested lambda) + **/ + const DVariable * var_ = nullptr; }; public: -// explicit DLocalSymtab(obj value) noexcept; + /** @defgroup scm-lambdaexpr-constructors **/ + ///@{ - /** @defgroup xo-expression2-symboltable-facet symboltable facet**/ + /** empty instance with capacity for n slots. + * Caller must ensure that slots_[0..n) are actually addressable + **/ + DLocalSymtab(size_type n); + + /** scaffold empty symtab instance, + * with capacity for @p n slots, using memory from allocator @p mm + **/ + static DLocalSymtab * _make_empty(obj mm, size_type n); + + ///@} + /** @defgroup scm-lambdaexpr-methods **/ + ///@{ + + size_type capacity() const noexcept { return capacity_; } + size_type size() const noexcept { return size_; } + + const DVariable * lookup_var(Binding ix) const noexcept { + assert(ix.i_link() == 0); + assert(ix.j_slot() < static_cast(size_)); + + return slots_[ix.j_slot()].var_; + } + + /** increase slot size (provided beleow capacity) to append + * binding for one local variable. Local variable will be allocated + * from @p mm, named @p name, with type described by @p typeref. + **/ + Binding append_var(obj mm, + const DUniqueString * name, + TypeRef typeref); + + ///@} + /** @defgroup xo-localsymtab-symboltable-facet symboltable facet**/ ///@{ /** true for global symbol table **/ @@ -41,9 +88,20 @@ namespace xo { Binding lookup_binding(const DUniqueString * sym) const noexcept; ///@} + /** @defgroup xo-localsymtab-printable-facet printable facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} private: - + /** actual range of slots_[] array. Can use inices in [0,..,n) **/ + size_type capacity_ = 0; + /** number of slots in use **/ + size_type size_ = 0; + /** memory for names and bindings **/ + Slot slots_[]; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp new file mode 100644 index 00000000..d488b6b3 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp @@ -0,0 +1,66 @@ +/** @file IExpression_DLambdaExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DLambdaExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DLambdaExpr.json5] + **/ + +#pragma once + +#include "Expression.hpp" +#include "Expression.hpp" +#include "DLambdaExpr.hpp" + +namespace xo { namespace scm { class IExpression_DLambdaExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IExpression_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IExpression_DLambdaExpr + **/ + class IExpression_DLambdaExpr { + public: + /** @defgroup scm-expression-dlambdaexpr-type-traits **/ + ///@{ + using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; + ///@} + /** @defgroup scm-expression-dlambdaexpr-methods **/ + ///@{ + // const methods + /** expression type (constant | apply | ..) **/ + static exprtype extype(const DLambdaExpr & self) noexcept; + /** placeholder for type giving possible values for this expression **/ + static TypeRef typeref(const DLambdaExpr & self) noexcept; + /** type giving possible values for this expression. Maybe null before typecheck **/ + static TypeDescr valuetype(const DLambdaExpr & self) noexcept; + + // non-const methods + /** assing to valuetype member. Useful when scaffolding expressions **/ + static void assign_valuetype(DLambdaExpr & self, TypeDescr td) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp new file mode 100644 index 00000000..64ab6af1 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DLambdaExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLambdaExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLambdaExpr.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DLambdaExpr.hpp" + +namespace xo { namespace scm { class IPrintable_DLambdaExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DLambdaExpr + **/ + class IPrintable_DLambdaExpr { + public: + /** @defgroup scm-printable-dlambdaexpr-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dlambdaexpr-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DLambdaExpr & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/exprtype.hpp b/xo-expression2/include/xo/expression2/exprtype.hpp index 952051be..861d62bd 100644 --- a/xo-expression2/include/xo/expression2/exprtype.hpp +++ b/xo-expression2/include/xo/expression2/exprtype.hpp @@ -32,10 +32,10 @@ namespace xo { #endif /** function call **/ apply, -#ifdef NOT_YET + /** function definition **/ lambda, -#endif + /** variable reference **/ variable, /** if-then-else **/ diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 840e7070..0aa357b9 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -7,6 +7,7 @@ set(SELF_SRCS DConstant.cpp DVariable.cpp DDefineExpr.cpp + DLambdaExpr.cpp DApplyExpr.cpp DIfElseExpr.cpp @@ -26,6 +27,9 @@ set(SELF_SRCS IExpression_DApplyExpr.cpp IPrintable_DApplyExpr.cpp + IExpression_DLambdaExpr.cpp + IPrintable_DLambdaExpr.cpp + IExpression_DIfElseExpr.cpp IPrintable_DIfElseExpr.cpp diff --git a/xo-expression2/src/expression2/DLambdaExpr.cpp b/xo-expression2/src/expression2/DLambdaExpr.cpp new file mode 100644 index 00000000..18f737ab --- /dev/null +++ b/xo-expression2/src/expression2/DLambdaExpr.cpp @@ -0,0 +1,129 @@ +/** @file DLambda.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DLambdaExpr.hpp" +// #include "detail/IExpression_DLambdaExpr.hpp" +#include +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::reflect::TypeDescr; + using xo::reflect::typeseq; + + namespace scm { + +#ifdef NOT_YET + TypeDescr + assemble_lambda_td() + { + std::vector arg_td_v; + { + arg_td_v.reserve(local_symtab->size()); + + for (DLocalSymtab::size_type i = 0, n = local_symtab->size(); i < n; ++i) { + const DVariable * var = local_symtab->lookup_var(i); + + if (!var) + break; + + TypeDescr arg_td = var->valuetype(); + + if (!arg_td) + break; + + arg_td_v.push_back(arg_td); + } + } + } +#endif + + DLambdaExpr::DLambdaExpr(TypeRef typeref, + const DUniqueString * name, + DLocalSymtab * local_symtab, + obj body) : typeref_{typeref}, + name_{name}, + local_symtab_{local_symtab}, + body_expr_{body} + { + } + +#ifdef NOT_YET + obj + DLambdaExpr::make(obj mm, + TypeRef typeref, + const DUniqueString * name, + DLocalSymtab * local_symtab, + obj body) + { + return obj(_make(mm, typeref, + name, local_symtab, body); + } +#endif + + DLambdaExpr * + DLambdaExpr::_make(obj mm, + TypeRef typeref, + const DUniqueString * name, + DLocalSymtab * local_symtab, + obj body) + { + // in general we're not going to know argument types yet. + // perhaps want to delay this until after type resolution. + + void * mem = mm.alloc(typeseq::id(), sizeof(DLambdaExpr)); + + return new (mem) DLambdaExpr(typeref, + name, + local_symtab, + body); + } + + exprtype + DLambdaExpr::extype() const noexcept { + return exprtype::lambda; + } + + TypeRef + DLambdaExpr::typeref() const noexcept { + return typeref_; + } + + TypeDescr + DLambdaExpr::valuetype() const noexcept { + return typeref_.td(); + } + + void + DLambdaExpr::assign_valuetype(TypeDescr td) noexcept { + typeref_.resolve(td); + } + + bool + DLambdaExpr::pretty(const ppindentinfo & ppii) const + { + auto body + = FacetRegistry::instance().try_variant(body_expr_); + + if (name_ && body) { + return ppii.pps()->pretty_struct(ppii, + "LambdaExpr", + refrtag("name", name_), + //refrtag("argv", local_env_->argv()), + refrtag("body", body)); + } else { + return ppii.pps()->pretty_struct(ppii, + "LambdaExpr"); + } + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLambda.cpp */ diff --git a/xo-expression2/src/expression2/DLocalSymtab.cpp b/xo-expression2/src/expression2/DLocalSymtab.cpp index febd1463..c38096ff 100644 --- a/xo-expression2/src/expression2/DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/DLocalSymtab.cpp @@ -8,13 +8,62 @@ #include namespace xo { + using xo::facet::typeseq; + namespace scm { + DLocalSymtab::DLocalSymtab(size_type n) : capacity_{n}, size_{0} + { + for (size_type i = 0; i < n; ++i) { + void * mem = &slots_[i]; + new (mem) Slot(); + } + } + + DLocalSymtab * + DLocalSymtab::_make_empty(obj mm, size_type n) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DLocalSymtab) + (n * sizeof(Slot))); + + return new (mem) DLocalSymtab(n); + } + + Binding + DLocalSymtab::append_var(obj mm, + const DUniqueString * name, + TypeRef typeref) + { + assert(name); + + if (size_ >= capacity_ || !name) { + assert(false); + + return Binding::null(); + } else { + size_type i_slot = (this->size_)++; + Binding binding = Binding::local(i_slot); + DVariable * var = DVariable::make(mm, name, typeref, binding); + + this->slots_[i_slot] = Slot(var); + + return binding; + } + } + Binding DLocalSymtab::lookup_binding(const DUniqueString * sym) const noexcept { - scope log(XO_DEBUG(true), "stub impl"); - log && log(xtag("sym", std::string_view(*sym))); + assert(sym); + + if (sym) { + for (size_type i = 0; i < size_; ++i) { + const Slot & slot = slots_[i]; + + if (*sym == *(slot.var_->name())) + return slot.var_->path(); + } + } return Binding(); } diff --git a/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp b/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp new file mode 100644 index 00000000..273f5544 --- /dev/null +++ b/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp @@ -0,0 +1,45 @@ +/** @file IExpression_DLambdaExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DLambdaExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DLambdaExpr.json5] +**/ + +#include "detail/IExpression_DLambdaExpr.hpp" + +namespace xo { + namespace scm { + auto + IExpression_DLambdaExpr::extype(const DLambdaExpr & self) noexcept -> exprtype + { + return self.extype(); + } + + auto + IExpression_DLambdaExpr::typeref(const DLambdaExpr & self) noexcept -> TypeRef + { + return self.typeref(); + } + + auto + IExpression_DLambdaExpr::valuetype(const DLambdaExpr & self) noexcept -> TypeDescr + { + return self.valuetype(); + } + + auto + IExpression_DLambdaExpr::assign_valuetype(DLambdaExpr & self, TypeDescr td) noexcept -> void + { + self.assign_valuetype(td); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IExpression_DLambdaExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp b/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp new file mode 100644 index 00000000..12e6c22c --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DLambdaExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLambdaExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLambdaExpr.json5] +**/ + +#include "detail/IPrintable_DLambdaExpr.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DLambdaExpr::pretty(const DLambdaExpr & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DLambdaExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 8ab2ff51..8e10e9a4 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include + #include #include @@ -48,6 +51,7 @@ namespace xo { // +- Variable // +- DefineExpr // +- ApplyExpr + // +- LambdaExpr // \- IfElseExpr FacetRegistry::register_impl(); @@ -62,6 +66,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -70,6 +77,7 @@ namespace xo { log && log(xtag("DVariable.tseq", typeseq::id())); log && log(xtag("DConstant.tseq", typeseq::id())); log && log(xtag("DApplyExpr.tseq", typeseq::id())); + log && log(xtag("DLambdaExpr.tseq", typeseq::id())); log && log(xtag("DIfElseExpr.tseq", typeseq::id())); log && log(xtag("AExpression.tqseq", typeseq::id())); diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 066b7ffd..66a1c1e1 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -51,6 +51,12 @@ namespace xo { **/ void _do_eval_define_op(); + /** evaluate a lambda expression + * Require: + * - expression in @ref expr_ + **/ + void _do_eval_lambda_op(); + /** evaluate a variable expression * Require: * - expression in @ref expr_ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 11a60c64..fe104f9a 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -48,6 +48,9 @@ namespace xo { case exprtype::define: _do_eval_define_op(); break; + case exprtype::lambda: + _do_eval_lambda_op(); + break; case exprtype::variable: _do_eval_variable_op(); break; @@ -77,6 +80,13 @@ namespace xo { assert(false); } + void + VirtualSchematikaMachine::_do_eval_lambda_op() + { + // not implemented + assert(false); + } + void VirtualSchematikaMachine::_do_eval_variable_op() { From c9011c12965014a6aa6283e9eab3cc0b3244cc10 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 28 Jan 2026 10:57:55 -0500 Subject: [PATCH 103/258] xo-reader2 xo-expression2: + DLambdaSsm [WIP] --- .../include/xo/expression2/DConstant.hpp | 14 +- .../include/xo/expression2/DLambdaExpr.hpp | 4 +- .../src/expression2/DLambdaExpr.cpp | 6 +- xo-reader2/CMakeLists.txt | 26 ++ xo-reader2/idl/IPrintable_DLambdaSsm.json5 | 13 + .../idl/ISyntaxStateMachine_DLambdaSsm.json5 | 13 + xo-reader2/include/xo/reader2/DDefineSsm.hpp | 2 +- xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 186 ++++++++ .../xo/reader2/ssm/IPrintable_DLambdaSsm.hpp | 62 +++ .../ssm/ISyntaxStateMachine_DLambdaSsm.hpp | 73 ++++ .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 4 + xo-reader2/src/reader2/DLambdaSsm.cpp | 409 ++++++++++++++++++ .../src/reader2/IPrintable_DLambdaSsm.cpp | 28 ++ .../ISyntaxStateMachine_DLambdaSsm.cpp | 60 +++ xo-reader2/src/reader2/syntaxstatetype.cpp | 2 + xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 17 files changed, 896 insertions(+), 11 deletions(-) create mode 100644 xo-reader2/idl/IPrintable_DLambdaSsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/DLambdaSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DLambdaSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp create mode 100644 xo-reader2/src/reader2/DLambdaSsm.cpp create mode 100644 xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp diff --git a/xo-expression2/include/xo/expression2/DConstant.hpp b/xo-expression2/include/xo/expression2/DConstant.hpp index 50f0e38f..1046176a 100644 --- a/xo-expression2/include/xo/expression2/DConstant.hpp +++ b/xo-expression2/include/xo/expression2/DConstant.hpp @@ -44,18 +44,26 @@ namespace xo { bool is_resolved() const noexcept { return typeref_.is_resolved(); } - exprtype extype() const noexcept { return exprtype::constant; } + obj value() const noexcept { return value_; } TypeDescr value_td() const noexcept { return typeref_.td(); } TaggedPtr value_tp() const noexcept { return TaggedPtr(typeref_.td(), value_.data()); } + /** @defgroup scm-constant-expression-facet **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::constant; } TypeRef typeref() const noexcept { return typeref_; } TypeDescr valuetype() const noexcept { return typeref_.td(); } - obj value() const noexcept { return value_; } - void assign_valuetype(TypeDescr td) noexcept { typeref_.resolve(td); } + ///@} + /** @defgroup scm-constant-printable-facet **/ + ///@{ + bool pretty(const ppindentinfo & ppii) const; + ///@} + private: static TypeDescr _lookup_td(typeseq tseq); diff --git a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp index 72492ffb..bd9ff2c5 100644 --- a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp @@ -34,14 +34,12 @@ namespace xo { DLocalSymtab * local_symtab, obj body); -#ifdef NOT_YET /** create instance using memory from @p mm **/ static obj make(obj mm, TypeRef typeref, const DUniqueString * name, DLocalSymtab * local_symtab, obj body); -#endif /** create instance, using memory from @p mm **/ static DLambdaExpr * _make(obj mm, @@ -53,6 +51,8 @@ namespace xo { /** @defgroup scm-lambdaexpr-methods **/ ///@{ + DLocalSymtab * local_symtab() const noexcept { return local_symtab_; } + // get_free_variables() // visit_preorder() // visit_layer() diff --git a/xo-expression2/src/expression2/DLambdaExpr.cpp b/xo-expression2/src/expression2/DLambdaExpr.cpp index 18f737ab..fec939ac 100644 --- a/xo-expression2/src/expression2/DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/DLambdaExpr.cpp @@ -4,7 +4,7 @@ **/ #include "DLambdaExpr.hpp" -// #include "detail/IExpression_DLambdaExpr.hpp" +#include "detail/IExpression_DLambdaExpr.hpp" #include #include #include @@ -53,7 +53,6 @@ namespace xo { { } -#ifdef NOT_YET obj DLambdaExpr::make(obj mm, TypeRef typeref, @@ -62,9 +61,8 @@ namespace xo { obj body) { return obj(_make(mm, typeref, - name, local_symtab, body); + name, local_symtab, body)); } -#endif DLambdaExpr * DLambdaExpr::_make(obj mm, diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index a4124f45..5ebdf95c 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -86,6 +86,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-lambdassm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR LambdaSsm + INPUT idl/ISyntaxStateMachine_DLambdaSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-lambdassm + FACET_PKG xo_printable2 + FACET Printable + REPR LambdaSsm + INPUT idl/IPrintable_DLambdaSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-ifelsessm diff --git a/xo-reader2/idl/IPrintable_DLambdaSsm.json5 b/xo-reader2/idl/IPrintable_DLambdaSsm.json5 new file mode 100644 index 00000000..63fad901 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DLambdaSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DLambdaSsm", + using_doxygen: true, + repr: "DLambdaSsm", + doc: [ "implement APrintable for DLambdaSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 new file mode 100644 index 00000000..a24f0147 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DLambdaSsm", + using_doxygen: true, + repr: "DLambdaSsm", + doc: [ "implement ASyntaxStateMachine for DLambdaSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 6d15c5ee..41a27b39 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -102,7 +102,7 @@ namespace xo { /** @defgroup scm-definessm-access-methods **/ ///@{ - /** identify define-expression state **/ + /** identify this nested state machine **/ defexprstatetype defstate() const noexcept { return defstate_; } ///@} diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp new file mode 100644 index 00000000..bb110165 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -0,0 +1,186 @@ +/** @file DLambdaSsm.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include +#include +//#include + +namespace xo { + namespace scm { + class ParserStateMachine; + + /** + * @text + * + * lambda ( name(1) : type(1), ..., ) : type body-expr ; + * ^ ^ ^ ^ ^ ^ + * | | | | lm_4 lm_5 + * | | | lm_3 + * lm_0 lm_1 lm_2 + * + * lm_0 --on_lambda_token()--> lm_1 + * lm_1 --on_formal_arglist()--> lm_2 + * lm_2 --on_expr()--> lm_3 + * lm_5 --on_semicolon_token()--> (done) + * + * @endtext + **/ + enum class lambdastatetype { + invalid = -1, + + lm_0, + lm_1, + lm_2, + lm_3, + lm_4, + lm_5, + + n_lambdastatetype + }; + + extern const char * + lambdastatetype_descr(lambdastatetype x); + + inline std::ostream & + operator<< (std::ostream & os, lambdastatetype x) { + os << lambdastatetype_descr(x); + return os; + } + + /** @class DLambdaSsm + * @brief parsing state-machine for a lambda-expression + **/ + class DLambdaSsm { + public: + //using DSymbolTable = xo::scm::DSymbolTable; + using DLocalSymtab = xo::scm::DLocalSymtab; + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-lambdassm-ctors **/ + ///@{ + + DLambdaSsm(); + + /** create instance using memory from @p parser_mm **/ + static obj make(DArena & parser_mm); + + /** create instance using memory from @p parser_mm **/ + static DLambdaSsm * _make(DArena & parser_mm); + + ///@} + /** @defgroup scm-lambdassm-methods **/ + ///@{ + + static void start(ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-lambdassm-syntaxstatemachine-facet **/ + ///@{ + + /** identify this nested state machine **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error messages + **/ + std::string_view get_expect_str() const noexcept; + + /** update this ssm for incoming token @p tk **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update this ssm when nested parser + * emits expression @p expr + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + + /** update this ssm when nested parser + * emits expression @p expr + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + + /** update this ssm when nested parser + * emits @p td. + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + /** update this ssm when nested parser + * emits @p td. + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + virtual const char * get_expect_str() const override; + + virtual void on_lambda_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_typedescr(TypeDescr td, + parserstatemachine * p_psm) override; + virtual void on_formal_arglist(const std::vector> & argl, + parserstatemachine * p_psm) override; + virtual void on_expr(bp expr, + parserstatemachine * p_psm) override; + virtual void on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) override; + virtual void on_leftbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_colon_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_semicolon_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_f64_token(const token_type & tk, + parserstatemachine * p_psm) final override; + + virtual void print(std::ostream & os) const override; + virtual bool pretty_print(const print::ppindentinfo & ppii) const override; +#endif + + ///@} + /** @defgroup scm-lambdassm-printable-facet **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + + private: + /** parsing state-machine state **/ + lambdastatetype lmstate_ = lambdastatetype::lm_0; + +#ifdef NOT_YET + /** lambda environment (for formal parameters) **/ + DLocalSymtab * local_symtab_ = nullptr; + + /** explicit return type (if supplied) **/ + TypeDescr explicit_return_td_ = nullptr; + + /** lambda signature (when known) **/ + TypeDescr lambda_td_ = nullptr; +#endif + + /** body expression **/ + obj body_; + + /** parent environment **/ + obj parent_symtab_; + + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLambdaSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DLambdaSsm.hpp new file mode 100644 index 00000000..9d2cad26 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DLambdaSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DLambdaSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLambdaSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLambdaSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DLambdaSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DLambdaSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DLambdaSsm + **/ + class IPrintable_DLambdaSsm { + public: + /** @defgroup scm-printable-dlambdassm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dlambdassm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DLambdaSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp new file mode 100644 index 00000000..943400c5 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp @@ -0,0 +1,73 @@ +/** @file ISyntaxStateMachine_DLambdaSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DLambdaSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DLambdaSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DLambdaSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DLambdaSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DLambdaSsm + **/ + class ISyntaxStateMachine_DLambdaSsm { + public: + /** @defgroup scm-syntaxstatemachine-dlambdassm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dlambdassm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DLambdaSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DLambdaSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DLambdaSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DLambdaSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DLambdaSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 796743d7..074a5aec 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -33,6 +33,9 @@ namespace xo { /** handle define-expression. See @ref DDefineSsm **/ defexpr, + /** handle lambda-expression. See @ref DLambdaSsm **/ + lambdaexpr, + /** handle ifelse-expression. See @ref DIfElseSsm **/ ifelseexpr, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 2ab9d917..99384589 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -29,6 +29,10 @@ set(SELF_SRCS ISyntaxStateMachine_DIfElseSsm.cpp IPrintable_DIfElseSsm.cpp + DLambdaSsm.cpp + ISyntaxStateMachine_DLambdaSsm.cpp + IPrintable_DLambdaSsm.cpp + DExpectSymbolSsm.cpp ISyntaxStateMachine_DExpectSymbolSsm.cpp IPrintable_DExpectSymbolSsm.cpp diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp new file mode 100644 index 00000000..ad678af8 --- /dev/null +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -0,0 +1,409 @@ +/** @file lambda_xs.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DLambdaSsm.hpp" +#include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include +#include + +#ifdef NOT_YET +#include "define_xs.hpp" +#include "parserstatemachine.hpp" +#include "exprstatestack.hpp" +#include "expect_formal_arglist_xs.hpp" +#include "expect_expr_xs.hpp" +#include "expect_type_xs.hpp" +#include "pretty_expression.hpp" +#include "pretty_variable.hpp" +#include "xo/expression/Lambda.hpp" +#endif + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::reflect::typeseq; + + namespace scm { + const char * + lambdastatetype_descr(lambdastatetype x) { + switch(x) { + case lambdastatetype::invalid: return "invalid"; + case lambdastatetype::lm_0: return "lm_0"; + case lambdastatetype::lm_1: return "lm_1"; + case lambdastatetype::lm_2: return "lm_2"; + case lambdastatetype::lm_3: return "lm_3"; + case lambdastatetype::lm_4: return "lm_4"; + case lambdastatetype::lm_5: return "lm_5"; + default: break; + } + + return "???lambdastatetype"; + } + + // ----- lambda_xs - ---- + + DLambdaSsm::DLambdaSsm() + {} + + obj + DLambdaSsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + DLambdaSsm * + DLambdaSsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc(typeseq::id(), + sizeof(DLambdaSsm)); + + return new (mem) DLambdaSsm(); + } + + void + DLambdaSsm::start(ParserStateMachine * p_psm) + { + p_psm->push_ssm(DLambdaSsm::make(p_psm->parser_alloc())); + p_psm->on_token(Token::lambda_token()); + } + + syntaxstatetype + DLambdaSsm::ssm_type() const noexcept + { + return syntaxstatetype::lambdaexpr; + } + + std::string_view + DLambdaSsm::get_expect_str() const noexcept + { + /* + * lambda (x : f64) : f64 { ... } ; + * ^ ^ ^ ^ ^ ^ + * | | | | | lm_5 + * | | | | lm_4:expect_expression + * | | | lm_3 + * | | lm_2 + * | lm_1: + * expect_expression + */ + switch (this->lmstate_) { + case lambdastatetype::invalid: + case lambdastatetype::n_lambdastatetype: + assert(false); // impossible + break; + case lambdastatetype::lm_0: + return "lambda"; + case lambdastatetype::lm_1: + return "lambda-params"; + case lambdastatetype::lm_2: + return "colon|lambda-body"; + case lambdastatetype::lm_3: + return "type"; + case lambdastatetype::lm_4: + return "lambda-body"; + case lambdastatetype::lm_5: + return "semicolon"; + } + + return "?expect"; + } + + void + DLambdaSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DLambdaSsm::on_token", + tk, + this->get_expect_str()); + } + +#ifdef NOT_YET + void + lambda_xs::on_lambda_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (lmxs_type_ == lambdastatetype::lm_0) { + this->lmxs_type_ = lambdastatetype::lm_1; + expect_formal_arglist_xs::start(p_psm); + } else { + exprstate::on_lambda_token(tk, p_psm); + } + } + + void + lambda_xs::on_formal_arglist(const std::vector> & argl, + parserstatemachine * p_psm) + { + if (lmxs_type_ == lambdastatetype::lm_1) { + this->lmxs_type_ = lambdastatetype::lm_2; + this->parent_env_ = p_psm->top_envframe().promote(); + this->local_env_ = LocalSymtab::make(argl, parent_env_); + + p_psm->push_envframe(local_env_); + + //expect_expr_xs::start(p_psm); + } else { + exprstate::on_formal_arglist(argl, p_psm); + } + } + + void + lambda_xs::on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) + { + this->on_expr(expr, p_psm); + this->on_semicolon_token(token_type::semicolon(), p_psm); + } + + void + lambda_xs::on_colon_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr const char * c_self_name = "lambda_xs::on_colon_token"; + + if (lmxs_type_ == lambdastatetype::lm_2) { + this->lmxs_type_ = lambdastatetype::lm_3; + expect_type_xs::start(p_psm); + /* control reenters via .on_typedescr() */ + } else { + this->illegal_input_on_token(c_self_name, tk, this->get_expect_str(), p_psm); + } + } + + void + lambda_xs::on_leftbrace_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr const char * c_self_name = "lambda_xs::on_leftbrace_token"; + + if (lmxs_type_ == lambdastatetype::lm_2) + this->lmxs_type_ = lambdastatetype::lm_4; + + if (lmxs_type_ == lambdastatetype::lm_4) { + expect_expr_xs::start(p_psm); + /* want { to start expr sequence, that finishes on matching } */ + p_psm->on_leftbrace_token(token_type::leftbrace()); + } else { + this->illegal_input_on_token(c_self_name, tk, this->get_expect_str(), p_psm); + } + } +#endif + + void + DLambdaSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DLambdaSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + +#ifdef NOT_YET + void + lambda_xs::on_typedescr(TypeDescr td, + parserstatemachine * p_psm) + { + constexpr const char * c_self_name = "lambda_xs::on_typedescr"; + scope log(XO_DEBUG(p_psm->debug_flag())); + + assert(td); + + if (lmxs_type_ == lambdastatetype::lm_3) { + this->lmxs_type_ = lambdastatetype::lm_4; + this->explicit_return_td_ = td; + + this->lambda_td_ = Lambda::assemble_lambda_td(local_env_->argv(), + explicit_return_td_); + + /* 1. at this point we know function signature (@ref lambda_td_) + * 2. if this lambda appears on the rhs of a define, + * propagate function signature to the define. + * 3. this makes recursive function definitions like this work + * without relying on type inference: + * def fact = lambda (n : i64) : i64 { + * if (n == 0) then + * 1 + * else + * n * fact(n - 1) + * } + * 4. while parsing the body of the lambda, we want environment + * to already associate the lambda's signature with variable 'fact', + * so that when parser encounters 'fact(n - 1)' the expression has + * known valuetype. + */ + + if ((p_psm->exprstate_stack_size() >= 3) + && (p_psm->lookup_exprstate(1).exs_type() == exprstatetype::expect_rhs_expression) + && (p_psm->lookup_exprstate(2).exs_type() == exprstatetype::defexpr) + && (p_psm->env_stack_size() >= 2) + ) + { + const define_xs * def_xs = dynamic_cast(&(p_psm->lookup_exprstate(2))); + + assert(def_xs); + + bp def_var = def_xs->lhs_variable(); + + if (def_var->valuetype() == nullptr) { + log && log("assign discovered lambda type T to enclosing define", + xtag("lhs", def_var.get()), + xtag("T", print::unq(this->lambda_td_->canonical_name()))); + + def_var->assign_valuetype(lambda_td_); + } else { + /* don't need to unify here. if def already hasa a type, + * that's because it was explicitly specified. + * will discover any conflict after reporting parsed lambda + * to define_xs + */ + } + } + + expect_expr_xs::start(p_psm); + /* control reenters via .on_expr() or .on_expr_with_semicolon() */ + } else { + this->illegal_input_on_type(c_self_name, td, this->get_expect_str(), p_psm); + } + } +#endif + + void + DLambdaSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DLambdaSsm::on_parsed_sybol", + sym, + this->get_expect_str()); + } + + void + DLambdaSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression + ("DLambdaSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + + void + DLambdaSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DLambdaSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + +#ifdef NOT_YET + void + lambda_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + constexpr const char * c_self_name = "lambda_xs::on_expr"; + + if (lmxs_type_ == lambdastatetype::lm_4) { + this->lmxs_type_ = lambdastatetype::lm_5; + this->body_ = expr.promote(); + } else { + this->illegal_input_on_expr(c_self_name, expr, this->get_expect_str(), p_psm); + } + } + + void + lambda_xs::on_semicolon_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (lmxs_type_ == lambdastatetype::lm_5) { + /* done! */ + + std::unique_ptr self = p_psm->pop_exprstate(); + + std::string name = Variable::gensym("lambda"); + + /* top env frame recorded arguments to this lambda */ + p_psm->pop_envframe(); + + rp lm; + + /* TODO: unify explicit_return_td_ with body_ */ + + if (lambda_td_) { + lm = Lambda::make(name, lambda_td_, local_env_, body_); + } else { + lm = Lambda::make_from_env(name, local_env_, + explicit_return_td_, body_); + } + + p_psm->top_exprstate().on_expr(lm, p_psm); + p_psm->top_exprstate().on_semicolon_token(tk, p_psm); + + return; + } + + exprstate::on_semicolon_token(tk, p_psm); + } + + void + lambda_xs::on_f64_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr const char * c_self_name = "lambda_xs::on_f64_token"; + + /* f64 literal can begin lambda body, otherwise illegal. + * for example: + * def foo = lambda (x: bool) 3.14; + */ + if (lmxs_type_ == lambdastatetype::lm_2) { + /* omitting return type. + * omitting left brace. + */ + this->lmxs_type_ = lambdastatetype::lm_4; + + expect_expr_xs::start(p_psm); + p_psm->on_f64_token(tk); + } else { + this->illegal_input_on_token(c_self_name, tk, this->get_expect_str(), p_psm); + } + } + + // TODO: on_i64_token, on_bool token + + void + lambda_xs::print(std::ostream & os) const { + os << ""; + } +#endif + + bool + DLambdaSsm::pretty(const ppindentinfo & ppii) const + { + obj body + = FacetRegistry::instance().variant(body_); + + if (body) { + return ppii.pps()->pretty_struct + (ppii, + "DLambdaSsm", + refrtag("lmstate", lmstate_), + refrtag("body", body)); + } else { + return ppii.pps()->pretty_struct + (ppii, + "DLambdaSsm", + refrtag("lmstate", lmstate_)); + } + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLambdaSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp b/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp new file mode 100644 index 00000000..6cf5b29a --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DLambdaSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLambdaSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLambdaSsm.json5] +**/ + +#include "ssm/IPrintable_DLambdaSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DLambdaSsm::pretty(const DLambdaSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DLambdaSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp new file mode 100644 index 00000000..ac4b2d14 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp @@ -0,0 +1,60 @@ +/** @file ISyntaxStateMachine_DLambdaSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DLambdaSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DLambdaSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DLambdaSsm::ssm_type(const DLambdaSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DLambdaSsm::get_expect_str(const DLambdaSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DLambdaSsm::on_token(DLambdaSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + + auto + ISyntaxStateMachine_DLambdaSsm::on_parsed_symbol(DLambdaSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DLambdaSsm::on_parsed_typedescr(DLambdaSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DLambdaSsm::on_parsed_expression(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DLambdaSsm::on_parsed_expression_with_semicolon(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DLambdaSsm.cpp */ diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index 1100bdb3..c03667c4 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -23,6 +23,8 @@ namespace xo { return "expect-rhs-expression"; case syntaxstatetype::defexpr: return "defexpr"; + case syntaxstatetype::lambdaexpr: + return "lambdaexpr"; case syntaxstatetype::ifelseexpr: return "ifelseexpr"; case syntaxstatetype::progress: diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index 38e73902..f9807d05 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -134,7 +134,7 @@ namespace xo { /** token representing keyword @c def **/ static Token def_token() { return Token(tokentype::tk_def); } /** token representing keyword @c lambda **/ - static Token lambda() { return Token(tokentype::tk_lambda); } + static Token lambda_token() { return Token(tokentype::tk_lambda); } /** token representing keyword @c if **/ static Token if_token() { return Token(tokentype::tk_if); } /** token representing keyword @c then **/ From f9ae5bc3c69d90f2838f8d1e2b9f92bc48b34039 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 28 Jan 2026 15:31:52 -0500 Subject: [PATCH 104/258] xo-reader2: + DExpectFormalArglistSsm [WIP] --- xo-reader2/CMakeLists.txt | 26 ++ .../IPrintable_DExpectFormalArglistSsm.json5 | 13 + ...StateMachine_DExpectFormalArglistSsm.json5 | 13 + .../xo/reader2/DExpectFormalArglistSsm.hpp | 146 +++++++++++ .../include/xo/reader2/DExprSeqState.hpp | 5 + xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 9 +- .../IPrintable_DExpectFormalArglistSsm.hpp | 62 +++++ ...axStateMachine_DExpectFormalArglistSsm.hpp | 73 ++++++ .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 4 + .../src/reader2/DExpectFormalArglistSsm.cpp | 227 ++++++++++++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 36 ++- xo-reader2/src/reader2/DLambdaSsm.cpp | 73 +++++- .../IPrintable_DExpectFormalArglistSsm.cpp | 28 +++ ...axStateMachine_DExpectFormalArglistSsm.cpp | 59 +++++ .../src/reader2/reader2_register_facets.cpp | 15 ++ xo-reader2/src/reader2/syntaxstatetype.cpp | 2 + xo-reader2/utest/SchematikaParser.test.cpp | 113 +++++++++ 18 files changed, 899 insertions(+), 8 deletions(-) create mode 100644 xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArglistSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp create mode 100644 xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp create mode 100644 xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 5ebdf95c..a1028a18 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -112,6 +112,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectformalarglistssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExpectFormalArglistSsm + INPUT idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectformalarglistssm + FACET_PKG xo_printable2 + FACET Printable + REPR ExpectFormalArglistSsm + INPUT idl/IPrintable_DExpectFormalArglistSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-ifelsessm diff --git a/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 b/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 new file mode 100644 index 00000000..44f474dd --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectFormalArglistSsm", + using_doxygen: true, + repr: "DExpectFormalArglistSsm", + doc: [ "implement APrintable for DExpectFormalArglistSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 new file mode 100644 index 00000000..d3e16953 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectFormalArglistSsm", + using_doxygen: true, + repr: "DExpectFormalArglistSsm", + doc: [ "implement ASyntaxStateMachine for DExpectFormalArglistSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..5b32c760 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -0,0 +1,146 @@ +/** @file DExpectFormalArglistSsm.hpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include +#include + +#ifdef NOT_YET +#include "exprstate.hpp" +#include "formal_arg.hpp" +#include +#endif + +namespace xo { + namespace scm { + /** + * ( name(1) : type(1) , ..., ) + * ^ ^ ^ ^ ^ + * | | | | | + * | | | | argl_1b + * | argl_1a | argl_1a + * argl_0 argl_1b + * + * argl_0 --on_leftparen_token()--> argl_1a + * argl_1a --on_formal()--> argl_1b + * argl_1b -+-on_comma_token()--> argl_1a + * \-on_rightparen_token()--> (done) + **/ + enum class formalarglstatetype { + invalid = -1, + + argl_0, + argl_1a, + argl_1b, + + n_formalarglstatetype, + }; + + extern const char * + formalarglstatetype_descr(formalarglstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, formalarglstatetype x) { + os << formalarglstatetype_descr(x); + return os; + } + + /** @class expect_formal_arglist + * @brief parser state-machine for a formal parameter list + **/ + class DExpectFormalArglistSsm { + public: + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; + + public: + DExpectFormalArglistSsm(DArray * argl); + + /** create instance, using memory from @parser_mm **/ + static obj make(DArena & parser_mm); + static DExpectFormalArglistSsm * _make(DArena & parser_mm); + + static void start(ParserStateMachine * p_psm); + + /** @defgroup scm-expectformalarglistssm-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + std::string_view get_expect_str() const; + + /** update state on incoming token @p tk, + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on parsed symbol @p sym emitted by nested ssm, + * with overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + /** update state on parsed typedescr @p td emitted by nested ssm, + * with overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + + /** update state on parsed expression emitted by nested ssm + * with overall parser state in @p p_psm + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + + /** update state on parsed expression, along with following semicolon, + * emitted by nested ssm with overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + + virtual void on_leftparen_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_formal(const rp & formal, + parserstatemachine * p_psm) override; + virtual void on_comma_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) override; +#endif + + ///@} + /** @defgroup scm-expectformalarglistssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** parsing state-machine state **/ + formalarglstatetype fastate_ = formalarglstatetype::argl_0; + /** number of formal parameters encountered. + * Invariant: n_args_ <= argl_->size() + **/ + size_type n_args_ = 0; + /** populate with (parmaeter-name, parameter-type) list + * as they're encountered. + * + * Not using flexible array here since we don't know size + **/ + DArray * argl_ = nullptr; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectFormalArglistSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 72566004..96eea236 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -81,6 +81,11 @@ namespace xo { **/ void on_def_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming lamdba token @p tk, + * overall parser state in @p p_psm + **/ + void on_lambda_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index bb110165..d9b0754d 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -59,6 +59,7 @@ namespace xo { public: //using DSymbolTable = xo::scm::DSymbolTable; using DLocalSymtab = xo::scm::DLocalSymtab; + using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; @@ -81,6 +82,12 @@ namespace xo { static void start(ParserStateMachine * p_psm); + /** update ssm on lambda keyword token @p tk, + * with overall parser state in @p p_psm + **/ + void on_lambda_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-lambdassm-syntaxstatemachine-facet **/ ///@{ @@ -124,8 +131,6 @@ namespace xo { #ifdef NOT_YET virtual const char * get_expect_str() const override; - virtual void on_lambda_token(const token_type & tk, - parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, parserstatemachine * p_psm) override; virtual void on_formal_arglist(const std::vector> & argl, diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..7b5479b7 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArglistSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectFormalArglistSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectFormalArglistSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectFormalArglistSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectFormalArglistSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectFormalArglistSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectFormalArglistSsm + **/ + class IPrintable_DExpectFormalArglistSsm { + public: + /** @defgroup scm-printable-dexpectformalarglistssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectformalarglistssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectFormalArglistSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..93154f83 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp @@ -0,0 +1,73 @@ +/** @file ISyntaxStateMachine_DExpectFormalArglistSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectFormalArglistSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectFormalArglistSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectFormalArglistSsm + **/ + class ISyntaxStateMachine_DExpectFormalArglistSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectformalarglistssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectformalarglistssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectFormalArglistSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectFormalArglistSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectFormalArglistSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectFormalArglistSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectFormalArglistSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 074a5aec..2eb34122 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -21,6 +21,9 @@ namespace xo { /** toplevel of some translation unit. See @ref DExprSeqState **/ expect_toplevel_expression_sequence, + /** expecting a formal argument list (sub-syntax within lambda-expression) **/ + expect_formal_arglist, + /** expecting a s symbol. See @ref DExpectSymbolSsm **/ expect_symbol, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 99384589..949af024 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -33,6 +33,10 @@ set(SELF_SRCS ISyntaxStateMachine_DLambdaSsm.cpp IPrintable_DLambdaSsm.cpp + DExpectFormalArglistSsm.cpp + ISyntaxStateMachine_DExpectFormalArglistSsm.cpp + IPrintable_DExpectFormalArglistSsm.cpp + DExpectSymbolSsm.cpp ISyntaxStateMachine_DExpectSymbolSsm.cpp IPrintable_DExpectSymbolSsm.cpp diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..c7d3fffd --- /dev/null +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -0,0 +1,227 @@ +/* @file DExpectFormalArglistSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + */ + +#include "DExpectFormalArglistSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" +#include + +#ifdef NOT_YET +#include "parserstatemachine.hpp" +#include "exprstatestack.hpp" +#include "expect_formal_xs.hpp" +#include "expect_symbol_xs.hpp" +#include "xo/expression/Variable.hpp" +#include "xo/indentlog/print/vector.hpp" +#endif + +namespace xo { + using xo::mm::AAllocator; + using xo::print::ppindentinfo; + using xo::reflect::typeseq; + + namespace scm { + const char * + formalarglstatetype_descr(formalarglstatetype x) { + switch (x) { + case formalarglstatetype::invalid: + return "invalid"; + case formalarglstatetype::argl_0: + return "argl_0"; + case formalarglstatetype::argl_1a: + return "argl_1a"; + case formalarglstatetype::argl_1b: + return "argl_1b"; + case formalarglstatetype::n_formalarglstatetype: + break; + } + + return "?formalarglstatetype"; + } + + DExpectFormalArglistSsm::DExpectFormalArglistSsm(DArray * argl) : argl_{argl} + {} + + DExpectFormalArglistSsm * + DExpectFormalArglistSsm::_make(DArena & arena) + { + obj mm(&arena); + + /* out-of-order so argl follows ssm in arena, + * consistent with any subsequent arglist realloc. + * Not a load-bearing choice however + */ + + void * mem = arena.alloc(typeseq::id(), + sizeof(DExpectFormalArglistSsm)); + + + /* allocate room for 8 arguments (during parsing) + * will re-alloc to expand as needed + */ + DArray * argl = DArray::empty(mm, 8); + + return new (mem) DExpectFormalArglistSsm(argl); + } + + obj + DExpectFormalArglistSsm::make(DArena & arena) + { + obj retval(_make(arena)); + + return retval; + } + + void + DExpectFormalArglistSsm::start(ParserStateMachine * p_psm) + { + p_psm->push_ssm(DExpectFormalArglistSsm::make(p_psm->parser_alloc())); + } + + syntaxstatetype + DExpectFormalArglistSsm::ssm_type() const noexcept { + return syntaxstatetype::expect_formal_arglist; + } + + std::string_view + DExpectFormalArglistSsm::get_expect_str() const { + switch (fastate_) { + case formalarglstatetype::invalid: + case formalarglstatetype::n_formalarglstatetype: + assert(false); // impossible + break; + case formalarglstatetype::argl_0: + return "leftparen"; + case formalarglstatetype::argl_1a: + return "formal-name"; + case formalarglstatetype::argl_1b: + return "comma|rightparen"; + } + + return "?expect"; + } + + void + DExpectFormalArglistSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_token", + tk, + this->get_expect_str()); + } + + void + DExpectFormalArglistSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExpectFormalArglistSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + + void + DExpectFormalArglistSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DExpectFormalArglistSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + + void + DExpectFormalArglistSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectFormalArglistSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + + void + DExpectFormalArglistSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectFormalArglistSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + +#ifdef NOT_YET + expect_formal_arglist_xs::expect_formal_arglist_xs() + : exprstate(exprstatetype::expect_formal_arglist), + farglxs_type_{formalarglstatetype::argl_0} + {} + + void + expect_formal_arglist_xs::on_leftparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_0) { + this->farglxs_type_ = formalarglstatetype::argl_1a; + /* TODO: refactor to have setup method on each exprstate */ + expect_formal_xs::start(p_psm); + } else { + exprstate::on_leftparen_token(tk, p_psm); + } + } + + void + expect_formal_arglist_xs::on_formal(const rp & formal, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_1a) { + this->farglxs_type_ = formalarglstatetype::argl_1b; + this->argl_.push_back(formal); + } else { + exprstate::on_formal(formal, p_psm); + } + } + + void + expect_formal_arglist_xs::on_comma_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_1b) { + this->farglxs_type_ = formalarglstatetype::argl_1a; + expect_formal_xs::start(p_psm); + } else { + exprstate::on_comma_token(tk, p_psm); + } + } + + void + expect_formal_arglist_xs::on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_1b) { + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->top_exprstate().on_formal_arglist(this->argl_, p_psm); + } else { + exprstate::on_rightparen_token(tk, p_psm); + } + } + + void + expect_formal_arglist_xs::print(std::ostream & os) const { + os << ""; + } +#endif + + bool + DExpectFormalArglistSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DExpectFormalArglistSsm"); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DExpectFormalArglistSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index cfd92683..28c62354 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -4,10 +4,12 @@ **/ #include "DExprSeqState.hpp" -#include "DDefineSsm.hpp" #include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" -#include -#include +#include "DDefineSsm.hpp" +#include "DLambdaSsm.hpp" +#include "DProgressSsm.hpp" +#include "DIfElseSsm.hpp" + #include #include #include @@ -121,6 +123,10 @@ namespace xo { this->on_def_token(tk, p_psm); return; + case tokentype::tk_lambda: + this->on_lambda_token(tk, p_psm); + return; + case tokentype::tk_if: this->on_if_token(tk, p_psm); return; @@ -177,7 +183,6 @@ namespace xo { case tokentype::tk_cmpeq: case tokentype::tk_cmpne: case tokentype::tk_type: - case tokentype::tk_lambda: case tokentype::tk_then: case tokentype::tk_else: case tokentype::tk_let: @@ -241,6 +246,29 @@ namespace xo { */ } + void + DExprSeqState::on_lambda_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + DLambdaSsm::start(p_psm); + return; + case exprseqtype::toplevel_batch: + /* lambda not allowed at top-level in batch mode */ + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + p_psm->illegal_input_on_token("DExprSeqState::on_lambda_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_if_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index ad678af8..a7db6e11 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -5,6 +5,8 @@ #include "DLambdaSsm.hpp" #include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" +#include "DExpectFormalArglistSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" #include @@ -25,6 +27,7 @@ namespace xo { using xo::print::APrintable; + using xo::mm::AAllocator; using xo::facet::FacetRegistry; using xo::reflect::typeseq; @@ -117,11 +120,77 @@ namespace xo { DLambdaSsm::on_token(const Token & tk, ParserStateMachine * p_psm) { + switch (tk.tk_type()) { + case tokentype::tk_lambda: + this->on_lambda_token(tk, p_psm); + return; + + // all the not-yet-handled cases + case tokentype::tk_def: + case tokentype::tk_if: + case tokentype::tk_symbol: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_semicolon: + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + p_psm->illegal_input_on_token("DLambdaSsm::on_token", tk, this->get_expect_str()); } + void + DLambdaSsm::on_lambda_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (lmstate_ == lambdastatetype::lm_0) { + this->lmstate_ = lambdastatetype::lm_1; + + DExpectFormalArglistSsm::start(p_psm); + + return; + } + + p_psm->illegal_input_on_token("DLambdaSsm::on_lambda_token", + tk, + this->get_expect_str()); + } + + #ifdef NOT_YET void lambda_xs::on_lambda_token(const token_type & tk, @@ -386,8 +455,8 @@ namespace xo { DLambdaSsm::pretty(const ppindentinfo & ppii) const { obj body - = FacetRegistry::instance().variant(body_); + = FacetRegistry::instance().try_variant(body_); if (body) { return ppii.pps()->pretty_struct diff --git a/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..d5df450d --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectFormalArglistSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectFormalArglistSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectFormalArglistSsm.json5] +**/ + +#include "ssm/IPrintable_DExpectFormalArglistSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectFormalArglistSsm::pretty(const DExpectFormalArglistSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectFormalArglistSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..91738110 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp @@ -0,0 +1,59 @@ +/** @file ISyntaxStateMachine_DExpectFormalArglistSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::ssm_type(const DExpectFormalArglistSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::get_expect_str(const DExpectFormalArglistSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_token(DExpectFormalArglistSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_symbol(DExpectFormalArglistSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_typedescr(DExpectFormalArglistSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression_with_semicolon(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectFormalArglistSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 712f5998..1cb37de9 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -11,9 +11,15 @@ #include #include +#include +#include + #include #include +#include +#include + #include #include @@ -48,9 +54,15 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -65,11 +77,14 @@ namespace xo { log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); + log && log(xtag("DLambdaSsm.tseq", typeseq::id())); log && log(xtag("DIfElseSsm.tseq", typeseq::id())); + log && log(xtag("DExpectFormalArglistSsm.tseq", typeseq::id())); log && log(xtag("DExpectSymbolSsm.tseq", typeseq::id())); log && log(xtag("DExpectTypeSsm.tseq", typeseq::id())); log && log(xtag("DExpectExprSsm.tseq", typeseq::id())); log && log(xtag("DProgressSsm.tseq", typeseq::id())); + log && log(xtag("ASyntaxStateMachine.tseq", typeseq::id())); return true; } diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index c03667c4..7a2ece4c 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -15,6 +15,8 @@ namespace xo { break; case syntaxstatetype::expect_toplevel_expression_sequence: return "expect-toplevel-expression-sequence"; + case syntaxstatetype::expect_formal_arglist: + return "expect-formal-arglist"; case syntaxstatetype::expect_symbol: return "expect-symbol"; case syntaxstatetype::expect_type: diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 0f8c1a19..5b6124a9 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -197,6 +197,119 @@ namespace xo { //REQUIRE(result.error_description()); } + TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * lambda ; + * + **/ + + { + auto & result = parser.on_token(Token::lambda_token()); + + log && log("after lambda token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + +#ifdef NOT_YET + { + auto & result = parser.on_token(Token::bool_token("true")); + + log && log("after true token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::then_token()); + + log && log("after then token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::i64_token("777")); + + log && log("after i64 token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::else_token()); + + log && log("after else token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::string_token("fooey")); + + log && log("after string token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::semicolon_token()); + + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(!result.is_incomplete()); + } +#endif + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); + } + TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") { constexpr bool c_debug_flag = true; From 02e83594c4dd2ccb1c27d1537afcca8877349251 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 28 Jan 2026 17:40:57 -0500 Subject: [PATCH 105/258] xo-reader2: + DExpectFormalArgSsm [WIP] --- xo-expression2/src/expression2/DApplyExpr.cpp | 4 + xo-reader2/CMakeLists.txt | 14 ++ ...ntaxStateMachine_DExpectFormalArgSsm.json5 | 13 + .../xo/reader2/DExpectFormalArgSsm.hpp | 139 +++++++++++ .../xo/reader2/DExpectFormalArglistSsm.hpp | 11 +- ...SyntaxStateMachine_DExpectFormalArgSsm.hpp | 73 ++++++ .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 4 + .../src/reader2/DExpectFormalArgSsm.cpp | 235 ++++++++++++++++++ .../src/reader2/DExpectFormalArglistSsm.cpp | 136 +++++++++- ...SyntaxStateMachine_DExpectFormalArgSsm.cpp | 59 +++++ xo-reader2/src/reader2/syntaxstatetype.cpp | 2 + xo-reader2/utest/SchematikaParser.test.cpp | 6 +- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 14 files changed, 684 insertions(+), 17 deletions(-) create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp create mode 100644 xo-reader2/src/reader2/DExpectFormalArgSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp diff --git a/xo-expression2/src/expression2/DApplyExpr.cpp b/xo-expression2/src/expression2/DApplyExpr.cpp index ffc6372a..751c1d85 100644 --- a/xo-expression2/src/expression2/DApplyExpr.cpp +++ b/xo-expression2/src/expression2/DApplyExpr.cpp @@ -128,6 +128,8 @@ namespace xo { return false; } + pps->write(">"); + return true; } else { pps->write("pretty(refrtag(concat("arg", 1+i_arg), arg_i)); } + pps->write(">"); + return false; } } diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index a1028a18..1f6b9d75 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -138,6 +138,20 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectformalargssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExpectFormalArgSsm + INPUT idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-ifelsessm diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 new file mode 100644 index 00000000..4b83866e --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectFormalArgSsm", + using_doxygen: true, + repr: "DExpectFormalArgSsm", + doc: [ "implement ASyntaxStateMachine for DExpectFormalArgSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp new file mode 100644 index 00000000..3c913b90 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -0,0 +1,139 @@ +/** @file DExpectFormalSsm.hpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +//#include +//#include "exprstate.hpp" + +namespace xo { + namespace scm { + /** + * name : type + * ^ ^ ^ + * | | formal_2 + * | formal_1 + * formal_0 + * + * formal_0 --on_symbol()--> formal_1 + * formal_1 --on_colon_token()--> formal_2 + * formal_2 --on_typedescr()--> (done) + **/ + enum class formalstatetype { + invalid = -1, + + formal_0, + formal_1, + formal_2, + + n_formalstatetype, + }; + + extern const char * + formalstatetype_descr(formalstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, formalstatetype x) { + os << formalstatetype_descr(x); + return os; + } + + /** @class expect_formal_xs + * @brief parser state-machine for a typed formal parameter + **/ + class DExpectFormalArgSsm { + public: + using TypeDescr = xo::reflect::TypeDescr; + using DArena = xo::mm::DArena; + + public: + DExpectFormalArgSsm(); + + /** create empty instance using memory from @p mm **/ + DExpectFormalArgSsm * _make(DArena & mm); + + static void start(ParserStateMachine * p_psm); + + /** @defgroup scm-expectformalargssm-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** mnemonic for expected input (for this ssm) in current state **/ + std::string_view get_expect_str() const noexcept; + + /** update state on incoming token @p tk, + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on parsed symbol @p sym emitted by nested ssm, + * with overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + /** update state on parsed typedescr @p td emitted by nested ssm, + * with overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + + /** update state on parsed expression emitted by nested ssm + * with overall parser state in @p p_psm + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + + /** update state on parsed expression, along with following semicolon, + * emitted by nested ssm with overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + + ///@} + +#ifdef NOT_YET + + virtual void on_symbol(const std::string & symbol_name, + parserstatemachine * p_psm) override; + + virtual void on_colon_token(const token_type & tk, + parserstatemachine * p_psm) override; + + // virtual void on_comma_token(...) override; + +#ifdef PROBABLY_NOT + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; +#endif + + virtual void on_typedescr(TypeDescr td, + parserstatemachine * p_psm) override; + + virtual void print(std::ostream & os) const override; + + private: + static std::unique_ptr make(); +#endif + + private: + /** parsing state-machine state **/ + formalstatetype fstate_ = formalstatetype::formal_0; + + /** formal parameter name **/ + const DUniqueString * name_ = nullptr; + + /** formal parameter type (if specified) **/ + TypeDescr td_ = nullptr; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectFormalArgSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index 5b32c760..c9cd2ac5 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -68,12 +68,21 @@ namespace xo { static void start(ParserStateMachine * p_psm); + /** @defgroup scm-expectformalarglistssm-methods general methods **/ + ///@{ + + /** update state on incoming token @p tk, with overall parser state in @p psm **/ + void on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} /** @defgroup scm-expectformalarglistssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ /** identifies the ssm implemented here **/ syntaxstatetype ssm_type() const noexcept; + /** mnemonic for expected input (for this ssm) in current state **/ std::string_view get_expect_str() const; /** update state on incoming token @p tk, @@ -108,8 +117,6 @@ namespace xo { #ifdef NOT_YET - virtual void on_leftparen_token(const token_type & tk, - parserstatemachine * p_psm) override; virtual void on_formal(const rp & formal, parserstatemachine * p_psm) override; virtual void on_comma_token(const token_type & tk, diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp new file mode 100644 index 00000000..39d19b05 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp @@ -0,0 +1,73 @@ +/** @file ISyntaxStateMachine_DExpectFormalArgSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectFormalArgSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectFormalArgSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectFormalArgSsm + **/ + class ISyntaxStateMachine_DExpectFormalArgSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectformalargssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectformalargssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectFormalArgSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectFormalArgSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectFormalArgSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectFormalArgSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectFormalArgSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 2eb34122..2d87aa25 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -24,6 +24,9 @@ namespace xo { /** expecting a formal argument list (sub-syntax within lambda-expression) **/ expect_formal_arglist, + /** expecting a formal argument (sub-syntax within formal-arglist) **/ + expect_formal_arg, + /** expecting a s symbol. See @ref DExpectSymbolSsm **/ expect_symbol, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 949af024..49be467b 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -37,6 +37,10 @@ set(SELF_SRCS ISyntaxStateMachine_DExpectFormalArglistSsm.cpp IPrintable_DExpectFormalArglistSsm.cpp + DExpectFormalArgSsm.cpp + ISyntaxStateMachine_DExpectFormalArgSsm.cpp + # IPrintable_DExpectFormalArgSsm.cpp + DExpectSymbolSsm.cpp ISyntaxStateMachine_DExpectSymbolSsm.cpp IPrintable_DExpectSymbolSsm.cpp diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp new file mode 100644 index 00000000..31a26888 --- /dev/null +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -0,0 +1,235 @@ +/** @file DExpectFormalArgSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DExpectFormalArgSsm.hpp" + +#ifdef NOT_YET +#include "expect_symbol_xs.hpp" +#include "expect_type_xs.hpp" +#include "parserstatemachine.hpp" +#include "exprstatestack.hpp" +#include "xo/expression/Variable.hpp" +#endif + +namespace xo { + using xo::scm::DVariable; + using xo::reflect::TypeDescr; + using xo::facet::typeseq; + + namespace scm { + const char * + formalstatetype_descr(formalstatetype x) { + switch (x) { + case formalstatetype::invalid: + case formalstatetype::n_formalstatetype: + return "?formalstatetype"; + case formalstatetype::formal_0: + return "formal_0"; + case formalstatetype::formal_1: + return "formal_1"; + case formalstatetype::formal_2: + return "formal_2"; + } + + return "???formalstatetype"; + } + + DExpectFormalArgSsm::DExpectFormalArgSsm() = default; + + DExpectFormalArgSsm * + DExpectFormalArgSsm::_make(DArena & mm) + { + void * mem = mm.alloc(typeseq::id(), sizeof(DExpectFormalArgSsm)); + + return new (mem) DExpectFormalArgSsm(); + } + + syntaxstatetype + DExpectFormalArgSsm::ssm_type() const noexcept { + return syntaxstatetype::expect_formal_arg; + } + + std::string_view + DExpectFormalArgSsm::get_expect_str() const noexcept + { + switch(fstate_) { + case formalstatetype::invalid: + case formalstatetype::n_formalstatetype: + break; + case formalstatetype::formal_0: + return "formal-name"; + case formalstatetype::formal_1: + return "colon|typename"; + case formalstatetype::formal_2: + return "typename"; + } + + return "?expect"; + } + + /** update state on incoming token @p tk, + * with overall parser state in @p p_psm + **/ + void + DExpectFormalArgSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (tk.tk_type()) { + // all the not-yet-handled cases + case tokentype::tk_leftparen: + case tokentype::tk_lambda: + case tokentype::tk_def: + case tokentype::tk_if: + case tokentype::tk_symbol: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_semicolon: + case tokentype::tk_invalid: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + p_psm->illegal_input_on_token("DExpectFormalArgSsm::on_token", + tk, + this->get_expect_str()); + } + + void + DExpectFormalArgSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExpectFormalArgSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + + void + DExpectFormalArgSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DExpectFormalArgSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + + void + DExpectFormalArgSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectFormalArgSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + + void + DExpectFormalArgSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectFormalArgSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } +#ifdef NOT_YET + void + DExpectFormalSsm::start(ParserStateMachine * p_psm) { + p_psm->push_exprstate(expect_formal_xs::make()); + + expect_symbol_xs::start(p_psm); + } + + expect_formal_xs::expect_formal_xs() + : exprstate(exprstatetype::expect_formal) + {} + + void + expect_formal_xs::on_symbol(const std::string & symbol_name, + parserstatemachine * p_psm) + { + if (this->formalxs_type_ == formalstatetype::formal_0) { + this->formalxs_type_ = formalstatetype::formal_1; + this->result_.assign_name(symbol_name); + } else { + exprstate::on_symbol(symbol_name, p_psm); + } + } + + void + expect_formal_xs::on_colon_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (this->formalxs_type_ == formalstatetype::formal_1) { + this->formalxs_type_ = formalstatetype::formal_2; + expect_type_xs::start(p_psm); + /* control reenters via expect_formal_xs::on_typedescr() */ + } else { + exprstate::on_colon_token(tk, + p_psm); + } + } + + void + expect_formal_xs::on_typedescr(TypeDescr td, + parserstatemachine * p_psm) + { + if (this->formalxs_type_ == formalstatetype::formal_2) { + this->result_.assign_td(td); + + std::unique_ptr self = p_psm->pop_exprstate(); + + rp var = Variable::make(result_.name(), + result_.td()); + + p_psm->top_exprstate().on_formal(var, p_psm); + } else { + exprstate::on_typedescr(td, p_psm); + } + } + + void + expect_formal_xs::print(std::ostream & os) const { + os << ""; + } +#endif + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DExpectFormalArgSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index c7d3fffd..3912a43d 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -5,7 +5,10 @@ #include "DExpectFormalArglistSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" +#include #include +#include +#include #ifdef NOT_YET #include "parserstatemachine.hpp" @@ -17,8 +20,12 @@ #endif namespace xo { - using xo::mm::AAllocator; + using xo::print::APrintable; + using xo::print::ppstate; using xo::print::ppindentinfo; + using xo::mm::AGCObject; + using xo::mm::AAllocator; + using xo::facet::FacetRegistry; using xo::reflect::typeseq; namespace scm { @@ -106,6 +113,54 @@ namespace xo { DExpectFormalArglistSsm::on_token(const Token & tk, ParserStateMachine * p_psm) { + switch (tk.tk_type()) { + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + + // all the not-yet-handled cases + case tokentype::tk_lambda: + case tokentype::tk_def: + case tokentype::tk_if: + case tokentype::tk_symbol: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_semicolon: + case tokentype::tk_invalid: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_token", tk, this->get_expect_str()); @@ -152,20 +207,29 @@ namespace xo { : exprstate(exprstatetype::expect_formal_arglist), farglxs_type_{formalarglstatetype::argl_0} {} +#endif void - expect_formal_arglist_xs::on_leftparen_token(const token_type & tk, - parserstatemachine * p_psm) + DExpectFormalArglistSsm::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) { - if (farglxs_type_ == formalarglstatetype::argl_0) { - this->farglxs_type_ = formalarglstatetype::argl_1a; - /* TODO: refactor to have setup method on each exprstate */ - expect_formal_xs::start(p_psm); - } else { - exprstate::on_leftparen_token(tk, p_psm); + scope log(XO_DEBUG(true)); + + if (fastate_ == formalarglstatetype::argl_0) { + this->fastate_ = formalarglstatetype::argl_1a; + + log && log("STUB: DExpectFormalArglistSsm::on_leftparen_token -> DExpectFormalSsm::start()"); + + //DExpectFormalSsm::start(p_psm); + return; } + + p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_token", + tk, + this->get_expect_str()); } +#ifdef NOT_YET void expect_formal_arglist_xs::on_formal(const rp & formal, parserstatemachine * p_psm) @@ -216,8 +280,58 @@ namespace xo { bool DExpectFormalArglistSsm::pretty(const ppindentinfo & ppii) const { - return ppii.pps()->pretty_struct(ppii, - "DExpectFormalArglistSsm"); + ppstate * pps = ppii.pps(); + + if (ppii.upto()) { + if (!pps->print_upto("print_upto(xrefrtag("fastate", fastate_))) + return false; + + if (!pps->print_upto(xrefrtag("n_args", n_args_))) + return false; + + for (size_type i_arg = 0; i_arg < n_args_; ++i_arg) { + char buf[80]; + snprintf(buf, sizeof(buf), "arg[%ud]", i_arg); + + auto arg_gco = argl_->at(i_arg); + obj arg_pr + = FacetRegistry::instance().try_variant(arg_gco); + + if (!pps->print_upto(xrefrtag(buf, arg_pr))) + return false; + } + + pps->write(">"); + + return true; + } else { + pps->write("newline_indent(ppii.ci1()); + pps->pretty(refrtag("fastate", fastate_)); + + pps->newline_indent(ppii.ci1()); + pps->pretty(refrtag("n_args", n_args_)); + + for (size_type i_arg = 0; i_arg < n_args_; ++i_arg) { + char buf[80]; + snprintf(buf, sizeof(buf), "arg[%ud]", i_arg); + + auto arg_gco = argl_->at(i_arg); + obj arg_pr + = FacetRegistry::instance().try_variant(arg_gco); + + pps->newline_indent(ppii.ci1()); + pps->pretty(refrtag(buf, arg_pr)); + } + + pps->write(">"); + + return false; + } } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp new file mode 100644 index 00000000..ad5678a5 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp @@ -0,0 +1,59 @@ +/** @file ISyntaxStateMachine_DExpectFormalArgSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectFormalArgSsm::ssm_type(const DExpectFormalArgSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectFormalArgSsm::get_expect_str(const DExpectFormalArgSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_token(DExpectFormalArgSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_symbol(DExpectFormalArgSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_typedescr(DExpectFormalArgSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_expression(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_expression_with_semicolon(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectFormalArgSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index 7a2ece4c..e003b27d 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -17,6 +17,8 @@ namespace xo { return "expect-toplevel-expression-sequence"; case syntaxstatetype::expect_formal_arglist: return "expect-formal-arglist"; + case syntaxstatetype::expect_formal_arg: + return "expect-formal-arg"; case syntaxstatetype::expect_symbol: return "expect-symbol"; case syntaxstatetype::expect_type: diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 5b6124a9..0a3ae658 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -231,11 +231,10 @@ namespace xo { REQUIRE(result.is_incomplete()); } -#ifdef NOT_YET { - auto & result = parser.on_token(Token::bool_token("true")); + auto & result = parser.on_token(Token::leftparen_token()); - log && log("after true token:"); + log && log("after lparen token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); @@ -244,6 +243,7 @@ namespace xo { REQUIRE(result.is_incomplete()); } +#ifdef NOT_YET { auto & result = parser.on_token(Token::then_token()); diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index f9807d05..55a2d57d 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -92,7 +92,7 @@ namespace xo { /** token representing right angle bracket @c ">" **/ static Token rightangle() { return Token(tokentype::tk_rightangle); } /** token representing left parenthesis @c "(" **/ - static Token leftparen() { return Token(tokentype::tk_leftparen); } + static Token leftparen_token() { return Token(tokentype::tk_leftparen); } /** Token representing right parenthesis @c ")" **/ static Token rightparen() { return Token(tokentype::tk_rightparen); } /** token representing left bracket @c "[" **/ From 60657ae68a4b552616349f6871da69ccca996116 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 28 Jan 2026 18:04:08 -0500 Subject: [PATCH 106/258] xo-reader2: + DFormalArgSsm printable facet --- xo-reader2/CMakeLists.txt | 12 ++++ .../idl/IPrintable_DExpectFormalArgSsm.json5 | 13 ++++ .../xo/reader2/DExpectFormalArgSsm.hpp | 10 ++- .../ssm/IPrintable_DExpectFormalArgSsm.hpp | 62 +++++++++++++++++++ xo-reader2/src/reader2/CMakeLists.txt | 2 +- xo-reader2/src/reader2/DDefineSsm.cpp | 10 ++- .../src/reader2/DExpectFormalArgSsm.cpp | 19 +++--- .../IPrintable_DExpectFormalArgSsm.cpp | 28 +++++++++ 8 files changed, 136 insertions(+), 20 deletions(-) create mode 100644 xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArgSsm.hpp create mode 100644 xo-reader2/src/reader2/IPrintable_DExpectFormalArgSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 1f6b9d75..4fcbe399 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -150,6 +150,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectformalargssm + FACET_PKG xo_printable2 + FACET Printable + REPR ExpectFormalArgSsm + INPUT idl/IPrintable_DExpectFormalArgSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + # ---------------------------------------------------------------- # note: manual target; generated code committed to git diff --git a/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 b/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 new file mode 100644 index 00000000..854a458e --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectFormalArgSsm", + using_doxygen: true, + repr: "DExpectFormalArgSsm", + doc: [ "implement APrintable for DExpectFormalArgSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index 3c913b90..540b66c2 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -48,6 +48,7 @@ namespace xo { public: using TypeDescr = xo::reflect::TypeDescr; using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; public: DExpectFormalArgSsm(); @@ -97,6 +98,13 @@ namespace xo { ParserStateMachine * p_psm); ///@} + /** @defgroup scm-expectformalargssm-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} #ifdef NOT_YET @@ -117,8 +125,6 @@ namespace xo { virtual void on_typedescr(TypeDescr td, parserstatemachine * p_psm) override; - virtual void print(std::ostream & os) const override; - private: static std::unique_ptr make(); #endif diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArgSsm.hpp new file mode 100644 index 00000000..21e724e1 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArgSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectFormalArgSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectFormalArgSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectFormalArgSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectFormalArgSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectFormalArgSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectFormalArgSsm + **/ + class IPrintable_DExpectFormalArgSsm { + public: + /** @defgroup scm-printable-dexpectformalargssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectformalargssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectFormalArgSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 49be467b..aebe5d77 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -39,7 +39,7 @@ set(SELF_SRCS DExpectFormalArgSsm.cpp ISyntaxStateMachine_DExpectFormalArgSsm.cpp - # IPrintable_DExpectFormalArgSsm.cpp + IPrintable_DExpectFormalArgSsm.cpp DExpectSymbolSsm.cpp ISyntaxStateMachine_DExpectSymbolSsm.cpp diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index c4628c22..af8cee87 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -739,12 +739,10 @@ namespace xo { assert(expr.data()); (void)expr; - return ppii.pps()->pretty_struct - (ppii, - "DDefineSsm", - refrtag("defstate", defstate_), - refrtag("def_expr", expr) - ); + return ppii.pps()->pretty_struct(ppii, + "DDefineSsm", + refrtag("defstate", defstate_), + refrtag("def_expr", expr)); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index 31a26888..7952c8f2 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -216,18 +216,15 @@ namespace xo { exprstate::on_typedescr(td, p_psm); } } - - void - expect_formal_xs::print(std::ostream & os) const { - os << ""; - } #endif + + bool + DExpectFormalArgSsm::pretty(const ppindentinfo & ppii) const { + return ppii.pps()->pretty_struct + (ppii, + "DExpectFormalArgSsm"); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectFormalArgSsm.cpp new file mode 100644 index 00000000..a38d4d86 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExpectFormalArgSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectFormalArgSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectFormalArgSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectFormalArgSsm.json5] +**/ + +#include "ssm/IPrintable_DExpectFormalArgSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectFormalArgSsm::pretty(const DExpectFormalArgSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectFormalArgSsm.cpp */ \ No newline at end of file From 089bd9fcbb142a8aee48107e057bf89dc7d5f59e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 28 Jan 2026 18:31:10 -0500 Subject: [PATCH 107/258] xo-reader2: + DExpectFormalArglistSsm starts DExpectFormalArgSsm --- .../xo/reader2/DExpectFormalArgSsm.hpp | 6 +++- .../include/xo/reader2/DExpectSymbolSsm.hpp | 3 +- xo-reader2/src/reader2/DDefineSsm.cpp | 2 +- .../src/reader2/DExpectFormalArgSsm.cpp | 30 ++++++++++++------- .../src/reader2/DExpectFormalArglistSsm.cpp | 8 ++--- xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 5 ++-- .../src/reader2/reader2_register_facets.cpp | 7 +++++ 7 files changed, 39 insertions(+), 22 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index 540b66c2..1860853c 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -54,8 +54,12 @@ namespace xo { DExpectFormalArgSsm(); /** create empty instance using memory from @p mm **/ - DExpectFormalArgSsm * _make(DArena & mm); + static obj make(DArena & mm); + /** create empty instance using memory from @p mm **/ + static DExpectFormalArgSsm * _make(DArena & mm); + + /** puah instance of this ssm onto @p p_psm **/ static void start(ParserStateMachine * p_psm); /** @defgroup scm-expectformalargssm-ssm-facet syntaxstatemachine facet methods **/ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 4cb04019..d874e63a 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -38,8 +38,7 @@ namespace xo { * to the state machine on top of the stack * as of when this start() method invoked **/ - static void start(DArena & parser_mm, - ParserStateMachine * p_psm); + static void start(ParserStateMachine * p_psm); /** update state for this syntax on incoming token @p tk, * with overall parser state in @p p_psm diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index af8cee87..f7edd2a3 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -597,7 +597,7 @@ namespace xo { if (defstate_ == defexprstatetype::def_0) { this->defstate_ = defexprstatetype::def_1; - DExpectSymbolSsm::start(p_psm->parser_alloc(), p_psm); + DExpectSymbolSsm::start(p_psm); return; } diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index 7952c8f2..2a19ce62 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -4,12 +4,14 @@ **/ #include "DExpectFormalArgSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp" +#include "DExpectSymbolSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp" #ifdef NOT_YET -#include "expect_symbol_xs.hpp" #include "expect_type_xs.hpp" -#include "parserstatemachine.hpp" -#include "exprstatestack.hpp" +//#include "parserstatemachine.hpp" +//#include "exprstatestack.hpp" #include "xo/expression/Variable.hpp" #endif @@ -38,6 +40,12 @@ namespace xo { DExpectFormalArgSsm::DExpectFormalArgSsm() = default; + obj + DExpectFormalArgSsm::make(DArena & mm) + { + return obj(_make(mm)); + } + DExpectFormalArgSsm * DExpectFormalArgSsm::_make(DArena & mm) { @@ -46,6 +54,14 @@ namespace xo { return new (mem) DExpectFormalArgSsm(); } + void + DExpectFormalArgSsm::start(ParserStateMachine * p_psm) + { + p_psm->push_ssm(DExpectFormalArgSsm::make(p_psm->parser_alloc())); + + DExpectSymbolSsm::start(p_psm); + } + syntaxstatetype DExpectFormalArgSsm::ssm_type() const noexcept { return syntaxstatetype::expect_formal_arg; @@ -161,14 +177,8 @@ namespace xo { expr, this->get_expect_str()); } + #ifdef NOT_YET - void - DExpectFormalSsm::start(ParserStateMachine * p_psm) { - p_psm->push_exprstate(expect_formal_xs::make()); - - expect_symbol_xs::start(p_psm); - } - expect_formal_xs::expect_formal_xs() : exprstate(exprstatetype::expect_formal) {} diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index 3912a43d..eaad8028 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -5,6 +5,8 @@ #include "DExpectFormalArglistSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" +#include "DExpectFormalArgSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp" #include #include #include @@ -213,14 +215,10 @@ namespace xo { DExpectFormalArglistSsm::on_leftparen_token(const Token & tk, ParserStateMachine * p_psm) { - scope log(XO_DEBUG(true)); - if (fastate_ == formalarglstatetype::argl_0) { this->fastate_ = formalarglstatetype::argl_1a; - log && log("STUB: DExpectFormalArglistSsm::on_leftparen_token -> DExpectFormalSsm::start()"); - - //DExpectFormalSsm::start(p_psm); + DExpectFormalArgSsm::start(p_psm); return; } diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index c10678f2..7a86e721 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -29,11 +29,10 @@ namespace xo { } void - DExpectSymbolSsm::start(DArena & parser_alloc, - ParserStateMachine * p_psm) + DExpectSymbolSsm::start(ParserStateMachine * p_psm) { DExpectSymbolSsm * sym_ssm - = DExpectSymbolSsm::make(parser_alloc); + = DExpectSymbolSsm::make(p_psm->parser_alloc()); // note: // relying on [ISyntaxStateMachine_DExpectedSymbolSsm.hpp] diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 1cb37de9..9dc10aa2 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include + #include #include @@ -63,6 +66,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -80,6 +86,7 @@ namespace xo { log && log(xtag("DLambdaSsm.tseq", typeseq::id())); log && log(xtag("DIfElseSsm.tseq", typeseq::id())); log && log(xtag("DExpectFormalArglistSsm.tseq", typeseq::id())); + log && log(xtag("DExpectFormalArgSsm.tseq", typeseq::id())); log && log(xtag("DExpectSymbolSsm.tseq", typeseq::id())); log && log(xtag("DExpectTypeSsm.tseq", typeseq::id())); log && log(xtag("DExpectExprSsm.tseq", typeseq::id())); From dcb5a8fb3008161137a0358043675abec3e44169 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 10:16:13 -0500 Subject: [PATCH 108/258] xo-expression2: AGCObject support for DVariable --- xo-expression2/CMakeLists.txt | 12 ++++ xo-expression2/idl/IGCObject_DVariable.json5 | 15 +++++ .../include/xo/expression2/DVariable.hpp | 9 +++ .../detail/IGCObject_DVariable.hpp | 67 +++++++++++++++++++ xo-expression2/src/expression2/CMakeLists.txt | 1 + xo-expression2/src/expression2/DVariable.cpp | 31 +++++++++ .../src/expression2/IGCObject_DVariable.cpp | 39 +++++++++++ .../expression2_register_facets.cpp | 2 + 8 files changed, 176 insertions(+) create mode 100644 xo-expression2/idl/IGCObject_DVariable.json5 create mode 100644 xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp create mode 100644 xo-expression2/src/expression2/IGCObject_DVariable.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 3eaff32c..63ff9fad 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -84,6 +84,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-variable + FACET_PKG xo_gc + FACET GCObject + REPR Variable + INPUT idl/IGCObject_DVariable.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-variable diff --git a/xo-expression2/idl/IGCObject_DVariable.json5 b/xo-expression2/idl/IGCObject_DVariable.json5 new file mode 100644 index 00000000..7327507f --- /dev/null +++ b/xo-expression2/idl/IGCObject_DVariable.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVariable", + using_doxygen: true, + repr: "DVariable", + doc: [ "implement AGCObject for DVariable" ], +} diff --git a/xo-expression2/include/xo/expression2/DVariable.hpp b/xo-expression2/include/xo/expression2/DVariable.hpp index af2eddd5..3c89cc58 100644 --- a/xo-expression2/include/xo/expression2/DVariable.hpp +++ b/xo-expression2/include/xo/expression2/DVariable.hpp @@ -21,6 +21,7 @@ namespace xo { class DVariable { public: using ppindentinfo = xo::print::ppindentinfo; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; @@ -56,6 +57,14 @@ namespace xo { TypeDescr valuetype() const noexcept { return typeref_.td(); }; void assign_valuetype(TypeDescr td) noexcept; + ///@} + /** @defgroup scm-variable-gcobject-facet **/ + ///@{ + + size_t shallow_size() const noexcept; + DVariable * shallow_copy(obj mm) const noexcept; + size_t forward_children(obj gc) noexcept; + ///@} /** @defgroup scm-variable-printable-facet **/ ///@{ diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp new file mode 100644 index 00000000..aee612ea --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVariable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVariable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVariable.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVariable.hpp" + +namespace xo { namespace scm { class IGCObject_DVariable; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVariable + **/ + class IGCObject_DVariable { + public: + /** @defgroup scm-gcobject-dvariable-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvariable-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVariable & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVariable & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVariable & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 0aa357b9..03bd8230 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -19,6 +19,7 @@ set(SELF_SRCS IPrintable_DConstant.cpp IExpression_DVariable.cpp + IGCObject_DVariable.cpp IPrintable_DVariable.cpp IExpression_DDefineExpr.cpp diff --git a/xo-expression2/src/expression2/DVariable.cpp b/xo-expression2/src/expression2/DVariable.cpp index af47de00..ac051387 100644 --- a/xo-expression2/src/expression2/DVariable.cpp +++ b/xo-expression2/src/expression2/DVariable.cpp @@ -5,9 +5,11 @@ #include "DVariable.hpp" #include "exprtype.hpp" +#include #include namespace xo { + using xo::mm::ACollector; using xo::facet::typeseq; namespace scm { @@ -36,6 +38,35 @@ namespace xo { typeref_.resolve(td); } + size_t + DVariable::shallow_size() const noexcept + { + return sizeof(DVariable); + } + + DVariable * + DVariable::shallow_copy(obj mm) const noexcept + { + DVariable * copy = (DVariable *)mm.alloc_copy((std::byte *)this); + + if (copy) { + *copy = *this; + } + + return copy; + } + + size_t + DVariable::forward_children(obj) noexcept + { + // nothing to collect. + // - DUniqueString never in GC space + // - TypeDescr not in GC space + // - path only integers + + return shallow_size(); + } + bool DVariable::pretty(const ppindentinfo & ppii) const { diff --git a/xo-expression2/src/expression2/IGCObject_DVariable.cpp b/xo-expression2/src/expression2/IGCObject_DVariable.cpp new file mode 100644 index 00000000..8735b286 --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DVariable.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVariable.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVariable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVariable.json5] +**/ + +#include "detail/IGCObject_DVariable.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVariable::shallow_size(const DVariable & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVariable::shallow_copy(const DVariable & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVariable::forward_children(DVariable & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVariable.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 8e10e9a4..a6bd50e5 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -58,6 +59,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); From 2a149d371c886e7cf7cb8bbea7d0a33daa414724 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 10:16:52 -0500 Subject: [PATCH 109/258] xo-reader2: lambda ssm progress. incremental [WIP] --- .../xo/reader2/DExpectFormalArgSsm.hpp | 2 ++ .../src/reader2/DExpectFormalArgSsm.cpp | 21 ++++++++++-- xo-reader2/utest/SchematikaParser.test.cpp | 32 ++++++++++++++++--- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index 1860853c..2ec63834 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -140,8 +140,10 @@ namespace xo { /** formal parameter name **/ const DUniqueString * name_ = nullptr; +#ifdef NOT_YET /** formal parameter type (if specified) **/ TypeDescr td_ = nullptr; +#endif }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index 2a19ce62..ad63fa5d 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -146,6 +146,12 @@ namespace xo { DExpectFormalArgSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { + if (fstate_ == formalstatetype::formal_0) { + this->fstate_ = formalstatetype::formal_1; + this->name_ = p_psm->intern_string(sym); + return; + } + p_psm->illegal_input_on_symbol("DExpectFormalArgSsm::on_parsed_symbol", sym, this->get_expect_str()); @@ -230,9 +236,18 @@ namespace xo { bool DExpectFormalArgSsm::pretty(const ppindentinfo & ppii) const { - return ppii.pps()->pretty_struct - (ppii, - "DExpectFormalArgSsm"); + if (name_) { + return ppii.pps()->pretty_struct + (ppii, + "DExpectFormalArgSsm", + refrtag("fstate", fstate_), + refrtag("name", std::string_view(*name_))); + } else { + return ppii.pps()->pretty_struct + (ppii, + "DExpectFormalArgSsm", + refrtag("fstate", fstate_)); + } } } /*namespace scm*/ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 0a3ae658..934b26ed 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -215,7 +215,7 @@ namespace xo { /** Walkthrough parsing input equivalent to: * - * lambda ; + * lambda (n : i64; * **/ @@ -243,11 +243,10 @@ namespace xo { REQUIRE(result.is_incomplete()); } -#ifdef NOT_YET { - auto & result = parser.on_token(Token::then_token()); + auto & result = parser.on_token(Token::symbol_token("n")); - log && log("after then token:"); + log && log("after symbol(n) token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); @@ -256,6 +255,31 @@ namespace xo { REQUIRE(result.is_incomplete()); } + { + auto & result = parser.on_token(Token::colon_token()); + + log && log("after colon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("i64")); + + log && log("after symbol(i64) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + +#ifdef NOT_YET { auto & result = parser.on_token(Token::i64_token("777")); From 2ddaa861fa275d93b8fbfadb2e56532a624ed140 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 10:35:13 -0500 Subject: [PATCH 110/258] xo-reader2: in DExpectFormalArgSsm handle colon token --- .../xo/reader2/DExpectFormalArgSsm.hpp | 18 ++++++-- .../include/xo/reader2/DExpectTypeSsm.hpp | 4 +- xo-reader2/src/reader2/DDefineSsm.cpp | 3 +- .../src/reader2/DExpectFormalArgSsm.cpp | 41 +++++++++++-------- xo-reader2/src/reader2/DExpectTypeSsm.cpp | 7 ++-- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index 2ec63834..f58a09b2 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -51,6 +51,9 @@ namespace xo { using ppindentinfo = xo::print::ppindentinfo; public: + /** @defgroupo scm-expectfromalargssm-ctors constructors **/ + ///@{ + DExpectFormalArgSsm(); /** create empty instance using memory from @p mm **/ @@ -62,6 +65,18 @@ namespace xo { /** puah instance of this ssm onto @p p_psm **/ static void start(ParserStateMachine * p_psm); + ///@} + + /** @defgroup scm-expectformalargssm-methods general methods **/ + ///@{ + + /** update state on incoming colon token @p tk; + * with overall parser state in @p p_psm + **/ + void on_colon_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} /** @defgroup scm-expectformalargssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -115,9 +130,6 @@ namespace xo { virtual void on_symbol(const std::string & symbol_name, parserstatemachine * p_psm) override; - virtual void on_colon_token(const token_type & tk, - parserstatemachine * p_psm) override; - // virtual void on_comma_token(...) override; #ifdef PROBABLY_NOT diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 346a6d6c..c2bb4297 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -32,9 +32,7 @@ namespace xo { static DExpectTypeSsm * make(DArena & parser_mm); - static void start(DArena & parser_mm, - //obj expr_mm, - ParserStateMachine * p_psm); + static void start(ParserStateMachine * p_psm); /** @defgroup scm-expecttype-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index f7edd2a3..4a13d41d 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -622,8 +622,7 @@ namespace xo { if (defstate_ == defexprstatetype::def_2) { this->defstate_ = defexprstatetype::def_3; - DExpectTypeSsm::start(p_psm->parser_alloc(), - p_psm); + DExpectTypeSsm::start(p_psm); return; } diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index ad63fa5d..d08858f7 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -7,11 +7,10 @@ #include "ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp" #include "DExpectSymbolSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp" +#include "DExpectTypeSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp" #ifdef NOT_YET -#include "expect_type_xs.hpp" -//#include "parserstatemachine.hpp" -//#include "exprstatestack.hpp" #include "xo/expression/Variable.hpp" #endif @@ -93,13 +92,15 @@ namespace xo { ParserStateMachine * p_psm) { switch (tk.tk_type()) { + case tokentype::tk_colon: + this->on_colon_token(tk, p_psm); + return; // all the not-yet-handled cases case tokentype::tk_leftparen: case tokentype::tk_lambda: case tokentype::tk_def: case tokentype::tk_if: case tokentype::tk_symbol: - case tokentype::tk_colon: case tokentype::tk_singleassign: case tokentype::tk_string: case tokentype::tk_f64: @@ -142,6 +143,24 @@ namespace xo { this->get_expect_str()); } + void + DExpectFormalArgSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (fstate_ == formalstatetype::formal_1) { + this->fstate_ = formalstatetype::formal_2; + + DExpectTypeSsm::start(p_psm); + + /* control reenters via DExpectFormalArgSsm::on_parsed_typedescr() */ + return; + } + + p_psm->illegal_input_on_token("DExpectFormalArgSsm::on_colon_token", + tk, + this->get_expect_str()); + } + void DExpectFormalArgSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) @@ -201,20 +220,6 @@ namespace xo { } } - void - expect_formal_xs::on_colon_token(const token_type & tk, - parserstatemachine * p_psm) - { - if (this->formalxs_type_ == formalstatetype::formal_1) { - this->formalxs_type_ = formalstatetype::formal_2; - expect_type_xs::start(p_psm); - /* control reenters via expect_formal_xs::on_typedescr() */ - } else { - exprstate::on_colon_token(tk, - p_psm); - } - } - void expect_formal_xs::on_typedescr(TypeDescr td, parserstatemachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index d99ff817..8b151c5f 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -32,11 +32,10 @@ namespace xo { } void - DExpectTypeSsm::start(DArena & mm, - //obj expr_mm, - ParserStateMachine * p_psm) + DExpectTypeSsm::start(ParserStateMachine * p_psm) { - DExpectTypeSsm * expect_type_ssm = DExpectTypeSsm::make(mm); + DExpectTypeSsm * expect_type_ssm + = DExpectTypeSsm::make(p_psm->parser_alloc()); auto ssm = with_facet::mkobj(expect_type_ssm); From fb48c94be66939e4bf1cad45efc2e3ce2d438e68 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 10:49:55 -0500 Subject: [PATCH 111/258] xo-reader2: ssm pretty-printers include .expect_str() output --- xo-reader2/src/reader2/DDefineSsm.cpp | 1 + xo-reader2/src/reader2/DExpectFormalArgSsm.cpp | 5 ++++- xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp | 6 ++++++ xo-reader2/src/reader2/DLambdaSsm.cpp | 4 +++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 4a13d41d..4676b3c8 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -741,6 +741,7 @@ namespace xo { return ppii.pps()->pretty_struct(ppii, "DDefineSsm", refrtag("defstate", defstate_), + refrtag("expect", this->get_expect_str()), refrtag("def_expr", expr)); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index d08858f7..215c9471 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -246,12 +246,15 @@ namespace xo { (ppii, "DExpectFormalArgSsm", refrtag("fstate", fstate_), + refrtag("expect", this->get_expect_str()), refrtag("name", std::string_view(*name_))); } else { return ppii.pps()->pretty_struct (ppii, "DExpectFormalArgSsm", - refrtag("fstate", fstate_)); + refrtag("fstate", fstate_), + refrtag("expect", this->get_expect_str()) + ); } } diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index eaad8028..db8b1f6d 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -287,6 +287,9 @@ namespace xo { if (!pps->print_upto(xrefrtag("fastate", fastate_))) return false; + if (!pps->print_upto(xrefrtag("expect", this->get_expect_str()))) + return false; + if (!pps->print_upto(xrefrtag("n_args", n_args_))) return false; @@ -311,6 +314,9 @@ namespace xo { pps->newline_indent(ppii.ci1()); pps->pretty(refrtag("fastate", fastate_)); + pps->newline_indent(ppii.ci1()); + pps->pretty(refrtag("expect", this->get_expect_str())); + pps->newline_indent(ppii.ci1()); pps->pretty(refrtag("n_args", n_args_)); diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index a7db6e11..1fda9547 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -463,12 +463,14 @@ namespace xo { (ppii, "DLambdaSsm", refrtag("lmstate", lmstate_), + refrtag("expect", this->get_expect_str()), refrtag("body", body)); } else { return ppii.pps()->pretty_struct (ppii, "DLambdaSsm", - refrtag("lmstate", lmstate_)); + refrtag("lmstate", lmstate_), + refrtag("expect", this->get_expect_str())); } } From 1c2352c00820249ca30362e7635c09624121c979 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 12:24:46 -0500 Subject: [PATCH 112/258] xo-reader2: use DUniqueString* to report parsed formal --- xo-reader2/idl/SyntaxStateMachine.json5 | 10 +++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 7 ++++ .../include/xo/reader2/DExpectExprSsm.hpp | 7 ++++ .../xo/reader2/DExpectFormalArgSsm.hpp | 13 ++++--- .../xo/reader2/DExpectFormalArglistSsm.hpp | 10 +++-- .../include/xo/reader2/DExpectSymbolSsm.hpp | 7 ++++ .../include/xo/reader2/DExpectTypeSsm.hpp | 7 ++++ .../include/xo/reader2/DExprSeqState.hpp | 7 ++++ xo-reader2/include/xo/reader2/DIfElseSsm.hpp | 27 +++++++++----- xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 37 ++++++++++--------- .../include/xo/reader2/DProgressSsm.hpp | 3 ++ .../include/xo/reader2/ParserStateMachine.hpp | 15 ++++++++ .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 + .../xo/reader2/ssm/IPrintable_DLambdaSsm.hpp | 2 +- .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectExprSsm.hpp | 2 + ...SyntaxStateMachine_DExpectFormalArgSsm.hpp | 2 + ...axStateMachine_DExpectFormalArglistSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 + .../ssm/ISyntaxStateMachine_DIfElseSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DLambdaSsm.hpp | 4 +- .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 + .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 ++ .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 ++ xo-reader2/src/reader2/DDefineSsm.cpp | 11 ++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 15 +++++++- .../src/reader2/DExpectFormalArgSsm.cpp | 27 ++++++++++++++ .../src/reader2/DExpectFormalArglistSsm.cpp | 11 ++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 11 ++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 17 +++++++-- xo-reader2/src/reader2/DExprSeqState.cpp | 11 ++++++ xo-reader2/src/reader2/DIfElseSsm.cpp | 11 ++++++ xo-reader2/src/reader2/DLambdaSsm.cpp | 35 +++++++++--------- xo-reader2/src/reader2/DProgressSsm.cpp | 11 ++++++ .../src/reader2/IPrintable_DLambdaSsm.cpp | 2 +- .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 +++ .../ISyntaxStateMachine_DDefineSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExpectExprSsm.cpp | 5 +++ ...SyntaxStateMachine_DExpectFormalArgSsm.cpp | 5 +++ ...axStateMachine_DExpectFormalArglistSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 +++ .../ISyntaxStateMachine_DExprSeqState.cpp | 5 +++ .../ISyntaxStateMachine_DIfElseSsm.cpp | 5 +++ .../ISyntaxStateMachine_DLambdaSsm.cpp | 10 +++-- .../ISyntaxStateMachine_DProgressSsm.cpp | 5 +++ xo-reader2/src/reader2/ParserStateMachine.cpp | 36 ++++++++++++++++++ 50 files changed, 377 insertions(+), 65 deletions(-) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 15a36f12..fba93437 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -72,6 +72,16 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_formal", + doc: ["operate state machine for formal emitted by nested ssm"], + return_type: "void", + args: [ + {type: "const DUniqueString *", name: "param_name"}, + {type: "TypeDescr", name: "param_type"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_parsed_expression", doc: ["update state machine for incoming parsed expression @p expr"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 41a27b39..bf0a3ffb 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -195,6 +195,13 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state for this ssm to consume param (name,value) + * emitted by nested @p_psm + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index b994b498..8e51124d 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -135,6 +135,13 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state to consume parsed formal (name, value) from nested ssm, + * with overall parser state in @p p_psm + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index f58a09b2..ee5eb0ea 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -104,6 +104,14 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** consume parsed formal (name,type) = (@p sym, @p td) from nested ssm + * with overall parser state in @p p_psm. + * (In practice not reachable) + **/ + void on_parsed_formal(const DUniqueString * sym, + TypeDescr td, + ParserStateMachine * p_psm); + /** update state on parsed expression emitted by nested ssm * with overall parser state in @p p_psm **/ @@ -151,11 +159,6 @@ namespace xo { /** formal parameter name **/ const DUniqueString * name_ = nullptr; - -#ifdef NOT_YET - /** formal parameter type (if specified) **/ - TypeDescr td_ = nullptr; -#endif }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index c9cd2ac5..f4c24303 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -103,6 +103,13 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state to consume parsed param (name,type) emitted by + * nested ssm, with overall parser state in @p p_psm + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm); + /** update state on parsed expression emitted by nested ssm * with overall parser state in @p p_psm **/ @@ -116,9 +123,6 @@ namespace xo { ParserStateMachine * p_psm); #ifdef NOT_YET - - virtual void on_formal(const rp & formal, - parserstatemachine * p_psm) override; virtual void on_comma_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_rightparen_token(const token_type & tk, diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index d874e63a..080380b9 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -78,6 +78,13 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state to consume param (name, value) emitted + * by nested ssm + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr * in nested state machine. * (provided to satisfy ASyntaxStateMachine api. not reachable) diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index c2bb4297..3ca99815 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -129,6 +129,13 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine to consume formal param (name,value) + * emitted by nested ssm + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm); + /** operate state machine for this syntax on receiving expression * from nested parser. * (provided to satisfy ASyntaxStateMachine api. not reachable) diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 96eea236..c718cbef 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -138,6 +138,13 @@ namespace xo { **/ void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update this ssm to consume parsed formal param (name, value) + * emitted by nested ssm, with overall parser state in @p p_psm + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm); + /** update state for this syntax on parsed expression @p expr * from nested ssm. * overall parser state in @p p_psm diff --git a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp index 9b3e5d17..647a5e34 100644 --- a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp @@ -140,11 +140,11 @@ namespace xo { void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax after parsing an expression @p expr, - * overall parser state in @p p_psm. + /** update state for this syntax after parsing a symbol @p sym, + * with overall parser state in @p p_psm **/ - void on_parsed_expression(obj expr, - ParserStateMachine * p_psm); + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); /** update state for this syntax after parsing a type description @p td; * overall parser state in @p p_psm @@ -152,6 +152,19 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update state to consume formal param (name,value) + * from nested ssm + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing an expression @p expr, + * overall parser state in @p p_psm. + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr, * followed by semicolon, * with overall parser state in @p p_psm. @@ -159,12 +172,6 @@ namespace xo { void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm); - /** update state for this syntax after parsing a symbol @p sym, - * with overall parser state in @p p_psm - **/ - void on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm); - ///@} /** @defgroup scm-ifelsessm-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index d9b0754d..69cb3322 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -104,18 +104,6 @@ namespace xo { void on_token(const Token & tk, ParserStateMachine * p_psm); - /** update this ssm when nested parser - * emits expression @p expr - **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); - - /** update this ssm when nested parser - * emits expression @p expr - **/ - void on_parsed_expression(obj expr, - ParserStateMachine * p_psm); - /** update this ssm when nested parser * emits @p td. **/ @@ -128,17 +116,30 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + /** update this ssm to consume parsed formal (name,value) + * from nested (and now expired) ssm + **/ + void on_parsed_formal(const DUniqueString * sym, + TypeDescr td, + ParserStateMachine * p_psm); + + /** update this ssm when nested parser + * emits expression @p expr + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + + /** update this ssm when nested parser + * emits expression @p expr + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + #ifdef NOT_YET virtual const char * get_expect_str() const override; - virtual void on_typedescr(TypeDescr td, - parserstatemachine * p_psm) override; virtual void on_formal_arglist(const std::vector> & argl, parserstatemachine * p_psm) override; - virtual void on_expr(bp expr, - parserstatemachine * p_psm) override; - virtual void on_expr_with_semicolon(bp expr, - parserstatemachine * p_psm) override; virtual void on_leftbrace_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 788c10ca..fa0ec733 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -170,6 +170,9 @@ namespace xo { ParserStateMachine * p_psm); void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm); void on_parsed_expression(obj, ParserStateMachine * p_psm); void on_parsed_expression_with_semicolon(obj expr, diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index a674e7e2..74f27876 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -102,6 +102,12 @@ namespace xo { **/ void on_parsed_typedescr(TypeDescr td); + /** update state to consume param (name, value) emitted by + * nested (but not popped) parsing state + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type); + /** update state to respond to parsed expression @p expr * (from nested parsing state) **/ @@ -163,6 +169,15 @@ namespace xo { TypeDescr td, std::string_view expect_str); + /** report illegal parsed formal (param_name, param_type) from nested ssm. + * Introducing as placeholder; not expected to be reachable in + * full parser + **/ + void illegal_parsed_formal(std::string_view ssm_name, + const DUniqueString * param_name, + TypeDescr param_type, + std::string_view expect_str); + /** report illegal parsed expression from nested ssm. * Introducing as placeholder; not clear if this will be reachable * in full parser diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index 3115d692..6cc3b829 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -63,6 +63,8 @@ public: virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; /** operate state machine for incoming type description @p td **/ virtual void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) = 0; + /** operate state machine for formal emitted by nested ssm **/ + virtual void on_parsed_formal(Opaque data, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) = 0; /** update state machine for incoming parsed expression @p expr **/ virtual void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DLambdaSsm.hpp index 9d2cad26..6d9681ee 100644 --- a/xo-reader2/include/xo/reader2/ssm/IPrintable_DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DLambdaSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 45be148e..3faa0f67 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -63,6 +63,7 @@ namespace scm { [[noreturn]] void on_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; + [[noreturn]] void on_parsed_formal(Opaque, const DUniqueString *, TypeDescr, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression(Opaque, obj, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression_with_semicolon(Opaque, obj, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index dad8ff29..f4d0da9d 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DDefineSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 7250cec7..3ff00e07 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DExpectExprSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectExprSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp index 39d19b05..adce6eb9 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DExpectFormalArgSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExpectFormalArgSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectFormalArgSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp index 93154f83..b8a3b416 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DExpectFormalArglistSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExpectFormalArglistSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectFormalArglistSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 7e83d0e4..d778e293 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectSymbolSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index c8c4cc9f..9d6f153a 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DExpectTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectTypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 2a86db05..d958f1f8 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExprSeqState & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp index 2101b8e1..88a8b7d8 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DIfElseSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DIfElseSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DIfElseSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp index 943400c5..02582d0b 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DLambdaSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DLambdaSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DLambdaSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DLambdaSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index 3d70afed..ee2dfbaf 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -60,6 +60,8 @@ namespace xo { static void on_parsed_symbol(DProgressSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ static void on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DProgressSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 36c2ff83..51ab0f30 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -61,6 +61,9 @@ namespace scm { void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) override { return I::on_parsed_typedescr(_dcast(data), td, p_psm); } + void on_parsed_formal(Opaque data, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) override { + return I::on_parsed_formal(_dcast(data), param_name, param_type, p_psm); + } void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) override { return I::on_parsed_expression(_dcast(data), expr, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index fb1fb496..3de33f8e 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -65,6 +65,9 @@ public: void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm) { return O::iface()->on_parsed_typedescr(O::data(), td, p_psm); } + void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_formal(O::data(), param_name, param_type, p_psm); + } void on_parsed_expression(obj expr, ParserStateMachine * p_psm) { return O::iface()->on_parsed_expression(O::data(), expr, p_psm); } diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 4676b3c8..65df6349 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -704,6 +704,17 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal("DDefineSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + void DDefineSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 4f61df72..2a836e87 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -340,7 +340,7 @@ namespace xo { DExpectExprSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_symbol("DExpectExprSsm", + p_psm->illegal_input_on_symbol("DExpectExprSsm::on_parsed_symbol", sym, this->get_expect_str()); } @@ -349,11 +349,22 @@ namespace xo { DExpectExprSsm::on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_typedescr("DExpectExprSsm", + p_psm->illegal_input_on_typedescr("DExpectExprSsm::on_parsed_typedescr", td, this->get_expect_str()); } + void + DExpectExprSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal("DExpectExprSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + void DExpectExprSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index 215c9471..eb174fc9 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -166,6 +166,10 @@ namespace xo { ParserStateMachine * p_psm) { if (fstate_ == formalstatetype::formal_0) { + // parsed symbol @c sym is stored in tokenizer memory; + // must be copied to storage with expression lifetime, + // hence call to intern_string() + this->fstate_ = formalstatetype::formal_1; this->name_ = p_psm->intern_string(sym); return; @@ -180,11 +184,34 @@ namespace xo { DExpectFormalArgSsm::on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm) { + if (fstate_ == formalstatetype::formal_2) { + assert(name_); + + p_psm->pop_ssm(); + p_psm->on_parsed_formal(name_, td); + + return; + } + p_psm->illegal_input_on_typedescr("DExpectFormalArgSsm::on_parsed_typedescr", td, this->get_expect_str()); } + void + DExpectFormalArgSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + // NOTE: (param_name,param_type) *produced* by this SSM, + // but never *consumed* + + p_psm->illegal_parsed_formal("DExpectFormalArgSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + void DExpectFormalArgSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index db8b1f6d..a5b77c4d 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -186,6 +186,17 @@ namespace xo { this->get_expect_str()); } + void + DExpectFormalArglistSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal("DExpectFormalArglistSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + void DExpectFormalArglistSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 7a86e721..cee3a08c 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -73,6 +73,17 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal("DExpectSymbolSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 8b151c5f..8f848269 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -247,7 +247,7 @@ namespace xo { td = Reflect::require(); if (!td) { - p_psm->illegal_input_on_token("DExpectTypeSsm", + p_psm->illegal_input_on_token("DExpectTypeSsm::on_symbol_token", tk, this->get_expect_str()); } @@ -260,7 +260,7 @@ namespace xo { DExpectTypeSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_symbol("ExpectTypeSsm", + p_psm->illegal_input_on_symbol("ExpectTypeSsm::on_parsed_symbol", sym, this->get_expect_str()); } @@ -269,11 +269,22 @@ namespace xo { DExpectTypeSsm::on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_typedescr("ExpectTypeSsm", + p_psm->illegal_input_on_typedescr("ExpectTypeSsm::on_parsed_typedescr", td, this->get_expect_str()); } + void + DExpectTypeSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal("DExpectTypeSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + void DExpectTypeSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 28c62354..5d9fe9b1 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -449,6 +449,17 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal("DExprSeqState::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + void DExprSeqState::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index eca02910..9f7d7167 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -510,6 +510,17 @@ namespace xo { this->get_expect_str()); } + void + DIfElseSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal("DIfElseSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + bool DIfElseSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 1fda9547..f9fcd6ae 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -192,18 +192,6 @@ namespace xo { #ifdef NOT_YET - void - lambda_xs::on_lambda_token(const token_type & tk, - parserstatemachine * p_psm) - { - if (lmxs_type_ == lambdastatetype::lm_0) { - this->lmxs_type_ = lambdastatetype::lm_1; - expect_formal_arglist_xs::start(p_psm); - } else { - exprstate::on_lambda_token(tk, p_psm); - } - } - void lambda_xs::on_formal_arglist(const std::vector> & argl, parserstatemachine * p_psm) @@ -351,13 +339,14 @@ namespace xo { } void - DLambdaSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + DLambdaSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) { - p_psm->illegal_parsed_expression - ("DLambdaSsm::on_parsed_expression_with_semicolon", - expr, - this->get_expect_str()); + p_psm->illegal_parsed_formal("DLambdaSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); } void @@ -369,6 +358,16 @@ namespace xo { this->get_expect_str()); } + void + DLambdaSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression + ("DLambdaSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + #ifdef NOT_YET void lambda_xs::on_expr(bp expr, diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index e773f9a7..1233c198 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -555,6 +555,17 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal("DProgressSsm::on_parsed_formal", + param_name, + param_type, + this->get_expect_str()); + } + void DProgressSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp b/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp index 6cf5b29a..93a703aa 100644 --- a/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 4cfb72a7..2a16a292 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -52,6 +52,12 @@ ISyntaxStateMachine_Any::on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachi _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_formal(Opaque, const DUniqueString *, TypeDescr, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_parsed_expression(Opaque, obj, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 85c2a8f0..7117484b 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_parsed_formal(DDefineSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index e545eedd..b0f5861d 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_formal(DExpectExprSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp index ad5678a5..a242df29 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_formal(DExpectFormalArgSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_expression(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp index 91738110..006d122b 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_formal(DExpectFormalArglistSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 0a35bb71..b7f208e8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_formal(DExpectSymbolSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 4b6950ab..473bd4b7 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_formal(DExpectTypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index af5d3cc9..d11ab3b7 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_parsed_formal(DExprSeqState & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp index 66633e88..39a3abb2 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DIfElseSsm::on_parsed_formal(DIfElseSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DIfElseSsm::on_parsed_expression(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp index ac4b2d14..e59546c8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DLambdaSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -32,7 +32,6 @@ namespace xo { { self.on_token(tk, p_psm); } - auto ISyntaxStateMachine_DLambdaSsm::on_parsed_symbol(DLambdaSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { @@ -44,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DLambdaSsm::on_parsed_formal(DLambdaSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DLambdaSsm::on_parsed_expression(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); @@ -57,4 +61,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISyntaxStateMachine_DLambdaSsm.cpp */ +/* end ISyntaxStateMachine_DLambdaSsm.cpp */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 1fdd6c90..6fe3f822 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -43,6 +43,11 @@ namespace xo { self.on_parsed_typedescr(td, p_psm); } auto + ISyntaxStateMachine_DProgressSsm::on_parsed_formal(DProgressSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto ISyntaxStateMachine_DProgressSsm::on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 2d9e4970..911b594a 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -129,6 +129,17 @@ namespace xo { this->stack_->top().on_parsed_typedescr(td, this); } + void + ParserStateMachine::on_parsed_formal(const DUniqueString * sym, + TypeDescr td) + { + scope log(XO_DEBUG(debug_flag_), xtag("sym", std::string_view(*sym)), xtag("td", td)); + + assert(stack_); + + this->stack_->top().on_parsed_formal(sym, td, this); + } + void ParserStateMachine::on_parsed_expression(obj expr) { @@ -248,6 +259,31 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + void + ParserStateMachine::illegal_parsed_formal(std::string_view ssm_name, + const DUniqueString * param_name, + TypeDescr param_type, + std::string_view expect_str) + { + // TODO: + // - want to write error message using DArena + // - need something like log_streambuf and/or tostr() that's arena-aware + + auto errmsg_string = tostr("Unexpected expression", + xtag("param_name", std::string_view(*param_name)), + xtag("param_type", param_type), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_parsed_expression")); + + assert(expr_alloc_); + + auto errmsg = DString::from_view(expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } + void ParserStateMachine::illegal_parsed_expression(std::string_view ssm_name, obj expr, From f8d5d8834dc463928febf7675533c4e509a10adf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 13:28:30 -0500 Subject: [PATCH 113/258] xo-reader2: DExpectFormalArglistSsm handles+stores parsed formals --- .../xo/reader2/DExpectFormalArglistSsm.hpp | 2 +- .../src/reader2/DExpectFormalArglistSsm.cpp | 67 +++++++++++++++---- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index f4c24303..ac7bc643 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -147,7 +147,7 @@ namespace xo { /** populate with (parmaeter-name, parameter-type) list * as they're encountered. * - * Not using flexible array here since we don't know size + * Not using flexible array here since we don't know size at construction time **/ DArray * argl_ = nullptr; }; diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index a5b77c4d..555ab275 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -7,6 +7,8 @@ #include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" #include "DExpectFormalArgSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp" +#include +#include #include #include #include @@ -191,12 +193,65 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm) { + if (fastate_ == formalarglstatetype::argl_1a) { + this->fastate_ = formalarglstatetype::argl_1b; + + TypeRef typeref = TypeRef::dwim(TypeRef::prefix_type::from_chars("formal"), param_type); + + DVariable * var = DVariable::make(p_psm->expr_alloc(), + param_name, + typeref); + + // need AGCObject facet to use DArray here. + // May want to have gc feature that allows it to use + // FacetRegistry on memory that stores obj + // + // In this case doesn't matter since DExpectFormalArglistSsm not actually collected! + + obj var_o(var); + + if (argl_->size() == argl_->capacity()) { + // need to expand argl_ capacity. + // If DArena were to allow it (i.e. offer a realloc() feature, + // could do this in place since this SSM is at the top of the parser stack. + + obj mm(&(p_psm->parser_alloc())); + + DArray * argl_2x = DArray::empty(mm, 2 * argl_->capacity()); + + for (DArray::size_type i = 0, n = argl_->size(); i < n; ++i) { + // TODO: prefer non-bounds-checked access here + argl_2x->push_back(argl_->at(i)); + } + + // update in place + this->argl_ = argl_2x; + } + + this->argl_->push_back(var_o); + return; + } + p_psm->illegal_parsed_formal("DExpectFormalArglistSsm::on_parsed_formal", param_name, param_type, this->get_expect_str()); } +#ifdef NOT_YET + void + expect_formal_arglist_xs::on_formal(const rp & formal, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_1a) { + this->farglxs_type_ = formalarglstatetype::argl_1b; + this->argl_.push_back(formal); + } else { + exprstate::on_formal(formal, p_psm); + } + } +#endif + void DExpectFormalArglistSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) @@ -239,18 +294,6 @@ namespace xo { } #ifdef NOT_YET - void - expect_formal_arglist_xs::on_formal(const rp & formal, - parserstatemachine * p_psm) - { - if (farglxs_type_ == formalarglstatetype::argl_1a) { - this->farglxs_type_ = formalarglstatetype::argl_1b; - this->argl_.push_back(formal); - } else { - exprstate::on_formal(formal, p_psm); - } - } - void expect_formal_arglist_xs::on_comma_token(const token_type & tk, parserstatemachine * p_psm) From 6df599673aa43a472d537eacc91e4a36460e5def Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 13:48:24 -0500 Subject: [PATCH 114/258] xo-reader2: DExpectFormalArglistSsm parses multiple formals --- .../xo/reader2/DExpectFormalArglistSsm.hpp | 8 +-- .../src/reader2/DExpectFormalArglistSsm.cpp | 67 ++++++------------- xo-reader2/utest/SchematikaParser.test.cpp | 44 ++++++++++-- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 4 files changed, 67 insertions(+), 54 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index ac7bc643..2898fa7c 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -75,6 +75,10 @@ namespace xo { void on_leftparen_token(const Token & tk, ParserStateMachine * p_psm); + /** update state on incoming token @p tk, with overall parser state in @p psm **/ + void on_comma_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectformalarglistssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -140,10 +144,6 @@ namespace xo { private: /** parsing state-machine state **/ formalarglstatetype fastate_ = formalarglstatetype::argl_0; - /** number of formal parameters encountered. - * Invariant: n_args_ <= argl_->size() - **/ - size_type n_args_ = 0; /** populate with (parmaeter-name, parameter-type) list * as they're encountered. * diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index 555ab275..676e0a9e 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -122,6 +122,10 @@ namespace xo { this->on_leftparen_token(tk, p_psm); return; + case tokentype::tk_comma: + this->on_comma_token(tk, p_psm); + return; + // all the not-yet-handled cases case tokentype::tk_lambda: case tokentype::tk_def: @@ -145,7 +149,6 @@ namespace xo { case tokentype::tk_lessequal: case tokentype::tk_greatequal: case tokentype::tk_dot: - case tokentype::tk_comma: case tokentype::tk_doublecolon: case tokentype::tk_assign: case tokentype::tk_yields: @@ -238,20 +241,6 @@ namespace xo { this->get_expect_str()); } -#ifdef NOT_YET - void - expect_formal_arglist_xs::on_formal(const rp & formal, - parserstatemachine * p_psm) - { - if (farglxs_type_ == formalarglstatetype::argl_1a) { - this->farglxs_type_ = formalarglstatetype::argl_1b; - this->argl_.push_back(formal); - } else { - exprstate::on_formal(formal, p_psm); - } - } -#endif - void DExpectFormalArglistSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) @@ -270,13 +259,6 @@ namespace xo { this->get_expect_str()); } -#ifdef NOT_YET - expect_formal_arglist_xs::expect_formal_arglist_xs() - : exprstate(exprstatetype::expect_formal_arglist), - farglxs_type_{formalarglstatetype::argl_0} - {} -#endif - void DExpectFormalArglistSsm::on_leftparen_token(const Token & tk, ParserStateMachine * p_psm) @@ -293,19 +275,23 @@ namespace xo { this->get_expect_str()); } -#ifdef NOT_YET void - expect_formal_arglist_xs::on_comma_token(const token_type & tk, - parserstatemachine * p_psm) + DExpectFormalArglistSsm::on_comma_token(const Token & tk, + ParserStateMachine * p_psm) { - if (farglxs_type_ == formalarglstatetype::argl_1b) { - this->farglxs_type_ = formalarglstatetype::argl_1a; - expect_formal_xs::start(p_psm); - } else { - exprstate::on_comma_token(tk, p_psm); + if (fastate_ == formalarglstatetype::argl_1b) { + this->fastate_ = formalarglstatetype::argl_1a; + + DExpectFormalArgSsm::start(p_psm); + return; } + + p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_comma_token", + tk, + this->get_expect_str()); } +#ifdef NOT_YET void expect_formal_arglist_xs::on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) @@ -318,15 +304,6 @@ namespace xo { exprstate::on_rightparen_token(tk, p_psm); } } - - void - expect_formal_arglist_xs::print(std::ostream & os) const { - os << ""; - } #endif bool @@ -344,12 +321,12 @@ namespace xo { if (!pps->print_upto(xrefrtag("expect", this->get_expect_str()))) return false; - if (!pps->print_upto(xrefrtag("n_args", n_args_))) + if (!pps->print_upto(xrefrtag("n_args", argl_->size()))) return false; - for (size_type i_arg = 0; i_arg < n_args_; ++i_arg) { + for (size_type i_arg = 0; i_arg < argl_->size(); ++i_arg) { char buf[80]; - snprintf(buf, sizeof(buf), "arg[%ud]", i_arg); + snprintf(buf, sizeof(buf), "arg[%u]", i_arg); auto arg_gco = argl_->at(i_arg); obj arg_pr @@ -372,11 +349,11 @@ namespace xo { pps->pretty(refrtag("expect", this->get_expect_str())); pps->newline_indent(ppii.ci1()); - pps->pretty(refrtag("n_args", n_args_)); + pps->pretty(refrtag("n_args", argl_->size())); - for (size_type i_arg = 0; i_arg < n_args_; ++i_arg) { + for (size_type i_arg = 0, n_arg = argl_->size(); i_arg < n_arg; ++i_arg) { char buf[80]; - snprintf(buf, sizeof(buf), "arg[%ud]", i_arg); + snprintf(buf, sizeof(buf), "arg[%u]", i_arg); auto arg_gco = argl_->at(i_arg); obj arg_pr diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 934b26ed..cedb4c1d 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -215,7 +215,7 @@ namespace xo { /** Walkthrough parsing input equivalent to: * - * lambda (n : i64; + * lambda (n : i64, * **/ @@ -279,11 +279,10 @@ namespace xo { REQUIRE(result.is_incomplete()); } -#ifdef NOT_YET { - auto & result = parser.on_token(Token::i64_token("777")); + auto & result = parser.on_token(Token::comma_token()); - log && log("after i64 token:"); + log && log("after comma token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); @@ -292,6 +291,43 @@ namespace xo { REQUIRE(result.is_incomplete()); } + { + auto & result = parser.on_token(Token::symbol_token("r")); + + log && log("after symbol(r) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::colon_token()); + + log && log("after colon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("i64")); + + log && log("after symbol(i64) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + +#ifdef NOT_YET { auto & result = parser.on_token(Token::else_token()); diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index 55a2d57d..607bc0a4 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -106,7 +106,7 @@ namespace xo { /** token representing period @c "." **/ static Token dot() { return Token(tokentype::tk_dot); } /** token representing comma @c "," **/ - static Token comma() { return Token(tokentype::tk_comma); } + static Token comma_token() { return Token(tokentype::tk_comma); } /** token representing colon @c ":" **/ static Token colon_token() { return Token(tokentype::tk_colon); } /** token representing double-colo @c "::" **/ From 8f531065a9f5e8e8216a3df740cd62cd582d64c2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 15:12:00 -0500 Subject: [PATCH 115/258] xo-object2: implement APrintable for DArray --- xo-object2/CMakeLists.txt | 12 ++++++ xo-object2/include/xo/object2/DArray.hpp | 3 ++ .../xo/object2/number/IGCObject_DFloat.hpp | 1 + xo-object2/src/object2/CMakeLists.txt | 1 + xo-object2/src/object2/DArray.cpp | 41 +++++++++++++++++++ 5 files changed, 58 insertions(+) diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index 261b59df..83b24223 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -184,6 +184,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-printable-array + FACET_PKG xo_printable2 + FACET Printable + REPR Array + INPUT idl/IPrintable_DArray.json5 + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR array + OUTPUT_CPP_DIR src/object2 +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-object2-facetimpl-gcobject-array diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index 097b9a45..f50936e3 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -108,6 +108,9 @@ namespace xo { /** @defgroup darray-printable-methods **/ ///@{ + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + ///@} /** @defgroup darray-gcobject-methods **/ ///@{ diff --git a/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp b/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp index b27163c2..a5a01fff 100644 --- a/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp +++ b/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp @@ -14,6 +14,7 @@ #pragma once #include "GCObject.hpp" +#include #include #include #include "DFloat.hpp" diff --git a/xo-object2/src/object2/CMakeLists.txt b/xo-object2/src/object2/CMakeLists.txt index 2ea8a07f..609290e8 100644 --- a/xo-object2/src/object2/CMakeLists.txt +++ b/xo-object2/src/object2/CMakeLists.txt @@ -16,6 +16,7 @@ set(SELF_SRCS ISequence_Any.cpp ISequence_DArray.cpp ISequence_DList.cpp + IPrintable_DArray.cpp IPrintable_DList.cpp IPrintable_DBoolean.cpp IPrintable_DFloat.cpp diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index 1b4138c6..b1343a67 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -4,11 +4,16 @@ **/ #include "DArray.hpp" +#include +#include +#include #include #include #include namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; using xo::mm::AGCObject; using xo::facet::typeseq; @@ -62,6 +67,42 @@ namespace xo { } } + // printing support + + bool + DArray::pretty(const ppindentinfo & ppii) const + { + using xo::print::ppstate; + + ppstate * pps = ppii.pps(); + + if (ppii.upto()) { + /* perhaps print on one line */ + pps->write("["); + + for (size_t i = 0, n = this->size(); i < n; ++i ) { + if (i > 0) + pps->write(" "); + + obj elt + = FacetRegistry::instance().variant(this->at(i)); + + assert(elt.data()); + + if (!pps->print_upto(elt)) + return false; + + ++i; + } + + pps->write("]"); + return true; + } else { + pps->write("[...]"); + return false; + } + } + // gc hooks for IGCObject_DArray std::size_t From eaa99881e0b75459cd1bc004f3ae36b0543a78ea Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 15:17:57 -0500 Subject: [PATCH 116/258] xo-reader2: + PSM,SSM on_parsed_formal_arglist() --- .../src/object2/object2_register_facets.cpp | 2 ++ xo-reader2/idl/SyntaxStateMachine.json5 | 9 ++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 6 ++++ .../include/xo/reader2/DExpectExprSsm.hpp | 6 ++++ .../xo/reader2/DExpectFormalArgSsm.hpp | 6 ++++ .../xo/reader2/DExpectFormalArglistSsm.hpp | 8 ++++- .../include/xo/reader2/DExpectSymbolSsm.hpp | 6 ++++ .../include/xo/reader2/DExpectTypeSsm.hpp | 6 ++++ .../include/xo/reader2/DExprSeqState.hpp | 6 ++++ xo-reader2/include/xo/reader2/DIfElseSsm.hpp | 6 ++++ xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 6 ++++ .../include/xo/reader2/DProgressSsm.hpp | 2 ++ .../include/xo/reader2/ParserStateMachine.hpp | 14 ++++++++- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 ++ .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectExprSsm.hpp | 2 ++ ...SyntaxStateMachine_DExpectFormalArgSsm.hpp | 2 ++ ...axStateMachine_DExpectFormalArglistSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 ++ .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DIfElseSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DLambdaSsm.hpp | 2 ++ .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 ++ .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 ++ .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 ++ xo-reader2/src/reader2/DDefineSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 9 ++++++ .../src/reader2/DExpectFormalArgSsm.cpp | 9 ++++++ .../src/reader2/DExpectFormalArglistSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DExpectTypeSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 9 ++++++ xo-reader2/src/reader2/DIfElseSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DLambdaSsm.cpp | 9 ++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 9 ++++++ .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 ++++ .../ISyntaxStateMachine_DDefineSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DExpectExprSsm.cpp | 5 ++++ ...SyntaxStateMachine_DExpectFormalArgSsm.cpp | 5 ++++ ...axStateMachine_DExpectFormalArglistSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DExprSeqState.cpp | 5 ++++ .../ISyntaxStateMachine_DIfElseSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DLambdaSsm.cpp | 5 ++++ .../ISyntaxStateMachine_DProgressSsm.cpp | 5 ++++ xo-reader2/src/reader2/ParserStateMachine.cpp | 30 ++++++++++++++++++- 49 files changed, 285 insertions(+), 3 deletions(-) diff --git a/xo-object2/src/object2/object2_register_facets.cpp b/xo-object2/src/object2/object2_register_facets.cpp index be68e009..a910e276 100644 --- a/xo-object2/src/object2/object2_register_facets.cpp +++ b/xo-object2/src/object2/object2_register_facets.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); log && log(xtag("DVariantPlaceholder.tseq", typeseq::id())); diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index fba93437..716b7268 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -82,6 +82,15 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_formal_arglist", + doc: ["consume formal arglist emitted by nested ssm"], + return_type: "void", + args: [ + {type: "DArray *", name: "arglist"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_parsed_expression", doc: ["update state machine for incoming parsed expression @p expr"], diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index bf0a3ffb..ebd454c0 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -202,6 +202,12 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 8e51124d..ae4154ef 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -142,6 +142,12 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index ee5eb0ea..51eb6536 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -112,6 +112,12 @@ namespace xo { TypeDescr td, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** update state on parsed expression emitted by nested ssm * with overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index 2898fa7c..289b7cf5 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -114,6 +114,12 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** update state on parsed expression emitted by nested ssm * with overall parser state in @p p_psm **/ @@ -144,7 +150,7 @@ namespace xo { private: /** parsing state-machine state **/ formalarglstatetype fastate_ = formalarglstatetype::argl_0; - /** populate with (parmaeter-name, parameter-type) list + /** populate with (parameter-name, parameter-type) list * as they're encountered. * * Not using flexible array here since we don't know size at construction time diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 080380b9..accfa936 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -85,6 +85,12 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr * in nested state machine. * (provided to satisfy ASyntaxStateMachine api. not reachable) diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 3ca99815..729eac83 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -136,6 +136,12 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** operate state machine for this syntax on receiving expression * from nested parser. * (provided to satisfy ASyntaxStateMachine api. not reachable) diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index c718cbef..a7b19c28 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -145,6 +145,12 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** update state for this syntax on parsed expression @p expr * from nested ssm. * overall parser state in @p p_psm diff --git a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp index 647a5e34..62f7d137 100644 --- a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp @@ -159,6 +159,12 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm. **/ diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index 69cb3322..8800ad1c 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -123,6 +123,12 @@ namespace xo { TypeDescr td, ParserStateMachine * p_psm); + /** consume formal params @p arglist from completed nested ssm, + * with overall parser state in @p p_psm. + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); + /** update this ssm when nested parser * emits expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index fa0ec733..ae9c2244 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -173,6 +173,8 @@ namespace xo { void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm); void on_parsed_expression(obj, ParserStateMachine * p_psm); void on_parsed_expression_with_semicolon(obj expr, diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 74f27876..1c5729a6 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -103,11 +104,16 @@ namespace xo { void on_parsed_typedescr(TypeDescr td); /** update state to consume param (name, value) emitted by - * nested (but not popped) parsing state + * nested (expired) parsing state **/ void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type); + /** update state to consume formal arugment list + * emitted by nested (expired) parsing state + **/ + void on_parsed_formal_arglist(DArray * arglist); + /** update state to respond to parsed expression @p expr * (from nested parsing state) **/ @@ -178,6 +184,12 @@ namespace xo { TypeDescr param_type, std::string_view expect_str); + /** @p arglist stores obj pointers. + **/ + void illegal_parsed_formal_arglist(std::string_view ssm_name, + DArray * arglist, + std::string_view expect_str); + /** report illegal parsed expression from nested ssm. * Introducing as placeholder; not clear if this will be reachable * in full parser diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index 6cc3b829..b9df6e6d 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -65,6 +65,8 @@ public: virtual void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) = 0; /** operate state machine for formal emitted by nested ssm **/ virtual void on_parsed_formal(Opaque data, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) = 0; + /** consume formal arglist emitted by nested ssm **/ + virtual void on_parsed_formal_arglist(Opaque data, DArray * arglist, ParserStateMachine * p_psm) = 0; /** update state machine for incoming parsed expression @p expr **/ virtual void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 3faa0f67..e239c46b 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -64,6 +64,7 @@ namespace scm { [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; [[noreturn]] void on_parsed_formal(Opaque, const DUniqueString *, TypeDescr, ParserStateMachine *) override; + [[noreturn]] void on_parsed_formal_arglist(Opaque, DArray *, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression(Opaque, obj, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression_with_semicolon(Opaque, obj, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index f4d0da9d..42616a38 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DDefineSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DDefineSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 3ff00e07..53669967 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectExprSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DExpectExprSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp index adce6eb9..99d6c9a9 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectFormalArgSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectFormalArgSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DExpectFormalArgSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp index b8a3b416..570ee3a4 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectFormalArglistSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectFormalArglistSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DExpectFormalArglistSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index d778e293..2003db8a 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectSymbolSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DExpectSymbolSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 9d6f153a..acb752fe 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectTypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DExpectTypeSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index d958f1f8..3c160d00 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExprSeqState & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DExprSeqState & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp index 88a8b7d8..462172d2 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DIfElseSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DIfElseSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DIfElseSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp index 02582d0b..fa0cb0a2 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DLambdaSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DLambdaSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DLambdaSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index ee2dfbaf..ddd0c06e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DProgressSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DProgressSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr followed by semicolon **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 51ab0f30..e89357ab 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -64,6 +64,9 @@ namespace scm { void on_parsed_formal(Opaque data, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) override { return I::on_parsed_formal(_dcast(data), param_name, param_type, p_psm); } + void on_parsed_formal_arglist(Opaque data, DArray * arglist, ParserStateMachine * p_psm) override { + return I::on_parsed_formal_arglist(_dcast(data), arglist, p_psm); + } void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) override { return I::on_parsed_expression(_dcast(data), expr, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 3de33f8e..0e2b8636 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -68,6 +68,9 @@ public: void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) { return O::iface()->on_parsed_formal(O::data(), param_name, param_type, p_psm); } + void on_parsed_formal_arglist(DArray * arglist, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_formal_arglist(O::data(), arglist, p_psm); + } void on_parsed_expression(obj expr, ParserStateMachine * p_psm) { return O::iface()->on_parsed_expression(O::data(), expr, p_psm); } diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 65df6349..1636c4b0 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -715,6 +715,15 @@ namespace xo { this->get_expect_str()); } + void + DDefineSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DDefineSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DDefineSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 2a836e87..c7fe298a 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -365,6 +365,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectExprSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DExpectExprSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DExpectExprSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index eb174fc9..4aaf7c4b 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -212,6 +212,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectFormalArgSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DExpectFormalArgSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DExpectFormalArgSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index 676e0a9e..63113f4e 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -241,6 +241,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectFormalArglistSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DExpectFormalArglistSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DExpectFormalArglistSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index cee3a08c..60985cae 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -84,6 +84,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DExpectSymbolSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 8f848269..5e42f758 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -285,6 +285,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DExpectTypeSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DExpectTypeSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 5d9fe9b1..12847350 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -460,6 +460,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DExprSeqState::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DExprSeqState::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index 9f7d7167..f0bf9556 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -391,6 +391,15 @@ namespace xo { } + void + DIfElseSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DIfElseSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + #ifdef NOT_YET void if_else_xs::on_expr(bp expr, diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index f9fcd6ae..99e01ffd 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -349,6 +349,15 @@ namespace xo { this->get_expect_str()); } + void + DLambdaSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DLambdaSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DLambdaSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 1233c198..57e21ec8 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -566,6 +566,15 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist("DProgressSsm::on_parsed_formal_arglist", + arglist, + this->get_expect_str()); + } + void DProgressSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 2a16a292..18510abb 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -58,6 +58,12 @@ ISyntaxStateMachine_Any::on_parsed_formal(Opaque, const DUniqueString *, TypeDes _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_formal_arglist(Opaque, DArray *, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_parsed_expression(Opaque, obj, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 7117484b..80dc0c81 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_parsed_formal_arglist(DDefineSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index b0f5861d..d6b44995 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_formal_arglist(DExpectExprSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp index a242df29..b3337d4e 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_formal_arglist(DExpectFormalArgSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_expression(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp index 006d122b..318283a3 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_formal_arglist(DExpectFormalArglistSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index b7f208e8..77b083d6 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_formal_arglist(DExpectSymbolSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 473bd4b7..ffd0b209 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_formal_arglist(DExpectTypeSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index d11ab3b7..5a9c2e3a 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExprSeqState::on_parsed_formal_arglist(DExprSeqState & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DExprSeqState::on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp index 39a3abb2..94aa8be5 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DIfElseSsm::on_parsed_formal_arglist(DIfElseSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DIfElseSsm::on_parsed_expression(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp index e59546c8..2a03a774 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DLambdaSsm::on_parsed_formal_arglist(DLambdaSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DLambdaSsm::on_parsed_expression(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 6fe3f822..1f161ffc 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DProgressSsm::on_parsed_formal_arglist(DProgressSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto ISyntaxStateMachine_DProgressSsm::on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm) -> void { self.on_parsed_expression(expr, p_psm); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 911b594a..0316515e 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -6,6 +6,8 @@ #include "ParserStateMachine.hpp" #include "ParserStack.hpp" #include "SyntaxStateMachine.hpp" +#include +#include #include #include #include @@ -13,6 +15,7 @@ #include namespace xo { + using xo::print::APrintable; using xo::facet::with_facet; namespace scm { @@ -140,6 +143,17 @@ namespace xo { this->stack_->top().on_parsed_formal(sym, td, this); } + void + ParserStateMachine::on_parsed_formal_arglist(DArray * arglist) + { + scope log(XO_DEBUG(debug_flag_), + xtag("arglist", obj(arglist))); + + assert(stack_); + + this->stack_->top().on_parsed_formal_arglist(arglist, this); + } + void ParserStateMachine::on_parsed_expression(obj expr) { @@ -269,7 +283,7 @@ namespace xo { // - want to write error message using DArena // - need something like log_streambuf and/or tostr() that's arena-aware - auto errmsg_string = tostr("Unexpected expression", + auto errmsg_string = tostr("Unexpected formal", xtag("param_name", std::string_view(*param_name)), xtag("param_type", param_type), xtag("expecting", expect_str), @@ -284,6 +298,20 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + void + ParserStateMachine::illegal_parsed_formal_arglist(std::string_view ssm_name, + DArray * arglist, + std::string_view expect_str) + { + obj arglist_pr(arglist); + + auto errmsg_string = tostr("Unexpected formal arglist", + xtag("arglist", arglist_pr), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_parsed_formal_arglist")); + } + void ParserStateMachine::illegal_parsed_expression(std::string_view ssm_name, obj expr, From 298e05dd06bcbec4f150ccd40861d1ff5f6ab443 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 15:19:35 -0500 Subject: [PATCH 117/258] xo-object2: missed generated (Printable,Array) code + .json5 --- xo-object2/idl/IPrintable_DArray.json5 | 13 ++++ .../xo/object2/array/IPrintable_DArray.hpp | 62 +++++++++++++++++++ xo-object2/src/object2/IPrintable_DArray.cpp | 28 +++++++++ .../xo/reader2/DSyntaxStateMachine.hpp | 42 +++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 xo-object2/idl/IPrintable_DArray.json5 create mode 100644 xo-object2/include/xo/object2/array/IPrintable_DArray.hpp create mode 100644 xo-object2/src/object2/IPrintable_DArray.cpp create mode 100644 xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp diff --git a/xo-object2/idl/IPrintable_DArray.json5 b/xo-object2/idl/IPrintable_DArray.json5 new file mode 100644 index 00000000..df0ef171 --- /dev/null +++ b/xo-object2/idl/IPrintable_DArray.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DArray", + using_doxygen: true, + repr: "DArray", + doc: [ "implement APrintable for DArray" ], +} diff --git a/xo-object2/include/xo/object2/array/IPrintable_DArray.hpp b/xo-object2/include/xo/object2/array/IPrintable_DArray.hpp new file mode 100644 index 00000000..1b3a4663 --- /dev/null +++ b/xo-object2/include/xo/object2/array/IPrintable_DArray.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DArray.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DArray.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DArray.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DArray.hpp" + +namespace xo { namespace scm { class IPrintable_DArray; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DArray + **/ + class IPrintable_DArray { + public: + /** @defgroup scm-printable-darray-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-darray-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DArray & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-object2/src/object2/IPrintable_DArray.cpp b/xo-object2/src/object2/IPrintable_DArray.cpp new file mode 100644 index 00000000..d444800b --- /dev/null +++ b/xo-object2/src/object2/IPrintable_DArray.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DArray.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DArray.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DArray.json5] +**/ + +#include "array/IPrintable_DArray.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DArray::pretty(const DArray & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DArray.cpp */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp new file mode 100644 index 00000000..4aa35f4d --- /dev/null +++ b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp @@ -0,0 +1,42 @@ +/** @file DSyntaxStateMachine.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + + /** @class DSyntaxStateMachine + * @brief static interface for implementing ASyntaxStateMachine + * + * Using CRTP to collect methods common to ASyntaxStateMachine + * implementations. + * + * Deliberately unusable through base class pointer. + * For runtime polymorphism use something like: + * @code + * Derived * d = ...; + * auto obj = with_facet::mkobj(d); + * // or + * obj(d) + * @endcode + **/ + template + class DSyntaxStateMachine { + friend Derived; + + /** arglist is DArray of obj **/ + void on_parsed_formal_arglist(this auto&& self, DArray * arglist, ParserStateMachine * p_psm) { + p_psm->illegal_parsed_formal_arglist( + + } + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DSyntaxStateMachine.hpp */ From 94efaf46cd18746d7fa04289e38f838bca9ca003 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 10:26:35 -0500 Subject: [PATCH 118/258] xo-expression2 xo-reader2: local symtab stack in PSM --- xo-expression2/CMakeLists.txt | 24 +++++++ .../idl/IPrintable_DLocalSymtab.json5 | 13 ++++ .../idl/ISymbolTable_DLocalSymtab.json5 | 12 ++++ .../include/xo/expression2/Binding.hpp | 1 + .../include/xo/expression2/DLocalSymtab.hpp | 11 +++- .../detail/IExpression_DIfElseExpr.hpp | 2 +- .../detail/IGCObject_DVariable.hpp | 2 +- .../detail/IPrintable_DIfElseExpr.hpp | 2 +- .../symtab/IPrintable_DLocalSymtab.hpp | 62 +++++++++++++++++++ .../symtab/ISymbolTable_DLocalSymtab.hpp | 60 ++++++++++++++++++ xo-expression2/src/expression2/CMakeLists.txt | 3 + .../src/expression2/DLocalSymtab.cpp | 62 ++++++++++++++++++- .../expression2/IExpression_DIfElseExpr.cpp | 2 +- .../src/expression2/IGCObject_DVariable.cpp | 2 +- .../expression2/IPrintable_DIfElseExpr.cpp | 2 +- .../expression2/IPrintable_DLocalSymtab.cpp | 28 +++++++++ .../expression2/ISymbolTable_DLocalSymtab.cpp | 34 ++++++++++ .../expression2_register_facets.cpp | 9 +++ .../xo/reader2/DExpectFormalArglistSsm.hpp | 8 ++- xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 4 +- .../include/xo/reader2/ParserStateMachine.hpp | 31 +++++++++- .../src/reader2/DExpectFormalArglistSsm.cpp | 25 +++++--- xo-reader2/src/reader2/DLambdaSsm.cpp | 52 ++++++++++++++++ xo-reader2/src/reader2/ParserStack.cpp | 2 +- xo-reader2/src/reader2/ParserStateMachine.cpp | 20 ++++++ xo-reader2/utest/SchematikaParser.test.cpp | 6 +- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 27 files changed, 447 insertions(+), 34 deletions(-) create mode 100644 xo-expression2/idl/IPrintable_DLocalSymtab.json5 create mode 100644 xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 create mode 100644 xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp create mode 100644 xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp create mode 100644 xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp create mode 100644 xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 63ff9fad..ae1bb8c2 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -34,6 +34,30 @@ xo_add_genfacet( # ---------------------------------------------------------------- +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-symboltable-localsymtab + FACET_PKG xo_expression2 + FACET SymbolTable + REPR LocalSymtab + INPUT idl/ISymbolTable_DLocalSymtab.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR symtab + OUTPUT_CPP_DIR src/expression2 +) + +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-localsymtab + FACET_PKG xo_printable2 + FACET Printable + REPR LocalSymtab + INPUT idl/IPrintable_DLocalSymtab.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR symtab + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacet( TARGET xo-expression2-facet-expression diff --git a/xo-expression2/idl/IPrintable_DLocalSymtab.json5 b/xo-expression2/idl/IPrintable_DLocalSymtab.json5 new file mode 100644 index 00000000..3f17e64e --- /dev/null +++ b/xo-expression2/idl/IPrintable_DLocalSymtab.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DLocalSymtab", + using_doxygen: true, + repr: "DLocalSymtab", + doc: [ "implement APrintable for DLocalSymtab" ], +} diff --git a/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 b/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 new file mode 100644 index 00000000..026c0ed1 --- /dev/null +++ b/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SymbolTable.json5", + brief: "provide ASymbolTable interface for DLocalSymtab", + using_doxygen: true, + repr: "DLocalSymtab", + doc: [ "implement ASymbolTable for DLocalSymtab" ], +} diff --git a/xo-expression2/include/xo/expression2/Binding.hpp b/xo-expression2/include/xo/expression2/Binding.hpp index e97cc715..6dffb16b 100644 --- a/xo-expression2/include/xo/expression2/Binding.hpp +++ b/xo-expression2/include/xo/expression2/Binding.hpp @@ -25,6 +25,7 @@ namespace xo { static Binding local(int32_t j_slot) { return Binding(0, j_slot); } bool is_global() const { return i_link_ == s_link_global; } + bool is_local() const { return (i_link_ == 0) && (j_slot_ >= 0); } int32_t i_link() const noexcept { return i_link_; } int32_t j_slot() const noexcept { return j_slot_; } diff --git a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp index 9eada176..01d9aa85 100644 --- a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp @@ -45,20 +45,23 @@ namespace xo { /** @defgroup scm-lambdaexpr-constructors **/ ///@{ - /** empty instance with capacity for n slots. + /** empty instance with parent @p p and capacity for @p n slots. * Caller must ensure that slots_[0..n) are actually addressable **/ - DLocalSymtab(size_type n); + DLocalSymtab(DLocalSymtab * p, size_type n); /** scaffold empty symtab instance, * with capacity for @p n slots, using memory from allocator @p mm **/ - static DLocalSymtab * _make_empty(obj mm, size_type n); + static DLocalSymtab * _make_empty(obj mm, + DLocalSymtab * p, + size_type n); ///@} /** @defgroup scm-lambdaexpr-methods **/ ///@{ + DLocalSymtab * parent() const noexcept { return parent_; } size_type capacity() const noexcept { return capacity_; } size_type size() const noexcept { return size_; } @@ -96,6 +99,8 @@ namespace xo { ///@} private: + /** parent symbol table from scoping surrounding this one **/ + DLocalSymtab * parent_ = nullptr; /** actual range of slots_[] array. Can use inices in [0,..,n) **/ size_type capacity_ = 0; /** number of slots in use **/ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp index 03500a39..7d726dde 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp index aee612ea..24dc591f 100644 --- a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp index e9cf67ff..fcf80fd5 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp new file mode 100644 index 00000000..c013e937 --- /dev/null +++ b/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DLocalSymtab.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLocalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLocalSymtab.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DLocalSymtab.hpp" + +namespace xo { namespace scm { class IPrintable_DLocalSymtab; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DLocalSymtab + **/ + class IPrintable_DLocalSymtab { + public: + /** @defgroup scm-printable-dlocalsymtab-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dlocalsymtab-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DLocalSymtab & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp new file mode 100644 index 00000000..72f409dd --- /dev/null +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp @@ -0,0 +1,60 @@ +/** @file ISymbolTable_DLocalSymtab.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISymbolTable_DLocalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISymbolTable_DLocalSymtab.json5] + **/ + +#pragma once + +#include "SymbolTable.hpp" +#include "DLocalSymtab.hpp" + +namespace xo { namespace scm { class ISymbolTable_DLocalSymtab; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISymbolTable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISymbolTable_DLocalSymtab + **/ + class ISymbolTable_DLocalSymtab { + public: + /** @defgroup scm-symboltable-dlocalsymtab-type-traits **/ + ///@{ + using Copaque = xo::scm::ASymbolTable::Copaque; + using Opaque = xo::scm::ASymbolTable::Opaque; + ///@} + /** @defgroup scm-symboltable-dlocalsymtab-methods **/ + ///@{ + // const methods + /** true iff this is toplevel (global) symbol table. **/ + static bool is_global_symtab(const DLocalSymtab & self) noexcept; + /** report ingredients needed to address variable at runtime. **/ + static Binding lookup_binding(const DLocalSymtab & self, const DUniqueString * sym) noexcept; + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 03bd8230..8e6565c4 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -39,6 +39,9 @@ set(SELF_SRCS ISymbolTable_Any.cpp + ISymbolTable_DLocalSymtab.cpp + IPrintable_DLocalSymtab.cpp + StringTable.cpp DUniqueString.cpp diff --git a/xo-expression2/src/expression2/DLocalSymtab.cpp b/xo-expression2/src/expression2/DLocalSymtab.cpp index c38096ff..85631d34 100644 --- a/xo-expression2/src/expression2/DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/DLocalSymtab.cpp @@ -5,14 +5,21 @@ #include "DLocalSymtab.hpp" #include "DUniqueString.hpp" +#include +#include #include namespace xo { + using xo::print::APrintable; using xo::facet::typeseq; + using xo::print::ppstate; namespace scm { - DLocalSymtab::DLocalSymtab(size_type n) : capacity_{n}, size_{0} + DLocalSymtab::DLocalSymtab(DLocalSymtab * p, + size_type n) : parent_{p}, + capacity_{n}, + size_{0} { for (size_type i = 0; i < n; ++i) { void * mem = &slots_[i]; @@ -21,12 +28,14 @@ namespace xo { } DLocalSymtab * - DLocalSymtab::_make_empty(obj mm, size_type n) + DLocalSymtab::_make_empty(obj mm, + DLocalSymtab * p, + size_type n) { void * mem = mm.alloc(typeseq::id(), sizeof(DLocalSymtab) + (n * sizeof(Slot))); - return new (mem) DLocalSymtab(n); + return new (mem) DLocalSymtab(p, n); } Binding @@ -68,6 +77,53 @@ namespace xo { return Binding(); } + bool + DLocalSymtab::pretty(const ppindentinfo & ppii) const + { + ppstate * pps = ppii.pps(); + + if (ppii.upto()) { + /* perhaps print on one line */ + if (!pps->print_upto("print_upto(xrefrtag("size", size_))) + return false; + + for (size_type i = 0; i < size_; ++i) { + char buf[32]; + snprintf(buf, sizeof(buf), "[%u]", i); + + assert(slots_[i].var_); + + obj arg_pr(const_cast(slots_[i].var_)); + + if (!pps->print_upto(xrefrtag(buf, arg_pr))) + return false; + } + + pps->write(">"); + return true; + } else { + /* with line breaks */ + + pps->write("newline_pretty_tag(ppii.ci1(), "size", size_); + + for (size_type i = 0; i < size_; ++i) { + char buf[32]; + snprintf(buf, sizeof(buf), "[%u]", i); + + assert(slots_[i].var_); + + obj arg_pr(const_cast(slots_[i].var_)); + + pps->newline_pretty_tag(ppii.ci1(), buf, arg_pr); + } + + pps->write(">"); + return false; + } + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp index 78680310..d913eaf0 100644 --- a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IGCObject_DVariable.cpp b/xo-expression2/src/expression2/IGCObject_DVariable.cpp index 8735b286..4af0f906 100644 --- a/xo-expression2/src/expression2/IGCObject_DVariable.cpp +++ b/xo-expression2/src/expression2/IGCObject_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp index ec68b9fc..a75cd6a4 100644 --- a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp b/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp new file mode 100644 index 00000000..dbd4887b --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DLocalSymtab.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLocalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLocalSymtab.json5] +**/ + +#include "symtab/IPrintable_DLocalSymtab.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DLocalSymtab::pretty(const DLocalSymtab & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DLocalSymtab.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp b/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp new file mode 100644 index 00000000..778cfdf4 --- /dev/null +++ b/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp @@ -0,0 +1,34 @@ +/** @file ISymbolTable_DLocalSymtab.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISymbolTable_DLocalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISymbolTable_DLocalSymtab.json5] +**/ + +#include "symtab/ISymbolTable_DLocalSymtab.hpp" + +namespace xo { + namespace scm { + auto + ISymbolTable_DLocalSymtab::is_global_symtab(const DLocalSymtab & self) noexcept -> bool + { + return self.is_global_symtab(); + } + + auto + ISymbolTable_DLocalSymtab::lookup_binding(const DLocalSymtab & self, const DUniqueString * sym) noexcept -> Binding + { + return self.lookup_binding(sym); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISymbolTable_DLocalSymtab.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index a6bd50e5..06ccc7d5 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -27,6 +27,9 @@ #include #include +#include +#include + #include #include #include @@ -74,6 +77,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DUniqueString.tseq", typeseq::id())); log && log(xtag("DDefineExpr.tseq", typeseq::id())); log && log(xtag("DVariable.tseq", typeseq::id())); @@ -82,7 +88,10 @@ namespace xo { log && log(xtag("DLambdaExpr.tseq", typeseq::id())); log && log(xtag("DIfElseExpr.tseq", typeseq::id())); + log && log(xtag("DLocalSymtab.tseq", typeseq::id())); + log && log(xtag("AExpression.tqseq", typeseq::id())); + log && log(xtag("ASymbolTable.tseq", typeseq::id())); return true; } diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index 289b7cf5..81d7e85d 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -71,14 +71,18 @@ namespace xo { /** @defgroup scm-expectformalarglistssm-methods general methods **/ ///@{ - /** update state on incoming token @p tk, with overall parser state in @p psm **/ + /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ void on_leftparen_token(const Token & tk, ParserStateMachine * p_psm); - /** update state on incoming token @p tk, with overall parser state in @p psm **/ + /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ void on_comma_token(const Token & tk, ParserStateMachine * p_psm); + /** update state on incoming rightparen token @p tk, with overall parser state in @p p_psm **/ + void on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectformalarglistssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index 8800ad1c..22185269 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -144,8 +144,6 @@ namespace xo { #ifdef NOT_YET virtual const char * get_expect_str() const override; - virtual void on_formal_arglist(const std::vector> & argl, - parserstatemachine * p_psm) override; virtual void on_leftbrace_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_colon_token(const token_type & tk, @@ -173,10 +171,10 @@ namespace xo { /** parsing state-machine state **/ lambdastatetype lmstate_ = lambdastatetype::lm_0; -#ifdef NOT_YET /** lambda environment (for formal parameters) **/ DLocalSymtab * local_symtab_ = nullptr; +#ifdef NOT_YET /** explicit return type (if supplied) **/ TypeDescr explicit_return_td_ = nullptr; diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 1c5729a6..fbf636e3 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -6,6 +6,8 @@ #pragma once #include "ParserResult.hpp" +#include +#include #include #include #include @@ -47,6 +49,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_; } + DLocalSymtab * local_symtab() const noexcept { return local_symtab_; } const ParserResult & result() const noexcept { return result_; } /** true iff state machine is currently idle (at top-level) **/ @@ -79,6 +82,15 @@ namespace xo { **/ const DUniqueString * intern_string(std::string_view str); + /** push nested local symtab while parsing the body of a lambda expression; + * restore previous symtab at the end of lambda-expression definition. + * See @ref pop_local_symtab + **/ + void push_local_symtab(DLocalSymtab * symtab); + + /** pop nested symbol table from symbol-table stack **/ + void pop_local_symtab(); + /** add variable to current local environment (innermost lexical scope) **/ void upsert_var(DVariable * var); @@ -219,8 +231,10 @@ namespace xo { * after encountering a parsing error. **/ DArena::Checkpoint parser_alloc_ckp_; - - /** parser stack. Memory from @ref parser_alloc_ **/ + /** parser stack. Memory always from @ref parser_alloc_; + * elements that should survive parsing allocate from + * @ref expr_alloc_, see below. + **/ ParserStack * stack_ = nullptr; /** Allocator for parsed expressions. @@ -239,6 +253,19 @@ namespace xo { **/ obj expr_alloc_; + /** symbol table with local bindings. + * non-null during parsing of lambda expressions. + * Always allocated from @p expr_alloc_. + * Push local symbol table here to remember local params + * during the body of a lambda expression. + **/ + DLocalSymtab * local_symtab_ = nullptr; + + /** global symbol table. + * Toplevel definitions go here. + **/ + DGlobalSymtab * global_symtab_ = nullptr; + /** current output from parser **/ ParserResult result_; diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index 63113f4e..bebe4108 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -126,6 +126,10 @@ namespace xo { this->on_comma_token(tk, p_psm); return; + case tokentype::tk_rightparen: + this->on_rightparen_token(tk, p_psm); + return; + // all the not-yet-handled cases case tokentype::tk_lambda: case tokentype::tk_def: @@ -139,7 +143,6 @@ namespace xo { case tokentype::tk_bool: case tokentype::tk_semicolon: case tokentype::tk_invalid: - case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: case tokentype::tk_leftbrace: @@ -300,20 +303,22 @@ namespace xo { this->get_expect_str()); } -#ifdef NOT_YET void - expect_formal_arglist_xs::on_rightparen_token(const token_type & tk, - parserstatemachine * p_psm) + DExpectFormalArglistSsm::on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) { - if (farglxs_type_ == formalarglstatetype::argl_1b) { - std::unique_ptr self = p_psm->pop_exprstate(); + if (fastate_ == formalarglstatetype::argl_1b) { + DArray * args = argl_; - p_psm->top_exprstate().on_formal_arglist(this->argl_, p_psm); - } else { - exprstate::on_rightparen_token(tk, p_psm); + p_psm->pop_ssm(); + p_psm->on_parsed_formal_arglist(args); + return; } + + p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_rightparen_token", + tk, + this->get_expect_str()); } -#endif bool DExpectFormalArglistSsm::pretty(const ppindentinfo & ppii) const diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 99e01ffd..4bcbb844 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -9,6 +9,9 @@ #include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" +#include +#include +//#include #include #include #include @@ -28,6 +31,7 @@ namespace xo { using xo::print::APrintable; using xo::mm::AAllocator; + using xo::mm::AGCObject; using xo::facet::FacetRegistry; using xo::reflect::typeseq; @@ -353,6 +357,54 @@ namespace xo { DLambdaSsm::on_parsed_formal_arglist(DArray * arglist, ParserStateMachine * p_psm) { + if (lmstate_ == lambdastatetype::lm_1) { + this->lmstate_ = lambdastatetype::lm_2; + /// something with top env frame ? + + /// TODO: arena-friendly non-gc-aware vector; + // use instead of DArray for arglist. + // something like DTypedArray + + /// create LocalSymtab from arglist + + DLocalSymtab * symtab + = DLocalSymtab::_make_empty(p_psm->expr_alloc(), + p_psm->local_symtab(), + arglist->size()); + assert(symtab); + + for (DArray::size_type i = 0, n = arglist->size(); i < n; ++i) { + obj param = arglist->at(i); + + // sad! runtime poly conversion from obj + // We on need this because of (suboptimally) using DArray to store arglist + + obj param_expr + = FacetRegistry::instance().variant(param); + obj param_var + = obj::from(param_expr); + + assert(param_expr.data()); + assert(param_var.data()); + + Binding b = symtab->append_var(p_psm->expr_alloc(), + param_var.data()->name(), + param_var.data()->typeref()); + + assert(b.is_local()); + + this->local_symtab_ = symtab; + } + + // stash env frame: records local variables while we handle lambda body + + p_psm->push_local_symtab(symtab); + + // control reenters via .on_colon_token() / .on_leftbrace_token() + + return; + } + p_psm->illegal_parsed_formal_arglist("DLambdaSsm::on_parsed_formal_arglist", arglist, this->get_expect_str()); diff --git a/xo-reader2/src/reader2/ParserStack.cpp b/xo-reader2/src/reader2/ParserStack.cpp index 9af9f339..e3ffb290 100644 --- a/xo-reader2/src/reader2/ParserStack.cpp +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -70,7 +70,7 @@ namespace xo { std::size_t i_frame = 0; while (frame) { - char buf[80]; + char buf[32]; snprintf(buf, sizeof(buf), "[%lu]", i_frame); auto ssm = (FacetRegistry::instance().variant diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 0316515e..085cce56 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -88,6 +88,20 @@ namespace xo { return stringtable_.intern(str); } + void + ParserStateMachine::push_local_symtab(DLocalSymtab * symtab) + { + this->local_symtab_ = symtab; + } + + void + ParserStateMachine::pop_local_symtab() + { + assert(local_symtab_); + + this->local_symtab_ = local_symtab_->parent(); + } + void ParserStateMachine::upsert_var(DVariable * var) { @@ -310,6 +324,12 @@ namespace xo { xtag("expecting", expect_str), xtag("ssm", ssm_name), xtag("via", "ParserStateMachine::illegal_parsed_formal_arglist")); + + assert(expr_alloc_); + + auto errmsg = DString::from_str(expr_alloc_, errmsg_string); + + this->capture_error(ssm_name, errmsg); } void diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index cedb4c1d..cc1e51fa 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -327,11 +327,10 @@ namespace xo { REQUIRE(result.is_incomplete()); } -#ifdef NOT_YET { - auto & result = parser.on_token(Token::else_token()); + auto & result = parser.on_token(Token::rightparen_token()); - log && log("after else token:"); + log && log("after rightparen token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); @@ -340,6 +339,7 @@ namespace xo { REQUIRE(result.is_incomplete()); } +#ifdef NOT_YET { auto & result = parser.on_token(Token::string_token("fooey")); diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index 607bc0a4..66427c3e 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -94,7 +94,7 @@ namespace xo { /** token representing left parenthesis @c "(" **/ static Token leftparen_token() { return Token(tokentype::tk_leftparen); } /** Token representing right parenthesis @c ")" **/ - static Token rightparen() { return Token(tokentype::tk_rightparen); } + static Token rightparen_token() { return Token(tokentype::tk_rightparen); } /** token representing left bracket @c "[" **/ static Token leftbracket() { return Token(tokentype::tk_leftbracket); } /** token representing right bracket @c "]" **/ From 6f2c793b1d77afa1b321898fef6bb645bb933793 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 12:41:09 -0500 Subject: [PATCH 119/258] xo-reader2: + assemble lambda function type in DLambdaSsm --- .../include/xo/expression2/DLambdaExpr.hpp | 8 + .../src/expression2/DLambdaExpr.cpp | 29 ++++ .../include/xo/reader2/DExpectExprSsm.hpp | 3 +- xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 8 +- xo-reader2/src/reader2/DDefineSsm.cpp | 3 +- xo-reader2/src/reader2/DExpectExprSsm.cpp | 5 +- xo-reader2/src/reader2/DIfElseSsm.cpp | 7 +- xo-reader2/src/reader2/DLambdaSsm.cpp | 164 +++++------------- xo-reader2/src/reader2/DProgressSsm.cpp | 8 +- xo-reader2/utest/SchematikaParser.test.cpp | 36 ++++ xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 6 +- 11 files changed, 137 insertions(+), 140 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp index bd9ff2c5..14be115f 100644 --- a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp @@ -47,6 +47,14 @@ namespace xo { const DUniqueString * name, DLocalSymtab * local_symtab, obj body); + + /** create type description for lambda with arguments described by @p symtab + * and return type @p return_td. + * Load-bearing for DLambdaSsm in xo-reader2/ + **/ + static TypeDescr assemble_lambda_td(DLocalSymtab * symtab, + TypeDescr return_td); + ///@} /** @defgroup scm-lambdaexpr-methods **/ ///@{ diff --git a/xo-expression2/src/expression2/DLambdaExpr.cpp b/xo-expression2/src/expression2/DLambdaExpr.cpp index fec939ac..a27e788b 100644 --- a/xo-expression2/src/expression2/DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/DLambdaExpr.cpp @@ -14,6 +14,8 @@ namespace xo { using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::reflect::TypeDescr; + using xo::reflect::TypeDescrBase; + using xo::reflect::FunctionTdxInfo; using xo::reflect::typeseq; namespace scm { @@ -82,6 +84,33 @@ namespace xo { body); } + TypeDescr + DLambdaExpr::assemble_lambda_td(DLocalSymtab * symtab, + TypeDescr return_td) + { + assert(return_td); + + std::vector arg_td_v; + { + DLocalSymtab::size_type z = symtab->size(); + + arg_td_v.reserve(z); + + for (DLocalSymtab::size_type i = 0; i < z; ++i) { + auto param = symtab->lookup_var(Binding::local(i)); + + assert(param); + arg_td_v.push_back(param->valuetype()); + } + } + + auto function_tdx = FunctionTdxInfo(return_td, arg_td_v, false /*!is_noexcept*/); + + TypeDescr lambda_td = TypeDescrBase::require_by_fn_info(function_tdx); + + return lambda_td; + } + exprtype DLambdaExpr::extype() const noexcept { return exprtype::lambda; diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index ae4154ef..accdbff3 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -32,8 +32,7 @@ namespace xo { bool allow_defs, bool cxl_on_rightparen, ParserStateMachine * p_psm); - static void start(DArena & parser_mm, - ParserStateMachine * p_psm); + static void start(ParserStateMachine * p_psm); /** @defgroup scm-expectexpr-access-methods access methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index 22185269..1be39031 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -88,6 +88,12 @@ namespace xo { void on_lambda_token(const Token & tk, ParserStateMachine * p_psm); + /** update ssm on yield token @p tk, + * with overall parser state in @p p_psm + **/ + void on_yields_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-lambdassm-syntaxstatemachine-facet **/ ///@{ @@ -174,13 +180,11 @@ namespace xo { /** lambda environment (for formal parameters) **/ DLocalSymtab * local_symtab_ = nullptr; -#ifdef NOT_YET /** explicit return type (if supplied) **/ TypeDescr explicit_return_td_ = nullptr; /** lambda signature (when known) **/ TypeDescr lambda_td_ = nullptr; -#endif /** body expression **/ obj body_; diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 1636c4b0..4e2bcf97 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -643,8 +643,7 @@ namespace xo { { this->defstate_ = defexprstatetype::def_5; - DExpectExprSsm::start(p_psm->parser_alloc(), - p_psm); + DExpectExprSsm::start(p_psm); return; } diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index c7fe298a..3f99daca 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -83,10 +83,9 @@ namespace xo { } void - DExpectExprSsm::start(DArena & mm, - ParserStateMachine * p_psm) + DExpectExprSsm::start(ParserStateMachine * p_psm) { - start(mm, + start(p_psm->parser_alloc(), false /*!allow_defs*/, false /*!cxl_on_rightbrace*/, p_psm); diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index f0bf9556..fb66701a 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -215,8 +215,7 @@ namespace xo { if (ifstate_ == ifexprstatetype::if_0) { this->ifstate_ = ifexprstatetype::if_1; - DExpectExprSsm::start(p_psm->parser_alloc(), - p_psm); + DExpectExprSsm::start(p_psm); return; } @@ -236,7 +235,7 @@ namespace xo { if (ifstate_ == ifexprstatetype::if_2) { this->ifstate_ = ifexprstatetype::if_3; - DExpectExprSsm::start(p_psm->parser_alloc(), p_psm); + DExpectExprSsm::start(p_psm); return; } @@ -279,7 +278,7 @@ namespace xo { if (ifstate_ == ifexprstatetype::if_4) { this->ifstate_ = ifexprstatetype::if_5; - DExpectExprSsm::start(p_psm->parser_alloc(), p_psm); + DExpectExprSsm::start(p_psm); return; } diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 4bcbb844..3e33c627 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -7,6 +7,8 @@ #include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" #include "DExpectFormalArglistSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" +#include "DExpectTypeSsm.hpp" +#include "DExpectExprSsm.hpp" #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" #include @@ -89,11 +91,11 @@ namespace xo { DLambdaSsm::get_expect_str() const noexcept { /* - * lambda (x : f64) : f64 { ... } ; - * ^ ^ ^ ^ ^ ^ - * | | | | | lm_5 - * | | | | lm_4:expect_expression - * | | | lm_3 + * lambda (x : f64) -> f64 { ... } ; + * ^ ^ ^ ^ ^ ^ + * | | | | | lm_5 + * | | | | lm_4:expect_expression + * | | | lm_3 * | | lm_2 * | lm_1: * expect_expression @@ -108,7 +110,7 @@ namespace xo { case lambdastatetype::lm_1: return "lambda-params"; case lambdastatetype::lm_2: - return "colon|lambda-body"; + return "yields|lambda-body"; case lambdastatetype::lm_3: return "type"; case lambdastatetype::lm_4: @@ -129,6 +131,10 @@ namespace xo { this->on_lambda_token(tk, p_psm); return; + case tokentype::tk_yields: + this->on_yields_token(tk, p_psm); + return; + // all the not-yet-handled cases case tokentype::tk_def: case tokentype::tk_if: @@ -155,7 +161,6 @@ namespace xo { case tokentype::tk_comma: case tokentype::tk_doublecolon: case tokentype::tk_assign: - case tokentype::tk_yields: case tokentype::tk_plus: case tokentype::tk_minus: case tokentype::tk_star: @@ -194,25 +199,44 @@ namespace xo { this->get_expect_str()); } - -#ifdef NOT_YET void - lambda_xs::on_formal_arglist(const std::vector> & argl, - parserstatemachine * p_psm) + DLambdaSsm::on_yields_token(const Token & tk, + ParserStateMachine * p_psm) { - if (lmxs_type_ == lambdastatetype::lm_1) { - this->lmxs_type_ = lambdastatetype::lm_2; - this->parent_env_ = p_psm->top_envframe().promote(); - this->local_env_ = LocalSymtab::make(argl, parent_env_); + if (lmstate_ == lambdastatetype::lm_2) { + this->lmstate_ = lambdastatetype::lm_3; - p_psm->push_envframe(local_env_); + DExpectTypeSsm::start(p_psm); - //expect_expr_xs::start(p_psm); - } else { - exprstate::on_formal_arglist(argl, p_psm); + /* control reenters via .on_parsed_typedescr() */ + return; } + + p_psm->illegal_input_on_token("DLambdaSsm::on_yields_token", + tk, + this->get_expect_str()); } + + void + DLambdaSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + if (lmstate_ == lambdastatetype::lm_3) { + this->lmstate_ = lambdastatetype::lm_4; + this->explicit_return_td_ = td; + this->lambda_td_ = DLambdaExpr::assemble_lambda_td(local_symtab_, td); + + DExpectExprSsm::start(p_psm); + return; + } + + p_psm->illegal_input_on_typedescr("DLambdaSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + +#ifdef NOT_YET void lambda_xs::on_expr_with_semicolon(bp expr, parserstatemachine * p_psm) @@ -221,21 +245,6 @@ namespace xo { this->on_semicolon_token(token_type::semicolon(), p_psm); } - void - lambda_xs::on_colon_token(const token_type & tk, - parserstatemachine * p_psm) - { - constexpr const char * c_self_name = "lambda_xs::on_colon_token"; - - if (lmxs_type_ == lambdastatetype::lm_2) { - this->lmxs_type_ = lambdastatetype::lm_3; - expect_type_xs::start(p_psm); - /* control reenters via .on_typedescr() */ - } else { - this->illegal_input_on_token(c_self_name, tk, this->get_expect_str(), p_psm); - } - } - void lambda_xs::on_leftbrace_token(const token_type & tk, parserstatemachine * p_psm) @@ -255,84 +264,6 @@ namespace xo { } #endif - void - DLambdaSsm::on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_typedescr("DLambdaSsm::on_parsed_typedescr", - td, - this->get_expect_str()); - } - -#ifdef NOT_YET - void - lambda_xs::on_typedescr(TypeDescr td, - parserstatemachine * p_psm) - { - constexpr const char * c_self_name = "lambda_xs::on_typedescr"; - scope log(XO_DEBUG(p_psm->debug_flag())); - - assert(td); - - if (lmxs_type_ == lambdastatetype::lm_3) { - this->lmxs_type_ = lambdastatetype::lm_4; - this->explicit_return_td_ = td; - - this->lambda_td_ = Lambda::assemble_lambda_td(local_env_->argv(), - explicit_return_td_); - - /* 1. at this point we know function signature (@ref lambda_td_) - * 2. if this lambda appears on the rhs of a define, - * propagate function signature to the define. - * 3. this makes recursive function definitions like this work - * without relying on type inference: - * def fact = lambda (n : i64) : i64 { - * if (n == 0) then - * 1 - * else - * n * fact(n - 1) - * } - * 4. while parsing the body of the lambda, we want environment - * to already associate the lambda's signature with variable 'fact', - * so that when parser encounters 'fact(n - 1)' the expression has - * known valuetype. - */ - - if ((p_psm->exprstate_stack_size() >= 3) - && (p_psm->lookup_exprstate(1).exs_type() == exprstatetype::expect_rhs_expression) - && (p_psm->lookup_exprstate(2).exs_type() == exprstatetype::defexpr) - && (p_psm->env_stack_size() >= 2) - ) - { - const define_xs * def_xs = dynamic_cast(&(p_psm->lookup_exprstate(2))); - - assert(def_xs); - - bp def_var = def_xs->lhs_variable(); - - if (def_var->valuetype() == nullptr) { - log && log("assign discovered lambda type T to enclosing define", - xtag("lhs", def_var.get()), - xtag("T", print::unq(this->lambda_td_->canonical_name()))); - - def_var->assign_valuetype(lambda_td_); - } else { - /* don't need to unify here. if def already hasa a type, - * that's because it was explicitly specified. - * will discover any conflict after reporting parsed lambda - * to define_xs - */ - } - } - - expect_expr_xs::start(p_psm); - /* control reenters via .on_expr() or .on_expr_with_semicolon() */ - } else { - this->illegal_input_on_type(c_self_name, td, this->get_expect_str(), p_psm); - } - } -#endif - void DLambdaSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) @@ -376,8 +307,9 @@ namespace xo { for (DArray::size_type i = 0, n = arglist->size(); i < n; ++i) { obj param = arglist->at(i); + // TODO: // sad! runtime poly conversion from obj - // We on need this because of (suboptimally) using DArray to store arglist + // We need this because of (suboptimally) using DArray to store arglist obj param_expr = FacetRegistry::instance().variant(param); @@ -503,12 +435,6 @@ namespace xo { // TODO: on_i64_token, on_bool token - void - lambda_xs::print(std::ostream & os) const { - os << ""; - } #endif bool diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 57e21ec8..5a6317a3 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -398,7 +398,7 @@ namespace xo { // tk is the operator this instance was waiting for this->op_type_ = tk2op(tk.tk_type()); - DExpectExprSsm::start(p_psm->parser_alloc(), p_psm); + DExpectExprSsm::start(p_psm); return; } else if (rhs_) { optype op_type2 = tk2op(tk.tk_type()); @@ -441,15 +441,13 @@ namespace xo { lhs_, op_type_, p_psm); - DExpectExprSsm::start(p_psm->parser_alloc(), - p_psm); + DExpectExprSsm::start(p_psm); /* (b * ..) */ DProgressSsm::start(p_psm->parser_alloc(), rhs_, op_type2, p_psm); - DExpectExprSsm::start(p_psm->parser_alloc(), - p_psm); + DExpectExprSsm::start(p_psm); return; } } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index cc1e51fa..0d7dbba4 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -339,7 +339,43 @@ namespace xo { REQUIRE(result.is_incomplete()); } + { + auto & result = parser.on_token(Token::yields_token()); + + log && log("after yields token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("i64")); + + log && log("after symbol(i64) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + #ifdef NOT_YET + { + auto & result = parser.on_token(Token::leftbrace_token()); + + log && log("after leftbrace token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + { auto & result = parser.on_token(Token::string_token("fooey")); diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index 66427c3e..fc5dfc9a 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -100,7 +100,7 @@ namespace xo { /** token representing right bracket @c "]" **/ static Token rightbracket() { return Token(tokentype::tk_rightbracket); } /** token representing left brace @c "{" **/ - static Token leftbrace() { return Token(tokentype::tk_leftbrace); } + static Token leftbrace_token() { return Token(tokentype::tk_leftbrace); } /** token representing right brace @c "}" **/ static Token rightbrace() { return Token(tokentype::tk_rightbrace); } /** token representing period @c "." **/ @@ -117,8 +117,8 @@ namespace xo { static Token singleassign_token() { return Token(tokentype::tk_singleassign); } /** token representing unrestricted assignment @c ":=" **/ static Token assign_token() { return Token(tokentype::tk_assign); } - /** token representing indirection @c "->" **/ - static Token yields() { return Token(tokentype::tk_yields); } + /** token representing indirection @c "->" / function return type **/ + static Token yields_token() { return Token(tokentype::tk_yields); } /** token for @c "+" **/ static Token plus_token() { return Token(tokentype::tk_plus); } From d44bb78900394a897a5bfc62060933ef824a2199 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 13:23:28 -0500 Subject: [PATCH 120/258] switch build to c++23 --- xo-cmake/cmake/xo_macros/xo_cxx.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xo-cmake/cmake/xo_macros/xo_cxx.cmake b/xo-cmake/cmake/xo_macros/xo_cxx.cmake index dde3c081..fbce80bd 100644 --- a/xo-cmake/cmake/xo_macros/xo_cxx.cmake +++ b/xo-cmake/cmake/xo_macros/xo_cxx.cmake @@ -670,7 +670,7 @@ macro(xo_toplevel_compile_options) ) if(NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD 23) endif() if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED) set(CMAKE_CXX_STANDARD_REQUIRED True) From b5b6a51ce4d7acf2ed6e7c04ca131c364b4a06ad Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 13:23:44 -0500 Subject: [PATCH 121/258] xo-reader2: refactor: crtp to share code across SSM impls --- xo-reader2/CMakeLists.txt | 5 + xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 12 ++- .../xo/reader2/DSyntaxStateMachine.hpp | 94 +++++++++++++++++-- xo-reader2/src/reader2/DLambdaSsm.cpp | 45 +++------ 4 files changed, 116 insertions(+), 40 deletions(-) diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 4fcbe399..ff842708 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.10) +# relying on +# this auto&& +# +set(CMAKE_CXX_STANDARD 23) + project(xo_reader2 VERSION 1.0) enable_language(CXX) diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index 1be39031..7f29e946 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -5,7 +5,7 @@ #pragma once -#include "SyntaxStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" #include #include //#include @@ -55,9 +55,9 @@ namespace xo { /** @class DLambdaSsm * @brief parsing state-machine for a lambda-expression **/ - class DLambdaSsm { + class DLambdaSsm : public DSyntaxStateMachine { public: - //using DSymbolTable = xo::scm::DSymbolTable; + using Super = DSyntaxStateMachine; using DLocalSymtab = xo::scm::DLocalSymtab; using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; @@ -80,6 +80,8 @@ namespace xo { /** @defgroup scm-lambdassm-methods **/ ///@{ + const char * ssm_classname() const noexcept { return "DLambdaSsm"; } + static void start(ParserStateMachine * p_psm); /** update ssm on lambda keyword token @p tk, @@ -110,11 +112,13 @@ namespace xo { void on_token(const Token & tk, ParserStateMachine * p_psm); +#ifdef OBSOLETE /** update this ssm when nested parser * emits @p td. **/ void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); +#endif /** update this ssm when nested parser * emits @p td. @@ -122,12 +126,14 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); +#ifdef OBSOLETE /** update this ssm to consume parsed formal (name,value) * from nested (and now expired) ssm **/ void on_parsed_formal(const DUniqueString * sym, TypeDescr td, ParserStateMachine * p_psm); +#endif /** consume formal params @p arglist from completed nested ssm, * with overall parser state in @p p_psm. diff --git a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp index 4aa35f4d..1f5b2642 100644 --- a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp @@ -5,16 +5,16 @@ #pragma once +#include "SyntaxStateMachine.hpp" #include namespace xo { namespace scm { /** @class DSyntaxStateMachine - * @brief static interface for implementing ASyntaxStateMachine + * @brief static helper interface for ASyntaxStateMachine implementations * - * Using CRTP to collect methods common to ASyntaxStateMachine - * implementations. + * Using CRTP. * * Deliberately unusable through base class pointer. * For runtime polymorphism use something like: @@ -27,11 +27,91 @@ namespace xo { **/ template class DSyntaxStateMachine { - friend Derived; + public: + using TypeDescr = xo::reflect::TypeDescr; - /** arglist is DArray of obj **/ - void on_parsed_formal_arglist(this auto&& self, DArray * arglist, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_formal_arglist( + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_token(this auto&& self, + const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token(self.ssm_classname(), + tk, + self.get_expect_str()); + } + + void on_parsed_symbol(this auto&& self, + std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol(self.ssm_classname(), + sym, + self.get_expect_str()); + } + + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_parsed_typedescr(this auto&& self, + TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr(self.ssm_classname(), + td, + self.get_expect_str()); + } + + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_parsed_formal(this auto&& self, + const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal(self.ssm_classname(), + param_name, + param_type, + self.get_expect_str()); + } + + /** Default implementation for required SyntaxStateMachine facet method + * + * arglist is DArray of obj + **/ + void on_parsed_formal_arglist(this auto&& self, + DArray * arglist, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_formal_arglist(self.ssm_classname(), + arglist, + self.get_expect_str()); + } + + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_parsed_expression(this auto&& self, + obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression(self.ssm_classname(), + expr, + self.get_expect_str()); + + } + + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_parsed_expression_with_semicolon(this auto&& self, + obj expr, + ParserStateMachine * p_psm) + { + // We don't need a separate entry point, + // since the semicolon isn't relevant to problem with syntax + // + + p_psm->illegal_parsed_expression(self.ssm_classname(), + expr, + self.get_expect_str()); } }; diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 3e33c627..4866cd66 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -177,9 +177,12 @@ namespace xo { break; } + Super::on_token(tk, p_psm); +#ifdef OBSOLETE p_psm->illegal_input_on_token("DLambdaSsm::on_token", tk, this->get_expect_str()); +#endif } void @@ -194,9 +197,12 @@ namespace xo { return; } + Super::on_token(tk, p_psm); +#ifdef OBSOLETE p_psm->illegal_input_on_token("DLambdaSsm::on_lambda_token", tk, this->get_expect_str()); +#endif } void @@ -212,9 +218,12 @@ namespace xo { return; } + Super::on_token(tk, p_psm); +#ifdef OBSOLETE p_psm->illegal_input_on_token("DLambdaSsm::on_yields_token", tk, this->get_expect_str()); +#endif } @@ -231,9 +240,7 @@ namespace xo { return; } - p_psm->illegal_input_on_typedescr("DLambdaSsm::on_parsed_typedescr", - td, - this->get_expect_str()); + Super::on_parsed_typedescr(td, p_psm); } #ifdef NOT_YET @@ -264,26 +271,6 @@ namespace xo { } #endif - void - DLambdaSsm::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("DLambdaSsm::on_parsed_sybol", - sym, - this->get_expect_str()); - } - - void - DLambdaSsm::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal("DLambdaSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - void DLambdaSsm::on_parsed_formal_arglist(DArray * arglist, ParserStateMachine * p_psm) @@ -337,28 +324,26 @@ namespace xo { return; } + Super::on_parsed_formal_arglist(arglist, p_psm); +#ifdef OBSOLETE p_psm->illegal_parsed_formal_arglist("DLambdaSsm::on_parsed_formal_arglist", arglist, this->get_expect_str()); +#endif } void DLambdaSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_expression("DLambdaSsm::on_parsed_expression", - expr, - this->get_expect_str()); + Super::on_parsed_expression(expr, p_psm); } void DLambdaSsm::on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_expression - ("DLambdaSsm::on_parsed_expression_with_semicolon", - expr, - this->get_expect_str()); + Super::on_parsed_expression_with_semicolon(expr, p_psm); } #ifdef NOT_YET From 8b55483991bad87d9cad5ad93a171455738dcf49 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 13:38:43 -0500 Subject: [PATCH 122/258] xo-reader2: streamline DExpectSymbolSsm w/ DSyntaxStateMachine --- .../include/xo/reader2/DExpectSymbolSsm.hpp | 110 +--------- .../xo/reader2/DSyntaxStateMachine.hpp | 1 + xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 189 +----------------- 3 files changed, 17 insertions(+), 283 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index accfa936..f06cf94b 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -5,8 +5,7 @@ #pragma once -#include "ParserStateMachine.hpp" -//#include "SyntaxStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" #include #include @@ -19,8 +18,9 @@ namespace xo { * For example: * - lhs in a define-expression **/ - class DExpectSymbolSsm { + class DExpectSymbolSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using DArena = xo::mm::DArena; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; @@ -46,6 +46,8 @@ namespace xo { static void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); + const char * ssm_classname() const noexcept { return "DExpectSymbolSsm"; } + /** @defgroup scm-expectsymbol-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -57,114 +59,12 @@ namespace xo { **/ std::string_view get_expect_str() const noexcept; - /** update state for this syntax after parsing a symbol @p sym; - * overall parser state in @p p_psm. - * - * NOTE: - * might not be obvious that this is unreachable. - * DExpectSymbolSsm converts a symbol token, - * and delivers it to parent ssm using this entry point. - * This method would only be called if consecutive - * DExpectSymbolSsm instances on parser stack; - * which scenario never occurs in Schematika syntax - **/ - void on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm); - - /** update state for this syntax after parsing a type-description @p td - * in nested state machine. - * (provided to satisfy ASyntaxStateMachine api. not reachable) - **/ - void on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm); - - /** update state to consume param (name, value) emitted - * by nested ssm - **/ - void on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm); - - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); - - /** update state for this syntax after parsing an expression @p expr - * in nested state machine. - * (provided to satisfy ASyntaxStateMachine api. not reachable) - **/ - void on_parsed_expression(obj expr, - ParserStateMachine * p_psm); - - /** update state for this syntax after parsing an expression @p expr - * followed by semicolon in nested state machine. - * (provided to satisfy ASyntaxStateMachine api. not reachable) - **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); - /** operate state machine for this syntax on incoming token @p tk * with overall parser state in @p p_psm **/ void on_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax on incoming token @p tk, - * overall parser state in @p p_psm. - **/ - void on_def_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming token @p tk, - * overall parser state in @p p_psm - **/ - void on_if_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming colon token @p tk, - * overall parser state in @p p_psm - **/ - void on_colon_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming singleassign token @p tk, - * overall parser state in @p p_psm - **/ - void on_singleassign_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming string token @p tk, - * overall parser state in @p p_psm - **/ - void on_string_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming f64 token @p tk, - * overall parser state in @p p_psm - **/ - void on_f64_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming i64 token @p tk, - * overall parser state in @p p_psm - **/ - void on_i64_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming bool token @p tk, - * overall parser state in @p p_psm - **/ - void on_bool_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming semicolon token @p tk, - * overall parser state in @p p_psm - **/ - void on_semicolon_token(const Token & tk, - ParserStateMachine * p_psm); - ///@} /** @defgroup scm-expectsymbol-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp index 1f5b2642..ee4fca98 100644 --- a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp @@ -6,6 +6,7 @@ #pragma once #include "SyntaxStateMachine.hpp" +#include "ParserStateMachine.hpp" #include namespace xo { diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 60985cae..b252055b 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -55,62 +55,6 @@ namespace xo { return "symbol"; } - void - DExpectSymbolSsm::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("DExpectSymbolSsm::on_parsed_symbol", - sym, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_typedescr("DExpectSymbolSsm::on_parsed_typedescr", - td, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal("DExpectSymbolSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DExpectSymbolSsm::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_parsed_expression(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DExpectSymbolSsm::on_parsed_expression", - expr, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DExpectSymbolSsm::on_parsed_expression_with_semicolon", - expr, - this->get_expect_str()); - } - void DExpectSymbolSsm::on_token(const Token & tk, ParserStateMachine * p_psm) @@ -120,46 +64,19 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_symbol: this->on_symbol_token(tk, p_psm); - break; - - case tokentype::tk_def: - this->on_def_token(tk, p_psm); - break; - - case tokentype::tk_if: - this->on_if_token(tk, p_psm); - break; - - case tokentype::tk_colon: - this->on_colon_token(tk, p_psm); - break; - - case tokentype::tk_singleassign: - this->on_singleassign_token(tk, p_psm); - break; - - case tokentype::tk_string: - this->on_string_token(tk, p_psm); - break; - - case tokentype::tk_f64: - this->on_f64_token(tk, p_psm); - break; - - case tokentype::tk_i64: - this->on_i64_token(tk, p_psm); - break; - - case tokentype::tk_bool: - this->on_bool_token(tk, p_psm); - break; - - case tokentype::tk_semicolon: - this->on_semicolon_token(tk, p_psm); - break; + return; // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_def: + case tokentype::tk_if: + case tokentype::tk_singleassign: + case tokentype::tk_colon: + case tokentype::tk_semicolon: case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: @@ -189,12 +106,10 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: case tokentype::N: - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_token", - tk, - this->get_expect_str()); break; } + Super::on_token(tk, p_psm); } void @@ -214,91 +129,9 @@ namespace xo { * the o.g. symbol-requester */ p_psm->pop_ssm(); - p_psm->on_parsed_symbol(std::string_view(tk.text())); } - void - DExpectSymbolSsm::on_def_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_def_token", - tk, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_if_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_if_token", - tk, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_colon_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_colon_token", - tk, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_singleassign_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_singleassign_token", - tk, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_string_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_string_token", - tk, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_f64_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_f64_token", - tk, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_i64_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_i64_token", - tk, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_bool_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_bool_token", - tk, - this->get_expect_str()); - } - - void - DExpectSymbolSsm::on_semicolon_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectSymbolSsm::on_semicolon_token", - tk, - this->get_expect_str()); - } - bool DExpectSymbolSsm::pretty(const ppindentinfo & ppii) const { From 470d40c24d5770ba157486274a34d8f5237829c7 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 13:49:57 -0500 Subject: [PATCH 123/258] xo-reader2: streamline DIfElseSsm w/ DSyntaxStateMachine --- xo-reader2/include/xo/reader2/DIfElseSsm.hpp | 18 ++- xo-reader2/src/reader2/DIfElseSsm.cpp | 126 +------------------ 2 files changed, 14 insertions(+), 130 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp index 62f7d137..2e3533cd 100644 --- a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp @@ -5,14 +5,12 @@ #pragma once +#include "DSyntaxStateMachine.hpp" #include -#include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" #include #include #include -//#include "exprstate.hpp" -//#include "xo/indentlog/print/ppdetail_atomic.hpp" namespace xo { namespace scm { @@ -54,8 +52,9 @@ namespace xo { /** @class DIfElseSsm * @brief syntax state machine for parsing a conditional expression **/ - class DIfElseSsm { + class DIfElseSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; using TypeDescr = xo::reflect::TypeDescr; @@ -89,6 +88,9 @@ namespace xo { static void start(DArena & parser_mm, obj expr_mm, ParserStateMachine * p_psm); + + const char * ssm_classname() const noexcept { return "DIfElseSsm"; } + ///@} /** @defgroup scm-ifelsessm-expression-methods general methods **/ ///@{ @@ -140,6 +142,7 @@ namespace xo { void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); +#ifdef OBSOLETE /** update state for this syntax after parsing a symbol @p sym, * with overall parser state in @p p_psm **/ @@ -158,12 +161,7 @@ namespace xo { void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); - - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); +#endif /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm. diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index fb66701a..8551e1fe 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -189,21 +189,9 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DIfElseSsm::on_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } -#ifdef NOT_YET - // ----- if_else_xs ----- - - if_else_xs::if_else_xs(rp if_expr) - : exprstate(exprstatetype::ifexpr), - ifxs_type_{ifexprstatetype::if_0}, - if_expr_{std::move(if_expr)} - {} -#endif - void DIfElseSsm::on_if_token(const Token & tk, ParserStateMachine * p_psm) @@ -219,9 +207,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DIfElseSsm::on_if_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -239,34 +225,9 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DIfElseSsm::on_then_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } -#ifdef NOT_YET - void - if_else_xs::on_else_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - log && log("ifxs_type", ifxs_type_); - - if (this->ifxs_type_ == ifexprstatetype::if_4) { - this->ifxs_type_ = ifexprstatetype::if_5; - - expect_expr_xs::start(p_psm); - return; - } - - constexpr const char * c_self_name = "if_else_xs::on_else_token"; - const char * exp = this->get_expect_str(); - - this->illegal_input_on_token(c_self_name, tk, exp, p_psm); - } -#endif - void DIfElseSsm::on_else_token(const Token & tk, ParserStateMachine * p_psm) @@ -282,9 +243,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DIfElseSsm::on_else_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } #ifdef NOT_YET @@ -325,37 +284,6 @@ namespace xo { p_psm->on_rightbrace_token(tk); } - void - if_else_xs::on_semicolon_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - log && log("ifxs_type", ifxs_type_); - - const char * c_self_name = "if_else_xs::on_semicolon_token"; - - switch (this->ifxs_type_) { - case ifexprstatetype::invalid: - case ifexprstatetype::if_0: - case ifexprstatetype::n_ifexprstatetype: - // unreachable - assert(false); - break; - - case ifexprstatetype::if_1: - case ifexprstatetype::if_2: - case ifexprstatetype::if_3: - case ifexprstatetype::if_5: - this->illegal_input_on_token(c_self_name, tk, get_expect_str(), p_psm); - break; - case ifexprstatetype::if_4: - case ifexprstatetype::if_6: { - this->finish_and_continue(p_psm); - break; - } - } - } #endif void @@ -385,18 +313,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DIfElseSsm::on_semicolon_token", - tk, this->get_expect_str()); - - } - - void - DIfElseSsm::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DIfElseSsm::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); + Super::on_token(tk, p_psm); } #ifdef NOT_YET @@ -485,9 +402,7 @@ namespace xo { break; } - p_psm->illegal_parsed_expression("DIfElseSsm::on_parsed_expression", - expr, - this->get_expect_str()); + Super::on_parsed_expression(expr, p_psm); } void @@ -500,35 +415,6 @@ namespace xo { this->on_semicolon_token(Token::semicolon_token(), p_psm); } - void - DIfElseSsm::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("DIfElseSsm::on_parsed_symbol", - sym, - this->get_expect_str()); - } - - void - DIfElseSsm::on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_typedescr("DIfElseSsm::on_parsed_typedescr", - td, - this->get_expect_str()); - } - - void - DIfElseSsm::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal("DIfElseSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - bool DIfElseSsm::pretty(const ppindentinfo & ppii) const { From 79320c6a000727e6a933ddd83fa8910c4fb5d15f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 14:11:46 -0500 Subject: [PATCH 124/258] xo-reader2: simplify DDefineSsm w/ DSyntaxStateMachine --- xo-reader2/include/xo/reader2/DDefineSsm.hpp | 40 ++----- xo-reader2/src/reader2/DDefineSsm.cpp | 120 +++---------------- 2 files changed, 22 insertions(+), 138 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index ebd454c0..939d5479 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -5,12 +5,13 @@ #pragma once -#include "ParserStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" //#include "SyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" #include #include #include +#include namespace xo { namespace scm { @@ -69,8 +70,9 @@ namespace xo { /** @class DDefineSsm * @brief state machine for parsing a define expression **/ - class DDefineSsm { + class DDefineSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using TypeDescr = xo::reflect::TypeDescr; using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; @@ -102,6 +104,8 @@ namespace xo { /** @defgroup scm-definessm-access-methods **/ ///@{ + const char * ssm_classname() const noexcept { return "DDefineSsm"; } + /** identify this nested state machine **/ defexprstatetype defstate() const noexcept { return defstate_; } @@ -135,12 +139,6 @@ namespace xo { void on_def_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax on incoming token @p tk, - * overall parser state in @p p_psm - **/ - void on_if_token(const Token & tk, - ParserStateMachine * p_psm); - /** update state for this syntax on incoming colon token @p tk, * overall parser state in @p p_psm **/ @@ -153,30 +151,6 @@ namespace xo { void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax on incoming string tokne @p tk, - * overall parser state in @p p_psm - **/ - void on_string_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming f64 token @p tk, - * overall parser state in @p p_psm - **/ - void on_f64_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming i64 token @p tk, - * overall parser state in @p p_psm - **/ - void on_i64_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming bool token @p tk, - * overall parser state in @p p_psm - **/ - void on_bool_token(const Token & tk, - ParserStateMachine * p_psm); - /** update state for this syntax on incoming semicolon token @p tk, * overall parser state in @p p_psm **/ @@ -195,6 +169,7 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); +#ifdef OBSOLETE /** update state for this ssm to consume param (name,value) * emitted by nested @p_psm **/ @@ -207,6 +182,7 @@ namespace xo { **/ void on_parsed_formal_arglist(DArray * arglist, ParserStateMachine * p_psm); +#endif /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 4e2bcf97..4ad36f4f 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -506,10 +506,6 @@ namespace xo { this->on_def_token(tk, p_psm); return; - case tokentype::tk_if: - this->on_if_token(tk, p_psm); - return; - case tokentype::tk_colon: this->on_colon_token(tk, p_psm); return; @@ -518,28 +514,17 @@ namespace xo { this->on_singleassign_token(tk, p_psm); return; - case tokentype::tk_string: - this->on_string_token(tk, p_psm); - return; - - case tokentype::tk_f64: - this->on_f64_token(tk, p_psm); - return; - - case tokentype::tk_i64: - this->on_i64_token(tk, p_psm); - return; - - case tokentype::tk_bool: - this->on_bool_token(tk, p_psm); - return; - case tokentype::tk_semicolon: this->on_semicolon_token(tk, p_psm); return; // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_if: case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: @@ -569,11 +554,11 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: case tokentype::N: - p_psm->illegal_input_on_token("DDefineSsm::on_token", - tk, - this->get_expect_str()); + break; return; } + + Super::on_token(tk, p_psm); } void @@ -585,9 +570,7 @@ namespace xo { // symbol token arriving here means encountered symbol while // in some other, which can't happen for valid Schematika input - p_psm->illegal_input_on_token("DDefineSssm::on_symbol_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -601,18 +584,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DDefineSsm::on_define_token", - tk, - this->get_expect_str()); - } - - void - DDefineSsm::on_if_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DDefineSsm::on_if_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -627,9 +599,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DDefineSsm::on_colon_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -647,45 +617,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DDefineSsm::on_singleassign_token", - tk, - this->get_expect_str()); - } - - void - DDefineSsm::on_string_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DDefineSsm::on_string_token", - tk, - this->get_expect_str()); - } - - void - DDefineSsm::on_f64_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DDefineSsm::on_f64_token", - tk, - this->get_expect_str()); - } - - void - DDefineSsm::on_i64_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DDefineSsm::on_i64_token", - tk, - this->get_expect_str()); - } - - void - DDefineSsm::on_bool_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DDefineSsm::on_bool_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -698,29 +630,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DDefineSsm::on_semicolon_token", - tk, - this->get_expect_str()); - } - - void - DDefineSsm::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal("DDefineSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - - void - DDefineSsm::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DDefineSsm::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -735,9 +645,7 @@ namespace xo { return; } - p_psm->illegal_parsed_expression("DDefineSsm::on_parsed_expression", - expr, - this->get_expect_str()); + Super::on_parsed_expression(expr, p_psm); } void From f0c73499b26512e04c7aa4ef94ab3d95abbe4697 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 14:21:27 -0500 Subject: [PATCH 125/258] xo-reader2: simplify DExpectExprSsm w/ DSyntaxStateMachine --- .../include/xo/reader2/DExpectExprSsm.hpp | 57 +--- xo-reader2/src/reader2/DExpectExprSsm.cpp | 249 ++++++------------ 2 files changed, 87 insertions(+), 219 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index accdbff3..424afb99 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -5,17 +5,18 @@ #pragma once -#include "ParserStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" +//#include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" -//#include #include #include namespace xo { namespace scm { - class DExpectExprSsm { + class DExpectExprSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using TypeDescr = xo::reflect::TypeDescr; using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; @@ -37,6 +38,7 @@ namespace xo { /** @defgroup scm-expectexpr-access-methods access methods **/ ///@{ + const char * ssm_classname() const noexcept { return "DExpectExprSsm"; } bool allow_defs() const noexcept { return allow_defs_; } bool cxl_on_rightbrace() const noexcept { return cxl_on_rightbrace_; } @@ -98,55 +100,6 @@ namespace xo { void on_def_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax on incoming token @p tk, - * overall parser state in @p p_psm - **/ - void on_if_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming colon token @p tk, - * overall parser state in @p p_psm - **/ - void on_colon_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming singleassign token @p tk, - * overall parser state in @p p_psm - **/ - void on_singleassign_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming semicolon token @p tk, - * overall parser state in @p p_psm - **/ - void on_semicolon_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax after parsing a symbol @p sym; - * overall parser state in @p p_psm - **/ - void on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm); - - /** update state for this syntax after parsing a type-description @p td, - * overall parser state in @p p_psm - **/ - void on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm); - - /** update state to consume parsed formal (name, value) from nested ssm, - * with overall parser state in @p p_psm - **/ - void on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm); - - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); - /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 3f99daca..899731a3 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -116,46 +116,34 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_symbol: this->on_symbol_token(tk, p_psm); - break; + return; case tokentype::tk_def: this->on_def_token(tk, p_psm); - break; - - case tokentype::tk_if: - this->on_if_token(tk, p_psm); - break; - - case tokentype::tk_colon: - this->on_colon_token(tk, p_psm); - break; - - case tokentype::tk_singleassign: - this->on_singleassign_token(tk, p_psm); - break; + return; case tokentype::tk_string: this->on_string_token(tk, p_psm); - break; + return; case tokentype::tk_f64: this->on_f64_token(tk, p_psm); - break; + return; case tokentype::tk_i64: this->on_i64_token(tk, p_psm); - break; + return; case tokentype::tk_bool: this->on_bool_token(tk, p_psm); - break; - - case tokentype::tk_semicolon: - this->on_semicolon_token(tk, p_psm); - break; + return; // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_if: + case tokentype::tk_singleassign: + case tokentype::tk_colon: + case tokentype::tk_semicolon: case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: @@ -185,11 +173,10 @@ namespace xo { case tokentype::tk_in: case tokentype::tk_end: case tokentype::N: - p_psm->illegal_input_on_token("DExpectExprSsm::on_token", - tk, - this->get_expect_str()); break; } + + Super::on_token(tk, p_psm); } void @@ -201,40 +188,80 @@ namespace xo { this->get_expect_str()); } +#ifdef NOT_YET + void + expect_expr_xs::on_symbol_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("tk", tk)); + + constexpr const char * c_self_name = "expect_expr_xs::on_symbol_token"; + + /* various possibilities when looking for rhs expression: + * + * x := y // (1) + * x := f(a) // (2) + * x := f(a,b) // (3) + * + * need lookahead token following symbol to distinguish + * between (1) (symbol completes rhs expression) + * and {(2), (3)} (symbol is function call) + */ + + bp var = p_psm->lookup_var(tk.text()); + + if (!var) { + this->unknown_variable_error(c_self_name, tk, p_psm); + return; + } + + /* e.g. + * def pi = 3.14159265; + * def mypi = pi; + * ^ + * def pi2 = pi * 2; + * ^ + * def y = foo(pi2); + * ^ + */ + progress_xs::start(var.promote(), p_psm); + + #ifdef NOT_YET + p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, + Variable::make(name, type))); +#endif + +#ifdef LATER + p_psm->pop_exprstate(); + p_psm->top_exprstate().on_symbol(tk.text(), + p_stack, p_emit_expr); +#endif + return; + } +#endif + +#ifdef NOT_YET + void + expect_expr_xs::on_def_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + if (allow_defs_) { + define_xs::start(p_psm); + } else { + exprstate::on_def_token(tk, p_psm); + } + } +#endif + void DExpectExprSsm::on_def_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DExpectExprSsm", - tk, - this->get_expect_str()); - } - - void - DExpectExprSsm::on_if_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectExprSsm", - tk, - this->get_expect_str()); - } - - void - DExpectExprSsm::on_colon_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectExprSsm", - tk, - this->get_expect_str()); - } - - void - DExpectExprSsm::on_singleassign_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectExprSsm", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -326,53 +353,6 @@ namespace xo { p_psm); } - void - DExpectExprSsm::on_semicolon_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectExprSsm::on_semicolon_token", - tk, - this->get_expect_str()); - } - - void - DExpectExprSsm::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("DExpectExprSsm::on_parsed_symbol", - sym, - this->get_expect_str()); - } - - void - DExpectExprSsm::on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_typedescr("DExpectExprSsm::on_parsed_typedescr", - td, - this->get_expect_str()); - } - - void - DExpectExprSsm::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal("DExpectExprSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - - void - DExpectExprSsm::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DExpectExprSsm::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); - } - void DExpectExprSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) @@ -404,19 +384,6 @@ namespace xo { } #ifdef NOT_YET - void - expect_expr_xs::on_def_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - if (allow_defs_) { - define_xs::start(p_psm); - } else { - exprstate::on_def_token(tk, p_psm); - } - } - void expect_expr_xs::on_lambda_token(const token_type & /*tk*/, parserstatemachine * p_psm) @@ -475,58 +442,6 @@ namespace xo { } } - void - expect_expr_xs::on_symbol_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - log && log(xtag("tk", tk)); - - constexpr const char * c_self_name = "expect_expr_xs::on_symbol_token"; - - /* various possibilities when looking for rhs expression: - * - * x := y // (1) - * x := f(a) // (2) - * x := f(a,b) // (3) - * - * need lookahead token following symbol to distinguish - * between (1) (symbol completes rhs expression) - * and {(2), (3)} (symbol is function call) - */ - - bp var = p_psm->lookup_var(tk.text()); - - if (!var) { - this->unknown_variable_error(c_self_name, tk, p_psm); - return; - } - - /* e.g. - * def pi = 3.14159265; - * def mypi = pi; - * ^ - * def pi2 = pi * 2; - * ^ - * def y = foo(pi2); - * ^ - */ - progress_xs::start(var.promote(), p_psm); - - #ifdef NOT_YET - p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, - Variable::make(name, type))); -#endif - -#ifdef LATER - p_psm->pop_exprstate(); - p_psm->top_exprstate().on_symbol(tk.text(), - p_stack, p_emit_expr); -#endif - return; - } - void expect_expr_xs::on_expr(bp expr, parserstatemachine * p_psm) From 06f93bf86f802cdaee751ce1fab34d90baa6fec8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 14:27:32 -0500 Subject: [PATCH 126/258] xo-reader2: simplify DExpectFormalArgSsm using DSyntaxStateMachine --- .../xo/reader2/DExpectFormalArgSsm.hpp | 47 ++------------- .../src/reader2/DExpectFormalArgSsm.cpp | 57 ++----------------- 2 files changed, 9 insertions(+), 95 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index 51eb6536..5308c701 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -5,7 +5,7 @@ #pragma once -#include "SyntaxStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" //#include //#include "exprstate.hpp" @@ -44,8 +44,9 @@ namespace xo { /** @class expect_formal_xs * @brief parser state-machine for a typed formal parameter **/ - class DExpectFormalArgSsm { + class DExpectFormalArgSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using TypeDescr = xo::reflect::TypeDescr; using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; @@ -70,6 +71,8 @@ namespace xo { /** @defgroup scm-expectformalargssm-methods general methods **/ ///@{ + const char * ssm_classname() const noexcept { return "DExpectFormalArgSsm"; } + /** update state on incoming colon token @p tk; * with overall parser state in @p p_psm **/ @@ -104,32 +107,6 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); - /** consume parsed formal (name,type) = (@p sym, @p td) from nested ssm - * with overall parser state in @p p_psm. - * (In practice not reachable) - **/ - void on_parsed_formal(const DUniqueString * sym, - TypeDescr td, - ParserStateMachine * p_psm); - - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); - - /** update state on parsed expression emitted by nested ssm - * with overall parser state in @p p_psm - **/ - void on_parsed_expression(obj expr, - ParserStateMachine * p_psm); - - /** update state on parsed expression, along with following semicolon, - * emitted by nested ssm with overall parser state in @p p_psm - **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); - ///@} /** @defgroup scm-expectformalargssm-printable-facet printable facet methods **/ ///@{ @@ -139,26 +116,12 @@ namespace xo { ///@} -#ifdef NOT_YET - - virtual void on_symbol(const std::string & symbol_name, - parserstatemachine * p_psm) override; - - // virtual void on_comma_token(...) override; - #ifdef PROBABLY_NOT virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, rp * p_emit_expr) override; #endif - virtual void on_typedescr(TypeDescr td, - parserstatemachine * p_psm) override; - - private: - static std::unique_ptr make(); -#endif - private: /** parsing state-machine state **/ formalstatetype fstate_ = formalstatetype::formal_0; diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index 4aaf7c4b..d865cd71 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -138,9 +138,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExpectFormalArgSsm::on_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -156,9 +154,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DExpectFormalArgSsm::on_colon_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -175,9 +171,7 @@ namespace xo { return; } - p_psm->illegal_input_on_symbol("DExpectFormalArgSsm::on_parsed_symbol", - sym, - this->get_expect_str()); + Super::on_parsed_symbol(sym, p_psm); } void @@ -193,50 +187,7 @@ namespace xo { return; } - p_psm->illegal_input_on_typedescr("DExpectFormalArgSsm::on_parsed_typedescr", - td, - this->get_expect_str()); - } - - void - DExpectFormalArgSsm::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - // NOTE: (param_name,param_type) *produced* by this SSM, - // but never *consumed* - - p_psm->illegal_parsed_formal("DExpectFormalArgSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - - void - DExpectFormalArgSsm::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DExpectFormalArgSsm::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); - } - - void - DExpectFormalArgSsm::on_parsed_expression(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DExpectFormalArgSsm::on_parsed_expression", - expr, - this->get_expect_str()); - } - - void - DExpectFormalArgSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DExpectFormalArgSsm::on_parsed_expression_with_semicolon", - expr, - this->get_expect_str()); + Super::on_parsed_typedescr(td, p_psm); } #ifdef NOT_YET From 3b1b4f03b52414881b96f27d25c8d97b25261a7c Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 14:33:44 -0500 Subject: [PATCH 127/258] xo-reader2: simplify DSyntaxStateMachine w/ DExpectFormalArglistSsm --- .../xo/reader2/DExpectFormalArglistSsm.hpp | 44 ++----------- .../src/reader2/DExpectFormalArglistSsm.cpp | 66 ++----------------- 2 files changed, 10 insertions(+), 100 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index 81d7e85d..716dfc28 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -5,7 +5,7 @@ #pragma once -#include "SyntaxStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" #include #include @@ -52,8 +52,9 @@ namespace xo { /** @class expect_formal_arglist * @brief parser state-machine for a formal parameter list **/ - class DExpectFormalArglistSsm { + class DExpectFormalArglistSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using DArena = xo::mm::DArena; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; @@ -71,6 +72,8 @@ namespace xo { /** @defgroup scm-expectformalarglistssm-methods general methods **/ ///@{ + const char * ssm_classname() const noexcept { return "DExpectFormalArglistSsm"; } + /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ void on_leftparen_token(const Token & tk, ParserStateMachine * p_psm); @@ -99,18 +102,6 @@ namespace xo { void on_token(const Token & tk, ParserStateMachine * p_psm); - /** update state on parsed symbol @p sym emitted by nested ssm, - * with overall parser state in @p p_psm - **/ - void on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm); - - /** update state on parsed typedescr @p td emitted by nested ssm, - * with overall parser state in @p p_psm - **/ - void on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm); - /** update state to consume parsed param (name,type) emitted by * nested ssm, with overall parser state in @p p_psm **/ @@ -118,31 +109,6 @@ namespace xo { TypeDescr param_type, ParserStateMachine * p_psm); - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); - - /** update state on parsed expression emitted by nested ssm - * with overall parser state in @p p_psm - **/ - void on_parsed_expression(obj expr, - ParserStateMachine * p_psm); - - /** update state on parsed expression, along with following semicolon, - * emitted by nested ssm with overall parser state in @p p_psm - **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); - -#ifdef NOT_YET - virtual void on_comma_token(const token_type & tk, - parserstatemachine * p_psm) override; - virtual void on_rightparen_token(const token_type & tk, - parserstatemachine * p_psm) override; -#endif - ///@} /** @defgroup scm-expectformalarglistssm-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index bebe4108..b34ad135 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -171,27 +171,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_token", - tk, - this->get_expect_str()); - } - - void - DExpectFormalArglistSsm::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("DExpectFormalArglistSsm::on_parsed_symbol", - sym, - this->get_expect_str()); - } - - void - DExpectFormalArglistSsm::on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_typedescr("DExpectFormalArglistSsm::on_parsed_typedescr", - td, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -238,37 +218,7 @@ namespace xo { return; } - p_psm->illegal_parsed_formal("DExpectFormalArglistSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - - void - DExpectFormalArglistSsm::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DExpectFormalArglistSsm::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); - } - - void - DExpectFormalArglistSsm::on_parsed_expression(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DExpectFormalArglistSsm::on_parsed_expression", - expr, - this->get_expect_str()); - } - - void - DExpectFormalArglistSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DExpectFormalArglistSsm::on_parsed_expression_with_semicolon", - expr, - this->get_expect_str()); + Super::on_parsed_formal(param_name, param_type, p_psm); } void @@ -282,9 +232,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -298,9 +246,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_comma_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -315,9 +261,7 @@ namespace xo { return; } - p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_rightparen_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } bool From feb94b13cb88a83c89eb1fa8b081df07f2fc977a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 14:53:49 -0500 Subject: [PATCH 128/258] xo-reader2: simplify DExpectTypeSsm w/ DSyntaxStateMachine --- .../include/xo/reader2/DExpectTypeSsm.hpp | 106 +--------- xo-reader2/src/reader2/DExpectTypeSsm.cpp | 187 ++---------------- 2 files changed, 16 insertions(+), 277 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 729eac83..421e3019 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -5,7 +5,7 @@ #pragma once -#include "SyntaxStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" #include namespace xo { @@ -21,8 +21,9 @@ namespace xo { * * @endpre **/ - class DExpectTypeSsm { + class DExpectTypeSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using TypeDescr = xo::reflect::TypeDescr; using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; @@ -34,6 +35,8 @@ namespace xo { static void start(ParserStateMachine * p_psm); + const char * ssm_classname() const noexcept { return "DExpectTypeSsm"; } + /** @defgroup scm-expecttype-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -57,105 +60,6 @@ namespace xo { void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); - /** operate state machine for this syntax on incoming define-token @p tk - * with overall parser state in @p p_psm - **/ - void on_def_token(const Token & tk, - ParserStateMachine * p_psm); - - /** operate state machine for this syntax on incoming if-token @p tk - * with overall parser state in @p p_psm - **/ - void on_if_token(const Token & tk, - ParserStateMachine * p_psm); - - /** operate state machine for this syntax on incoming colon-token @p tk - * with overall parser state in @p p_psm - **/ - void on_colon_token(const Token & tk, - ParserStateMachine * p_psm); - - /** operate state machine for this syntax on incoming singleassign-token @p tk - * with overall parser state in @p p_psm - **/ - void on_singleassign_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming string token @p tk, - * overall parser state in @p p_psm - **/ - void on_string_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming f64 token @p tk, - * overall parser state in @p p_psm - **/ - void on_f64_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming i64 token @p tk, - * overall parser state in @p p_psm - **/ - void on_i64_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming bool token @p tk, - * overall parser state in @p p_psm - **/ - void on_bool_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state for this syntax on incoming semicolon token @p tk, - * overall parser state in @p p_psm - **/ - void on_semicolon_token(const Token & tk, - ParserStateMachine * p_psm); - - /** (Never called). - * Operate state machine for this syntax after symbol - * emitted from nested ssm. - * Impossible path for DExpectTypeSsm until such time as it relies - * on nested ssms. Currently using on_symbol_token - * entry point instead. - **/ - void on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm); - - /** operate state machine for this syntax on receiving type-description - * from nested parser. - * Currently (jan 2026) impossible path for DExpectTypeSsm. - * Active path is via on_symbol_token() - **/ - void on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm); - - /** operate state machine to consume formal param (name,value) - * emitted by nested ssm - **/ - void on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm); - - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); - - /** operate state machine for this syntax on receiving expression - * from nested parser. - * (provided to satisfy ASyntaxStateMachine api. not reachable) - **/ - void on_parsed_expression(obj expr, - ParserStateMachine * p_psm); - - /** operate state machine for this syntax on receiving expression - * followed by semicolon from nested parser. - * (provided to satisfy ASyntaxStateMachine api. not reachable) - **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); - ///@} /** @defgroup scm-expecttype-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 5e42f758..f7ee3689 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -66,44 +66,14 @@ namespace xo { this->on_symbol_token(tk, p_psm); break; - case tokentype::tk_def: - this->on_def_token(tk, p_psm); - break; - - case tokentype::tk_if: - this->on_if_token(tk, p_psm); - break; - - case tokentype::tk_colon: - this->on_colon_token(tk, p_psm); - break; - - case tokentype::tk_singleassign: - this->on_singleassign_token(tk, p_psm); - break; - - case tokentype::tk_string: - this->on_string_token(tk, p_psm); - break; - - case tokentype::tk_f64: - this->on_f64_token(tk, p_psm); - break; - - case tokentype::tk_i64: - this->on_i64_token(tk, p_psm); - break; - - case tokentype::tk_bool: - this->on_bool_token(tk, p_psm); - break; - - case tokentype::tk_semicolon: - this->on_semicolon_token(tk, p_psm); - break; - // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_def: + case tokentype::tk_if: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_string: case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: @@ -116,8 +86,11 @@ namespace xo { case tokentype::tk_greatequal: case tokentype::tk_dot: case tokentype::tk_comma: + case tokentype::tk_colon: + case tokentype::tk_semicolon: case tokentype::tk_doublecolon: case tokentype::tk_assign: + case tokentype::tk_singleassign: case tokentype::tk_yields: case tokentype::tk_plus: case tokentype::tk_minus: @@ -140,87 +113,6 @@ namespace xo { } } - void - DExpectTypeSsm::on_def_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectTypeSsm", - tk, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_if_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DxpectTypeSsm", - tk, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_colon_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DxpectTypeSsm", - tk, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_singleassign_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectTypeSsm::on_singleassign_token", - tk, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_string_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectTypeSsm", - tk, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_f64_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectTypeSsm", - tk, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_i64_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectTypeSsm::on_i64_token", - tk, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_bool_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectTypeSsm::on_bool_token", - tk, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_semicolon_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExpectTypeSsm::on_semicolon_token", - tk, - this->get_expect_str()); - } - void DExpectTypeSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) @@ -247,71 +139,14 @@ namespace xo { td = Reflect::require(); if (!td) { - p_psm->illegal_input_on_token("DExpectTypeSsm::on_symbol_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); + return; } p_psm->pop_ssm(); p_psm->on_parsed_typedescr(td); } - void - DExpectTypeSsm::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("ExpectTypeSsm::on_parsed_symbol", - sym, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_typedescr("ExpectTypeSsm::on_parsed_typedescr", - td, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal("DExpectTypeSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DExpectTypeSsm::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_parsed_expression(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DExpectTypeSsm::on_parsed_expression", - expr, - this->get_expect_str()); - } - - void - DExpectTypeSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DExpectTypeSsm::on_parsed_expression_with_semicolon", - expr, - this->get_expect_str()); - } - bool DExpectTypeSsm::pretty(const ppindentinfo & ppii) const { From 09d517595729c9d653565d63a184ae1c930ad3ec Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 15:01:31 -0500 Subject: [PATCH 129/258] xo-reader2: simplify DExprSeqState w/ DSyntaxStateMachine --- .../include/xo/reader2/DExprSeqState.hpp | 48 +------- xo-reader2/src/reader2/DExprSeqState.cpp | 108 ++---------------- 2 files changed, 15 insertions(+), 141 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index a7b19c28..62ae9f5e 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -5,8 +5,7 @@ #pragma once -#include "ParserStateMachine.hpp" -#include "SyntaxStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" #include @@ -37,8 +36,9 @@ namespace xo { * * Similar to exprseq_xs in xo-expresion **/ - class DExprSeqState { + class DExprSeqState : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using TypeDescr = xo::reflect::TypeDescr; using AAllocator = xo::mm::AAllocator; using ppindentinfo = xo::print::ppindentinfo; @@ -54,6 +54,8 @@ namespace xo { ParserStateMachine * p_psm); public: + const char * ssm_classname() const noexcept { return "DExprSeqState"; } + /** @defgroup scm-exprseq-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -91,16 +93,6 @@ namespace xo { **/ void on_if_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax on incoming colon token @p tk, - * overall parser state in @p p_psm - **/ - void on_colon_token(const Token & tk, ParserStateMachine * p_psm); - - /** update state for this syntax on incoming single-assign token @p tk, - * overall parser state in @p p_psm - **/ - void on_singleassign_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax on incoming string token @p tk, * overall parser state in @p p_psm **/ @@ -121,36 +113,6 @@ namespace xo { **/ void on_bool_token(const Token & tk, ParserStateMachine * p_psm); - /** update state for this syntax on incoming semicolon token @p tk, - * overall parser state in @p p_psm - **/ - void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); - - /** update state for this syntax on parsed symbol @p sym - * from immediately-downstream ssm. - * overall parser state in @p p_psm - **/ - void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); - - /** update state for this syntax on parsed type-description @p td - * from nested ssm. - * overall parser state in @p p_psm - **/ - void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); - - /** update this ssm to consume parsed formal param (name, value) - * emitted by nested ssm, with overall parser state in @p p_psm - **/ - void on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm); - - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); - /** update state for this syntax on parsed expression @p expr * from nested ssm. * overall parser state in @p p_psm diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 12847350..ca6bfa27 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -131,14 +131,6 @@ namespace xo { this->on_if_token(tk, p_psm); return; - case tokentype::tk_colon: - this->on_colon_token(tk, p_psm); - return; - - case tokentype::tk_singleassign: - this->on_singleassign_token(tk, p_psm); - return; - case tokentype::tk_string: this->on_string_token(tk, p_psm); return; @@ -155,10 +147,6 @@ namespace xo { this->on_bool_token(tk, p_psm); return; - case tokentype::tk_semicolon: - this->on_semicolon_token(tk, p_psm); - return; - // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_leftparen: @@ -173,7 +161,10 @@ namespace xo { case tokentype::tk_greatequal: case tokentype::tk_dot: case tokentype::tk_comma: + case tokentype::tk_colon: + case tokentype::tk_semicolon: case tokentype::tk_doublecolon: + case tokentype::tk_singleassign: case tokentype::tk_assign: case tokentype::tk_yields: case tokentype::tk_plus: @@ -225,9 +216,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExprSeqState::on_symbol_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -264,9 +253,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExprSeqState::on_lambda_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -286,27 +273,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExprSeqState::on_if_token", - tk, - this->get_expect_str()); - } - - void - DExprSeqState::on_colon_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExprSeqState::on_colon_token", - tk, - this->get_expect_str()); - } - - void - DExprSeqState::on_singleassign_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExprSeqState::on_singleassign_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -333,9 +300,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExprSeqState::on_string_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -361,9 +326,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExprSeqState::on_f64_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -389,9 +352,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExprSeqState::on_i64_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -417,56 +378,7 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExprSeqState::on_bool_token", - tk, - this->get_expect_str()); - } - - void - DExprSeqState::on_semicolon_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DExprSeqState::on_semicolon_token", - tk, - this->get_expect_str()); - } - - void - DExprSeqState::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("DExprSeqState::on_parsed_symbol", - sym, - this->get_expect_str()); - } - - void - DExprSeqState::on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_typedescr("DExprSeqState::on_parsed_typedescr", - td, - this->get_expect_str()); - } - - void - DExprSeqState::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal("DExprSeqState::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - - void - DExprSeqState::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DExprSeqState::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void From 0b332b78727bc3ac1ccdfa0da132da87a01f767a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 15:17:28 -0500 Subject: [PATCH 130/258] xo-reader2: simplify DProgressSsm w/ DSyntaxStateMachine --- .../include/xo/reader2/DProgressSsm.hpp | 35 +--- xo-reader2/src/reader2/DProgressSsm.cpp | 185 ++---------------- 2 files changed, 27 insertions(+), 193 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index ae9c2244..542707f4 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -5,7 +5,7 @@ #pragma once -#include "ParserStateMachine.hpp" +#include "DSyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" //#include #include @@ -86,8 +86,9 @@ namespace xo { * To look at but not consume a token T, can push a progress_xs instance P, * then send T to P. **/ - class DProgressSsm { + class DProgressSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; using TypeDescr = xo::reflect::TypeDescr; using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; @@ -119,6 +120,8 @@ namespace xo { parserstatemachine * p_psm) const; #endif + const char * ssm_classname() const noexcept { return "DProgressSsm"; } + std::string_view get_expect_str() const noexcept; /** assemble expression from collected inputs. @@ -129,12 +132,11 @@ namespace xo { /** @defgroup scm-progressssm-methods general methods **/ ///@{ - void on_if_token(const Token & tk, - ParserStateMachine * p_psm); - void on_then_token(const Token & tk, - ParserStateMachine * p_psm); - void on_else_token(const Token & tk, - ParserStateMachine * p_psm); + /** token belongs to surrounding syntax, + * -> lock in current progress + **/ + void on_completing_token(const Token & tk, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-progressssm-ssm-facet syntaxstatemachine facet methods **/ @@ -148,8 +150,6 @@ namespace xo { void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); - void on_def_token(const Token & tk, - ParserStateMachine * p_psm); void on_colon_token(const Token & tk, ParserStateMachine * p_psm); void on_singleassign_token(const Token & tk, @@ -166,17 +166,6 @@ namespace xo { ParserStateMachine * p_psm); void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); - void on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm); - void on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm); - void on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm); - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); - void on_parsed_expression(obj, - ParserStateMachine * p_psm); void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm); @@ -204,10 +193,6 @@ namespace xo { parserstatemachine * p_psm) override; void on_rightbrace_token(const token_type & tk, parserstatemachine * p_psm) override; - void on_then_token(const token_type & tk, - parserstatemachine * p_psm) override; - void on_else_token(const token_type & tk, - parserstatemachine * p_psm) override; /* entry point for an infix operator token */ void on_operator_token(const token_type & tk, diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 5a6317a3..3c617fae 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -218,26 +218,15 @@ namespace xo { scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); switch (tk.tk_type()) { + case tokentype::tk_then: + case tokentype::tk_else: + this->on_completing_token(tk, p_psm); + return; + case tokentype::tk_symbol: this->on_symbol_token(tk, p_psm); return; - case tokentype::tk_def: - this->on_def_token(tk, p_psm); - return; - - case tokentype::tk_if: - this->on_if_token(tk, p_psm); - return; - - case tokentype::tk_then: - this->on_then_token(tk, p_psm); - return; - - case tokentype::tk_else: - this->on_else_token(tk, p_psm); - return; - case tokentype::tk_colon: this->on_colon_token(tk, p_psm); return; @@ -268,6 +257,8 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_def: + case tokentype::tk_if: case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: @@ -304,61 +295,20 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DProgressSsm::on_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void DProgressSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DProgressSsm::on_symbol_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void - DProgressSsm::on_def_token(const Token & tk, - ParserStateMachine * p_psm) + DProgressSsm::on_completing_token(const Token & tk, + ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DProgressSsm::on_def_token", - tk, - this->get_expect_str()); - } - - void - DProgressSsm::on_if_token(const Token & tk, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_token("DProgressSsm::on_if_token", - tk, - this->get_expect_str()); - } - - void - DProgressSsm::on_then_token(const Token & tk, - ParserStateMachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - (void)tk; - - obj expr = this->assemble_expr(p_psm); - - p_psm->pop_ssm(); // completes self - - // TODO: perhaps need to generalize on_parsed_expression_with_semicolon() ..? - p_psm->on_parsed_expression(expr); - p_psm->on_token(tk); - } - - void - DProgressSsm::on_else_token(const Token & tk, - ParserStateMachine * p_psm) - { - // note: common with .on_then_token() - scope log(XO_DEBUG(p_psm->debug_flag())); (void)tk; @@ -461,36 +411,28 @@ namespace xo { DProgressSsm::on_string_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DProgressSsm::on_string_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void DProgressSsm::on_f64_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DProgressSsm::on_f64_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void DProgressSsm::on_i64_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DProgressSsm::on_i64_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void DProgressSsm::on_bool_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DProgressSsm::on_bool_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } void @@ -529,59 +471,10 @@ namespace xo { */ #ifdef OBSOLETE - p_psm->illegal_input_on_token("DProgressSsm::on_semicolon_token", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); #endif } - void - DProgressSsm::on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_symbol("DProgressSsm::on_parsed_symbol", - sym, - this->get_expect_str()); - } - - void - DProgressSsm::on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm) - { - p_psm->illegal_input_on_typedescr("DProgressSsm::on_parsed_typedescr", - td, - this->get_expect_str()); - } - - void - DProgressSsm::on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal("DProgressSsm::on_parsed_formal", - param_name, - param_type, - this->get_expect_str()); - } - - void - DProgressSsm::on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_formal_arglist("DProgressSsm::on_parsed_formal_arglist", - arglist, - this->get_expect_str()); - } - - void - DProgressSsm::on_parsed_expression(obj expr, - ParserStateMachine * p_psm) - { - p_psm->illegal_parsed_expression("DProgressSsm::on_parsed_expression", - expr, - this->get_expect_str()); - } - void DProgressSsm::on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm) @@ -905,14 +798,6 @@ namespace xo { p_psm->top_exprstate().on_comma_token(tk, p_psm); } - void - progress_xs::on_typedescr(TypeDescr /*td*/, - parserstatemachine * /*p_psm*/) - { - /* unreachable */ - assert(false); - } - void progress_xs::on_semicolon_token(const token_type & /*tk*/, parserstatemachine * p_psm) @@ -1116,44 +1001,8 @@ namespace xo { exprstate::on_i64_token(tk, p_psm); } } - - void - progress_xs::print(std::ostream & os) const { - os << ""; - } - - bool - progress_xs::pretty_print(const xo::print::ppindentinfo & ppii) const - { - if (ppii.upto()) { - return (ppii.pps()->print_upto("print_upto(refrtag("lhs", lhs_)) : true) - && (op_type_ != optype::invalid ? ppii.pps()->print_upto(refrtag("op", op_type_)) : true) - && (rhs_ ? ppii.pps()->print_upto(refrtag("rhs", rhs_)) : true) - && ppii.pps()->print_upto(">")); - } else { - ppii.pps()->write("pretty(refrtag("lhs", lhs_)); - if (op_type_ != optype::invalid) - ppii.pps()->pretty(refrtag("op", op_type_)); - if (rhs_) - ppii.pps()->pretty(refrtag("rhs", rhs_)); - ppii.pps()->write(">"); - return false; - } - } - #endif + bool DProgressSsm::pretty(const xo::print::ppindentinfo & ppii) const { From 7960e05b84c64d5ac53043cc8fd31f0d828de8bc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 20:08:41 -0500 Subject: [PATCH 131/258] xo-expression2 xo-reader2 DSequenceExpr, DSequenceSsm [WIP] --- xo-expression2/DSequenceExpr.hpp | 77 ++++++++++ .../include/xo/expression2/exprtype.hpp | 4 +- .../src/expression2/DSequenceExpr.cpp | 88 +++++++++++ xo-object2/include/xo/object2/DArray.hpp | 2 + xo-reader2/include/xo/reader2/DDefineSsm.hpp | 15 -- .../include/xo/reader2/DSequenceSsm.hpp | 57 ++++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 4 +- xo-reader2/src/reader2/DSequenceSsm.cpp | 137 ++++++++++++++++++ 8 files changed, 364 insertions(+), 20 deletions(-) create mode 100644 xo-expression2/DSequenceExpr.hpp create mode 100644 xo-expression2/src/expression2/DSequenceExpr.cpp create mode 100644 xo-reader2/include/xo/reader2/DSequenceSsm.hpp create mode 100644 xo-reader2/src/reader2/DSequenceSsm.cpp diff --git a/xo-expression2/DSequenceExpr.hpp b/xo-expression2/DSequenceExpr.hpp new file mode 100644 index 00000000..12caf649 --- /dev/null +++ b/xo-expression2/DSequenceExpr.hpp @@ -0,0 +1,77 @@ +/** @file DSequenceExpr.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "TypeRef.hpp" +#include + +namespace xo { + namespace scm { + + /** syntax for a sequence of expressions + * { + * expr(1); + * expr(2); + * ... + * expr(n); + * } + **/ + class DSequenceExpr { + public: + using size_type = DArray::size_type; + using ppindentinfo = xo::print::ppindentinfo; + + public: + DSequenceExpr() = default; + DSequenceExpr(DArray * xv) : expr_v_{xv} {} + + /** create empty sequence using memory from @p mm **/ + static obj make_empty(obj mm); + + /** create empty sequence expression using mmeory from @p mm **/ + static DSequenceExpr * _make_empty(obj mm); + + size_type size() const noexcept; + obj operator[](std::size_t i) const; + + /** append @p expr to the end of this sequence **/ + void push_back(obj expr); + + // get_free_variables(); + // visit_preorder(); + // visit_layer(); + // xform_layer() + // attach_envs() + + /** @defgroup scm-ifelseexpr-expression-facets **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::sequence; } + TypeRef typeref() const noexcept { return typeref_; } + TypeDescr valuetype() const noexcept { return typeref_.td(); } + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + /** @defgroup scm-sequenceexpr-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printing driver; combine layout+printing **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** expression value always has type consistent with this description + **/ + TypeRef typeref_; + /** array of expressions **/ + DArray * expr_v_ = nullptr; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DSequenceExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/exprtype.hpp b/xo-expression2/include/xo/expression2/exprtype.hpp index 861d62bd..3bcda3c4 100644 --- a/xo-expression2/include/xo/expression2/exprtype.hpp +++ b/xo-expression2/include/xo/expression2/exprtype.hpp @@ -40,10 +40,10 @@ namespace xo { variable, /** if-then-else **/ ifexpr, -#ifdef NOT_YET /** sequence **/ sequence, - /** type conversion **/ +#ifdef NOT_YET + ) /** type conversion **/ convert, #endif diff --git a/xo-expression2/src/expression2/DSequenceExpr.cpp b/xo-expression2/src/expression2/DSequenceExpr.cpp new file mode 100644 index 00000000..c5abf27b --- /dev/null +++ b/xo-expression2/src/expression2/DSequenceExpr.cpp @@ -0,0 +1,88 @@ +/** @file DSequenceExpr.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DSequenceExpr.hpp" + +namespace xo { + namespace scm { + + obj + DSequenceExpr::make_empty(obj mm) + { + return obj(_make_empty(mm)); + } + + DSequenceExpr * + DSequenceExpr::_make_empty(obj mm) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DSequenceExpr)); + + DSequenceExpr * expr = new (mem) DSequenceExpr(); + + constexpr size_type c_hint_capacity = 8; + + /** allocate 2nd, so it comes after DSequenceExpr in + * memory. This may later allow realloc + **/ + DArray * expr_v = DArray::empty(mm, + c_hint_capacity); + + expr->expr_v_ = expr_v; + + return expr; + } + + size_type + DSequenceExpr::size() const noexcept + { + return expr_v_->size(); + } + + obj + DSequenceExpr::operator[](std::size_t i) const + { + return (*expr_v_)[i]; + } + + void + DSequenceExpr::push_back(obj mm, + obj expr) + { + if (expr_v_->size() == expr_v_->capacity()) { + /* reallocate+expand */ + + DArray * expr_2x_v + = DArray::empty(mm, 2 * expr_v_->capacity()); + + for (size_type i = 0, z = expr_v_->size(); i < z; ++i) { + expr_2x_v->push_back((*expr_2x_v)[i]); + } + + this->expr_v_ = expr_2x_v; + } + + this->expr_v_->push_back(expr); + } + + void + DSequenceExpr::assign_valuetype(TypeDescr td) noexcept + { + typeref_.resolve(td); + } + + void + DSequenceExpr::pretty(const ppindentinfo & ppii) const + { + using xo::print::ppstate; + + ppstate * pps = ppii.pps(); + + xxx; + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DSequenceExpr.cpp */ diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index f50936e3..e95f67f6 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -68,6 +68,8 @@ namespace xo { requires (std::same_as> && ...) static DArray * array(obj mm, Args... args); + obj operator[](size_type index) const noexcept { return elts_[index]; } + ///@} /** @defgroup darray-access acecss methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 939d5479..34918dc9 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -169,21 +169,6 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); -#ifdef OBSOLETE - /** update state for this ssm to consume param (name,value) - * emitted by nested @p_psm - **/ - void on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm); - - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); -#endif - /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp new file mode 100644 index 00000000..8d936254 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp @@ -0,0 +1,57 @@ +/** @file DSequenceSsm.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +//#include "exprstate.hpp" + +namespace xo { + namespace scm { class Sequence; } + namespace scm { class Lambda; } + + namespace scm { + class DSequenceSsm : public DSyntaxStateMachine { + public: + using Sequence = xo::scm::Sequence; + using Lambda = xo::scm::Lambda; + + public: + const char * ssm_classname() const noexcept { return "DSequenceSsm"; } + +#ifdef NOT_YET + /** start parsing a sequence-expr. + * input begins with first expression in the sequence. + **/ + static void start(parserstatemachine * p_psm); + + /** named ctor idiom **/ + static std::unique_ptr make(); + + virtual void on_expr(bp expr, + parserstatemachine * p_psm) override; + virtual void on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) override; + + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + + virtual void print(std::ostream & os) const override; + virtual bool pretty_print(const xo::print::ppindentinfo & ppii) const override; +#endif + + private: + DSequenceSsm(); + + private: + /** will build SequenceExpr from in-order contents of this array **/ + DArray * expr_v_; + //std::vector> expr_v_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DSequenceSsm.hpp */ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 899731a3..3b4b2c36 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -183,9 +183,7 @@ namespace xo { DExpectExprSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DExpectExprSsm", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } #ifdef NOT_YET diff --git a/xo-reader2/src/reader2/DSequenceSsm.cpp b/xo-reader2/src/reader2/DSequenceSsm.cpp new file mode 100644 index 00000000..285960bd --- /dev/null +++ b/xo-reader2/src/reader2/DSequenceSsm.cpp @@ -0,0 +1,137 @@ +/* @file DSequenceSsm.cpp */ + +#include "DSequenceSsm.hpp" + +#ifdef NOT_YET +#include "expect_expr_xs.hpp" +#include "let1_xs.hpp" +#include "xo/expression/DefineExpr.hpp" +#include "xo/expression/Sequence.hpp" +#include "xo/expression/pretty_expression.hpp" +#endif + +namespace xo { + using xo::scm::DefineExpr; + + namespace scm { +#ifdef NOT_YET + std::unique_ptr + sequence_xs::make() { + return std::make_unique(sequence_xs()); + } +#endif + + void + sequence_xs::start(parserstatemachine * p_psm) { + p_psm->push_exprstate(sequence_xs::make()); + /* want to accept anything that starts an expression, + * except that } ends it + */ + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } + + sequence_xs::sequence_xs() + : exprstate(exprstatetype::sequenceexpr) + {} + + void + sequence_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("expr", expr.promote())); + + /* TODO: if expr is a DefineExpr, + * then need to rewrite... + * + * ...prefix + * DefineExpr(lhs_name, rhs) + * rest... + * + * becomes: + * + * /-- .outer_seq_expr_ + * v + * Sequence( + * ...prefix, + * + * /-- .inner_lm_expr_ + * v + * Apply(Lambda(gen999, + * [Variable(lhs_name, type(rhs))], + * /-- .expr_v_ + * v + * sequencify(rest...)), + * rhs)) + * + * so amongst other things, + * helpful to have nested seequence_xs that propagates '}' + * instead of swallowing it. + */ + bp def_expr = DefineExpr::from(expr); + + if (def_expr) { + /** nested_start: control returns via + * .on_expr(x) + * with x something like: + * Apply(Lambda(gensym(), + * [Variable(def_expr->lhs_name(), + * def_expr->valuetype())], + * body...)) + * followed immediately by + * .on_rightbrace_token() + **/ + let1_xs::start(def_expr->lhs_name(), + def_expr->rhs(), + p_psm); + } else { + this->expr_v_.push_back(expr.promote()); + + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } + } + + void + sequence_xs::on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) + { + /* sequence continues until right brace */ + this->on_expr(expr, p_psm); + } + + void + sequence_xs::on_rightbrace_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + auto self = p_psm->pop_exprstate(); + + /* make sequence from expressions seen at this level, + * and report it to parent + */ + auto expr = Sequence::make(this->expr_v_); + + p_psm->top_exprstate().on_expr(expr, p_psm); + } + + void + sequence_xs::print(std::ostream & os) const { + os << ""; + } + + bool + sequence_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, "sequence_xs", + xrefrtag("expr_v.size", expr_v_.size())); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DSequenceSsm.cpp */ From 3358bf885d35b18b597862dfb7c4c485221b33b2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 01:13:26 -0500 Subject: [PATCH 132/258] xo-objecdt2: bugfix: dup loop increment --- xo-object2/src/object2/DArray.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index b1343a67..65162511 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -91,8 +91,6 @@ namespace xo { if (!pps->print_upto(elt)) return false; - - ++i; } pps->write("]"); From f08403bfe334d228a7367bf408eaa22a54ab7dcc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 01:13:55 -0500 Subject: [PATCH 133/258] xo-interpreter2: + _do_eval_sequence_op() --- .../xo/interpreter2/VirtualSchematikaMachine.hpp | 6 ++++++ .../src/interpreter2/VirtualSchematikaMachine.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 66a1c1e1..0f58f2c4 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -75,6 +75,12 @@ namespace xo { **/ void _do_eval_if_else_op(); + /** evaluate a sequence expression + * Require: + * - expression in @ref expr_ + **/ + void _do_eval_sequence_op(); + private: /* * Some registers are preserved by evaluation: diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index fe104f9a..02ed023a 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -60,6 +60,9 @@ namespace xo { case exprtype::ifexpr: _do_eval_if_else_op(); break; + case exprtype::sequence: + _do_eval_sequence_op(); + break; } } @@ -107,6 +110,13 @@ namespace xo { // not implemented assert(false); } + + void + VirtualSchematikaMachine::_do_eval_sequence_op() + { + // not implemented + assert(false); + } } /*namespace scm*/ } /*namespace xo*/ From 315c066734c335e38cb3bc0d7c7ce8809a2b3d87 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 01:14:33 -0500 Subject: [PATCH 134/258] xo-reader2: revert c++23 feature, to keep osx clang build --- xo-reader2/CMakeLists.txt | 5 +- xo-reader2/include/xo/reader2/DDefineSsm.hpp | 2 +- .../include/xo/reader2/DExpectExprSsm.hpp | 2 +- .../xo/reader2/DExpectFormalArgSsm.hpp | 2 +- .../xo/reader2/DExpectFormalArglistSsm.hpp | 2 +- .../include/xo/reader2/DExpectSymbolSsm.hpp | 2 +- .../include/xo/reader2/DExpectTypeSsm.hpp | 2 +- .../include/xo/reader2/DExprSeqState.hpp | 2 +- xo-reader2/include/xo/reader2/DIfElseSsm.hpp | 27 ++------- xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 2 +- .../include/xo/reader2/DProgressSsm.hpp | 2 +- .../xo/reader2/DSyntaxStateMachine.hpp | 56 ++++++++++++------- .../include/xo/reader2/ParserStateMachine.hpp | 2 + xo-reader2/src/reader2/DIfElseSsm.cpp | 12 ++-- 14 files changed, 57 insertions(+), 63 deletions(-) diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index ff842708..79d692ba 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -2,10 +2,7 @@ cmake_minimum_required(VERSION 3.10) -# relying on -# this auto&& -# -set(CMAKE_CXX_STANDARD 23) +#set(CMAKE_CXX_STANDARD 23) project(xo_reader2 VERSION 1.0) enable_language(CXX) diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 34918dc9..0e3b1404 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -104,7 +104,7 @@ namespace xo { /** @defgroup scm-definessm-access-methods **/ ///@{ - const char * ssm_classname() const noexcept { return "DDefineSsm"; } + static const char * ssm_classname() { return "DDefineSsm"; } /** identify this nested state machine **/ defexprstatetype defstate() const noexcept { return defstate_; } diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 424afb99..4b407881 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -38,7 +38,7 @@ namespace xo { /** @defgroup scm-expectexpr-access-methods access methods **/ ///@{ - const char * ssm_classname() const noexcept { return "DExpectExprSsm"; } + static const char * ssm_classname() { return "DExpectExprSsm"; } bool allow_defs() const noexcept { return allow_defs_; } bool cxl_on_rightbrace() const noexcept { return cxl_on_rightbrace_; } diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index 5308c701..62f5ae34 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -71,7 +71,7 @@ namespace xo { /** @defgroup scm-expectformalargssm-methods general methods **/ ///@{ - const char * ssm_classname() const noexcept { return "DExpectFormalArgSsm"; } + static const char * ssm_classname() { return "DExpectFormalArgSsm"; } /** update state on incoming colon token @p tk; * with overall parser state in @p p_psm diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index 716dfc28..203c7293 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -72,7 +72,7 @@ namespace xo { /** @defgroup scm-expectformalarglistssm-methods general methods **/ ///@{ - const char * ssm_classname() const noexcept { return "DExpectFormalArglistSsm"; } + static const char * ssm_classname() { return "DExpectFormalArglistSsm"; } /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ void on_leftparen_token(const Token & tk, diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index f06cf94b..d1cf3a3c 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -46,7 +46,7 @@ namespace xo { static void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); - const char * ssm_classname() const noexcept { return "DExpectSymbolSsm"; } + static const char * ssm_classname() { return "DExpectSymbolSsm"; } /** @defgroup scm-expectsymbol-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 421e3019..6719bfb8 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -35,7 +35,7 @@ namespace xo { static void start(ParserStateMachine * p_psm); - const char * ssm_classname() const noexcept { return "DExpectTypeSsm"; } + static const char * ssm_classname() { return "DExpectTypeSsm"; } /** @defgroup scm-expecttype-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 62ae9f5e..56578161 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -54,7 +54,7 @@ namespace xo { ParserStateMachine * p_psm); public: - const char * ssm_classname() const noexcept { return "DExprSeqState"; } + static const char * ssm_classname() { return "DExprSeqState"; } /** @defgroup scm-exprseq-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp index 2e3533cd..43f6d4b5 100644 --- a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp @@ -52,7 +52,7 @@ namespace xo { /** @class DIfElseSsm * @brief syntax state machine for parsing a conditional expression **/ - class DIfElseSsm : public DSyntaxStateMachine { + class DIfElseSsm : public DSyntaxStateMachine { public: using Super = DSyntaxStateMachine; using AAllocator = xo::mm::AAllocator; @@ -89,7 +89,9 @@ namespace xo { obj expr_mm, ParserStateMachine * p_psm); - const char * ssm_classname() const noexcept { return "DIfElseSsm"; } + static const char * ssm_classname() { return "DIfElseSsm"; } + + DSyntaxStateMachine * super() { return this; } ///@} /** @defgroup scm-ifelsessm-expression-methods general methods **/ @@ -142,27 +144,6 @@ namespace xo { void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); -#ifdef OBSOLETE - /** update state for this syntax after parsing a symbol @p sym, - * with overall parser state in @p p_psm - **/ - void on_parsed_symbol(std::string_view sym, - ParserStateMachine * p_psm); - - /** update state for this syntax after parsing a type description @p td; - * overall parser state in @p p_psm - **/ - void on_parsed_typedescr(TypeDescr td, - ParserStateMachine * p_psm); - - /** update state to consume formal param (name,value) - * from nested ssm - **/ - void on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm); -#endif - /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm. **/ diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index 7f29e946..d4147c76 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -80,7 +80,7 @@ namespace xo { /** @defgroup scm-lambdassm-methods **/ ///@{ - const char * ssm_classname() const noexcept { return "DLambdaSsm"; } + static const char * ssm_classname() { return "DLambdaSsm"; } static void start(ParserStateMachine * p_psm); diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 542707f4..85126bed 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -120,7 +120,7 @@ namespace xo { parserstatemachine * p_psm) const; #endif - const char * ssm_classname() const noexcept { return "DProgressSsm"; } + static const char * ssm_classname() { return "DProgressSsm"; } std::string_view get_expect_str() const noexcept; diff --git a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp index ee4fca98..f5a835ae 100644 --- a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp @@ -33,43 +33,51 @@ namespace xo { /** Default implementation for required SyntaxStateMachine facet method **/ - void on_token(this auto&& self, - const Token & tk, + void on_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token(self.ssm_classname(), + // starting with c++23 can use "this auto&& self" instead + Derived & self = reinterpret_cast(*this); + + p_psm->illegal_input_on_token(Derived::ssm_classname(), tk, self.get_expect_str()); } - void on_parsed_symbol(this auto&& self, - std::string_view sym, + void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_symbol(self.ssm_classname(), + // starting with c++23 can use "this auto&& self" instead + Derived & self = reinterpret_cast(*this); + + p_psm->illegal_input_on_symbol(Derived::ssm_classname(), sym, self.get_expect_str()); } /** Default implementation for required SyntaxStateMachine facet method **/ - void on_parsed_typedescr(this auto&& self, - TypeDescr td, + void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_typedescr(self.ssm_classname(), + // starting with c++23 can use "this auto&& self" instead + Derived & self = reinterpret_cast(*this); + + p_psm->illegal_input_on_typedescr(Derived::ssm_classname(), td, self.get_expect_str()); } /** Default implementation for required SyntaxStateMachine facet method **/ - void on_parsed_formal(this auto&& self, - const DUniqueString * param_name, + void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_formal(self.ssm_classname(), + // starting with c++23 can use "this auto&& self" instead + Derived & self = reinterpret_cast(*this); + + p_psm->illegal_parsed_formal(Derived::ssm_classname(), param_name, param_type, self.get_expect_str()); @@ -79,22 +87,26 @@ namespace xo { * * arglist is DArray of obj **/ - void on_parsed_formal_arglist(this auto&& self, - DArray * arglist, + void on_parsed_formal_arglist(DArray * arglist, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_formal_arglist(self.ssm_classname(), + // starting with c++23 can use "this auto&& self" instead + Derived & self = static_cast(*this); + + p_psm->illegal_parsed_formal_arglist(Derived::ssm_classname(), arglist, self.get_expect_str()); } /** Default implementation for required SyntaxStateMachine facet method **/ - void on_parsed_expression(this auto&& self, - obj expr, + void on_parsed_expression(obj expr, ParserStateMachine * p_psm) { - p_psm->illegal_parsed_expression(self.ssm_classname(), + // starting with c++23 can use "this auto&& self" instead + Derived & self = static_cast(*this); + + p_psm->illegal_parsed_expression(Derived::ssm_classname(), expr, self.get_expect_str()); @@ -102,15 +114,17 @@ namespace xo { /** Default implementation for required SyntaxStateMachine facet method **/ - void on_parsed_expression_with_semicolon(this auto&& self, - obj expr, + void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm) { + // starting with c++23 can use "this auto&& self" instead + Derived & self = static_cast(*this); + // We don't need a separate entry point, // since the semicolon isn't relevant to problem with syntax // - p_psm->illegal_parsed_expression(self.ssm_classname(), + p_psm->illegal_parsed_expression(Derived::ssm_classname(), expr, self.get_expect_str()); diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index fbf636e3..a57247c7 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -261,10 +261,12 @@ namespace xo { **/ DLocalSymtab * local_symtab_ = nullptr; +#ifdef NOT_YET /** global symbol table. * Toplevel definitions go here. **/ DGlobalSymtab * global_symtab_ = nullptr; +#endif /** current output from parser **/ ParserResult result_; diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index 8551e1fe..7efb4a7e 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -189,7 +189,7 @@ namespace xo { break; } - Super::on_token(tk, p_psm); + DSyntaxStateMachine::on_token(tk, p_psm); } void @@ -207,7 +207,7 @@ namespace xo { return; } - Super::on_token(tk, p_psm); + DSyntaxStateMachine::on_token(tk, p_psm); } void @@ -225,7 +225,7 @@ namespace xo { return; } - Super::on_token(tk, p_psm); + DSyntaxStateMachine::on_token(tk, p_psm); } void @@ -243,7 +243,7 @@ namespace xo { return; } - Super::on_token(tk, p_psm); + DSyntaxStateMachine::on_token(tk, p_psm); } #ifdef NOT_YET @@ -313,7 +313,7 @@ namespace xo { return; } - Super::on_token(tk, p_psm); + DSyntaxStateMachine::on_token(tk, p_psm); } #ifdef NOT_YET @@ -402,7 +402,7 @@ namespace xo { break; } - Super::on_parsed_expression(expr, p_psm); + DSyntaxStateMachine::on_parsed_expression(expr, p_psm); } void From 92e79852b9d99493ad3969004ea7a69537a4bd47 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 01:44:53 -0500 Subject: [PATCH 135/258] xo-expression2 xo-gc: DSequenceExpr builds [WIP] --- xo-expression2/CMakeLists.txt | 14 + .../idl/IExpression_DSequenceExpr.json5 | 12 + .../xo/expression2}/DSequenceExpr.hpp | 10 +- .../include/xo/expression2/Expression.hpp | 2 +- .../include/xo/expression2/SymbolTable.hpp | 2 +- .../xo/expression2/detail/AExpression.hpp | 2 +- .../xo/expression2/detail/IExpression_Any.hpp | 2 +- .../detail/IExpression_DApplyExpr.hpp | 2 +- .../detail/IExpression_DConstant.hpp | 2 +- .../detail/IExpression_DDefineExpr.hpp | 2 +- .../detail/IExpression_DIfElseExpr.hpp | 2 +- .../detail/IExpression_DLambdaExpr.hpp | 2 +- .../detail/IExpression_DSequenceExpr.hpp | 66 +++++ .../detail/IExpression_DVariable.hpp | 2 +- .../expression2/detail/IExpression_Xfer.hpp | 2 +- .../detail/IGCObject_DUniqueString.hpp | 2 +- .../detail/IGCObject_DVariable.hpp | 2 +- .../detail/IPrintable_DApplyExpr.hpp | 2 +- .../detail/IPrintable_DConstant.hpp | 2 +- .../detail/IPrintable_DDefineExpr.hpp | 2 +- .../detail/IPrintable_DIfElseExpr.hpp | 2 +- .../detail/IPrintable_DLambdaExpr.hpp | 2 +- .../detail/IPrintable_DUniqueString.hpp | 2 +- .../detail/IPrintable_DVariable.hpp | 2 +- .../xo/expression2/detail/RExpression.hpp | 2 +- .../xo/expression2/symtab/ASymbolTable.hpp | 2 +- .../symtab/IPrintable_DLocalSymtab.hpp | 2 +- .../expression2/symtab/ISymbolTable_Any.hpp | 2 +- .../symtab/ISymbolTable_DLocalSymtab.hpp | 2 +- .../expression2/symtab/ISymbolTable_Xfer.hpp | 2 +- .../xo/expression2/symtab/RSymbolTable.hpp | 2 +- xo-expression2/src/expression2/CMakeLists.txt | 3 + .../src/expression2/DSequenceExpr.cpp | 33 ++- .../expression2/IExpression_DApplyExpr.cpp | 2 +- .../src/expression2/IExpression_DConstant.cpp | 2 +- .../expression2/IExpression_DDefineExpr.cpp | 2 +- .../expression2/IExpression_DIfElseExpr.cpp | 2 +- .../expression2/IExpression_DLambdaExpr.cpp | 2 +- .../expression2/IExpression_DSequenceExpr.cpp | 45 +++ .../src/expression2/IExpression_DVariable.cpp | 2 +- .../expression2/IGCObject_DUniqueString.cpp | 2 +- .../src/expression2/IGCObject_DVariable.cpp | 2 +- .../src/expression2/IPrintable_DApplyExpr.cpp | 2 +- .../src/expression2/IPrintable_DConstant.cpp | 2 +- .../expression2/IPrintable_DDefineExpr.cpp | 2 +- .../expression2/IPrintable_DIfElseExpr.cpp | 2 +- .../expression2/IPrintable_DLambdaExpr.cpp | 2 +- .../expression2/IPrintable_DLocalSymtab.cpp | 2 +- .../expression2/IPrintable_DUniqueString.cpp | 2 +- .../src/expression2/IPrintable_DVariable.cpp | 2 +- .../expression2/ISymbolTable_DLocalSymtab.cpp | 2 +- xo-gc/CMakeLists.txt | 4 + xo-gc/idl/GCObject.json5 | 6 +- xo-gc/include/xo/gc/GCObject.hpp | 3 +- xo-gc/include/xo/gc/detail/AGCObject.hpp | 2 +- xo-gc/include/xo/gc/detail/IGCObject_Any.hpp | 2 +- xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp | 2 +- xo-gc/include/xo/gc/detail/RGCObject.hpp | 7 +- .../include/xo/object2/GCObjectConverter.hpp | 158 +++++++++++ xo-object2/src/object2/GCObjectConverter.cpp | 258 ++++++++++++++++++ 60 files changed, 651 insertions(+), 62 deletions(-) create mode 100644 xo-expression2/idl/IExpression_DSequenceExpr.json5 rename xo-expression2/{ => include/xo/expression2}/DSequenceExpr.hpp (85%) create mode 100644 xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp create mode 100644 xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp create mode 100644 xo-object2/include/xo/object2/GCObjectConverter.hpp create mode 100644 xo-object2/src/object2/GCObjectConverter.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index ae1bb8c2..4f7705ce 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -238,6 +238,20 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-expression-sequenceexpr + FACET_PKG xo_expression2 + FACET Expression + REPR SequenceExpr + INPUT idl/IExpression_DSequenceExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-uniquestring diff --git a/xo-expression2/idl/IExpression_DSequenceExpr.json5 b/xo-expression2/idl/IExpression_DSequenceExpr.json5 new file mode 100644 index 00000000..451d39f1 --- /dev/null +++ b/xo-expression2/idl/IExpression_DSequenceExpr.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ "\"Expression.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Expression.json5", + brief: "provide AExpression interface for DSequenceExpr state", + using_doxygen: true, + repr: "DSequenceExpr", + doc: ["doc for something or other IExpression+DSequenceExpr" ], +} diff --git a/xo-expression2/DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/DSequenceExpr.hpp similarity index 85% rename from xo-expression2/DSequenceExpr.hpp rename to xo-expression2/include/xo/expression2/DSequenceExpr.hpp index 12caf649..7285ada8 100644 --- a/xo-expression2/DSequenceExpr.hpp +++ b/xo-expression2/include/xo/expression2/DSequenceExpr.hpp @@ -5,6 +5,7 @@ #pragma once +#include "Expression.hpp" #include "TypeRef.hpp" #include @@ -21,6 +22,8 @@ namespace xo { **/ class DSequenceExpr { public: + using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; using size_type = DArray::size_type; using ppindentinfo = xo::print::ppindentinfo; @@ -37,8 +40,11 @@ namespace xo { size_type size() const noexcept; obj operator[](std::size_t i) const; - /** append @p expr to the end of this sequence **/ - void push_back(obj expr); + /** append @p expr to the end of this sequence; + * use memory from @p mm if need to expand storage + **/ + void push_back(obj mm, + obj expr); // get_free_variables(); // visit_preorder(); diff --git a/xo-expression2/include/xo/expression2/Expression.hpp b/xo-expression2/include/xo/expression2/Expression.hpp index df4161a1..60e8a402 100644 --- a/xo-expression2/include/xo/expression2/Expression.hpp +++ b/xo-expression2/include/xo/expression2/Expression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/SymbolTable.hpp b/xo-expression2/include/xo/expression2/SymbolTable.hpp index 26576ed6..09fc04a8 100644 --- a/xo-expression2/include/xo/expression2/SymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/SymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/AExpression.hpp b/xo-expression2/include/xo/expression2/detail/AExpression.hpp index e080ece8..10375114 100644 --- a/xo-expression2/include/xo/expression2/detail/AExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/AExpression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp index 17545afb..c92c2c4a 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp index c8952199..d577854f 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp index 61b92e12..89c5044c 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp index 3ac7fd49..f5585b60 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp index 7d726dde..03500a39 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp index d488b6b3..916b82ac 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp new file mode 100644 index 00000000..b010ac65 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp @@ -0,0 +1,66 @@ +/** @file IExpression_DSequenceExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DSequenceExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DSequenceExpr.json5] + **/ + +#pragma once + +#include "Expression.hpp" +#include "Expression.hpp" +#include "DSequenceExpr.hpp" + +namespace xo { namespace scm { class IExpression_DSequenceExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IExpression_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IExpression_DSequenceExpr + **/ + class IExpression_DSequenceExpr { + public: + /** @defgroup scm-expression-dsequenceexpr-type-traits **/ + ///@{ + using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; + ///@} + /** @defgroup scm-expression-dsequenceexpr-methods **/ + ///@{ + // const methods + /** expression type (constant | apply | ..) **/ + static exprtype extype(const DSequenceExpr & self) noexcept; + /** placeholder for type giving possible values for this expression **/ + static TypeRef typeref(const DSequenceExpr & self) noexcept; + /** type giving possible values for this expression. Maybe null before typecheck **/ + static TypeDescr valuetype(const DSequenceExpr & self) noexcept; + + // non-const methods + /** assing to valuetype member. Useful when scaffolding expressions **/ + static void assign_valuetype(DSequenceExpr & self, TypeDescr td) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp index 6b9b702f..95b1becb 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp index fac8c541..9f7356bc 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp index b971daea..c95db10f 100644 --- a/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp index 24dc591f..aee612ea 100644 --- a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp index c05e87e2..b7782166 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp index a1e31382..35535d80 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp index 6d727d86..758022a6 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp index fcf80fd5..e9cf67ff 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp index 64ab6af1..45970bd8 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp index 34c9da79..51afa9da 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp index 6e97451b..a31ee97e 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/RExpression.hpp b/xo-expression2/include/xo/expression2/detail/RExpression.hpp index 4d717640..caf69fe0 100644 --- a/xo-expression2/include/xo/expression2/detail/RExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/RExpression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp index f0c6e10f..36d4c812 100644 --- a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp index c013e937..d4481dca 100644 --- a/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp index b642adb7..6a119832 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp index 72f409dd..2c1816e4 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISymbolTable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp index 3d5f7221..2333bb05 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp index 600ea4f8..c72503cc 100644 --- a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 8e6565c4..ab10048e 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -10,6 +10,7 @@ set(SELF_SRCS DLambdaExpr.cpp DApplyExpr.cpp DIfElseExpr.cpp + DSequenceExpr.cpp TypeRef.cpp @@ -34,6 +35,8 @@ set(SELF_SRCS IExpression_DIfElseExpr.cpp IPrintable_DIfElseExpr.cpp + IExpression_DSequenceExpr.cpp + DLocalSymtab.cpp DGlobalSymtab.cpp diff --git a/xo-expression2/src/expression2/DSequenceExpr.cpp b/xo-expression2/src/expression2/DSequenceExpr.cpp index c5abf27b..5e449531 100644 --- a/xo-expression2/src/expression2/DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/DSequenceExpr.cpp @@ -4,8 +4,19 @@ **/ #include "DSequenceExpr.hpp" +#include "detail/IExpression_DSequenceExpr.hpp" +#include +#include +#include +#include +#include +#include namespace xo { + using xo::mm::AGCObject; + using xo::facet::FacetRegistry; + using xo::reflect::typeseq; + namespace scm { obj @@ -35,8 +46,8 @@ namespace xo { return expr; } - size_type - DSequenceExpr::size() const noexcept + auto + DSequenceExpr::size() const noexcept -> size_type { return expr_v_->size(); } @@ -44,7 +55,9 @@ namespace xo { obj DSequenceExpr::operator[](std::size_t i) const { - return (*expr_v_)[i]; + obj gco = (*expr_v_)[i]; + + return FacetRegistry::instance().variant(gco); } void @@ -64,7 +77,10 @@ namespace xo { this->expr_v_ = expr_2x_v; } - this->expr_v_->push_back(expr); + obj expr_gco + = FacetRegistry::instance().variant(expr); + + this->expr_v_->push_back(expr_gco); } void @@ -73,15 +89,16 @@ namespace xo { typeref_.resolve(td); } - void + bool DSequenceExpr::pretty(const ppindentinfo & ppii) const { using xo::print::ppstate; - ppstate * pps = ppii.pps(); - - xxx; + return ppii.pps()->pretty_struct + (ppii, + "DSequenceExpr"); } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp b/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp index 2098e050..c00e91dc 100644 --- a/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DConstant.cpp b/xo-expression2/src/expression2/IExpression_DConstant.cpp index 2d39c36d..0e91d27d 100644 --- a/xo-expression2/src/expression2/IExpression_DConstant.cpp +++ b/xo-expression2/src/expression2/IExpression_DConstant.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp index 3222eabd..ab0676a4 100644 --- a/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp index d913eaf0..78680310 100644 --- a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp b/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp index 273f5544..d9174ad2 100644 --- a/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp b/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp new file mode 100644 index 00000000..e269a114 --- /dev/null +++ b/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp @@ -0,0 +1,45 @@ +/** @file IExpression_DSequenceExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DSequenceExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DSequenceExpr.json5] +**/ + +#include "detail/IExpression_DSequenceExpr.hpp" + +namespace xo { + namespace scm { + auto + IExpression_DSequenceExpr::extype(const DSequenceExpr & self) noexcept -> exprtype + { + return self.extype(); + } + + auto + IExpression_DSequenceExpr::typeref(const DSequenceExpr & self) noexcept -> TypeRef + { + return self.typeref(); + } + + auto + IExpression_DSequenceExpr::valuetype(const DSequenceExpr & self) noexcept -> TypeDescr + { + return self.valuetype(); + } + + auto + IExpression_DSequenceExpr::assign_valuetype(DSequenceExpr & self, TypeDescr td) noexcept -> void + { + self.assign_valuetype(td); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IExpression_DSequenceExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/IExpression_DVariable.cpp b/xo-expression2/src/expression2/IExpression_DVariable.cpp index 2b4a007b..ca657c36 100644 --- a/xo-expression2/src/expression2/IExpression_DVariable.cpp +++ b/xo-expression2/src/expression2/IExpression_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp b/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp index b13b3f79..5d2553f0 100644 --- a/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp +++ b/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IGCObject_DVariable.cpp b/xo-expression2/src/expression2/IGCObject_DVariable.cpp index 4af0f906..8735b286 100644 --- a/xo-expression2/src/expression2/IGCObject_DVariable.cpp +++ b/xo-expression2/src/expression2/IGCObject_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp b/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp index 4f4a50d3..6c7c16a8 100644 --- a/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DConstant.cpp b/xo-expression2/src/expression2/IPrintable_DConstant.cpp index 1bacfb9d..02e8bde0 100644 --- a/xo-expression2/src/expression2/IPrintable_DConstant.cpp +++ b/xo-expression2/src/expression2/IPrintable_DConstant.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp b/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp index e8c6a799..31f8c554 100644 --- a/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp index a75cd6a4..ec68b9fc 100644 --- a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp b/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp index 12e6c22c..966c9d2f 100644 --- a/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp b/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp index dbd4887b..90f69407 100644 --- a/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp b/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp index a7b92af8..ef7cf037 100644 --- a/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp +++ b/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DVariable.cpp b/xo-expression2/src/expression2/IPrintable_DVariable.cpp index 75e673ae..edf79638 100644 --- a/xo-expression2/src/expression2/IPrintable_DVariable.cpp +++ b/xo-expression2/src/expression2/IPrintable_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp b/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp index 778cfdf4..3e5e465c 100644 --- a/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISymbolTable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-gc/CMakeLists.txt b/xo-gc/CMakeLists.txt index 2ad70af5..c0bf8418 100644 --- a/xo-gc/CMakeLists.txt +++ b/xo-gc/CMakeLists.txt @@ -30,6 +30,10 @@ xo_add_genfacet( # ---------------------------------------------------------------- +xo_add_genfacet_all(xo-gc-genfacet-all) + +# ---------------------------------------------------------------- + # must complete definition of expression lib before configuring examples add_subdirectory(src/gc) add_subdirectory(utest) diff --git a/xo-gc/idl/GCObject.json5 b/xo-gc/idl/GCObject.json5 index ef00b5d9..f2336678 100644 --- a/xo-gc/idl/GCObject.json5 +++ b/xo-gc/idl/GCObject.json5 @@ -6,11 +6,13 @@ "", "", ], + // extra includes in GCObject.hpp, if any + user_hpp_includes: [], + namespace1: "xo", + namespace2: "mm", pretext: [ "namespace xo { namespace mm { struct ACollector; }}", ], - namespace1: "xo", - namespace2: "mm", facet: "GCObject", detail_subdir: "detail", brief: "xxx", diff --git a/xo-gc/include/xo/gc/GCObject.hpp b/xo-gc/include/xo/gc/GCObject.hpp index 25834817..2eede6b3 100644 --- a/xo-gc/include/xo/gc/GCObject.hpp +++ b/xo-gc/include/xo/gc/GCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for facet .hpp file: @@ -18,4 +18,5 @@ #include "detail/IGCObject_Xfer.hpp" #include "detail/RGCObject.hpp" + /* end GCObject.hpp */ \ No newline at end of file diff --git a/xo-gc/include/xo/gc/detail/AGCObject.hpp b/xo-gc/include/xo/gc/detail/AGCObject.hpp index b7a5ffa3..ab6b4096 100644 --- a/xo-gc/include/xo/gc/detail/AGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/AGCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp b/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp index c930693f..e1b274a7 100644 --- a/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp b/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp index 655263bf..d25eb81e 100644 --- a/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-gc/include/xo/gc/detail/RGCObject.hpp b/xo-gc/include/xo/gc/detail/RGCObject.hpp index e54a2539..435d5a64 100644 --- a/xo-gc/include/xo/gc/detail/RGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/RGCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -40,6 +40,9 @@ public: ///@{ RGCObject() {} RGCObject(Object::DataPtr data) : Object{std::move(data)} {} + RGCObject(const AGCObject * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} ///@} /** @defgroup mm-gcobject-router-methods **/ @@ -54,7 +57,7 @@ public: return O::iface()->shallow_copy(O::data(), mm); } - // non-const methods + // non-const methods (still const in router!) size_type forward_children(obj gc) noexcept { return O::iface()->forward_children(O::data(), gc); } diff --git a/xo-object2/include/xo/object2/GCObjectConverter.hpp b/xo-object2/include/xo/object2/GCObjectConverter.hpp new file mode 100644 index 00000000..bf244f48 --- /dev/null +++ b/xo-object2/include/xo/object2/GCObjectConverter.hpp @@ -0,0 +1,158 @@ +/** @file GCObjectConverter.hpp + * + * @author Roland Conybeare, Nov 2025 + **/ + +#pragma once + +#include +#include +#include +//#include "xo/reflect/TaggedPtr.hpp" +#include + +namespace xo { + namespace scm { + /* Convert between xo::reflect::TaggedPtr and xo::Object for + * a particular wrapped c++ type + */ + struct Converter { + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using TaggedPtr = xo::reflect::TaggedPtr; + /** convert from some reflected T* @p src to + * obj dest + * using memory from allocator @p mm + **/ + using ConvertToObjectFn = obj (*)(obj mm, + TaggedPtr src); + /** convert from obj @p src to some refected T* @p dest + * using memory from allocator @p mm. + * + * NOTE: obj is gc-aware -> will likely reside in + * a collected memory region. + **/ + using ConvertFromObjectFn = TaggedPtr (*)(obj mm, + obj obj); + + public: + Converter() = default; + explicit Converter(ConvertToObjectFn to, + ConvertFromObjectFn from) + : cvt_to_object_{to}, + cvt_from_object_{from} + {} + + /** convert tagged pointer @p tp to new object, + * allocated via @p mm. + * + * Conversion will typically be for some specific type; + * see @ref ObjectConverter + **/ + ConvertToObjectFn cvt_to_object_ = nullptr; + + /** convert object to tagged pointer @p, + * allocated via @p mm. + * + * Conversion will typically be for some specific type; + * see @ref ObjectConverter + **/ + ConvertFromObjectFn cvt_from_object_ = nullptr; + }; + + /** @class ObjectConverter + * @brief Conversion to/from Object + * + * For some instance of type T: + * + * @code + * ObjectConverter & converters = ...; + * T x = ...; + * TaggedPtr tp = Reflect::make_tp(&x); + * TypeId tid = tp.td()->id(); + * + * const Converter * cvt = converters.cvt_.lookup(tid); + * + * if (cvt) { + * // cvt is a converter for T instances + * gp obj = (*(cvt->cvt_to_object_))(mm, + * @endcode + **/ + class ObjectConverter { + public: + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using Reflect = xo::reflect::Reflect; + using TaggedPtr = xo::reflect::TaggedPtr; + using TypeId = xo::reflect::TypeId; + + /** sets up standard conversions **/ + ObjectConverter(); + + /** singleton instance **/ + static const ObjectConverter & instance(); + + /** establish conversion: use @p fn to convert values of type @tparam T. **/ + template + void establish_conversion(Converter::ConvertToObjectFn to, + Converter::ConvertFromObjectFn from); + + /** convert tagged poitner @p tp to object. allocates memory only from @p mm. + * return nullptr if no converter available and @p throw_flag not set. + * throw exception if no converter available and @p throw_flag set. + **/ + obj tp_to_gco(obj mm, + TaggedPtr tp, + bool throw_flag) const; + + /** convert @p x to object. + * return converted object; if allocated, using only memory from @p mm. + * return nullptr if no converter available, and @p throw_flag not set. + * throw exception if no converter available, and @p throw_flag set. + **/ + template + obj to_gco(obj mm, const T & x, bool throw_flag); + + /** convert object @p obj to tagged pointer, with typeid @p target_id. + * Allocates memory only from @p mm. + * return null TaggedPtr if no converter available and @p throw_flag not set. + * Throw exception if no converter available and @p throw_flag set. + **/ + TaggedPtr tp_from_gco(obj mm, + obj obj, + TypeId target_type_id, + bool throw_flag) const; + + private: + /** expandable type-driven conversion table. + **/ + xo::reflect::TypeDrivenMap cvt_; + }; + + template + void + ObjectConverter::establish_conversion(Converter::ConvertToObjectFn to, + Converter::ConvertFromObjectFn from) + { + using xo::reflect::TypeDescrW; + using xo::reflect::Reflect; + + TypeDescrW td = Reflect::require(); + Converter * cvt = cvt_.require(td); + + *cvt = Converter(to, from); + } + + template + auto + ObjectConverter::to_gco(obj mm, const T & x, bool throw_flag) + -> obj + { + TaggedPtr x_tp = Reflect::make_tp(&x); + + return tp_to_gco(mm, x_tp, throw_flag); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end GCObjectConverter.hpp */ diff --git a/xo-object2/src/object2/GCObjectConverter.cpp b/xo-object2/src/object2/GCObjectConverter.cpp new file mode 100644 index 00000000..6f3f5b4a --- /dev/null +++ b/xo-object2/src/object2/GCObjectConverter.cpp @@ -0,0 +1,258 @@ +/** @file GCObjectConverter.cpp + * + * @author Roland Conybeare, Nov 2025 + **/ + +#include "GCObjectConverter.hpp" + +#include "DInteger.hpp" +#include "number/IGCObject_DInteger.hpp" + +#include "DFloat.hpp" +#include "number/IGCObject_DFloat.hpp" + +#include "DBoolean.hpp" +#include "boolean/IGCObject_DBoolean.hpp" + +#include "DString.hpp" +#include "string/IGCObject_DString.hpp" + +#include +#include +//#include "xo/alloc/Blob.hpp" + +namespace xo { + using xo::mm::AGCObject; + using xo::reflect::Reflect; + using xo::reflect::TaggedPtr; + using xo::reflect::TypeId; + using xo::facet::obj; + using xo::facet::typeseq; + using xo::mm::AAllocator; + + namespace scm { + namespace { + // DInteger <-> T + + template + obj + int_to_gco(obj mm, TaggedPtr src) + { + T * native = src.recover_native(); + + assert(native); + + return DInteger::box(mm, *native); + } + + template + TaggedPtr + gco_to_int(obj mm, + obj obj) + { + + /* mm cannot be GC allocator! + * That's Object-only + */ + + auto int_obj = xo::facet::obj::from(obj); //Integer::from(obj); + + if (!int_obj) { + throw std::runtime_error + (tostr("Object obj found where Integer expected", + xtag("obj", obj))); + } + + void * mem = mm.alloc(typeseq::id(), sizeof(T)); + + T * p = reinterpret_cast(mem); + + *p = int_obj.data()->value(); + + /* Note: + * retval invalidated when + * *mm cleared/recycled/collected + */ + + return Reflect::make_tp(p); + } + + // DFloat <-> T + + template + xo::facet::obj + float_to_gco(xo::facet::obj mm, + TaggedPtr src) + { + T * native = src.recover_native(); + + assert(native); + + return DFloat::box(mm, *native); + } + + template + TaggedPtr + gco_to_float(obj mm, obj obj) + { + auto float_obj = xo::facet::obj::from(obj); + + if (!float_obj) { + throw std::runtime_error + (tostr("Object obj found where Float expected", + xtag("obj", obj))); + } + + void * mem = mm.alloc(typeseq::id(), sizeof(T)); + + T * p = reinterpret_cast(mem); + + *p = float_obj.data()->value(); + + /* Note: + * retval invalidated when *mm cleared/recycled/collected + */ + + return Reflect::make_tp(p); + } + + // DBoolean <-> T + + obj + bool_to_gco(obj mm, TaggedPtr src) + { + bool * native = src.recover_native(); + + assert(native); + + return DBoolean::box(mm, *native); + } + + TaggedPtr + gco_to_bool(obj /*mm*/, + obj obj) + { + static bool s_true = true; + static bool s_false = false; + + auto bool_obj = xo::facet::obj::from(obj); + + if (!bool_obj) { + throw std::runtime_error + (tostr("Object obj found where Boolean expected", + xtag("obj", obj))); + } + + return Reflect::make_tp(bool_obj.data()->value() ? &s_true : &s_false); + } + + // DString <-> T + // w/ + // T = std::string + + obj + string_to_gco(obj mm, TaggedPtr src) + { + // try std::string.. + + std::string * native = src.recover_native(); + + assert(native); + + DString * dstr = DString::from_str(mm, *native); + + return xo::facet::obj(dstr); + } + + TaggedPtr + gco_to_string(obj mm, obj obj) + { + auto string_obj = xo::facet::obj::from(obj); + + if (!string_obj) { + throw std::runtime_error + (tostr("Object obj founcd where String expected", + xtag("obj", obj))); + } + + // still don't have impl for this + // Need regular std::allocator interface + // + + (void)mm; + assert(false); + } + } + + ObjectConverter::ObjectConverter() + { + this->establish_conversion(&int_to_gco, + &gco_to_int); + this->establish_conversion(&int_to_gco, + &gco_to_int); + + this->establish_conversion(&float_to_gco, + &gco_to_float); + + this->establish_conversion(&bool_to_gco, + &gco_to_bool); + + this->establish_conversion(&string_to_gco, + &gco_to_string); + } + + const ObjectConverter & + ObjectConverter::instance() { + static ObjectConverter s_instance; + + return s_instance; + } + + obj + ObjectConverter::tp_to_gco(obj mm, + TaggedPtr x_tp, + bool throw_flag) const + { + using xo::reflect::Reflect; + using xo::reflect::TaggedPtr; + + const Converter * cvt = cvt_.lookup(x_tp.td()); + + if (cvt) { + return (cvt->cvt_to_object_)(mm, x_tp); + } else { + if (throw_flag) { + throw std::runtime_error + (tostr("no to-object-converter available for instance of type", + xtag("id", x_tp.td()->id()), + xtag("name", x_tp.td()->short_name()))); + } + + return obj(); + } + } + + TaggedPtr + ObjectConverter::tp_from_gco(obj mm, + obj obj, + TypeId target_id, + bool throw_flag) const + { + const Converter * cvt = cvt_.lookup(target_id); + + if (cvt) { + return (cvt->cvt_from_object_)(mm, obj); + } else { + if (throw_flag) { + throw std::runtime_error + (tostr("no from-object-converter available for instance of type", + xtag("id", target_id))); + } + + return TaggedPtr::universal_null(); + } + } + } +} + +/* end GCObjectConverter.cpp */ From 805055bc743c676469b35ee0e2fc2db4efa1a088 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 12:40:50 -0500 Subject: [PATCH 136/258] xo-expression2: + GCObject,Printable facets for DSequenceExpr --- xo-expression2/CMakeLists.txt | 24 +++++++ .../idl/IGCObject_DSequenceExpr.json5 | 15 +++++ .../idl/IPrintable_DSequenceExpr.json5 | 13 ++++ .../include/xo/expression2/DSequenceExpr.hpp | 9 +++ .../include/xo/expression2/Expression.hpp | 2 +- .../include/xo/expression2/SymbolTable.hpp | 2 +- .../xo/expression2/detail/AExpression.hpp | 2 +- .../xo/expression2/detail/IExpression_Any.hpp | 2 +- .../detail/IExpression_DApplyExpr.hpp | 2 +- .../detail/IExpression_DConstant.hpp | 2 +- .../detail/IExpression_DDefineExpr.hpp | 2 +- .../detail/IExpression_DIfElseExpr.hpp | 2 +- .../detail/IExpression_DLambdaExpr.hpp | 2 +- .../detail/IExpression_DSequenceExpr.hpp | 2 +- .../detail/IExpression_DVariable.hpp | 2 +- .../expression2/detail/IExpression_Xfer.hpp | 2 +- .../detail/IGCObject_DSequenceExpr.hpp | 67 +++++++++++++++++++ .../detail/IGCObject_DUniqueString.hpp | 2 +- .../detail/IGCObject_DVariable.hpp | 2 +- .../detail/IPrintable_DApplyExpr.hpp | 2 +- .../detail/IPrintable_DConstant.hpp | 2 +- .../detail/IPrintable_DDefineExpr.hpp | 2 +- .../detail/IPrintable_DIfElseExpr.hpp | 2 +- .../detail/IPrintable_DLambdaExpr.hpp | 2 +- .../detail/IPrintable_DSequenceExpr.hpp | 62 +++++++++++++++++ .../detail/IPrintable_DUniqueString.hpp | 2 +- .../detail/IPrintable_DVariable.hpp | 2 +- .../xo/expression2/detail/RExpression.hpp | 2 +- .../xo/expression2/symtab/ASymbolTable.hpp | 2 +- .../symtab/IPrintable_DLocalSymtab.hpp | 2 +- .../expression2/symtab/ISymbolTable_Any.hpp | 2 +- .../symtab/ISymbolTable_DLocalSymtab.hpp | 2 +- .../expression2/symtab/ISymbolTable_Xfer.hpp | 2 +- .../xo/expression2/symtab/RSymbolTable.hpp | 2 +- xo-expression2/src/expression2/CMakeLists.txt | 2 + .../src/expression2/DSequenceExpr.cpp | 34 ++++++++++ .../expression2/IExpression_DApplyExpr.cpp | 2 +- .../src/expression2/IExpression_DConstant.cpp | 2 +- .../expression2/IExpression_DDefineExpr.cpp | 2 +- .../expression2/IExpression_DIfElseExpr.cpp | 2 +- .../expression2/IExpression_DLambdaExpr.cpp | 2 +- .../expression2/IExpression_DSequenceExpr.cpp | 2 +- .../src/expression2/IExpression_DVariable.cpp | 2 +- .../expression2/IGCObject_DSequenceExpr.cpp | 39 +++++++++++ .../expression2/IGCObject_DUniqueString.cpp | 2 +- .../src/expression2/IGCObject_DVariable.cpp | 2 +- .../src/expression2/IPrintable_DApplyExpr.cpp | 2 +- .../src/expression2/IPrintable_DConstant.cpp | 2 +- .../expression2/IPrintable_DDefineExpr.cpp | 2 +- .../expression2/IPrintable_DIfElseExpr.cpp | 2 +- .../expression2/IPrintable_DLambdaExpr.cpp | 2 +- .../expression2/IPrintable_DLocalSymtab.cpp | 2 +- .../expression2/IPrintable_DSequenceExpr.cpp | 28 ++++++++ .../expression2/IPrintable_DUniqueString.cpp | 2 +- .../src/expression2/IPrintable_DVariable.cpp | 2 +- .../expression2/ISymbolTable_DLocalSymtab.cpp | 2 +- .../expression2_register_facets.cpp | 9 +++ 57 files changed, 348 insertions(+), 46 deletions(-) create mode 100644 xo-expression2/idl/IGCObject_DSequenceExpr.json5 create mode 100644 xo-expression2/idl/IPrintable_DSequenceExpr.json5 create mode 100644 xo-expression2/include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IPrintable_DSequenceExpr.hpp create mode 100644 xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp create mode 100644 xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 4f7705ce..7cc83f11 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -250,6 +250,30 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-sequenceexpr + FACET_PKG xo_gc + FACET GCObject + REPR SequenceExpr + INPUT idl/IGCObject_DSequenceExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-sequenceexpr + FACET_PKG xo_printable2 + FACET Printable + REPR SequenceExpr + INPUT idl/IPrintable_DSequenceExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + # ---------------------------------------------------------------- # note: manual target; generated code committed to git diff --git a/xo-expression2/idl/IGCObject_DSequenceExpr.json5 b/xo-expression2/idl/IGCObject_DSequenceExpr.json5 new file mode 100644 index 00000000..d3bf4aef --- /dev/null +++ b/xo-expression2/idl/IGCObject_DSequenceExpr.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DSequenceExpr", + using_doxygen: true, + repr: "DSequenceExpr", + doc: [ "implement AGCObject for DSequenceExpr" ], +} diff --git a/xo-expression2/idl/IPrintable_DSequenceExpr.json5 b/xo-expression2/idl/IPrintable_DSequenceExpr.json5 new file mode 100644 index 00000000..34154a1e --- /dev/null +++ b/xo-expression2/idl/IPrintable_DSequenceExpr.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DSequenceExpr", + using_doxygen: true, + repr: "DSequenceExpr", + doc: [ "implement APrintable for DSequenceExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/DSequenceExpr.hpp index 7285ada8..c5bb6f16 100644 --- a/xo-expression2/include/xo/expression2/DSequenceExpr.hpp +++ b/xo-expression2/include/xo/expression2/DSequenceExpr.hpp @@ -22,6 +22,7 @@ namespace xo { **/ class DSequenceExpr { public: + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; using size_type = DArray::size_type; @@ -68,6 +69,14 @@ namespace xo { bool pretty(const ppindentinfo & ppii) const; ///@} + /** @defgroup scm-sequenceexpr-gcobject-facet gcobject facet methods **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DSequenceExpr * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} private: /** expression value always has type consistent with this description diff --git a/xo-expression2/include/xo/expression2/Expression.hpp b/xo-expression2/include/xo/expression2/Expression.hpp index 60e8a402..df4161a1 100644 --- a/xo-expression2/include/xo/expression2/Expression.hpp +++ b/xo-expression2/include/xo/expression2/Expression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/SymbolTable.hpp b/xo-expression2/include/xo/expression2/SymbolTable.hpp index 09fc04a8..26576ed6 100644 --- a/xo-expression2/include/xo/expression2/SymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/SymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/AExpression.hpp b/xo-expression2/include/xo/expression2/detail/AExpression.hpp index 10375114..e080ece8 100644 --- a/xo-expression2/include/xo/expression2/detail/AExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/AExpression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp index c92c2c4a..17545afb 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp index d577854f..c8952199 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp index 89c5044c..61b92e12 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp index f5585b60..3ac7fd49 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp index 03500a39..7d726dde 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp index 916b82ac..d488b6b3 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp index b010ac65..e66d657c 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DSequenceExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp index 95b1becb..6b9b702f 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp index 9f7356bc..fac8c541 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp new file mode 100644 index 00000000..5ffb5007 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DSequenceExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DSequenceExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DSequenceExpr.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DSequenceExpr.hpp" + +namespace xo { namespace scm { class IGCObject_DSequenceExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DSequenceExpr + **/ + class IGCObject_DSequenceExpr { + public: + /** @defgroup scm-gcobject-dsequenceexpr-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dsequenceexpr-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DSequenceExpr & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DSequenceExpr & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DSequenceExpr & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp index c95db10f..b971daea 100644 --- a/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp index aee612ea..24dc591f 100644 --- a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp index b7782166..c05e87e2 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp index 35535d80..a1e31382 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp index 758022a6..6d727d86 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp index e9cf67ff..fcf80fd5 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp index 45970bd8..64ab6af1 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DSequenceExpr.hpp new file mode 100644 index 00000000..eec1649c --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DSequenceExpr.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DSequenceExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DSequenceExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DSequenceExpr.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DSequenceExpr.hpp" + +namespace xo { namespace scm { class IPrintable_DSequenceExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DSequenceExpr + **/ + class IPrintable_DSequenceExpr { + public: + /** @defgroup scm-printable-dsequenceexpr-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dsequenceexpr-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DSequenceExpr & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp index 51afa9da..34c9da79 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp index a31ee97e..6e97451b 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/RExpression.hpp b/xo-expression2/include/xo/expression2/detail/RExpression.hpp index caf69fe0..4d717640 100644 --- a/xo-expression2/include/xo/expression2/detail/RExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/RExpression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp index 36d4c812..f0c6e10f 100644 --- a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp index d4481dca..c013e937 100644 --- a/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp index 6a119832..b642adb7 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp index 2c1816e4..72f409dd 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISymbolTable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp index 2333bb05..3d5f7221 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp index c72503cc..600ea4f8 100644 --- a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index ab10048e..4f929fa4 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -36,6 +36,8 @@ set(SELF_SRCS IPrintable_DIfElseExpr.cpp IExpression_DSequenceExpr.cpp + IGCObject_DSequenceExpr.cpp + IPrintable_DSequenceExpr.cpp DLocalSymtab.cpp DGlobalSymtab.cpp diff --git a/xo-expression2/src/expression2/DSequenceExpr.cpp b/xo-expression2/src/expression2/DSequenceExpr.cpp index 5e449531..73b9c2b5 100644 --- a/xo-expression2/src/expression2/DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/DSequenceExpr.cpp @@ -5,6 +5,7 @@ #include "DSequenceExpr.hpp" #include "detail/IExpression_DSequenceExpr.hpp" +#include #include #include #include @@ -99,6 +100,39 @@ namespace xo { "DSequenceExpr"); } + // gc hooks for IGCObject_DSequenceExpr + + std::size_t + DSequenceExpr::shallow_size() const noexcept + { + return sizeof(DSequenceExpr); + } + + DSequenceExpr * + DSequenceExpr::shallow_copy(obj mm) const noexcept + { + DSequenceExpr * copy = (DSequenceExpr *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DSequenceExpr::forward_children(obj gc) noexcept + { + // WARNING. + // if this proves problematic, + // may resort to obj for expr_v_ member + + auto iface = facet::impl_for(); + + gc.forward_inplace(&iface, (void**)&expr_v_); + + return shallow_size(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp b/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp index c00e91dc..2098e050 100644 --- a/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DConstant.cpp b/xo-expression2/src/expression2/IExpression_DConstant.cpp index 0e91d27d..2d39c36d 100644 --- a/xo-expression2/src/expression2/IExpression_DConstant.cpp +++ b/xo-expression2/src/expression2/IExpression_DConstant.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp index ab0676a4..3222eabd 100644 --- a/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp index 78680310..d913eaf0 100644 --- a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp b/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp index d9174ad2..273f5544 100644 --- a/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp b/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp index e269a114..cf00bc60 100644 --- a/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DSequenceExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IExpression_DVariable.cpp b/xo-expression2/src/expression2/IExpression_DVariable.cpp index ca657c36..2b4a007b 100644 --- a/xo-expression2/src/expression2/IExpression_DVariable.cpp +++ b/xo-expression2/src/expression2/IExpression_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp b/xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp new file mode 100644 index 00000000..474851ed --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DSequenceExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DSequenceExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DSequenceExpr.json5] +**/ + +#include "detail/IGCObject_DSequenceExpr.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DSequenceExpr::shallow_size(const DSequenceExpr & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DSequenceExpr::shallow_copy(const DSequenceExpr & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DSequenceExpr::forward_children(DSequenceExpr & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DSequenceExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp b/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp index 5d2553f0..b13b3f79 100644 --- a/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp +++ b/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IGCObject_DVariable.cpp b/xo-expression2/src/expression2/IGCObject_DVariable.cpp index 8735b286..4af0f906 100644 --- a/xo-expression2/src/expression2/IGCObject_DVariable.cpp +++ b/xo-expression2/src/expression2/IGCObject_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp b/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp index 6c7c16a8..4f4a50d3 100644 --- a/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DConstant.cpp b/xo-expression2/src/expression2/IPrintable_DConstant.cpp index 02e8bde0..1bacfb9d 100644 --- a/xo-expression2/src/expression2/IPrintable_DConstant.cpp +++ b/xo-expression2/src/expression2/IPrintable_DConstant.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp b/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp index 31f8c554..e8c6a799 100644 --- a/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp index ec68b9fc..a75cd6a4 100644 --- a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp b/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp index 966c9d2f..12e6c22c 100644 --- a/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp b/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp index 90f69407..dbd4887b 100644 --- a/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp b/xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp new file mode 100644 index 00000000..d07c5f08 --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DSequenceExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DSequenceExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DSequenceExpr.json5] +**/ + +#include "detail/IPrintable_DSequenceExpr.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DSequenceExpr::pretty(const DSequenceExpr & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DSequenceExpr.cpp */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp b/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp index ef7cf037..a7b92af8 100644 --- a/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp +++ b/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/IPrintable_DVariable.cpp b/xo-expression2/src/expression2/IPrintable_DVariable.cpp index edf79638..75e673ae 100644 --- a/xo-expression2/src/expression2/IPrintable_DVariable.cpp +++ b/xo-expression2/src/expression2/IPrintable_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp b/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp index 3e5e465c..778cfdf4 100644 --- a/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/ISymbolTable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 06ccc7d5..8109293a 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -27,6 +27,10 @@ #include #include +#include +#include +#include + #include #include @@ -77,6 +81,10 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -87,6 +95,7 @@ namespace xo { log && log(xtag("DApplyExpr.tseq", typeseq::id())); log && log(xtag("DLambdaExpr.tseq", typeseq::id())); log && log(xtag("DIfElseExpr.tseq", typeseq::id())); + log && log(xtag("DSequenceExpr.tseq", typeseq::id())); log && log(xtag("DLocalSymtab.tseq", typeseq::id())); From fc37c7325be9030cfb8e8bd9f4c9b874f1337aeb Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 12:55:45 -0500 Subject: [PATCH 137/258] xo-facet: genfacet: predictable path to genfacet in comment --- xo-facet/codegen/genfacet | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xo-facet/codegen/genfacet b/xo-facet/codegen/genfacet index ddea77e6..3aa114de 100755 --- a/xo-facet/codegen/genfacet +++ b/xo-facet/codegen/genfacet @@ -153,7 +153,7 @@ def gen_facet(env, router_facet_hpp_fname = f'{router_facet}.hpp' context = { - 'genfacet': __file__, + 'genfacet': 'xo-facet/codegen/genfacet', 'genfacet_input': idl_fname, 'using_dox': using_dox, 'impl_hpp_subdir': facet_detail_subdir, @@ -345,7 +345,7 @@ def gen_facet_impl(env, # ================================================================ context = { - 'genfacet': __file__, + 'genfacet': 'xo-facet/codegen/genfacet', 'genfacet_input': idl_fname, 'using_dox': using_dox, 'impl_hpp_subdir': output_impl_hpp_subdir, From 14d4aa5cf16cd021596df1b89de9e2879c7c833a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 12:56:45 -0500 Subject: [PATCH 138/258] xo-facet: genfacet: keep trailing newlines from .j2 templates --- xo-facet/codegen/genfacet | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xo-facet/codegen/genfacet b/xo-facet/codegen/genfacet index 3aa114de..c20689d3 100755 --- a/xo-facet/codegen/genfacet +++ b/xo-facet/codegen/genfacet @@ -482,7 +482,8 @@ def main(): env = Environment(loader = FileSystemLoader(template_dir), trim_blocks = True, - lstrip_blocks = True) + lstrip_blocks = True, + keep_trailing_newline = True) # custom filters. # A filter 'foo' provides ability to write '{{var | foo}}' to expand From 3a290a456cb148a3d3bcc07f0a08c58d4c193994 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 13:00:12 -0500 Subject: [PATCH 139/258] xo-expression2: stable generated facet files. --- xo-expression2/include/xo/expression2/Expression.hpp | 4 ++-- xo-expression2/include/xo/expression2/SymbolTable.hpp | 4 ++-- xo-expression2/include/xo/expression2/detail/AExpression.hpp | 4 ++-- .../include/xo/expression2/detail/IExpression_Any.hpp | 4 ++-- .../include/xo/expression2/detail/IExpression_DApplyExpr.hpp | 2 +- .../include/xo/expression2/detail/IExpression_DConstant.hpp | 2 +- .../include/xo/expression2/detail/IExpression_DDefineExpr.hpp | 2 +- .../include/xo/expression2/detail/IExpression_DIfElseExpr.hpp | 2 +- .../include/xo/expression2/detail/IExpression_DLambdaExpr.hpp | 2 +- .../xo/expression2/detail/IExpression_DSequenceExpr.hpp | 2 +- .../include/xo/expression2/detail/IExpression_DVariable.hpp | 2 +- .../include/xo/expression2/detail/IExpression_Xfer.hpp | 4 ++-- .../include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp | 2 +- .../include/xo/expression2/detail/IGCObject_DUniqueString.hpp | 2 +- .../include/xo/expression2/detail/IGCObject_DVariable.hpp | 2 +- .../include/xo/expression2/detail/IPrintable_DApplyExpr.hpp | 2 +- .../include/xo/expression2/detail/IPrintable_DConstant.hpp | 2 +- .../include/xo/expression2/detail/IPrintable_DDefineExpr.hpp | 2 +- .../include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp | 2 +- .../include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp | 2 +- .../xo/expression2/detail/IPrintable_DSequenceExpr.hpp | 2 +- .../xo/expression2/detail/IPrintable_DUniqueString.hpp | 2 +- .../include/xo/expression2/detail/IPrintable_DVariable.hpp | 2 +- xo-expression2/include/xo/expression2/detail/RExpression.hpp | 4 ++-- xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp | 4 ++-- .../include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp | 2 +- .../include/xo/expression2/symtab/ISymbolTable_Any.hpp | 4 ++-- .../xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp | 2 +- .../include/xo/expression2/symtab/ISymbolTable_Xfer.hpp | 4 ++-- xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp | 4 ++-- xo-expression2/src/expression2/IExpression_Any.cpp | 2 +- xo-expression2/src/expression2/IExpression_DApplyExpr.cpp | 4 ++-- xo-expression2/src/expression2/IExpression_DConstant.cpp | 4 ++-- xo-expression2/src/expression2/IExpression_DDefineExpr.cpp | 4 ++-- xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp | 4 ++-- xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp | 4 ++-- xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp | 4 ++-- xo-expression2/src/expression2/IExpression_DVariable.cpp | 4 ++-- xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp | 4 ++-- xo-expression2/src/expression2/IGCObject_DUniqueString.cpp | 4 ++-- xo-expression2/src/expression2/IGCObject_DVariable.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DConstant.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DUniqueString.cpp | 4 ++-- xo-expression2/src/expression2/IPrintable_DVariable.cpp | 4 ++-- xo-expression2/src/expression2/ISymbolTable_Any.cpp | 2 +- xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp | 4 ++-- 52 files changed, 82 insertions(+), 82 deletions(-) diff --git a/xo-expression2/include/xo/expression2/Expression.hpp b/xo-expression2/include/xo/expression2/Expression.hpp index df4161a1..6ed0e1f2 100644 --- a/xo-expression2/include/xo/expression2/Expression.hpp +++ b/xo-expression2/include/xo/expression2/Expression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for facet .hpp file: @@ -19,4 +19,4 @@ #include "detail/RExpression.hpp" -/* end Expression.hpp */ \ No newline at end of file +/* end Expression.hpp */ diff --git a/xo-expression2/include/xo/expression2/SymbolTable.hpp b/xo-expression2/include/xo/expression2/SymbolTable.hpp index 26576ed6..618cf2bf 100644 --- a/xo-expression2/include/xo/expression2/SymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/SymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for facet .hpp file: @@ -19,4 +19,4 @@ #include "symtab/RSymbolTable.hpp" -/* end SymbolTable.hpp */ \ No newline at end of file +/* end SymbolTable.hpp */ diff --git a/xo-expression2/include/xo/expression2/detail/AExpression.hpp b/xo-expression2/include/xo/expression2/detail/AExpression.hpp index e080ece8..59c83339 100644 --- a/xo-expression2/include/xo/expression2/detail/AExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/AExpression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -79,4 +79,4 @@ using IExpression_ImplType = xo::facet::FacetImplType; } /*namespace scm*/ } /*namespace xo*/ -/* AExpression.hpp */ \ No newline at end of file +/* AExpression.hpp */ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp index 17545afb..8ecb604d 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -86,4 +86,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo */ -/* IExpression_Any.hpp */ \ No newline at end of file +/* IExpression_Any.hpp */ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp index c8952199..49cce701 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DApplyExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp index 61b92e12..c6bbd819 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DConstant.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp index 3ac7fd49..135c7bb4 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DDefineExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp index 7d726dde..ca6e5705 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DIfElseExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp index d488b6b3..bdb074d9 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DLambdaExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp index e66d657c..6e0107dd 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DSequenceExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DSequenceExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp index 6b9b702f..cacd4be2 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp index fac8c541..b95b8526 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -89,4 +89,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo*/ -/* end IExpression_Xfer.hpp */ \ No newline at end of file +/* end IExpression_Xfer.hpp */ diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp index 5ffb5007..1f6b8deb 100644 --- a/xo-expression2/include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DSequenceExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DSequenceExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp index b971daea..398e3eed 100644 --- a/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DUniqueString.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp index 24dc591f..242f335f 100644 --- a/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp index c05e87e2..930846ce 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DApplyExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp index a1e31382..dc907b89 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DConstant.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp index 6d727d86..f399c743 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DDefineExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp index fcf80fd5..f4045504 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DIfElseExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp index 64ab6af1..c14cfefe 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DLambdaExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DSequenceExpr.hpp index eec1649c..a27ba9a4 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DSequenceExpr.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DSequenceExpr.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DSequenceExpr.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp index 34c9da79..a57039a8 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DUniqueString.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp index 6e97451b..10bbecca 100644 --- a/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DVariable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/detail/RExpression.hpp b/xo-expression2/include/xo/expression2/detail/RExpression.hpp index 4d717640..a14a2ee5 100644 --- a/xo-expression2/include/xo/expression2/detail/RExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/RExpression.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Expression.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -86,4 +86,4 @@ namespace xo { namespace facet { }; } } -/* end RExpression.hpp */ \ No newline at end of file +/* end RExpression.hpp */ diff --git a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp index f0c6e10f..50d6b4b7 100644 --- a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -72,4 +72,4 @@ using ISymbolTable_ImplType = xo::facet::FacetImplType; } /*namespace scm*/ } /*namespace xo*/ -/* ASymbolTable.hpp */ \ No newline at end of file +/* ASymbolTable.hpp */ diff --git a/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp index c013e937..729534c0 100644 --- a/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/symtab/IPrintable_DLocalSymtab.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp index b642adb7..1f4c9b2e 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -83,4 +83,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo */ -/* ISymbolTable_Any.hpp */ \ No newline at end of file +/* ISymbolTable_Any.hpp */ diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp index 72f409dd..9c9a2f0d 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DLocalSymtab.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISymbolTable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp index 3d5f7221..f19f6e2e 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -81,4 +81,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo*/ -/* end ISymbolTable_Xfer.hpp */ \ No newline at end of file +/* end ISymbolTable_Xfer.hpp */ diff --git a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp index 600ea4f8..f6375b37 100644 --- a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SymbolTable.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -79,4 +79,4 @@ namespace xo { namespace facet { }; } } -/* end RSymbolTable.hpp */ \ No newline at end of file +/* end RSymbolTable.hpp */ diff --git a/xo-expression2/src/expression2/IExpression_Any.cpp b/xo-expression2/src/expression2/IExpression_Any.cpp index 7f60e5af..9557e7e7 100644 --- a/xo-expression2/src/expression2/IExpression_Any.cpp +++ b/xo-expression2/src/expression2/IExpression_Any.cpp @@ -44,4 +44,4 @@ IExpression_Any::assign_valuetype(Opaque, TypeDescr) noexcept -> void } /*namespace scm*/ } /*namespace xo*/ -/* end IExpression_Any.cpp */ \ No newline at end of file +/* end IExpression_Any.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp b/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp index 2098e050..4ee365e0 100644 --- a/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DApplyExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -42,4 +42,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IExpression_DApplyExpr.cpp */ \ No newline at end of file +/* end IExpression_DApplyExpr.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DConstant.cpp b/xo-expression2/src/expression2/IExpression_DConstant.cpp index 2d39c36d..836a6aee 100644 --- a/xo-expression2/src/expression2/IExpression_DConstant.cpp +++ b/xo-expression2/src/expression2/IExpression_DConstant.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -42,4 +42,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IExpression_DConstant.cpp */ \ No newline at end of file +/* end IExpression_DConstant.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp index 3222eabd..f8f2429c 100644 --- a/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DDefineExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -42,4 +42,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IExpression_DDefineExpr.cpp */ \ No newline at end of file +/* end IExpression_DDefineExpr.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp index d913eaf0..947ca8de 100644 --- a/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DIfElseExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -42,4 +42,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IExpression_DIfElseExpr.cpp */ \ No newline at end of file +/* end IExpression_DIfElseExpr.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp b/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp index 273f5544..1b177c91 100644 --- a/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DLambdaExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -42,4 +42,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IExpression_DLambdaExpr.cpp */ \ No newline at end of file +/* end IExpression_DLambdaExpr.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp b/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp index cf00bc60..5ae4f3f7 100644 --- a/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/IExpression_DSequenceExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DSequenceExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -42,4 +42,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IExpression_DSequenceExpr.cpp */ \ No newline at end of file +/* end IExpression_DSequenceExpr.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DVariable.cpp b/xo-expression2/src/expression2/IExpression_DVariable.cpp index 2b4a007b..bea2a24e 100644 --- a/xo-expression2/src/expression2/IExpression_DVariable.cpp +++ b/xo-expression2/src/expression2/IExpression_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IExpression_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -42,4 +42,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IExpression_DVariable.cpp */ \ No newline at end of file +/* end IExpression_DVariable.cpp */ diff --git a/xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp b/xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp index 474851ed..54ad1bd5 100644 --- a/xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/IGCObject_DSequenceExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DSequenceExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DSequenceExpr.cpp */ \ No newline at end of file +/* end IGCObject_DSequenceExpr.cpp */ diff --git a/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp b/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp index b13b3f79..8238990f 100644 --- a/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp +++ b/xo-expression2/src/expression2/IGCObject_DUniqueString.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DUniqueString.cpp */ \ No newline at end of file +/* end IGCObject_DUniqueString.cpp */ diff --git a/xo-expression2/src/expression2/IGCObject_DVariable.cpp b/xo-expression2/src/expression2/IGCObject_DVariable.cpp index 4af0f906..ecc403ef 100644 --- a/xo-expression2/src/expression2/IGCObject_DVariable.cpp +++ b/xo-expression2/src/expression2/IGCObject_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DVariable.cpp */ \ No newline at end of file +/* end IGCObject_DVariable.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp b/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp index 4f4a50d3..06b7b752 100644 --- a/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DApplyExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DApplyExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DApplyExpr.cpp */ \ No newline at end of file +/* end IPrintable_DApplyExpr.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DConstant.cpp b/xo-expression2/src/expression2/IPrintable_DConstant.cpp index 1bacfb9d..57bd271f 100644 --- a/xo-expression2/src/expression2/IPrintable_DConstant.cpp +++ b/xo-expression2/src/expression2/IPrintable_DConstant.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DConstant.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DConstant.cpp */ \ No newline at end of file +/* end IPrintable_DConstant.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp b/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp index e8c6a799..2774e610 100644 --- a/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DDefineExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DDefineExpr.cpp */ \ No newline at end of file +/* end IPrintable_DDefineExpr.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp index a75cd6a4..52694cb5 100644 --- a/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DIfElseExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DIfElseExpr.cpp */ \ No newline at end of file +/* end IPrintable_DIfElseExpr.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp b/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp index 12e6c22c..049a81c8 100644 --- a/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DLambdaExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DLambdaExpr.cpp */ \ No newline at end of file +/* end IPrintable_DLambdaExpr.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp b/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp index dbd4887b..0e178e09 100644 --- a/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/IPrintable_DLocalSymtab.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DLocalSymtab.cpp */ \ No newline at end of file +/* end IPrintable_DLocalSymtab.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp b/xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp index d07c5f08..a3471232 100644 --- a/xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/IPrintable_DSequenceExpr.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DSequenceExpr.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DSequenceExpr.cpp */ \ No newline at end of file +/* end IPrintable_DSequenceExpr.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp b/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp index a7b92af8..5f490bd9 100644 --- a/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp +++ b/xo-expression2/src/expression2/IPrintable_DUniqueString.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DUniqueString.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DUniqueString.cpp */ \ No newline at end of file +/* end IPrintable_DUniqueString.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DVariable.cpp b/xo-expression2/src/expression2/IPrintable_DVariable.cpp index 75e673ae..53364de5 100644 --- a/xo-expression2/src/expression2/IPrintable_DVariable.cpp +++ b/xo-expression2/src/expression2/IPrintable_DVariable.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DVariable.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DVariable.cpp */ \ No newline at end of file +/* end IPrintable_DVariable.cpp */ diff --git a/xo-expression2/src/expression2/ISymbolTable_Any.cpp b/xo-expression2/src/expression2/ISymbolTable_Any.cpp index 7c811253..95718429 100644 --- a/xo-expression2/src/expression2/ISymbolTable_Any.cpp +++ b/xo-expression2/src/expression2/ISymbolTable_Any.cpp @@ -38,4 +38,4 @@ ISymbolTable_Any::_valid } /*namespace scm*/ } /*namespace xo*/ -/* end ISymbolTable_Any.cpp */ \ No newline at end of file +/* end ISymbolTable_Any.cpp */ diff --git a/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp b/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp index 778cfdf4..b67ada5c 100644 --- a/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/ISymbolTable_DLocalSymtab.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISymbolTable_DLocalSymtab.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -31,4 +31,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISymbolTable_DLocalSymtab.cpp */ \ No newline at end of file +/* end ISymbolTable_DLocalSymtab.cpp */ From cd369cf2e8eb595f682ff4f8c33ff6236f59743a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 18:28:25 -0500 Subject: [PATCH 140/258] xo-reader2 xo-expression2: + DSequenceSsm ++ utest --- xo-expression2/CMakeLists.txt | 24 ++++++ xo-expression2/idl/IGCObject_DConstant.json5 | 15 ++++ .../idl/IGCObject_DIfElseExpr.json5 | 15 ++++ .../include/xo/expression2/DConstant.hpp | 12 ++- .../include/xo/expression2/DIfElseExpr.hpp | 10 +++ .../detail/IGCObject_DConstant.hpp | 67 ++++++++++++++++ .../detail/IGCObject_DIfElseExpr.hpp | 67 ++++++++++++++++ xo-expression2/src/expression2/CMakeLists.txt | 2 + xo-expression2/src/expression2/DConstant.cpp | 25 ++++++ .../src/expression2/DIfElseExpr.cpp | 41 ++++++++++ .../src/expression2/IGCObject_DConstant.cpp | 39 ++++++++++ .../src/expression2/IGCObject_DIfElseExpr.cpp | 39 ++++++++++ .../expression2_register_facets.cpp | 11 ++- .../expression2_register_types.cpp | 21 ++++- xo-reader2/CMakeLists.txt | 28 ++++++- xo-reader2/idl/IPrintable_DSequenceSsm.json5 | 13 ++++ .../ISyntaxStateMachine_DSequenceSsm.json5 | 13 ++++ .../include/xo/reader2/DExpectExprSsm.hpp | 6 ++ xo-reader2/include/xo/reader2/DIfElseSsm.hpp | 21 +---- .../include/xo/reader2/DSequenceSsm.hpp | 56 ++++++++++---- .../include/xo/reader2/SyntaxStateMachine.hpp | 4 +- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 4 +- .../xo/reader2/ssm/IPrintable_DDefineSsm.hpp | 2 +- .../reader2/ssm/IPrintable_DExpectExprSsm.hpp | 2 +- .../ssm/IPrintable_DExpectFormalArgSsm.hpp | 2 +- .../IPrintable_DExpectFormalArglistSsm.hpp | 2 +- .../ssm/IPrintable_DExpectSymbolSsm.hpp | 2 +- .../reader2/ssm/IPrintable_DExpectTypeSsm.hpp | 2 +- .../reader2/ssm/IPrintable_DExprSeqState.hpp | 2 +- .../xo/reader2/ssm/IPrintable_DIfElseSsm.hpp | 2 +- .../xo/reader2/ssm/IPrintable_DLambdaSsm.hpp | 2 +- .../reader2/ssm/IPrintable_DProgressSsm.hpp | 2 +- .../reader2/ssm/IPrintable_DSequenceSsm.hpp | 62 +++++++++++++++ .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 4 +- .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 +- .../ISyntaxStateMachine_DExpectExprSsm.hpp | 2 +- ...SyntaxStateMachine_DExpectFormalArgSsm.hpp | 2 +- ...axStateMachine_DExpectFormalArglistSsm.hpp | 2 +- .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 +- .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 +- .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 2 +- .../ssm/ISyntaxStateMachine_DIfElseSsm.hpp | 2 +- .../ssm/ISyntaxStateMachine_DLambdaSsm.hpp | 2 +- .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 +- .../ssm/ISyntaxStateMachine_DSequenceSsm.hpp | 77 +++++++++++++++++++ .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 4 +- .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 4 +- .../include/xo/reader2/syntaxstatetype.hpp | 27 ++++--- xo-reader2/src/reader2/CMakeLists.txt | 4 + xo-reader2/src/reader2/DExpectExprSsm.cpp | 28 ++++--- xo-reader2/src/reader2/DLambdaSsm.cpp | 2 +- xo-reader2/src/reader2/DSequenceSsm.cpp | 72 +++++++++++++---- .../src/reader2/IPrintable_DDefineSsm.cpp | 4 +- .../src/reader2/IPrintable_DExpectExprSsm.cpp | 4 +- .../IPrintable_DExpectFormalArgSsm.cpp | 4 +- .../IPrintable_DExpectFormalArglistSsm.cpp | 4 +- .../reader2/IPrintable_DExpectSymbolSsm.cpp | 4 +- .../src/reader2/IPrintable_DExpectTypeSsm.cpp | 4 +- .../src/reader2/IPrintable_DExprSeqState.cpp | 4 +- .../src/reader2/IPrintable_DIfElseSsm.cpp | 4 +- .../src/reader2/IPrintable_DLambdaSsm.cpp | 4 +- .../src/reader2/IPrintable_DProgressSsm.cpp | 4 +- .../src/reader2/IPrintable_DSequenceSsm.cpp | 28 +++++++ .../src/reader2/ISyntaxStateMachine_Any.cpp | 2 +- .../ISyntaxStateMachine_DDefineSsm.cpp | 4 +- .../ISyntaxStateMachine_DExpectExprSsm.cpp | 4 +- ...SyntaxStateMachine_DExpectFormalArgSsm.cpp | 4 +- ...axStateMachine_DExpectFormalArglistSsm.cpp | 4 +- .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 4 +- .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 4 +- .../ISyntaxStateMachine_DExprSeqState.cpp | 4 +- .../ISyntaxStateMachine_DIfElseSsm.cpp | 4 +- .../ISyntaxStateMachine_DLambdaSsm.cpp | 4 +- .../ISyntaxStateMachine_DProgressSsm.cpp | 4 +- .../ISyntaxStateMachine_DSequenceSsm.cpp | 69 +++++++++++++++++ .../src/reader2/reader2_register_facets.cpp | 4 + xo-reader2/src/reader2/syntaxstatetype.cpp | 18 +++-- xo-reader2/utest/SchematikaParser.test.cpp | 2 +- 78 files changed, 900 insertions(+), 160 deletions(-) create mode 100644 xo-expression2/idl/IGCObject_DConstant.json5 create mode 100644 xo-expression2/idl/IGCObject_DIfElseExpr.json5 create mode 100644 xo-expression2/include/xo/expression2/detail/IGCObject_DConstant.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IGCObject_DIfElseExpr.hpp create mode 100644 xo-expression2/src/expression2/IGCObject_DConstant.cpp create mode 100644 xo-expression2/src/expression2/IGCObject_DIfElseExpr.cpp create mode 100644 xo-reader2/idl/IPrintable_DSequenceSsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DSequenceSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp create mode 100644 xo-reader2/src/reader2/IPrintable_DSequenceSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 7cc83f11..a9060ce1 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -82,6 +82,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-constant + FACET_PKG xo_gc + FACET GCObject + REPR Constant + INPUT idl/IGCObject_DConstant.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-constant @@ -224,6 +236,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-ifelseexpr + FACET_PKG xo_gc + FACET GCObject + REPR IfElseExpr + INPUT idl/IGCObject_DIfElseExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-ifelseexpr diff --git a/xo-expression2/idl/IGCObject_DConstant.json5 b/xo-expression2/idl/IGCObject_DConstant.json5 new file mode 100644 index 00000000..f67c5b52 --- /dev/null +++ b/xo-expression2/idl/IGCObject_DConstant.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DConstant", + using_doxygen: true, + repr: "DConstant", + doc: [ "implement AGCObject for DConstant" ], +} diff --git a/xo-expression2/idl/IGCObject_DIfElseExpr.json5 b/xo-expression2/idl/IGCObject_DIfElseExpr.json5 new file mode 100644 index 00000000..1c5d0661 --- /dev/null +++ b/xo-expression2/idl/IGCObject_DIfElseExpr.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DIfElseExpr", + using_doxygen: true, + repr: "DIfElseExpr", + doc: [ "implement AGCObject for DIfElseExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/DConstant.hpp b/xo-expression2/include/xo/expression2/DConstant.hpp index 1046176a..0c57f924 100644 --- a/xo-expression2/include/xo/expression2/DConstant.hpp +++ b/xo-expression2/include/xo/expression2/DConstant.hpp @@ -8,8 +8,9 @@ #include "Expression.hpp" #include "TypeRef.hpp" #include "exprtype.hpp" -#include +#include #include +#include namespace xo { namespace scm { @@ -20,6 +21,7 @@ namespace xo { public: using TaggedPtr = xo::reflect::TaggedPtr; using TypeDescr = xo::reflect::TypeDescr; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using typeseq = xo::reflect::typeseq; @@ -56,6 +58,14 @@ namespace xo { TypeDescr valuetype() const noexcept { return typeref_.td(); } void assign_valuetype(TypeDescr td) noexcept { typeref_.resolve(td); } + ///@} + /** @defgroup scm-constant-gcobject-facet **/ + ///@{ + + size_t shallow_size() const noexcept; + DConstant * shallow_copy(obj mm) const noexcept; + size_t forward_children(obj gc) noexcept; + ///@} /** @defgroup scm-constant-printable-facet **/ ///@{ diff --git a/xo-expression2/include/xo/expression2/DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/DIfElseExpr.hpp index 8222834a..3b7b07e2 100644 --- a/xo-expression2/include/xo/expression2/DIfElseExpr.hpp +++ b/xo-expression2/include/xo/expression2/DIfElseExpr.hpp @@ -8,6 +8,7 @@ #include "Expression.hpp" #include "TypeRef.hpp" #include "exprtype.hpp" +#include #include //#include #include @@ -21,6 +22,7 @@ namespace xo { **/ class DIfElseExpr { public: + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; @@ -93,6 +95,14 @@ namespace xo { bool pretty(const ppindentinfo & ppii) const; ///@} + /** @defgroup scm-ifelseexpr-gcobject-facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DIfElseExpr * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} #ifdef NOT_YET virtual std::set get_free_variables() const override { diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DConstant.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DConstant.hpp new file mode 100644 index 00000000..871f9c91 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DConstant.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DConstant.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DConstant.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DConstant.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DConstant.hpp" + +namespace xo { namespace scm { class IGCObject_DConstant; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DConstant + **/ + class IGCObject_DConstant { + public: + /** @defgroup scm-gcobject-dconstant-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dconstant-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DConstant & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DConstant & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DConstant & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DIfElseExpr.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DIfElseExpr.hpp new file mode 100644 index 00000000..6a47d9b8 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DIfElseExpr.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DIfElseExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DIfElseExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DIfElseExpr.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DIfElseExpr.hpp" + +namespace xo { namespace scm { class IGCObject_DIfElseExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DIfElseExpr + **/ + class IGCObject_DIfElseExpr { + public: + /** @defgroup scm-gcobject-difelseexpr-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-difelseexpr-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DIfElseExpr & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DIfElseExpr & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DIfElseExpr & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 4f929fa4..4f3d63c1 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -17,6 +17,7 @@ set(SELF_SRCS IExpression_Any.cpp IExpression_DConstant.cpp + IGCObject_DConstant.cpp IPrintable_DConstant.cpp IExpression_DVariable.cpp @@ -33,6 +34,7 @@ set(SELF_SRCS IPrintable_DLambdaExpr.cpp IExpression_DIfElseExpr.cpp + IGCObject_DIfElseExpr.cpp IPrintable_DIfElseExpr.cpp IExpression_DSequenceExpr.cpp diff --git a/xo-expression2/src/expression2/DConstant.cpp b/xo-expression2/src/expression2/DConstant.cpp index f03fe625..f1f560be 100644 --- a/xo-expression2/src/expression2/DConstant.cpp +++ b/xo-expression2/src/expression2/DConstant.cpp @@ -71,6 +71,31 @@ namespace xo { return nullptr; } + std::size_t + DConstant::shallow_size() const noexcept + { + return sizeof(DConstant); + } + + DConstant * + DConstant::shallow_copy(obj mm) const noexcept + { + DConstant * copy = (DConstant *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DConstant::forward_children(obj gc) noexcept + { + gc.forward_inplace(value_.iface(), (void **)&(value_.data_)); + + return shallow_size(); + } + bool DConstant::pretty(const ppindentinfo & ppii) const { diff --git a/xo-expression2/src/expression2/DIfElseExpr.cpp b/xo-expression2/src/expression2/DIfElseExpr.cpp index d858dfab..e1d5e70e 100644 --- a/xo-expression2/src/expression2/DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/DIfElseExpr.cpp @@ -5,11 +5,13 @@ #include "DIfElseExpr.hpp" #include "detail/IExpression_DIfElseExpr.hpp" +#include #include #include #include namespace xo { + using xo::mm::AGCObject; using xo::print::APrintable; using xo::reflect::typeseq; using xo::facet::FacetRegistry; @@ -120,6 +122,45 @@ namespace xo { } } + // GCObject facet + + std::size_t + DIfElseExpr::shallow_size() const noexcept + { + return sizeof(DIfElseExpr); + } + + DIfElseExpr * + DIfElseExpr::shallow_copy(obj mm) const noexcept + { + DIfElseExpr * copy = (DIfElseExpr *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DIfElseExpr::forward_children(obj gc) noexcept + { + // GC needs to locate AGCObject iface for each member. + { + auto gco = FacetRegistry::instance().variant(test_); + gc.forward_inplace(gco.iface(), (void **)&(test_.data_)); + } + { + auto gco = FacetRegistry::instance().variant(when_true_); + gc.forward_inplace(gco.iface(), (void **)&(when_true_.data_)); + } + { + auto gco = FacetRegistry::instance().variant(when_false_); + gc.forward_inplace(gco.iface(), (void **)&(when_false_.data_)); + } + + return shallow_size(); + } + // ---------------------------------------------------------------- #ifdef NOPE diff --git a/xo-expression2/src/expression2/IGCObject_DConstant.cpp b/xo-expression2/src/expression2/IGCObject_DConstant.cpp new file mode 100644 index 00000000..ea3be262 --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DConstant.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DConstant.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DConstant.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DConstant.json5] +**/ + +#include "detail/IGCObject_DConstant.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DConstant::shallow_size(const DConstant & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DConstant::shallow_copy(const DConstant & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DConstant::forward_children(DConstant & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DConstant.cpp */ diff --git a/xo-expression2/src/expression2/IGCObject_DIfElseExpr.cpp b/xo-expression2/src/expression2/IGCObject_DIfElseExpr.cpp new file mode 100644 index 00000000..8a0f03d5 --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DIfElseExpr.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DIfElseExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DIfElseExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DIfElseExpr.json5] +**/ + +#include "detail/IGCObject_DIfElseExpr.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DIfElseExpr::shallow_size(const DIfElseExpr & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DIfElseExpr::shallow_copy(const DIfElseExpr & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DIfElseExpr::forward_children(DIfElseExpr & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DIfElseExpr.cpp */ diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 8109293a..26869d50 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -9,6 +9,7 @@ #include #include +//#include #include #include @@ -16,15 +17,19 @@ #include #include +#include #include #include +//#include #include #include +//#include #include #include +#include #include #include @@ -32,6 +37,7 @@ #include #include +//#include #include #include @@ -60,9 +66,11 @@ namespace xo { // +- DefineExpr // +- ApplyExpr // +- LambdaExpr - // \- IfElseExpr + // +- IfElseExpr + // \- SequenceExpr FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -79,6 +87,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); diff --git a/xo-expression2/src/expression2/expression2_register_types.cpp b/xo-expression2/src/expression2/expression2_register_types.cpp index 2b8aadcf..b3dd21f8 100644 --- a/xo-expression2/src/expression2/expression2_register_types.cpp +++ b/xo-expression2/src/expression2/expression2_register_types.cpp @@ -5,11 +5,18 @@ #include "expression2_register_types.hpp" +#include "detail/IGCObject_DConstant.hpp" +#include "detail/IGCObject_DVariable.hpp" +//#include "detail/IGCObject_DDefineExpr.hpp" // when avail +//#include "detail/IGCObject_DApplyExpr.hpp" // when avail +//#include "detail/IGCObject_DLambdaExpr.hpp" // when avail +#include "detail/IGCObject_DIfElseExpr.hpp" +#include "detail/IGCObject_DSequenceExpr.hpp" +//#include "detail/IGCObject_DLocalSymtab.hpp" // when avail #include "detail/IGCObject_DUniqueString.hpp" -//#include "detail/IPrintable_DUniqueString.hpp" +//#include "detail/IPrintable_DUniqueString.hpp" // when avail -//#include #include namespace xo { @@ -27,6 +34,16 @@ namespace xo { bool ok = true; + ok &= gc.install_type(impl_for()); + ok &= gc.install_type(impl_for()); + //ok &= gc.install_type(impl_for()); // when avail + //ok &= gc.install_type(impl_for()); // when avail + //ok &= gc.install_type(impl_for()); // when avail + ok &= gc.install_type(impl_for()); + ok &= gc.install_type(impl_for()); + + //ok &= gc.install_type(impl_for()); // when avail + ok &= gc.install_type(impl_for()); return ok; diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 79d692ba..c936619f 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -183,7 +183,7 @@ xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-printable-ifelsessm FACET_PKG xo_printable2 FACET Printable - REPR Ifelsessm + REPR IfElseSsm INPUT idl/IPrintable_DIfElseSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm @@ -192,6 +192,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-sequencessm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR SequenceSsm + INPUT idl/ISyntaxStateMachine_DSequenceSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-sequencessm + FACET_PKG xo_printable2 + FACET Printable + REPR SequenceSsm + INPUT idl/IPrintable_DSequenceSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-expectsymbolssm diff --git a/xo-reader2/idl/IPrintable_DSequenceSsm.json5 b/xo-reader2/idl/IPrintable_DSequenceSsm.json5 new file mode 100644 index 00000000..a217b24c --- /dev/null +++ b/xo-reader2/idl/IPrintable_DSequenceSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DSequenceSsm", + using_doxygen: true, + repr: "DSequenceSsm", + doc: [ "implement APrintable for DSequenceSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 new file mode 100644 index 00000000..7538c09b --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DSequenceSsm", + using_doxygen: true, + repr: "DSequenceSsm", + doc: [ "implement ASyntaxStateMachine for DSequenceSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 4b407881..6b2fe30f 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -46,6 +46,12 @@ namespace xo { /** @defgroup scm-expectexpr-methods general methods **/ ///@{ + /** update state for this syntax on incoming leftbrace token @p tk, + * with overall parser state in @p p_psm + **/ + void on_leftbrace_token(const Token & tk, + ParserStateMachine * p_psm); + /** step state machine for this syntax on incoming boolean literal token @p tkk * with overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp index 43f6d4b5..5e6d4d8c 100644 --- a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp @@ -166,27 +166,8 @@ namespace xo { ///@} #ifdef NOT_YET - // ----- inherited from exprstate ----- - - virtual const char * get_expect_str() const override; - - virtual void on_if_token(const token_type & tk, - parserstatemachine * p_psm) override; - virtual void on_then_token(const token_type & tk, - parserstatemachine * p_psm) override; - virtual void on_else_token(const token_type & tk, - parserstatemachine * p_psm) override; - virtual void on_semicolon_token(const token_type & tk, - parserstatemachine * p_psm) override; virtual void on_rightbrace_token(const token_type & tk, parserstatemachine * p_psm) override; - - virtual void on_expr(bp expr, - parserstatemachine * p_psm) override; - virtual void on_expr_with_semicolon(bp expr, - parserstatemachine * p_psm) override; - - virtual void print(std::ostream & os) const override; #endif private: @@ -203,6 +184,8 @@ namespace xo { ifexprstatetype ifstate_ = ifexprstatetype::invalid; /** scaffold ifelse-expression here. * This will eventually be the output of this ssm + * + * TODO: can use DIfElseExpr* here. See xo-object2//DList **/ obj if_expr_; diff --git a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp index 8d936254..6423ee29 100644 --- a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp +++ b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp @@ -6,7 +6,7 @@ #pragma once #include "DSyntaxStateMachine.hpp" -//#include "exprstate.hpp" +#include namespace xo { namespace scm { class Sequence; } @@ -15,21 +15,29 @@ namespace xo { namespace scm { class DSequenceSsm : public DSyntaxStateMachine { public: - using Sequence = xo::scm::Sequence; - using Lambda = xo::scm::Lambda; + //using Sequence = xo::scm::Sequence; + //using Lambda = xo::scm::Lambda; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; public: - const char * ssm_classname() const noexcept { return "DSequenceSsm"; } + static const char * ssm_classname() { return "DSequenceSsm"; } -#ifdef NOT_YET /** start parsing a sequence-expr. * input begins with first expression in the sequence. **/ - static void start(parserstatemachine * p_psm); + static void start(ParserStateMachine * p_psm); - /** named ctor idiom **/ - static std::unique_ptr make(); + /** create instance using memory from @p parser_mm **/ + static obj make(DArena & parser_mm, + obj expr_mm); + /** create instance using memory from @p parser_mm **/ + static DSequenceSsm * _make(DArena & parser_mm, + obj expr_mm); + +#ifdef NOT_YET virtual void on_expr(bp expr, parserstatemachine * p_psm) override; virtual void on_expr_with_semicolon(bp expr, @@ -37,18 +45,34 @@ namespace xo { virtual void on_rightbrace_token(const token_type & tk, parserstatemachine * p_psm) override; - - virtual void print(std::ostream & os) const override; - virtual bool pretty_print(const xo::print::ppindentinfo & ppii) const override; #endif - private: - DSequenceSsm(); + /** @defgroup scm-sequencessm-syntaxstatemachine-facet ssm facet **/ + ///@{ + + /** indentifies this state machine **/ + syntaxstatetype ssm_type() const noexcept; + + /** mnemonic for syntax sequence ssm expects given current state **/ + std::string_view get_expect_str() const noexcept; + + ///@} + /** @defgroup scm-sequencessm-printable-facet printable facet **/ + ///@{ + + /** pretty printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} private: - /** will build SequenceExpr from in-order contents of this array **/ - DArray * expr_v_; - //std::vector> expr_v_; + explicit DSequenceSsm(DSequenceExpr * seq_expr); + + private: + /** scaffold sequence-expression here. + * This will eventually be the output of this ssm + **/ + DSequenceExpr * seq_expr_ = nullptr; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp index deda9e1d..c9c37ee1 100644 --- a/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for facet .hpp file: @@ -19,4 +19,4 @@ #include "ssm/RSyntaxStateMachine.hpp" -/* end SyntaxStateMachine.hpp */ \ No newline at end of file +/* end SyntaxStateMachine.hpp */ diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index b9df6e6d..b6475877 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -90,4 +90,4 @@ using ISyntaxStateMachine_ImplType = xo::facet::FacetImplType +#include +#include "DSequenceSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DSequenceSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DSequenceSsm + **/ + class IPrintable_DSequenceSsm { + public: + /** @defgroup scm-printable-dsequencessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dsequencessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DSequenceSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index e239c46b..9cf16408 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -91,4 +91,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo */ -/* ISyntaxStateMachine_Any.hpp */ \ No newline at end of file +/* ISyntaxStateMachine_Any.hpp */ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index 42616a38..c34a66a5 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DDefineSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 53669967..7280b78e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectExprSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp index 99d6c9a9..acf84462 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp index 570ee3a4..4cf9e3ff 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 2003db8a..1a33685f 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index acb752fe..054c03f1 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExpectTypeSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index 3c160d00..cd241d52 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp index 462172d2..65f585af 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DIfElseSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp index fa0cb0a2..6d931744 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DLambdaSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index ddd0c06e..27ec4f53 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISyntaxStateMachine_DProgressSsm.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp new file mode 100644 index 00000000..da541414 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp @@ -0,0 +1,77 @@ +/** @file ISyntaxStateMachine_DSequenceSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DSequenceSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DSequenceSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DSequenceSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DSequenceSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DSequenceSsm + **/ + class ISyntaxStateMachine_DSequenceSsm { + public: + /** @defgroup scm-syntaxstatemachine-dsequencessm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dsequencessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DSequenceSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DSequenceSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DSequenceSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DSequenceSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DSequenceSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DSequenceSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DSequenceSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DSequenceSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DSequenceSsm & self, obj expr, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index e89357ab..5fffca24 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -105,4 +105,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo*/ -/* end ISyntaxStateMachine_Xfer.hpp */ \ No newline at end of file +/* end ISyntaxStateMachine_Xfer.hpp */ diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 0e2b8636..b84082d2 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/SyntaxStateMachine.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -101,4 +101,4 @@ namespace xo { namespace facet { }; } } -/* end RSyntaxStateMachine.hpp */ \ No newline at end of file +/* end RSyntaxStateMachine.hpp */ diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 2d87aa25..a5b4b563 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -18,6 +18,21 @@ namespace xo { enum class syntaxstatetype { invalid = -1, + /** handle define-expression. See @ref DDefineSsm **/ + defexpr, + + /** handle lambda-expression. See @ref DLambdaSsm **/ + lambdaexpr, + + /** handle ifelse-expression. See @ref DIfElseSsm **/ + ifelseexpr, + + /** handle sequence-expression. See @ref DSequenceSsm **/ + sequence, + + /** rhs expression. state exists to achieve 1-token lookahead **/ + progress, + /** toplevel of some translation unit. See @ref DExprSeqState **/ expect_toplevel_expression_sequence, @@ -36,18 +51,6 @@ namespace xo { /** expecting a rhs expression. See @ref DExpectExprSsm **/ expect_rhs_expression, - /** handle define-expression. See @ref DDefineSsm **/ - defexpr, - - /** handle lambda-expression. See @ref DLambdaSsm **/ - lambdaexpr, - - /** handle ifelse-expression. See @ref DIfElseSsm **/ - ifelseexpr, - - /** rhs expression. state exists to achieve 1-token lookahead **/ - progress, - /** comes lasts, counts number of valid enums **/ N }; diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index aebe5d77..d883fa82 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -29,6 +29,10 @@ set(SELF_SRCS ISyntaxStateMachine_DIfElseSsm.cpp IPrintable_DIfElseSsm.cpp + DSequenceSsm.cpp + ISyntaxStateMachine_DSequenceSsm.cpp + IPrintable_DSequenceSsm.cpp + DLambdaSsm.cpp ISyntaxStateMachine_DLambdaSsm.cpp IPrintable_DLambdaSsm.cpp diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 3b4b2c36..cddfb865 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -8,6 +8,7 @@ #include "SyntaxStateMachine.hpp" #include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" +#include "DSequenceSsm.hpp" #include "syntaxstatetype.hpp" #include #include @@ -114,6 +115,10 @@ namespace xo { scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); switch (tk.tk_type()) { + case tokentype::tk_leftbrace: + this->on_leftbrace_token(tk, p_psm); + return; + case tokentype::tk_symbol: this->on_symbol_token(tk, p_psm); return; @@ -148,7 +153,6 @@ namespace xo { case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: - case tokentype::tk_leftbrace: case tokentype::tk_rightbrace: case tokentype::tk_leftangle: case tokentype::tk_rightangle: @@ -179,6 +183,15 @@ namespace xo { Super::on_token(tk, p_psm); } + void + DExpectExprSsm::on_leftbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DSequenceSsm::start(p_psm); + } + void DExpectExprSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) @@ -377,7 +390,8 @@ namespace xo { (ppii, "DExpectExprSsm", refrtag("allow_defs", allow_defs_), - refrtag("cxl_on_rightbrace", cxl_on_rightbrace_) + refrtag("cxl_on_rightbrace", cxl_on_rightbrace_), + refrtag("expect", this->get_expect_str()) ); } @@ -412,16 +426,6 @@ namespace xo { paren_xs::start(p_psm); } - void - expect_expr_xs::on_leftbrace_token(const token_type & /*tk*/, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - /* push lparen_0 to remember to look for subsequent rightparen. */ - sequence_xs::start(p_psm); - } - void expect_expr_xs::on_rightbrace_token(const token_type & tk, parserstatemachine * p_psm) diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 4866cd66..99351533 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -1,4 +1,4 @@ -/** @file lambda_xs.cpp +/** @file DLambdaSsm.cpp * * @author Roland Conybeare, Jan 2026 **/ diff --git a/xo-reader2/src/reader2/DSequenceSsm.cpp b/xo-reader2/src/reader2/DSequenceSsm.cpp index 285960bd..6a6b8c76 100644 --- a/xo-reader2/src/reader2/DSequenceSsm.cpp +++ b/xo-reader2/src/reader2/DSequenceSsm.cpp @@ -1,6 +1,8 @@ /* @file DSequenceSsm.cpp */ #include "DSequenceSsm.hpp" +#include "ssm/ISyntaxStateMachine_DSequenceSsm.hpp" +#include "DExpectExprSsm.hpp" #ifdef NOT_YET #include "expect_expr_xs.hpp" @@ -11,31 +13,67 @@ #endif namespace xo { - using xo::scm::DefineExpr; +#ifdef NOT_YET + using xo::scm::DDefineExpr; +#endif + using xo::facet::typeseq; namespace scm { -#ifdef NOT_YET - std::unique_ptr - sequence_xs::make() { - return std::make_unique(sequence_xs()); - } -#endif - void - sequence_xs::start(parserstatemachine * p_psm) { - p_psm->push_exprstate(sequence_xs::make()); + DSequenceSsm::start(ParserStateMachine * p_psm) + { + p_psm->push_ssm(DSequenceSsm::make(p_psm->parser_alloc(), + p_psm->expr_alloc())); /* want to accept anything that starts an expression, - * except that } ends it + * except that rightbrace '}' ends it */ - expect_expr_xs::start(true /*allow_defs*/, + DExpectExprSsm::start(p_psm->parser_alloc(), + true /*allow_defs*/, true /*cxl_on_rightbrace*/, p_psm); } + obj + DSequenceSsm::make(DArena & mm, + obj expr_mm) + { + return obj(_make(mm, expr_mm)); + } + + DSequenceSsm * + DSequenceSsm::_make(DArena & mm, + obj expr_mm) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DSequenceSsm)); + + DSequenceExpr * seq_expr = DSequenceExpr::_make_empty(expr_mm); + + return new (mem) DSequenceSsm(seq_expr); + } + + DSequenceSsm::DSequenceSsm(DSequenceExpr * seq_expr) : seq_expr_{seq_expr} + {} + +#ifdef NOT_YET sequence_xs::sequence_xs() : exprstate(exprstatetype::sequenceexpr) {} +#endif + syntaxstatetype + DSequenceSsm::ssm_type() const noexcept + { + return syntaxstatetype::sequence; + } + + std::string_view + DSequenceSsm::get_expect_str() const noexcept + { + return "expr|semicolon|rightbrace"; + } + +#ifdef NOT_YET void sequence_xs::on_expr(bp expr, parserstatemachine * p_psm) @@ -122,12 +160,16 @@ namespace xo { sequence_xs::print(std::ostream & os) const { os << ""; } +#endif bool - sequence_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + DSequenceSsm::pretty(const xo::print::ppindentinfo & ppii) const { - return ppii.pps()->pretty_struct(ppii, "sequence_xs", - xrefrtag("expr_v.size", expr_v_.size())); + return ppii.pps()->pretty_struct + (ppii, + "SequenceSsm", + xrefrtag("seq_expr.size", seq_expr_->size()), + xrefrtag("expect", this->get_expect_str())); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp b/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp index bb3c2096..dbd0bfc9 100644 --- a/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DDefineSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DDefineSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DDefineSsm.cpp */ \ No newline at end of file +/* end IPrintable_DDefineSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp index bfeaccd1..7febe575 100644 --- a/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectExprSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DExpectExprSsm.cpp */ \ No newline at end of file +/* end IPrintable_DExpectExprSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectFormalArgSsm.cpp index a38d4d86..13164b15 100644 --- a/xo-reader2/src/reader2/IPrintable_DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExpectFormalArgSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectFormalArgSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DExpectFormalArgSsm.cpp */ \ No newline at end of file +/* end IPrintable_DExpectFormalArgSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp index d5df450d..262cb91e 100644 --- a/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectFormalArglistSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DExpectFormalArglistSsm.cpp */ \ No newline at end of file +/* end IPrintable_DExpectFormalArglistSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp index e58d15f9..f03af120 100644 --- a/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectSymbolSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DExpectSymbolSsm.cpp */ \ No newline at end of file +/* end IPrintable_DExpectSymbolSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp index 3fc75136..14c20d53 100644 --- a/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExpectTypeSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DExpectTypeSsm.cpp */ \ No newline at end of file +/* end IPrintable_DExpectTypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp b/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp index 71997ede..36cfbd78 100644 --- a/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DExprSeqState.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DExprSeqState.cpp */ \ No newline at end of file +/* end IPrintable_DExprSeqState.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DIfElseSsm.cpp b/xo-reader2/src/reader2/IPrintable_DIfElseSsm.cpp index f2aebf7c..d0ef4bb3 100644 --- a/xo-reader2/src/reader2/IPrintable_DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DIfElseSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DIfElseSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DIfElseSsm.cpp */ \ No newline at end of file +/* end IPrintable_DIfElseSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp b/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp index 93a703aa..4e7a09d8 100644 --- a/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DLambdaSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DLambdaSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DLambdaSsm.cpp */ \ No newline at end of file +/* end IPrintable_DLambdaSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp b/xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp index c72399c9..bd9dd7e8 100644 --- a/xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DProgressSsm.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DProgressSsm.cpp */ \ No newline at end of file +/* end IPrintable_DProgressSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DSequenceSsm.cpp b/xo-reader2/src/reader2/IPrintable_DSequenceSsm.cpp new file mode 100644 index 00000000..8c525ba8 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DSequenceSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DSequenceSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DSequenceSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DSequenceSsm.json5] +**/ + +#include "ssm/IPrintable_DSequenceSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DSequenceSsm::pretty(const DSequenceSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DSequenceSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 18510abb..2cd6f304 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -80,4 +80,4 @@ ISyntaxStateMachine_Any::on_parsed_expression_with_semicolon(Opaque, obj syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DSequenceSsm::get_expect_str(const DSequenceSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DSequenceSsm::on_token(DSequenceSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DSequenceSsm::on_parsed_symbol(DSequenceSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DSequenceSsm::on_parsed_typedescr(DSequenceSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DSequenceSsm::on_parsed_formal(DSequenceSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DSequenceSsm::on_parsed_formal_arglist(DSequenceSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DSequenceSsm::on_parsed_expression(DSequenceSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DSequenceSsm::on_parsed_expression_with_semicolon(DSequenceSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DSequenceSsm.cpp */ diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 9dc10aa2..ef584c44 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -17,6 +17,8 @@ #include #include +#include + #include #include @@ -63,6 +65,8 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index e003b27d..aff0a87c 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -13,6 +13,16 @@ namespace xo { switch (x) { case syntaxstatetype::invalid: break; + case syntaxstatetype::defexpr: + return "defexpr"; + case syntaxstatetype::lambdaexpr: + return "lambdaexpr"; + case syntaxstatetype::ifelseexpr: + return "ifelseexpr"; + case syntaxstatetype::sequence: + return "sequence"; + case syntaxstatetype::progress: + return "progress"; case syntaxstatetype::expect_toplevel_expression_sequence: return "expect-toplevel-expression-sequence"; case syntaxstatetype::expect_formal_arglist: @@ -25,14 +35,6 @@ namespace xo { return "expect-type"; case syntaxstatetype::expect_rhs_expression: return "expect-rhs-expression"; - case syntaxstatetype::defexpr: - return "defexpr"; - case syntaxstatetype::lambdaexpr: - return "lambdaexpr"; - case syntaxstatetype::ifelseexpr: - return "ifelseexpr"; - case syntaxstatetype::progress: - return "progress"; case syntaxstatetype::N: break; } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 0d7dbba4..ef487af3 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -363,7 +363,6 @@ namespace xo { REQUIRE(result.is_incomplete()); } -#ifdef NOT_YET { auto & result = parser.on_token(Token::leftbrace_token()); @@ -376,6 +375,7 @@ namespace xo { REQUIRE(result.is_incomplete()); } +#ifdef NOT_YET { auto & result = parser.on_token(Token::string_token("fooey")); From e0eeeb12c25a50516ccedb415909c09c7681e9d0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 31 Jan 2026 21:33:39 -0500 Subject: [PATCH 141/258] xo-reader2: DLambdaSsm work towards producing DLambdaExpr [WIP] --- .../include/xo/reader2/DProgressSsm.hpp | 17 +-- .../include/xo/reader2/DSequenceSsm.hpp | 32 ++++- .../include/xo/reader2/ParserStateMachine.hpp | 12 ++ xo-reader2/src/reader2/DLambdaSsm.cpp | 17 +++ xo-reader2/src/reader2/DProgressSsm.cpp | 35 ++++- xo-reader2/src/reader2/DSequenceSsm.cpp | 122 +++++++++++++----- xo-reader2/src/reader2/ParserStateMachine.cpp | 35 ++++- xo-reader2/utest/SchematikaParser.test.cpp | 16 +-- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 9 files changed, 219 insertions(+), 69 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 85126bed..792d6eb2 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -166,6 +166,8 @@ namespace xo { ParserStateMachine * p_psm); void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); + void on_rightbrace_token(const Token & tk, + ParserStateMachine * p_psm); void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm); @@ -183,27 +185,12 @@ namespace xo { void on_typedescr(TypeDescr td, parserstatemachine * p_psm) override; - void on_semicolon_token(const token_type & tk, - parserstatemachine * p_psm) override; void on_assign_token(const token_type & tk, parserstatemachine * p_psm) final override; void on_leftparen_token(const token_type & tk, parserstatemachine * p_psm) override; void on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) override; - void on_rightbrace_token(const token_type & tk, - parserstatemachine * p_psm) override; - - /* entry point for an infix operator token */ - void on_operator_token(const token_type & tk, - parserstatemachine * p_psm) final override; - - void on_bool_token(const token_type & tk, - parserstatemachine * p_psm) override; - - void on_i64_token(const token_type & tk, - parserstatemachine * p_psm) override; - void print(std::ostream & os) const override; #endif diff --git a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp index 6423ee29..e2943ae8 100644 --- a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp +++ b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp @@ -7,12 +7,25 @@ #include "DSyntaxStateMachine.hpp" #include +#include "syntaxstatetype.hpp" +#include +#include +#include namespace xo { namespace scm { class Sequence; } namespace scm { class Lambda; } namespace scm { + // TODO: need switching between 1a,1b states. + // Allow + // { } + // { 1 } + // { 1; } + // Reject + // { 1 2 } + // + class DSequenceSsm : public DSyntaxStateMachine { public: //using Sequence = xo::scm::Sequence; @@ -38,15 +51,14 @@ namespace xo { obj expr_mm); #ifdef NOT_YET - virtual void on_expr(bp expr, - parserstatemachine * p_psm) override; virtual void on_expr_with_semicolon(bp expr, parserstatemachine * p_psm) override; - - virtual void on_rightbrace_token(const token_type & tk, - parserstatemachine * p_psm) override; #endif + /** update ssm for incoming rightbrace token '}' **/ + void on_rightbrace_token(const Token & tk, + ParserStateMachine * p_psm); + /** @defgroup scm-sequencessm-syntaxstatemachine-facet ssm facet **/ ///@{ @@ -56,6 +68,16 @@ namespace xo { /** mnemonic for syntax sequence ssm expects given current state **/ std::string_view get_expect_str() const noexcept; + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** consume expression @p expr produced by nested ssm; overall parser state in @p p_psm **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-sequencessm-printable-facet printable facet **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index a57247c7..91c84ef1 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -142,6 +142,18 @@ namespace xo { **/ void on_parsed_expression_with_semicolon(obj expr); + /** update state to respond to parsed expression @p expr + * (from nested parsing state), with trailing token @p tk. + * + * Need to distinguish cases like: + * 6 // ) ? ; allowed } ? + * f(6 // ) allowed ; forbidden } forbidden + * 6 + // ) forbidden ; forbidden } forbidden + * + **/ + void on_parsed_expression_with_token(obj expr, + const Token & tk); + /** update state to respond to input token @p tk. * record output (if any) in @ref result_ **/ diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 99351533..4b2d7df8 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -336,6 +336,23 @@ namespace xo { DLambdaSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { + if (lm_state_ == lambdastatetype::lm_4) { + this->lmstate_ = lambdastatetype::lm_5; + this->body_ = expr; + + // assemble lambda + + obj lm_expr = DLambda::make(p_psm->expr_alloc(), + xxx typeref, + xxx name, + local_symtab_, + body_); + + p_psm->pop_ssm(); // this lambda + p_psm->on_parsed_expression(lm_expr); + return; + } + Super::on_parsed_expression(expr, p_psm); } diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 3c617fae..9fd6e7b1 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -205,7 +205,7 @@ namespace xo { std::string_view DProgressSsm::get_expect_str() const noexcept { if (op_type_ == optype::invalid) { - return "oper|semicolon|rightparen"; + return "oper|semicolon|rightparen|righbrace"; } else { return "expr|leftparen"; } @@ -255,6 +255,10 @@ namespace xo { this->on_semicolon_token(tk, p_psm); return; + case tokentype::tk_rightbrace: + this->on_rightbrace_token(tk, p_psm); + return; + // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_def: @@ -264,7 +268,6 @@ namespace xo { case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: case tokentype::tk_leftbrace: - case tokentype::tk_rightbrace: case tokentype::tk_leftangle: case tokentype::tk_rightangle: case tokentype::tk_lessequal: @@ -448,7 +451,8 @@ namespace xo { obj expr = this->assemble_expr(p_psm); { - obj expr_pr = FacetRegistry::instance().variant(expr); + obj expr_pr + = FacetRegistry::instance().variant(expr); assert(expr_pr); log && log(xtag("expr", expr_pr)); } @@ -475,6 +479,27 @@ namespace xo { #endif } + void + DProgressSsm::on_rightbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + (void)tk; + + obj expr = this->assemble_expr(p_psm); + + { + obj expr_pr + = FacetRegistry::instance().variant(expr); + assert(expr_pr); + log && log(xtag("expr", expr_pr)); + } + + p_psm->pop_ssm(); + p_psm->on_parsed_expression_with_token(expr, tk); + } + void DProgressSsm::on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm) @@ -1024,7 +1049,8 @@ namespace xo { "DProgressSsm", refrtag("lhs", lhs), refrtag("op", op_type_), - cond(rhs, refrtag("rhs", rhs), "nullptr") + cond(rhs, refrtag("rhs", rhs), "nullptr"), + refrtag("expect", this->get_expect_str()) ); } @@ -1048,6 +1074,7 @@ namespace xo { std::string_view(errmsg_string)); p_psm->capture_error(c_self_name, errmsg); + return obj(); } /* consecutive expressions not legal, e.g: diff --git a/xo-reader2/src/reader2/DSequenceSsm.cpp b/xo-reader2/src/reader2/DSequenceSsm.cpp index 6a6b8c76..56efb896 100644 --- a/xo-reader2/src/reader2/DSequenceSsm.cpp +++ b/xo-reader2/src/reader2/DSequenceSsm.cpp @@ -55,12 +55,6 @@ namespace xo { DSequenceSsm::DSequenceSsm(DSequenceExpr * seq_expr) : seq_expr_{seq_expr} {} -#ifdef NOT_YET - sequence_xs::sequence_xs() - : exprstate(exprstatetype::sequenceexpr) - {} -#endif - syntaxstatetype DSequenceSsm::ssm_type() const noexcept { @@ -73,15 +67,93 @@ namespace xo { return "expr|semicolon|rightbrace"; } -#ifdef NOT_YET void - sequence_xs::on_expr(bp expr, - parserstatemachine * p_psm) + DSequenceSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_rightbrace: + this->on_rightbrace_token(tk, p_psm); + return; + case tokentype::tk_symbol: + case tokentype::tk_def: + case tokentype::tk_if: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_semicolon: + case tokentype::tk_invalid: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + // default = illegal token error + DSyntaxStateMachine::on_token(tk, p_psm); + } + + void + DSequenceSsm::on_rightbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + /** rightbrace ends DSequenceSsm **/ + + obj expr(seq_expr_); + + p_psm->pop_ssm(); + + /* make sequence from expressions seen at this level, + * and report it to parent + */ + p_psm->top_ssm().on_parsed_expression(expr, p_psm); + } + + void + DSequenceSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) { scope log(XO_DEBUG(p_psm->debug_flag())); - log && log(xtag("expr", expr.promote())); + // TODO: stream inserter that sets up pretty-printing. + // Or integrate with indentlog. + // Maybe trouble is that indentlog doesn't #include Printable ? + // + log && log(xtag("expr", expr)); +#ifdef NOT_YET /* TODO: if expr is a DefineExpr, * then need to rewrite... * @@ -132,8 +204,13 @@ namespace xo { true /*cxl_on_rightbrace*/, p_psm); } +#endif + + this->seq_expr_->push_back(p_psm->expr_alloc(), + expr); } +#ifdef NOT_YET void sequence_xs::on_expr_with_semicolon(bp expr, parserstatemachine * p_psm) @@ -141,25 +218,6 @@ namespace xo { /* sequence continues until right brace */ this->on_expr(expr, p_psm); } - - void - sequence_xs::on_rightbrace_token(const token_type & /*tk*/, - parserstatemachine * p_psm) - { - auto self = p_psm->pop_exprstate(); - - /* make sequence from expressions seen at this level, - * and report it to parent - */ - auto expr = Sequence::make(this->expr_v_); - - p_psm->top_exprstate().on_expr(expr, p_psm); - } - - void - sequence_xs::print(std::ostream & os) const { - os << ""; - } #endif bool @@ -167,9 +225,9 @@ namespace xo { { return ppii.pps()->pretty_struct (ppii, - "SequenceSsm", - xrefrtag("seq_expr.size", seq_expr_->size()), - xrefrtag("expect", this->get_expect_str())); + "DSequenceSsm", + refrtag("seq_expr.size", seq_expr_->size()), + refrtag("expect", this->get_expect_str())); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 085cce56..82435b50 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ namespace xo { using xo::print::APrintable; + using xo::facet::FacetRegistry; using xo::facet::with_facet; namespace scm { @@ -188,6 +190,21 @@ namespace xo { this->top_ssm().on_parsed_expression_with_semicolon(expr, this); } + void + ParserStateMachine::on_parsed_expression_with_token(obj expr, + const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("expr", expr), xtag("tk", tk)); + + assert(stack_); + + this->top_ssm().on_parsed_expression(expr, this); + + assert(stack_); + + this->top_ssm().on_token(tk, this); + } + void ParserStateMachine::on_token(const Token & tk) { @@ -215,7 +232,11 @@ namespace xo { ParserStateMachine::capture_error(std::string_view ssm_name, const DString * errmsg) { - this->result_ = ParserResult::error(ssm_name, errmsg); + if (result_.is_error()) { + /* in case one error triggers another, remmber just the first one */ + } else { + this->result_ = ParserResult::error(ssm_name, errmsg); + } } void @@ -302,7 +323,7 @@ namespace xo { xtag("param_type", param_type), xtag("expecting", expect_str), xtag("ssm", ssm_name), - xtag("via", "ParserStateMachine::illegal_parsed_expression")); + xtag("via", "ParserStateMachine::illegal_parsed_formal")); assert(expr_alloc_); @@ -341,8 +362,16 @@ namespace xo { // - want to write error message using DArena // - need something like log_streambuf and/or tostr() that's arena-aware + obj expr_pr + = FacetRegistry::instance().variant(expr); + assert(expr_pr); + + /** TODO + * problem here: we have pretty() support for obj, + * but not "ordinary printing" support. So expression doesn't get printed + **/ auto errmsg_string = tostr("Unexpected expression", - xtag("expr", expr), + xtag("expr", expr_pr), xtag("expecting", expect_str), xtag("ssm", ssm_name), xtag("via", "ParserStateMachine::illegal_parsed_expression")); diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index ef487af3..b30b67f3 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -215,7 +215,7 @@ namespace xo { /** Walkthrough parsing input equivalent to: * - * lambda (n : i64, + * lambda (n : i64, r : i64) -> i64 { 123 } * **/ @@ -375,11 +375,10 @@ namespace xo { REQUIRE(result.is_incomplete()); } -#ifdef NOT_YET { - auto & result = parser.on_token(Token::string_token("fooey")); + auto & result = parser.on_token(Token::i64_token("123")); - log && log("after string token:"); + log && log("after f64(123) token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); @@ -389,17 +388,16 @@ namespace xo { } { - auto & result = parser.on_token(Token::semicolon_token()); + auto & result = parser.on_token(Token::rightbrace_token()); - log && log("after semicolon token:"); + log && log("after rightbrace token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); - REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(!result.is_error()); - REQUIRE(!result.is_incomplete()); + REQUIRE(result.is_incomplete()); } -#endif //REQUIRE(result.is_error()); //// illegal input on token diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index fc5dfc9a..ab3f0cb7 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -102,7 +102,7 @@ namespace xo { /** token representing left brace @c "{" **/ static Token leftbrace_token() { return Token(tokentype::tk_leftbrace); } /** token representing right brace @c "}" **/ - static Token rightbrace() { return Token(tokentype::tk_rightbrace); } + static Token rightbrace_token() { return Token(tokentype::tk_rightbrace); } /** token representing period @c "." **/ static Token dot() { return Token(tokentype::tk_dot); } /** token representing comma @c "," **/ From 6a932912e37fa2fbb7a1dd7badd187803fd7d2fe Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 1 Feb 2026 00:16:37 -0500 Subject: [PATCH 142/258] xo-reader2: construct LambdaExpr to complete LambdaSsm + utest --- .../include/xo/expression2/StringTable.hpp | 5 ++++ .../src/expression2/DLambdaExpr.cpp | 12 ++++++-- .../src/expression2/DSequenceExpr.cpp | 7 ++++- .../src/expression2/StringTable.cpp | 30 +++++++++++++++++++ .../include/xo/reader2/ParserStateMachine.hpp | 3 ++ xo-reader2/src/reader2/DLambdaSsm.cpp | 19 ++++++++---- xo-reader2/src/reader2/ParserStateMachine.cpp | 6 ++++ xo-reader2/utest/SchematikaParser.test.cpp | 5 ++-- 8 files changed, 76 insertions(+), 11 deletions(-) diff --git a/xo-expression2/include/xo/expression2/StringTable.hpp b/xo-expression2/include/xo/expression2/StringTable.hpp index 54b0a826..471fbc0d 100644 --- a/xo-expression2/include/xo/expression2/StringTable.hpp +++ b/xo-expression2/include/xo/expression2/StringTable.hpp @@ -35,6 +35,11 @@ namespace xo { /** return unique string with contents @p key. Idempotent! **/ const DUniqueString * intern(std::string_view key); + /** generate unique symbol -- guaranteed not to collide + * with existing symbol in this table. + **/ + const DUniqueString * gensym(std::string_view prefix); + /** verify StringTable invariants. * Act on failure according to policy @p p **/ diff --git a/xo-expression2/src/expression2/DLambdaExpr.cpp b/xo-expression2/src/expression2/DLambdaExpr.cpp index a27e788b..080e49b5 100644 --- a/xo-expression2/src/expression2/DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/DLambdaExpr.cpp @@ -1,10 +1,12 @@ -/** @file DLambda.cpp +/** @file DLambdaExpr.cpp * * @author Roland Conybeare, Jan 2026 **/ #include "DLambdaExpr.hpp" #include "detail/IExpression_DLambdaExpr.hpp" +#include "DLocalSymtab.hpp" +#include "symtab/IPrintable_DLocalSymtab.hpp" #include #include #include @@ -17,6 +19,7 @@ namespace xo { using xo::reflect::TypeDescrBase; using xo::reflect::FunctionTdxInfo; using xo::reflect::typeseq; + using xo::print::quot; namespace scm { @@ -139,9 +142,14 @@ namespace xo { AExpression>(body_expr_); if (name_ && body) { + auto local_symtab_pr + = obj(local_symtab_); + return ppii.pps()->pretty_struct(ppii, "LambdaExpr", - refrtag("name", name_), + refrtag("tref", typeref_), + refrtag("name", quot(std::string_view(*name_))), + refrtag("local_symtab", local_symtab_pr), //refrtag("argv", local_env_->argv()), refrtag("body", body)); } else { diff --git a/xo-expression2/src/expression2/DSequenceExpr.cpp b/xo-expression2/src/expression2/DSequenceExpr.cpp index 73b9c2b5..a9783802 100644 --- a/xo-expression2/src/expression2/DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/DSequenceExpr.cpp @@ -6,6 +6,7 @@ #include "DSequenceExpr.hpp" #include "detail/IExpression_DSequenceExpr.hpp" #include +#include #include #include #include @@ -15,6 +16,7 @@ namespace xo { using xo::mm::AGCObject; + using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::reflect::typeseq; @@ -95,9 +97,12 @@ namespace xo { { using xo::print::ppstate; + auto expr_v_pr = obj(expr_v_); + return ppii.pps()->pretty_struct (ppii, - "DSequenceExpr"); + "DSequenceExpr", + refrtag("expr_v", expr_v_pr)); } // gc hooks for IGCObject_DSequenceExpr diff --git a/xo-expression2/src/expression2/StringTable.cpp b/xo-expression2/src/expression2/StringTable.cpp index ae48eea9..f59bb24d 100644 --- a/xo-expression2/src/expression2/StringTable.cpp +++ b/xo-expression2/src/expression2/StringTable.cpp @@ -72,6 +72,36 @@ namespace xo { return nullptr; } + const DUniqueString * + StringTable::gensym(std::string_view prefix) + { + static std::size_t s_counter = 0; + + while (true) { + ++s_counter; + + char buf[80]; + assert(prefix.size() + 20 < sizeof(buf)); + + int n = snprintf(buf, sizeof(buf), + "%s:%lu", + prefix.data(), s_counter); + + if ((0 < n) && (std::size_t(n) < sizeof(buf))) + buf[n] = '\0'; + else + buf[sizeof(buf)-1] = '\0'; + + std::string_view sv(buf); + const DUniqueString * retval = this->lookup(sv); + if (!retval) { + /* not already in string view -> we have viable candidate */ + retval = this->intern(sv); + return retval; + } + } + } + bool StringTable::verify_ok(verify_policy policy) const { diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 91c84ef1..d065e24f 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -82,6 +82,9 @@ namespace xo { **/ const DUniqueString * intern_string(std::string_view str); + /** get unique (within stringtable) string, beginning with @p prefix **/ + const DUniqueString * gensym(std::string_view prefix); + /** push nested local symtab while parsing the body of a lambda expression; * restore previous symtab at the end of lambda-expression definition. * See @ref pop_local_symtab diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 4b2d7df8..4ed77732 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -11,6 +11,7 @@ #include "DExpectExprSsm.hpp" #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" +#include #include #include //#include @@ -336,17 +337,23 @@ namespace xo { DLambdaSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { - if (lm_state_ == lambdastatetype::lm_4) { + if (lmstate_ == lambdastatetype::lm_4) { this->lmstate_ = lambdastatetype::lm_5; this->body_ = expr; // assemble lambda - obj lm_expr = DLambda::make(p_psm->expr_alloc(), - xxx typeref, - xxx name, - local_symtab_, - body_); + auto prefix = TypeRef::prefix_type::from_chars("lm"); + TypeRef tref = TypeRef::dwim(prefix, nullptr); + + const DUniqueString * name = p_psm->gensym("lambda"); + + auto lm_expr = obj + (DLambdaExpr::make(p_psm->expr_alloc(), + tref, + name, + local_symtab_, + body_)); p_psm->pop_ssm(); // this lambda p_psm->on_parsed_expression(lm_expr); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 82435b50..cf9c26c1 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -90,6 +90,12 @@ namespace xo { return stringtable_.intern(str); } + const DUniqueString * + ParserStateMachine::gensym(std::string_view str) + { + return stringtable_.gensym(str); + } + void ParserStateMachine::push_local_symtab(DLocalSymtab * symtab) { diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index b30b67f3..0defdeb5 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -394,9 +394,10 @@ namespace xo { log && log(xtag("parser", &parser)); log && log(xtag("result", result)); - REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(parser.has_incomplete_expr() == false); REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); } //REQUIRE(result.is_error()); From 6b948e82004a55a7b0fb7dced230081a10e1b3c8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 1 Feb 2026 17:26:24 -0500 Subject: [PATCH 143/258] xo-reader2 xo-gc: streamline example + DX1Collector.ref() method --- xo-gc/include/xo/gc/DX1Collector.hpp | 8 ++- .../example/readerreplxx/readerreplxx.cpp | 69 ++++++++++++------- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/xo-gc/include/xo/gc/DX1Collector.hpp b/xo-gc/include/xo/gc/DX1Collector.hpp index 78b55d20..40c7f4f2 100644 --- a/xo-gc/include/xo/gc/DX1Collector.hpp +++ b/xo-gc/include/xo/gc/DX1Collector.hpp @@ -175,10 +175,16 @@ namespace xo { /** Create X1 collector instance. **/ explicit DX1Collector(const CollectorConfig & cfg); + /** faceted object pointer to this instance */ + template + obj ref() { return obj(this); } + +#ifdef NOT_YET /** create instance with default configuration, * generation size @p gen_z **/ - DX1Collector make_std(std::size_t gen_z); + static DX1Collector make_std(std::size_t gen_z); +#endif std::string_view name() const { return config_.name_; } diff --git a/xo-reader2/example/readerreplxx/readerreplxx.cpp b/xo-reader2/example/readerreplxx/readerreplxx.cpp index 341893cf..122b2730 100644 --- a/xo-reader2/example/readerreplxx/readerreplxx.cpp +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -134,6 +134,43 @@ namespace { } } +struct AppConfig { + using ReaderConfig = xo::scm::ReaderConfig; + using CollectorConfig = xo::mm::CollectorConfig; + + AppConfig() { + rdr_config_.reader_debug_flag_ = true; + //rdr_config.parser_debug_flag_ = true; + //rdr_config.tk_debug_flag_ = true; + } + + std::size_t max_history_size_ = 1000; + std::string repl_history_fname_ = "repl_history.txt";; + CollectorConfig x1_config_ = (CollectorConfig().with_size(4*1024*1024)); + ReaderConfig rdr_config_; +}; + +struct AppContext { + using DX1Collector = xo::mm::DX1Collector; + using CollectorConfig = xo::mm::CollectorConfig; + using Replxx = replxx::Replxx; + + AppContext(const AppConfig & cfg = AppConfig()) : config_{cfg}, + x1_{CollectorConfig().with_size(4*1024*1024)}, + rdr_{config_.rdr_config_, x1_.ref()} + { + rx_.set_max_history_size(config_.max_history_size_); + rx_.history_load(config_.repl_history_fname_); + // rx.bind_key_internal(Replxx::KEY::control('p'), "history_previous"); + // rx.bind_key_internal(Replxx::KEY::control('n'), "history_next"); + } + + AppConfig config_; + Replxx rx_; + DX1Collector x1_; + SchematikaReader rdr_; +}; + int main() { @@ -143,7 +180,6 @@ main() using xo::scm::ReaderConfig; using xo::mm::AAllocator; using xo::mm::DX1Collector; - using xo::mm::CollectorConfig; using xo::mm::DArena; using xo::facet::with_facet; using xo::facet::obj; @@ -158,45 +194,28 @@ main() InitSubsys::require(); Subsystem::initialize_all(); - Replxx rx; - rx.set_max_history_size(1000); - rx.history_load("repl_history.txt"); -// rx.bind_key_internal(Replxx::KEY::control('p'), "history_previous"); -// rx.bind_key_internal(Replxx::KEY::control('n'), "history_next"); + AppConfig cfg; + AppContext cx(cfg); constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag)); - CollectorConfig x1_config = (CollectorConfig() - .with_size(4*1024*1024)); - DX1Collector x1(x1_config); - obj expr_alloc = with_facet::mkobj(&x1); - - // accepting defaults too - ReaderConfig rdr_config; - { - rdr_config.reader_debug_flag_ = true; - //rdr_config.parser_debug_flag_ = true; - //rdr_config.tk_debug_flag_ = true; - } - - SchematikaReader rdr(rdr_config, expr_alloc); using span_type = SchematikaReader::span_type; welcome(cerr); - rdr.begin_interactive_session(); + cx.rdr_.begin_interactive_session(); bool eof = false; const char * input_str = nullptr; span_type input; - while (replxx_getline(interactive, rdr.is_at_toplevel(), rx, &input_str)) { + while (replxx_getline(interactive, cx.rdr_.is_at_toplevel(), cx.rx_, &input_str)) { if (input_str && *input_str) { input = span_type::from_cstr(input_str); while (!input.empty() - && reader_seq(&rdr, &input, false /*eof*/, c_debug_flag)) + && reader_seq(&cx.rdr_, &input, false /*eof*/, c_debug_flag)) { ; } @@ -209,9 +228,9 @@ main() } /* reminder: eof can complete at most one token */ - reader_seq(&rdr, &input, true /*eof*/, c_debug_flag); + reader_seq(&cx.rdr_, &input, true /*eof*/, c_debug_flag); - rx.history_save("repl_history.txt"); + cx.rx_.history_save(cx.config_.repl_history_fname_); } /* end readerreplxx.cpp */ From 756e8a94cf8399370af5a9875abd8d7f0bce1cd4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 1 Feb 2026 22:12:28 -0500 Subject: [PATCH 144/258] xo-interpreter2: work towards utest w/ vsm+reader [WIP] --- .../include/xo/alloc2/alloc/AAllocator.hpp | 6 + .../xo/alloc2/alloc/IAllocator_Any.hpp | 4 +- .../xo/alloc2/alloc/IAllocator_Xfer.hpp | 9 +- .../include/xo/alloc2/alloc/RAllocator.hpp | 1 + xo-expression2/utest/X1Collector.test.cpp | 17 ++- xo-facet/include/xo/facet/OUniqueBox.hpp | 74 ------------- xo-facet/include/xo/facet/box.hpp | 83 ++++++++++++++ xo-facet/include/xo/facet/obj.hpp | 8 +- xo-gc/include/xo/gc/DX1Collector.hpp | 103 +----------------- xo-gc/include/xo/gc/X1CollectorConfig.hpp | 92 ++++++++++++++++ xo-gc/src/gc/DX1Collector.cpp | 12 +- xo-gc/utest/Collector.test.cpp | 62 +++++------ xo-gc/utest/DX1CollectorIterator.test.cpp | 26 ++--- xo-interpreter2/CMakeLists.txt | 2 +- .../interpreter2/VirtualSchematikaMachine.hpp | 14 ++- .../include/xo/interpreter2/VsmConfig.hpp | 28 +++++ .../xo/interpreter2/init_interpreter2.hpp | 21 ++++ .../src/interpreter2/CMakeLists.txt | 3 +- .../interpreter2/VirtualSchematikaMachine.cpp | 9 +- .../src/interpreter2/init_interpreter2.cpp | 50 +++++++++ xo-interpreter2/utest/CMakeLists.txt | 11 ++ .../utest/VirtualSchematikaMachine.test.cpp | 63 +++++++++++ .../utest/interpreter2_utest_main.cpp | 27 +++++ xo-object2/utest/Printable.test.cpp | 19 ++-- xo-object2/utest/X1Collector.test.cpp | 21 ++-- .../example/readerreplxx/readerreplxx.cpp | 8 +- 26 files changed, 503 insertions(+), 270 deletions(-) delete mode 100644 xo-facet/include/xo/facet/OUniqueBox.hpp create mode 100644 xo-facet/include/xo/facet/box.hpp create mode 100644 xo-gc/include/xo/gc/X1CollectorConfig.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/init_interpreter2.hpp create mode 100644 xo-interpreter2/src/interpreter2/init_interpreter2.cpp create mode 100644 xo-interpreter2/utest/CMakeLists.txt create mode 100644 xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp create mode 100644 xo-interpreter2/utest/interpreter2_utest_main.cpp diff --git a/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp index 588b439b..4639d47e 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp @@ -62,6 +62,10 @@ namespace xo { /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d. Calls c++ destructor for actual runtime type. + * does not recover memory. + **/ + virtual void _drop(Opaque d) const noexcept = 0; /** optional name for allocator @p d . * Allows labeling allocators, for diagnostics/instrumentation. **/ @@ -142,10 +146,12 @@ namespace xo { virtual value_type alloc_copy(Opaque d, value_type src) const = 0; /** reset allocator @p d to empty state. **/ virtual void clear(Opaque d) const = 0; +#ifdef OBSOLETE /** Destruct allocator @p d. * Releases allocator memory to operating system. **/ virtual void destruct_data(Opaque d) const = 0; +#endif ///@} }; /*AAllocator*/ diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp index b45e7651..aac80bca 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp @@ -32,7 +32,10 @@ namespace xo { const AAllocator * iface() const { return std::launder(this); } // from AAllocator + + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque) const noexcept override { _fatal(); } // const methods [[noreturn]] std::string_view name(Copaque) const noexcept override { _fatal(); } @@ -55,7 +58,6 @@ namespace xo { [[noreturn]] value_type sub_alloc(Opaque, std::size_t, bool) const override { _fatal(); } [[noreturn]] value_type alloc_copy(Opaque, value_type) const override { _fatal(); } [[noreturn]] void clear(Opaque) const override { _fatal(); } - [[noreturn]] void destruct_data(Opaque) const override { _fatal(); } private: [[noreturn]] static void _fatal(); diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp index 790bcdc0..e23d1470 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp @@ -36,10 +36,14 @@ namespace xo { // from AAllocator - // const methods - + // builtin methods /** return typeseq for @tparam DRepr **/ typeseq _typeseq() const noexcept override { return s_typeseq; } + /** invoke native c++ dtor **/ + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods + std::string_view name(Copaque d) const noexcept override { return I::name(_dcast(d)); } size_type reserved(Copaque d) const noexcept override { return I::reserved(_dcast(d)); } size_type size(Copaque d) const noexcept override { return I::size(_dcast(d)); } @@ -73,7 +77,6 @@ namespace xo { value_type alloc_copy(Opaque d, value_type src) const override { return I::alloc_copy(_dcast(d), src); } void clear(Opaque d) const override { return I::clear(_dcast(d)); } - void destruct_data(Opaque d) const override { return I::destruct_data(_dcast(d)); } ///@} private: diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index 2e9e7a80..c07b5e81 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -29,6 +29,7 @@ namespace xo { RAllocator(Object::DataPtr data) : Object{std::move(data)} {} typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } std::string_view name() const noexcept { return O::iface()->name(O::data()); } size_type reserved() const noexcept { return O::iface()->reserved(O::data()); } size_type size() const noexcept { return O::iface()->size(O::data()); } diff --git a/xo-expression2/utest/X1Collector.test.cpp b/xo-expression2/utest/X1Collector.test.cpp index a664f9a2..b872d877 100644 --- a/xo-expression2/utest/X1Collector.test.cpp +++ b/xo-expression2/utest/X1Collector.test.cpp @@ -39,7 +39,7 @@ namespace ut { using xo::mm::ACollector; using xo::mm::AGCObject; using xo::mm::DX1Collector; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::facet::with_facet; using xo::facet::typeseq; @@ -54,14 +54,13 @@ namespace ut { REQUIRE(s_init.evidence()); // Create collector - CollectorConfig cfg{ - .name_ = "x1_duniquestring_test", - .arena_config_ = ArenaConfig{ - .size_ = 8192, - .store_header_flag_ = true}, - .object_types_z_ = 16384, - .gc_trigger_v_{{1024, 1024}}, - .debug_flag_ = false, + X1CollectorConfig cfg{ .name_ = "x1_duniquestring_test", + .arena_config_ = ArenaConfig{ + .size_ = 8192, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{1024, 1024}}, + .debug_flag_ = false, }; DX1Collector gc(cfg); diff --git a/xo-facet/include/xo/facet/OUniqueBox.hpp b/xo-facet/include/xo/facet/OUniqueBox.hpp deleted file mode 100644 index d22ad70f..00000000 --- a/xo-facet/include/xo/facet/OUniqueBox.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/** @file OUniqueBox.hpp - * - * @author Roland Conybeare, Dec 2025 - **/ - -namespace xo { - namespace facet { - /** - * Uniquely-owned instance with runtime polymorphism. - * - * Reminder that in the facet object model we expect - * objects to be transient. - * - - * - * Unlike OUniqueBox can use for variant data - * without additional overhead. Tradeoff is that avoiding such - * overhead excludes std::unique_ptr. - * - * We're going to instead rely on AInterface providing a destruct_data() method, - * so in practice get the deleter from interface state. - * - * Possibly means we need all abstract interfaces to share a common base - * - * Remarks: - * - when @tparam Data is supplied - **/ - template - struct OUniqueBox { - using AbstractInterface = AInterface; - using ISpecific = ISpecificFor::ImplType; - /* note: Data can be void here */ - using DataType = Data; - using DataBox = Data*; - - explicit OUniqueBox() {} - /* unsatisfactory b/c doesn't enforce that @p d is heap-allocated */ - explicit OUniqueBox(DataBox d) : data_{std::move(d)} {} - - ~OUniqueBox() { - if (data_ != nullptr) { - this->iface()->destruct_data(data_); - delete data_; - this->data_ = nullptr; - } - } - - const AInterface * iface() const - requires std::is_same_v - { - return std::launder(&iface_); - } - - const AInterface * iface() const - requires (!std::is_same_v) - { - return &iface_; - } - - /** note: would prefer this to be constexpr, but not simple asof gcc 14.3 **/ - static bool _valid; - - /** note: load-bearing for routing classes such as RComplex **/ - Data * data() const { return data_; } - - ISpecific iface_; - DataBox data_ = nullptr; - }; - - - } -} /*namespace xo*/ - -/* end OUniqueBox.hpp */ diff --git a/xo-facet/include/xo/facet/box.hpp b/xo-facet/include/xo/facet/box.hpp new file mode 100644 index 00000000..25a6561e --- /dev/null +++ b/xo-facet/include/xo/facet/box.hpp @@ -0,0 +1,83 @@ +/** @file box.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "obj.hpp" + +namespace xo { + namespace facet { + + /** object with owned state + * - with default DRepr argument: + * type-erased container (runtime polymorphism). + * - with sepcific DRepr argument: + * typed container (comptime polymorphism). + **/ + template + struct box : public RoutingType> { + using Super = RoutingType>; + + box() : Super() {} + + /** box takes ownership of data @p *d; + * will destroy when box goes out of scope. + * + * Note this is not useful when DRepr=DVariablePlaceholder + **/ + explicit box(Super::DataPtr d) : Super(d) {} + + /** Adopt instance that has interface @p iface and (type-erased here) + * representation @p data + **/ + box(const AFacet * iface, void * data) + requires std::is_same_v + : Super(iface, data) + {} + + /** (copy ctor not supported -- ownership is unique) **/ + + // -------------------------------- + + /** Move constructor **/ + template + box(box && other) + requires (std::is_same_v + || std::is_same_v) + : obj() + { + /* replacing .iface_ along w/ .data_ */ + this->from_obj(other); + + other.reset_opaque(nullptr); + } + + /** explicit conversion to obj **/ + obj to_op() const noexcept { return obj(this->iface(), this->data()); } + + /** Take ownership from unowned object **/ + template + box & adopt(const obj & other) + requires (std::is_same_v + || std::is_same_v) + { + /* replace .iface_ along w/ .data_ */ + this->from_obj(other); + + return *this; + } + + ~box() { + auto p = this->data(); + this->_drop(); + ::operator delete(p); + } + }; + } /*namespace facet*/ + + using facet::box; +} /*namespace xo*/ + +/* end box.hpp */ diff --git a/xo-facet/include/xo/facet/obj.hpp b/xo-facet/include/xo/facet/obj.hpp index 3983cecf..850ef7bf 100644 --- a/xo-facet/include/xo/facet/obj.hpp +++ b/xo-facet/include/xo/facet/obj.hpp @@ -12,9 +12,9 @@ namespace xo { namespace facet { /** object with borrowed state pointer - * - With default Data argument: + * - With default DRepr argument: * type-erased polymorphic container - * - with specific Data argument: + * - with specific DRepr argument: * typed container. Trivially de-virtualizable * * Example: @@ -88,7 +88,7 @@ namespace xo { * - same strategy for holding state (naked / unique / refcounted ...) **/ template - obj(const obj && other) + obj(obj && other) requires (std::is_same_v || std::is_convertible_v) : Super() @@ -98,7 +98,7 @@ namespace xo { } obj & operator=(const obj & rhs) { - /* ensure we replace .iface_ along w/ .ata_ */ + /* ensure we replace .iface_ along w/ .data_ */ this->from_obj(rhs); return *this; } diff --git a/xo-gc/include/xo/gc/DX1Collector.hpp b/xo-gc/include/xo/gc/DX1Collector.hpp index 40c7f4f2..af41ae0d 100644 --- a/xo-gc/include/xo/gc/DX1Collector.hpp +++ b/xo-gc/include/xo/gc/DX1Collector.hpp @@ -5,6 +5,7 @@ #pragma once +#include "X1CollectorConfig.hpp" #include "GCObject.hpp" #include "generation.hpp" #include "object_age.hpp" @@ -40,104 +41,6 @@ namespace xo { }; #endif - struct CollectorConfig { - using size_type = std::size_t; - -#ifdef OBSOLETE // get from arena_config_.header_ - /* - * alloc header - * TTTTTTTTTTTTGGGGGZZZZZZZZZZZZ - * < tseq >< size > - * - * masking - * - * ..432107654321076543210 bit - * - * > < .gen_bits - * 0..............01111111 gen_mask_unshifted - * 0..011111110..........0 gen_mask_shifted - * > < gen_shift - */ - //constexpr std::uint64_t gen_mult() const; - constexpr std::uint64_t gen_shift() const; - constexpr std::uint64_t gen_mask_unshifted() const; - constexpr std::uint64_t gen_mask_shifted() const; - - //constexpr std::uint64_t tseq_mult() const; - constexpr std::uint64_t tseq_shift() const; - constexpr std::uint64_t tseq_mask_unshifted() const; - constexpr std::uint64_t tseq_mask_shifted() const; -#endif - - - /** copy of this config, - * with @c arena_config_.size_ set to @p gen_z - **/ - CollectorConfig with_size(std::size_t gen_z); - - generation age2gen(object_age age) const noexcept { - return generation(age % n_survive_threshold_); - } - - public: - // ----- Instance Variables ----- - - /** optional name, for diagnostics **/ - std::string name_; - - /** Configuration for collector spaces. - * Will have at least {nursery,tenured} x {from,to} spaces. - * Not using name_ member. - * - * REQUIRE: - * - arena_config_.store_header_flag_ must be true - **/ - ArenaConfig arena_config_; - - /** storage for N object types requires 8*N bytes **/ - std::size_t object_types_z_ = 2*1024*1024; - - /** storage for N object roots requires 8*N bytes **/ - std::size_t object_roots_z_ = 16*1024; - - /** number of bits to represent generation **/ - std::uint64_t gen_bits_ = 8; - - /** number of bits to represent tseq **/ - std::uint64_t tseq_bits_ = 24; - - /** Number of generations. - * Must be at least 2. - **/ - uint32_t n_generation_ = 2; - - /** Number of promotion steps. - * An object that survives this number of collections - * advances to the next generation. - **/ - uint32_t n_survive_threshold_ = 2; - - /** Trigger garbage collection when to-space allocation for - * generation g reaches gc_trigger_v_[g] - **/ - std::array gc_trigger_v_; - - /** true -> enable incremental collection. - * false -> only do full collection. - * - * Incremental collection requires mutation logs. - **/ - bool allow_incremental_gc_ = true; - - /** If non-zero remember statistics for - * the last @p stats_history_z_ collections. - **/ - uint32_t stats_history_z_ = false; - - /** true to enable debug logging **/ - bool debug_flag_ = false; - }; - // ----- GCRunState ----- /** @class GCRunState @@ -173,7 +76,7 @@ namespace xo { static constexpr size_t c_max_typeseq = 4096; /** Create X1 collector instance. **/ - explicit DX1Collector(const CollectorConfig & cfg); + explicit DX1Collector(const X1CollectorConfig & cfg); /** faceted object pointer to this instance */ template @@ -344,7 +247,7 @@ namespace xo { public: /** garbage collector configuration **/ - CollectorConfig config_; + X1CollectorConfig config_; /** current gc state **/ GCRunState runstate_; diff --git a/xo-gc/include/xo/gc/X1CollectorConfig.hpp b/xo-gc/include/xo/gc/X1CollectorConfig.hpp new file mode 100644 index 00000000..54296e2c --- /dev/null +++ b/xo-gc/include/xo/gc/X1CollectorConfig.hpp @@ -0,0 +1,92 @@ +/** @file X1CollectorConfig.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "object_age.hpp" +#include "generation.hpp" +#include +#include +#include + +namespace xo { + namespace mm { + struct X1CollectorConfig { + using size_type = std::size_t; + + /** copy of this config, + * with @c arena_config_.size_ set to @p gen_z + **/ + X1CollectorConfig with_size(std::size_t gen_z); + + generation age2gen(object_age age) const noexcept { + return generation(age % n_survive_threshold_); + } + + public: + // ----- Instance Variables ----- + + /** optional name, for diagnostics **/ + std::string name_; + + /** Configuration for collector spaces. + * Will have at least {nursery,tenured} x {from,to} spaces. + * Not using name_ member. + * + * REQUIRE: + * - arena_config_.store_header_flag_ must be true + **/ + ArenaConfig arena_config_; + + /** storage for N object types requires 8*N bytes **/ + std::size_t object_types_z_ = 2*1024*1024; + + /** storage for N object roots requires 8*N bytes **/ + std::size_t object_roots_z_ = 16*1024; + + /** number of bits to represent generation **/ + std::uint64_t gen_bits_ = 8; + + /** number of bits to represent tseq **/ + std::uint64_t tseq_bits_ = 24; + + /** Number of generations. + * Must be at least 2. + **/ + uint32_t n_generation_ = 2; + + /** Number of promotion steps. + * An object that survives this number of collections + * advances to the next generation. + **/ + uint32_t n_survive_threshold_ = 2; + + /** Trigger garbage collection when to-space allocation for + * generation g reaches gc_trigger_v_[g] + **/ + std::array gc_trigger_v_; + + /** true -> enable incremental collection. + * false -> only do full collection. + * + * Incremental collection requires mutation logs. + **/ + bool allow_incremental_gc_ = true; + + /** If non-zero remember statistics for + * the last @p stats_history_z_ collections. + **/ + uint32_t stats_history_z_ = false; + + /** true to enable debug logging **/ + bool debug_flag_ = false; + }; + + + } /*namespace mm*/ +} /*namespace xo*/ + +/* end X1CollectorConfig.hpp */ + diff --git a/xo-gc/src/gc/DX1Collector.cpp b/xo-gc/src/gc/DX1Collector.cpp index 3a77e15f..16bdedc3 100644 --- a/xo-gc/src/gc/DX1Collector.cpp +++ b/xo-gc/src/gc/DX1Collector.cpp @@ -25,24 +25,24 @@ namespace xo { namespace mm { - CollectorConfig - CollectorConfig::with_size(std::size_t gen_z) + X1CollectorConfig + X1CollectorConfig::with_size(std::size_t gen_z) { - CollectorConfig copy = *this; + X1CollectorConfig copy = *this; copy.arena_config_ = arena_config_.with_size(gen_z); return copy; } #ifdef NOT_USING constexpr std::uint64_t - CollectorConfig::gen_mult() const { + X1CollectorConfig::gen_mult() const { return 1ul << arena_config_.header_size_bits_; } #endif #ifdef NOT_USING constexpr std::uint64_t - CollectorConfig::tseq_mult() const { + X1CollectorConfig::tseq_mult() const { return 1ul << (gen_bits_ + arena_config_.header_size_bits_); } #endif @@ -69,7 +69,7 @@ namespace xo { using size_type = xo::mm::DX1Collector::size_type; - DX1Collector::DX1Collector(const CollectorConfig & cfg) : config_{cfg} + DX1Collector::DX1Collector(const X1CollectorConfig & cfg) : config_{cfg} { assert(config_.arena_config_.header_.size_bits_ + config_.arena_config_.header_.age_bits_ + diff --git a/xo-gc/utest/Collector.test.cpp b/xo-gc/utest/Collector.test.cpp index f322c286..318c9c21 100644 --- a/xo-gc/utest/Collector.test.cpp +++ b/xo-gc/utest/Collector.test.cpp @@ -23,7 +23,7 @@ namespace xo { using xo::mm::AAllocator; using xo::mm::ACollector; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::DX1Collector; using xo::mm::ArenaConfig; using xo::mm::AllocHeaderConfig; @@ -61,12 +61,12 @@ namespace xo { 0 /*tseq_bits*/, 0 /*age_bits*/, 16 /*size_bits*/), }; - CollectorConfig cfg = { .arena_config_ = arena_cfg, - .n_generation_ = 2, - .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0}} }; + X1CollectorConfig cfg = { .arena_config_ = arena_cfg, + .n_generation_ = 2, + .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}} }; DX1Collector gc = DX1Collector{cfg}; @@ -109,12 +109,12 @@ namespace xo { 0 /*tseq_bits*/, 0 /*age_bits*/, 16 /*size_bits*/), }; - CollectorConfig cfg = { .arena_config_ = arena_cfg, - .n_generation_ = 2, - .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0}} }; + X1CollectorConfig cfg = { .arena_config_ = arena_cfg, + .n_generation_ = 2, + .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}} }; DX1Collector gc = DX1Collector{cfg}; @@ -135,12 +135,12 @@ namespace xo { 0 /*tseq-bits*/, 0 /*age-bits*/, 16 /*size-bits*/), }; - CollectorConfig cfg = { .arena_config_ = arena_cfg, - .n_generation_ = 2, - .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0}} }; + X1CollectorConfig cfg = { .arena_config_ = arena_cfg, + .n_generation_ = 2, + .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}} }; DX1Collector gc = DX1Collector{cfg}; @@ -165,12 +165,12 @@ namespace xo { 16 /*size-bits*/), }; /* collector with one generation collapses to a non-generational copying collector */ - CollectorConfig cfg = { .arena_config_ = arena_cfg, - .n_generation_ = 1, - .gc_trigger_v_ = {{64*1024, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0}} }; + X1CollectorConfig cfg = { .arena_config_ = arena_cfg, + .n_generation_ = 1, + .gc_trigger_v_ = {{64*1024, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}} }; DX1Collector x1state = DX1Collector{cfg}; @@ -209,12 +209,12 @@ namespace xo { }; /* collector with one generation collapses to a non-generational copying collector */ - CollectorConfig cfg = { .arena_config_ = arena_cfg, - .n_generation_ = 1, - .gc_trigger_v_ = {{64*1024, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0}} }; + X1CollectorConfig cfg = { .arena_config_ = arena_cfg, + .n_generation_ = 1, + .gc_trigger_v_ = {{64*1024, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}} }; /* X1 allocator+collector */ DX1Collector x1state = DX1Collector{cfg}; diff --git a/xo-gc/utest/DX1CollectorIterator.test.cpp b/xo-gc/utest/DX1CollectorIterator.test.cpp index 99347fad..314eb4a8 100644 --- a/xo-gc/utest/DX1CollectorIterator.test.cpp +++ b/xo-gc/utest/DX1CollectorIterator.test.cpp @@ -24,7 +24,7 @@ namespace xo { using xo::mm::DX1CollectorIterator; using xo::mm::DArena; using xo::mm::DArenaIterator; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::mm::AllocHeaderConfig; using xo::mm::cmpresult; @@ -51,12 +51,12 @@ namespace xo { 0 /*tseq_bits*/, 0 /*age_bits*/, 16 /*size_bits*/), }; - CollectorConfig cfg = { .arena_config_ = arena_cfg, - .n_generation_ = 2, - .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0}} }; + X1CollectorConfig cfg = { .arena_config_ = arena_cfg, + .n_generation_ = 2, + .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}} }; DX1Collector gc = DX1Collector{cfg}; @@ -94,12 +94,12 @@ namespace xo { 0 /*tseq_bits*/, 0 /*age_bits*/, 16 /*size_bits*/), }; - CollectorConfig cfg = { .arena_config_ = arena_cfg, - .n_generation_ = 2, - .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0}} }; + X1CollectorConfig cfg = { .arena_config_ = arena_cfg, + .n_generation_ = 2, + .gc_trigger_v_ = {{64*1024, 1024*1024, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0}} }; DX1Collector gc = DX1Collector{cfg}; obj a1o{&gc}; diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index ac944a36..466e1a1c 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -21,7 +21,7 @@ add_definitions(${PROJECT_CXX_FLAGS}) # output targets add_subdirectory(src/interpreter2) -#add_subdirectory(utest) +add_subdirectory(utest) xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 0f58f2c4..6e1595da 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -5,9 +5,12 @@ #pragma once +#include "VsmConfig.hpp" #include "VsmInstr.hpp" +#include #include #include +#include namespace xo { namespace scm { @@ -18,10 +21,11 @@ namespace xo { public: // will be DArenaVector> probably using Stack = void *; + using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; public: - VirtualSchematikaMachine(); + VirtualSchematikaMachine(const VsmConfig & config); /** borrow calling thread to run indefinitely, * until halt instruction @@ -93,6 +97,14 @@ namespace xo { * value_ */ + /** configuration **/ + VsmConfig config_; + + box mm_; + + /** reader: text -> expression **/ + SchematikaReader reader_; + /** program counter **/ VsmInstr pc_ = VsmInstr::halt(); diff --git a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp new file mode 100644 index 00000000..5071c020 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp @@ -0,0 +1,28 @@ +/** @file VsmConfig.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include +#include + +namespace xo { + namespace scm { + /** Configuration for virtual schematika machine + **/ + struct VsmConfig { + using X1CollectorConfig = xo::mm::X1CollectorConfig; + + /** reader configuration **/ + ReaderConfig rdr_config_; + /** Configuration for allocator/collector. + * TODO: may want to make CollectorConfig polymorphic + **/ + X1CollectorConfig x1_config_ = X1CollectorConfig().with_size(4*1024*1024); + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VsmConfig.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/init_interpreter2.hpp b/xo-interpreter2/include/xo/interpreter2/init_interpreter2.hpp new file mode 100644 index 00000000..87e93438 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/init_interpreter2.hpp @@ -0,0 +1,21 @@ +/** @file init_interpreter2.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + /* tag to represent the xo-interpreter2/ subsystem within ordered initialization */ + enum S_interpreter2_tag {}; + + template <> + struct InitSubsys { + static void init(); + static InitEvidence require(); + }; +} /*namespace xo*/ + +/* end init_interpreter2.hpp */ diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 15d06fdf..7d9cd250 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -2,6 +2,7 @@ set(SELF_LIB xo_interpreter2) set(SELF_SRCS + init_interpreter2.cpp VirtualSchematikaMachine.cpp #IExpression_Any.cpp #interpreter2_register_facets.cpp @@ -9,7 +10,7 @@ set(SELF_SRCS xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) # note: deps here must also appear in cmake/xo_interpreter2Config.cmake.in -xo_dependency(${SELF_LIB} xo_expression2) +xo_dependency(${SELF_LIB} xo_reader2) xo_dependency(${SELF_LIB} xo_gc) #xo_dependency(${SELF_LIB} reflect) #xo_dependency(${SELF_LIB} xo_printable2) diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 02ed023a..f7e8259e 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -6,12 +6,19 @@ #include "VirtualSchematikaMachine.hpp" #include #include +#include +#include #include namespace xo { + using xo::mm::DX1Collector; + namespace scm { - VirtualSchematikaMachine::VirtualSchematikaMachine() + VirtualSchematikaMachine::VirtualSchematikaMachine(const VsmConfig & config) + : config_{config}, + mm_(box(new DX1Collector(config.x1_config_))), + reader_{config.rdr_config_, mm_.to_op()} {} void diff --git a/xo-interpreter2/src/interpreter2/init_interpreter2.cpp b/xo-interpreter2/src/interpreter2/init_interpreter2.cpp new file mode 100644 index 00000000..b0e8a71c --- /dev/null +++ b/xo-interpreter2/src/interpreter2/init_interpreter2.cpp @@ -0,0 +1,50 @@ +/** @file init_interpreter2.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "init_interpreter2.hpp" + +#ifdef NOT_YET +#include "interpreter2_register_facets.hpp" +#include "interpreter2_register_types.hpp" +#endif + +#include +#ifdef NOT_YET +#include +#endif + +namespace xo { +#ifdef NOT_YET + using xo::scm::interpreter2_register_facets; + using xo::scm::interpreter2_register_types; + using xo::mm::CollectorTypeRegistry; +#endif + + void + InitSubsys::init() + { +#ifdef NOT_YET + interpreter2_register_facets(); + + CollectorTypeRegistry::instance().register_types(&interpreter2_register_types); +#endif + } + + InitEvidence + InitSubsys::require() + { + InitEvidence retval; + + /* direct subsystem deps for xo-interpreter2/ */ + retval ^= InitSubsys::require(); + + /* xo-interpreter2/'s own initialization code */ + retval ^= Subsystem::provide("interpreter2", &init); + + return retval; + } +} /*namespace xo*/ + +/* end init_interpreter2.cpp */ diff --git a/xo-interpreter2/utest/CMakeLists.txt b/xo-interpreter2/utest/CMakeLists.txt new file mode 100644 index 00000000..e45cffaa --- /dev/null +++ b/xo-interpreter2/utest/CMakeLists.txt @@ -0,0 +1,11 @@ +# build unittest xo-interpreter2/utest + +set(UTEST_EXE utest.interpreter2) +set(UTEST_SRCS + interpreter2_utest_main.cpp + VirtualSchematikaMachine.test.cpp +) + +xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) +xo_self_dependency(${UTEST_EXE} xo_interpreter2) +xo_external_target_dependency(${UTEST_EXE} Catch2 Catch2::Catch2) diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp new file mode 100644 index 00000000..29301b1f --- /dev/null +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -0,0 +1,63 @@ +/** @file VirtualSchematikaMachine.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include + +#ifdef NOT_YET +#include +#include +#include +#include +#include +#endif +#include +#ifdef NOT_YET +#include +#endif + +#include + +namespace xo { +#ifdef NOT_YET + using xo::scm::SchematikaParser; + using xo::scm::ASyntaxStateMachine; + using xo::scm::syntaxstatetype; +// using xo::scm::DDefineSsm; + using xo::scm::DExpectExprSsm; +// using xo::scm::defexprstatetype; + //using xo::scm::ParserResult; + //using xo::scm::parser_result_type; + using xo::scm::Token; + using xo::scm::DString; + using xo::mm::ArenaConfig; + using xo::mm::AAllocator; + using xo::mm::DArena; + using xo::facet::with_facet; +#endif + + static InitEvidence s_init = (InitSubsys::require()); + + namespace ut { + TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]") + { +#ifdef NOT_YET + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + REQUIRE(parser.debug_flag() == false); + REQUIRE(parser.is_at_toplevel() == true); +#endif + } + + } /*namespace ut*/ +} /*namespace xo*/ + +/* end SchematikaParser.test.cpp */ diff --git a/xo-interpreter2/utest/interpreter2_utest_main.cpp b/xo-interpreter2/utest/interpreter2_utest_main.cpp new file mode 100644 index 00000000..addc079a --- /dev/null +++ b/xo-interpreter2/utest/interpreter2_utest_main.cpp @@ -0,0 +1,27 @@ +/** @file interpreter2_utest_main.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include + +#define CATCH_CONFIG_RUNNER +#include "catch2/catch.hpp" + +int +main(int argc, char* argv[]) +{ + using xo::Subsystem; + + // initialize subsystems + Subsystem::initialize_all(); + + // Run Catch2's test session + int result = Catch::Session().run(argc, argv); + + // cleanup here, if any + + return result; +} + +/* end interpreter2_utest_main.cpp */ diff --git a/xo-object2/utest/Printable.test.cpp b/xo-object2/utest/Printable.test.cpp index 6c09ca90..64736d22 100644 --- a/xo-object2/utest/Printable.test.cpp +++ b/xo-object2/utest/Printable.test.cpp @@ -44,7 +44,7 @@ namespace ut { using xo::mm::ACollector; using xo::mm::AGCObject; using xo::mm::DX1Collector; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::print::APrintable; using xo::facet::FacetRegistry; @@ -99,15 +99,14 @@ namespace ut { try { const testcase_pp & tc = s_testcase_v[i_tc]; - CollectorConfig cfg{ - .name_ = "pp_test", - .arena_config_ = ArenaConfig{ - .size_ = tc.gc_gen_size_, - .store_header_flag_ = true}, - .object_types_z_ = 16384, - .gc_trigger_v_{{tc.gc_trigger_threshold_, - tc.gc_trigger_threshold_}}, - .debug_flag_ = c_debug_flag + X1CollectorConfig cfg{ .name_ = "pp_test", + .arena_config_ = ArenaConfig{ + .size_ = tc.gc_gen_size_, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{tc.gc_trigger_threshold_, + tc.gc_trigger_threshold_}}, + .debug_flag_ = c_debug_flag }; DX1Collector gc(cfg); diff --git a/xo-object2/utest/X1Collector.test.cpp b/xo-object2/utest/X1Collector.test.cpp index 0f20e68a..90122c25 100644 --- a/xo-object2/utest/X1Collector.test.cpp +++ b/xo-object2/utest/X1Collector.test.cpp @@ -48,7 +48,7 @@ namespace ut { using xo::mm::AGCObject; using xo::mm::DX1Collector; using xo::mm::DArena; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::mm::generation; using xo::mm::role; @@ -108,16 +108,15 @@ namespace ut { try { const testcase_x1 & tc = s_testcase_v[i_tc]; - CollectorConfig cfg{ - .name_ = "x1_test", - .arena_config_ = ArenaConfig{ - .size_ = tc.tenured_z_, - .store_header_flag_ = true}, - .object_types_z_ = 16384, - .gc_trigger_v_{{ - tc.incr_gc_threshold_, - tc.full_gc_threshold_}}, - .debug_flag_ = c_debug_flag, + X1CollectorConfig cfg{ .name_ = "x1_test", + .arena_config_ = ArenaConfig{ + .size_ = tc.tenured_z_, + .store_header_flag_ = true}, + .object_types_z_ = 16384, + .gc_trigger_v_{{ + tc.incr_gc_threshold_, + tc.full_gc_threshold_}}, + .debug_flag_ = c_debug_flag, }; DX1Collector gc(cfg); diff --git a/xo-reader2/example/readerreplxx/readerreplxx.cpp b/xo-reader2/example/readerreplxx/readerreplxx.cpp index 122b2730..c95dd101 100644 --- a/xo-reader2/example/readerreplxx/readerreplxx.cpp +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -136,7 +136,7 @@ namespace { struct AppConfig { using ReaderConfig = xo::scm::ReaderConfig; - using CollectorConfig = xo::mm::CollectorConfig; + using X1CollectorConfig = xo::mm::X1CollectorConfig; AppConfig() { rdr_config_.reader_debug_flag_ = true; @@ -146,17 +146,17 @@ struct AppConfig { std::size_t max_history_size_ = 1000; std::string repl_history_fname_ = "repl_history.txt";; - CollectorConfig x1_config_ = (CollectorConfig().with_size(4*1024*1024)); ReaderConfig rdr_config_; + X1CollectorConfig x1_config_ = (X1CollectorConfig().with_size(4*1024*1024)); }; struct AppContext { using DX1Collector = xo::mm::DX1Collector; - using CollectorConfig = xo::mm::CollectorConfig; + using X1CollectorConfig = xo::mm::X1CollectorConfig; using Replxx = replxx::Replxx; AppContext(const AppConfig & cfg = AppConfig()) : config_{cfg}, - x1_{CollectorConfig().with_size(4*1024*1024)}, + x1_{X1CollectorConfig().with_size(4*1024*1024)}, rdr_{config_.rdr_config_, x1_.ref()} { rx_.set_max_history_size(config_.max_history_size_); From 7028fa49f8ef463409127682c9931bf6ef9185d8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 2 Feb 2026 10:53:28 -0500 Subject: [PATCH 145/258] xo-interpreter2: refactor to setup vsm utest + repl --- .../include/xo/alloc2/alloc/RAllocator.hpp | 3 ++ xo-expression2/utest/DApplyExpr.test.cpp | 14 ++--- xo-expression2/utest/DConstant.test.cpp | 10 ++-- xo-expression2/utest/DDefineExpr.test.cpp | 16 +++--- xo-expression2/utest/DIfElseExpr.test.cpp | 20 +++---- xo-expression2/utest/DVariable.test.cpp | 12 ++--- xo-facet/include/xo/facet/box.hpp | 12 +++-- .../interpreter2/VirtualSchematikaMachine.hpp | 24 +++++++++ .../include/xo/interpreter2/VsmConfig.hpp | 4 +- .../interpreter2/VirtualSchematikaMachine.cpp | 54 +++++++++++++++++++ .../utest/VirtualSchematikaMachine.test.cpp | 5 ++ .../include/xo/reader2/ReaderConfig.hpp | 2 +- 12 files changed, 133 insertions(+), 43 deletions(-) diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index c07b5e81..bbd35d5c 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -27,6 +27,9 @@ namespace xo { RAllocator() {} RAllocator(Object::DataPtr data) : Object{std::move(data)} {} + RAllocator(const AAllocator * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } void _drop() const noexcept { O::iface()->_drop(O::data()); } diff --git a/xo-expression2/utest/DApplyExpr.test.cpp b/xo-expression2/utest/DApplyExpr.test.cpp index d151b776..f217d47e 100644 --- a/xo-expression2/utest/DApplyExpr.test.cpp +++ b/xo-expression2/utest/DApplyExpr.test.cpp @@ -47,7 +47,7 @@ namespace ut { using xo::mm::ACollector; using xo::mm::AGCObject; using xo::mm::DX1Collector; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::print::APrintable; using xo::print::ppstate_standalone; @@ -71,7 +71,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dapplyexpr_make2_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -111,7 +111,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dapplyexpr_extype_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -146,7 +146,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dapplyexpr_n_args_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -181,7 +181,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dapplyexpr_fn_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -219,7 +219,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dapplyexpr_arg_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -263,7 +263,7 @@ namespace ut { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dapplyexpr_pretty_test", .arena_config_ = ArenaConfig{ .size_ = 8192, diff --git a/xo-expression2/utest/DConstant.test.cpp b/xo-expression2/utest/DConstant.test.cpp index ddff5b20..fd8e9b1b 100644 --- a/xo-expression2/utest/DConstant.test.cpp +++ b/xo-expression2/utest/DConstant.test.cpp @@ -39,7 +39,7 @@ namespace ut { using xo::mm::ACollector; using xo::mm::AGCObject; using xo::mm::DX1Collector; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::print::APrintable; using xo::print::ppstate_standalone; @@ -66,7 +66,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dconstant_float_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -105,7 +105,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dconstant_int_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -146,7 +146,7 @@ namespace ut { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dconstant_pp_float_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -190,7 +190,7 @@ namespace ut { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dconstant_pp_int_test", .arena_config_ = ArenaConfig{ .size_ = 8192, diff --git a/xo-expression2/utest/DDefineExpr.test.cpp b/xo-expression2/utest/DDefineExpr.test.cpp index 5bb91582..5f78891d 100644 --- a/xo-expression2/utest/DDefineExpr.test.cpp +++ b/xo-expression2/utest/DDefineExpr.test.cpp @@ -44,7 +44,7 @@ namespace ut { using xo::mm::ACollector; using xo::mm::AGCObject; using xo::mm::DX1Collector; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::print::APrintable; using xo::print::ppstate_standalone; @@ -68,7 +68,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "ddefineexpr_make_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -103,7 +103,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "ddefineexpr_lhs_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -138,7 +138,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "ddefineexpr_rhs_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -174,7 +174,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "ddefineexpr_name_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -207,7 +207,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "ddefineexpr_extype_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -239,7 +239,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "ddefineexpr_valuetype_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -273,7 +273,7 @@ namespace ut { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "ddefineexpr_pretty_test", .arena_config_ = ArenaConfig{ .size_ = 8192, diff --git a/xo-expression2/utest/DIfElseExpr.test.cpp b/xo-expression2/utest/DIfElseExpr.test.cpp index a82521a0..2dee2f26 100644 --- a/xo-expression2/utest/DIfElseExpr.test.cpp +++ b/xo-expression2/utest/DIfElseExpr.test.cpp @@ -42,15 +42,15 @@ namespace ut { using xo::mm::ACollector; using xo::mm::AGCObject; using xo::mm::DX1Collector; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::print::APrintable; using xo::print::ppstate_standalone; using xo::print::ppconfig; - using xo::facet::FacetRegistry; + //using xo::facet::FacetRegistry; using xo::facet::with_facet; using xo::facet::obj; - using xo::reflect::Reflect; + //using xo::reflect::Reflect; using xo::InitEvidence; using xo::InitSubsys; using xo::scope; @@ -66,7 +66,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "difelseexpr_make_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -107,7 +107,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "difelseexpr_test_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -145,7 +145,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "difelseexpr_when_true_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -183,7 +183,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "difelseexpr_when_false_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -221,7 +221,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "difelseexpr_extype_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -256,7 +256,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "difelseexpr_valuetype_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -296,7 +296,7 @@ namespace ut { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "difelseexpr_pretty_test", .arena_config_ = ArenaConfig{ .size_ = 8192, diff --git a/xo-expression2/utest/DVariable.test.cpp b/xo-expression2/utest/DVariable.test.cpp index 8afee360..9c26a7c4 100644 --- a/xo-expression2/utest/DVariable.test.cpp +++ b/xo-expression2/utest/DVariable.test.cpp @@ -37,7 +37,7 @@ namespace ut { using xo::mm::AAllocator; using xo::mm::ACollector; using xo::mm::DX1Collector; - using xo::mm::CollectorConfig; + using xo::mm::X1CollectorConfig; using xo::mm::ArenaConfig; using xo::print::APrintable; using xo::print::ppstate_standalone; @@ -61,7 +61,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dvariable_make_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -92,7 +92,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dvariable_extype_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -122,7 +122,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dvariable_valuetype_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -152,7 +152,7 @@ namespace ut { { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dvariable_name_test", .arena_config_ = ArenaConfig{ .size_ = 8192, @@ -185,7 +185,7 @@ namespace ut { REQUIRE(s_init.evidence()); - CollectorConfig cfg{ + X1CollectorConfig cfg{ .name_ = "dvariable_pretty_test", .arena_config_ = ArenaConfig{ .size_ = 8192, diff --git a/xo-facet/include/xo/facet/box.hpp b/xo-facet/include/xo/facet/box.hpp index 25a6561e..54e724ed 100644 --- a/xo-facet/include/xo/facet/box.hpp +++ b/xo-facet/include/xo/facet/box.hpp @@ -46,7 +46,7 @@ namespace xo { box(box && other) requires (std::is_same_v || std::is_same_v) - : obj() + : RoutingType>() { /* replacing .iface_ along w/ .data_ */ this->from_obj(other); @@ -55,8 +55,10 @@ namespace xo { } /** explicit conversion to obj **/ - obj to_op() const noexcept { return obj(this->iface(), this->data()); } - + obj to_op() const noexcept { + return obj(this->iface(), this->data()); + } + /** Take ownership from unowned object **/ template box & adopt(const obj & other) @@ -65,11 +67,11 @@ namespace xo { { /* replace .iface_ along w/ .data_ */ this->from_obj(other); - + return *this; } - ~box() { + ~box() { auto p = this->data(); this->_drop(); ::operator delete(p); diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 6e1595da..c9dc0749 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -14,6 +14,23 @@ namespace xo { namespace scm { + /** similar to @ref xo::scm::ReaderResult **/ + struct VsmResult { + using AGCObject = xo::mm::AGCObject; + using span_type = xo::mm::span; + + bool is_tk_error() const { return tk_error_.is_error(); } + + /** result of evaluating first expression encountered in input **/ + obj value_; + + /** unconsumed portion of input span **/ + span_type remaining_input_; + + /** {src_function, error_description, input_state, error_pos} **/ + TokenizerError tk_error_; + }; + /** @class VirtualSchematikaMachine * @brief virtual machine for schematika **/ @@ -23,10 +40,17 @@ namespace xo { using Stack = void *; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; + using span_type = xo::mm::span; public: VirtualSchematikaMachine(const VsmConfig & config); + /** consume input @p input_cstr **/ + VsmResult read_eval_print(span_type input_span, bool eof); + + /** evaluate expression @p expr **/ + std::pair, TokenizerError> eval(obj expr); + /** borrow calling thread to run indefinitely, * until halt instruction **/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp index 5071c020..2957b297 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp @@ -10,11 +10,13 @@ namespace xo { namespace scm { - /** Configuration for virtual schematika machine + /** Configuration for virtual schematika machine **/ struct VsmConfig { using X1CollectorConfig = xo::mm::X1CollectorConfig; + VsmConfig() = default; + /** reader configuration **/ ReaderConfig rdr_config_; /** Configuration for allocator/collector. diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index f7e8259e..fabc5441 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -8,10 +8,18 @@ #include #include #include +#include +#include #include namespace xo { + using xo::print::APrintable; + using xo::print::ppconfig; + using xo::print::ppstate_standalone; + using xo::mm::AGCObject; using xo::mm::DX1Collector; + using xo::facet::FacetRegistry; + using std::cout; namespace scm { @@ -21,6 +29,52 @@ namespace xo { reader_{config.rdr_config_, mm_.to_op()} {} + VsmResult + VirtualSchematikaMachine::read_eval_print(span_type input, bool eof) + { + if (input.empty()) { + return VsmResult(); + } + + auto [expr, remaining, error1] + = reader_.read_expr(input, eof); + + if (!expr) { + return { + .remaining_input_ = remaining, + .tk_error_ = error1 + }; + } + + auto [value, error2] = this->eval(expr); + + if (!value) { + return { + .remaining_input_ = remaining, + .tk_error_ = error2 + }; + } + + obj value_pr + = FacetRegistry::instance().variant(value); + + // pretty_toplevel(value_pr, &cout, ppconfig()); + ppconfig ppc; + ppstate_standalone pps(&cout, 0, &ppc); + pps.prettyn(value_pr); + + return { .remaining_input_ = remaining }; + } + + std::pair, TokenizerError> + VirtualSchematikaMachine::eval(obj expr) + { + (void)expr; + + assert(false); + return std::make_pair(obj(), TokenizerError()); + } + void VirtualSchematikaMachine::run() { diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 29301b1f..8dacb437 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -20,6 +20,9 @@ #include namespace xo { + using xo::scm::VirtualSchematikaMachine; + using xo::scm::VsmConfig; + #ifdef NOT_YET using xo::scm::SchematikaParser; using xo::scm::ASyntaxStateMachine; @@ -42,6 +45,8 @@ namespace xo { namespace ut { TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]") { + VirtualSchematikaMachine vsm(VsmConfig); + #ifdef NOT_YET ArenaConfig config; config.name_ = "test-arena"; diff --git a/xo-reader2/include/xo/reader2/ReaderConfig.hpp b/xo-reader2/include/xo/reader2/ReaderConfig.hpp index 826bb215..5b02e62c 100644 --- a/xo-reader2/include/xo/reader2/ReaderConfig.hpp +++ b/xo-reader2/include/xo/reader2/ReaderConfig.hpp @@ -41,7 +41,7 @@ namespace xo { size_t max_stringtable_cap_ = 64*1024; /** debug flag for schematika_reader **/ - bool reader_debug_flag_ = false;; + bool reader_debug_flag_ = false; }; } /*namespace scm*/ From f6aae4190e27b10f3ccfca6f1719e055d9ec0949 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 2 Feb 2026 21:55:34 -0500 Subject: [PATCH 146/258] xo-interpreter2: scaffold repl + alloc measurement frameowkr --- xo-alloc2/CMakeLists.txt | 17 ++ xo-alloc2/idl/ResourceVisitor.json5 | 49 ++++ .../include/xo/alloc2/ResourceVisitor.hpp | 22 ++ .../xo/alloc2/visitor/AResourceVisitor.hpp | 74 ++++++ .../alloc2/visitor/IResourceVisitor_Any.hpp | 86 +++++++ .../alloc2/visitor/IResourceVisitor_Xfer.hpp | 81 ++++++ .../xo/alloc2/visitor/RResourceVisitor.hpp | 80 ++++++ xo-alloc2/src/alloc2/CMakeLists.txt | 2 + xo-alloc2/src/alloc2/IResourceVisitor_Any.cpp | 41 +++ xo-arena/include/xo/arena/ArenaConfig.hpp | 6 + xo-arena/include/xo/arena/DArena.hpp | 5 + xo-arena/include/xo/arena/DArenaHashMap.hpp | 6 + xo-arena/include/xo/arena/DArenaVector.hpp | 5 + xo-arena/include/xo/arena/DCircularBuffer.hpp | 3 + xo-arena/include/xo/arena/ErrorArena.hpp | 54 ++++ xo-arena/include/xo/arena/MemorySizeInfo.hpp | 37 +++ xo-arena/include/xo/arena/arena_streambuf.hpp | 236 ++++++++++++++++++ .../include/xo/arena/hashmap/HashMapStore.hpp | 13 + xo-arena/src/arena/CMakeLists.txt | 2 + xo-arena/src/arena/DArena.cpp | 9 + xo-arena/src/arena/DCircularBuffer.cpp | 25 ++ xo-arena/src/arena/ErrorArena.cpp | 43 ++++ xo-arena/src/arena/arena_streambuf.cpp | 214 ++++++++++++++++ .../include/xo/expression2/StringTable.hpp | 4 + .../src/expression2/StringTable.cpp | 19 ++ xo-facet/include/xo/facet/box.hpp | 7 +- .../include/xo/indentlog/log_state.hpp | 151 ----------- .../interpreter2/VirtualSchematikaMachine.hpp | 63 ++++- .../include/xo/interpreter2/VsmConfig.hpp | 3 + .../include/xo/interpreter2/VsmInstr.hpp | 4 +- .../src/interpreter2/CMakeLists.txt | 1 + .../interpreter2/VirtualSchematikaMachine.cpp | 73 ++++-- xo-interpreter2/src/interpreter2/VsmInstr.cpp | 18 ++ .../utest/VirtualSchematikaMachine.test.cpp | 35 ++- .../include/xo/reader2/ParserStateMachine.hpp | 6 + .../include/xo/reader2/SchematikaParser.hpp | 6 + .../include/xo/reader2/SchematikaReader.hpp | 9 + xo-reader2/src/reader2/ParserStateMachine.cpp | 24 ++ xo-reader2/src/reader2/SchematikaParser.cpp | 13 + xo-reader2/src/reader2/SchematikaReader.cpp | 31 +++ .../include/xo/tokenizer2/Tokenizer.hpp | 6 + xo-tokenizer2/src/tokenizer2/Tokenizer.cpp | 13 + 42 files changed, 1398 insertions(+), 198 deletions(-) create mode 100644 xo-alloc2/idl/ResourceVisitor.json5 create mode 100644 xo-alloc2/include/xo/alloc2/ResourceVisitor.hpp create mode 100644 xo-alloc2/include/xo/alloc2/visitor/AResourceVisitor.hpp create mode 100644 xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Any.hpp create mode 100644 xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Xfer.hpp create mode 100644 xo-alloc2/include/xo/alloc2/visitor/RResourceVisitor.hpp create mode 100644 xo-alloc2/src/alloc2/IResourceVisitor_Any.cpp create mode 100644 xo-arena/include/xo/arena/ErrorArena.hpp create mode 100644 xo-arena/include/xo/arena/MemorySizeInfo.hpp create mode 100644 xo-arena/include/xo/arena/arena_streambuf.hpp create mode 100644 xo-arena/src/arena/ErrorArena.cpp create mode 100644 xo-arena/src/arena/arena_streambuf.cpp create mode 100644 xo-interpreter2/src/interpreter2/VsmInstr.cpp diff --git a/xo-alloc2/CMakeLists.txt b/xo-alloc2/CMakeLists.txt index afe3d225..54a2cc4c 100644 --- a/xo-alloc2/CMakeLists.txt +++ b/xo-alloc2/CMakeLists.txt @@ -18,6 +18,23 @@ add_definitions(${PROJECT_CXX_FLAGS}) # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacet( + TARGET xo-alloc2-facet-resourcevisitor + FACET ResourceVisitor + INPUT idl/ResourceVisitor.json5 + OUTPUT_HPP_DIR include/xo/alloc2 + OUTPUT_IMPL_SUBDIR visitor + OUTPUT_CPP_DIR src/alloc2 +) + +# ---------------------------------------------------------------- + +xo_add_genfacet_all(xo-alloc2-genfacet-all) + +# ---------------------------------------------------------------- + + # must complete definition of expression lib before configuring examples add_subdirectory(src/alloc2) add_subdirectory(utest) diff --git a/xo-alloc2/idl/ResourceVisitor.json5 b/xo-alloc2/idl/ResourceVisitor.json5 new file mode 100644 index 00000000..a3369649 --- /dev/null +++ b/xo-alloc2/idl/ResourceVisitor.json5 @@ -0,0 +1,49 @@ +{ + mode: "facet", + includes: [ + "\"Allocator.hpp\"" + ], + // extra includes in ResourceVisitor.hpp, if any + user_hpp_includes: [], + namespace1: "xo", + namespace2: "mm", + // text after includes, before AResourceVisitor + pretext: [ "// {pretext} here" ], + facet: "ResourceVisitor", + detail_subdir: "visitor", + brief: "visitor to inspect resource consumption", + using_doxygen: true, + doc: [ + "Visitor to receive measured resource consumption" + ], + types: [ + // using size_type = std::size_t + { + name: "size_type", + doc: ["type for length of a sequence"], + definition: "std::size_t", + }, +// // using AGCObject = xo::mm::AGCObject +// { +// name: "AGCObject", +// doc: ["facet for types with GC support"], +// definition: "xo::mm::AGCObject", +// } + ], + const_methods: [ + // bool on_memory(name, allocated, committed, reserved) const noexcept + { + name: "on_allocator", + doc: ["report memory consumption"], + return_type: "void", + args: [ + {type: "obj", name: "mm"}, + ], + const: true, + noexcept: true, + attributes: [], + }, + ], + nonconst_methods: [ + ], +} diff --git a/xo-alloc2/include/xo/alloc2/ResourceVisitor.hpp b/xo-alloc2/include/xo/alloc2/ResourceVisitor.hpp new file mode 100644 index 00000000..b995e891 --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/ResourceVisitor.hpp @@ -0,0 +1,22 @@ +/** @file ResourceVisitor.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ResourceVisitor.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/ResourceVisitor.json5] + **/ + +#pragma once + +#include "visitor/AResourceVisitor.hpp" +#include "visitor/IResourceVisitor_Any.hpp" +#include "visitor/IResourceVisitor_Xfer.hpp" +#include "visitor/RResourceVisitor.hpp" + + +/* end ResourceVisitor.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/visitor/AResourceVisitor.hpp b/xo-alloc2/include/xo/alloc2/visitor/AResourceVisitor.hpp new file mode 100644 index 00000000..1466474a --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/visitor/AResourceVisitor.hpp @@ -0,0 +1,74 @@ +/** @file AResourceVisitor.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ResourceVisitor.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/ResourceVisitor.json5] + **/ + +#pragma once + +// includes (via {facet_includes}) +#include "Allocator.hpp" +#include +#include +#include + +// {pretext} here + +namespace xo { +namespace mm { + +using Copaque = const void *; +using Opaque = void *; + +/** +Visitor to receive measured resource consumption +**/ +class AResourceVisitor { +public: + /** @defgroup mm-resourcevisitor-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; + /** type for length of a sequence **/ + using size_type = std::size_t; + ///@} + + /** @defgroup mm-resourcevisitor-methods **/ + ///@{ + // const methods + /** RTTI: unique id# for actual runtime data representation **/ + virtual typeseq _typeseq() const noexcept = 0; + /** report memory consumption **/ + virtual void on_allocator(Copaque data, obj mm) const noexcept = 0; + + // nonconst methods + ///@} +}; /*AResourceVisitor*/ + +/** Implementation IResourceVisitor_DRepr of AResourceVisitor for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = IResourceVisitor_DRepr; + * }; + * + * then IResourceVisitor_ImplType --> IResourceVisitor_DRepr + **/ +template +using IResourceVisitor_ImplType = xo::facet::FacetImplType; + +} /*namespace mm*/ +} /*namespace xo*/ + +/* AResourceVisitor.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Any.hpp b/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Any.hpp new file mode 100644 index 00000000..a0d3e3c3 --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Any.hpp @@ -0,0 +1,86 @@ +/** @file IResourceVisitor_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ResourceVisitor.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ResourceVisitor.json5] + **/ + +#pragma once + +#include "AResourceVisitor.hpp" +#include + +namespace xo { namespace mm { class IResourceVisitor_Any; } } + +namespace xo { +namespace facet { + +template <> +struct FacetImplementation +{ + using ImplType = xo::mm::IResourceVisitor_Any; +}; + +} +} + +namespace xo { +namespace mm { + + /** @class IResourceVisitor_Any + * @brief AResourceVisitor implementation for empty variant instance + **/ + class IResourceVisitor_Any : public AResourceVisitor { + public: + /** @defgroup mm-resourcevisitor-any-type-traits **/ + ///@{ + + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using size_type = AResourceVisitor::size_type; + + ///@} + /** @defgroup mm-resourcevisitor-any-methods **/ + ///@{ + + const AResourceVisitor * iface() const { return std::launder(this); } + + // from AResourceVisitor + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void on_allocator(Copaque, obj) const noexcept override { _fatal(); } + + // nonconst methods + + ///@} + + private: + /** @defgraoup mm-resourcevisitor-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup mm-resourcevisitor-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace mm */ +} /*namespace xo */ + +/* IResourceVisitor_Any.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Xfer.hpp b/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Xfer.hpp new file mode 100644 index 00000000..2ff8abdb --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Xfer.hpp @@ -0,0 +1,81 @@ +/** @file IResourceVisitor_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ResourceVisitor.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ResourceVisitor.json5] + **/ + +#pragma once + +#include "Allocator.hpp" + +namespace xo { +namespace mm { + /** @class IResourceVisitor_Xfer + **/ + template + class IResourceVisitor_Xfer : public AResourceVisitor { + public: + /** @defgroup mm-resourcevisitor-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = IResourceVisitor_DRepr; + /** integer identifying a type **/ + using typeseq = AResourceVisitor::typeseq; + using size_type = AResourceVisitor::size_type; + ///@} + + /** @defgroup mm-resourcevisitor-xfer-methods **/ + ///@{ + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + + // from AResourceVisitor + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + void on_allocator(Copaque data, obj mm) const noexcept override { + return I::on_allocator(_dcast(data), mm); + } + + // non-const methods + + ///@} + + private: + using I = Impl; + + public: + /** @defgroup mm-resourcevisitor-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + xo::facet::typeseq + IResourceVisitor_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + IResourceVisitor_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace mm */ +} /*namespace xo*/ + +/* end IResourceVisitor_Xfer.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/visitor/RResourceVisitor.hpp b/xo-alloc2/include/xo/alloc2/visitor/RResourceVisitor.hpp new file mode 100644 index 00000000..3396e6e7 --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/visitor/RResourceVisitor.hpp @@ -0,0 +1,80 @@ +/** @file RResourceVisitor.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ResourceVisitor.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ResourceVisitor.json5] + **/ + +#pragma once + +#include "AResourceVisitor.hpp" + +namespace xo { +namespace mm { + +/** @class RResourceVisitor + **/ +template +class RResourceVisitor : public Object { +private: + using O = Object; + +public: + /** @defgroup mm-resourcevisitor-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; + using size_type = AResourceVisitor::size_type; + ///@} + + /** @defgroup mm-resourcevisitor-router-ctors **/ + ///@{ + RResourceVisitor() {} + RResourceVisitor(Object::DataPtr data) : Object{std::move(data)} {} + RResourceVisitor(const AResourceVisitor * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} + + ///@} + /** @defgroup mm-resourcevisitor-router-methods **/ + ///@{ + + // const methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void on_allocator(obj mm) const noexcept { + return O::iface()->on_allocator(O::data(), mm); + } + + // non-const methods (still const in router!) + + ///@} + /** @defgroup mm-resourcevisitor-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RResourceVisitor::_valid = xo::facet::valid_object_router(); + +} /*namespace mm*/ +} /*namespace xo*/ + +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::mm::RResourceVisitor; + }; +} } + +/* end RResourceVisitor.hpp */ diff --git a/xo-alloc2/src/alloc2/CMakeLists.txt b/xo-alloc2/src/alloc2/CMakeLists.txt index 3a279746..7cebc7ae 100644 --- a/xo-alloc2/src/alloc2/CMakeLists.txt +++ b/xo-alloc2/src/alloc2/CMakeLists.txt @@ -17,6 +17,8 @@ set(SELF_SRCS # DArenaIterator.cpp IAllocIterator_DArenaIterator.cpp + IResourceVisitor_Any.cpp + ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/xo-alloc2/src/alloc2/IResourceVisitor_Any.cpp b/xo-alloc2/src/alloc2/IResourceVisitor_Any.cpp new file mode 100644 index 00000000..2d9fb12a --- /dev/null +++ b/xo-alloc2/src/alloc2/IResourceVisitor_Any.cpp @@ -0,0 +1,41 @@ +/** @file IResourceVisitor_Any.cpp + * + **/ + +#include "visitor/IResourceVisitor_Any.hpp" +#include + +namespace xo { +namespace mm { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +IResourceVisitor_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " IResourceVisitor_Any method" + << std::endl; + std::terminate(); +} + +typeseq +IResourceVisitor_Any::s_typeseq = typeseq::id(); + +bool +IResourceVisitor_Any::_valid + = valid_facet_implementation(); + +// nonconst methods + + +} /*namespace mm*/ +} /*namespace xo*/ + +/* end IResourceVisitor_Any.cpp */ diff --git a/xo-arena/include/xo/arena/ArenaConfig.hpp b/xo-arena/include/xo/arena/ArenaConfig.hpp index db5a4400..4d72b912 100644 --- a/xo-arena/include/xo/arena/ArenaConfig.hpp +++ b/xo-arena/include/xo/arena/ArenaConfig.hpp @@ -19,6 +19,12 @@ namespace xo { struct ArenaConfig { /** @defgroup mm-arenaconfig-ctors **/ + ArenaConfig with_name(std::string name) { + ArenaConfig copy(*this); + copy.name_ = name; + return copy; + } + ArenaConfig with_size(std::size_t z) { ArenaConfig copy(*this); copy.size_ = z; diff --git a/xo-arena/include/xo/arena/DArena.hpp b/xo-arena/include/xo/arena/DArena.hpp index ffd710f0..8c7203d6 100644 --- a/xo-arena/include/xo/arena/DArena.hpp +++ b/xo-arena/include/xo/arena/DArena.hpp @@ -7,6 +7,7 @@ #include "ArenaConfig.hpp" #include "AllocError.hpp" +#include "MemorySizeInfo.hpp" #include "AllocInfo.hpp" #include @@ -140,6 +141,9 @@ namespace xo { /** get header from allocated object address **/ header_type * obj2hdr(void * obj) noexcept; + /** resource ocnsumption in normal form **/ + MemorySizeInfo _store_info() const noexcept; + /** report alloc book-keeping info for allocation at @p mem * * Require: @@ -206,6 +210,7 @@ namespace xo { /** restore arena state to previously-established checkpoint **/ void restore(Checkpoint ckp) noexcept { free_ = ckp.free_; } + /** discard all allocated memory, return to empty state * Promise: * - committed memory unchanged diff --git a/xo-arena/include/xo/arena/DArenaHashMap.hpp b/xo-arena/include/xo/arena/DArenaHashMap.hpp index 50b7b4aa..042dc900 100644 --- a/xo-arena/include/xo/arena/DArenaHashMap.hpp +++ b/xo-arena/include/xo/arena/DArenaHashMap.hpp @@ -45,6 +45,7 @@ namespace xo { using value_type = std::pair; using key_hash = Hash; using key_equal = Equal; + using MemorySizeInfo = xo::mm::MemorySizeInfo; using byte = std::byte; using group_type = detail::ControlGroup; using store_type = detail::HashMapStore; @@ -76,6 +77,11 @@ namespace xo { iterator begin() { return _promote_iterator(_begin_aux()); } iterator end() { return _promote_iterator(_end_aux()); } + std::size_t _n_store() const noexcept { return store_._n_store(); } + MemorySizeInfo _store_info(std::size_t i) const noexcept { + return store_._store_info(i); + } + /** insert @p kv_pair into hash map. * Replaces any previous value stored under the same key. * diff --git a/xo-arena/include/xo/arena/DArenaVector.hpp b/xo-arena/include/xo/arena/DArenaVector.hpp index f8bd9820..b7a0b2aa 100644 --- a/xo-arena/include/xo/arena/DArenaVector.hpp +++ b/xo-arena/include/xo/arena/DArenaVector.hpp @@ -79,6 +79,11 @@ namespace xo { constexpr T * data() { return reinterpret_cast(store_.lo_); } constexpr const T * data() const { return reinterpret_cast(store_.lo_); } + /** arena used for element storage + * (Might prefer obj here; refrain to avoid leveling violation) + **/ + MemorySizeInfo _store_info() const { return store_._store_info(); } + /** reserve space, if possible, for at least @p z elements. * Always limited by ArenaConfig.size_ **/ diff --git a/xo-arena/include/xo/arena/DCircularBuffer.hpp b/xo-arena/include/xo/arena/DCircularBuffer.hpp index 30a38960..538d272d 100644 --- a/xo-arena/include/xo/arena/DCircularBuffer.hpp +++ b/xo-arena/include/xo/arena/DCircularBuffer.hpp @@ -83,6 +83,9 @@ namespace xo { const_span_type occupied_range() const noexcept { return occupied_range_; } const_span_type input_range() const noexcept { return input_range_; } + std::size_t _n_store() const noexcept; + MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** verify DCircularBuffer invariants. * Act on failure according to policy @p p * (combination of throw|log bits) diff --git a/xo-arena/include/xo/arena/ErrorArena.hpp b/xo-arena/include/xo/arena/ErrorArena.hpp new file mode 100644 index 00000000..0236c325 --- /dev/null +++ b/xo-arena/include/xo/arena/ErrorArena.hpp @@ -0,0 +1,54 @@ +/** @file ErrorArena.hpp +* + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DArena.hpp" + +namespace xo { + namespace mm { + + /** @brief Dedicated arena for error reporting + * + * Reserving memory for error messaages. + * Motivation + * 1. so we have room to report an out-of-memory condition + * 2. so we have place to allocate for an error that + * doesn't interfere with other allocator state + * + * Expect to reset arena between errors, so only need + * enough room to report one error. + * + * To initialize explicitly: + * @code + * // before any other ErrorArena method calls: + * ErrorArena::init_once(cfg...); + * + * // do stuff with ErrorArena.. + * ErrorArena::instance() + * @endcode + * + * Reminder: can't use obj here, + * would be leveling violation. + **/ + class ErrorArena { + public: + /** default configuration for error arena **/ + static ArenaConfig default_config(); + + /** idempotent initialization **/ + static void init_once(const ArenaConfig & cfg = default_config()); + + /** get initialized instnace **/ + static DArena * instance(); + + private: + static DArena s_instance; + }; + + } /*namespace mm*/ +} /*namespace xo*/ + +/* end ErrorArena.hpp */ diff --git a/xo-arena/include/xo/arena/MemorySizeInfo.hpp b/xo-arena/include/xo/arena/MemorySizeInfo.hpp new file mode 100644 index 00000000..7cba082c --- /dev/null +++ b/xo-arena/include/xo/arena/MemorySizeInfo.hpp @@ -0,0 +1,37 @@ +/** @file MemorySizeInfo.hpp +* + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include + +namespace xo { + namespace mm { + + struct MemorySizeInfo { + using size_type = std::size_t; + + MemorySizeInfo(std::string_view name, std::size_t a, std::size_t c, std::size_t r) + : resource_name_{name}, allocated_{a}, committed_{c}, reserved_{r} + {} + + static MemorySizeInfo sentinel() { return MemorySizeInfo("", 0, 0, 0); } + + /** resource name **/ + std::string_view resource_name_; + /** memory in-use **/ + std::size_t allocated_ = 0; + /** memory committed (backed by physical memory) **/ + std::size_t committed_ = 0; + /** memory reserved: + * virtual memory addresses range obtained, whether or not committed + **/ + std::size_t reserved_ = 0; + }; + + } +} + +/* end MemorySizeInfo.hpp */ diff --git a/xo-arena/include/xo/arena/arena_streambuf.hpp b/xo-arena/include/xo/arena/arena_streambuf.hpp new file mode 100644 index 00000000..2b364622 --- /dev/null +++ b/xo-arena/include/xo/arena/arena_streambuf.hpp @@ -0,0 +1,236 @@ +/** @file arena_streambuf.hpp +* + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DArena.hpp" +//#include "print/quoted_char.hpp" +#include +#include +#include +#include // e.g. for std::memcpy() +#include +#include + +namespace xo { + namespace mm { + /** @brief Arena-based buffer for logging and pretty-printing + * + * Arena-based using mmap + * Write to self-extending storage array + * Track position relative to start of line + **/ + class arena_streambuf : public std::streambuf { + public: + struct rewind_state { + explicit rewind_state(std::size_t solpos, std::size_t color_esc, std::uint32_t p) + : solpos{solpos}, color_escape_chars{color_esc}, pos{p} {} + + std::size_t solpos = 0; + std::size_t color_escape_chars = 0; + std::uint32_t pos = 0; + }; + + public: + /** arena should be ready-to-allocate i.e. have committed > 0 **/ + arena_streambuf(DArena * arena, bool debug_flag = false) : arena_{arena}, debug_flag_{debug_flag} { + this->reset_stream(); + } /*ctor*/ + + std::streamsize capacity() const { return arena_->committed(); } + const char * lo() const { return this->pbase(); } + const char * hi() const { return this->lo() + this->capacity(); } + std::uint32_t pos() const { return this->pptr() - this->pbase(); } + + /** output position (relative to pbase) when local state last computed. Exposed here for unit tests **/ + std::size_t _local_ppos() const { return local_ppos_; } + /** position (relative to pbase) one character after last \n or \r. For unit tests **/ + std::uint32_t _solpos() const { return solpos_; } + /** start of incomplete color-escape sequence **/ + const char * _color_escape_start() const { return color_escape_start_; } + /** number of non-printing chars after @ref solpos_ from completed color-escape sequences **/ + std::uint32_t _color_escape_chars() const { return color_escape_chars_; } + + /** number of visible characters since start of line (last \n or \r) **/ + std::uint32_t lpos() const; + + rewind_state checkpoint() const; + + bool debug_flag() const { return debug_flag_; } + + operator std::string_view () const { return std::string_view(this->pbase(), this->pptr()); } + + void reset_stream(); + + void rewind_to(rewind_state s); + + protected: + /** expand buffer storage (by 2x), preserve current contents **/ + void expand_to(std::size_t new_z); + + virtual std::streamsize xsputn(const char * s, std::streamsize n) override; + + virtual int_type overflow(int_type new_ch) override; + + /* off. offset, relative to starting point dir. + * dir. + * which. in|out|both + * + * Note that off=0,dir=cur,which=out reads offset + */ + virtual pos_type seekoff(off_type off, + std::ios_base::seekdir dir, + std::ios_base::openmode which) override; + + private: + void _update_local_state_char(const char * p_lo, const char * p) + { + if ((*p == '\n') || (*p == '\r')) { + this->solpos_ = (p+1 - this->pbase()); + /* reset, since these chars relevant as correction to solpos */ + this->color_escape_chars_ = 0; + /* -> incomplete color escape, broken by newline */ + this->color_escape_start_ = nullptr; + } else if (*p == '\033') { + if (debug_flag_) [[unlikely]] { + std::cout << "xsputn: \\033 at p-p_lo=" << (p - p_lo) << std::endl; + } + this->color_escape_start_ = p; + } else if (this->color_escape_start_ != nullptr) { + if (*p == 'm') { + /* escape seq non-printing including both endpoints */ + std::int64_t esc_chars = (p+1 - color_escape_start_); + + this->color_escape_chars_ += esc_chars; + + if (debug_flag_) [[unlikely]] { + std::cout << "xsputn: m at p-p_lo" << (p - p_lo) << " +" << esc_chars + << " -> color_escape_chars=" << color_escape_chars_ << std::endl; + } + this->color_escape_start_ = nullptr; + } else if (!isdigit(*p) && (*p != '[') && (*p != ';')) { + /* not color escape after all */ + this->color_escape_start_ = nullptr; + } + } + } + + /** recognize stale local state vars: + * @ref solpos_, @ref color_escape_chars_, @ref color_escape_start_. + * + * Require: + * - {pbase, pptr} in consistent state + * Promise: + * - @c local_ppos_ + @c pbase = @c pptr + * - @c solpos_, @c color_escape_chars_, @c color_escape_start_ all up-to-date + **/ + void _check_update_local_state() { + const char * p0 = this->pbase(); + const char * pn = this->pptr(); + + if (debug_flag_) { + std::cerr << "_check_update_local_state:" << std::endl; + std::cerr << " buf: (p0=" << (void*)p0 << ", pn=" << (void*)pn << ")" << std::endl; + std::cerr << " solpos_=" << solpos_ << ", color_escape_chars_=" << color_escape_chars_ << std::endl; + } + + if (p0 + local_ppos_ == pn) [[likely]] { + // solpos_, color_escape_chars_, color_escape_start_ all up-to-date + } else { + // [pnew, pn): input that hasn't been incorporated into + // {solpos_, color_escape_chars_, color_escape_start_) + + const char * pnew = this->pbase() + this->local_ppos_; + + if (debug_flag_) { + std::cerr << "_check_update_local_state: range: (pnew=" << (void*)pnew << ", pn=" << (void*)pn << ")" << std::endl; + } + + for(const char * p = pnew; p < pn; ++p) { + this->_update_local_state_char(p0, p); + } + } + + // solpos_, color_escape_chars_, color_escape_start_ all up-to-date + // for current buffered contents + + this->local_ppos_ = pn - p0; + + if (debug_flag_) { + std::cerr << "_check_update_local_state: pos=" << pos(); + std::cerr << ", solpos=" << solpos_; + std::cerr << ", color_escape_chars=" << color_escape_chars_ << std::endl; + } + + assert(pos() >= solpos_ + color_escape_chars_); + } + + private: + /* + * pbase: start of buffered text. Thils will be arena_->lo_ + * + * + * pbase pptr epptr + * v >e1< >e2< v v + * |xx\xxEEExxx\xxxxxxxEExxxxEExxxxxxxEExxx\xEExxxxxx..................| + * ^ ^<------new-------> + * solpos local_ppos + * + * solpos : first character after newline (stale) + * color_escape_pos : e1+e2+.. (stale) + * new : new characters not reflected + * in local_ppos_, color_escape_chars_ etc. + * + * Legend: + * [\] newline + * [x] visible character + * [E] color escape chars + * + * + * after _check_update_local_state(): + * + * + * pbase pptr epptr + * v >e1< v v + * |xx\xxEEExxx\xxxxxxxEExxxxEExxxxxxxEExxx\xEExxxxxx..................| + * ^ ^ + * solpos local_ppos + * + */ + + /** @defgroup logstreambuf-instance-vars **/ + ///@{ + + /** value of pptr (relative to pbase) when _check_update_local_state() last ran **/ + std::size_t local_ppos_ = 0; + /** position (relative to pbase) one character after last \n or \r. + * Use to drive @ref lpos. This _has_ to be lazy, since + * xsputn() isn'g guaranteed to be called when there's room in + * in buffer. + **/ + std::size_t solpos_ = 0; + /** number of non-printing chars after @ref solpos_, from + * completed color escape sequences. + * (ansi color escapes = text between '\033' and 'm') + **/ + std::size_t color_escape_chars_ = 0; + /** non-null: start of incomplete color escape sequence **/ + const char * color_escape_start_ = nullptr; + + /** buffered output stored here. + * We don't use arena's allocation api, just treat as a block of available memory + **/ + DArena * arena_ = nullptr;; + /** true to debug log_streambuf itself **/ + bool debug_flag_ = false; + + ///@} + }; /*log_streambuf*/ + + } /*namespace mm*/ +} /*namespace xo*/ + +/* end arena_streambuf.hpp */ + diff --git a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp index fd7c87f7..74f2f4e7 100644 --- a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp +++ b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp @@ -19,6 +19,7 @@ namespace xo { using group_type = detail::ControlGroup; using control_vector_type = xo::mm::DArenaVector; using slot_vector_type = xo::mm::DArenaVector; + using MemorySizeInfo = xo::mm::MemorySizeInfo; public: /** group_exp2: number of groups {x, 2^x} **/ @@ -47,6 +48,18 @@ namespace xo { size_type capacity() const noexcept { return n_group_ * c_group_size; } float load_factor() const noexcept { return size_ / static_cast(n_slot_); } + std::size_t _n_store() const noexcept { return 2; } + MemorySizeInfo _store_info(std::size_t i) const noexcept { + switch (i) { + case 0: + return control_._store_info(); + case 1: + return slots_._store_info(); + } + + return MemorySizeInfo::sentinel(); + } + void resize_from_empty(const std::pair & group_exp2) { diff --git a/xo-arena/src/arena/CMakeLists.txt b/xo-arena/src/arena/CMakeLists.txt index 5288c393..b3bb35a6 100644 --- a/xo-arena/src/arena/CMakeLists.txt +++ b/xo-arena/src/arena/CMakeLists.txt @@ -2,6 +2,8 @@ set(SELF_LIB xo_arena) set(SELF_SRCS + arena_streambuf.cpp + ErrorArena.cpp cmpresult.cpp mmap_util.cpp AllocError.cpp diff --git a/xo-arena/src/arena/DArena.cpp b/xo-arena/src/arena/DArena.cpp index 670666f5..3156fc1c 100644 --- a/xo-arena/src/arena/DArena.cpp +++ b/xo-arena/src/arena/DArena.cpp @@ -165,6 +165,15 @@ namespace xo { return (header_type *)((byte *)obj - sizeof(header_type)); } + MemorySizeInfo + DArena::_store_info() const noexcept + { + return MemorySizeInfo(config_.name_, + this->allocated(), + this->committed(), + this->reserved()); + } + AllocInfo DArena::alloc_info(value_type mem) const noexcept { diff --git a/xo-arena/src/arena/DCircularBuffer.cpp b/xo-arena/src/arena/DCircularBuffer.cpp index 2a415c49..2a5fb486 100644 --- a/xo-arena/src/arena/DCircularBuffer.cpp +++ b/xo-arena/src/arena/DCircularBuffer.cpp @@ -79,6 +79,31 @@ namespace xo { { } + std::size_t + DCircularBuffer::_n_store() const noexcept + { + return 2; + } + + MemorySizeInfo + DCircularBuffer::_store_info(std::size_t i) const noexcept + { + switch (i) { + case 0: + return MemorySizeInfo(config_.name_, + occupied_range_.size(), + mapped_range_.size(), + reserved_range_.size()); + case 1: + return pinned_spans_._store_info(); + default: + break; + } + + return MemorySizeInfo::sentinel(); + } + + bool DCircularBuffer::verify_ok(verify_policy policy) const { diff --git a/xo-arena/src/arena/ErrorArena.cpp b/xo-arena/src/arena/ErrorArena.cpp new file mode 100644 index 00000000..d1d3d62b --- /dev/null +++ b/xo-arena/src/arena/ErrorArena.cpp @@ -0,0 +1,43 @@ +/** @file ErrorArena.cpp +* + * @author Roland Conybeare, Feb 2026 + **/ + +#include "ErrorArena.hpp" + +namespace xo { + namespace mm { + DArena + ErrorArena::s_instance; + + ArenaConfig + ErrorArena::default_config() + { + return ArenaConfig().with_name("error-arena").with_size(16 * 1024); + } + + namespace { + bool s_init_done = false; + } + + void + ErrorArena::init_once(const ArenaConfig & cfg) + { + if (!s_init_done) { + s_init_done = true; + s_instance = DArena::map(cfg); + } + } + + DArena * + ErrorArena::instance() + { + init_once(default_config()); + + return &s_instance; + } + + } /*namespace mm*/ +} /*namespace xo*/ + +/* end ErrorArena.cpp */ diff --git a/xo-arena/src/arena/arena_streambuf.cpp b/xo-arena/src/arena/arena_streambuf.cpp new file mode 100644 index 00000000..18ea132e --- /dev/null +++ b/xo-arena/src/arena/arena_streambuf.cpp @@ -0,0 +1,214 @@ +/** @file arena_streambuf.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "arena_streambuf.hpp" + +namespace xo { + namespace mm { + + std::uint32_t + arena_streambuf::lpos() const + { + if (debug_flag_) { + std::cerr << "log_streambuf::lpos: enter" << std::endl; + } + + // logically-const. lazy implementation + arena_streambuf * self = const_cast(this); + + self->_check_update_local_state(); + + return pos() - solpos_ - color_escape_chars_; + } + + auto + arena_streambuf::checkpoint() const -> rewind_state + { + // logically-const. lazy implementation + arena_streambuf * self = const_cast(this); + + self->_check_update_local_state(); + + return rewind_state(solpos_, color_escape_chars_, pos()); + } + + void + arena_streambuf::reset_stream() + { + assert(arena_); + assert(arena_->committed() > 0); + + char * p_lo = (char *)(arena_->lo_); + char * p_hi = (char *)(arena_->limit_); + + /* tells parent our buffer extent */ + this->setp(p_lo, p_hi); + + this->local_ppos_ = 0; + this->solpos_ = 0; + this->color_escape_chars_ = 0; + this->color_escape_start_ = nullptr; + } + + void + arena_streambuf::rewind_to(rewind_state s) + { + if (debug_flag_) { + std::cout << "rewind_to: pos " << pos() << "->" << s.pos + << " solpos " << solpos_ << "->" << s.solpos + << " color_esc " << color_escape_chars_ << "->" << s.color_escape_chars + << std::endl; + } + + /* .setp(): using just for side effect: sets .pptr to .pbase */ + this->setp(this->pbase(), this->epptr()); + /* advance pptr to saved position */ + this->pbump(s.pos); + + this->local_ppos_ = this->pptr() - this->pbase(); + this->solpos_ = s.solpos; + this->color_escape_chars_ = s.color_escape_chars; + /* assuming we never try to capture rewind state with incomplete color escape */ + this->color_escape_start_ = nullptr; + } + + void + arena_streambuf::expand_to(std::size_t new_z) + { + char * old_pptr = pptr(); + std::streamsize old_n = old_pptr - pbase(); + + assert(old_n <= static_cast(arena_->allocated())); + assert(new_z > arena_->committed()); + + /* note: local_ppos_ invariant across expand_to() */ + + arena_->expand(new_z); + + char * p_base = (char *)(arena_->lo_); + char * p_hi = (char *)(arena_->limit_); + + this->setp(p_base, p_hi); + this->pbump(old_n); + } + + std::streamsize + arena_streambuf::xsputn(const char * s, std::streamsize n) + { + /* s must be an address in [this->lo() .. this->lo() + capacity()] */ + + assert(hi() >= pptr()); + + if (pptr() + n > hi()) { + std::size_t new_z = std::max(2 * arena_->committed(), std::size_t(this->pos() + n + 1)); + + if (new_z > arena_->reserved()) + new_z = arena_->reserved(); + + this->expand_to(new_z); + } + + if (debug_flag_) { + std::cout << "xsputn: pbase=" << (void *)(this->pbase()) + << ", pptr=" << (void*)(this->pptr()) + << "(+" << (this->pptr() - this->lo()) << ")" + << ", n=" << n << " -> (+" << (this->pptr() + n - this->lo()) << ")" + << ", arena.size=" << this->arena_->committed() + << std::endl; + } + + std::streamsize ncopied = 0; + + if (this->pptr() + n > this->hi()) { + ncopied = this->hi() - this->pptr(); + } else { + ncopied = n; + } + + if (false /*debug_flag_*/) { + std::cout << "xsputn: copying ncopied=" << ncopied << " (/n=" << n << ") bytes into range [lo,hi)" + << ", lo=" << (void*)this->pptr() + << ", hi=" << (void*)(this->pptr() + n) + << std::endl; + } + + std::memcpy(this->pptr(), s, ncopied); + + this->pbump(ncopied); + + /* now {pbase, pptr} consistent with new input */ + + this->_check_update_local_state(); + + return ncopied; + } + + auto + arena_streambuf::overflow(int_type new_ch) -> int_type + { + char * old_base = this->pbase(); + char * old_pptr = this->pptr(); + /* #of chars buffered */ + std::streamsize old_n = old_pptr - old_base; + + assert(old_n <= static_cast(arena_->committed())); + + // if (debug_flag_) { + // std::cout << "overflow: new_ch=" << quoted_char(new_ch) << std::endl; + // } + + /* increase buffer size */ + this->expand_to(2 * arena_->committed()); + + arena_->lo_[old_n] = static_cast(new_ch); + this->pbump(1); + + if ((new_ch == static_cast('\n')) || (new_ch == static_cast('\r'))) { + this->solpos_ = this->pos(); + + // what if new_ch starts color escape ? + } + + if (new_ch == std::char_traits::eof()) { + /* reminder: returning eof sets badbit on ostream */ + return std::char_traits::not_eof(new_ch); + } else { + return new_ch; + } + } + + auto + arena_streambuf::seekoff(off_type off, + std::ios_base::seekdir dir, + std::ios_base::openmode which) -> pos_type + { + //std::cout << "seekoff: off=" << off << ", dir=" << dir << ", which=" << which << std::endl; + if (debug_flag_) { + std::cout << "seekoff(off,dir,which)" << std::endl; + } + + // Only output stream is supported + if (which != std::ios_base::out) + throw std::runtime_error("log_streambuf: only output mode supported"); + + if (dir == std::ios_base::cur) { + this->pbump(off); + } else if (dir == std::ios_base::end) { + /* .setp(): using for side effect: sets .pptr to .pbase */ + this->setp(this->pbase(), this->epptr()); + this->pbump(off); + } else if (dir == std::ios_base::beg) { + /* .setp(): using for side effect: sets .pptr to .pbase */ + this->setp(this->pbase(), this->epptr()); + this->pbump(this->capacity() + off); + } + + return this->pptr() - this->pbase(); + } /*seekoff*/ + + } /*namespace mm*/ +} /*namespace xo*/ + +/* end arena_streambuf.cpp */ diff --git a/xo-expression2/include/xo/expression2/StringTable.hpp b/xo-expression2/include/xo/expression2/StringTable.hpp index 471fbc0d..b55c48ee 100644 --- a/xo-expression2/include/xo/expression2/StringTable.hpp +++ b/xo-expression2/include/xo/expression2/StringTable.hpp @@ -21,6 +21,7 @@ namespace xo { class StringTable { public: using DArena = xo::mm::DArena; + using MemorySizeInfo = xo::mm::MemorySizeInfo; using StringMap = xo::map::DArenaHashMap; using size_type = StringMap::size_type; @@ -45,6 +46,9 @@ namespace xo { **/ bool verify_ok(verify_policy p = verify_policy::throw_only()) const; + std::size_t _n_store() const noexcept; + MemorySizeInfo _store_info(std::size_t i) const noexcept; + private: /** allocate string storage in this arena; use DString to represent each string. * Can't use DArenaVector b/c DString has variable size diff --git a/xo-expression2/src/expression2/StringTable.cpp b/xo-expression2/src/expression2/StringTable.cpp index f59bb24d..79a17067 100644 --- a/xo-expression2/src/expression2/StringTable.cpp +++ b/xo-expression2/src/expression2/StringTable.cpp @@ -10,6 +10,7 @@ namespace xo { using xo::mm::ArenaConfig; using xo::mm::AAllocator; + using xo::mm::MemorySizeInfo; using xo::facet::with_facet; using xo::facet::obj; @@ -159,6 +160,24 @@ namespace xo { return true; } + std::size_t + StringTable::_n_store() const noexcept + { + return 1 + map_._n_store(); + } + + MemorySizeInfo + StringTable::_store_info(std::size_t i) const noexcept + { + if (i == 0) + return strings_._store_info(); + + if (i+1 < map_._n_store()) + return map_._store_info(i-1); + + return MemorySizeInfo::sentinel(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-facet/include/xo/facet/box.hpp b/xo-facet/include/xo/facet/box.hpp index 54e724ed..62f797e3 100644 --- a/xo-facet/include/xo/facet/box.hpp +++ b/xo-facet/include/xo/facet/box.hpp @@ -38,6 +38,7 @@ namespace xo { {} /** (copy ctor not supported -- ownership is unique) **/ + box(const box & other) = delete; // -------------------------------- @@ -73,8 +74,10 @@ namespace xo { ~box() { auto p = this->data(); - this->_drop(); - ::operator delete(p); + if (p) { + this->_drop(); + ::operator delete(p); + } } }; } /*namespace facet*/ diff --git a/xo-indentlog/include/xo/indentlog/log_state.hpp b/xo-indentlog/include/xo/indentlog/log_state.hpp index e28fb2c4..461f2c7b 100644 --- a/xo-indentlog/include/xo/indentlog/log_state.hpp +++ b/xo-indentlog/include/xo/indentlog/log_state.hpp @@ -255,157 +255,6 @@ namespace xo { // instead of post-processing, rely on newline-aware log_streambuf // to indent in advance -#ifdef OBSOLETE - log_streambuf_type * sbuf2 = this->p_sbuf_phase2_.get(); - - /* often sbuf contains one line of output. - * if it contains multiple newlines, need to indent - * after each one. - * - * will scan output in *sbuf1, post-process to *sbuf2, - * then write *sbuf2 to output stream - * - * note: we inherit .lpos from prec call to .flush2sbuf(), - * in the unlikely event that it's non-zero - */ - char const * s = sbuf1->lo(); - - char const * e = s + sbuf1->pos(); - char const * p = s; - - /* point to first space following a non-space character. - * will indent to just after this space - */ - char const * space_after_nonspace = nullptr; - - /* true on VT100 color escape (\033); in which case false on terminating char (m) - * don't advance lpos during escape - */ - bool in_color_escape = false; - - while(true) { - bool have_nonspace = false; - - /* invariant: s<=p<=e */ - - /* for indenting, looking for first 'space following non-space, on first line', if any */ - -#ifdef OBSOLETE - // ..multiline input should have already been indented by custom log_streambuf. - // may need to extend to recognize terminal control sequences like below - - std::size_t lpos_on_newline = 0; -#endif - -#ifdef OBSOLETE - while(p < e) { - if(space_after_nonspace) { - ; - } else { - if(*p != ' ') - have_nonspace = true; - - if(have_nonspace && (*p == ' ')) { - space_after_nonspace = p; - } - } - - if (in_color_escape && (*p != '\n')) { - /* in color escape -> don't advance .lpos */ - if (*p == 'm') - in_color_escape = false; - ++p; - } else if (*p == '\033') { - /* begin color escape sequence */ - in_color_escape = true; - ++p; - } else if (*p == '\n') { - /* reset .pos on newline; also drop any (incomplete + ill-formed) color escape */ - - in_color_escape = false; - -#ifdef OBSOLETE - lpos_on_newline = this->lpos_; - this->lpos_ = 0; -#endif - - ++p; - break; - } else { - /* increment .lpos on non-newline */ - ++(this->lpos_); - ++p; - } - } -#endif - - /* p=e or *p=\n */ - - /* charseq [s,p) does not contain any newlines, print it */ - if (lpos_on_newline > 0) { - /* charseq [s,p) does not contain any newlines, print it */ - sbuf2->sputn(s, p - s - 1); - - if (this->location_flag_) { - /* 'tab' to position lpos for [file:line] */ - sbuf2->sputc(' '); - for (std::uint32_t i = lpos_on_newline + 1; i < log_config::location_tab; ++i) - sbuf2->sputc(' '); - - std::stringstream ss; - ss << code_location(this->file_, this->line_, - log_config::code_location_color); - - std::string ss_str = ss.str(); /*hoping for copy elision here*/ - sbuf2->sputn(ss_str.c_str(), ss_str.size()); - - this->location_flag_ = false; - this->file_ = ""; - this->line_ = 0; - } - - sbuf2->sputc('\n'); - } else { - /* control here if .flush2sbuf() called without trailing newline in .p_sbuf_phase1 */ - sbuf2->sputn(s, p - s); - } - - if (p == e) - break; - - // { - // char buf[80]; - // snprintf(buf, sizeof(buf), "*** indent=[%d] next=[%c]", this->nesting_level_, *(p+1)); - // - // std::clog.rdbuf()->sputn(buf, strlen(buf)); - //} - - /* control here only for continuation lines (application logging code embedding its own newlines) - * - minimum indent = nesting level; - * - however if space_after_nonspace defined, also indent for that - */ - std::uint32_t n_indent = 0; - - n_indent += this->calc_time_indent(); - - n_indent += std::min(this->nesting_level_ * log_config::indent_width, - log_config::max_indent_width); - -#ifdef OBSOLETE // nice try, broken for multiline input + written before log_streambuf calculated lpos - /* this is just to indent for per-line entry/exit label */ - if(space_after_nonspace) - n_indent += (space_after_nonspace - s); -#endif - - for(std::uint32_t i = 0; i < n_indent; ++i) - sbuf2->sputc(' '); - - s = p; - } - - /* now write entire contents of *sbuf2 to clog */ - p_sbuf->sputn(sbuf2->lo(), sbuf2->pos()); -#endif p_sbuf->sputn(sbuf1->lo(), sbuf1->pos()); /* reset streams for next message */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index c9dc0749..5165c9a8 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -14,21 +14,42 @@ namespace xo { namespace scm { + struct EvaluationError { + /** source location (in vsm implementation) at which error identified **/ + std::string_view src_function_; + /** error description (allocated from ErrorArena) **/ + std::string_view error_description_; + // TODO: info about location in schematika source + }; + /** similar to @ref xo::scm::ReaderResult **/ struct VsmResult { using AGCObject = xo::mm::AGCObject; using span_type = xo::mm::span; - bool is_tk_error() const { return tk_error_.is_error(); } + VsmResult() = default; + VsmResult(obj value) : result_{value} {} + VsmResult(TokenizerError err) : result_{err} {} + + bool is_value() const { return std::holds_alternative>(result_); } + bool is_tk_error() const { return std::holds_alternative(result_); } + bool is_eval_error() const { return std::holds_alternative(result_); } + + const obj * value() const { return std::get_if>(&result_); } /** result of evaluating first expression encountered in input **/ - obj value_; + std::variant, TokenizerError, EvaluationError> result_; + }; - /** unconsumed portion of input span **/ - span_type remaining_input_; + /** vsm result + reamining span **/ + struct VsmResultExt : public VsmResult { + using span_type = VsmResult::span_type; - /** {src_function, error_description, input_state, error_pos} **/ - TokenizerError tk_error_; + VsmResultExt() = default; + VsmResultExt(const VsmResult & result, span_type rem) : VsmResult{result}, remaining_{rem} {} + + /** unconsumed portion of input **/ + VsmResult::span_type remaining_; }; /** @class VirtualSchematikaMachine @@ -40,16 +61,29 @@ namespace xo { using Stack = void *; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; + using MemorySizeInfo = xo::mm::MemorySizeInfo; using span_type = xo::mm::span; public: VirtualSchematikaMachine(const VsmConfig & config); - /** consume input @p input_cstr **/ - VsmResult read_eval_print(span_type input_span, bool eof); + size_t _n_store() const noexcept; + MemorySizeInfo _store_info(std::size_t i) const noexcept; - /** evaluate expression @p expr **/ - std::pair, TokenizerError> eval(obj expr); + /** begin interactive session. **/ + void begin_interactive_session(); + /** begin batch session **/ + void begin_batch_session(); + + /** consume input @p input_cstr. + * Require: must first start interactive/batch session + **/ + VsmResultExt read_eval_print(span_type input_span, bool eof); + + /** evaluate expression @p expr + * Require: must first start interactive/batch session + **/ + VsmResult start_eval(obj expr); /** borrow calling thread to run indefinitely, * until halt instruction @@ -124,13 +158,16 @@ namespace xo { /** configuration **/ VsmConfig config_; + /** allocator (likely collector) for + * expressions and values + **/ box mm_; /** reader: text -> expression **/ SchematikaReader reader_; /** program counter **/ - VsmInstr pc_ = VsmInstr::halt(); + VsmInstr pc_ = VsmInstr::c_halt; #ifdef NOT_YET /** stack pointer **/ @@ -141,10 +178,10 @@ namespace xo { obj expr_; /** result register **/ - obj value_; + VsmResult value_; /** continuation register **/ - VsmInstr cont_ = VsmInstr::halt(); + VsmInstr cont_ = VsmInstr::c_halt; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp index 2957b297..9d13ab8e 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp @@ -17,6 +17,9 @@ namespace xo { VsmConfig() = default; + /** true for interactive parser session; false for batch session **/ + bool interactive_flag_ = true; + /** reader configuration **/ ReaderConfig rdr_config_; /** Configuration for allocator/collector. diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index ca74bc4c..c956c607 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -13,8 +13,8 @@ namespace xo { public: explicit VsmInstr(vsm_opcode oc) : opcode_{oc} {} - static VsmInstr halt() { return VsmInstr{vsm_opcode::halt}; } - static VsmInstr eval() { return VsmInstr{vsm_opcode::eval}; } + static VsmInstr c_halt; + static VsmInstr c_eval; vsm_opcode opcode() const noexcept { return opcode_; } diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 7d9cd250..93ecd47e 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -4,6 +4,7 @@ set(SELF_LIB xo_interpreter2) set(SELF_SRCS init_interpreter2.cpp VirtualSchematikaMachine.cpp + VsmInstr.cpp #IExpression_Any.cpp #interpreter2_register_facets.cpp ) diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index fabc5441..d40b85c6 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -17,6 +17,7 @@ namespace xo { using xo::print::ppconfig; using xo::print::ppstate_standalone; using xo::mm::AGCObject; + using xo::mm::MemorySizeInfo; using xo::mm::DX1Collector; using xo::facet::FacetRegistry; using std::cout; @@ -29,50 +30,84 @@ namespace xo { reader_{config.rdr_config_, mm_.to_op()} {} - VsmResult + std::size_t + VirtualSchematikaMachine::_n_store() const noexcept + { + // oops. need something that goes through AAllocator api + + return reader_._n_store(); + } + + MemorySizeInfo + VirtualSchematikaMachine::_store_info(std::size_t i) const noexcept + { + // oops. need something poly that goes through AAllocator api + + return reader_._store_info(i); + } + + void + VirtualSchematikaMachine::begin_interactive_session() + { + reader_.begin_interactive_session(); + } + + void + VirtualSchematikaMachine::begin_batch_session() + { + reader_.begin_batch_session(); + } + + VsmResultExt VirtualSchematikaMachine::read_eval_print(span_type input, bool eof) { if (input.empty()) { - return VsmResult(); + return VsmResultExt(); } auto [expr, remaining, error1] = reader_.read_expr(input, eof); if (!expr) { - return { - .remaining_input_ = remaining, - .tk_error_ = error1 - }; + /* tokenizer error */ + + return VsmResultExt(VsmResult(error1), remaining); } - auto [value, error2] = this->eval(expr); + VsmResult evalresult = this->start_eval(expr); - if (!value) { - return { - .remaining_input_ = remaining, - .tk_error_ = error2 - }; + if (evalresult.is_eval_error() || evalresult.is_tk_error()) { + return VsmResultExt(evalresult, remaining); } + assert(evalresult.is_value()); + + obj * p_value = std::get_if>(&(evalresult.result_)); + + assert(p_value); + obj value_pr - = FacetRegistry::instance().variant(value); + = FacetRegistry::instance().variant(*p_value); // pretty_toplevel(value_pr, &cout, ppconfig()); ppconfig ppc; ppstate_standalone pps(&cout, 0, &ppc); pps.prettyn(value_pr); - return { .remaining_input_ = remaining }; + return VsmResultExt(VsmResult(*p_value), remaining); } - std::pair, TokenizerError> - VirtualSchematikaMachine::eval(obj expr) + VsmResult + VirtualSchematikaMachine::start_eval(obj expr) { - (void)expr; + this->pc_ = VsmInstr::c_eval; + this->expr_ = expr; + this->value_ = obj(); + this->cont_ = VsmInstr::c_halt; - assert(false); - return std::make_pair(obj(), TokenizerError()); + this->run(); + + return value_; } void diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp new file mode 100644 index 00000000..95a0ef74 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -0,0 +1,18 @@ +/** @file VsmInstr.cpp +* + * @author Roland Conybeare, Feb 2026 + **/ + +#include "VsmInstr.hpp" + +namespace xo { + namespace scm { + VsmInstr + VsmInstr::c_halt = VsmInstr(vsm_opcode::halt); + + VsmInstr + VsmInstr::c_eval = VsmInstr(vsm_opcode::eval); + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VsmInstr.cpp */ diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 8dacb437..a0554f87 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -4,6 +4,8 @@ **/ #include +#include +#include #ifdef NOT_YET #include @@ -16,12 +18,18 @@ #ifdef NOT_YET #include #endif +#include #include namespace xo { using xo::scm::VirtualSchematikaMachine; using xo::scm::VsmConfig; + using xo::scm::VsmResultExt; + using xo::scm::DFloat; + using xo::mm::AGCObject; + using span_type = xo::scm::VirtualSchematikaMachine::span_type; + using Catch::Matchers::WithinAbs; #ifdef NOT_YET using xo::scm::SchematikaParser; @@ -39,27 +47,32 @@ namespace xo { using xo::mm::DArena; using xo::facet::with_facet; #endif + using std::cout; + using std::endl; static InitEvidence s_init = (InitSubsys::require()); namespace ut { TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]") { - VirtualSchematikaMachine vsm(VsmConfig); + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); -#ifdef NOT_YET - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; + bool eof_flag = false; - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); + vsm.begin_interactive_session(); + VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("3.141592635;"), eof_flag); - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + REQUIRE(res.is_value()); + REQUIRE(res.value()); - REQUIRE(parser.debug_flag() == false); - REQUIRE(parser.is_at_toplevel() == true); -#endif + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE_THAT(x.data()->value(), WithinAbs(3.141592635, 1e-6)); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); } } /*namespace ut*/ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index d065e24f..89569695 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -36,6 +36,7 @@ namespace xo { using AAllocator = xo::mm::AAllocator; using ArenaConfig = xo::mm::ArenaConfig; using DArena = xo::mm::DArena; + using MemorySizeInfo = xo::mm::MemorySizeInfo; using size_type = std::size_t; public: @@ -61,6 +62,11 @@ namespace xo { /** top of parser stack **/ obj top_ssm() const; + /** number of distinct memory pools owned by PS **/ + std::size_t _n_store() const noexcept; + /** memory consumption for i'th memory pool **/ + MemorySizeInfo _store_info(std::size_t i) const noexcept; + ///@} /** @defgroup scm-parserstatemachine-bookkeeping bookkeeping methods **/ diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 7be74aa5..83e9230b 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -156,6 +156,7 @@ namespace xo { using token_type = Token; using ArenaConfig = xo::mm::ArenaConfig; using AAllocator = xo::mm::AAllocator; + using MemorySizeInfo = xo::mm::MemorySizeInfo; using ppindentinfo = xo::print::ppindentinfo; using size_type = std::size_t; @@ -192,6 +193,11 @@ namespace xo { /** top of parser stack **/ obj top_ssm() const; + /** number of distinct memory pools owned by PS **/ + std::size_t _n_store() const noexcept; + /** memory consumption for i'th memory pool **/ + MemorySizeInfo _store_info(std::size_t i) const noexcept; + ///@} /** scm-schematikaparser-general-methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index fd26a4ec..3c2b5312 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -36,6 +36,7 @@ namespace xo { class SchematikaReader { public: using AAllocator = xo::mm::AAllocator; + using MemorySizeInfo = xo::mm::MemorySizeInfo; using span_type = xo::mm::span; using size_type = std::size_t; @@ -43,6 +44,9 @@ namespace xo { SchematikaReader(const ReaderConfig & config, obj expr_alloc); + std::size_t _n_store() const noexcept; + MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** true iff parser is at top-level. * false iff parser is working on incomplete expression **/ @@ -53,6 +57,11 @@ namespace xo { **/ void begin_interactive_session(); + /** prepare batch session + * (limits expression types at toplevel) + **/ + void begin_batch_session(); + /** consume input @p input_cstr **/ const ReaderResult & read_expr(span_type input_span, bool eof); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index cf9c26c1..ff845762 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -16,6 +16,7 @@ #include namespace xo { + using xo::mm::MemorySizeInfo; using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::facet::with_facet; @@ -53,6 +54,29 @@ namespace xo { return this->stack_->top(); } + std::size_t + ParserStateMachine::_n_store() const noexcept + { + return stringtable_._n_store() + 1; + } + + MemorySizeInfo + ParserStateMachine::_store_info(std::size_t i) const noexcept + { + size_t n0 = stringtable_._n_store(); + + if (i < n0) + return stringtable_._store_info(i); + + if (i == n0) + return parser_alloc_._store_info(); + + // not counting expr_alloc_. We don't consider + // that to be owned by ParserStateMachine + + return MemorySizeInfo::sentinel(); + } + void ParserStateMachine::establish_toplevel_ssm(obj ssm) { diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index e584044c..07c74d17 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -13,6 +13,7 @@ namespace xo { using xo::mm::AAllocator; + using xo::mm::MemorySizeInfo; using xo::tostr; using xo::xtag; @@ -46,6 +47,18 @@ namespace xo { return psm_.top_ssm(); } + std::size_t + SchematikaParser::_n_store() const noexcept + { + return psm_._n_store(); + } + + MemorySizeInfo + SchematikaParser::_store_info(std::size_t i) const noexcept + { + return psm_._store_info(i); + } + void SchematikaParser::begin_interactive_session() { diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index 4dd8600c..097c68df 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -6,6 +6,8 @@ #include "SchematikaReader.hpp" namespace xo { + using xo::mm::MemorySizeInfo; + namespace scm { SchematikaReader::SchematikaReader(const ReaderConfig & config, obj expr_alloc) @@ -19,6 +21,29 @@ namespace xo { { } + std::size_t + SchematikaReader::_n_store() const noexcept + { + return tokenizer_._n_store() + parser_._n_store(); + } + + MemorySizeInfo + SchematikaReader::_store_info(std::size_t i) const noexcept + { + size_t n_tk = tokenizer_._n_store(); + + if (i < n_tk) { + return tokenizer_._store_info(i); + } + + size_t n_pr = parser_._n_store(); + + if (i < n_tk + n_pr) + return parser_._store_info(i - n_tk); + + return MemorySizeInfo::sentinel(); + } + bool SchematikaReader::is_at_toplevel() const noexcept { @@ -31,6 +56,12 @@ namespace xo { parser_.begin_interactive_session(); } + void + SchematikaReader::begin_batch_session() + { + parser_.begin_batch_session(); + } + // TODO: // Schematika::end_interactive_session() diff --git a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp index 3dc6da11..83015c03 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp @@ -61,6 +61,7 @@ namespace xo { using error_type = TokenizerError; using DCircularBuffer = xo::mm::DCircularBuffer; using CircularBufferConfig = xo::mm::CircularBufferConfig; + using MemorySizeInfo = xo::mm::MemorySizeInfo; using span_type = xo::mm::span; //using input_state_type = TkInputState; using result_type = scan_result; @@ -90,6 +91,11 @@ namespace xo { const TkInputState & input_state() const { return input_state_; } #pragma GCC diagnostic pop + /** number of distinct memory pools owned by tokenizer **/ + std::size_t _n_store() const noexcept; + /** memory consumption for i'th memory pool **/ + MemorySizeInfo _store_info(std::size_t i) const noexcept; + ///@} /** @defgroup tokenizer-general-methods tokenizer methods **/ diff --git a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp index c79e10c3..c36d85a5 100644 --- a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp +++ b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp @@ -6,6 +6,7 @@ #include "Tokenizer.hpp" namespace xo { + using xo::mm::MemorySizeInfo; using std::byte; namespace scm { @@ -21,6 +22,18 @@ namespace xo { this->input_state_.discard_current_line(); } + std::size_t + Tokenizer::_n_store() const noexcept + { + return input_buffer_._n_store(); + } + + MemorySizeInfo + Tokenizer::_store_info(std::size_t i) const noexcept + { + return input_buffer_._store_info(i); + } + bool Tokenizer::is_1char_punctuation(CharT ch) { From c931fca242b76f6f6c7d73c9ee80be17b8e757fc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 01:05:36 -0500 Subject: [PATCH 147/258] xo-interpreter2 .. xo-arena. memory pool introspection --- .../include/xo/alloc2/alloc/AAllocator.hpp | 19 +++++++------ .../xo/alloc2/alloc/IAllocator_Any.hpp | 2 ++ .../xo/alloc2/alloc/IAllocator_Xfer.hpp | 3 +- .../include/xo/alloc2/alloc/RAllocator.hpp | 1 + .../xo/alloc2/arena/IAllocator_DArena.hpp | 2 ++ xo-alloc2/src/alloc2/IAllocator_DArena.cpp | 7 +++++ xo-arena/include/xo/arena/ArenaConfig.hpp | 4 +-- xo-arena/include/xo/arena/DArena.hpp | 8 ++++-- xo-arena/include/xo/arena/DArenaHashMap.hpp | 7 ++--- xo-arena/include/xo/arena/DArenaVector.hpp | 2 +- xo-arena/include/xo/arena/DCircularBuffer.hpp | 4 +-- xo-arena/include/xo/arena/MemorySizeInfo.hpp | 10 +++++-- .../include/xo/arena/hashmap/HashMapStore.hpp | 15 +++------- xo-arena/src/arena/DArena.cpp | 13 ++++----- xo-arena/src/arena/DCircularBuffer.cpp | 28 +++++-------------- .../include/xo/expression2/StringTable.hpp | 6 ++-- .../src/expression2/StringTable.cpp | 19 +++---------- xo-gc/include/xo/gc/DX1Collector.hpp | 7 ++++- .../xo/gc/detail/IAllocator_DX1Collector.hpp | 2 ++ xo-gc/src/gc/DX1Collector.cpp | 27 ++++++++++++++++-- xo-gc/src/gc/IAllocator_DX1Collector.cpp | 6 ++++ .../interpreter2/VirtualSchematikaMachine.hpp | 6 ++-- .../interpreter2/VirtualSchematikaMachine.cpp | 17 +++-------- .../utest/VirtualSchematikaMachine.test.cpp | 12 ++++++++ .../include/xo/reader2/ParserStateMachine.hpp | 8 ++---- .../include/xo/reader2/SchematikaParser.hpp | 8 ++---- .../include/xo/reader2/SchematikaReader.hpp | 9 ++++-- xo-reader2/src/reader2/ParserStateMachine.cpp | 21 +++----------- xo-reader2/src/reader2/SchematikaParser.cpp | 12 ++------ xo-reader2/src/reader2/SchematikaReader.cpp | 24 +++------------- .../include/xo/tokenizer2/Tokenizer.hpp | 8 ++---- xo-tokenizer2/src/tokenizer2/Tokenizer.cpp | 12 ++------ 32 files changed, 157 insertions(+), 172 deletions(-) diff --git a/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp index 4639d47e..ecc52862 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/AAllocator.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include #include "AllocInfo.hpp" //#include "AllocIterator.hpp" @@ -33,9 +34,11 @@ namespace xo { struct AAllocator { /** @defgroup mm-allocator-type-traits allocator type traits **/ ///@{ - /** @brief type used for allocation amounts **/ + /** memory size report **/ + using MemorySizeInfo = xo::mm::MemorySizeInfo; + /** type used for allocation amounts **/ using size_type = std::size_t; - /** @brief type used for allocation responses **/ + /** type used for allocation responses **/ using value_type = std::byte *; /** object header, if configured **/ using header_type = std::uint64_t; @@ -95,6 +98,12 @@ namespace xo { * Includes alloc headers and guard regions **/ virtual size_type allocated(Copaque d) const noexcept = 0; + /** call @p fn(i,n,info) for each memory pool owned by this allocator. + * Note: using std::function instead of obj<> to avoid leveling trouble + * with DArena + **/ + virtual void visit_pools(Copaque d, + const MemorySizeVisitor & fn) const = 0; /** true iff allocator @p d is responsible for memory at address @p p. **/ virtual bool contains(Copaque d, const void * p) const noexcept = 0; @@ -146,12 +155,6 @@ namespace xo { virtual value_type alloc_copy(Opaque d, value_type src) const = 0; /** reset allocator @p d to empty state. **/ virtual void clear(Opaque d) const = 0; -#ifdef OBSOLETE - /** Destruct allocator @p d. - * Releases allocator memory to operating system. - **/ - virtual void destruct_data(Opaque d) const = 0; -#endif ///@} }; /*AAllocator*/ diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp index aac80bca..fa8c14ab 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Any.hpp @@ -45,6 +45,8 @@ namespace xo { [[noreturn]] size_type available(Copaque) const noexcept override { _fatal(); } [[noreturn]] size_type allocated(Copaque) const noexcept override { _fatal(); } [[noreturn]] bool contains(Copaque, const void *) const noexcept override { _fatal(); } + [[noreturn]] void visit_pools(Copaque, + const MemorySizeVisitor &) const override { _fatal(); } [[noreturn]] AllocError last_error(Copaque) const noexcept override { _fatal(); } [[noreturn]] AllocInfo alloc_info(Copaque, value_type) const noexcept override { _fatal(); } // defn in .cpp - problematic to require compiler know vt defn here diff --git a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp index e23d1470..e5b539a1 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/IAllocator_Xfer.hpp @@ -41,7 +41,7 @@ namespace xo { typeseq _typeseq() const noexcept override { return s_typeseq; } /** invoke native c++ dtor **/ void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } - + // const methods std::string_view name(Copaque d) const noexcept override { return I::name(_dcast(d)); } @@ -53,6 +53,7 @@ namespace xo { bool contains(Copaque d, const void * p) const noexcept override { return I::contains(_dcast(d), p); } + void visit_pools(Copaque d, const MemorySizeVisitor & fn) const override { I::visit_pools(_dcast(d), fn); } AllocError last_error(Copaque d) const noexcept override { return I::last_error(_dcast(d)); } AllocInfo alloc_info(Copaque d, value_type mem) const noexcept override { return I::alloc_info(_dcast(d), mem); diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index bbd35d5c..ad528ba5 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -39,6 +39,7 @@ namespace xo { size_type committed() const noexcept { return O::iface()->committed(O::data()); } size_type available() const noexcept { return O::iface()->available(O::data()); } size_type allocated() const noexcept { return O::iface()->allocated(O::data()); } + void visit_pools(const MemorySizeVisitor & fn) const { O::iface()->visit_pools(O::data(), fn); } bool contains(const void * p) const noexcept { return O::iface()->contains(O::data(), p); } AllocError last_error() const noexcept { return O::iface()->last_error(O::data()); } AllocInfo alloc_info(value_type mem) const noexcept { return O::iface()->alloc_info(O::data(), mem); } diff --git a/xo-alloc2/include/xo/alloc2/arena/IAllocator_DArena.hpp b/xo-alloc2/include/xo/alloc2/arena/IAllocator_DArena.hpp index 4a871822..81e92211 100644 --- a/xo-alloc2/include/xo/alloc2/arena/IAllocator_DArena.hpp +++ b/xo-alloc2/include/xo/alloc2/arena/IAllocator_DArena.hpp @@ -40,6 +40,8 @@ namespace xo { static size_type committed(const DArena &) noexcept; static size_type available(const DArena &) noexcept; static size_type allocated(const DArena &) noexcept; + static void visit_pools(const DArena &, + const MemorySizeVisitor & visitor); static bool contains(const DArena &, const void * p) noexcept; static AllocError last_error(const DArena &) noexcept; /** retrieve allocation bookkeeping info for @p mem from arena @p d **/ diff --git a/xo-alloc2/src/alloc2/IAllocator_DArena.cpp b/xo-alloc2/src/alloc2/IAllocator_DArena.cpp index a3bd9613..2a3a2d58 100644 --- a/xo-alloc2/src/alloc2/IAllocator_DArena.cpp +++ b/xo-alloc2/src/alloc2/IAllocator_DArena.cpp @@ -52,6 +52,13 @@ namespace xo { return s.allocated(); } + void + IAllocator_DArena::visit_pools(const DArena & s, + const MemorySizeVisitor & visitor) + { + s.visit_pools(visitor); + } + bool IAllocator_DArena::contains(const DArena & s, const void * p) noexcept diff --git a/xo-arena/include/xo/arena/ArenaConfig.hpp b/xo-arena/include/xo/arena/ArenaConfig.hpp index 4d72b912..9ca2a387 100644 --- a/xo-arena/include/xo/arena/ArenaConfig.hpp +++ b/xo-arena/include/xo/arena/ArenaConfig.hpp @@ -19,13 +19,13 @@ namespace xo { struct ArenaConfig { /** @defgroup mm-arenaconfig-ctors **/ - ArenaConfig with_name(std::string name) { + ArenaConfig with_name(std::string name) const { ArenaConfig copy(*this); copy.name_ = name; return copy; } - ArenaConfig with_size(std::size_t z) { + ArenaConfig with_size(std::size_t z) const { ArenaConfig copy(*this); copy.size_ = z; return copy; diff --git a/xo-arena/include/xo/arena/DArena.hpp b/xo-arena/include/xo/arena/DArena.hpp index 8c7203d6..4c12c8cb 100644 --- a/xo-arena/include/xo/arena/DArena.hpp +++ b/xo-arena/include/xo/arena/DArena.hpp @@ -138,12 +138,14 @@ namespace xo { **/ AllocHeader * end_header() const noexcept; + /** report memory use for this arena to @p fn. + * For DArena reporting just one pool = arena's memory range + **/ + void visit_pools(const MemorySizeVisitor & fn) const; + /** get header from allocated object address **/ header_type * obj2hdr(void * obj) noexcept; - /** resource ocnsumption in normal form **/ - MemorySizeInfo _store_info() const noexcept; - /** report alloc book-keeping info for allocation at @p mem * * Require: diff --git a/xo-arena/include/xo/arena/DArenaHashMap.hpp b/xo-arena/include/xo/arena/DArenaHashMap.hpp index 042dc900..da0e742a 100644 --- a/xo-arena/include/xo/arena/DArenaHashMap.hpp +++ b/xo-arena/include/xo/arena/DArenaHashMap.hpp @@ -45,7 +45,7 @@ namespace xo { using value_type = std::pair; using key_hash = Hash; using key_equal = Equal; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using byte = std::byte; using group_type = detail::ControlGroup; using store_type = detail::HashMapStore; @@ -77,9 +77,8 @@ namespace xo { iterator begin() { return _promote_iterator(_begin_aux()); } iterator end() { return _promote_iterator(_end_aux()); } - std::size_t _n_store() const noexcept { return store_._n_store(); } - MemorySizeInfo _store_info(std::size_t i) const noexcept { - return store_._store_info(i); + void visit_pools(const MemorySizeVisitor & visitor) const { + return store_.visit_pools(visitor); } /** insert @p kv_pair into hash map. diff --git a/xo-arena/include/xo/arena/DArenaVector.hpp b/xo-arena/include/xo/arena/DArenaVector.hpp index b7a0b2aa..33230b0c 100644 --- a/xo-arena/include/xo/arena/DArenaVector.hpp +++ b/xo-arena/include/xo/arena/DArenaVector.hpp @@ -82,7 +82,7 @@ namespace xo { /** arena used for element storage * (Might prefer obj here; refrain to avoid leveling violation) **/ - MemorySizeInfo _store_info() const { return store_._store_info(); } + void visit_pools(const MemorySizeVisitor & fn) const { store_.visit_pools(fn); } /** reserve space, if possible, for at least @p z elements. * Always limited by ArenaConfig.size_ diff --git a/xo-arena/include/xo/arena/DCircularBuffer.hpp b/xo-arena/include/xo/arena/DCircularBuffer.hpp index 538d272d..ba744531 100644 --- a/xo-arena/include/xo/arena/DCircularBuffer.hpp +++ b/xo-arena/include/xo/arena/DCircularBuffer.hpp @@ -83,8 +83,8 @@ namespace xo { const_span_type occupied_range() const noexcept { return occupied_range_; } const_span_type input_range() const noexcept { return input_range_; } - std::size_t _n_store() const noexcept; - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** report memory-size info for this buffer to @p fn **/ + void visit_pools(const MemorySizeVisitor & fn) const; /** verify DCircularBuffer invariants. * Act on failure according to policy @p p diff --git a/xo-arena/include/xo/arena/MemorySizeInfo.hpp b/xo-arena/include/xo/arena/MemorySizeInfo.hpp index 7cba082c..f12dcce5 100644 --- a/xo-arena/include/xo/arena/MemorySizeInfo.hpp +++ b/xo-arena/include/xo/arena/MemorySizeInfo.hpp @@ -5,7 +5,8 @@ #pragma once -#include +#include +#include namespace xo { namespace mm { @@ -31,7 +32,12 @@ namespace xo { std::size_t reserved_ = 0; }; - } + /** function that visits MemorySizeInfo for a collection of @p n memory pools. + * Each pool reported with index @p i in [0, n), with associated + * size record @p info. + **/ + using MemorySizeVisitor = std::function; + } } /* end MemorySizeInfo.hpp */ diff --git a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp index 74f2f4e7..22bfb120 100644 --- a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp +++ b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp @@ -19,7 +19,7 @@ namespace xo { using group_type = detail::ControlGroup; using control_vector_type = xo::mm::DArenaVector; using slot_vector_type = xo::mm::DArenaVector; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; public: /** group_exp2: number of groups {x, 2^x} **/ @@ -48,16 +48,9 @@ namespace xo { size_type capacity() const noexcept { return n_group_ * c_group_size; } float load_factor() const noexcept { return size_ / static_cast(n_slot_); } - std::size_t _n_store() const noexcept { return 2; } - MemorySizeInfo _store_info(std::size_t i) const noexcept { - switch (i) { - case 0: - return control_._store_info(); - case 1: - return slots_._store_info(); - } - - return MemorySizeInfo::sentinel(); + void visit_pools(const MemorySizeVisitor & visitor) const { + control_.visit_pools(visitor); + slots_.visit_pools(visitor); } void resize_from_empty(const std::pairallocated(), - this->committed(), - this->reserved()); + void + DArena::visit_pools(const MemorySizeVisitor & fn) const { + fn(MemorySizeInfo(config_.name_, + this->allocated(), + this->committed(), + this->reserved())); } AllocInfo diff --git a/xo-arena/src/arena/DCircularBuffer.cpp b/xo-arena/src/arena/DCircularBuffer.cpp index 2a5fb486..667126af 100644 --- a/xo-arena/src/arena/DCircularBuffer.cpp +++ b/xo-arena/src/arena/DCircularBuffer.cpp @@ -79,30 +79,16 @@ namespace xo { { } - std::size_t - DCircularBuffer::_n_store() const noexcept + void + DCircularBuffer::visit_pools(const MemorySizeVisitor & visitor) const { - return 2; - } + visitor(MemorySizeInfo(config_.name_, + occupied_range_.size(), + mapped_range_.size(), + reserved_range_.size())); - MemorySizeInfo - DCircularBuffer::_store_info(std::size_t i) const noexcept - { - switch (i) { - case 0: - return MemorySizeInfo(config_.name_, - occupied_range_.size(), - mapped_range_.size(), - reserved_range_.size()); - case 1: - return pinned_spans_._store_info(); - default: - break; - } - - return MemorySizeInfo::sentinel(); + pinned_spans_.visit_pools(visitor); } - bool DCircularBuffer::verify_ok(verify_policy policy) const diff --git a/xo-expression2/include/xo/expression2/StringTable.hpp b/xo-expression2/include/xo/expression2/StringTable.hpp index b55c48ee..8d0354c8 100644 --- a/xo-expression2/include/xo/expression2/StringTable.hpp +++ b/xo-expression2/include/xo/expression2/StringTable.hpp @@ -21,7 +21,7 @@ namespace xo { class StringTable { public: using DArena = xo::mm::DArena; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using StringMap = xo::map::DArenaHashMap; using size_type = StringMap::size_type; @@ -46,8 +46,8 @@ namespace xo { **/ bool verify_ok(verify_policy p = verify_policy::throw_only()) const; - std::size_t _n_store() const noexcept; - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit string-table memory pools, call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; private: /** allocate string storage in this arena; use DString to represent each string. diff --git a/xo-expression2/src/expression2/StringTable.cpp b/xo-expression2/src/expression2/StringTable.cpp index 79a17067..174c9e9f 100644 --- a/xo-expression2/src/expression2/StringTable.cpp +++ b/xo-expression2/src/expression2/StringTable.cpp @@ -160,22 +160,11 @@ namespace xo { return true; } - std::size_t - StringTable::_n_store() const noexcept + void + StringTable::visit_pools(const MemorySizeVisitor & visitor) const { - return 1 + map_._n_store(); - } - - MemorySizeInfo - StringTable::_store_info(std::size_t i) const noexcept - { - if (i == 0) - return strings_._store_info(); - - if (i+1 < map_._n_store()) - return map_._store_info(i-1); - - return MemorySizeInfo::sentinel(); + strings_.visit_pools(visitor); + map_.visit_pools(visitor); } } /*namespace scm*/ diff --git a/xo-gc/include/xo/gc/DX1Collector.hpp b/xo-gc/include/xo/gc/DX1Collector.hpp index af41ae0d..2ef7148a 100644 --- a/xo-gc/include/xo/gc/DX1Collector.hpp +++ b/xo-gc/include/xo/gc/DX1Collector.hpp @@ -81,7 +81,7 @@ namespace xo { /** faceted object pointer to this instance */ template obj ref() { return obj(this); } - + #ifdef NOT_YET /** create instance with default configuration, * generation size @p gen_z @@ -110,6 +110,11 @@ namespace xo { /** total allocated memory in bytes, across all {role, generation} **/ size_type allocated_total() const noexcept; + /** introspection for memory use. + * Call @p visitor(info) for each pool owned by this allocator + **/ + void visit_pools(const MemorySizeVisitor & visitor) const; + /** true iff address @p addr allocated from this collector * in role @p r (according to current GC state) **/ diff --git a/xo-gc/include/xo/gc/detail/IAllocator_DX1Collector.hpp b/xo-gc/include/xo/gc/detail/IAllocator_DX1Collector.hpp index 424f24ff..ca529990 100644 --- a/xo-gc/include/xo/gc/detail/IAllocator_DX1Collector.hpp +++ b/xo-gc/include/xo/gc/detail/IAllocator_DX1Collector.hpp @@ -48,6 +48,8 @@ namespace xo { static size_type available(const DX1Collector &) noexcept; /** space used by @p d across all {roles, generations}. **/ static size_type allocated(const DX1Collector &) noexcept; + /** visit memory pools owned by this allocator; call fn(info) for each pool **/ + static void visit_pools(const DX1Collector & d, const MemorySizeVisitor & fn); /** true iff address @p p comes from collector @p d **/ static bool contains(const DX1Collector & d, const void * p) noexcept; /** report last error, if any, for collector @p d **/ diff --git a/xo-gc/src/gc/DX1Collector.cpp b/xo-gc/src/gc/DX1Collector.cpp index 16bdedc3..a4375da5 100644 --- a/xo-gc/src/gc/DX1Collector.cpp +++ b/xo-gc/src/gc/DX1Collector.cpp @@ -96,8 +96,18 @@ namespace xo { .store_header_flag_ = false}); for (uint32_t igen = 0, ngen = cfg.n_generation_; igen < ngen; ++igen) { - space_storage_[0][igen] = DArena::map(cfg.arena_config_); - space_storage_[1][igen] = DArena::map(cfg.arena_config_); + { + char buf[40]; + snprintf(buf, sizeof(buf), "x1-space-G%u-a", igen); + + space_storage_[0][igen] = DArena::map(cfg.arena_config_.with_name(std::string(buf))); + } + { + char buf[40]; + snprintf(buf, sizeof(buf), "x1-space-G%u-b", igen); + + space_storage_[1][igen] = DArena::map(cfg.arena_config_.with_name(std::string(buf))); + } space_[role::to_space()][igen] = &space_storage_[0][igen]; space_[role::from_space()][igen] = &space_storage_[1][igen]; @@ -109,6 +119,19 @@ namespace xo { } } + void + DX1Collector::visit_pools(const MemorySizeVisitor & visitor) const + { + object_types_.visit_pools(visitor); + roots_.visit_pools(visitor); + + for (uint32_t i = 0; i < c_n_role; ++i) { + for (uint32_t j = 0; j < config_.n_generation_; ++j) { + space_storage_[i][j].visit_pools(visitor); + } + } + } + bool DX1Collector::contains(role r, const void * addr) const noexcept { diff --git a/xo-gc/src/gc/IAllocator_DX1Collector.cpp b/xo-gc/src/gc/IAllocator_DX1Collector.cpp index 58e89941..039e84df 100644 --- a/xo-gc/src/gc/IAllocator_DX1Collector.cpp +++ b/xo-gc/src/gc/IAllocator_DX1Collector.cpp @@ -56,6 +56,12 @@ namespace xo { return d.allocated_total(); } + void + IAllocator_DX1Collector::visit_pools(const DX1Collector & d, const MemorySizeVisitor & visitor) + { + d.visit_pools(visitor); + } + bool IAllocator_DX1Collector::contains(const DX1Collector & d, const void * addr) noexcept { diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 5165c9a8..5aecbc55 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -61,14 +61,14 @@ namespace xo { using Stack = void *; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using span_type = xo::mm::span; public: VirtualSchematikaMachine(const VsmConfig & config); - size_t _n_store() const noexcept; - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit vsm-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; /** begin interactive session. **/ void begin_interactive_session(); diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index d40b85c6..7c4873fb 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -30,20 +30,11 @@ namespace xo { reader_{config.rdr_config_, mm_.to_op()} {} - std::size_t - VirtualSchematikaMachine::_n_store() const noexcept + void + VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const { - // oops. need something that goes through AAllocator api - - return reader_._n_store(); - } - - MemorySizeInfo - VirtualSchematikaMachine::_store_info(std::size_t i) const noexcept - { - // oops. need something poly that goes through AAllocator api - - return reader_._store_info(i); + mm_.visit_pools(visitor); + reader_.visit_pools(visitor); } void diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index a0554f87..2ad7122d 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -28,6 +28,7 @@ namespace xo { using xo::scm::VsmResultExt; using xo::scm::DFloat; using xo::mm::AGCObject; + using xo::mm::MemorySizeInfo; using span_type = xo::scm::VirtualSchematikaMachine::span_type; using Catch::Matchers::WithinAbs; @@ -55,6 +56,8 @@ namespace xo { namespace ut { TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]") { + scope log(XO_DEBUG(true)); + VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -73,6 +76,15 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); + + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + vsm.visit_pools(visitor); } } /*namespace ut*/ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 89569695..3fae8903 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -36,7 +36,7 @@ namespace xo { using AAllocator = xo::mm::AAllocator; using ArenaConfig = xo::mm::ArenaConfig; using DArena = xo::mm::DArena; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using size_type = std::size_t; public: @@ -62,10 +62,8 @@ namespace xo { /** top of parser stack **/ obj top_ssm() const; - /** number of distinct memory pools owned by PS **/ - std::size_t _n_store() const noexcept; - /** memory consumption for i'th memory pool **/ - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit psm-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; ///@} diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 83e9230b..8c3f51b1 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -156,7 +156,7 @@ namespace xo { using token_type = Token; using ArenaConfig = xo::mm::ArenaConfig; using AAllocator = xo::mm::AAllocator; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using ppindentinfo = xo::print::ppindentinfo; using size_type = std::size_t; @@ -193,10 +193,8 @@ namespace xo { /** top of parser stack **/ obj top_ssm() const; - /** number of distinct memory pools owned by PS **/ - std::size_t _n_store() const noexcept; - /** memory consumption for i'th memory pool **/ - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit parser-owned memory pools; invoke visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; ///@} /** scm-schematikaparser-general-methods **/ diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index 3c2b5312..ee3de91f 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -36,7 +36,7 @@ namespace xo { class SchematikaReader { public: using AAllocator = xo::mm::AAllocator; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using span_type = xo::mm::span; using size_type = std::size_t; @@ -44,8 +44,11 @@ namespace xo { SchematikaReader(const ReaderConfig & config, obj expr_alloc); - std::size_t _n_store() const noexcept; - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit reader-owned memory pools; call visitor(info) for each. + * Specifically exclude expr_alloc, since we don't consider + * that reader-owned + **/ + void visit_pools(const MemorySizeVisitor & visitor) const; /** true iff parser is at top-level. * false iff parser is working on incomplete expression diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index ff845762..38f7ff4a 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -54,27 +54,14 @@ namespace xo { return this->stack_->top(); } - std::size_t - ParserStateMachine::_n_store() const noexcept + void + ParserStateMachine::visit_pools(const MemorySizeVisitor & visitor) const { - return stringtable_._n_store() + 1; - } - - MemorySizeInfo - ParserStateMachine::_store_info(std::size_t i) const noexcept - { - size_t n0 = stringtable_._n_store(); - - if (i < n0) - return stringtable_._store_info(i); - - if (i == n0) - return parser_alloc_._store_info(); + stringtable_.visit_pools(visitor); + parser_alloc_.visit_pools(visitor); // not counting expr_alloc_. We don't consider // that to be owned by ParserStateMachine - - return MemorySizeInfo::sentinel(); } void diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 07c74d17..c53acc16 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -47,16 +47,10 @@ namespace xo { return psm_.top_ssm(); } - std::size_t - SchematikaParser::_n_store() const noexcept + void + SchematikaParser::visit_pools(const MemorySizeVisitor & visitor) const { - return psm_._n_store(); - } - - MemorySizeInfo - SchematikaParser::_store_info(std::size_t i) const noexcept - { - return psm_._store_info(i); + return psm_.visit_pools(visitor); } void diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index 097c68df..47140d63 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -21,27 +21,11 @@ namespace xo { { } - std::size_t - SchematikaReader::_n_store() const noexcept + void + SchematikaReader::visit_pools(const MemorySizeVisitor & visitor) const { - return tokenizer_._n_store() + parser_._n_store(); - } - - MemorySizeInfo - SchematikaReader::_store_info(std::size_t i) const noexcept - { - size_t n_tk = tokenizer_._n_store(); - - if (i < n_tk) { - return tokenizer_._store_info(i); - } - - size_t n_pr = parser_._n_store(); - - if (i < n_tk + n_pr) - return parser_._store_info(i - n_tk); - - return MemorySizeInfo::sentinel(); + tokenizer_.visit_pools(visitor); + parser_.visit_pools(visitor); } bool diff --git a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp index 83015c03..0a212a8f 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Tokenizer.hpp @@ -61,7 +61,7 @@ namespace xo { using error_type = TokenizerError; using DCircularBuffer = xo::mm::DCircularBuffer; using CircularBufferConfig = xo::mm::CircularBufferConfig; - using MemorySizeInfo = xo::mm::MemorySizeInfo; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using span_type = xo::mm::span; //using input_state_type = TkInputState; using result_type = scan_result; @@ -91,10 +91,8 @@ namespace xo { const TkInputState & input_state() const { return input_state_; } #pragma GCC diagnostic pop - /** number of distinct memory pools owned by tokenizer **/ - std::size_t _n_store() const noexcept; - /** memory consumption for i'th memory pool **/ - MemorySizeInfo _store_info(std::size_t i) const noexcept; + /** visit tokenizer-owned memory pools; invoke visitor(info) for each one **/ + void visit_pools(const MemorySizeVisitor & visitor) const; ///@} diff --git a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp index c36d85a5..f176a88f 100644 --- a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp +++ b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp @@ -22,16 +22,10 @@ namespace xo { this->input_state_.discard_current_line(); } - std::size_t - Tokenizer::_n_store() const noexcept + void + Tokenizer::visit_pools(const MemorySizeVisitor & visitor) const { - return input_buffer_._n_store(); - } - - MemorySizeInfo - Tokenizer::_store_info(std::size_t i) const noexcept - { - return input_buffer_._store_info(i); + input_buffer_.visit_pools(visitor); } bool From ecf686b1a90c611aa2503140d86c76d8fdee08c2 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 10:32:43 -0500 Subject: [PATCH 148/258] xo-reader2 stack: curate memory pool naming --- xo-arena/include/xo/arena/DArenaHashMap.hpp | 16 ++++++++++------ xo-arena/include/xo/arena/MemorySizeInfo.hpp | 1 + .../include/xo/arena/hashmap/HashMapStore.hpp | 4 ++-- xo-arena/src/arena/DCircularBuffer.cpp | 2 +- xo-arena/utest/DArenaHashMap.test.cpp | 12 ++++++------ xo-expression2/src/expression2/StringTable.cpp | 2 +- xo-reader2/include/xo/reader2/ReaderConfig.hpp | 2 +- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/xo-arena/include/xo/arena/DArenaHashMap.hpp b/xo-arena/include/xo/arena/DArenaHashMap.hpp index da0e742a..c40f6926 100644 --- a/xo-arena/include/xo/arena/DArenaHashMap.hpp +++ b/xo-arena/include/xo/arena/DArenaHashMap.hpp @@ -55,9 +55,11 @@ namespace xo { public: /** create hash map **/ - DArenaHashMap(size_type hint_max_capacity, + DArenaHashMap(const std::string & name, + size_type hint_max_capacity, bool debug_flag = false); - DArenaHashMap(Hash && hash = Hash(), + DArenaHashMap(const std::string & name, + Hash && hash = Hash(), Equal && eq = Equal(), size_type hint_max_capacity = 0, bool debug_flag = false); @@ -196,9 +198,10 @@ namespace xo { }; template - DArenaHashMap::DArenaHashMap(size_type hint_max_capacity, + DArenaHashMap::DArenaHashMap(const std::string & name, + size_type hint_max_capacity, bool debug_flag) - : DArenaHashMap(Hash(), Equal(), hint_max_capacity, debug_flag) + : DArenaHashMap(name, Hash(), Equal(), hint_max_capacity, debug_flag) { } @@ -207,13 +210,14 @@ namespace xo { * last 16 bytes will be copy of first 16 bytes */ template - DArenaHashMap::DArenaHashMap(Hash && hash, + DArenaHashMap::DArenaHashMap(const std::string & name, + Hash && hash, Equal && eq, size_type hint_max_capacity, bool debug_flag) : hash_{std::move(hash)}, equal_{std::move(eq)}, - store_{"arenahashmap", lub_exp2(lub_group_mult(hint_max_capacity))}, + store_{name, lub_exp2(lub_group_mult(hint_max_capacity))}, debug_flag_{debug_flag} { } diff --git a/xo-arena/include/xo/arena/MemorySizeInfo.hpp b/xo-arena/include/xo/arena/MemorySizeInfo.hpp index f12dcce5..540453fd 100644 --- a/xo-arena/include/xo/arena/MemorySizeInfo.hpp +++ b/xo-arena/include/xo/arena/MemorySizeInfo.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include #include diff --git a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp index 22bfb120..34850222 100644 --- a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp +++ b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp @@ -32,11 +32,11 @@ namespace xo { n_slot_{group_exp2.second * c_group_size}, control_{control_vector_type::map (xo::mm::ArenaConfig{ - .name_ = name, + .name_ = name + "-ctl", .size_ = control_size(n_slot_)})}, slots_{slot_vector_type::map (xo::mm::ArenaConfig{ - .name_ = name, + .name_ = name + "-slots", .size_ = n_slot_ * sizeof(value_type)})} { /* here: arenas have allocated address range, but no committed memory yet */ diff --git a/xo-arena/src/arena/DCircularBuffer.cpp b/xo-arena/src/arena/DCircularBuffer.cpp index 667126af..372462f4 100644 --- a/xo-arena/src/arena/DCircularBuffer.cpp +++ b/xo-arena/src/arena/DCircularBuffer.cpp @@ -75,7 +75,7 @@ namespace xo { mapped_range_{reserved_range_.prefix(0)}, occupied_range_{mapped_range_.prefix(0)}, input_range_{occupied_range_.prefix(0)}, - pinned_spans_{} + pinned_spans_{DArenaVector::map(ArenaConfig().with_name(config.name_ + "-pins"))} { } diff --git a/xo-arena/utest/DArenaHashMap.test.cpp b/xo-arena/utest/DArenaHashMap.test.cpp index bc672c8b..02ac3fc3 100644 --- a/xo-arena/utest/DArenaHashMap.test.cpp +++ b/xo-arena/utest/DArenaHashMap.test.cpp @@ -24,7 +24,7 @@ namespace xo { { using HashMap = DArenaHashMap; - HashMap map; + HashMap map("utest"); REQUIRE(map.empty()); REQUIRE(map.size() == 0); @@ -36,7 +36,7 @@ namespace xo { { using HashMap = DArenaHashMap; - HashMap map(257); + HashMap map("utest", 257); REQUIRE(map.empty()); REQUIRE(map.size() == 0); @@ -49,7 +49,7 @@ namespace xo { { using HashMap = DArenaHashMap; - HashMap map; + HashMap map("utest"); REQUIRE(map.empty()); REQUIRE(map.size() == 0); @@ -209,7 +209,7 @@ namespace xo { */ for (std::uint32_t n = 0; n <= 8; ) { - HashMap hash_map; + HashMap hash_map("utest"); auto test_fn = [&rgen, &hash_map](bool dbg_flag, std::uint32_t n) @@ -245,7 +245,7 @@ namespace xo { using HashMap = DArenaHashMap; - HashMap map; + HashMap map("utest"); // copy keys here so we can print stuff std::vector key_v; @@ -336,7 +336,7 @@ namespace xo { { using HashMap = DArenaHashMap; - HashMap map(1024); + HashMap map("utest", 1024); REQUIRE(map.verify_ok()); diff --git a/xo-expression2/src/expression2/StringTable.cpp b/xo-expression2/src/expression2/StringTable.cpp index 174c9e9f..2d23d03e 100644 --- a/xo-expression2/src/expression2/StringTable.cpp +++ b/xo-expression2/src/expression2/StringTable.cpp @@ -19,7 +19,7 @@ namespace xo { bool debug_flag) : strings_{DArena::map(ArenaConfig{.name_ = "strings", .size_ = hint_max_capacity})}, - map_{hint_max_capacity} + map_{"stringkeys", hint_max_capacity} { (void)debug_flag; } diff --git a/xo-reader2/include/xo/reader2/ReaderConfig.hpp b/xo-reader2/include/xo/reader2/ReaderConfig.hpp index 5b02e62c..62e0e758 100644 --- a/xo-reader2/include/xo/reader2/ReaderConfig.hpp +++ b/xo-reader2/include/xo/reader2/ReaderConfig.hpp @@ -28,7 +28,7 @@ namespace xo { bool tk_debug_flag_ = false; /** arena configuration for parser stack **/ - ArenaConfig parser_arena_config_ { .name_ = "parer-arena", + ArenaConfig parser_arena_config_ { .name_ = "parser-arena", .size_ = 2*1024*1024, .hugepage_z_ = 2*1024*1024, .store_header_flag_ = false, From 0e6afabaa3101d0792928ef91df943b64e8d57e8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 11:55:50 -0500 Subject: [PATCH 149/258] xo-interpreter2 stack: cleanup memory reporting --- xo-arena/include/xo/arena/ArenaConfig.hpp | 8 ++++++- xo-arena/include/xo/arena/DArena.hpp | 2 +- xo-arena/include/xo/arena/DArenaHashMap.hpp | 6 +++-- xo-arena/include/xo/arena/DArenaVector.hpp | 22 ++++++++++++++++--- .../include/xo/arena/hashmap/HashMapStore.hpp | 6 +++-- xo-facet/include/xo/facet/FacetRegistry.hpp | 22 ++++++++++++++----- .../utest/VirtualSchematikaMachine.test.cpp | 2 ++ .../utest/interpreter2_utest_main.cpp | 5 +++++ .../include/xo/object2/init_object2.hpp | 2 +- xo-object2/src/object2/init_object2.cpp | 2 +- .../include/xo/reflectutil/typeseq.hpp | 6 ++++- 11 files changed, 66 insertions(+), 17 deletions(-) diff --git a/xo-arena/include/xo/arena/ArenaConfig.hpp b/xo-arena/include/xo/arena/ArenaConfig.hpp index 9ca2a387..d1ecbdca 100644 --- a/xo-arena/include/xo/arena/ArenaConfig.hpp +++ b/xo-arena/include/xo/arena/ArenaConfig.hpp @@ -31,6 +31,12 @@ namespace xo { return copy; } + ArenaConfig with_store_header_flag(bool x) const { + ArenaConfig copy(*this); + copy.store_header_flag_ = x; + return copy; + } + /** @defgroup mm-arenaconfig-instance-vars ArenaConfig members **/ ///@{ @@ -44,7 +50,7 @@ namespace xo { std::size_t hugepage_z_ = 2 * 1024 * 1024; /** true to store header (8 bytes) at the beginning of each allocation. * necessary and sufficient to allows iterating over allocs - * present in arena + * present in arena. **/ bool store_header_flag_ = false; /** configuration for per-alloc header **/ diff --git a/xo-arena/include/xo/arena/DArena.hpp b/xo-arena/include/xo/arena/DArena.hpp index 4c12c8cb..658d2b1b 100644 --- a/xo-arena/include/xo/arena/DArena.hpp +++ b/xo-arena/include/xo/arena/DArena.hpp @@ -205,7 +205,7 @@ namespace xo { void establish_initial_guard() noexcept; /** checkpoint arena state. Revert to the same state with - * @ref rstore + * @ref restore **/ Checkpoint checkpoint() noexcept { return Checkpoint(free_); } diff --git a/xo-arena/include/xo/arena/DArenaHashMap.hpp b/xo-arena/include/xo/arena/DArenaHashMap.hpp index c40f6926..c52b9894 100644 --- a/xo-arena/include/xo/arena/DArenaHashMap.hpp +++ b/xo-arena/include/xo/arena/DArenaHashMap.hpp @@ -30,8 +30,10 @@ namespace xo { * * Replicates (to the extent feasible) std::unordered_map * - * @tparam K key type. - * @tparam V value type. + * @tparam Key key type. + * @tparam Value value type. + * @tparam Hash hash function for keys + * @tparam Equal equality function for keys **/ template @@ -122,14 +123,16 @@ namespace xo { size_type arena_align_z, DArena::value_type lo, DArena::value_type hi) - : store_{cfg, page_z, arena_align_z, lo, hi} + : store_{cfg, page_z, arena_align_z, lo, hi}, + zero_ckp_{store_.checkpoint()} {} template DArenaVector::DArenaVector(DArenaVector && other) - : size_{other.size_}, store_{std::move(other.store_)} + : size_{other.size_}, store_{std::move(other.store_)}, zero_ckp_{std::move(other.zero_ckp_)} { other.size_ = 0; + other.zero_ckp_ = DArena::Checkpoint(); } template @@ -153,8 +156,10 @@ namespace xo { { this->size_ = other.size_; this->store_ = std::move(other.store_); + this->zero_ckp_ = std::move(other.zero_ckp_); other.size_ = 0; + other.zero_ckp_ = DArena::Checkpoint(); return *this; } @@ -166,6 +171,7 @@ namespace xo { DArenaVector retval; retval.store_ = std::move(DArena::map(cfg)); + retval.zero_ckp_ = retval.store_.checkpoint(); return retval; } @@ -179,9 +185,11 @@ namespace xo { template void DArenaVector::resize(size_type z) { + // new arena size in bytes + size_t req_z = z * sizeof(T); + if (z > size_) { // expand arena to accomodate - size_t req_z = z * sizeof(T); store_.expand(req_z); @@ -208,6 +216,14 @@ namespace xo { } } + // rewind to checkpoint, then reallocate. + // This is for form's sake, so that DArena considers memory + // to be 'allocated'. DArenaVector doesn't care for itself, + // but this preserves expected behavior of visit_pools(). + // + store_.restore(zero_ckp_); + store_.alloc(xo::reflect::typeseq::id(), req_z); + this->size_ = z; } diff --git a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp index 34850222..436e88ed 100644 --- a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp +++ b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp @@ -33,11 +33,13 @@ namespace xo { control_{control_vector_type::map (xo::mm::ArenaConfig{ .name_ = name + "-ctl", - .size_ = control_size(n_slot_)})}, + .size_ = control_size(n_slot_), + .store_header_flag_ = false})}, slots_{slot_vector_type::map (xo::mm::ArenaConfig{ .name_ = name + "-slots", - .size_ = n_slot_ * sizeof(value_type)})} + .size_ = n_slot_ * sizeof(value_type), + .store_header_flag_ = false})} { /* here: arenas have allocated address range, but no committed memory yet */ diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index da3a6676..ad19cf53 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -10,6 +10,7 @@ #include "facet_implementation.hpp" #include "typeseq.hpp" #include "obj.hpp" +#include #include #include #include @@ -38,6 +39,7 @@ namespace xo { **/ class FacetRegistry { public: + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using typeseq = xo::reflect::typeseq; using key_type = std::pair; @@ -51,9 +53,12 @@ namespace xo { } }; - /** singleton instance **/ - static FacetRegistry & instance() { - static FacetRegistry s_instance; + /** singleton instance. + * @p hint_max_capacity is a lower bound for swiss hash map implementation. + * Only honored the first time instance is called. + **/ + static FacetRegistry & instance(uint32_t hint_max_capacity = 1024) { + static FacetRegistry s_instance(hint_max_capacity); return s_instance; } @@ -88,6 +93,11 @@ namespace xo { /** Number of registered (facet, repr) pairs **/ std::size_t size() const { return registry_.size(); } + /** visit memory pools owned by facet registry **/ + void visit_pools(const MemorySizeVisitor & visitor) { + registry_.visit_pools(visitor); + } + /** Check if implementation is registered **/ bool contains(typeseq facet_id, typeseq repr_id) const @@ -221,10 +231,12 @@ namespace xo { } private: - FacetRegistry() = default; + FacetRegistry(uint32_t hint_max_capacity) + : registry_("facets", hint_max_capacity, false /*!debug_flag*/) {} /** runtime lookup table (AFacet,DRepr) -> impl **/ - std::unordered_map registry_; + xo::map::DArenaHashMap registry_; + //std::unordered_map registry_; }; } /*namespace facet*/ diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 2ad7122d..a4970b72 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -29,6 +29,7 @@ namespace xo { using xo::scm::DFloat; using xo::mm::AGCObject; using xo::mm::MemorySizeInfo; + using xo::facet::FacetRegistry; using span_type = xo::scm::VirtualSchematikaMachine::span_type; using Catch::Matchers::WithinAbs; @@ -84,6 +85,7 @@ namespace xo { xtag("resv", info.reserved_)); }; + FacetRegistry::instance().visit_pools(visitor); vsm.visit_pools(visitor); } diff --git a/xo-interpreter2/utest/interpreter2_utest_main.cpp b/xo-interpreter2/utest/interpreter2_utest_main.cpp index addc079a..ca898beb 100644 --- a/xo-interpreter2/utest/interpreter2_utest_main.cpp +++ b/xo-interpreter2/utest/interpreter2_utest_main.cpp @@ -3,6 +3,7 @@ * @author Roland Conybeare, Jan 2026 **/ +#include #include #define CATCH_CONFIG_RUNNER @@ -11,8 +12,12 @@ int main(int argc, char* argv[]) { + using xo::facet::FacetRegistry; using xo::Subsystem; + // initialize facet registry + FacetRegistry::instance(1024); + // initialize subsystems Subsystem::initialize_all(); diff --git a/xo-object2/include/xo/object2/init_object2.hpp b/xo-object2/include/xo/object2/init_object2.hpp index 5c26e76d..aa3dd510 100644 --- a/xo-object2/include/xo/object2/init_object2.hpp +++ b/xo-object2/include/xo/object2/init_object2.hpp @@ -1,5 +1,5 @@ /** @file init_object2.hpp -* + * * @author Roland Conybeare, Jan 2026 **/ diff --git a/xo-object2/src/object2/init_object2.cpp b/xo-object2/src/object2/init_object2.cpp index b5e57aba..0f804fe0 100644 --- a/xo-object2/src/object2/init_object2.cpp +++ b/xo-object2/src/object2/init_object2.cpp @@ -1,5 +1,5 @@ /** @file init_object2.cpp -* + * * @author Roland Conybeare, Jan 2026 **/ diff --git a/xo-reflectutil/include/xo/reflectutil/typeseq.hpp b/xo-reflectutil/include/xo/reflectutil/typeseq.hpp index dd0b869a..d2f888cd 100644 --- a/xo-reflectutil/include/xo/reflectutil/typeseq.hpp +++ b/xo-reflectutil/include/xo/reflectutil/typeseq.hpp @@ -16,6 +16,10 @@ namespace xo { */ template struct typeseq_impl { + /** create sentinel value **/ + typeseq_impl() = default; + + /** typeseq with specific unique id **/ explicit typeseq_impl(int32_t s) : seqno_{s} {} /** Can't have this be constexpr. @@ -56,7 +60,7 @@ namespace xo { private: static int32_t s_next_id; - int32_t seqno_; + int32_t seqno_ = 0; }; template From e6fdd2b436599e05c6c277bb70c14c2abd4afd69 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 12:23:56 -0500 Subject: [PATCH 150/258] xo-interpreter2 stack: + MemorySizeInfo.used + pop for DArenaHashMap --- xo-arena/include/xo/arena/MemorySizeInfo.hpp | 11 +++++++---- .../include/xo/arena/hashmap/HashMapStore.hpp | 17 +++++++++++++++-- xo-arena/src/arena/DArena.cpp | 5 +++++ xo-arena/src/arena/DCircularBuffer.cpp | 1 + .../utest/VirtualSchematikaMachine.test.cpp | 1 + 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/xo-arena/include/xo/arena/MemorySizeInfo.hpp b/xo-arena/include/xo/arena/MemorySizeInfo.hpp index 540453fd..764eae6d 100644 --- a/xo-arena/include/xo/arena/MemorySizeInfo.hpp +++ b/xo-arena/include/xo/arena/MemorySizeInfo.hpp @@ -15,15 +15,18 @@ namespace xo { struct MemorySizeInfo { using size_type = std::size_t; - MemorySizeInfo(std::string_view name, std::size_t a, std::size_t c, std::size_t r) - : resource_name_{name}, allocated_{a}, committed_{c}, reserved_{r} + MemorySizeInfo() = default; + MemorySizeInfo(std::string_view name, std::size_t u, std::size_t a, std::size_t c, std::size_t r) + : resource_name_{name}, used_{u}, allocated_{a}, committed_{c}, reserved_{r} {} - static MemorySizeInfo sentinel() { return MemorySizeInfo("", 0, 0, 0); } + static MemorySizeInfo sentinel() { return MemorySizeInfo(); } /** resource name **/ std::string_view resource_name_; - /** memory in-use **/ + /** memory used (excluding wasted space) **/ + std::size_t used_ = 0; + /** memory allocated (including wasted space e.g. empty slots in hash tables **/ std::size_t allocated_ = 0; /** memory committed (backed by physical memory) **/ std::size_t committed_ = 0; diff --git a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp index 436e88ed..6393bb02 100644 --- a/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp +++ b/xo-arena/include/xo/arena/hashmap/HashMapStore.hpp @@ -20,6 +20,7 @@ namespace xo { using control_vector_type = xo::mm::DArenaVector; using slot_vector_type = xo::mm::DArenaVector; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using MemorySizeInfo = xo::mm::MemorySizeInfo; public: /** group_exp2: number of groups {x, 2^x} **/ @@ -51,8 +52,20 @@ namespace xo { float load_factor() const noexcept { return size_ / static_cast(n_slot_); } void visit_pools(const MemorySizeVisitor & visitor) const { - control_.visit_pools(visitor); - slots_.visit_pools(visitor); + // complexity here in service of HashMapStore-specific value for MemorySizeInfo.used + + MemorySizeInfo ctl_info; + MemorySizeInfo slot_info; + + control_.visit_pools([&ctl_info](const auto & x) { ctl_info = x; }); + slots_.visit_pools([&slot_info](const auto & x) { slot_info = x; }); + + // control: 1 byte per (key,value) pair + ctl_info.used_ = size_; + slot_info.used_ = size_ * sizeof(value_type); + + visitor(ctl_info); + visitor(slot_info); } void resize_from_empty(const std::pairallocated() /*used*/, this->allocated(), this->committed(), this->reserved())); diff --git a/xo-arena/src/arena/DCircularBuffer.cpp b/xo-arena/src/arena/DCircularBuffer.cpp index 372462f4..e5b1c725 100644 --- a/xo-arena/src/arena/DCircularBuffer.cpp +++ b/xo-arena/src/arena/DCircularBuffer.cpp @@ -83,6 +83,7 @@ namespace xo { DCircularBuffer::visit_pools(const MemorySizeVisitor & visitor) const { visitor(MemorySizeInfo(config_.name_, + occupied_range_.size() /*used*/, occupied_range_.size(), mapped_range_.size(), reserved_range_.size())); diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index a4970b72..9c70f85c 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -80,6 +80,7 @@ namespace xo { auto visitor = [&log](const MemorySizeInfo & info) { log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), xtag("alloc", info.allocated_), xtag("commit", info.committed_), xtag("resv", info.reserved_)); From 854a8dcc48900eb8d8026368da7d2f52da565e18 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 12:58:55 -0500 Subject: [PATCH 151/258] xo-interpreter2 stack: bugfix: top-level i64 token -> DInteger --- .../utest/VirtualSchematikaMachine.test.cpp | 59 +++++++++++++++++++ xo-reader2/src/reader2/DExprSeqState.cpp | 13 ++-- xo-reader2/utest/SchematikaParser.test.cpp | 54 +++++++++++++++++ 3 files changed, 122 insertions(+), 4 deletions(-) diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 9c70f85c..0a2ba92f 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #ifdef NOT_YET #include @@ -27,6 +29,7 @@ namespace xo { using xo::scm::VsmConfig; using xo::scm::VsmResultExt; using xo::scm::DFloat; + using xo::scm::DInteger; using xo::mm::AGCObject; using xo::mm::MemorySizeInfo; using xo::facet::FacetRegistry; @@ -62,6 +65,25 @@ namespace xo { VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + FacetRegistry::instance().visit_pools(visitor); + vsm.visit_pools(visitor); + } + + TEST_CASE("VirtualSchematikaMachine-const1", "[interpreter2][VSM]") + { + scope log(XO_DEBUG(true)); + + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); + bool eof_flag = false; vsm.begin_interactive_session(); @@ -90,6 +112,43 @@ namespace xo { vsm.visit_pools(visitor); } + TEST_CASE("VirtualSchematikaMachine-const2", "[interpreter2][VSM]") + { + scope log(XO_DEBUG(true)); + + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("1011;"), eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq())); + + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE(x.data()->value() == 1011); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + FacetRegistry::instance().visit_pools(visitor); + vsm.visit_pools(visitor); + } + } /*namespace ut*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index ca6bfa27..802f37a2 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -12,14 +12,19 @@ #include #include + #include #include + #include #include -#include -#include + #include +#include + +#include #include + #include namespace xo { @@ -336,8 +341,8 @@ namespace xo { switch (seqtype_) { case exprseqtype::toplevel_interactive: { - auto i64o = DFloat::box(p_psm->expr_alloc(), - tk.i64_value()); + auto i64o = DInteger::box(p_psm->expr_alloc(), + tk.i64_value()); auto expr = DConstant::make(p_psm->expr_alloc(), i64o); DProgressSsm::start(p_psm->parser_alloc(), diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 0defdeb5..29697389 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -197,6 +197,60 @@ namespace xo { //REQUIRE(result.error_description()); } + TEST_CASE("SchematikaParser-interactive-integer", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 1011 ; + * + **/ + + { + auto & result = parser.on_token(Token::i64_token("1011")); + + log && log("after integer token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::semicolon_token()); + + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); + } + TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") { constexpr bool c_debug_flag = true; From 8f975026776d0e91c0698607b9abde1f4d73b7f4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 13:23:38 -0500 Subject: [PATCH 152/258] xo-reader2 stack: misc qol improvements + improve reader2 utest --- .../include/xo/expression2/Constant.hpp | 13 +++++++++++++ xo-facet/include/xo/facet/OObject.hpp | 9 +++++++++ xo-object2/include/xo/object2/DInteger.hpp | 2 +- xo-object2/include/xo/object2/Integer.hpp | 12 ++++++++++++ xo-reader2/utest/SchematikaParser.test.cpp | 17 +++++++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 xo-expression2/include/xo/expression2/Constant.hpp create mode 100644 xo-object2/include/xo/object2/Integer.hpp diff --git a/xo-expression2/include/xo/expression2/Constant.hpp b/xo-expression2/include/xo/expression2/Constant.hpp new file mode 100644 index 00000000..29e6694f --- /dev/null +++ b/xo-expression2/include/xo/expression2/Constant.hpp @@ -0,0 +1,13 @@ +/** @file Constant.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DConstant.hpp" +#include "detail/IExpression_DConstant.hpp" +#include "detail/IGCObject_DConstant.hpp" +#include "detail/IPrintable_DConstant.hpp" + +/* end Constant.hpp */ diff --git a/xo-facet/include/xo/facet/OObject.hpp b/xo-facet/include/xo/facet/OObject.hpp index e4ed5b06..e6eb0f6d 100644 --- a/xo-facet/include/xo/facet/OObject.hpp +++ b/xo-facet/include/xo/facet/OObject.hpp @@ -253,6 +253,15 @@ namespace xo { //iface_ = *std::launder(&iface_); } + /** use this to access non-facet methods, + * _when representation is known at compile time_. + * + * Deliberately disable this for variants + **/ + DRepr * operator->() + requires (!std::is_same_v) + { return data_; } + #ifdef NOPE DRepr & operator*() { return *data_; } #endif diff --git a/xo-object2/include/xo/object2/DInteger.hpp b/xo-object2/include/xo/object2/DInteger.hpp index c56a4be1..b03693be 100644 --- a/xo-object2/include/xo/object2/DInteger.hpp +++ b/xo-object2/include/xo/object2/DInteger.hpp @@ -28,7 +28,7 @@ namespace xo { /** allocate boxed value @p x using memory from @p mm **/ static DInteger * _box(obj mm, long x); - double value() const noexcept { return value_; } + long value() const noexcept { return value_; } bool pretty(const ppindentinfo & ppii) const; diff --git a/xo-object2/include/xo/object2/Integer.hpp b/xo-object2/include/xo/object2/Integer.hpp new file mode 100644 index 00000000..7279f97d --- /dev/null +++ b/xo-object2/include/xo/object2/Integer.hpp @@ -0,0 +1,12 @@ +/** @file Integer.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DInteger.hpp" +#include "number/IGCObject_DInteger.hpp" +#include "number/IPrintable_DInteger.hpp" + +/* end Integer.hpp */ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 29697389..0761ce39 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include @@ -18,11 +20,15 @@ namespace xo { using xo::scm::syntaxstatetype; // using xo::scm::DDefineSsm; using xo::scm::DExpectExprSsm; + using xo::scm::AExpression; + using xo::scm::DConstant; // using xo::scm::defexprstatetype; //using xo::scm::ParserResult; //using xo::scm::parser_result_type; using xo::scm::Token; using xo::scm::DString; + using xo::scm::DInteger; + using xo::mm::AGCObject; using xo::mm::ArenaConfig; using xo::mm::AAllocator; using xo::mm::DArena; @@ -244,6 +250,17 @@ namespace xo { REQUIRE(!result.is_error()); REQUIRE(result.is_expression()); REQUIRE(result.result_expr()); + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + + REQUIRE(expr->value()); + + auto value_i64 = obj::from(expr->value()); + + REQUIRE(value_i64); + + REQUIRE(value_i64->value() == 1011); } //REQUIRE(result.is_error()); From b994c56bc5185e72e17fc98467c4c3b1085bd1f3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 13:43:00 -0500 Subject: [PATCH 153/258] xo-reader2 stack: convenience #includes + parsing examples --- .../include/xo/expression2/DefineExpr.hpp | 13 ++ xo-object2/include/xo/object2/Float.hpp | 12 ++ xo-object2/include/xo/object2/String.hpp | 12 ++ xo-reader2/utest/SchematikaParser.test.cpp | 147 +++++++++++++++++- 4 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 xo-expression2/include/xo/expression2/DefineExpr.hpp create mode 100644 xo-object2/include/xo/object2/Float.hpp create mode 100644 xo-object2/include/xo/object2/String.hpp diff --git a/xo-expression2/include/xo/expression2/DefineExpr.hpp b/xo-expression2/include/xo/expression2/DefineExpr.hpp new file mode 100644 index 00000000..37a77c03 --- /dev/null +++ b/xo-expression2/include/xo/expression2/DefineExpr.hpp @@ -0,0 +1,13 @@ +/** @file DefineExpr.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DDefineExpr.hpp" +#include "detail/IExpression_DDefineExpr.hpp" +//#include "detail/IGCObject_DDefineExpr.hpp" +#include "detail/IPrintable_DDefineExpr.hpp" + +/* end DefineExpr.hpp */ diff --git a/xo-object2/include/xo/object2/Float.hpp b/xo-object2/include/xo/object2/Float.hpp new file mode 100644 index 00000000..94751ecf --- /dev/null +++ b/xo-object2/include/xo/object2/Float.hpp @@ -0,0 +1,12 @@ +/** @file Float.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DFloat.hpp" +#include "number/IGCObject_DFloat.hpp" +#include "number/IPrintable_DFloat.hpp" + +/* end Float.hpp */ diff --git a/xo-object2/include/xo/object2/String.hpp b/xo-object2/include/xo/object2/String.hpp new file mode 100644 index 00000000..b2e6d09b --- /dev/null +++ b/xo-object2/include/xo/object2/String.hpp @@ -0,0 +1,12 @@ +/** @file String.hpp + * + * @author Roland Conybeare, Feb 22026 + **/ + +#pragma once + +#include "DString.hpp" +#include "string/IGCObject_DString.hpp" +#include "string/IPrintable_DString.hpp" + +/* end String.hpp */ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 0761ce39..9ccad56b 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -9,8 +9,11 @@ #include #include #include +#include #include +#include #include +#include #include #include @@ -20,15 +23,18 @@ namespace xo { using xo::scm::syntaxstatetype; // using xo::scm::DDefineSsm; using xo::scm::DExpectExprSsm; + using xo::scm::AExpression; + using xo::scm::DDefineExpr; using xo::scm::DConstant; -// using xo::scm::defexprstatetype; + //using xo::scm::ParserResult; - //using xo::scm::parser_result_type; using xo::scm::Token; - using xo::scm::DString; - using xo::scm::DInteger; using xo::mm::AGCObject; + using xo::scm::DString; + using xo::scm::DFloat; + using xo::scm::DInteger; + using xo::mm::ArenaConfig; using xo::mm::AAllocator; using xo::mm::DArena; @@ -196,6 +202,9 @@ namespace xo { log && log(xtag("result", result)); REQUIRE(parser.has_incomplete_expr() == false); + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); } // define-expressions not properly implemented @@ -268,6 +277,136 @@ namespace xo { //REQUIRE(result.error_description()); } + TEST_CASE("SchematikaParser-interactive-float", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 3.14159265 ; + * + **/ + + { + auto & result = parser.on_token(Token::f64_token("3.14159265")); + + log && log("after float token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::semicolon_token()); + + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + + REQUIRE(expr->value()); + + auto value_f64 = obj::from(expr->value()); + + REQUIRE(value_f64); + + REQUIRE(value_f64->value() == 3.14159265); + } + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); + } + + TEST_CASE("SchematikaParser-interactive-string", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * "hello world" ; + * + **/ + + { + auto & result = parser.on_token(Token::string_token("hello world")); + + log && log("after string token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::semicolon_token()); + + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + + REQUIRE(expr->value()); + + auto value_str = obj::from(expr->value()); + + REQUIRE(value_str); + + REQUIRE(strcmp(value_str->chars(), "hello world") == 0); + } + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); + } + TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") { constexpr bool c_debug_flag = true; From bdc7b33c8f32e8d704fb9e28e433d2ea0911f5a7 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 14:27:42 -0500 Subject: [PATCH 154/258] xo-reader2 stack: streamlining + arith parser test --- .../include/xo/expression2/ApplyExpr.hpp | 13 +++ .../include/xo/procedure2/DPrimitive.hpp | 4 +- .../xo/procedure2/Primitive_gco_2_gco_gco.hpp | 11 ++ xo-reader2/src/reader2/DProgressSsm.cpp | 36 +++--- xo-reader2/utest/SchematikaParser.test.cpp | 108 ++++++++++++++++++ 5 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 xo-expression2/include/xo/expression2/ApplyExpr.hpp create mode 100644 xo-procedure2/include/xo/procedure2/Primitive_gco_2_gco_gco.hpp diff --git a/xo-expression2/include/xo/expression2/ApplyExpr.hpp b/xo-expression2/include/xo/expression2/ApplyExpr.hpp new file mode 100644 index 00000000..fd9c0764 --- /dev/null +++ b/xo-expression2/include/xo/expression2/ApplyExpr.hpp @@ -0,0 +1,13 @@ +/** @file ApplyExpr.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DApplyExpr.hpp" +#include "detail/IExpression_DApplyExpr.hpp" +//#include "detail/IGCObject_DApplyExpr.hpp" +#include "detail/IPrintable_DApplyExpr.hpp" + +/* end ApplyExpr.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp index 90fdba50..abec46cc 100644 --- a/xo-procedure2/include/xo/procedure2/DPrimitive.hpp +++ b/xo-procedure2/include/xo/procedure2/DPrimitive.hpp @@ -76,9 +76,11 @@ namespace xo { TypeDescr fn_td() const noexcept { return fn_td_; } - bool is_nary() const noexcept { return false; } + std::string_view name() const noexcept { return name_; } static constexpr std::int32_t n_args() noexcept { return Traits::n_args; } + bool is_nary() const noexcept { return false; } + obj apply_nocheck(obj rcx, const DArray * args) { return _apply_nocheck(rcx, args, std::make_index_sequence{}); diff --git a/xo-procedure2/include/xo/procedure2/Primitive_gco_2_gco_gco.hpp b/xo-procedure2/include/xo/procedure2/Primitive_gco_2_gco_gco.hpp new file mode 100644 index 00000000..9e6814f4 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/Primitive_gco_2_gco_gco.hpp @@ -0,0 +1,11 @@ +/** @file Primitive_gco_2_gco_gco.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DPrimitive_gco_2_gco_gco.hpp" +#include "detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp" +#include "detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp" +#include "detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp" + +/* end Primitive_gco_2_gco_gco.hpp */ diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 9fd6e7b1..102384e2 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -1038,21 +1038,27 @@ namespace xo { obj lhs = FacetRegistry::instance().variant(lhs_); - obj rhs; - if (rhs_) - rhs = FacetRegistry::instance().variant(rhs_); - - (void)lhs; - - return ppii.pps()->pretty_struct - (ppii, - "DProgressSsm", - refrtag("lhs", lhs), - refrtag("op", op_type_), - cond(rhs, refrtag("rhs", rhs), "nullptr"), - refrtag("expect", this->get_expect_str()) - ); + obj rhs + = FacetRegistry::instance().try_variant(rhs_); + if (rhs) { + return ppii.pps()->pretty_struct + (ppii, + "DProgressSsm", + refrtag("lhs", lhs), + refrtag("op", op_type_), + refrtag("rhs", rhs), + refrtag("expect", this->get_expect_str()) + ); + } else { + return ppii.pps()->pretty_struct + (ppii, + "DProgressSsm", + refrtag("lhs", lhs), + refrtag("op", op_type_), + refrtag("expect", this->get_expect_str()) + ); + } } obj @@ -1065,7 +1071,7 @@ namespace xo { constexpr const char * c_self_name = "DProgressSsm::assemble_expr"; - if ((op_type_ != optype::invalid) && rhs_) { + if ((op_type_ != optype::invalid) && !rhs_) { std::string errmsg_string = tostr("expected expression on rhs of operator op", xtag("lhs", lhs_), xtag("op", op_type_)); diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 9ccad56b..2fb10ea5 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -26,11 +28,13 @@ namespace xo { using xo::scm::AExpression; using xo::scm::DDefineExpr; + using xo::scm::DApplyExpr; using xo::scm::DConstant; //using xo::scm::ParserResult; using xo::scm::Token; using xo::mm::AGCObject; + using xo::scm::DPrimitive_gco_2_gco_gco; using xo::scm::DString; using xo::scm::DFloat; using xo::scm::DInteger; @@ -407,6 +411,110 @@ namespace xo { //REQUIRE(result.error_description()); } + TEST_CASE("SchematikaParser-interactive-arith", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 3.14159265 * 0.5 ; + * + **/ + + { + auto & result = parser.on_token(Token::f64_token("3.14159265")); + + log && log("after float(3.14159265) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::star_token()); + + log && log("after star token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::f64_token("0.5")); + + log && log("after float(0.5) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::semicolon_token()); + + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + + REQUIRE(expr->n_args() == 2); + + auto fn = obj::from(expr->fn()); + REQUIRE(fn); + + auto pm = obj::from(fn->value()); + REQUIRE(pm); + REQUIRE(pm->name() == "_mul"); + + auto lhs = obj::from(expr->arg(0)); + REQUIRE(lhs); + + auto lhs_f64 = obj::from(lhs->value()); + REQUIRE(lhs_f64); + REQUIRE(lhs_f64->value() == 3.14159265); + + auto rhs = obj::from(expr->arg(1)); + REQUIRE(rhs); + + auto rhs_f64 = obj::from(rhs->value()); + REQUIRE(rhs_f64); + REQUIRE(rhs_f64->value() == 0.5); + } + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); + } + TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") { constexpr bool c_debug_flag = true; From 771a0e640c3ea7f403eeddd2b7a7b1e6582eb0e1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Feb 2026 21:44:40 -0500 Subject: [PATCH 155/258] xo-interpreter: + VSM work in progress --- .../include/xo/interpreter2/DApplyFrame.hpp | 20 +++++ .../interpreter2/VirtualSchematikaMachine.hpp | 15 +++- .../include/xo/interpreter2/VsmFrame.hpp | 86 +++++++++++++++++++ .../include/xo/interpreter2/VsmInstr.hpp | 3 + .../include/xo/interpreter2/VsmOpcode.hpp | 9 ++ .../src/interpreter2/CMakeLists.txt | 1 + .../interpreter2/VirtualSchematikaMachine.cpp | 69 ++++++++++++++- xo-interpreter2/src/interpreter2/VsmFrame.cpp | 68 +++++++++++++++ xo-interpreter2/src/interpreter2/VsmInstr.cpp | 6 ++ .../utest/VirtualSchematikaMachine.test.cpp | 37 ++++++++ 10 files changed, 307 insertions(+), 7 deletions(-) create mode 100644 xo-interpreter2/include/xo/interpreter2/DApplyFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp create mode 100644 xo-interpreter2/src/interpreter2/VsmFrame.cpp diff --git a/xo-interpreter2/include/xo/interpreter2/DApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DApplyFrame.hpp new file mode 100644 index 00000000..d1c81c2b --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DApplyFrame.hpp @@ -0,0 +1,20 @@ +/** @file DApplyFrame.hpp + * + * @author Roland Conyberae, Feb 2026 + **/ + +#pragma once + +namespace xo { + namespace scm { + /** In virtual schematika machine (VSM): + * stack frame for interpreted apply expression + * (@ref DApplyExpr) + **/ + class DApplyFrame { + obj + }; + } +} + +/* end DApplyFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 5aecbc55..26366d50 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -7,6 +7,7 @@ #include "VsmConfig.hpp" #include "VsmInstr.hpp" +#include "VsmFrame.hpp" #include #include #include @@ -143,6 +144,12 @@ namespace xo { **/ void _do_eval_sequence_op(); + /** apply a function to evaluated arguments **/ + void _do_apply_op(); + + /** evaluate arguments on behalf of a function call **/ + void _do_evalargs_op(); + private: /* * Some registers are preserved by evaluation: @@ -163,16 +170,18 @@ namespace xo { **/ box mm_; + // consider separate allocator (which _may_ turn out to be the same) + // for VM stack. Only works for code that doesn't rely on fancy + // lexical scoping + /** reader: text -> expression **/ SchematikaReader reader_; /** program counter **/ VsmInstr pc_ = VsmInstr::c_halt; -#ifdef NOT_YET /** stack pointer **/ - Stack stack_; -#endif + VsmFrame * stack_ = nullptr; /** expression register **/ obj expr_; diff --git a/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp new file mode 100644 index 00000000..09b542a8 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp @@ -0,0 +1,86 @@ +/** @file VsmFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "VsmInstr.hpp" +#include +#include + +namespace xo { + namespace scm { + class VsmFrame { + public: + VsmFrame(VsmFrame * parent, VsmInstr cont) : parent_{parent}, cont_{cont} {} + + VsmFrame * parent() const noexcept { return parent_; } + VsmInstr cont() const noexcept { return cont_; } + + protected: + /** saved VSM stack; restore when this frame consumed **/ + VsmFrame * parent_ = nullptr; + /** saved continuation; restore when this frame consumed **/ + VsmInstr cont_; + }; + + class VsmApplyFrame : public VsmFrame { + public: + using AProcedure = xo::scm::AProcedure; + using AAllocator = xo::mm::AAllocator; + + public: + VsmApplyFrame(VsmFrame * old_parent, + VsmInstr old_cont, + DArray * args); + + static VsmApplyFrame * make(obj mm, + VsmFrame * old_parent, + VsmInstr old_cont, + DArray * args); + + obj fn() const noexcept { return fn_; } + DArray * args() const noexcept { return args_; } + + private: + /** evaluated target procedure. + * + * note: when initially created, this will be unpopulated; + * don't know correct value until we evaluate + * expression in head position + **/ + obj fn_; + /** evaluated arguments (to target procedure) **/ + DArray * args_; + }; + + /** frame for executing an apply expression **/ + class VsmEvalArgsFrame : public VsmFrame { + public: + using AAllocator = xo::mm::AAllocator; + + public: + /** see picture in VirtualSchematikaMachine._do_eval_apply_op() + * + * old_parent = [apply frame] + * old_cont = [xfer to called function] + * + **/ + VsmEvalArgsFrame(VsmApplyFrame * old_parent, + VsmInstr old_cont); + + static VsmEvalArgsFrame * make(obj mm, + VsmApplyFrame * apply_frame, + VsmInstr old_cont); + + private: + /** next argument to be evaluated. -1 means function head **/ + int32_t i_arg_ = -1; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VsmFrame.hpp */ + diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index c956c607..a94ee625 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -16,6 +16,9 @@ namespace xo { static VsmInstr c_halt; static VsmInstr c_eval; + static VsmInstr c_apply; + static VsmInstr c_evalargs; + vsm_opcode opcode() const noexcept { return opcode_; } private: diff --git a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp index 3638fa29..6e41c5c1 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp @@ -18,6 +18,15 @@ namespace xo { /** Evaluate expression in expr register **/ eval, + /** Apply function in stack frame + * See diagram in VirtualSchematikaMachine::_do_eval_apply_op + **/ + apply, + /** Eval arguments to function. + * See diagram in VirtualSchematikaMachine::_do_eval_apply_op + **/ + evalargs, + /** sentinel, counts number of opcodes **/ N, }; diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 93ecd47e..8ce214ba 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -4,6 +4,7 @@ set(SELF_LIB xo_interpreter2) set(SELF_SRCS init_interpreter2.cpp VirtualSchematikaMachine.cpp + VsmFrame.cpp VsmInstr.cpp #IExpression_Any.cpp #interpreter2_register_facets.cpp diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 7c4873fb..dc876b44 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -4,8 +4,8 @@ **/ #include "VirtualSchematikaMachine.hpp" -#include -#include +#include +#include #include #include #include @@ -117,6 +117,13 @@ namespace xo { return false; case vsm_opcode::eval: _do_eval_op(); + break; + case vsm_opcode::apply: + _do_apply_op(); + break; + case vsm_opcode::evalargs: + _do_evalargs_op(); + break; } return true; @@ -187,8 +194,47 @@ namespace xo { void VirtualSchematikaMachine::_do_eval_apply_op() { - // not implemented - assert(false); + // ApplyExpr in expr_ register + + // assuming bump allocator: + // + // DArray VsmApplyFrame VsmEvalArgsFrame + // v v v + // +----------------------+-------+------+----+--------+-------+------+-------+ + // | argument expressions | par x | cont | fn | args x | par x | cont | i_arg | + // +----------------------+-----|-+------+----+------|-+-----|-+------+-------+ + // ^ ^ | | | + // | \----------------------------------/ + // \ | / + // \-----------------------------------------------/ + // / + // <---------------------------/ + // + // - VsmEvalArgsFrame: owned by VSM, state for evalargs loop + // - VsmApplyFrame: owned by VSM, state for transferring control to called function + // - DArray: contains evaluated args; owned by called primitive + + auto apply = obj::from(expr_); + + // evaluated arguments + DArray * args = DArray::empty(mm_.to_op(), + apply->n_args()); + + // TODO: check function signature + + VsmApplyFrame * apply_frame + = VsmApplyFrame::make(mm_.to_op(), stack_, cont_, args); + + VsmEvalArgsFrame * evalargs_frame + = VsmEvalArgsFrame::make(mm_.to_op(), apply_frame, VsmInstr::c_apply); + + this->stack_ = evalargs_frame; + + // Setup evaluation of first argument. No new stack for this. + + this->cont_ = VsmInstr::c_evalargs; + this->expr_ = apply->fn(); + this->pc_ = VsmInstr::c_eval; } void @@ -204,6 +250,21 @@ namespace xo { // not implemented assert(false); } + + void + VirtualSchematikaMachine::_do_apply_op() + { + // not implemented + assert(false); + } + + void + VirtualSchematikaMachine::_do_evalargs_op() + { + // not implemented + assert(false); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/VsmFrame.cpp b/xo-interpreter2/src/interpreter2/VsmFrame.cpp new file mode 100644 index 00000000..2f262431 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/VsmFrame.cpp @@ -0,0 +1,68 @@ +/** @file VsmFrame.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "VsmFrame.hpp" + +namespace xo { + using xo::facet::typeseq; + + namespace scm { + + VsmApplyFrame::VsmApplyFrame(VsmFrame * old_parent, + VsmInstr old_cont, + DArray * args) + : VsmFrame(old_parent, old_cont), + args_{args} + {} + + VsmApplyFrame * + VsmApplyFrame::make(obj mm, + VsmFrame * old_parent, + VsmInstr old_cont, + DArray * args) + { + VsmApplyFrame * result = nullptr; + + void * mem = mm.alloc(typeseq::id(), + sizeof(VsmApplyFrame)); + + result = new (mem) VsmApplyFrame(old_parent, + old_cont, + args); + + assert(result); + + return result; + } + + // ----- VsmEvalArgsFrame ----- + + VsmEvalArgsFrame::VsmEvalArgsFrame(VsmApplyFrame * old_parent, + VsmInstr old_cont) + : VsmFrame(old_parent, old_cont) + {} + + VsmEvalArgsFrame * + VsmEvalArgsFrame::make(obj mm, + VsmApplyFrame * apply_frame, + VsmInstr cont) + { + VsmEvalArgsFrame * result = nullptr; + + void * mem = mm.alloc(typeseq::id(), + sizeof(VsmEvalArgsFrame)); + + result = new (mem) VsmEvalArgsFrame(apply_frame, cont); + + assert(result); + + return result; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VsmFrame.cpp */ + diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp index 95a0ef74..8d0907fc 100644 --- a/xo-interpreter2/src/interpreter2/VsmInstr.cpp +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -12,6 +12,12 @@ namespace xo { VsmInstr VsmInstr::c_eval = VsmInstr(vsm_opcode::eval); + + VsmInstr + VsmInstr::c_apply = VsmInstr(vsm_opcode::apply); + + VsmInstr + VsmInstr::c_evalargs = VsmInstr(vsm_opcode::evalargs); } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 0a2ba92f..59104860 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -149,6 +149,43 @@ namespace xo { vsm.visit_pools(visitor); } + TEST_CASE("VirtualSchematikaMachine-arith1", "[interpreter2][VSM]") + { + scope log(XO_DEBUG(true)); + + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("3.14159265 * 0.5;"), eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq())); + + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE(x.data()->value() == 1011); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + FacetRegistry::instance().visit_pools(visitor); + vsm.visit_pools(visitor); + } + } /*namespace ut*/ } /*namespace xo*/ From b75010fa49d9396de2c6b61fa6ae4eadd4d66516 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 4 Feb 2026 01:44:28 -0500 Subject: [PATCH 156/258] xo-interpreter2: vsm stack: facet + gcobject + printable + init --- xo-expression2/CMakeLists.txt | 2 +- .../interpreter/VirtualSchematikaMachine.cpp | 3 +- xo-interpreter2/CMakeLists.txt | 59 +++++++++++++ .../idl/IGCObject_DVsmApplyFrame.json5 | 15 ++++ .../idl/IGCObject_DVsmEvalArgsFrame.json5 | 15 ++++ .../idl/IPrintable_DVsmApplyFrame.json5 | 13 +++ .../idl/IPrintable_DVsmEvalArgsFrame.json5 | 13 +++ .../xo/interpreter2/DVsmApplyFrame.hpp | 53 ++++++++++++ .../xo/interpreter2/DVsmEvalArgsFrame.hpp | 48 +++++++++++ .../interpreter2/VirtualSchematikaMachine.hpp | 2 +- .../include/xo/interpreter2/VsmApplyFrame.hpp | 12 +++ .../xo/interpreter2/VsmEvalArgsFrame.hpp | 12 +++ .../include/xo/interpreter2/VsmFrame.hpp | 68 +++------------ .../include/xo/interpreter2/VsmInstr.hpp | 6 ++ .../include/xo/interpreter2/VsmOpcode.hpp | 11 +++ .../detail/IGCObject_DVsmApplyFrame.hpp | 67 +++++++++++++++ .../detail/IGCObject_DVsmEvalArgsFrame.hpp | 67 +++++++++++++++ .../detail/IPrintable_DVsmApplyFrame.hpp | 62 ++++++++++++++ .../detail/IPrintable_DVsmEvalArgsFrame.hpp | 62 ++++++++++++++ .../interpreter2_register_facets.hpp | 15 ++++ .../interpreter2_register_types.hpp | 17 ++++ .../src/interpreter2/CMakeLists.txt | 14 +++- .../src/interpreter2/DVsmApplyFrame.cpp | 82 +++++++++++++++++++ .../src/interpreter2/DVsmEvalArgsFrame.cpp | 77 +++++++++++++++++ .../interpreter2/IGCObject_DVsmApplyFrame.cpp | 39 +++++++++ .../IGCObject_DVsmEvalArgsFrame.cpp | 39 +++++++++ .../IPrintable_DVsmApplyFrame.cpp | 28 +++++++ .../IPrintable_DVsmEvalArgsFrame.cpp | 28 +++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 23 +++++- .../src/interpreter2/VsmApplyFrame.cpp | 0 xo-interpreter2/src/interpreter2/VsmFrame.cpp | 68 --------------- xo-interpreter2/src/interpreter2/VsmInstr.cpp | 15 ++++ .../src/interpreter2/init_interpreter2.cpp | 8 -- .../interpreter2_register_facets.cpp | 47 +++++++++++ .../interpreter2_register_types.cpp | 36 ++++++++ 35 files changed, 983 insertions(+), 143 deletions(-) create mode 100644 xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 create mode 100644 xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 create mode 100644 xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 create mode 100644 xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmApplyFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmEvalArgsFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmApplyFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmEvalArgsFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmApplyFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmEvalArgsFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/interpreter2_register_facets.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/interpreter2_register_types.hpp create mode 100644 xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DVsmApplyFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DVsmEvalArgsFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DVsmApplyFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DVsmEvalArgsFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/VsmApplyFrame.cpp delete mode 100644 xo-interpreter2/src/interpreter2/VsmFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp create mode 100644 xo-interpreter2/src/interpreter2/interpreter2_register_types.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index a9060ce1..d826a155 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -317,7 +317,7 @@ xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-uniquestring FACET_PKG xo_printable2 FACET Printable - REPR DUniqueString + REPR UniqueString INPUT idl/IPrintable_DUniqueString.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail diff --git a/xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp b/xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp index 9a9c7ddf..25f620b0 100644 --- a/xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp +++ b/xo-interpreter/src/interpreter/VirtualSchematikaMachine.cpp @@ -189,7 +189,8 @@ namespace xo { VirtualSchematikaMachine::execute_one() { scope log(XO_DEBUG(true)); - log && log("stack", stack_); + log && log(xtag("pc", pc_), xtag("cont", cont_)); + log && log(xtag("stack", stack_)); using Opcode = VsmInstr::Opcode; diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 466e1a1c..259c3f03 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -23,6 +23,65 @@ add_definitions(${PROJECT_CXX_FLAGS}) add_subdirectory(src/interpreter2) add_subdirectory(utest) +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-vsmapplyframe + FACET_PKG xo_gc + FACET GCObject + REPR VsmApplyFrame + INPUT idl/IGCObject_DVsmApplyFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-vsmapplyframe + FACET_PKG xo_printable2 + FACET Printable + REPR VsmApplyFrame + INPUT idl/IPrintable_DVsmApplyFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-vsmevalargsframe + FACET_PKG xo_gc + FACET GCObject + REPR VsmEvalArgsFrame + INPUT idl/IGCObject_DVsmEvalArgsFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-vsmevalargsframe + FACET_PKG xo_printable2 + FACET Printable + REPR DVsmEvalArgsFrame + INPUT idl/IPrintable_DVsmEvalArgsFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# ---------------------------------------------------------------- + +xo_add_genfacet_all(xo-interpreter2-genfacet-all) + +# ---------------------------------------------------------------- +# cmake helper (for external xo-interpreter2 users) + xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) # ---------------------------------------------------------------- diff --git a/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 new file mode 100644 index 00000000..979c14bf --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVsmApplyFrame", + using_doxygen: true, + repr: "DVsmApplyFrame", + doc: [ "implement AGCObject for DVsmApplyFrame" ], +} diff --git a/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 new file mode 100644 index 00000000..8bebc6ec --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVsmEvalArgsFrame", + using_doxygen: true, + repr: "DVsmEvalArgsFrame", + doc: [ "implement AGCObject for DVsmEvalArgsFrame" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 new file mode 100644 index 00000000..f5957d7e --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVsmApplyFrame", + using_doxygen: true, + repr: "DVsmApplyFrame", + doc: [ "implement APrintable for DVsmApplyFrame" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 new file mode 100644 index 00000000..24df6cbd --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVsmEvalArgsFrame", + using_doxygen: true, + repr: "DVsmEvalArgsFrame", + doc: [ "implement APrintable for DVsmEvalArgsFrame" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp new file mode 100644 index 00000000..d947a8bc --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp @@ -0,0 +1,53 @@ +/** @file DVsmApplyFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "VsmFrame.hpp" + +namespace xo { + namespace scm { + class DVsmApplyFrame : public VsmFrame { + public: + using AProcedure = xo::scm::AProcedure; + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using ppindentinfo = xo::print::ppindentinfo; + + public: + DVsmApplyFrame(obj old_parent, + VsmInstr old_cont, + DArray * args); + + static DVsmApplyFrame * make(obj mm, + obj old_parent, + VsmInstr old_cont, + DArray * args); + + obj fn() const noexcept { return fn_; } + DArray * args() const noexcept { return args_; } + + std::size_t shallow_size() const noexcept; + DVsmApplyFrame * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + private: + /** evaluated target procedure. + * + * note: when initially created, this will be unpopulated; + * don't know correct value until we evaluate + * expression in head position + **/ + obj fn_; + /** evaluated arguments (to target procedure) **/ + DArray * args_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmApplyFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp new file mode 100644 index 00000000..a8ef0226 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp @@ -0,0 +1,48 @@ +/** @file DVsmEvalArgsFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVsmApplyFrame.hpp" + +namespace xo { + namespace scm { + + /** frame for executing an apply expression **/ + class DVsmEvalArgsFrame : public VsmFrame { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** see picture in VirtualSchematikaMachine._do_eval_apply_op() + * + * old_parent = [apply frame] + * old_cont = [xfer to called function] + * + **/ + DVsmEvalArgsFrame(obj old_parent, + VsmInstr old_cont); + + static DVsmEvalArgsFrame * make(obj mm, + obj apply_frame, + VsmInstr old_cont); + + std::size_t shallow_size() const noexcept; + DVsmEvalArgsFrame * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + bool pretty(const ppindentinfo & ppii) const; + + protected: + /** next argument to be evaluated. -1 means function head **/ + int32_t i_arg_ = -1; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmEvalArgsFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 26366d50..78c2f3f7 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -181,7 +181,7 @@ namespace xo { VsmInstr pc_ = VsmInstr::c_halt; /** stack pointer **/ - VsmFrame * stack_ = nullptr; + obj stack_; /** expression register **/ obj expr_; diff --git a/xo-interpreter2/include/xo/interpreter2/VsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmApplyFrame.hpp new file mode 100644 index 00000000..5ed121ba --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmApplyFrame.hpp @@ -0,0 +1,12 @@ +/** @file VsmApplyFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVsmApplyFrame.hpp" +#include "detail/IGCObject_DVsmApplyFrame.hpp" +#include "detail/IPrintable_DVsmApplyFrame.hpp" + +/* end VsmApplyFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmEvalArgsFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmEvalArgsFrame.hpp new file mode 100644 index 00000000..8c45b25e --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmEvalArgsFrame.hpp @@ -0,0 +1,12 @@ +/** @file VsmEvalArgsFrame.hpp +* +* @author Roland Conybeare, Feb 2026 +**/ + +#pragma once + +#include "DVsmEvalArgsFrame.hpp" +#include "detail/IGCObject_DVsmEvalArgsFrame.hpp" +#include "detail/IPrintable_DVsmEvalArgsFrame.hpp" + +/* end VsmEvalArgsFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp index 09b542a8..f4cf5f1e 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp @@ -13,74 +13,26 @@ namespace xo { namespace scm { class VsmFrame { public: - VsmFrame(VsmFrame * parent, VsmInstr cont) : parent_{parent}, cont_{cont} {} + using AGCObject = xo::mm::AGCObject; - VsmFrame * parent() const noexcept { return parent_; } + public: + VsmFrame(obj parent, + VsmInstr cont) : parent_{parent}, cont_{cont} {} + + //obj parent() const noexcept { return parent_; } + VsmFrame * parent() const noexcept { + return reinterpret_cast(parent_.data()); + } VsmInstr cont() const noexcept { return cont_; } protected: /** saved VSM stack; restore when this frame consumed **/ - VsmFrame * parent_ = nullptr; + obj parent_; /** saved continuation; restore when this frame consumed **/ VsmInstr cont_; }; - class VsmApplyFrame : public VsmFrame { - public: - using AProcedure = xo::scm::AProcedure; - using AAllocator = xo::mm::AAllocator; - - public: - VsmApplyFrame(VsmFrame * old_parent, - VsmInstr old_cont, - DArray * args); - - static VsmApplyFrame * make(obj mm, - VsmFrame * old_parent, - VsmInstr old_cont, - DArray * args); - - obj fn() const noexcept { return fn_; } - DArray * args() const noexcept { return args_; } - - private: - /** evaluated target procedure. - * - * note: when initially created, this will be unpopulated; - * don't know correct value until we evaluate - * expression in head position - **/ - obj fn_; - /** evaluated arguments (to target procedure) **/ - DArray * args_; - }; - - /** frame for executing an apply expression **/ - class VsmEvalArgsFrame : public VsmFrame { - public: - using AAllocator = xo::mm::AAllocator; - - public: - /** see picture in VirtualSchematikaMachine._do_eval_apply_op() - * - * old_parent = [apply frame] - * old_cont = [xfer to called function] - * - **/ - VsmEvalArgsFrame(VsmApplyFrame * old_parent, - VsmInstr old_cont); - - static VsmEvalArgsFrame * make(obj mm, - VsmApplyFrame * apply_frame, - VsmInstr old_cont); - - private: - /** next argument to be evaluated. -1 means function head **/ - int32_t i_arg_ = -1; - }; - } /*namespace scm*/ } /*namespace xo*/ /* end VsmFrame.hpp */ - diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index a94ee625..ec836c4d 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -24,6 +24,12 @@ namespace xo { private: vsm_opcode opcode_; }; + + inline std::ostream & + operator<<(std::ostream & os, VsmInstr x) { + os << x.opcode(); + return os; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp index 6e41c5c1..2c58c04f 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include namespace xo { @@ -32,6 +33,16 @@ namespace xo { }; static constexpr uint32_t n_opcode = static_cast(vsm_opcode::N); + + /** stringified enum value **/ + const char * + vsm_opcode_descr(vsm_opcode x); + + inline std::ostream & + operator<<(std::ostream & os, vsm_opcode x) { + os << vsm_opcode_descr(x); + return os; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmApplyFrame.hpp new file mode 100644 index 00000000..ca6d3b10 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmApplyFrame.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVsmApplyFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmApplyFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmApplyFrame.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVsmApplyFrame.hpp" + +namespace xo { namespace scm { class IGCObject_DVsmApplyFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVsmApplyFrame + **/ + class IGCObject_DVsmApplyFrame { + public: + /** @defgroup scm-gcobject-dvsmapplyframe-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvsmapplyframe-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVsmApplyFrame & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVsmApplyFrame & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVsmApplyFrame & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmEvalArgsFrame.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmEvalArgsFrame.hpp new file mode 100644 index 00000000..4a8ad18a --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmEvalArgsFrame.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVsmEvalArgsFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmEvalArgsFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmEvalArgsFrame.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVsmEvalArgsFrame.hpp" + +namespace xo { namespace scm { class IGCObject_DVsmEvalArgsFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVsmEvalArgsFrame + **/ + class IGCObject_DVsmEvalArgsFrame { + public: + /** @defgroup scm-gcobject-dvsmevalargsframe-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvsmevalargsframe-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVsmEvalArgsFrame & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVsmEvalArgsFrame & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVsmEvalArgsFrame & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmApplyFrame.hpp new file mode 100644 index 00000000..af1a4e02 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmApplyFrame.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVsmApplyFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmApplyFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmApplyFrame.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVsmApplyFrame.hpp" + +namespace xo { namespace scm { class IPrintable_DVsmApplyFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVsmApplyFrame + **/ + class IPrintable_DVsmApplyFrame { + public: + /** @defgroup scm-printable-dvsmapplyframe-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvsmapplyframe-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVsmApplyFrame & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmEvalArgsFrame.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmEvalArgsFrame.hpp new file mode 100644 index 00000000..1c06f71e --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmEvalArgsFrame.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVsmEvalArgsFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmEvalArgsFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmEvalArgsFrame.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVsmEvalArgsFrame.hpp" + +namespace xo { namespace scm { class IPrintable_DVsmEvalArgsFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVsmEvalArgsFrame + **/ + class IPrintable_DVsmEvalArgsFrame { + public: + /** @defgroup scm-printable-dvsmevalargsframe-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvsmevalargsframe-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVsmEvalArgsFrame & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/interpreter2_register_facets.hpp b/xo-interpreter2/include/xo/interpreter2/interpreter2_register_facets.hpp new file mode 100644 index 00000000..587f882b --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/interpreter2_register_facets.hpp @@ -0,0 +1,15 @@ +/** @file interpreter2_register_facets.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +namespace xo { + namespace scm { + /** Register interpreter2 (facet,impl) combinations with FacetRegistry **/ + bool interpreter2_register_facets(); + } +} + +/* end interpreter2_register_facets.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/interpreter2_register_types.hpp b/xo-interpreter2/include/xo/interpreter2/interpreter2_register_types.hpp new file mode 100644 index 00000000..1409d13a --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/interpreter2_register_types.hpp @@ -0,0 +1,17 @@ +/** @file interpreter2_register_types.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + /** Register interpreter2 (facet,impl) combinations with FacetRegistry **/ + bool interpreter2_register_types(obj gc); + } +} + +/* end interpreter2_register_types.hpp */ diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 8ce214ba..635ecff3 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -3,11 +3,21 @@ set(SELF_LIB xo_interpreter2) set(SELF_SRCS init_interpreter2.cpp + interpreter2_register_facets.cpp + interpreter2_register_types.cpp + VirtualSchematikaMachine.cpp - VsmFrame.cpp + + DVsmEvalArgsFrame.cpp + IGCObject_DVsmEvalArgsFrame.cpp + IPrintable_DVsmEvalArgsFrame.cpp + + DVsmApplyFrame.cpp + IGCObject_DVsmApplyFrame.cpp + IPrintable_DVsmApplyFrame.cpp + VsmInstr.cpp #IExpression_Any.cpp - #interpreter2_register_facets.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp new file mode 100644 index 00000000..75da5877 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp @@ -0,0 +1,82 @@ +/** @file DVsmApplyFrame.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVsmApplyFrame.hpp" +#include + +namespace xo { + using xo::facet::typeseq; + + namespace scm { + + DVsmApplyFrame::DVsmApplyFrame(obj old_parent, + VsmInstr old_cont, + DArray * args) + : VsmFrame(old_parent, old_cont), + args_{args} + {} + + DVsmApplyFrame * + DVsmApplyFrame::make(obj mm, + obj old_parent, + VsmInstr old_cont, + DArray * args) + { + DVsmApplyFrame * result = nullptr; + + void * mem = mm.alloc(typeseq::id(), + sizeof(DVsmApplyFrame)); + + result = new (mem) DVsmApplyFrame(old_parent, + old_cont, + args); + + assert(result); + + return result; + } + + std::size_t + DVsmApplyFrame::shallow_size() const noexcept + { + return sizeof(DVsmApplyFrame); + } + + DVsmApplyFrame * + DVsmApplyFrame::shallow_copy(obj mm) const noexcept + { + DVsmApplyFrame * copy = (DVsmApplyFrame *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DVsmApplyFrame::forward_children(obj gc) noexcept + { + // GC needs to locate AGCObject iface for each member + + (void)gc; + + return this->shallow_size(); + } + + bool + DVsmApplyFrame::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DVsmApplyFrame", + refrtag("cont", cont_), + refrtag("n_args", args_->size()) + ); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmApplyFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp new file mode 100644 index 00000000..cb2b328e --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp @@ -0,0 +1,77 @@ +/** @file DVsmEvalArgsFrame.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVsmEvalArgsFrame.hpp" +#include + +namespace xo { + using xo::facet::typeseq; + using xo::print::ppindentinfo; + + namespace scm { + + // ----- VsmEvalArgsFrame ----- + + DVsmEvalArgsFrame::DVsmEvalArgsFrame(obj old_parent, + VsmInstr old_cont) + : VsmFrame(old_parent, old_cont) + {} + + DVsmEvalArgsFrame * + DVsmEvalArgsFrame::make(obj mm, + obj apply_frame, + VsmInstr cont) + { + DVsmEvalArgsFrame * result = nullptr; + + void * mem = mm.alloc(typeseq::id(), + sizeof(DVsmEvalArgsFrame)); + + result = new (mem) DVsmEvalArgsFrame(apply_frame, cont); + + assert(result); + + return result; + } + + std::size_t + DVsmEvalArgsFrame::shallow_size() const noexcept + { + return sizeof(DVsmEvalArgsFrame); + } + + DVsmEvalArgsFrame * + DVsmEvalArgsFrame::shallow_copy(obj mm) const noexcept + { + DVsmEvalArgsFrame * copy = (DVsmEvalArgsFrame *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DVsmEvalArgsFrame::forward_children(obj gc) noexcept + { + (void)gc; + + return this->shallow_size(); + } + + bool + DVsmEvalArgsFrame::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DVsmEvalArgsFrame", + refrtag("cont", cont_), + refrtag("i_arg", i_arg_) + ); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VsmEvalArgsFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DVsmApplyFrame.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DVsmApplyFrame.cpp new file mode 100644 index 00000000..1e794477 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DVsmApplyFrame.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVsmApplyFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmApplyFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmApplyFrame.json5] +**/ + +#include "detail/IGCObject_DVsmApplyFrame.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVsmApplyFrame::shallow_size(const DVsmApplyFrame & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVsmApplyFrame::shallow_copy(const DVsmApplyFrame & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVsmApplyFrame::forward_children(DVsmApplyFrame & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVsmApplyFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DVsmEvalArgsFrame.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DVsmEvalArgsFrame.cpp new file mode 100644 index 00000000..d64b47bd --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DVsmEvalArgsFrame.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVsmEvalArgsFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmEvalArgsFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmEvalArgsFrame.json5] +**/ + +#include "detail/IGCObject_DVsmEvalArgsFrame.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVsmEvalArgsFrame::shallow_size(const DVsmEvalArgsFrame & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVsmEvalArgsFrame::shallow_copy(const DVsmEvalArgsFrame & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVsmEvalArgsFrame::forward_children(DVsmEvalArgsFrame & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVsmEvalArgsFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DVsmApplyFrame.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DVsmApplyFrame.cpp new file mode 100644 index 00000000..5faa360f --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DVsmApplyFrame.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVsmApplyFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmApplyFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmApplyFrame.json5] +**/ + +#include "detail/IPrintable_DVsmApplyFrame.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVsmApplyFrame::pretty(const DVsmApplyFrame & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVsmApplyFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DVsmEvalArgsFrame.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DVsmEvalArgsFrame.cpp new file mode 100644 index 00000000..25d81800 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DVsmEvalArgsFrame.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVsmEvalArgsFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmEvalArgsFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmEvalArgsFrame.json5] +**/ + +#include "detail/IPrintable_DVsmEvalArgsFrame.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVsmEvalArgsFrame::pretty(const DVsmEvalArgsFrame & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVsmEvalArgsFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index dc876b44..22f9ed12 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -4,6 +4,8 @@ **/ #include "VirtualSchematikaMachine.hpp" +#include "VsmApplyFrame.hpp" +#include "VsmEvalArgsFrame.hpp" #include #include #include @@ -111,6 +113,17 @@ namespace xo { bool VirtualSchematikaMachine::execute_one() { + scope log(XO_DEBUG(true)); + log && log(xtag("pc", pc_), + xtag("cont", cont_)); + + obj stack_pr + = (FacetRegistry::instance() + .try_variant(stack_)); + + if (stack_pr) + log && log(xtag("stack", stack_pr)); + switch (pc_.opcode()) { case vsm_opcode::halt: case vsm_opcode::N: @@ -222,11 +235,13 @@ namespace xo { // TODO: check function signature - VsmApplyFrame * apply_frame - = VsmApplyFrame::make(mm_.to_op(), stack_, cont_, args); + auto apply_frame + = obj + (DVsmApplyFrame::make(mm_.to_op(), stack_, cont_, args)); - VsmEvalArgsFrame * evalargs_frame - = VsmEvalArgsFrame::make(mm_.to_op(), apply_frame, VsmInstr::c_apply); + auto evalargs_frame + = obj + (DVsmEvalArgsFrame::make(mm_.to_op(), apply_frame, VsmInstr::c_apply)); this->stack_ = evalargs_frame; diff --git a/xo-interpreter2/src/interpreter2/VsmApplyFrame.cpp b/xo-interpreter2/src/interpreter2/VsmApplyFrame.cpp new file mode 100644 index 00000000..e69de29b diff --git a/xo-interpreter2/src/interpreter2/VsmFrame.cpp b/xo-interpreter2/src/interpreter2/VsmFrame.cpp deleted file mode 100644 index 2f262431..00000000 --- a/xo-interpreter2/src/interpreter2/VsmFrame.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/** @file VsmFrame.cpp - * - * @author Roland Conybeare, Feb 2026 - **/ - -#include "VsmFrame.hpp" - -namespace xo { - using xo::facet::typeseq; - - namespace scm { - - VsmApplyFrame::VsmApplyFrame(VsmFrame * old_parent, - VsmInstr old_cont, - DArray * args) - : VsmFrame(old_parent, old_cont), - args_{args} - {} - - VsmApplyFrame * - VsmApplyFrame::make(obj mm, - VsmFrame * old_parent, - VsmInstr old_cont, - DArray * args) - { - VsmApplyFrame * result = nullptr; - - void * mem = mm.alloc(typeseq::id(), - sizeof(VsmApplyFrame)); - - result = new (mem) VsmApplyFrame(old_parent, - old_cont, - args); - - assert(result); - - return result; - } - - // ----- VsmEvalArgsFrame ----- - - VsmEvalArgsFrame::VsmEvalArgsFrame(VsmApplyFrame * old_parent, - VsmInstr old_cont) - : VsmFrame(old_parent, old_cont) - {} - - VsmEvalArgsFrame * - VsmEvalArgsFrame::make(obj mm, - VsmApplyFrame * apply_frame, - VsmInstr cont) - { - VsmEvalArgsFrame * result = nullptr; - - void * mem = mm.alloc(typeseq::id(), - sizeof(VsmEvalArgsFrame)); - - result = new (mem) VsmEvalArgsFrame(apply_frame, cont); - - assert(result); - - return result; - } - - } /*namespace scm*/ -} /*namespace xo*/ - -/* end VsmFrame.cpp */ - diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp index 8d0907fc..ddcc8c20 100644 --- a/xo-interpreter2/src/interpreter2/VsmInstr.cpp +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -7,6 +7,21 @@ namespace xo { namespace scm { + const char * + vsm_opcode_descr(vsm_opcode x) + { + switch (x) { + case vsm_opcode::halt: return "halt"; + case vsm_opcode::eval: return "eval"; + case vsm_opcode::apply: return "apply"; + case vsm_opcode::evalargs: return "evalargs"; + case vsm_opcode::N: + break; + } + + return "opcode?"; + } + VsmInstr VsmInstr::c_halt = VsmInstr(vsm_opcode::halt); diff --git a/xo-interpreter2/src/interpreter2/init_interpreter2.cpp b/xo-interpreter2/src/interpreter2/init_interpreter2.cpp index b0e8a71c..07308863 100644 --- a/xo-interpreter2/src/interpreter2/init_interpreter2.cpp +++ b/xo-interpreter2/src/interpreter2/init_interpreter2.cpp @@ -5,31 +5,23 @@ #include "init_interpreter2.hpp" -#ifdef NOT_YET #include "interpreter2_register_facets.hpp" #include "interpreter2_register_types.hpp" -#endif #include -#ifdef NOT_YET #include -#endif namespace xo { -#ifdef NOT_YET using xo::scm::interpreter2_register_facets; using xo::scm::interpreter2_register_types; using xo::mm::CollectorTypeRegistry; -#endif void InitSubsys::init() { -#ifdef NOT_YET interpreter2_register_facets(); CollectorTypeRegistry::instance().register_types(&interpreter2_register_types); -#endif } InitEvidence diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp new file mode 100644 index 00000000..b16d33ef --- /dev/null +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -0,0 +1,47 @@ +/** @file interpreter2_register_facets.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "interpreter2_register_facets.hpp" + +#include "VsmApplyFrame.hpp" +#include "VsmEvalArgsFrame.hpp" + +#include +#include +#include +#include + +namespace xo { + using xo::mm::AGCObject; + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::reflect::typeseq; + using xo::xtag; + + namespace scm { + bool + interpreter2_register_facets() + { + scope log(XO_DEBUG(true)); + + // VsmStackFrame + // +- VsmApplyFrame + // \- VsmEvalArgsFrame + + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + log && log(xtag("DVsmApplyFrame.tseq", typeseq::id())); + log && log(xtag("DVsmEvalArgsFrame.tseq", typeseq::id())); + + return true; + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end interpreter2_register_facets.cpp */ diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_types.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_types.cpp new file mode 100644 index 00000000..54351beb --- /dev/null +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_types.cpp @@ -0,0 +1,36 @@ +/** @file interpreter2_register_types.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "interpreter2_register_types.hpp" + +#include "VsmApplyFrame.hpp" +#include "VsmEvalArgsFrame.hpp" + +#include + +namespace xo { + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::facet::impl_for; + //using xo::facet::typeseq; + using xo::scope; + + namespace scm { + bool + interpreter2_register_types(obj gc) + { + scope log(XO_DEBUG(true)); + + bool ok = true; + + ok &= gc.install_type(impl_for()); + ok &= gc.install_type(impl_for()); + + return ok; + } + } +} /*namespace xo*/ + +/* end interpreter2_register_types.cpp */ From 8cca5db5a1deafed974c2f62392eef4c48e81e07 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 4 Feb 2026 10:31:42 -0500 Subject: [PATCH 157/258] xo-indentlog: presence flag for refrtag/xrefrtag --- .../include/xo/indentlog/print/pretty.hpp | 17 +++++++++++ .../include/xo/indentlog/print/tag.hpp | 28 +++++++++++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/xo-indentlog/include/xo/indentlog/print/pretty.hpp b/xo-indentlog/include/xo/indentlog/print/pretty.hpp index 3ae010eb..d215b8b3 100644 --- a/xo-indentlog/include/xo/indentlog/print/pretty.hpp +++ b/xo-indentlog/include/xo/indentlog/print/pretty.hpp @@ -256,6 +256,11 @@ namespace xo { Member && member, Rest&&... rest) { + if constexpr (has_present>) { + if (!member.present()) + return this->print_upto_struct_members(ppii, rest...); + } + if (this->print_upto(" ") && this->print_upto(member)) return this->print_upto_struct_members(ppii, rest...); @@ -268,6 +273,13 @@ namespace xo { Member && member, Rest&&... rest) { + if constexpr (has_present>) { + if (!member.present()) { + this->pretty_struct_members(ppii, rest...); + return; + } + } + newline_indent(ppii.ci1()); this->pretty(member); this->pretty_struct_members(ppii, rest...); @@ -381,6 +393,11 @@ namespace xo { static bool print_pretty(const ppindentinfo & ppii, const Tag & tag) { + if constexpr (has_present) { + if (!tag.present()) + return true; + } + if (ppii.upto()) { if (tag.prefix_space()) ppii.pps()->write(" "); diff --git a/xo-indentlog/include/xo/indentlog/print/tag.hpp b/xo-indentlog/include/xo/indentlog/print/tag.hpp index 026e8205..03a03223 100644 --- a/xo-indentlog/include/xo/indentlog/print/tag.hpp +++ b/xo-indentlog/include/xo/indentlog/print/tag.hpp @@ -6,6 +6,7 @@ #include "concat.hpp" #include "quoted.hpp" #include "color.hpp" +#include #include // STRINGIFY(xyz) -> "xyz" @@ -20,6 +21,12 @@ #define XTAG(x) xo::xtag(STRINGIFY(x), x) namespace xo { + /** concept: true if T has a .present() method returning something bool-like **/ + template + concept has_present = requires(const T& t) { + { t.present() } -> std::convertible_to; + }; + enum class tagstyle { /** print with automatic escapes for embedded special characters * (any of ' ','"','\','\n','\r','\t'). @@ -79,10 +86,13 @@ namespace xo { **/ template struct ref_tag_impl { - ref_tag_impl(Name const & n, Value const & v) : name_{n}, value_{v} {} - ref_tag_impl(Name && n, Value && v) : name_{std::forward(n)}, value_{std::forward(v)} {} + ref_tag_impl(Name const & n, Value const & v, bool present = true) + : name_{n}, value_{v}, present_{present} {} + ref_tag_impl(Name && n, Value && v, bool present = true) + : name_{std::forward(n)}, value_{std::forward(v)}, present_{present} {} constexpr bool prefix_space() const { return PrefixSpace; } + bool present() const { return present_; } Name const & name() const { return name_; } Value const & value() const { return value_; } @@ -90,6 +100,7 @@ namespace xo { private: Name name_; const Value& value_; + bool present_ = true; }; // ----- xtag ----- @@ -150,12 +161,14 @@ namespace xo { /** 'reference raw tag'. * 1. @p v must survive until refrtag is used (i.e. until tag inserted into some stream) * 2. don't escape whitespace when printing value (pretty-printing with parseable structure) + * + * Print nothing if @p present is false **/ template auto - refrtag(Name && n, Value && v) + refrtag(Name && n, Value && v, bool present = true) { - return ref_tag_impl, std::decay_t>(n, v); + return ref_tag_impl, std::decay_t>(n, v, present); } // ----- xrefrtag ----- @@ -164,9 +177,9 @@ namespace xo { **/ template auto - xrefrtag(Name && n, Value && v) + xrefrtag(Name && n, Value && v, bool present = true) { - return ref_tag_impl, std::decay_t>(n, v); + return ref_tag_impl, std::decay_t>(n, v, present); } // ----- operator<< on tag_impl ----- @@ -199,6 +212,9 @@ namespace xo { operator<<(std::ostream &s, ref_tag_impl const & tag) { + if (!tag.present()) + return s; + using xo::print::unq; if (PrefixSpace) From 8c93134cfef056a419be2b7491e33ebedd378722 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 4 Feb 2026 10:32:16 -0500 Subject: [PATCH 158/258] xo-reader2 xo-expression2: streamline pretty w/ presence flag --- .../src/expression2/DIfElseExpr.cpp | 38 ++++++------------- xo-reader2/src/reader2/DProgressSsm.cpp | 28 +++++--------- 2 files changed, 21 insertions(+), 45 deletions(-) diff --git a/xo-expression2/src/expression2/DIfElseExpr.cpp b/xo-expression2/src/expression2/DIfElseExpr.cpp index e1d5e70e..631be466 100644 --- a/xo-expression2/src/expression2/DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/DIfElseExpr.cpp @@ -93,33 +93,17 @@ namespace xo { = FacetRegistry::instance().try_variant(when_false_); - if (when_false) { - return ppii.pps()->pretty_struct - (ppii, - "DIfElseExpr", - refrtag("typeref", typeref_), - refrtag("test", test), - refrtag("when_true", when_true), - refrtag("when_false", when_false)); - } else if (when_true) { - return ppii.pps()->pretty_struct - (ppii, - "DIfElseExpr", - refrtag("typeref", typeref_), - refrtag("test", test), - refrtag("when_true", when_true)); - } else if (test) { - return ppii.pps()->pretty_struct - (ppii, - "DIfElseExpr", - refrtag("typeref", typeref_), - refrtag("test", test)); - } else { - return ppii.pps()->pretty_struct - (ppii, - "DIfElseExpr", - refrtag("typeref", typeref_)); - } + bool test_present = test; + bool when_true_present = when_true; + bool when_false_present = when_false; + + return ppii.pps()->pretty_struct + (ppii, + "DIfElseExpr", + refrtag("typeref", typeref_), + refrtag("test", test, test_present), + refrtag("when_true", when_true, when_true_present), + refrtag("when_false", when_false, when_false_present)); } // GCObject facet diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 102384e2..626963b4 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -1041,24 +1041,16 @@ namespace xo { obj rhs = FacetRegistry::instance().try_variant(rhs_); - if (rhs) { - return ppii.pps()->pretty_struct - (ppii, - "DProgressSsm", - refrtag("lhs", lhs), - refrtag("op", op_type_), - refrtag("rhs", rhs), - refrtag("expect", this->get_expect_str()) - ); - } else { - return ppii.pps()->pretty_struct - (ppii, - "DProgressSsm", - refrtag("lhs", lhs), - refrtag("op", op_type_), - refrtag("expect", this->get_expect_str()) - ); - } + bool rhs_present = rhs; + + return ppii.pps()->pretty_struct + (ppii, + "DProgressSsm", + refrtag("lhs", lhs), + refrtag("op", op_type_), + refrtag("rhs", rhs, rhs_present), + refrtag("expect", this->get_expect_str()) + ); } obj From 24912ffd389a2b6ae5fdb625e8e9dc3778f5630d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 4 Feb 2026 16:22:39 -0500 Subject: [PATCH 159/258] xo-facet: + builtin _drop() method for poly dtor call --- xo-facet/CMakeLists.txt | 1 + xo-facet/codegen/abstract_facet.hpp.j2 | 2 ++ xo-facet/codegen/iface_facet_any.hpp.j2 | 5 ++++- xo-facet/codegen/iface_facet_xfer.hpp.j2 | 5 ++++- xo-facet/codegen/router_facet.hpp.j2 | 5 ++++- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/xo-facet/CMakeLists.txt b/xo-facet/CMakeLists.txt index ad8a4cb4..d8ad41a4 100644 --- a/xo-facet/CMakeLists.txt +++ b/xo-facet/CMakeLists.txt @@ -27,6 +27,7 @@ set(SELF_LIB xo_facet) xo_add_headeronly_library(${SELF_LIB}) # note: dependencies here must coordinate with cmake/xo_facetConfig.cmake.in +xo_headeronly_dependency(${SELF_LIB} xo_arena) xo_headeronly_dependency(${SELF_LIB} xo_reflectutil) xo_install_library4(${SELF_LIB} ${PROJECT_NAME}Targets) diff --git a/xo-facet/codegen/abstract_facet.hpp.j2 b/xo-facet/codegen/abstract_facet.hpp.j2 index 76985b6a..b125bce4 100644 --- a/xo-facet/codegen/abstract_facet.hpp.j2 +++ b/xo-facet/codegen/abstract_facet.hpp.j2 @@ -60,6 +60,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; {% for md in const_methods %} /** {{md.doc}} **/ virtual {{md.return_type}} {{md.name}}({{md.args | args}}) {{md | qualifiers}} = 0; diff --git a/xo-facet/codegen/iface_facet_any.hpp.j2 b/xo-facet/codegen/iface_facet_any.hpp.j2 index 87e9d74a..361bb2ef 100644 --- a/xo-facet/codegen/iface_facet_any.hpp.j2 +++ b/xo-facet/codegen/iface_facet_any.hpp.j2 @@ -62,8 +62,11 @@ namespace {{facet_ns2}} { // from {{abstract_facet}} - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods {% for md in const_methods %} [[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatal(); } {% endfor %} diff --git a/xo-facet/codegen/iface_facet_xfer.hpp.j2 b/xo-facet/codegen/iface_facet_xfer.hpp.j2 index c0f02814..80bd79c1 100644 --- a/xo-facet/codegen/iface_facet_xfer.hpp.j2 +++ b/xo-facet/codegen/iface_facet_xfer.hpp.j2 @@ -49,8 +49,11 @@ namespace {{facet_ns2}} { // from {{abstract_facet}} - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods {% for md in const_methods %} {{md.return_type}} {{md.name}}({{md.args | args}}) {{md | qualifiers}} override { return I::{{md.name}}({{md.args | argnames}}); diff --git a/xo-facet/codegen/router_facet.hpp.j2 b/xo-facet/codegen/router_facet.hpp.j2 index b8d70733..5c3f6497 100644 --- a/xo-facet/codegen/router_facet.hpp.j2 +++ b/xo-facet/codegen/router_facet.hpp.j2 @@ -56,8 +56,11 @@ public: ///@{ {% endif %} - // const methods + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods {% for md in const_methods %} {{md.return_type}} {{md.name}}({{md.args | argsnodata}}) {{md | qualifiers}} { return O::iface()->{{md.name}}({{md.args | argrouting}}); From 5c3772e62e426237b4471a26591e4df295ad170a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 4 Feb 2026 16:23:55 -0500 Subject: [PATCH 160/258] xo-facet: + to_facet() convenience method on obj --- xo-facet/cmake/xo_facetConfig.cmake.in | 1 + xo-facet/include/xo/facet/FacetRegistry.hpp | 18 +++++++++++++++++- xo-facet/include/xo/facet/OObject.hpp | 4 ++++ .../include/xo/facet/facet_implementation.hpp | 8 ++++++++ xo-facet/include/xo/facet/obj.hpp | 10 ++++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/xo-facet/cmake/xo_facetConfig.cmake.in b/xo-facet/cmake/xo_facetConfig.cmake.in index 88709824..23483949 100644 --- a/xo-facet/cmake/xo_facetConfig.cmake.in +++ b/xo-facet/cmake/xo_facetConfig.cmake.in @@ -2,6 +2,7 @@ include(CMakeFindDependencyMacro) # note: dependencies here must coordinate with xo-facet/CMakeLists.txt +find_dependency(xo_arena) find_dependency(xo_reflectutil) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") check_required_components("@PROJECT_NAME@") diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index ad19cf53..d4b15188 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -236,9 +236,25 @@ namespace xo { /** runtime lookup table (AFacet,DRepr) -> impl **/ xo::map::DArenaHashMap registry_; - //std::unordered_map registry_; }; + // Deferred definitioon of obj::to_facet(), + // since implementation requires FacetRegistry + // + template + template + obj + obj::to_facet() + { + if constexpr (std::is_same_v) { + // return type has type-erased data + return FacetRegistry::instance().variant(*this); + } else { + // return type has known data + return obj(this->data()); + } + } + } /*namespace facet*/ } /*namespace xo*/ diff --git a/xo-facet/include/xo/facet/OObject.hpp b/xo-facet/include/xo/facet/OObject.hpp index e6eb0f6d..234a84df 100644 --- a/xo-facet/include/xo/facet/OObject.hpp +++ b/xo-facet/include/xo/facet/OObject.hpp @@ -59,6 +59,10 @@ namespace xo { **/ template struct OObject { + static_assert(has_facet_impl, + "Missing FacetImplementation specialization. " + "Did you include IFacet_DRepr.hpp (via the convenience header)?"); + using FacetType = AFacet; using ISpecific = FacetImplType; using DataType = DRepr; diff --git a/xo-facet/include/xo/facet/facet_implementation.hpp b/xo-facet/include/xo/facet/facet_implementation.hpp index 025645e8..7ce2ed5a 100644 --- a/xo-facet/include/xo/facet/facet_implementation.hpp +++ b/xo-facet/include/xo/facet/facet_implementation.hpp @@ -92,6 +92,14 @@ namespace xo { //static_assert(false && "expect specialization which should provide ImplType trait"); }; + /** true iff FacetImplementation has been specialized with ImplType. + * False when specialization header (IFacet_DRepr.hpp) not included. + **/ + template + concept has_facet_impl = requires { + typename FacetImplementation::ImplType; + }; + /** Retrieve facet implementation for a (facet,datatype) pair **/ template using FacetImplType = FacetImplementation::ImplType; diff --git a/xo-facet/include/xo/facet/obj.hpp b/xo-facet/include/xo/facet/obj.hpp index 850ef7bf..3619ae3e 100644 --- a/xo-facet/include/xo/facet/obj.hpp +++ b/xo-facet/include/xo/facet/obj.hpp @@ -6,6 +6,7 @@ #pragma once #include "RRouter.hpp" +//#include "FacetRegistry.hpp" // nope, would create include cycle #include #include @@ -127,6 +128,15 @@ namespace xo { return obj(iface, data); } + /** - runtime polymorphism (DRepr == DVariantPlaceholder) + * (requires FacetRegistry for lookup) + * - comptime polymorphism (DRepr != DVariantPlaceholder) + * + * Definition in FacetRegistry.hpp, to avoid #include dependency + **/ + template + obj to_facet(); + /** enabled when RRouter provides _preincrement. * Note we don't need this trick for comparison operators, * since return type is fixed. From e71954697cc049db2b2605e871341eaeb7cf958b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 4 Feb 2026 16:25:37 -0500 Subject: [PATCH 161/258] xo-procedure2: streamline DSimpleRcx + regen facet *.pp --- xo-procedure2/CMakeLists.txt | 6 +++--- xo-procedure2/include/xo/procedure2/Procedure.hpp | 4 ++-- .../include/xo/procedure2/RuntimeContext.hpp | 4 ++-- xo-procedure2/include/xo/procedure2/SimpleRcx.hpp | 11 +++++++++++ .../include/xo/procedure2/detail/AProcedure.hpp | 6 ++++-- .../xo/procedure2/detail/ARuntimeContext.hpp | 6 ++++-- .../detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp | 2 +- .../detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp | 2 +- .../include/xo/procedure2/detail/IProcedure_Any.hpp | 9 ++++++--- .../detail/IProcedure_DPrimitive_gco_2_gco_gco.hpp | 2 +- .../xo/procedure2/detail/IProcedure_Xfer.hpp | 9 ++++++--- .../xo/procedure2/detail/IRuntimeContext_Any.hpp | 9 ++++++--- .../detail/IRuntimeContext_DSimpleRcx.hpp | 2 +- .../xo/procedure2/detail/IRuntimeContext_Xfer.hpp | 9 ++++++--- .../include/xo/procedure2/detail/RProcedure.hpp | 9 ++++++--- .../xo/procedure2/detail/RRuntimeContext.hpp | 9 ++++++--- .../IGCObject_DPrimitive_gco_2_gco_gco.cpp | 4 ++-- .../IPrintable_DPrimitive_gco_2_gco_gco.cpp | 4 ++-- xo-procedure2/src/procedure2/IProcedure_Any.cpp | 2 +- .../IProcedure_DPrimitive_gco_2_gco_gco.cpp | 4 ++-- .../src/procedure2/IRuntimeContext_Any.cpp | 2 +- .../src/procedure2/IRuntimeContext_DSimpleRcx.cpp | 4 ++-- .../src/procedure2/procedure2_register_facets.cpp | 13 +++++++------ 23 files changed, 83 insertions(+), 49 deletions(-) create mode 100644 xo-procedure2/include/xo/procedure2/SimpleRcx.hpp diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt index ad8673d1..a6fd4d21 100644 --- a/xo-procedure2/CMakeLists.txt +++ b/xo-procedure2/CMakeLists.txt @@ -91,12 +91,12 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/procedure2 ) -add_subdirectory(src/procedure2) -add_subdirectory(utest) +xo_add_genfacet_all(xo-procedure2-genfacet-all) # ---------------------------------------------------------------- -xo_add_genfacet_all(xo-procedure2-genfacet-all) +add_subdirectory(src/procedure2) +add_subdirectory(utest) # ---------------------------------------------------------------- # cmake export diff --git a/xo-procedure2/include/xo/procedure2/Procedure.hpp b/xo-procedure2/include/xo/procedure2/Procedure.hpp index 784608ed..05d1b661 100644 --- a/xo-procedure2/include/xo/procedure2/Procedure.hpp +++ b/xo-procedure2/include/xo/procedure2/Procedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for facet .hpp file: @@ -19,4 +19,4 @@ #include "detail/RProcedure.hpp" -/* end Procedure.hpp */ \ No newline at end of file +/* end Procedure.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp index 3241451b..48891944 100644 --- a/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/RuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for facet .hpp file: @@ -19,4 +19,4 @@ #include "detail/RRuntimeContext.hpp" -/* end RuntimeContext.hpp */ \ No newline at end of file +/* end RuntimeContext.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/SimpleRcx.hpp b/xo-procedure2/include/xo/procedure2/SimpleRcx.hpp new file mode 100644 index 00000000..2fdc4929 --- /dev/null +++ b/xo-procedure2/include/xo/procedure2/SimpleRcx.hpp @@ -0,0 +1,11 @@ +/** @file SimpleRcx.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DSimpleRcx.hpp" +#include "detail/IRuntimeContext_DSimpleRcx.hpp" + +/* end SimpleRcx.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp index 63a4da9b..eb119fbd 100644 --- a/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/AProcedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -49,6 +49,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; /** true iff procedure takes n arguments **/ virtual bool is_nary(Copaque data) const noexcept = 0; /** number of arguments. -1 for n-ary **/ @@ -76,4 +78,4 @@ using IProcedure_ImplType = xo::facet::FacetImplType; } /*namespace scm*/ } /*namespace xo*/ -/* AProcedure.hpp */ \ No newline at end of file +/* AProcedure.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp index 4e96bc8f..09831870 100644 --- a/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/ARuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -47,6 +47,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; /** default allocator to use for objects **/ virtual obj allocator(Copaque data) const noexcept = 0; @@ -70,4 +72,4 @@ using IRuntimeContext_ImplType = xo::facet::FacetImplType allocator(Copaque) const noexcept override { _fatal(); } // nonconst methods @@ -83,4 +86,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo */ -/* IRuntimeContext_Any.hpp */ \ No newline at end of file +/* IRuntimeContext_Any.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp index 06f14bc5..247b6762 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_DSimpleRcx.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IRuntimeContext_DSimpleRcx.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp index cd71b73e..a4545b8f 100644 --- a/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/IRuntimeContext_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -39,8 +39,11 @@ namespace scm { // from ARuntimeContext - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods obj allocator(Copaque data) const noexcept override { return I::allocator(_dcast(data)); } @@ -78,4 +81,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo*/ -/* end IRuntimeContext_Xfer.hpp */ \ No newline at end of file +/* end IRuntimeContext_Xfer.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp index 93599ae3..61bcb7f7 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Procedure.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -46,8 +46,11 @@ public: /** @defgroup scm-procedure-router-methods **/ ///@{ - // const methods + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods bool is_nary() const noexcept { return O::iface()->is_nary(O::data()); } @@ -83,4 +86,4 @@ namespace xo { namespace facet { }; } } -/* end RProcedure.hpp */ \ No newline at end of file +/* end RProcedure.hpp */ diff --git a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp index b06227c8..a6df812e 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/RuntimeContext.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -46,8 +46,11 @@ public: /** @defgroup scm-runtimecontext-router-methods **/ ///@{ - // const methods + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods obj allocator() const noexcept { return O::iface()->allocator(O::data()); } @@ -77,4 +80,4 @@ namespace xo { namespace facet { }; } } -/* end RRuntimeContext.hpp */ \ No newline at end of file +/* end RRuntimeContext.hpp */ diff --git a/xo-procedure2/src/procedure2/IGCObject_DPrimitive_gco_2_gco_gco.cpp b/xo-procedure2/src/procedure2/IGCObject_DPrimitive_gco_2_gco_gco.cpp index bd88e9ff..b889d0d0 100644 --- a/xo-procedure2/src/procedure2/IGCObject_DPrimitive_gco_2_gco_gco.cpp +++ b/xo-procedure2/src/procedure2/IGCObject_DPrimitive_gco_2_gco_gco.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DPrimitive_gco_2_gco_gco.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DPrimitive_gco_2_gco_gco.cpp */ \ No newline at end of file +/* end IGCObject_DPrimitive_gco_2_gco_gco.cpp */ diff --git a/xo-procedure2/src/procedure2/IPrintable_DPrimitive_gco_2_gco_gco.cpp b/xo-procedure2/src/procedure2/IPrintable_DPrimitive_gco_2_gco_gco.cpp index 2c791324..c8b7c2d8 100644 --- a/xo-procedure2/src/procedure2/IPrintable_DPrimitive_gco_2_gco_gco.cpp +++ b/xo-procedure2/src/procedure2/IPrintable_DPrimitive_gco_2_gco_gco.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DPrimitive_gco_2_gco_gco.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DPrimitive_gco_2_gco_gco.cpp */ \ No newline at end of file +/* end IPrintable_DPrimitive_gco_2_gco_gco.cpp */ diff --git a/xo-procedure2/src/procedure2/IProcedure_Any.cpp b/xo-procedure2/src/procedure2/IProcedure_Any.cpp index d28d98ee..dcdf9eeb 100644 --- a/xo-procedure2/src/procedure2/IProcedure_Any.cpp +++ b/xo-procedure2/src/procedure2/IProcedure_Any.cpp @@ -44,4 +44,4 @@ IProcedure_Any::apply_nocheck(Opaque, obj, const DArray *) -> } /*namespace scm*/ } /*namespace xo*/ -/* end IProcedure_Any.cpp */ \ No newline at end of file +/* end IProcedure_Any.cpp */ diff --git a/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp b/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp index 67e73c97..1207429f 100644 --- a/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp +++ b/xo-procedure2/src/procedure2/IProcedure_DPrimitive_gco_2_gco_gco.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IProcedure_DPrimitive_gco_2_gco_gco.cpp */ \ No newline at end of file +/* end IProcedure_DPrimitive_gco_2_gco_gco.cpp */ diff --git a/xo-procedure2/src/procedure2/IRuntimeContext_Any.cpp b/xo-procedure2/src/procedure2/IRuntimeContext_Any.cpp index a9c5b55a..1ea5859a 100644 --- a/xo-procedure2/src/procedure2/IRuntimeContext_Any.cpp +++ b/xo-procedure2/src/procedure2/IRuntimeContext_Any.cpp @@ -38,4 +38,4 @@ IRuntimeContext_Any::_valid } /*namespace scm*/ } /*namespace xo*/ -/* end IRuntimeContext_Any.cpp */ \ No newline at end of file +/* end IRuntimeContext_Any.cpp */ diff --git a/xo-procedure2/src/procedure2/IRuntimeContext_DSimpleRcx.cpp b/xo-procedure2/src/procedure2/IRuntimeContext_DSimpleRcx.cpp index 4ec8378b..f057220d 100644 --- a/xo-procedure2/src/procedure2/IRuntimeContext_DSimpleRcx.cpp +++ b/xo-procedure2/src/procedure2/IRuntimeContext_DSimpleRcx.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IRuntimeContext_DSimpleRcx.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IRuntimeContext_DSimpleRcx.cpp */ \ No newline at end of file +/* end IRuntimeContext_DSimpleRcx.cpp */ diff --git a/xo-procedure2/src/procedure2/procedure2_register_facets.cpp b/xo-procedure2/src/procedure2/procedure2_register_facets.cpp index 5b84b4dd..6905e0ba 100644 --- a/xo-procedure2/src/procedure2/procedure2_register_facets.cpp +++ b/xo-procedure2/src/procedure2/procedure2_register_facets.cpp @@ -3,12 +3,9 @@ * @author Roland Conybeare, Jan 2026 **/ -#include "DSimpleRcx.hpp" -#include "detail/IRuntimeContext_DSimpleRcx.hpp" - -#include "DPrimitive_gco_2_gco_gco.hpp" -#include "detail/IGCObject_DPrimitive_gco_2_gco_gco.hpp" -#include "detail/IPrintable_DPrimitive_gco_2_gco_gco.hpp" +#include "Procedure.hpp" +#include "SimpleRcx.hpp" +#include "Primitive_gco_2_gco_gco.hpp" #include #include @@ -28,12 +25,16 @@ namespace xo { FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); log && log(xtag("DSimpleRcx.tseq", typeseq::id())); log && log(xtag("DPrimitive_gco_2_gco_gco.tseq", typeseq::id())); + log && log(xtag("ARuntimeContext.tseq", typeseq::id())); + log && log(xtag("AProcedure.tseq", typeseq::id())); + return true; } From 61d41a229833c71134f8ed0427af2b232733c2dc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 4 Feb 2026 16:26:19 -0500 Subject: [PATCH 162/258] xo-interpreter2: apply sequence now working in interpreter --- .../xo/interpreter2/DVsmApplyFrame.hpp | 2 + .../xo/interpreter2/DVsmEvalArgsFrame.hpp | 31 +++- .../interpreter2/VirtualSchematikaMachine.hpp | 21 ++- .../include/xo/interpreter2/VsmFrame.hpp | 4 +- .../src/interpreter2/DVsmEvalArgsFrame.cpp | 16 +- .../interpreter2/VirtualSchematikaMachine.cpp | 156 ++++++++++++++++-- .../utest/VirtualSchematikaMachine.test.cpp | 4 +- xo-object2/include/xo/object2/DArray.hpp | 3 +- 8 files changed, 203 insertions(+), 34 deletions(-) diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp index d947a8bc..c898c602 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp @@ -29,6 +29,8 @@ namespace xo { obj fn() const noexcept { return fn_; } DArray * args() const noexcept { return args_; } + void assign_fn(obj x) { this->fn_ = x; } + std::size_t shallow_size() const noexcept; DVsmApplyFrame * shallow_copy(obj mm) const noexcept; std::size_t forward_children(obj gc) noexcept; diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp index a8ef0226..7131a001 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp @@ -5,16 +5,18 @@ #pragma once -#include "DVsmApplyFrame.hpp" +#include "VsmApplyFrame.hpp" +#include namespace xo { namespace scm { /** frame for executing an apply expression **/ - class DVsmEvalArgsFrame : public VsmFrame { + class DVsmEvalArgsFrame { public: using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; using ppindentinfo = xo::print::ppindentinfo; public: @@ -24,12 +26,21 @@ namespace xo { * old_cont = [xfer to called function] * **/ - DVsmEvalArgsFrame(obj old_parent, - VsmInstr old_cont); + DVsmEvalArgsFrame(DVsmApplyFrame * parent, + VsmInstr cont, + const DApplyExpr * apply_expr); static DVsmEvalArgsFrame * make(obj mm, - obj apply_frame, - VsmInstr old_cont); + DVsmApplyFrame * apply_frame, + VsmInstr old_cont, + const DApplyExpr * apply_expr); + + DVsmApplyFrame * parent() const noexcept { return parent_; } + VsmInstr cont() const noexcept { return cont_; } + const DApplyExpr * apply_expr() const noexcept { return apply_expr_; } + int32_t i_arg() const noexcept { return i_arg_; } + + int32_t increment_arg() { return ++i_arg_; } std::size_t shallow_size() const noexcept; DVsmEvalArgsFrame * shallow_copy(obj mm) const noexcept; @@ -38,6 +49,14 @@ namespace xo { bool pretty(const ppindentinfo & ppii) const; protected: + /** parent stack frame **/ + DVsmApplyFrame * parent_ = nullptr; + /** continuation after eval args completed (always VsmInstr::c_apply) **/ + VsmInstr cont_; + + /** expression being evaluated **/ + const DApplyExpr * apply_expr_ = nullptr; + /** next argument to be evaluated. -1 means function head **/ int32_t i_arg_ = -1; }; diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 78c2f3f7..774659eb 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -147,7 +147,14 @@ namespace xo { /** apply a function to evaluated arguments **/ void _do_apply_op(); - /** evaluate arguments on behalf of a function call **/ + /** evaluate arguments on behalf of a function call + * Require: + * - expression value in @ref value_ + * - stack: + * [0] VsmEvalArgsFrame + * [1] VsmApplyFrame + * ... + **/ void _do_evalargs_op(); private: @@ -159,6 +166,8 @@ namespace xo { * Other registers are not preserved * pc_ * expr_ + * fn_ + * args_ * value_ */ @@ -170,6 +179,11 @@ namespace xo { **/ box mm_; + /** runtime context for this vsm. + * For example, provides allocator to primitives + **/ + box rcx_; + // consider separate allocator (which _may_ turn out to be the same) // for VM stack. Only works for code that doesn't rely on fancy // lexical scoping @@ -186,6 +200,11 @@ namespace xo { /** expression register **/ obj expr_; + /** function to call **/ + obj fn_; + /** evaluated argument list **/ + DArray * args_; + /** result register **/ VsmResult value_; diff --git a/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp index f4cf5f1e..52a30761 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmFrame.hpp @@ -20,9 +20,7 @@ namespace xo { VsmInstr cont) : parent_{parent}, cont_{cont} {} //obj parent() const noexcept { return parent_; } - VsmFrame * parent() const noexcept { - return reinterpret_cast(parent_.data()); - } + obj parent() const noexcept { return parent_; } VsmInstr cont() const noexcept { return cont_; } protected: diff --git a/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp index cb2b328e..01391cf2 100644 --- a/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp @@ -14,22 +14,26 @@ namespace xo { // ----- VsmEvalArgsFrame ----- - DVsmEvalArgsFrame::DVsmEvalArgsFrame(obj old_parent, - VsmInstr old_cont) - : VsmFrame(old_parent, old_cont) + DVsmEvalArgsFrame::DVsmEvalArgsFrame(DVsmApplyFrame * parent, + VsmInstr cont, + const DApplyExpr * apply_expr) + : parent_{parent}, + cont_{cont}, + apply_expr_{apply_expr} {} DVsmEvalArgsFrame * DVsmEvalArgsFrame::make(obj mm, - obj apply_frame, - VsmInstr cont) + DVsmApplyFrame * apply_frame, + VsmInstr cont, + const DApplyExpr * apply_expr) { DVsmEvalArgsFrame * result = nullptr; void * mem = mm.alloc(typeseq::id(), sizeof(DVsmEvalArgsFrame)); - result = new (mem) DVsmEvalArgsFrame(apply_frame, cont); + result = new (mem) DVsmEvalArgsFrame(apply_frame, cont, apply_expr); assert(result); diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 22f9ed12..b32f6b24 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -8,6 +8,8 @@ #include "VsmEvalArgsFrame.hpp" #include #include +#include +#include #include #include #include @@ -26,9 +28,13 @@ namespace xo { namespace scm { + // NOTE: using heap for {DX1Collector, DSimpleRcx} instances + // (though allocation from explictly mmap'd memory) + // VirtualSchematikaMachine::VirtualSchematikaMachine(const VsmConfig & config) : config_{config}, mm_(box(new DX1Collector(config.x1_config_))), + rcx_(box(new DSimpleRcx(mm_.to_op()))), reader_{config.rdr_config_, mm_.to_op()} {} @@ -211,21 +217,23 @@ namespace xo { // assuming bump allocator: // - // DArray VsmApplyFrame VsmEvalArgsFrame - // v v v - // +----------------------+-------+------+----+--------+-------+------+-------+ - // | argument expressions | par x | cont | fn | args x | par x | cont | i_arg | - // +----------------------+-----|-+------+----+------|-+-----|-+------+-------+ - // ^ ^ | | | - // | \----------------------------------/ - // \ | / - // \-----------------------------------------------/ + // DArray VsmApplyFrame VsmEvalArgsFrame + // v v v + // +----------------------+-------+-------+----+--------+-------+-------+-------+ + // | argument expressions | par x | cont1 | fn | args x | par x | cont2 | i_arg | + // +----------------------+-----|-+-------+----+------|-+-----|-+-------+-------+ + // ^ ^ | | | + // | \-----------------------------------/ + // \ | / + // \------------------------------------------------/ // / // <---------------------------/ // // - VsmEvalArgsFrame: owned by VSM, state for evalargs loop // - VsmApplyFrame: owned by VSM, state for transferring control to called function // - DArray: contains evaluated args; owned by called primitive + // - cont2: always c_apply + // auto apply = obj::from(expr_); @@ -235,13 +243,13 @@ namespace xo { // TODO: check function signature - auto apply_frame - = obj - (DVsmApplyFrame::make(mm_.to_op(), stack_, cont_, args)); + DVsmApplyFrame * apply_frame + = DVsmApplyFrame::make(mm_.to_op(), stack_, cont_, args); auto evalargs_frame = obj - (DVsmEvalArgsFrame::make(mm_.to_op(), apply_frame, VsmInstr::c_apply)); + (DVsmEvalArgsFrame::make(mm_.to_op(), + apply_frame, VsmInstr::c_apply, apply.data())); this->stack_ = evalargs_frame; @@ -269,13 +277,131 @@ namespace xo { void VirtualSchematikaMachine::_do_apply_op() { - // not implemented - assert(false); + // rcx_ : runtime context + // fn_ : function to call + // args_ : array of arguments + + // TODO: check argument types + + this->value_ = fn_.apply_nocheck(rcx_.to_op(), args_); + this->pc_ = cont_; + + return; } void VirtualSchematikaMachine::_do_evalargs_op() { + scope log(XO_DEBUG(false)); + + if (!value_.is_value()) { + // error while evaluating function arg + + log.retroactively_enable(); + log && log("error in apply -> terminating app"); + + this->pc_ = VsmInstr::c_halt; + return; + } + + // here: nested evaluation succeeded + + // value of one of {fn, arg(i), ..} in fn(arg0 .. arg(n-1)) + // + obj value = *(value_.value()); + + // value_ in [i_arg] value_ + // . (if i_arg >= 0) . (if i_arg = -1) + // . . + // DArray . VsmApplyFrame . VsmEvalArgsFrame + // v v v v v + // +----------------------+-------+-------+----+--------+-------+-------+--------+-------+ + // | argument expressions | par o | cont1 | fn | args x | par o | cont2 | applyx | i_arg | + // +----------------------+-----|-+-------+----+------|-+-----|-+-------+--------+-------+ + // ^ ^ | | | + // | \-----------------------------------/ + // \ | / + // \------------------------------------------------/ + // / + // <---------------------------/ + // + // - VsmEvalArgsFrame: owned by VSM, state for evalargs loop + // - VsmApplyFrame: owned by VSM, state for transferring control to called function + // - DArray: contains evaluated args; owned by called primitive + + // - i_arg + // if -1: value_ register holds function + // if >=0: value_ register holds i'th function argument + // + + auto evalargs_frame + = obj::from(stack_); + + assert(evalargs_frame); + + int32_t i_arg = evalargs_frame->i_arg(); + + DVsmApplyFrame * apply_frame = evalargs_frame->parent(); + + const DApplyExpr * apply_expr + = evalargs_frame->apply_expr(); + + if (i_arg == -1) { + auto fn = value.to_facet(); + + if (fn) { + apply_frame->assign_fn(fn); + + i_arg = evalargs_frame->increment_arg(); + + // now i_arg is 0 -> evaluate that argument + + this->expr_ = apply_expr->arg(i_arg); + this->pc_ = VsmInstr::c_eval; + //this->cont_ = VsmInstra::c_evalargs; // redundant, since preserved + + return; + } else { + // error - function position must deliver something with AProcedure? + // or DClosure, but we'll get to that. + + log.retroactively_enable(); + log("expected procedure in function position -> terminate"); + + assert(false); + } + } else { + DArray * args = apply_frame->args(); + + log && log(xtag("i_arg", i_arg), xtag("n_arg", args->size()), xtag("cap", args->capacity())); + + args->push_back(value); + + i_arg = evalargs_frame->increment_arg(); + + if (i_arg == static_cast(apply_expr->n_args())) { + // all apply-arguments have been evaluated + // -> done with VsmEvalArgsFrame + // + + this->fn_ = apply_frame->fn(); + this->args_ = apply_frame->args(); + + this->stack_ = apply_frame->parent(); + this->pc_ = VsmInstr::c_apply; + this->cont_ = apply_frame->cont(); + + return; + + } else { + this->expr_ = apply_expr->arg(i_arg); + this->pc_ = VsmInstr::c_eval; + //this->cont_ = VsmInstra::c_evalargs; // redundant, since preserved + + return; + } + } + // not implemented assert(false); } diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 59104860..32cf7cab 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -166,10 +166,10 @@ namespace xo { log && log(xtag("res.tseq", res.value()->_typeseq())); - auto x = obj::from(*res.value()); + auto x = obj::from(*res.value()); REQUIRE(x); - REQUIRE(x.data()->value() == 1011); + REQUIRE(x.data()->value() == 1.570796325); REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index e95f67f6..c6f25221 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -68,7 +68,8 @@ namespace xo { requires (std::same_as> && ...) static DArray * array(obj mm, Args... args); - obj operator[](size_type index) const noexcept { return elts_[index]; } + const obj & operator[](size_type index) const noexcept { return elts_[index]; } + obj & operator[](size_type index) noexcept { return elts_[index]; } ///@} /** @defgroup darray-access acecss methods **/ From c9c43fbef23b7aaf7ef852549d49a546f0abe31d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 4 Feb 2026 19:17:07 -0500 Subject: [PATCH 163/258] xo-interpreter2 stack: scaffold DClosure, DLocalEnv [WIP] --- .../include/xo/alloc2/alloc/RAllocator.hpp | 5 + .../include/xo/expression2/DLambdaExpr.hpp | 2 + .../include/xo/expression2/DLocalSymtab.hpp | 2 +- .../include/xo/expression2/LambdaExpr.hpp | 13 +++ .../include/xo/expression2/LocalSymtab.hpp | 12 +++ xo-facet/codegen/genfacet | 3 + xo-facet/codegen/router_facet.hpp.j2 | 5 + .../include/xo/interpreter2/DClosure.hpp | 49 ++++++++++ .../include/xo/interpreter2/DLocalEnv.hpp | 67 ++++++++++++++ .../xo/interpreter2/DVsmApplyFrame.hpp | 1 + .../include/xo/interpreter2/LocalEnv.hpp | 12 +++ .../src/interpreter2/CMakeLists.txt | 4 + xo-interpreter2/src/interpreter2/DClosure.cpp | 29 ++++++ .../src/interpreter2/DLocalEnv.cpp | 92 +++++++++++++++++++ 14 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 xo-expression2/include/xo/expression2/LambdaExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/LocalSymtab.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/DClosure.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp create mode 100644 xo-interpreter2/src/interpreter2/DClosure.cpp create mode 100644 xo-interpreter2/src/interpreter2/DLocalEnv.cpp diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index ad528ba5..ecd80bb7 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -31,6 +31,11 @@ namespace xo { requires std::is_same_v : Object(iface, data) {} + template + void * alloc_for() noexcept { + return O::iface()->alloc(O::data(), typeseq::id(), sizeof(T)); + } + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } void _drop() const noexcept { O::iface()->_drop(O::data()); } std::string_view name() const noexcept { return O::iface()->name(O::data()); } diff --git a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp index 14be115f..2a0cc2c3 100644 --- a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp @@ -23,6 +23,7 @@ namespace xo { using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; + using size_type = DLocalSymtab::size_type; public: @@ -60,6 +61,7 @@ namespace xo { ///@{ DLocalSymtab * local_symtab() const noexcept { return local_symtab_; } + size_type n_args() const noexcept { return local_symtab_->size(); } // get_free_variables() // visit_preorder() diff --git a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp index 01d9aa85..163d031e 100644 --- a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp @@ -101,7 +101,7 @@ namespace xo { private: /** parent symbol table from scoping surrounding this one **/ DLocalSymtab * parent_ = nullptr; - /** actual range of slots_[] array. Can use inices in [0,..,n) **/ + /** actual range of slots_[] array. Can use indices in [0,..,n) **/ size_type capacity_ = 0; /** number of slots in use **/ size_type size_ = 0; diff --git a/xo-expression2/include/xo/expression2/LambdaExpr.hpp b/xo-expression2/include/xo/expression2/LambdaExpr.hpp new file mode 100644 index 00000000..45f86b25 --- /dev/null +++ b/xo-expression2/include/xo/expression2/LambdaExpr.hpp @@ -0,0 +1,13 @@ +/** @file LambdaExpr.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DLambdaExpr.hpp" +#include "detail/IExpression_DLambdaExpr.hpp" +//#include "detail/IGCObject_DLambdaExpr.hpp" +#include "detail/IPrintable_DLambdaExpr.hpp" + +/* end LambdaExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/LocalSymtab.hpp b/xo-expression2/include/xo/expression2/LocalSymtab.hpp new file mode 100644 index 00000000..4c852652 --- /dev/null +++ b/xo-expression2/include/xo/expression2/LocalSymtab.hpp @@ -0,0 +1,12 @@ +/** @file LocalSymtab.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DLocalSymtab.hpp" +#include "symtab/ISymbolTable_DLocalSymtab.hpp" +#include "symtab/IPrintable_DLocalSymtab.hpp" + +/* end LocalSymtab.hpp */ diff --git a/xo-facet/codegen/genfacet b/xo-facet/codegen/genfacet index c20689d3..8edadc1c 100755 --- a/xo-facet/codegen/genfacet +++ b/xo-facet/codegen/genfacet @@ -314,6 +314,8 @@ def gen_facet_impl(env, router_facet = f'R{facet_name}' # RFoo.hpp router_facet_hpp_fname = f'{router_facet}.hpp' + # user defined content -- whatever you want + router_facet_explicit_content = facet_idl['router_facet_explicit_content'] # ================================================================ # vars for IFacet_DRepr @@ -384,6 +386,7 @@ def gen_facet_impl(env, 'router_facet': router_facet, 'router_facet_hpp_j2': 'router_facet.hpp.j2', 'router_facet_hpp_fname': router_facet_hpp_fname, + 'router_facet_explicit_content': router_facet_explicit_content, # 'types': facet_types, 'local_types': local_types, diff --git a/xo-facet/codegen/router_facet.hpp.j2 b/xo-facet/codegen/router_facet.hpp.j2 index 5c3f6497..ca8d6404 100644 --- a/xo-facet/codegen/router_facet.hpp.j2 +++ b/xo-facet/codegen/router_facet.hpp.j2 @@ -56,6 +56,11 @@ public: ///@{ {% endif %} + // explicit injected content + {% for c in router_facet_explicit_content %} + {{c}} + {% endif %} + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } void _drop() const noexcept { O::iface()->_drop(O::data()); } diff --git a/xo-interpreter2/include/xo/interpreter2/DClosure.hpp b/xo-interpreter2/include/xo/interpreter2/DClosure.hpp new file mode 100644 index 00000000..09966038 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DClosure.hpp @@ -0,0 +1,49 @@ +/** @file DClosure.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "LocalEnv.hpp" +#include + +namespace xo { + namespace scm { + + /** @brief runtime representation for a procedure + * + * Maintains lambda + captured lexical context + **/ + class DClosure { + public: + using AAllocator = xo::mm::AAllocator; + using size_type = std::int32_t; + + public: + DClosure(const DLambdaExpr * lm, + const DLocalEnv * env); + + /** create instance using memory from @p mm + * for lambda @p lm with captured environment @p env. + **/ + static DClosure * make(obj mm, + const DLambdaExpr * lm, + const DLocalEnv * env); + + /** for now, support just fixed-arity procedures **/ + bool is_nary() const noexcept { return false; } + /** number of arguments expected by this procedure (-1 if nary) **/ + size_type n_args() const noexcept { return lambda_->n_args(); } + + private: + /** lambda expression **/ + const DLambdaExpr * lambda_ = nullptr; + /** bindings for captured variables + * (from lexical context where lambda evaluated) + **/ + const DLocalEnv * env_ = nullptr; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DClosure.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp new file mode 100644 index 00000000..fec8148d --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp @@ -0,0 +1,67 @@ +/** @file DLocalEnv.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include +#include + +namespace xo { + namespace scm { + + /** @brief bindings for arguments to a lambda + **/ + class DLocalEnv { + public: + using DArray = xo::scm::DArray; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; + + public: + /** @defgroup scm-localenv-constructors constructors **/ + ///@{ + + /** empty instance with parent @p p for variables in @p symtab **/ + DLocalEnv(DLocalEnv * parent, + DLocalSymtab * symtab, + DArray * args); + + static DLocalEnv * _make_empty(obj mm, + DLocalEnv * parent, + DLocalSymtab * symtab, + DArray * args); + + ///@} + /** @defgroup scm-local-env-methods methods **/ + ///@{ + + DLocalEnv * parent() const noexcept { return parent_; } + size_type size() const noexcept { return symtab_->size(); } + + /** lookup current value associated with binding @p ix **/ + obj lookup_value(Binding ix) const noexcept; + + /** assign value associated with binding @p ix to @p x **/ + void assign_value(Binding ix, obj x); + + ///@} + + private: + /** parent environment (from closure) **/ + DLocalEnv * parent_ = nullptr; + /** bind values for variables in this symbol table **/ + DLocalSymtab * symtab_ = nullptr; + /** bindings. + * (*args)[i] associates a value with symtab->slots_[i] + **/ + DArray * args_ = nullptr;; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLocalEnv.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp index c898c602..72900eb2 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp @@ -21,6 +21,7 @@ namespace xo { VsmInstr old_cont, DArray * args); + /** create instance using memory from @p mm **/ static DVsmApplyFrame * make(obj mm, obj old_parent, VsmInstr old_cont, diff --git a/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp new file mode 100644 index 00000000..8976452f --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp @@ -0,0 +1,12 @@ +/** @file LocalEnv.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DLocalEnv.hpp" +//#include "detail/IGCObject_DLocalEnv.hpp" +//#include "detail/IPrintable_DLocalEnv.hpp" + +/* end LocalEnv.hpp */ diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 635ecff3..e0903be8 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -17,6 +17,10 @@ set(SELF_SRCS IPrintable_DVsmApplyFrame.cpp VsmInstr.cpp + + DClosure.cpp + DLocalEnv.cpp + #IExpression_Any.cpp ) diff --git a/xo-interpreter2/src/interpreter2/DClosure.cpp b/xo-interpreter2/src/interpreter2/DClosure.cpp new file mode 100644 index 00000000..6d9bc446 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DClosure.cpp @@ -0,0 +1,29 @@ +/** @file DClosure.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DClosure.hpp" + +namespace xo { + namespace scm { + + DClosure::DClosure(const DLambdaExpr * lm, + const DLocalEnv * env) + : lambda_{lm}, env_{env} + {} + + DClosure * + DClosure::make(obj mm, + const DLambdaExpr * lm, + const DLocalEnv * env) + { + void * mem = mm.alloc_for(); + + return new (mem) DClosure(lm, env); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DClosure.cpp */ diff --git a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp new file mode 100644 index 00000000..3aba3aa8 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp @@ -0,0 +1,92 @@ +/** @file DLocalEnv.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DLocalEnv.hpp" +#include + +namespace xo { + using xo::mm::AGCObject; + using xo::reflect::typeseq; + + namespace scm { + + DLocalEnv::DLocalEnv(DLocalEnv * parent, + DLocalSymtab * symtab, + DArray * args) + : parent_{parent}, + symtab_{symtab}, + args_{args} + {} + + DLocalEnv * + DLocalEnv::_make_empty(obj mm, + DLocalEnv * parent, + DLocalSymtab * symtab, + DArray * args) + { + assert(symtab); + + void * mem = mm.alloc_for(); + + return new (mem) DLocalEnv(parent, symtab, args); + } + + obj + DLocalEnv::lookup_value(Binding ix) const noexcept + { + assert(!ix.is_global()); + + const DLocalEnv * env = this; + + for (auto i = ix.i_link(); i > 0; --i) { + env = env->parent(); + } + + if (env) { + auto j = ix.j_slot(); + + if (j < static_cast(env->size())) { + return (*(env->args_))[j]; + } else { + assert(false); + } + } else { + assert(false); + } + + /* something terribly wrong if control here */ + return obj(); + } + + void + DLocalEnv::assign_value(Binding ix, obj x) + { + assert(!ix.is_global()); + + const DLocalEnv * env = this; + + for (auto i = ix.i_link(); i > 0; --i) { + env = env->parent(); + } + + if (env) { + auto j = ix.j_slot(); + + if (j < static_cast(env->size())) { + (*(env->args_))[j] = x; + } else { + assert(false); + } + } else { + assert(false); + } + + /* something terribly wrong if control here */ + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLocalEnv.cpp */ From 370e52a149979666b7bee93bf3663e6c88d521e1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 5 Feb 2026 10:44:11 -0500 Subject: [PATCH 164/258] xo-interpreter2 stack: work on variable references [WIP] --- .../include/xo/expression2/Binding.hpp | 3 + .../include/xo/expression2/Variable.hpp | 13 ++ xo-interpreter2/CMakeLists.txt | 14 ++ xo-interpreter2/idl/IProcedure_DClosure.json5 | 17 ++ .../include/xo/interpreter2/Closure.hpp | 11 ++ .../include/xo/interpreter2/DClosure.hpp | 30 +++ .../detail/IProcedure_DClosure.hpp | 67 +++++++ .../src/interpreter2/CMakeLists.txt | 2 + xo-interpreter2/src/interpreter2/DClosure.cpp | 12 ++ .../src/interpreter2/IProcedure_DClosure.cpp | 39 ++++ .../interpreter2_register_facets.cpp | 9 + .../utest/VirtualSchematikaMachine.test.cpp | 37 ++++ xo-object2/include/xo/object2/Boolean.hpp | 12 ++ xo-object2/include/xo/object2/String.hpp | 2 +- xo-procedure2/idl/Procedure.json5 | 1 + .../include/xo/reader2/ExpectExprSsm.hpp | 12 ++ .../include/xo/reader2/ParserStateMachine.hpp | 8 + xo-reader2/src/reader2/DExpectExprSsm.cpp | 41 +++-- xo-reader2/src/reader2/DIfElseSsm.cpp | 3 +- xo-reader2/src/reader2/ParserStateMachine.cpp | 57 ++++++ xo-reader2/utest/SchematikaParser.test.cpp | 174 +++++++++++++++++- 21 files changed, 542 insertions(+), 22 deletions(-) create mode 100644 xo-expression2/include/xo/expression2/Variable.hpp create mode 100644 xo-interpreter2/idl/IProcedure_DClosure.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/Closure.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IProcedure_DClosure.hpp create mode 100644 xo-interpreter2/src/interpreter2/IProcedure_DClosure.cpp create mode 100644 xo-object2/include/xo/object2/Boolean.hpp create mode 100644 xo-reader2/include/xo/reader2/ExpectExprSsm.hpp diff --git a/xo-expression2/include/xo/expression2/Binding.hpp b/xo-expression2/include/xo/expression2/Binding.hpp index 6dffb16b..a27de6b3 100644 --- a/xo-expression2/include/xo/expression2/Binding.hpp +++ b/xo-expression2/include/xo/expression2/Binding.hpp @@ -24,6 +24,9 @@ namespace xo { static Binding global() { return Binding(s_link_global, 0); } static Binding local(int32_t j_slot) { return Binding(0, j_slot); } + bool is_null() const { + return (i_link_ == s_link_sentinel) && (j_slot_ == -1); + } bool is_global() const { return i_link_ == s_link_global; } bool is_local() const { return (i_link_ == 0) && (j_slot_ >= 0); } diff --git a/xo-expression2/include/xo/expression2/Variable.hpp b/xo-expression2/include/xo/expression2/Variable.hpp new file mode 100644 index 00000000..26ef649b --- /dev/null +++ b/xo-expression2/include/xo/expression2/Variable.hpp @@ -0,0 +1,13 @@ +/** @file Variable.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVariable.hpp" +#include "detail/IExpression_DVariable.hpp" +#include "detail/IGCObject_DVariable.hpp" +#include "detail/IPrintable_DVariable.hpp" + +/* end Variable.hpp */ diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 259c3f03..25d8cd0d 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -77,6 +77,20 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-procedure-closure + FACET_PKG xo_procedure2 + FACET Printable + REPR DClosure + INPUT idl/IProcedure_DClosure.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-interpreter2-genfacet-all) # ---------------------------------------------------------------- diff --git a/xo-interpreter2/idl/IProcedure_DClosure.json5 b/xo-interpreter2/idl/IProcedure_DClosure.json5 new file mode 100644 index 00000000..d503f5c6 --- /dev/null +++ b/xo-interpreter2/idl/IProcedure_DClosure.json5 @@ -0,0 +1,17 @@ +{ + mode: "implementation", + includes: [ + "", + "", + "", + "", + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Procedure.json5", + brief: "provide AProcedure interface for DClosure", + using_doxygen: true, + repr: "DClosure", + doc: [ "implement AProcedure for DClosure" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/Closure.hpp b/xo-interpreter2/include/xo/interpreter2/Closure.hpp new file mode 100644 index 00000000..f352e7f0 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/Closure.hpp @@ -0,0 +1,11 @@ +/** @file Closure.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DClosure.hpp" +#include "detail/IProcedure_DClosure.hpp" + +/* end Closure.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/DClosure.hpp b/xo-interpreter2/include/xo/interpreter2/DClosure.hpp index 09966038..bcf85c97 100644 --- a/xo-interpreter2/include/xo/interpreter2/DClosure.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DClosure.hpp @@ -3,8 +3,11 @@ * @author Roland Conybeare, Feb 2026 **/ +#pragma once + #include "LocalEnv.hpp" #include +#include namespace xo { namespace scm { @@ -15,7 +18,10 @@ namespace xo { **/ class DClosure { public: + using ARuntimeContext = xo::scm::ARuntimeContext; using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using ppindentinfo = xo::print::ppindentinfo; using size_type = std::int32_t; public: @@ -29,11 +35,35 @@ namespace xo { const DLambdaExpr * lm, const DLocalEnv * env); + /** @defgroup scm-closure-general-methods **/ + ///@{ + + const DLambdaExpr * lambda() const noexcept { return lambda_; } + const DLocalEnv * env() const noexcept { return env_; } + + ///@} + /** @defgroup scm-closure-procedure-facet **/ + ///@{ + /** for now, support just fixed-arity procedures **/ bool is_nary() const noexcept { return false; } /** number of arguments expected by this procedure (-1 if nary) **/ size_type n_args() const noexcept { return lambda_->n_args(); } + obj apply_nocheck(obj rcx, const DArray * args); + + ///@} + /** @defgroup scm-closure-gcobject-facet **/ + ///@{ + + ///@} + /** @defgroup scm-closure-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + private: /** lambda expression **/ const DLambdaExpr * lambda_ = nullptr; diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IProcedure_DClosure.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IProcedure_DClosure.hpp new file mode 100644 index 00000000..2c966a50 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IProcedure_DClosure.hpp @@ -0,0 +1,67 @@ +/** @file IProcedure_DClosure.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IProcedure_DClosure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IProcedure_DClosure.json5] + **/ + +#pragma once + +#include "Procedure.hpp" +#include +#include +#include +#include +#include "DClosure.hpp" + +namespace xo { namespace scm { class IProcedure_DClosure; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IProcedure_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IProcedure_DClosure + **/ + class IProcedure_DClosure { + public: + /** @defgroup scm-procedure-dclosure-type-traits **/ + ///@{ + using AGCObject = xo::scm::AProcedure::AGCObject; + using Copaque = xo::scm::AProcedure::Copaque; + using Opaque = xo::scm::AProcedure::Opaque; + ///@} + /** @defgroup scm-procedure-dclosure-methods **/ + ///@{ + // const methods + /** true iff procedure takes n arguments **/ + static bool is_nary(const DClosure & self) noexcept; + /** number of arguments. -1 for n-ary **/ + static std::int32_t n_args(const DClosure & self) noexcept; + + // non-const methods + /** invoke procedure; assume arguments satisfy type system **/ + static obj apply_nocheck(DClosure & self, obj rcx, const DArray * args); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index e0903be8..b47ea31d 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -16,6 +16,8 @@ set(SELF_SRCS IGCObject_DVsmApplyFrame.cpp IPrintable_DVsmApplyFrame.cpp + IProcedure_DClosure.cpp + VsmInstr.cpp DClosure.cpp diff --git a/xo-interpreter2/src/interpreter2/DClosure.cpp b/xo-interpreter2/src/interpreter2/DClosure.cpp index 6d9bc446..1057a25d 100644 --- a/xo-interpreter2/src/interpreter2/DClosure.cpp +++ b/xo-interpreter2/src/interpreter2/DClosure.cpp @@ -6,6 +6,8 @@ #include "DClosure.hpp" namespace xo { + using xo::mm::AGCObject; + namespace scm { DClosure::DClosure(const DLambdaExpr * lm, @@ -23,6 +25,16 @@ namespace xo { return new (mem) DClosure(lm, env); } + obj + DClosure::apply_nocheck(obj rcx, + const DArray * args) + { + (void)rcx; + (void)args; + + assert(false); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/IProcedure_DClosure.cpp b/xo-interpreter2/src/interpreter2/IProcedure_DClosure.cpp new file mode 100644 index 00000000..b41c7be1 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IProcedure_DClosure.cpp @@ -0,0 +1,39 @@ +/** @file IProcedure_DClosure.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IProcedure_DClosure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IProcedure_DClosure.json5] +**/ + +#include "detail/IProcedure_DClosure.hpp" + +namespace xo { + namespace scm { + auto + IProcedure_DClosure::is_nary(const DClosure & self) noexcept -> bool + { + return self.is_nary(); + } + + auto + IProcedure_DClosure::n_args(const DClosure & self) noexcept -> std::int32_t + { + return self.n_args(); + } + + auto + IProcedure_DClosure::apply_nocheck(DClosure & self, obj rcx, const DArray * args) -> obj + { + return self.apply_nocheck(rcx, args); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IProcedure_DClosure.cpp */ diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index b16d33ef..820dac2c 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -8,6 +8,8 @@ #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" +#include "Closure.hpp" + #include #include #include @@ -36,8 +38,15 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + // Procedure + // +- Primitive_gco_2_gco_gco + // \- Closure + + FacetRegistry::register_impl(); + log && log(xtag("DVsmApplyFrame.tseq", typeseq::id())); log && log(xtag("DVsmEvalArgsFrame.tseq", typeseq::id())); + log && log(xtag("DClosure.tseq", typeseq::id())); return true; } diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 32cf7cab..90805af7 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -186,6 +186,43 @@ namespace xo { vsm.visit_pools(visitor); } + TEST_CASE("VirtualSchematikaMachine-lambda1", "[interpreter2][VSM]") + { + scope log(XO_DEBUG(true)); + + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("lambda (x : i64) -> i64 { x * x; };"), eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq())); + + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE(x.data()->value() == 1.570796325); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + FacetRegistry::instance().visit_pools(visitor); + vsm.visit_pools(visitor); + } + } /*namespace ut*/ } /*namespace xo*/ diff --git a/xo-object2/include/xo/object2/Boolean.hpp b/xo-object2/include/xo/object2/Boolean.hpp new file mode 100644 index 00000000..a246ffc0 --- /dev/null +++ b/xo-object2/include/xo/object2/Boolean.hpp @@ -0,0 +1,12 @@ +/** @file Boolean.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DBoolean.hpp" +#include "boolean/IGCObject_DBoolean.hpp" +#include "boolean/IPrintable_DBoolean.hpp" + +/* end Boolean.hpp */ diff --git a/xo-object2/include/xo/object2/String.hpp b/xo-object2/include/xo/object2/String.hpp index b2e6d09b..111b04fb 100644 --- a/xo-object2/include/xo/object2/String.hpp +++ b/xo-object2/include/xo/object2/String.hpp @@ -1,6 +1,6 @@ /** @file String.hpp * - * @author Roland Conybeare, Feb 22026 + * @author Roland Conybeare, Feb 2026 **/ #pragma once diff --git a/xo-procedure2/idl/Procedure.json5 b/xo-procedure2/idl/Procedure.json5 index 91c8bdf3..449414f0 100644 --- a/xo-procedure2/idl/Procedure.json5 +++ b/xo-procedure2/idl/Procedure.json5 @@ -65,4 +65,5 @@ ] } ], + router_facet_explicit_content: [ ], } diff --git a/xo-reader2/include/xo/reader2/ExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ExpectExprSsm.hpp new file mode 100644 index 00000000..d46ef489 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectExprSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectExprSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DExpectExprSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" +#include "ssm/IPrintable_DExpectExprSsm.hpp" + +/* end ExpectExprSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 3fae8903..2bee6a96 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -89,6 +89,9 @@ namespace xo { /** get unique (within stringtable) string, beginning with @p prefix **/ const DUniqueString * gensym(std::string_view prefix); + /** get variable defn for @p symbolname, or else nullptr **/ + Binding lookup_binding(std::string_view symbolname); + /** push nested local symtab while parsing the body of a lambda expression; * restore previous symtab at the end of lambda-expression definition. * See @ref pop_local_symtab @@ -229,6 +232,11 @@ namespace xo { obj, std::string_view expect_str); + /** report error - no binding for variable @p sym + **/ + void error_unbound_variable(std::string_view ssm_name, + std::string_view sym); + ///@} private: diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index cddfb865..b1b0701b 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -3,23 +3,18 @@ * @author Roland Conybeare, Jan 2026 **/ -#include "DExpectExprSsm.hpp" +#include "ExpectExprSsm.hpp" #include "ParserStateMachine.hpp" #include "SyntaxStateMachine.hpp" -#include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" #include "DSequenceSsm.hpp" #include "syntaxstatetype.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include @@ -196,7 +191,27 @@ namespace xo { DExpectExprSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { - Super::on_token(tk, p_psm); + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("tk", tk)); + + const DVariable * var = p_psm->lookup_variable(tk.text()); + + if (!var) { + p_psm->error_unbound_variable(ssm_classname(), + tk.text()); + } + + // examples of possible continuations from symbol foo + // foo ; // (1) foo is entire rvalue expression + // foo + ... // (2) foo begin operator expression + // foo(..); // (3) foo begin apply function + // + // + + DProgressSsm::start(p_psm->parser_alloc(), + obj(const_cast(var)), + p_psm); } #ifdef NOT_YET diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index 7efb4a7e..0782f23a 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -68,8 +68,7 @@ namespace xo { obj expr_mm, ParserStateMachine * p_psm) { - constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(p_psm->debug_flag())); DIfElseExpr * if_expr = DIfElseExpr::_make_empty(expr_mm); DIfElseSsm * if_ssm = DIfElseSsm::_make(parser_mm, if_expr); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 38f7ff4a..bd1effbb 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -107,6 +107,48 @@ namespace xo { return stringtable_.gensym(str); } + Binding + ParserStateMachine::lookup_binding(std::string_view symbolname) + { + scope log(XO_DEBUG(debug_flag_)); + + if (!local_symtab_) + return Binding::null(); + + const DUniqueString * ustr = stringtable_.lookup(symbolname); + + if (!ustr) { + // if not in string table, then can't be a variable either + return Binding::null(); + } + + DLocalSymtab * symtab = local_symtab_; + + // count #of nested scopes to cross, to reach symbol + // + int32_t link_count = 0; + + while (symtab) { + Binding b = symtab->lookup_binding(ustr); + + if (b.is_local()) { + assert(b.i_link() == 0); + + return Binding(link_count, b.j_slot()); + } + + ++link_count; + symtab = symtab->parent(); + } + + // TODO: check global symtab also + + log.retroactively_enable(); + log("STUB: check global symtab"); + + return Binding::null(); + } + void ParserStateMachine::push_local_symtab(DLocalSymtab * symtab) { @@ -400,6 +442,21 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + + void + ParserStateMachine::error_unbound_variable(std::string_view ssm_name, + std::string_view sym) + { + auto errmsg_string = tostr("No binding for symbol", + xtag("symbol", sym), + xtag("ssm", ssm_name)); + + auto errmsg = DString::from_view(expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 2fb10ea5..48983353 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -220,7 +220,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; @@ -285,7 +285,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; @@ -350,7 +350,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; @@ -415,7 +415,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; @@ -517,7 +517,7 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") { - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag)); ArenaConfig config; @@ -725,7 +725,7 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") { - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag)); ArenaConfig config; @@ -834,6 +834,168 @@ namespace xo { //REQUIRE(result.error_description()); } + TEST_CASE("SchematikaParser-interactive-lambda2", "[reader2][SchematikaParser]") + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * lambda (x : i64) -> i64 { x * x }; + * + **/ + + { + auto & result = parser.on_token(Token::lambda_token()); + + log && log("after lambda token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::leftparen_token()); + + log && log("after lparen token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("x")); + + log && log("after symbol(n) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::colon_token()); + + log && log("after colon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("i64")); + + log && log("after symbol(i64) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::rightparen_token()); + + log && log("after rightparen token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::yields_token()); + + log && log("after yields token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("i64")); + + log && log("after symbol(i64) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::leftbrace_token()); + + log && log("after leftbrace token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("x")); + + log && log("after symbol(x) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + +#ifdef NOPE + { + auto & result = parser.on_token(Token::rightbrace_token()); + + log && log("after rightbrace token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); +#endif + REQUIRE(false); + } } /*namespace ut*/ } /*namespace xo*/ From d869e87516b0a8ad011fb94d861ef5579839a22b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 5 Feb 2026 15:45:40 -0500 Subject: [PATCH 165/258] xo-reader2 stack: top-level lambda w/ apply parses --- xo-expression2/CMakeLists.txt | 50 ++++++++ xo-expression2/idl/Expression.json5 | 1 + xo-expression2/idl/IExpression_DVarRef.json5 | 12 ++ xo-expression2/idl/IGCObject_DApplyExpr.json5 | 15 +++ xo-expression2/idl/IGCObject_DVarRef.json5 | 15 +++ xo-expression2/idl/IPrintable_DVarRef.json5 | 13 ++ .../include/xo/expression2/ApplyExpr.hpp | 2 +- .../include/xo/expression2/Binding.hpp | 22 +++- .../include/xo/expression2/DApplyExpr.hpp | 5 +- .../include/xo/expression2/DLocalSymtab.hpp | 6 +- .../include/xo/expression2/DVarRef.hpp | 84 +++++++++++++ .../include/xo/expression2/VarRef.hpp | 13 ++ .../detail/IExpression_DVarRef.hpp | 66 ++++++++++ .../detail/IGCObject_DApplyExpr.hpp | 67 ++++++++++ .../expression2/detail/IGCObject_DVarRef.hpp | 67 ++++++++++ .../expression2/detail/IPrintable_DVarRef.hpp | 62 +++++++++ .../include/xo/expression2/exprtype.hpp | 10 +- xo-expression2/src/expression2/Binding.cpp | 41 ++++++ xo-expression2/src/expression2/CMakeLists.txt | 11 +- xo-expression2/src/expression2/DApplyExpr.cpp | 42 +++++++ xo-expression2/src/expression2/DVarRef.cpp | 105 ++++++++++++++++ .../src/expression2/IExpression_DVarRef.cpp | 45 +++++++ .../src/expression2/IGCObject_DApplyExpr.cpp | 39 ++++++ .../src/expression2/IGCObject_DVarRef.cpp | 39 ++++++ .../src/expression2/IPrintable_DVarRef.cpp | 28 +++++ .../expression2_register_facets.cpp | 18 ++- xo-facet/codegen/router_facet.hpp.j2 | 6 +- xo-gc/idl/GCObject.json5 | 1 + .../interpreter2/VirtualSchematikaMachine.hpp | 8 +- .../interpreter2/VirtualSchematikaMachine.cpp | 10 ++ xo-object2/src/object2/DArray.cpp | 2 +- xo-printable2/idl/Printable.json5 | 1 + xo-reader2/idl/SyntaxStateMachine.json5 | 6 +- xo-reader2/include/xo/reader2/DDefineSsm.hpp | 9 +- .../include/xo/reader2/DExpectExprSsm.hpp | 7 +- .../include/xo/reader2/DExprSeqState.hpp | 6 +- xo-reader2/include/xo/reader2/DIfElseSsm.hpp | 7 +- xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 5 +- .../include/xo/reader2/DProgressSsm.hpp | 5 +- .../include/xo/reader2/DSequenceSsm.hpp | 8 ++ .../xo/reader2/DSyntaxStateMachine.hpp | 12 +- .../include/xo/reader2/ParserStateMachine.hpp | 26 ++-- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 6 +- .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 7 +- .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 4 +- .../ISyntaxStateMachine_DExpectExprSsm.hpp | 4 +- ...SyntaxStateMachine_DExpectFormalArgSsm.hpp | 4 +- ...axStateMachine_DExpectFormalArglistSsm.hpp | 4 +- .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 4 +- .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 4 +- .../ssm/ISyntaxStateMachine_DExprSeqState.hpp | 4 +- .../ssm/ISyntaxStateMachine_DIfElseSsm.hpp | 4 +- .../ssm/ISyntaxStateMachine_DLambdaSsm.hpp | 4 +- .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 4 +- .../ssm/ISyntaxStateMachine_DSequenceSsm.hpp | 4 +- .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 9 +- .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 11 +- xo-reader2/src/reader2/DDefineSsm.cpp | 27 +++- xo-reader2/src/reader2/DExpectExprSsm.cpp | 11 +- xo-reader2/src/reader2/DExprSeqState.cpp | 15 ++- xo-reader2/src/reader2/DIfElseSsm.cpp | 24 +++- xo-reader2/src/reader2/DLambdaSsm.cpp | 7 +- xo-reader2/src/reader2/DProgressSsm.cpp | 45 +++---- xo-reader2/src/reader2/DSequenceSsm.cpp | 33 ++++- .../src/reader2/ISyntaxStateMachine_Any.cpp | 2 +- .../ISyntaxStateMachine_DDefineSsm.cpp | 4 +- .../ISyntaxStateMachine_DExpectExprSsm.cpp | 4 +- ...SyntaxStateMachine_DExpectFormalArgSsm.cpp | 4 +- ...axStateMachine_DExpectFormalArglistSsm.cpp | 4 +- .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 4 +- .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 4 +- .../ISyntaxStateMachine_DExprSeqState.cpp | 4 +- .../ISyntaxStateMachine_DIfElseSsm.cpp | 4 +- .../ISyntaxStateMachine_DLambdaSsm.cpp | 4 +- .../ISyntaxStateMachine_DProgressSsm.cpp | 4 +- .../ISyntaxStateMachine_DSequenceSsm.cpp | 4 +- xo-reader2/src/reader2/ParserStateMachine.cpp | 118 ++++++++++++------ xo-reader2/utest/SchematikaParser.test.cpp | 32 +++-- 78 files changed, 1213 insertions(+), 219 deletions(-) create mode 100644 xo-expression2/idl/IExpression_DVarRef.json5 create mode 100644 xo-expression2/idl/IGCObject_DApplyExpr.json5 create mode 100644 xo-expression2/idl/IGCObject_DVarRef.json5 create mode 100644 xo-expression2/idl/IPrintable_DVarRef.json5 create mode 100644 xo-expression2/include/xo/expression2/DVarRef.hpp create mode 100644 xo-expression2/include/xo/expression2/VarRef.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IExpression_DVarRef.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IGCObject_DApplyExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IGCObject_DVarRef.hpp create mode 100644 xo-expression2/include/xo/expression2/detail/IPrintable_DVarRef.hpp create mode 100644 xo-expression2/src/expression2/Binding.cpp create mode 100644 xo-expression2/src/expression2/DVarRef.cpp create mode 100644 xo-expression2/src/expression2/IExpression_DVarRef.cpp create mode 100644 xo-expression2/src/expression2/IGCObject_DApplyExpr.cpp create mode 100644 xo-expression2/src/expression2/IGCObject_DVarRef.cpp create mode 100644 xo-expression2/src/expression2/IPrintable_DVarRef.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index d826a155..d070190e 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -146,6 +146,44 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-expression-varref + FACET_PKG xo_expression2 + FACET Expression + REPR VarRef + INPUT idl/IExpression_DVarRef.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-varref + FACET_PKG xo_gc + FACET GCObject + REPR VarRef + INPUT idl/IGCObject_DVarRef.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-varref + FACET_PKG xo_printable2 + FACET Printable + REPR VarRef + INPUT idl/IPrintable_DVarRef.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-expression-defineexpr @@ -184,6 +222,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-applyexpr + FACET_PKG xo_gc + FACET GCObject + REPR ApplyExpr + INPUT idl/IGCObject_DApplyExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-applyexpr diff --git a/xo-expression2/idl/Expression.json5 b/xo-expression2/idl/Expression.json5 index f2f7d44a..83ae1402 100644 --- a/xo-expression2/idl/Expression.json5 +++ b/xo-expression2/idl/Expression.json5 @@ -67,4 +67,5 @@ attributes: [], } ], + router_facet_explicit_content: [ ], } diff --git a/xo-expression2/idl/IExpression_DVarRef.json5 b/xo-expression2/idl/IExpression_DVarRef.json5 new file mode 100644 index 00000000..8dea30e5 --- /dev/null +++ b/xo-expression2/idl/IExpression_DVarRef.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ "\"Expression.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Expression.json5", + brief: "provide AExpression interface for DVarRef state", + using_doxygen: true, + repr: "DVarRef", + doc: ["doc for IExpression+DVarRef" ], +} diff --git a/xo-expression2/idl/IGCObject_DApplyExpr.json5 b/xo-expression2/idl/IGCObject_DApplyExpr.json5 new file mode 100644 index 00000000..4bf4304b --- /dev/null +++ b/xo-expression2/idl/IGCObject_DApplyExpr.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DApplyExpr", + using_doxygen: true, + repr: "DApplyExpr", + doc: [ "implement AGCObject for DApplyExpr" ], +} diff --git a/xo-expression2/idl/IGCObject_DVarRef.json5 b/xo-expression2/idl/IGCObject_DVarRef.json5 new file mode 100644 index 00000000..3101a035 --- /dev/null +++ b/xo-expression2/idl/IGCObject_DVarRef.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVarRef", + using_doxygen: true, + repr: "DVarRef", + doc: [ "implement AGCObject for DVarRef" ], +} diff --git a/xo-expression2/idl/IPrintable_DVarRef.json5 b/xo-expression2/idl/IPrintable_DVarRef.json5 new file mode 100644 index 00000000..d525886c --- /dev/null +++ b/xo-expression2/idl/IPrintable_DVarRef.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVarRef", + using_doxygen: true, + repr: "DVarRef", + doc: [ "implement APrintable for DVarRef" ], +} diff --git a/xo-expression2/include/xo/expression2/ApplyExpr.hpp b/xo-expression2/include/xo/expression2/ApplyExpr.hpp index fd9c0764..38625855 100644 --- a/xo-expression2/include/xo/expression2/ApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/ApplyExpr.hpp @@ -7,7 +7,7 @@ #include "DApplyExpr.hpp" #include "detail/IExpression_DApplyExpr.hpp" -//#include "detail/IGCObject_DApplyExpr.hpp" +#include "detail/IGCObject_DApplyExpr.hpp" #include "detail/IPrintable_DApplyExpr.hpp" /* end ApplyExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/Binding.hpp b/xo-expression2/include/xo/expression2/Binding.hpp index a27de6b3..97f74c27 100644 --- a/xo-expression2/include/xo/expression2/Binding.hpp +++ b/xo-expression2/include/xo/expression2/Binding.hpp @@ -5,14 +5,15 @@ #pragma once +#include #include namespace xo { namespace scm { class Binding { public: - static constexpr int32_t s_link_sentinel = -2; - static constexpr int32_t s_link_global = -1; + static constexpr int32_t c_link_sentinel = -2; + static constexpr int32_t c_link_global = -1; public: Binding() : i_link_{-2}, j_slot_{-1} {} @@ -21,18 +22,22 @@ namespace xo { static Binding null() { return Binding(); } /** global bindings are located by symbol name **/ - static Binding global() { return Binding(s_link_global, 0); } + static Binding global() { return Binding(c_link_global, 0); } static Binding local(int32_t j_slot) { return Binding(0, j_slot); } + static Binding relative(int32_t i_link, Binding def); bool is_null() const { - return (i_link_ == s_link_sentinel) && (j_slot_ == -1); + return (i_link_ == c_link_sentinel) && (j_slot_ == -1); } - bool is_global() const { return i_link_ == s_link_global; } + bool is_global() const { return i_link_ == c_link_global; } bool is_local() const { return (i_link_ == 0) && (j_slot_ >= 0); } int32_t i_link() const noexcept { return i_link_; } int32_t j_slot() const noexcept { return j_slot_; } + /** print human-readable repr to stream @p os **/ + void print(std::ostream & os) const; + private: /** * >= 0: number of parent links to traverse @@ -40,13 +45,18 @@ namespace xo { * -1: resolve globally * -2: sentinel (binding info not computed) **/ - int32_t i_link_ = s_link_sentinel; + int32_t i_link_ = c_link_sentinel; /** if @ref i_link_ >= 0, frame offset * (in 'variables' not bytes). * ignored if @ref i_link_ is global **/ int32_t j_slot_ = -1; }; + + inline std::ostream & operator<< (std::ostream & os, Binding x) { + x.print(os); + return os; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/include/xo/expression2/DApplyExpr.hpp b/xo-expression2/include/xo/expression2/DApplyExpr.hpp index 8502c62a..94bcea73 100644 --- a/xo-expression2/include/xo/expression2/DApplyExpr.hpp +++ b/xo-expression2/include/xo/expression2/DApplyExpr.hpp @@ -20,6 +20,7 @@ namespace xo { **/ class DApplyExpr { public: + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; @@ -81,7 +82,9 @@ namespace xo { /** @defgroup scm-applyexpr-gcobject-facet **/ ///@{ - // shallow_copy() etc. + std::size_t shallow_size() const noexcept; + DApplyExpr * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; ///@} /** @defgroup scm-applyexpr-printable-facet **/ diff --git a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp index 163d031e..6d1a6480 100644 --- a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp @@ -31,14 +31,14 @@ namespace xo { struct Slot { Slot() = default; - explicit Slot(const DVariable * var) : var_{var} {} + explicit Slot(DVariable * var) : var_{var} {} /** variable representing a formal argument. * binding will be correct only within the same layer * as top-level lambda body * (i.e. up to the doorstep of each and every nested lambda) **/ - const DVariable * var_ = nullptr; + DVariable * var_ = nullptr; }; public: @@ -65,7 +65,7 @@ namespace xo { size_type capacity() const noexcept { return capacity_; } size_type size() const noexcept { return size_; } - const DVariable * lookup_var(Binding ix) const noexcept { + DVariable * lookup_var(Binding ix) noexcept { assert(ix.i_link() == 0); assert(ix.j_slot() < static_cast(size_)); diff --git a/xo-expression2/include/xo/expression2/DVarRef.hpp b/xo-expression2/include/xo/expression2/DVarRef.hpp new file mode 100644 index 00000000..d4a230b3 --- /dev/null +++ b/xo-expression2/include/xo/expression2/DVarRef.hpp @@ -0,0 +1,84 @@ +/** @file DVarRef.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "Variable.hpp" + +namespace xo { + namespace scm { + + /** @class DVarRef + * @brief syntax for a variable reference + * + * Reference to a known variable possibly + * defined in another scope. + * For non-local non-global variables, + **/ + class DVarRef { + public: + using ppindentinfo = xo::print::ppindentinfo; + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; + + public: + DVarRef(DVariable * vardef, + Binding path); + + /** create instance + * @p mm memory allocator + * @p vardef variable definition (name, typeref, binding) + * @p link number of lexical scope boundaries we must cross + * to reach scope containing @p vardef. + * Only relevant for non-global vardef + **/ + static DVarRef * make(obj mm, + DVariable * vardef, + int32_t link); + + const DUniqueString * name() const; + Binding path() const { return path_; } + + /** @defgroup scm-variable-expression-facet **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::varref; } + TypeRef typeref() const noexcept; + TypeDescr valuetype() const noexcept; + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + /** @defgroup scm-variable-gcobject-facet **/ + ///@{ + + size_t shallow_size() const noexcept; + DVarRef * shallow_copy(obj mm) const noexcept; + size_t forward_children(obj gc) noexcept; + + ///@} + /** @defgroup scm-variable-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** variable definition. Created in the sccope where variable introduced. + * Has an associated @ref Binding, but that binding is only correct + * around any nested scopes. + **/ + DVariable * vardef_ = nullptr; + + /** at runtime: navigate environemnt via this path to get + * runtime memory location for this variable + **/ + Binding path_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVarRef.hpp */ diff --git a/xo-expression2/include/xo/expression2/VarRef.hpp b/xo-expression2/include/xo/expression2/VarRef.hpp new file mode 100644 index 00000000..19f2d1d0 --- /dev/null +++ b/xo-expression2/include/xo/expression2/VarRef.hpp @@ -0,0 +1,13 @@ +/** @file VarRef.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVarRef.hpp" +#include "detail/IExpression_DVarRef.hpp" +#include "detail/IGCObject_DVarRef.hpp" +#include "detail/IPrintable_DVarRef.hpp" + +/* end VarRef.hpp */ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_DVarRef.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_DVarRef.hpp new file mode 100644 index 00000000..332113c1 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IExpression_DVarRef.hpp @@ -0,0 +1,66 @@ +/** @file IExpression_DVarRef.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DVarRef.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DVarRef.json5] + **/ + +#pragma once + +#include "Expression.hpp" +#include "Expression.hpp" +#include "DVarRef.hpp" + +namespace xo { namespace scm { class IExpression_DVarRef; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IExpression_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IExpression_DVarRef + **/ + class IExpression_DVarRef { + public: + /** @defgroup scm-expression-dvarref-type-traits **/ + ///@{ + using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; + ///@} + /** @defgroup scm-expression-dvarref-methods **/ + ///@{ + // const methods + /** expression type (constant | apply | ..) **/ + static exprtype extype(const DVarRef & self) noexcept; + /** placeholder for type giving possible values for this expression **/ + static TypeRef typeref(const DVarRef & self) noexcept; + /** type giving possible values for this expression. Maybe null before typecheck **/ + static TypeDescr valuetype(const DVarRef & self) noexcept; + + // non-const methods + /** assing to valuetype member. Useful when scaffolding expressions **/ + static void assign_valuetype(DVarRef & self, TypeDescr td) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DApplyExpr.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DApplyExpr.hpp new file mode 100644 index 00000000..10b08c10 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DApplyExpr.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DApplyExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DApplyExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DApplyExpr.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DApplyExpr.hpp" + +namespace xo { namespace scm { class IGCObject_DApplyExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DApplyExpr + **/ + class IGCObject_DApplyExpr { + public: + /** @defgroup scm-gcobject-dapplyexpr-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dapplyexpr-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DApplyExpr & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DApplyExpr & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DApplyExpr & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DVarRef.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DVarRef.hpp new file mode 100644 index 00000000..e991ebb8 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DVarRef.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVarRef.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVarRef.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVarRef.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVarRef.hpp" + +namespace xo { namespace scm { class IGCObject_DVarRef; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVarRef + **/ + class IGCObject_DVarRef { + public: + /** @defgroup scm-gcobject-dvarref-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvarref-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVarRef & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVarRef & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVarRef & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/IPrintable_DVarRef.hpp b/xo-expression2/include/xo/expression2/detail/IPrintable_DVarRef.hpp new file mode 100644 index 00000000..50034312 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IPrintable_DVarRef.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVarRef.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVarRef.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVarRef.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVarRef.hpp" + +namespace xo { namespace scm { class IPrintable_DVarRef; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVarRef + **/ + class IPrintable_DVarRef { + public: + /** @defgroup scm-printable-dvarref-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvarref-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVarRef & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/exprtype.hpp b/xo-expression2/include/xo/expression2/exprtype.hpp index 3bcda3c4..8b1778fb 100644 --- a/xo-expression2/include/xo/expression2/exprtype.hpp +++ b/xo-expression2/include/xo/expression2/exprtype.hpp @@ -36,8 +36,10 @@ namespace xo { /** function definition **/ lambda, - /** variable reference **/ + /** variable definition **/ variable, + /** variabele reference (possibly non-local) **/ + varref, /** if-then-else **/ ifexpr, /** sequence **/ @@ -65,14 +67,16 @@ namespace xo { case exprtype::assign: return "assign"; #endif case exprtype::apply: return "apply"; -#ifdef NOT_YET case exprtype::lambda: return "lambda"; case exprtype::variable: return "variable"; + case exprtype::varref: return "varref"; case exprtype::ifexpr: return "if_expr"; case exprtype::sequence: return "sequence"; +#ifdef NOT_YET case exprtype::convert: return "convert"; #endif - default: break; + case exprtype::N: break; + //default: break; } return "???exprtype???"; diff --git a/xo-expression2/src/expression2/Binding.cpp b/xo-expression2/src/expression2/Binding.cpp new file mode 100644 index 00000000..6802ba69 --- /dev/null +++ b/xo-expression2/src/expression2/Binding.cpp @@ -0,0 +1,41 @@ +/** @file Binding.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "Binding.hpp" +#include + +namespace xo { + namespace scm { + + Binding + Binding::relative(int32_t i_link, Binding def) + { + if (def.i_link_ == Binding::c_link_global) { + // for globally defined vars, i_link always -1 + return def; + } else if (def.i_link_ >= 0) { + return Binding(i_link + def.i_link_, def.j_slot_); + } else { + assert(false); + return Binding(); + } + } + + void + Binding::print(std::ostream & os) const + { + if (i_link_ == c_link_global) { + os << "{path:global}"; + } else if (i_link_ == c_link_sentinel) { + os << "{path}"; + } else { + os << "{path:" << i_link_ << ":" << j_slot_ << "}"; + } + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end Binding.cpp */ diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 4f3d63c1..45b5a06e 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -3,9 +3,12 @@ set(SELF_LIB xo_expression2) set(SELF_SRCS init_expression2.cpp + expression2_register_facets.cpp + expression2_register_types.cpp DConstant.cpp DVariable.cpp + DVarRef.cpp DDefineExpr.cpp DLambdaExpr.cpp DApplyExpr.cpp @@ -13,6 +16,7 @@ set(SELF_SRCS DSequenceExpr.cpp TypeRef.cpp + Binding.cpp IExpression_Any.cpp @@ -24,10 +28,15 @@ set(SELF_SRCS IGCObject_DVariable.cpp IPrintable_DVariable.cpp + IExpression_DVarRef.cpp + IGCObject_DVarRef.cpp + IPrintable_DVarRef.cpp + IExpression_DDefineExpr.cpp IPrintable_DDefineExpr.cpp IExpression_DApplyExpr.cpp + IGCObject_DApplyExpr.cpp IPrintable_DApplyExpr.cpp IExpression_DLambdaExpr.cpp @@ -55,8 +64,6 @@ set(SELF_SRCS IGCObject_DUniqueString.cpp IPrintable_DUniqueString.cpp - expression2_register_facets.cpp - expression2_register_types.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/xo-expression2/src/expression2/DApplyExpr.cpp b/xo-expression2/src/expression2/DApplyExpr.cpp index 751c1d85..d4e1fa55 100644 --- a/xo-expression2/src/expression2/DApplyExpr.cpp +++ b/xo-expression2/src/expression2/DApplyExpr.cpp @@ -102,6 +102,48 @@ namespace xo { typeref_.resolve(td); } + // ----- gcobject facet ----- + + std::size_t + DApplyExpr::shallow_size() const noexcept { + return sizeof(DApplyExpr) + (n_args_ * sizeof(obj)); + } + + DApplyExpr * + DApplyExpr::shallow_copy(obj mm) const noexcept { + DApplyExpr * copy = (DApplyExpr *)mm.alloc_copy((std::byte *)this); + + if (copy) { + copy->typeref_ = typeref_; + copy->fn_ = fn_; + copy->n_args_ = n_args_; + + constexpr auto c_obj_z = sizeof(obj); + + ::memcpy((void*)&(copy->args_[0]), (void*)&(args_[0]), n_args_ * c_obj_z); + } + + return copy; + } + + std::size_t + DApplyExpr::forward_children(obj gc) noexcept + { + for (size_type i = 0; i < n_args_; ++i) { + obj & arg = args_[i]; + + // runtime poly here + obj arg_gco = arg.to_facet(); + + // need the data address within *this + gc.forward_inplace(arg_gco.iface(), (void **)(&arg.data_)); + } + + return shallow_size(); + } + + // ----- printable facet ----- + bool DApplyExpr::pretty(const ppindentinfo & ppii) const { using xo::print::ppstate; diff --git a/xo-expression2/src/expression2/DVarRef.cpp b/xo-expression2/src/expression2/DVarRef.cpp new file mode 100644 index 00000000..afd9190e --- /dev/null +++ b/xo-expression2/src/expression2/DVarRef.cpp @@ -0,0 +1,105 @@ +/** @file DVarRef.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVarRef.hpp" + +namespace xo { + using xo::mm::AGCObject; + using xo::reflect::TypeDescr; + + namespace scm { + + DVarRef::DVarRef(DVariable * vardef, + Binding path) + : vardef_{vardef}, + path_{path} + {} + + DVarRef * + DVarRef::make(obj mm, + DVariable * vardef, + int32_t link) + { + assert(vardef); + + void * mem = mm.alloc_for(); + + return new (mem) DVarRef(vardef, + Binding::relative(link, + vardef->path())); + } + + const DUniqueString * + DVarRef::name() const { + return vardef_->name(); + } + + TypeRef + DVarRef::typeref() const noexcept { + assert(vardef_); + + return vardef_->typeref(); + } + + TypeDescr + DVarRef::valuetype() const noexcept + { + return this->typeref().td(); + } + + void + DVarRef::assign_valuetype(TypeDescr td) noexcept + { + assert(vardef_); + vardef_->assign_valuetype(td); + } + + // gcobject facet + + std::size_t + DVarRef::shallow_size() const noexcept + { + return sizeof(DVarRef); + } + + DVarRef * + DVarRef::shallow_copy(obj mm) const noexcept + { + DVarRef * copy = (DVarRef *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DVarRef::forward_children(obj gc) noexcept + { + // TODO: this can be helper in RCollector interface + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)vardef_); + + // TODO: concept to indicate that no gc pointers in Binding + + return shallow_size(); + } + + // printable facet + + bool + DVarRef::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DVarRef", + refrtag("name", std::string_view(*(this->name()))), + refrtag("path", this->path_)); + } + + } +} /*namespace xo*/ + +/* end DVarRef.cpp */ diff --git a/xo-expression2/src/expression2/IExpression_DVarRef.cpp b/xo-expression2/src/expression2/IExpression_DVarRef.cpp new file mode 100644 index 00000000..843a0653 --- /dev/null +++ b/xo-expression2/src/expression2/IExpression_DVarRef.cpp @@ -0,0 +1,45 @@ +/** @file IExpression_DVarRef.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DVarRef.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DVarRef.json5] +**/ + +#include "detail/IExpression_DVarRef.hpp" + +namespace xo { + namespace scm { + auto + IExpression_DVarRef::extype(const DVarRef & self) noexcept -> exprtype + { + return self.extype(); + } + + auto + IExpression_DVarRef::typeref(const DVarRef & self) noexcept -> TypeRef + { + return self.typeref(); + } + + auto + IExpression_DVarRef::valuetype(const DVarRef & self) noexcept -> TypeDescr + { + return self.valuetype(); + } + + auto + IExpression_DVarRef::assign_valuetype(DVarRef & self, TypeDescr td) noexcept -> void + { + self.assign_valuetype(td); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IExpression_DVarRef.cpp */ diff --git a/xo-expression2/src/expression2/IGCObject_DApplyExpr.cpp b/xo-expression2/src/expression2/IGCObject_DApplyExpr.cpp new file mode 100644 index 00000000..ad6571e0 --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DApplyExpr.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DApplyExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DApplyExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DApplyExpr.json5] +**/ + +#include "detail/IGCObject_DApplyExpr.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DApplyExpr::shallow_size(const DApplyExpr & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DApplyExpr::shallow_copy(const DApplyExpr & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DApplyExpr::forward_children(DApplyExpr & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DApplyExpr.cpp */ diff --git a/xo-expression2/src/expression2/IGCObject_DVarRef.cpp b/xo-expression2/src/expression2/IGCObject_DVarRef.cpp new file mode 100644 index 00000000..61596baa --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DVarRef.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVarRef.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVarRef.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVarRef.json5] +**/ + +#include "detail/IGCObject_DVarRef.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVarRef::shallow_size(const DVarRef & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVarRef::shallow_copy(const DVarRef & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVarRef::forward_children(DVarRef & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVarRef.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DVarRef.cpp b/xo-expression2/src/expression2/IPrintable_DVarRef.cpp new file mode 100644 index 00000000..a2027a2a --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DVarRef.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVarRef.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVarRef.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVarRef.json5] +**/ + +#include "detail/IPrintable_DVarRef.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVarRef::pretty(const DVarRef & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVarRef.cpp */ diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 26869d50..67944a08 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -16,13 +16,13 @@ #include #include +#include + #include #include #include -#include -//#include -#include +#include #include //#include @@ -63,6 +63,7 @@ namespace xo { // Expression // +- Constant // +- Variable + // +- VarRef // +- DefineExpr // +- ApplyExpr // +- LambdaExpr @@ -77,13 +78,20 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + //FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); + //FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -95,11 +103,13 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + //FacetRegistry::register_impl(); FacetRegistry::register_impl(); log && log(xtag("DUniqueString.tseq", typeseq::id())); log && log(xtag("DDefineExpr.tseq", typeseq::id())); log && log(xtag("DVariable.tseq", typeseq::id())); + log && log(xtag("DVarRef.tseq", typeseq::id())); log && log(xtag("DConstant.tseq", typeseq::id())); log && log(xtag("DApplyExpr.tseq", typeseq::id())); log && log(xtag("DLambdaExpr.tseq", typeseq::id())); @@ -108,7 +118,7 @@ namespace xo { log && log(xtag("DLocalSymtab.tseq", typeseq::id())); - log && log(xtag("AExpression.tqseq", typeseq::id())); + log && log(xtag("AExpression.tseq", typeseq::id())); log && log(xtag("ASymbolTable.tseq", typeseq::id())); return true; diff --git a/xo-facet/codegen/router_facet.hpp.j2 b/xo-facet/codegen/router_facet.hpp.j2 index ca8d6404..067a87c2 100644 --- a/xo-facet/codegen/router_facet.hpp.j2 +++ b/xo-facet/codegen/router_facet.hpp.j2 @@ -57,9 +57,9 @@ public: {% endif %} // explicit injected content - {% for c in router_facet_explicit_content %} - {{c}} - {% endif %} + {% for content in router_facet_explicit_content %} + {{content}} + {% endfor %} // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } diff --git a/xo-gc/idl/GCObject.json5 b/xo-gc/idl/GCObject.json5 index f2336678..bf0d78cd 100644 --- a/xo-gc/idl/GCObject.json5 +++ b/xo-gc/idl/GCObject.json5 @@ -76,4 +76,5 @@ attributes: [], }, ], + router_facet_explicit_content: [ ], } diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 774659eb..d06deb26 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -120,12 +120,18 @@ namespace xo { **/ void _do_eval_lambda_op(); - /** evaluate a variable expression + /** evaluate variable expression (definition) * Require: * - expression in @ref expr_ **/ void _do_eval_variable_op(); + /** evaluate a variable reference (use after definition) + * Require: + * - expression in @ref expr_ + **/ + void _do_eval_varref_op(); + /** evaluate an apply expression * Require: * - expression in @ref expr_ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index b32f6b24..1395209a 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -167,6 +167,9 @@ namespace xo { case exprtype::variable: _do_eval_variable_op(); break; + case exprtype::varref: + _do_eval_varref_op(); + break; case exprtype::apply: _do_eval_apply_op(); break; @@ -210,6 +213,13 @@ namespace xo { assert(false); } + void + VirtualSchematikaMachine::_do_eval_varref_op() + { + // not implemented + assert(false); + } + void VirtualSchematikaMachine::_do_eval_apply_op() { diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index 65162511..401524e0 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -106,7 +106,7 @@ namespace xo { std::size_t DArray::shallow_size() const noexcept { - return sizeof(DArray); + return sizeof(DArray) + (capacity_ * sizeof(obj)); } DArray * diff --git a/xo-printable2/idl/Printable.json5 b/xo-printable2/idl/Printable.json5 index ada9d4ca..12925bbc 100644 --- a/xo-printable2/idl/Printable.json5 +++ b/xo-printable2/idl/Printable.json5 @@ -38,4 +38,5 @@ }, ], nonconst_methods: [], + router_facet_explicit_content: [], } diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 716b7268..4e33e468 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -101,13 +101,15 @@ ], }, { - name: "on_parsed_expression_with_semicolon", - doc: ["update state machine for incoming parsed expression @p expr followed by semicolon"], + name: "on_parsed_expression_with_token", + doc: ["update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk"], return_type: "void", args: [ {type: "obj", name: "expr"}, + {type: "const Token &", name: "tk"}, {type: "ParserStateMachine *", name: "p_psm"}, ], }, ], + router_facet_explicit_content: [ ], } diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 0e3b1404..d675090e 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -176,11 +176,12 @@ namespace xo { ParserStateMachine * p_psm); /** update state for this syntax after parsing an expression @p expr - * followed by semicolon, - * overall parser state in @p p_psm + * followed by token @p tk, + * with overall parser state in @p p_psm **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 6b2fe30f..9b4bbd98 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -113,11 +113,12 @@ namespace xo { ParserStateMachine * p_psm); /** update state for this syntax after parsing an expression @p expr - * followed by semicolon, + * followed by token @p tk * overall parser state in @p p_psm **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 56578161..72e26203 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -120,10 +120,12 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); /** update state for this syntax on parsed expression @p expr - * followed by semicolon from nested ssm. + * followed by token @p tk from nested ssm. * overall parser state in @p p_psm **/ - void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm); + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-exprseq-printable-facet printable facet methods **/ diff --git a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp index 5e6d4d8c..986ffcd7 100644 --- a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp @@ -54,7 +54,7 @@ namespace xo { **/ class DIfElseSsm : public DSyntaxStateMachine { public: - using Super = DSyntaxStateMachine; + using Super = DSyntaxStateMachine; using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; using TypeDescr = xo::reflect::TypeDescr; @@ -154,8 +154,9 @@ namespace xo { * followed by semicolon, * with overall parser state in @p p_psm. **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-ifelsessm-printable-facet printable facet methods **/ diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index d4147c76..d494639c 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -150,8 +150,9 @@ namespace xo { /** update this ssm when nested parser * emits expression @p expr **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); #ifdef NOT_YET virtual const char * get_expect_str() const override; diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 792d6eb2..3b9dff6f 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -168,8 +168,9 @@ namespace xo { ParserStateMachine * p_psm); void on_rightbrace_token(const Token & tk, ParserStateMachine * p_psm); - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm); + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-progressssm-printable-facet printable facet methods **/ diff --git a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp index e2943ae8..486187fc 100644 --- a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp +++ b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp @@ -28,6 +28,7 @@ namespace xo { class DSequenceSsm : public DSyntaxStateMachine { public: + using Super = DSyntaxStateMachine; //using Sequence = xo::scm::Sequence; //using Lambda = xo::scm::Lambda; using AAllocator = xo::mm::AAllocator; @@ -78,6 +79,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** consume expression @p expr produced by nested ssm followed by token @p tk; + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-sequencessm-printable-facet printable facet **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp index f5a835ae..947d3b84 100644 --- a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp @@ -114,8 +114,9 @@ namespace xo { /** Default implementation for required SyntaxStateMachine facet method **/ - void on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) { // starting with c++23 can use "this auto&& self" instead Derived & self = static_cast(*this); @@ -124,9 +125,10 @@ namespace xo { // since the semicolon isn't relevant to problem with syntax // - p_psm->illegal_parsed_expression(Derived::ssm_classname(), - expr, - self.get_expect_str()); + p_psm->illegal_parsed_expression_with_token(Derived::ssm_classname(), + expr, + tk, + self.get_expect_str()); } }; diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 2bee6a96..d8dc8da9 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -89,8 +90,8 @@ namespace xo { /** get unique (within stringtable) string, beginning with @p prefix **/ const DUniqueString * gensym(std::string_view prefix); - /** get variable defn for @p symbolname, or else nullptr **/ - Binding lookup_binding(std::string_view symbolname); + /** get variable reference for @p symbolname in current context, or else nullptr **/ + DVarRef * lookup_varref(std::string_view symbolname); /** push nested local symtab while parsing the body of a lambda expression; * restore previous symtab at the end of lambda-expression definition. @@ -141,17 +142,6 @@ namespace xo { **/ void on_parsed_expression(obj expr); - /** update state to respond to parsed expression @p expr - * (from nested parsing state), with trailing semicolon. - * - * Need to distinguish cases like: - * 6 // ; allowed - * f(6 // ) allowed ; forbidden - * 6 + // ) forbidden ; forbidden - * - **/ - void on_parsed_expression_with_semicolon(obj expr); - /** update state to respond to parsed expression @p expr * (from nested parsing state), with trailing token @p tk. * @@ -232,6 +222,16 @@ namespace xo { obj, std::string_view expect_str); + /** report illegal parsed expression @p expr from nested ssm @p ssm_name, + * presented with immediately-following input token @p tk + * Introducing as placeholder; not clear if this will be reachable + * in full parser + **/ + void illegal_parsed_expression_with_token(std::string_view ssm_name, + obj expr, + const Token & tk, + std::string_view expect_str); + /** report error - no binding for variable @p sym **/ void error_unbound_variable(std::string_view ssm_name, diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index b6475877..93a0e402 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -51,6 +51,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; /** identify a type of syntax state machine **/ virtual syntaxstatetype ssm_type(Copaque data) const noexcept = 0; /** text describing expected/allowed input to this ssm in current state **/ @@ -69,8 +71,8 @@ public: virtual void on_parsed_formal_arglist(Opaque data, DArray * arglist, ParserStateMachine * p_psm) = 0; /** update state machine for incoming parsed expression @p expr **/ virtual void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - virtual void on_parsed_expression_with_semicolon(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + virtual void on_parsed_expression_with_token(Opaque data, obj expr, const Token & tk, ParserStateMachine * p_psm) = 0; ///@} }; /*ASyntaxStateMachine*/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 9cf16408..05d292cc 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -54,8 +54,11 @@ namespace scm { // from ASyntaxStateMachine - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods [[noreturn]] syntaxstatetype ssm_type(Copaque) const noexcept override { _fatal(); } [[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); } @@ -66,7 +69,7 @@ namespace scm { [[noreturn]] void on_parsed_formal(Opaque, const DUniqueString *, TypeDescr, ParserStateMachine *) override; [[noreturn]] void on_parsed_formal_arglist(Opaque, DArray *, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression(Opaque, obj, ParserStateMachine *) override; - [[noreturn]] void on_parsed_expression_with_semicolon(Opaque, obj, ParserStateMachine *) override; + [[noreturn]] void on_parsed_expression_with_token(Opaque, obj, const Token &, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index c34a66a5..0a8ff60d 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DDefineSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DDefineSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DDefineSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 7280b78e..e425386e 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DExpectExprSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DExpectExprSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp index acf84462..4c8e8c44 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DExpectFormalArgSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DExpectFormalArgSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp index 4cf9e3ff..2540684c 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DExpectFormalArglistSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DExpectFormalArglistSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 1a33685f..4b4ea7dd 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DExpectSymbolSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DExpectSymbolSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 054c03f1..49c0ffe4 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DExpectTypeSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DExpectTypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index cd241d52..cfb92548 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DExprSeqState & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DExprSeqState & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp index 65f585af..f1594b02 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DIfElseSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DIfElseSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp index 6d931744..062de20c 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DLambdaSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DLambdaSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index 27ec4f53..0d776976 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DProgressSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DProgressSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DProgressSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp index da541414..90c17b36 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp @@ -66,8 +66,8 @@ namespace xo { static void on_parsed_formal_arglist(DSequenceSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DSequenceSsm & self, obj expr, ParserStateMachine * p_psm); - /** update state machine for incoming parsed expression @p expr followed by semicolon **/ - static void on_parsed_expression_with_semicolon(DSequenceSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DSequenceSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 5fffca24..971f08b8 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -42,8 +42,11 @@ namespace scm { // from ASyntaxStateMachine - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods syntaxstatetype ssm_type(Copaque data) const noexcept override { return I::ssm_type(_dcast(data)); } @@ -70,8 +73,8 @@ namespace scm { void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) override { return I::on_parsed_expression(_dcast(data), expr, p_psm); } - void on_parsed_expression_with_semicolon(Opaque data, obj expr, ParserStateMachine * p_psm) override { - return I::on_parsed_expression_with_semicolon(_dcast(data), expr, p_psm); + void on_parsed_expression_with_token(Opaque data, obj expr, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_parsed_expression_with_token(_dcast(data), expr, tk, p_psm); } ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index b84082d2..28be39be 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -46,8 +46,13 @@ public: /** @defgroup scm-syntaxstatemachine-router-methods **/ ///@{ - // const methods + // explicit injected content + + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods syntaxstatetype ssm_type() const noexcept { return O::iface()->ssm_type(O::data()); } @@ -74,8 +79,8 @@ public: void on_parsed_expression(obj expr, ParserStateMachine * p_psm) { return O::iface()->on_parsed_expression(O::data(), expr, p_psm); } - void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm) { - return O::iface()->on_parsed_expression_with_semicolon(O::data(), expr, p_psm); + void on_parsed_expression_with_token(obj expr, const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_expression_with_token(O::data(), expr, tk, p_psm); } ///@} diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 4ad36f4f..26a68224 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -626,7 +626,7 @@ namespace xo { { if (defstate_ == defexprstatetype::def_6) { p_psm->pop_ssm(); - p_psm->on_parsed_expression_with_semicolon(def_expr_); + p_psm->on_parsed_expression_with_token(def_expr_, tk); return; } @@ -649,11 +649,28 @@ namespace xo { } void - DDefineSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + DDefineSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) { - this->on_parsed_expression(expr, p_psm); - this->on_semicolon_token(Token::semicolon_token(), p_psm); + /* must end with semicolon */ + + if (tk.tk_type() == tokentype::tk_semicolon) { + if (defstate_ == defexprstatetype::def_5) + { + this->defstate_ = defexprstatetype::def_6; + + def_expr_.data()->assign_rhs(expr); + + // completes this definition syntax + this->on_semicolon_token(tk, p_psm); + + return; + } + } + + // error in all other cases + Super::on_parsed_expression_with_token(expr, tk, p_psm); } bool diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index b1b0701b..c3cb4b31 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -195,7 +195,7 @@ namespace xo { log && log(xtag("tk", tk)); - const DVariable * var = p_psm->lookup_variable(tk.text()); + DVarRef * var = p_psm->lookup_varref(tk.text()); if (!var) { p_psm->error_unbound_variable(ssm_classname(), @@ -210,7 +210,7 @@ namespace xo { // DProgressSsm::start(p_psm->parser_alloc(), - obj(const_cast(var)), + obj(var), p_psm); } @@ -388,14 +388,15 @@ namespace xo { } void - DExpectExprSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + DExpectExprSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) { // expression (reported by nested ProgressSsm) // completes this DExpectExprSsm's assignment p_psm->pop_ssm(); - p_psm->on_parsed_expression_with_semicolon(expr); + p_psm->on_parsed_expression_with_token(expr, tk); } bool diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 802f37a2..08094655 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -167,7 +167,10 @@ namespace xo { case tokentype::tk_dot: case tokentype::tk_comma: case tokentype::tk_colon: + break; case tokentype::tk_semicolon: + assert(false); + break; case tokentype::tk_doublecolon: case tokentype::tk_singleassign: case tokentype::tk_assign: @@ -396,10 +399,16 @@ namespace xo { } void - DExprSeqState::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + DExprSeqState::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) { - p_psm->capture_result("DExprSeqState::on_parsed_expression_with_semicolon", expr); + if (tk.tk_type() == tokentype::tk_semicolon) { + p_psm->capture_result("DExprSeqState::on_parsed_expression_with_token", expr); + return; + } + + Super::on_parsed_expression_with_token(expr, tk, p_psm); } bool diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index 0782f23a..ccf4705f 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -150,13 +150,15 @@ namespace xo { case tokentype::tk_else: this->on_else_token(tk, p_psm); return; + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + return; case tokentype::tk_colon: case tokentype::tk_singleassign: case tokentype::tk_string: case tokentype::tk_f64: case tokentype::tk_i64: case tokentype::tk_bool: - case tokentype::tk_semicolon: case tokentype::tk_invalid: case tokentype::tk_leftparen: case tokentype::tk_rightparen: @@ -405,13 +407,25 @@ namespace xo { } void - DIfElseSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + DIfElseSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) { scope log(XO_DEBUG(p_psm->debug_flag())); - this->on_parsed_expression(expr, p_psm); - this->on_semicolon_token(Token::semicolon_token(), p_psm); + // TODO: may consider allowing if-else to terminate on other particular tokens + // e.g. ')' + + if ((tk.tk_type() == tokentype::tk_then) + || (tk.tk_type() == tokentype::tk_else) + || (tk.tk_type() == tokentype::tk_semicolon)) + { + this->on_parsed_expression(expr, p_psm); + this->on_token(tk, p_psm); + return; + } + + Super::on_parsed_expression_with_token(expr, tk, p_psm); } bool diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 4ed77732..286fcfa5 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -364,10 +364,11 @@ namespace xo { } void - DLambdaSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + DLambdaSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) { - Super::on_parsed_expression_with_semicolon(expr, p_psm); + Super::on_parsed_expression_with_token(expr, tk, p_psm); } #ifdef NOT_YET diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 626963b4..751264dd 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -319,10 +319,7 @@ namespace xo { obj expr = this->assemble_expr(p_psm); p_psm->pop_ssm(); // completes self - - // TODO: perhaps need to generalize on_parsed_expression_with_semicolon() ..? - p_psm->on_parsed_expression(expr); - p_psm->on_token(tk); + p_psm->on_parsed_expression_with_token(expr, tk); } void @@ -458,25 +455,7 @@ namespace xo { } p_psm->pop_ssm(); - p_psm->on_parsed_expression_with_semicolon(expr); - - /* control here on input like: - * (1.234; - * - * a. '(' sets up stack [lparen_0:expect_rhs_expression] - * (see exprstate::on_leftparen()) - * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] - * (see exprstate::on_f64()) - * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] - * deliver expresssion to expect_rhs_expression.on_expr_with_semicolon() - * (see exprstate::on_expr_with_semicolon()) - * d. expr_rhs_expression forwards expression to [lparen_0] - * e. lparen_0 would advance to [lparen_1], but rejects semicolon - */ - -#ifdef OBSOLETE - Super::on_token(tk, p_psm); -#endif + p_psm->on_parsed_expression_with_token(expr, tk); } void @@ -489,11 +468,15 @@ namespace xo { obj expr = this->assemble_expr(p_psm); - { + if (expr) { obj expr_pr - = FacetRegistry::instance().variant(expr); + = FacetRegistry::instance().try_variant(expr); assert(expr_pr); log && log(xtag("expr", expr_pr)); + } else { + // illegal token if assemble failed + Super::on_token(tk, p_psm); + return; } p_psm->pop_ssm(); @@ -501,15 +484,19 @@ namespace xo { } void - DProgressSsm::on_parsed_expression_with_semicolon(obj expr, - ParserStateMachine * p_psm) + DProgressSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) { scope log(XO_DEBUG(p_psm->debug_flag()), xtag("expr", expr)); if (op_type_ == optype::invalid) { + // e.g. control here on input like + // x : = 4 4 + p_psm->illegal_parsed_expression - ("DProgressSsm::on_parsed_expression_with_semicolon", + ("DProgressSsm::on_parsed_expression_with_token", expr, this->get_expect_str()); return; @@ -521,7 +508,7 @@ namespace xo { if (expr2) { p_psm->pop_ssm(); - p_psm->on_parsed_expression_with_semicolon(expr2); + p_psm->on_parsed_expression_with_token(expr2, tk); } } diff --git a/xo-reader2/src/reader2/DSequenceSsm.cpp b/xo-reader2/src/reader2/DSequenceSsm.cpp index 56efb896..7a65d60d 100644 --- a/xo-reader2/src/reader2/DSequenceSsm.cpp +++ b/xo-reader2/src/reader2/DSequenceSsm.cpp @@ -147,10 +147,8 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); - // TODO: stream inserter that sets up pretty-printing. - // Or integrate with indentlog. - // Maybe trouble is that indentlog doesn't #include Printable ? - // + // TODO: switch to printable facet + log && log(xtag("expr", expr)); #ifdef NOT_YET @@ -206,8 +204,31 @@ namespace xo { } #endif - this->seq_expr_->push_back(p_psm->expr_alloc(), - expr); + this->seq_expr_->push_back(p_psm->expr_alloc(), expr); + } + + void + DSequenceSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + if (tk.tk_type() == tokentype::tk_semicolon) { + // keep sequence on stack, consuming semicolon + + this->seq_expr_->push_back(p_psm->expr_alloc(), + expr); + return; + } else if (tk.tk_type() == tokentype::tk_rightbrace) { + // rightbrace ends sequence + + this->seq_expr_->push_back(p_psm->expr_alloc(), expr); + this->on_rightbrace_token(tk, p_psm); + return; + } + + Super::on_parsed_expression_with_token(expr, tk, p_psm); } #ifdef NOT_YET diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 2cd6f304..6a78fa5e 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -71,7 +71,7 @@ ISyntaxStateMachine_Any::on_parsed_expression(Opaque, obj, ParserSt } auto -ISyntaxStateMachine_Any::on_parsed_expression_with_semicolon(Opaque, obj, ParserStateMachine *) -> void +ISyntaxStateMachine_Any::on_parsed_expression_with_token(Opaque, obj, const Token &, ParserStateMachine *) -> void { _fatal(); } diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 70ff908d..8940c1b5 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DDefineSsm::on_parsed_expression_with_semicolon(DDefineSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DDefineSsm::on_parsed_expression_with_token(DDefineSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index e3e008dd..17f0ec3f 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression_with_semicolon(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression_with_token(DExpectExprSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp index c6b45889..77afbe60 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_expression_with_semicolon(DExpectFormalArgSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_expression_with_token(DExpectFormalArgSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp index fc9ae0a0..619f2ceb 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression_with_semicolon(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression_with_token(DExpectFormalArglistSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 1dee4234..efd7b893 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression_with_semicolon(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression_with_token(DExpectSymbolSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 42a4ce23..32e07aaa 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression_with_semicolon(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression_with_token(DExpectTypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index faccd745..71b0cc1a 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DExprSeqState::on_parsed_expression_with_semicolon(DExprSeqState & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_parsed_expression_with_token(DExprSeqState & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp index 0283eee0..3dbd66a8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DIfElseSsm::on_parsed_expression_with_semicolon(DIfElseSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DIfElseSsm::on_parsed_expression_with_token(DIfElseSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp index f3f23819..967e328a 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DLambdaSsm::on_parsed_expression_with_semicolon(DLambdaSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DLambdaSsm::on_parsed_expression_with_token(DLambdaSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index b4320d51..4cb25bf4 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DProgressSsm::on_parsed_expression_with_semicolon(DProgressSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DProgressSsm::on_parsed_expression_with_token(DProgressSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp index b7f770df..b27f25ba 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp @@ -58,9 +58,9 @@ namespace xo { self.on_parsed_expression(expr, p_psm); } auto - ISyntaxStateMachine_DSequenceSsm::on_parsed_expression_with_semicolon(DSequenceSsm & self, obj expr, ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DSequenceSsm::on_parsed_expression_with_token(DSequenceSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void { - self.on_parsed_expression_with_semicolon(expr, p_psm); + self.on_parsed_expression_with_token(expr, tk, p_psm); } } /*namespace scm*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index bd1effbb..56a4560c 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -107,38 +107,57 @@ namespace xo { return stringtable_.gensym(str); } - Binding - ParserStateMachine::lookup_binding(std::string_view symbolname) + DVarRef * + ParserStateMachine::lookup_varref(std::string_view symbolname) { scope log(XO_DEBUG(debug_flag_)); - if (!local_symtab_) - return Binding::null(); - - const DUniqueString * ustr = stringtable_.lookup(symbolname); - - if (!ustr) { - // if not in string table, then can't be a variable either - return Binding::null(); - } - - DLocalSymtab * symtab = local_symtab_; - - // count #of nested scopes to cross, to reach symbol + // TODO: + // 1. check global symtab + // 2. combine local+global symtab into indept struct + // 3. move lookup_varref implementation there. // - int32_t link_count = 0; - while (symtab) { - Binding b = symtab->lookup_binding(ustr); + if (local_symtab_) { + const DUniqueString * ustr = stringtable_.lookup(symbolname); - if (b.is_local()) { - assert(b.i_link() == 0); + if (ustr) { + DLocalSymtab * symtab = local_symtab_; - return Binding(link_count, b.j_slot()); + // count #of nested scopes to cross, to reach symbol + // + int32_t link_count = 0; + + while (symtab) { + Binding b = symtab->lookup_binding(ustr); + + if (b.is_local()) { + assert(b.i_link() == 0); + + DVariable * vardef = symtab->lookup_var(b); + assert(vardef); + + + /** ascii diagram here + **/ + + return DVarRef::make(expr_alloc_, + vardef, + link_count); + } else { + assert(b.is_null()); + } + + ++link_count; + symtab = symtab->parent(); + } + } else { + // if we don't already know the symbol, + // -> can't be a valid variable reference + // (whether global or local) + + return nullptr; } - - ++link_count; - symtab = symtab->parent(); } // TODO: check global symtab also @@ -146,7 +165,7 @@ namespace xo { log.retroactively_enable(); log("STUB: check global symtab"); - return Binding::null(); + return nullptr; } void @@ -239,16 +258,6 @@ namespace xo { this->top_ssm().on_parsed_expression(expr, this); } - void - ParserStateMachine::on_parsed_expression_with_semicolon(obj expr) - { - scope log(XO_DEBUG(debug_flag_), xtag("expr", expr)); - - assert(stack_); - - this->top_ssm().on_parsed_expression_with_semicolon(expr, this); - } - void ParserStateMachine::on_parsed_expression_with_token(obj expr, const Token & tk) @@ -257,11 +266,7 @@ namespace xo { assert(stack_); - this->top_ssm().on_parsed_expression(expr, this); - - assert(stack_); - - this->top_ssm().on_token(tk, this); + this->top_ssm().on_parsed_expression_with_token(expr, tk, this); } void @@ -443,6 +448,39 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + void + ParserStateMachine::illegal_parsed_expression_with_token(std::string_view ssm_name, + obj expr, + const Token & tk, + std::string_view expect_str) + { + // TODO: + // - want to write error message using DArena + // - need something like log_streambuf and/or tostr() that's arena-aware + + obj expr_pr + = FacetRegistry::instance().variant(expr); + assert(expr_pr); + + /** TODO + * problem here: we have pretty() support for obj, + * but not "ordinary printing" support. So expression doesn't get printed + **/ + auto errmsg_string = tostr("Unexpected expression", + xtag("expr", expr_pr), + xtag("tk", tk), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_parsed_expression")); + + assert(expr_alloc_); + + auto errmsg = DString::from_view(expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } + void ParserStateMachine::error_unbound_variable(std::string_view ssm_name, std::string_view sym) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 48983353..740d71f4 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -976,11 +976,34 @@ namespace xo { REQUIRE(result.is_incomplete()); } -#ifdef NOPE + { + auto & result = parser.on_token(Token::star_token()); + + log && log("after star(*) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("x")); + + log && log("after symbol(x) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + { auto & result = parser.on_token(Token::rightbrace_token()); - log && log("after rightbrace token:"); + log && log("after rightbrace(}) token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); @@ -990,11 +1013,6 @@ namespace xo { REQUIRE(result.result_expr()); } - //REQUIRE(result.is_error()); - //// illegal input on token - //REQUIRE(result.error_description()); -#endif - REQUIRE(false); } } /*namespace ut*/ } /*namespace xo*/ From 6f87a2324af7d8cf664b9e8d6c16863037033270 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 7 Feb 2026 23:14:48 -0500 Subject: [PATCH 166/258] xo-interpreter: vsm work on environments [WIP] --- .../include/xo/interpreter2/DGlobalEnv.hpp | 29 +++++++++++++++++++ .../include/xo/interpreter2/DLocalEnv.hpp | 2 +- .../include/xo/interpreter2/DVsmRcx.hpp | 2 ++ .../interpreter2/VirtualSchematikaMachine.hpp | 13 +++++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 28 +++++++++++++++++- 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp diff --git a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp new file mode 100644 index 00000000..d0ab0827 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp @@ -0,0 +1,29 @@ +/** @file DGlobalEnv.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include +#include + +namespace xo { + namespace scm { + + + /** @brief runtime bindings for global variabels + **/ + class DGlobalEnv { + public: + DGLobalEnv() = default; + + private: + // absurd O(n) implementation for now + // replace with gc-aware hashtable, when available. + + /** globals. Slots in @ref global_v_ are numbered in DLocalSymtab **/ + DArray * global_v_ = nullptr; + }; + } +} diff --git a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp index fec8148d..0291c748 100644 --- a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp @@ -11,7 +11,7 @@ namespace xo { namespace scm { - /** @brief bindings for arguments to a lambda + /** @brief runtime bindings for arguments to a lambda **/ class DLocalEnv { public: diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp new file mode 100644 index 00000000..3506206e --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp @@ -0,0 +1,2 @@ +/** @file DVsmRcx.hpp +n* diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index d06deb26..7a209bf1 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -194,6 +194,9 @@ namespace xo { // for VM stack. Only works for code that doesn't rely on fancy // lexical scoping + // consider separate allocator for reader (i.e. program code) + // and data (program execution) + /** reader: text -> expression **/ SchematikaReader reader_; @@ -206,6 +209,16 @@ namespace xo { /** expression register **/ obj expr_; + /** environment pointer. Provides bindings + * for surrounding lexical scope at this point + * in execution + **/ + DLocalEnv * local_env_ = nullptr; + /** environment pointer. Maintains bindings + * for global variables. + **/ + DGlobalEnv * global_env_ = nullptr; + /** function to call **/ obj fn_; /** evaluated argument list **/ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 1395209a..767ef784 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -36,7 +36,9 @@ namespace xo { mm_(box(new DX1Collector(config.x1_config_))), rcx_(box(new DSimpleRcx(mm_.to_op()))), reader_{config.rdr_config_, mm_.to_op()} - {} + { + // TODO: allocate global_env + } void VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const @@ -202,6 +204,30 @@ namespace xo { void VirtualSchematikaMachine::_do_eval_lambda_op() { + // assuming bump allocator + // + // +----------- DArray---------+ +-------------DLocalEnv-----------+ +-----DClosure-------+ + // | .cap |.size | .elts_[]... |h| .parent x | .symtab x | .args x |h| .lambda x | .env x | + // +------+------+-------------+ +---------|-+---------|-+-------|-+ +---------|-+------|-+ + // ^ ^ | | | | | + // \-----------------------------|---------|-----------|---------/ | | + // | | | | | + // \---------|-----------|-----------------------|--------/ + // | | | + // <--------------------------------------/ | | + // | | + // v v + // DLocalSymtab DLambdaExpr + // + // DClosure runtime procedure (created below) + // DArray bound non-local variables (established by VSM) + // DLocalEnv local environment (copy ref from VSM state) + // h alloc header + // DLocalSymtab local symbol table (created by parser) + // DLambdaExpr lambda expression (created by parser) + + DArray * args = + // not implemented assert(false); } From 9a4a6b7188afba6c9c71ba0206f440273579ffd9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 8 Feb 2026 01:01:03 -0500 Subject: [PATCH 167/258] xo-interpreter2 stack: work on VSM for apply -> closure action [WIP] --- xo-expression2/CMakeLists.txt | 26 +++++++ .../idl/IGCObject_DLambdaExpr.json5 | 15 +++++ .../idl/IGCObject_DLocalSymtab.json5 | 15 +++++ xo-expression2/idl/SymbolTable.json5 | 1 + .../include/xo/expression2/DLocalSymtab.hpp | 9 +++ .../include/xo/expression2/LambdaExpr.hpp | 2 +- .../include/xo/expression2/LocalSymtab.hpp | 1 + .../xo/expression2/detail/AExpression.hpp | 2 + .../xo/expression2/detail/IExpression_Any.hpp | 5 +- .../expression2/detail/IExpression_Xfer.hpp | 5 +- .../detail/IGCObject_DLambdaExpr.hpp | 67 +++++++++++++++++++ .../xo/expression2/detail/RExpression.hpp | 7 +- .../xo/expression2/symtab/ASymbolTable.hpp | 2 + .../symtab/IGCObject_DLocalSymtab.hpp | 67 +++++++++++++++++++ .../expression2/symtab/ISymbolTable_Any.hpp | 5 +- .../expression2/symtab/ISymbolTable_Xfer.hpp | 5 +- .../xo/expression2/symtab/RSymbolTable.hpp | 7 +- .../src/expression2/IGCObject_DLambdaExpr.cpp | 39 +++++++++++ .../expression2/IGCObject_DLocalSymtab.cpp | 39 +++++++++++ xo-gc/include/xo/gc/detail/RGCObject.hpp | 2 +- xo-interpreter2/CMakeLists.txt | 42 +++++++++++- xo-interpreter2/idl/IGCObject_DClosure.json5 | 15 +++++ xo-interpreter2/idl/IGCObject_DLocalEnv.json5 | 15 +++++ xo-interpreter2/idl/IPrintable_DClosure.json5 | 13 ++++ .../include/xo/interpreter2/Closure.hpp | 2 + .../include/xo/interpreter2/DClosure.hpp | 5 ++ .../include/xo/interpreter2/DGlobalEnv.hpp | 6 +- .../include/xo/interpreter2/DLocalEnv.hpp | 11 ++- .../include/xo/interpreter2/LocalEnv.hpp | 2 +- .../interpreter2/VirtualSchematikaMachine.hpp | 4 ++ .../detail/IGCObject_DClosure.hpp | 67 +++++++++++++++++++ .../detail/IGCObject_DLocalEnv.hpp | 67 +++++++++++++++++++ .../detail/IPrintable_DClosure.hpp | 62 +++++++++++++++++ .../src/interpreter2/CMakeLists.txt | 7 +- xo-interpreter2/src/interpreter2/DClosure.cpp | 36 +++++++++- .../src/interpreter2/DLocalEnv.cpp | 37 +++++++++- .../src/interpreter2/IGCObject_DClosure.cpp | 39 +++++++++++ .../src/interpreter2/IGCObject_DLocalEnv.cpp | 39 +++++++++++ .../src/interpreter2/IPrintable_DClosure.cpp | 28 ++++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 21 +++++- .../interpreter2_register_facets.cpp | 4 +- xo-object2/include/xo/object2/Array.hpp | 14 ++++ 42 files changed, 835 insertions(+), 22 deletions(-) create mode 100644 xo-expression2/idl/IGCObject_DLambdaExpr.json5 create mode 100644 xo-expression2/idl/IGCObject_DLocalSymtab.json5 create mode 100644 xo-expression2/include/xo/expression2/detail/IGCObject_DLambdaExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/symtab/IGCObject_DLocalSymtab.hpp create mode 100644 xo-expression2/src/expression2/IGCObject_DLambdaExpr.cpp create mode 100644 xo-expression2/src/expression2/IGCObject_DLocalSymtab.cpp create mode 100644 xo-interpreter2/idl/IGCObject_DClosure.json5 create mode 100644 xo-interpreter2/idl/IGCObject_DLocalEnv.json5 create mode 100644 xo-interpreter2/idl/IPrintable_DClosure.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DClosure.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DLocalEnv.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DClosure.hpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DClosure.cpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DClosure.cpp create mode 100644 xo-object2/include/xo/object2/Array.hpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index d070190e..382769ba 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -34,6 +34,7 @@ xo_add_genfacet( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-symboltable-localsymtab FACET_PKG xo_expression2 @@ -45,6 +46,19 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-localsymtab + FACET_PKG xo_gc + FACET GCObject + REPR LocalSymtab + INPUT idl/IGCObject_DLocalSymtab.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR symtab + OUTPUT_CPP_DIR src/expression2 +) + +# note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-localsymtab FACET_PKG xo_printable2 @@ -260,6 +274,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-lambdaexpr + FACET_PKG xo_gc + FACET GCObject + REPR LambdaExpr + INPUT idl/IGCObject_DLambdaExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-lambdaexpr diff --git a/xo-expression2/idl/IGCObject_DLambdaExpr.json5 b/xo-expression2/idl/IGCObject_DLambdaExpr.json5 new file mode 100644 index 00000000..b35ad45e --- /dev/null +++ b/xo-expression2/idl/IGCObject_DLambdaExpr.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DLambdaExpr", + using_doxygen: true, + repr: "DLambdaExpr", + doc: [ "implement AGCObject for DLambdaExpr" ], +} diff --git a/xo-expression2/idl/IGCObject_DLocalSymtab.json5 b/xo-expression2/idl/IGCObject_DLocalSymtab.json5 new file mode 100644 index 00000000..03705f5e --- /dev/null +++ b/xo-expression2/idl/IGCObject_DLocalSymtab.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DLocalSymtab", + using_doxygen: true, + repr: "DLocalSymtab", + doc: [ "implement AGCObject for DLocalSymtab" ], +} diff --git a/xo-expression2/idl/SymbolTable.json5 b/xo-expression2/idl/SymbolTable.json5 index 3d91a3d7..4d7dc2a4 100644 --- a/xo-expression2/idl/SymbolTable.json5 +++ b/xo-expression2/idl/SymbolTable.json5 @@ -56,4 +56,5 @@ // // Variable gives both {name, type} // void upsert_local(DVariable * target) = 0; ], + router_facet_explicit_content: [ ], } diff --git a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp index 6d1a6480..6a75422d 100644 --- a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp @@ -25,6 +25,7 @@ namespace xo { // using typeseq = xo::reflect::typeseq; using ppindentinfo = xo::print::ppindentinfo; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; /* note: uint16_t would be fine too */ using size_type = std::uint32_t; @@ -90,6 +91,14 @@ namespace xo { /** lookup binding for variable @p sym **/ Binding lookup_binding(const DUniqueString * sym) const noexcept; + ///@} + /** @defgroup xo-localsymtab-gcobject-facet gcobject facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DLocalSymtab * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} /** @defgroup xo-localsymtab-printable-facet printable facet **/ ///@{ diff --git a/xo-expression2/include/xo/expression2/LambdaExpr.hpp b/xo-expression2/include/xo/expression2/LambdaExpr.hpp index 45f86b25..043ca319 100644 --- a/xo-expression2/include/xo/expression2/LambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/LambdaExpr.hpp @@ -7,7 +7,7 @@ #include "DLambdaExpr.hpp" #include "detail/IExpression_DLambdaExpr.hpp" -//#include "detail/IGCObject_DLambdaExpr.hpp" +#include "detail/IGCObject_DLambdaExpr.hpp" #include "detail/IPrintable_DLambdaExpr.hpp" /* end LambdaExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/LocalSymtab.hpp b/xo-expression2/include/xo/expression2/LocalSymtab.hpp index 4c852652..e594a08d 100644 --- a/xo-expression2/include/xo/expression2/LocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/LocalSymtab.hpp @@ -7,6 +7,7 @@ #include "DLocalSymtab.hpp" #include "symtab/ISymbolTable_DLocalSymtab.hpp" +#include "symtab/IGCObject_DLocalSymtab.hpp" #include "symtab/IPrintable_DLocalSymtab.hpp" /* end LocalSymtab.hpp */ diff --git a/xo-expression2/include/xo/expression2/detail/AExpression.hpp b/xo-expression2/include/xo/expression2/detail/AExpression.hpp index 59c83339..96d68a65 100644 --- a/xo-expression2/include/xo/expression2/detail/AExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/AExpression.hpp @@ -50,6 +50,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; /** expression type (constant | apply | ..) **/ virtual exprtype extype(Copaque data) const noexcept = 0; /** placeholder for type giving possible values for this expression **/ diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp index 8ecb604d..827f9d9b 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Any.hpp @@ -54,8 +54,11 @@ namespace scm { // from AExpression - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods [[noreturn]] exprtype extype(Copaque) const noexcept override { _fatal(); } [[noreturn]] TypeRef typeref(Copaque) const noexcept override { _fatal(); } [[noreturn]] TypeDescr valuetype(Copaque) const noexcept override { _fatal(); } diff --git a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp index b95b8526..095e21ed 100644 --- a/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/detail/IExpression_Xfer.hpp @@ -41,8 +41,11 @@ namespace scm { // from AExpression - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods exprtype extype(Copaque data) const noexcept override { return I::extype(_dcast(data)); } diff --git a/xo-expression2/include/xo/expression2/detail/IGCObject_DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/detail/IGCObject_DLambdaExpr.hpp new file mode 100644 index 00000000..7d1ba5b0 --- /dev/null +++ b/xo-expression2/include/xo/expression2/detail/IGCObject_DLambdaExpr.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DLambdaExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DLambdaExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DLambdaExpr.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DLambdaExpr.hpp" + +namespace xo { namespace scm { class IGCObject_DLambdaExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DLambdaExpr + **/ + class IGCObject_DLambdaExpr { + public: + /** @defgroup scm-gcobject-dlambdaexpr-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dlambdaexpr-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DLambdaExpr & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DLambdaExpr & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DLambdaExpr & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/detail/RExpression.hpp b/xo-expression2/include/xo/expression2/detail/RExpression.hpp index a14a2ee5..89a8990f 100644 --- a/xo-expression2/include/xo/expression2/detail/RExpression.hpp +++ b/xo-expression2/include/xo/expression2/detail/RExpression.hpp @@ -46,8 +46,13 @@ public: /** @defgroup scm-expression-router-methods **/ ///@{ - // const methods + // explicit injected content + + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods exprtype extype() const noexcept { return O::iface()->extype(O::data()); } diff --git a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp index 50d6b4b7..59cf246f 100644 --- a/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ASymbolTable.hpp @@ -47,6 +47,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; /** true iff this is toplevel (global) symbol table. **/ virtual bool is_global_symtab(Copaque data) const noexcept = 0; /** report ingredients needed to address variable at runtime. **/ diff --git a/xo-expression2/include/xo/expression2/symtab/IGCObject_DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/IGCObject_DLocalSymtab.hpp new file mode 100644 index 00000000..94b9e279 --- /dev/null +++ b/xo-expression2/include/xo/expression2/symtab/IGCObject_DLocalSymtab.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DLocalSymtab.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DLocalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DLocalSymtab.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DLocalSymtab.hpp" + +namespace xo { namespace scm { class IGCObject_DLocalSymtab; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DLocalSymtab + **/ + class IGCObject_DLocalSymtab { + public: + /** @defgroup scm-gcobject-dlocalsymtab-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dlocalsymtab-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DLocalSymtab & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DLocalSymtab & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DLocalSymtab & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp index 1f4c9b2e..2d873ea1 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Any.hpp @@ -53,8 +53,11 @@ namespace scm { // from ASymbolTable - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods [[noreturn]] bool is_global_symtab(Copaque) const noexcept override { _fatal(); } [[noreturn]] Binding lookup_binding(Copaque, const DUniqueString *) const noexcept override { _fatal(); } diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp index f19f6e2e..db81237f 100644 --- a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp @@ -39,8 +39,11 @@ namespace scm { // from ASymbolTable - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods bool is_global_symtab(Copaque data) const noexcept override { return I::is_global_symtab(_dcast(data)); } diff --git a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp index f6375b37..31405e89 100644 --- a/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp +++ b/xo-expression2/include/xo/expression2/symtab/RSymbolTable.hpp @@ -45,8 +45,13 @@ public: /** @defgroup scm-symboltable-router-methods **/ ///@{ - // const methods + // explicit injected content + + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods bool is_global_symtab() const noexcept { return O::iface()->is_global_symtab(O::data()); } diff --git a/xo-expression2/src/expression2/IGCObject_DLambdaExpr.cpp b/xo-expression2/src/expression2/IGCObject_DLambdaExpr.cpp new file mode 100644 index 00000000..c7724cd5 --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DLambdaExpr.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DLambdaExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DLambdaExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DLambdaExpr.json5] +**/ + +#include "detail/IGCObject_DLambdaExpr.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DLambdaExpr::shallow_size(const DLambdaExpr & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DLambdaExpr::shallow_copy(const DLambdaExpr & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DLambdaExpr::forward_children(DLambdaExpr & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DLambdaExpr.cpp */ diff --git a/xo-expression2/src/expression2/IGCObject_DLocalSymtab.cpp b/xo-expression2/src/expression2/IGCObject_DLocalSymtab.cpp new file mode 100644 index 00000000..ca96d3b6 --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DLocalSymtab.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DLocalSymtab.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DLocalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DLocalSymtab.json5] +**/ + +#include "symtab/IGCObject_DLocalSymtab.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DLocalSymtab::shallow_size(const DLocalSymtab & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DLocalSymtab::shallow_copy(const DLocalSymtab & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DLocalSymtab::forward_children(DLocalSymtab & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DLocalSymtab.cpp */ diff --git a/xo-gc/include/xo/gc/detail/RGCObject.hpp b/xo-gc/include/xo/gc/detail/RGCObject.hpp index 435d5a64..ab4bcc54 100644 --- a/xo-gc/include/xo/gc/detail/RGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/RGCObject.hpp @@ -85,4 +85,4 @@ namespace xo { namespace facet { }; } } -/* end RGCObject.hpp */ \ No newline at end of file +/* end RGCObject.hpp */ diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 25d8cd0d..b0b3c63a 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -81,14 +81,52 @@ xo_add_genfacetimpl( xo_add_genfacetimpl( TARGET xo-interpreter2-facetimpl-procedure-closure FACET_PKG xo_procedure2 - FACET Printable - REPR DClosure + FACET Procedure + REPR Closure INPUT idl/IProcedure_DClosure.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail OUTPUT_CPP_DIR src/interpreter2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-closure + FACET_PKG xo_gc + FACET GCObject + REPR Closure + INPUT idl/IGCObject_DClosure.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-closure + FACET_PKG xo_printable2 + FACET Printable + REPR Closure + INPUT idl/IPrintable_DClosure.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-localenv + FACET_PKG xo_gc + FACET GCObject + REPR LocalEnv + INPUT idl/IGCObject_DLocalEnv.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + # ---------------------------------------------------------------- xo_add_genfacet_all(xo-interpreter2-genfacet-all) diff --git a/xo-interpreter2/idl/IGCObject_DClosure.json5 b/xo-interpreter2/idl/IGCObject_DClosure.json5 new file mode 100644 index 00000000..ec9f32fd --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DClosure.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for Closure", + using_doxygen: true, + repr: "DClosure", + doc: [ "implement AGCObject for DClosure" ], +} diff --git a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 new file mode 100644 index 00000000..3c747621 --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for LocalEnv", + using_doxygen: true, + repr: "DLocalEnv", + doc: [ "implement AGCObject for DLocalEnv" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DClosure.json5 b/xo-interpreter2/idl/IPrintable_DClosure.json5 new file mode 100644 index 00000000..d4b16a69 --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DClosure.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DClosure", + using_doxygen: true, + repr: "DClosure", + doc: [ "implement APrintable for DClosure" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/Closure.hpp b/xo-interpreter2/include/xo/interpreter2/Closure.hpp index f352e7f0..5bbeb9b8 100644 --- a/xo-interpreter2/include/xo/interpreter2/Closure.hpp +++ b/xo-interpreter2/include/xo/interpreter2/Closure.hpp @@ -7,5 +7,7 @@ #include "DClosure.hpp" #include "detail/IProcedure_DClosure.hpp" +#include "detail/IGCObject_DClosure.hpp" +#include "detail/IPrintable_DClosure.hpp" /* end Closure.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/DClosure.hpp b/xo-interpreter2/include/xo/interpreter2/DClosure.hpp index bcf85c97..26ff2703 100644 --- a/xo-interpreter2/include/xo/interpreter2/DClosure.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DClosure.hpp @@ -19,6 +19,7 @@ namespace xo { class DClosure { public: using ARuntimeContext = xo::scm::ARuntimeContext; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using ppindentinfo = xo::print::ppindentinfo; @@ -56,6 +57,10 @@ namespace xo { /** @defgroup scm-closure-gcobject-facet **/ ///@{ + std::size_t shallow_size() const noexcept; + DClosure * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} /** @defgroup scm-closure-printable-facet **/ ///@{ diff --git a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp index d0ab0827..e9f1a9c8 100644 --- a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace xo { namespace scm { @@ -16,9 +17,10 @@ namespace xo { **/ class DGlobalEnv { public: - DGLobalEnv() = default; + DGlobalEnv() = default; + + protected: // temporary, to appease compiler - private: // absurd O(n) implementation for now // replace with gc-aware hashtable, when available. diff --git a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp index 0291c748..5563fb3a 100644 --- a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp @@ -16,6 +16,7 @@ namespace xo { class DLocalEnv { public: using DArray = xo::scm::DArray; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; using ppindentinfo = xo::print::ppindentinfo; @@ -49,6 +50,14 @@ namespace xo { void assign_value(Binding ix, obj x); ///@} + /** @defgroup scm-localenv-gcobject-facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DLocalEnv * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} private: /** parent environment (from closure) **/ @@ -58,7 +67,7 @@ namespace xo { /** bindings. * (*args)[i] associates a value with symtab->slots_[i] **/ - DArray * args_ = nullptr;; + DArray * args_ = nullptr; }; } /*namespace scm*/ diff --git a/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp index 8976452f..a709e006 100644 --- a/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp @@ -6,7 +6,7 @@ #pragma once #include "DLocalEnv.hpp" -//#include "detail/IGCObject_DLocalEnv.hpp" +#include "detail/IGCObject_DLocalEnv.hpp" //#include "detail/IPrintable_DLocalEnv.hpp" /* end LocalEnv.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 7a209bf1..1aebed2c 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -8,6 +8,8 @@ #include "VsmConfig.hpp" #include "VsmInstr.hpp" #include "VsmFrame.hpp" +#include "DLocalEnv.hpp" +#include "DGlobalEnv.hpp" #include #include #include @@ -214,11 +216,13 @@ namespace xo { * in execution **/ DLocalEnv * local_env_ = nullptr; + protected: // temporarily, to appease compiler /** environment pointer. Maintains bindings * for global variables. **/ DGlobalEnv * global_env_ = nullptr; + private: /** function to call **/ obj fn_; /** evaluated argument list **/ diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DClosure.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DClosure.hpp new file mode 100644 index 00000000..fb863205 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DClosure.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DClosure.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DClosure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DClosure.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DClosure.hpp" + +namespace xo { namespace scm { class IGCObject_DClosure; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DClosure + **/ + class IGCObject_DClosure { + public: + /** @defgroup scm-gcobject-dclosure-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dclosure-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DClosure & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DClosure & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DClosure & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DLocalEnv.hpp new file mode 100644 index 00000000..d318bb61 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DLocalEnv.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DLocalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DLocalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DLocalEnv.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DLocalEnv.hpp" + +namespace xo { namespace scm { class IGCObject_DLocalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DLocalEnv + **/ + class IGCObject_DLocalEnv { + public: + /** @defgroup scm-gcobject-dlocalenv-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dlocalenv-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DLocalEnv & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DLocalEnv & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DLocalEnv & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DClosure.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DClosure.hpp new file mode 100644 index 00000000..6cc91cf1 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DClosure.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DClosure.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DClosure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DClosure.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DClosure.hpp" + +namespace xo { namespace scm { class IPrintable_DClosure; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DClosure + **/ + class IPrintable_DClosure { + public: + /** @defgroup scm-printable-dclosure-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dclosure-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DClosure & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index b47ea31d..e7493775 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -16,12 +16,15 @@ set(SELF_SRCS IGCObject_DVsmApplyFrame.cpp IPrintable_DVsmApplyFrame.cpp + DClosure.cpp + IGCObject_DClosure.cpp IProcedure_DClosure.cpp + IGCObject_DLocalEnv.cpp + DLocalEnv.cpp + VsmInstr.cpp - DClosure.cpp - DLocalEnv.cpp #IExpression_Any.cpp ) diff --git a/xo-interpreter2/src/interpreter2/DClosure.cpp b/xo-interpreter2/src/interpreter2/DClosure.cpp index 1057a25d..b1868950 100644 --- a/xo-interpreter2/src/interpreter2/DClosure.cpp +++ b/xo-interpreter2/src/interpreter2/DClosure.cpp @@ -3,7 +3,10 @@ * @author Roland Conybeare, Feb 2026 **/ -#include "DClosure.hpp" +#include "Closure.hpp" +#include "LambdaExpr.hpp" +#include "LocalEnv.hpp" +#include namespace xo { using xo::mm::AGCObject; @@ -35,6 +38,37 @@ namespace xo { assert(false); } + size_t + DClosure::shallow_size() const noexcept { + return sizeof(DClosure); + } + + DClosure * + DClosure::shallow_copy(obj mm) const noexcept { + DClosure * copy = (DClosure *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DClosure::forward_children(obj gc) noexcept + { + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&lambda_)); + + } + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&env_)); + } + + return shallow_size(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp index 3aba3aa8..9ba65085 100644 --- a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp @@ -3,7 +3,8 @@ * @author Roland Conybeare, Feb 2026 **/ -#include "DLocalEnv.hpp" +#include "LocalEnv.hpp" +#include #include namespace xo { @@ -86,6 +87,40 @@ namespace xo { /* something terribly wrong if control here */ } + std::size_t + DLocalEnv::shallow_size() const noexcept { + return sizeof(DLocalEnv); + } + + DLocalEnv * + DLocalEnv::shallow_copy(obj mm) const noexcept { + DLocalEnv * copy = (DLocalEnv *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DLocalEnv::forward_children(obj gc) noexcept + { + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&parent_)); + } + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&symtab_)); + } + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&args_)); + } + + return shallow_size(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DClosure.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DClosure.cpp new file mode 100644 index 00000000..28dd3277 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DClosure.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DClosure.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DClosure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DClosure.json5] +**/ + +#include "detail/IGCObject_DClosure.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DClosure::shallow_size(const DClosure & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DClosure::shallow_copy(const DClosure & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DClosure::forward_children(DClosure & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DClosure.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp new file mode 100644 index 00000000..3ee3b7c7 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DLocalEnv.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DLocalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DLocalEnv.json5] +**/ + +#include "detail/IGCObject_DLocalEnv.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DLocalEnv::shallow_size(const DLocalEnv & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DLocalEnv::shallow_copy(const DLocalEnv & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DLocalEnv::forward_children(DLocalEnv & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DLocalEnv.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DClosure.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DClosure.cpp new file mode 100644 index 00000000..e9c599fb --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DClosure.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DClosure.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DClosure.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DClosure.json5] +**/ + +#include "detail/IPrintable_DClosure.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DClosure::pretty(const DClosure & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DClosure.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 767ef784..bfd5e09f 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -6,7 +6,9 @@ #include "VirtualSchematikaMachine.hpp" #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" +#include "Closure.hpp" #include +#include #include #include #include @@ -21,7 +23,7 @@ namespace xo { using xo::print::ppconfig; using xo::print::ppstate_standalone; using xo::mm::AGCObject; - using xo::mm::MemorySizeInfo; + //using xo::mm::MemorySizeInfo; // not used yet using xo::mm::DX1Collector; using xo::facet::FacetRegistry; using std::cout; @@ -217,7 +219,7 @@ namespace xo { // <--------------------------------------/ | | // | | // v v - // DLocalSymtab DLambdaExpr + // DLocalSymtab DLambdaExpr // // DClosure runtime procedure (created below) // DArray bound non-local variables (established by VSM) @@ -225,8 +227,21 @@ namespace xo { // h alloc header // DLocalSymtab local symbol table (created by parser) // DLambdaExpr lambda expression (created by parser) + // - DArray * args = + // will create DClosure with local_env_ + + // local_env_ + // global_env_ + + auto lambda + = obj::from(expr_); + + DClosure * closure = DClosure::make(mm_.to_op(), + lambda.data(), + local_env_); + + this->value_ = obj(obj(closure)); // not implemented assert(false); diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index 820dac2c..1953bf1d 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -7,7 +7,6 @@ #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" - #include "Closure.hpp" #include @@ -38,6 +37,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // Procedure // +- Primitive_gco_2_gco_gco // \- Closure diff --git a/xo-object2/include/xo/object2/Array.hpp b/xo-object2/include/xo/object2/Array.hpp new file mode 100644 index 00000000..12c6eaa5 --- /dev/null +++ b/xo-object2/include/xo/object2/Array.hpp @@ -0,0 +1,14 @@ +/** @file Array.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DArray.hpp" +#include "array/ISequence_DArray.hpp" +#include "array/IGCObject_DArray.hpp" +#include "array/IPrintable_DArray.hpp" + + +/* end Array.hpp */ From 0170b8dacfb35c5b554fdd32f49fc074998b78b8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 8 Feb 2026 23:32:20 -0500 Subject: [PATCH 168/258] xo-interpreter2 stack: lambda expr -> closure runs in VSM utest --- .../include/xo/expression2/DLambdaExpr.hpp | 11 +++- .../include/xo/expression2/IfElseExpr.hpp | 13 ++++ .../include/xo/expression2/UniqueString.hpp | 12 ++++ xo-expression2/src/expression2/CMakeLists.txt | 15 ++--- .../src/expression2/DIfElseExpr.cpp | 54 ++++++++-------- .../src/expression2/DLambdaExpr.cpp | 51 +++++++++++++-- .../src/expression2/DLocalSymtab.cpp | 49 ++++++++++++++- .../expression2_register_facets.cpp | 28 +++------ xo-interpreter2/CMakeLists.txt | 12 ++++ .../idl/IPrintable_DLocalEnv.json5 | 13 ++++ .../include/xo/interpreter2/DLocalEnv.hpp | 6 ++ .../include/xo/interpreter2/LocalEnv.hpp | 2 +- .../interpreter2/VirtualSchematikaMachine.hpp | 1 + .../detail/IPrintable_DLocalEnv.hpp | 62 +++++++++++++++++++ .../src/interpreter2/CMakeLists.txt | 4 +- xo-interpreter2/src/interpreter2/DClosure.cpp | 19 ++++++ .../src/interpreter2/DLocalEnv.cpp | 16 +++++ .../src/interpreter2/IPrintable_DLocalEnv.cpp | 28 +++++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 7 +-- .../interpreter2_register_facets.cpp | 6 ++ .../utest/VirtualSchematikaMachine.test.cpp | 16 ++--- xo-object2/src/object2/DArray.cpp | 6 +- 22 files changed, 358 insertions(+), 73 deletions(-) create mode 100644 xo-expression2/include/xo/expression2/IfElseExpr.hpp create mode 100644 xo-expression2/include/xo/expression2/UniqueString.hpp create mode 100644 xo-interpreter2/idl/IPrintable_DLocalEnv.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DLocalEnv.hpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp diff --git a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp index 2a0cc2c3..b21a37ce 100644 --- a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp @@ -20,6 +20,7 @@ namespace xo { **/ class DLambdaExpr { public: + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; @@ -78,6 +79,14 @@ namespace xo { TypeDescr valuetype() const noexcept; void assign_valuetype(TypeDescr td) noexcept; + ///@} + /** @defgroup scm-lambdaexpr-gcobject-facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DLambdaExpr * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} /** @defgroup scm-lambdaexpr-printable-facet **/ ///@{ @@ -95,7 +104,7 @@ namespace xo { /** name for this lambda (generated if necessary) **/ const DUniqueString * name_ = nullptr; -#ifdef NOT_YET +#ifdef NOT_YET // when enabled, need to visit forward_children() /** e.g. * i64(f64,string) * for function of two arguments with types (f64, string) respectively, diff --git a/xo-expression2/include/xo/expression2/IfElseExpr.hpp b/xo-expression2/include/xo/expression2/IfElseExpr.hpp new file mode 100644 index 00000000..901062b2 --- /dev/null +++ b/xo-expression2/include/xo/expression2/IfElseExpr.hpp @@ -0,0 +1,13 @@ +/** @file IfElseExpr.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DIfElseExpr.hpp" +#include "detail/IExpression_DIfElseExpr.hpp" +#include "detail/IGCObject_DIfElseExpr.hpp" +#include "detail/IPrintable_DIfElseExpr.hpp" + +/* end IfElseExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/UniqueString.hpp b/xo-expression2/include/xo/expression2/UniqueString.hpp new file mode 100644 index 00000000..90cd1cd2 --- /dev/null +++ b/xo-expression2/include/xo/expression2/UniqueString.hpp @@ -0,0 +1,12 @@ +/** @file UniqueString.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DUniqueString.hpp" +#include "detail/IGCObject_DUniqueString.hpp" +#include "detail/IPrintable_DUniqueString.hpp" + +/* end UniqueString.hpp */ diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 45b5a06e..749910e4 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -10,15 +10,13 @@ set(SELF_SRCS DVariable.cpp DVarRef.cpp DDefineExpr.cpp - DLambdaExpr.cpp DApplyExpr.cpp - DIfElseExpr.cpp - DSequenceExpr.cpp TypeRef.cpp Binding.cpp IExpression_Any.cpp + ISymbolTable_Any.cpp IExpression_DConstant.cpp IGCObject_DConstant.cpp @@ -39,25 +37,28 @@ set(SELF_SRCS IGCObject_DApplyExpr.cpp IPrintable_DApplyExpr.cpp + DLambdaExpr.cpp IExpression_DLambdaExpr.cpp + IGCObject_DLambdaExpr.cpp IPrintable_DLambdaExpr.cpp + DIfElseExpr.cpp IExpression_DIfElseExpr.cpp IGCObject_DIfElseExpr.cpp IPrintable_DIfElseExpr.cpp + DSequenceExpr.cpp IExpression_DSequenceExpr.cpp IGCObject_DSequenceExpr.cpp IPrintable_DSequenceExpr.cpp DLocalSymtab.cpp - DGlobalSymtab.cpp - - ISymbolTable_Any.cpp - ISymbolTable_DLocalSymtab.cpp + IGCObject_DLocalSymtab.cpp IPrintable_DLocalSymtab.cpp + DGlobalSymtab.cpp + StringTable.cpp DUniqueString.cpp diff --git a/xo-expression2/src/expression2/DIfElseExpr.cpp b/xo-expression2/src/expression2/DIfElseExpr.cpp index 631be466..6a0b053c 100644 --- a/xo-expression2/src/expression2/DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/DIfElseExpr.cpp @@ -80,32 +80,6 @@ namespace xo { typeref_.resolve(td); } - bool - DIfElseExpr::pretty(const ppindentinfo & ppii) const - { - auto test - = FacetRegistry::instance().try_variant(test_); - auto when_true - = FacetRegistry::instance().try_variant(when_true_); - auto when_false - = FacetRegistry::instance().try_variant(when_false_); - - bool test_present = test; - bool when_true_present = when_true; - bool when_false_present = when_false; - - return ppii.pps()->pretty_struct - (ppii, - "DIfElseExpr", - refrtag("typeref", typeref_), - refrtag("test", test, test_present), - refrtag("when_true", when_true, when_true_present), - refrtag("when_false", when_false, when_false_present)); - } - // GCObject facet std::size_t @@ -145,6 +119,34 @@ namespace xo { return shallow_size(); } + // ----- printable facet ----- + + bool + DIfElseExpr::pretty(const ppindentinfo & ppii) const + { + auto test + = FacetRegistry::instance().try_variant(test_); + auto when_true + = FacetRegistry::instance().try_variant(when_true_); + auto when_false + = FacetRegistry::instance().try_variant(when_false_); + + bool test_present = test; + bool when_true_present = when_true; + bool when_false_present = when_false; + + return ppii.pps()->pretty_struct + (ppii, + "DIfElseExpr", + refrtag("typeref", typeref_), + refrtag("test", test, test_present), + refrtag("when_true", when_true, when_true_present), + refrtag("when_false", when_false, when_false_present)); + } + // ---------------------------------------------------------------- #ifdef NOPE diff --git a/xo-expression2/src/expression2/DLambdaExpr.cpp b/xo-expression2/src/expression2/DLambdaExpr.cpp index 080e49b5..56d55c03 100644 --- a/xo-expression2/src/expression2/DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/DLambdaExpr.cpp @@ -3,16 +3,16 @@ * @author Roland Conybeare, Jan 2026 **/ -#include "DLambdaExpr.hpp" -#include "detail/IExpression_DLambdaExpr.hpp" -#include "DLocalSymtab.hpp" -#include "symtab/IPrintable_DLocalSymtab.hpp" +#include "LambdaExpr.hpp" +#include "LocalSymtab.hpp" +#include "UniqueString.hpp" #include #include #include #include namespace xo { + using xo::mm::AGCObject; using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::reflect::TypeDescr; @@ -134,6 +134,49 @@ namespace xo { typeref_.resolve(td); } + std::size_t + DLambdaExpr::shallow_size() const noexcept { + return sizeof(DLambdaExpr); + } + + DLambdaExpr * + DLambdaExpr::shallow_copy(obj mm) const noexcept { + DLambdaExpr * copy = (DLambdaExpr *)mm.alloc_copy((std::byte *)this); + + if (copy) { + *copy = *this; + } + + return copy; + } + + std::size_t + DLambdaExpr::forward_children(obj gc) noexcept { + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&name_)); + } + + // type_name_str_ + + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&local_symtab_)); + } + + { + auto iface = body_expr_.to_facet().iface(); + gc.forward_inplace(iface, (void **)(&body_expr_)); + } + + // xxx free_var_set + // xxx captured_var_set + // xxx layer_var_map + // xxx nested_lambda_map + + return shallow_size(); + } + bool DLambdaExpr::pretty(const ppindentinfo & ppii) const { diff --git a/xo-expression2/src/expression2/DLocalSymtab.cpp b/xo-expression2/src/expression2/DLocalSymtab.cpp index 85631d34..cf9c8459 100644 --- a/xo-expression2/src/expression2/DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/DLocalSymtab.cpp @@ -3,13 +3,14 @@ * @author Roland Conybeare, Jan 2026 **/ -#include "DLocalSymtab.hpp" +#include "LocalSymtab.hpp" +#include "Variable.hpp" #include "DUniqueString.hpp" -#include #include #include namespace xo { + using xo::mm::AGCObject; using xo::print::APrintable; using xo::facet::typeseq; using xo::print::ppstate; @@ -77,6 +78,50 @@ namespace xo { return Binding(); } + // ----- gcobject facet ----- + + std::size_t + DLocalSymtab::shallow_size() const noexcept + { + return (sizeof(DLocalSymtab) + (capacity_ * sizeof(Slot))); + } + + DLocalSymtab * + DLocalSymtab::shallow_copy(obj mm) const noexcept + { + DLocalSymtab * copy = (DLocalSymtab *)mm.alloc_copy((std::byte *)this); + + if (copy) { + *copy = *this; + + ::memcpy((void*)&(copy->slots_[0]), + (void*)&(slots_[0]), + capacity_ * sizeof(Slot)); + } + + return copy; + } + + std::size_t + DLocalSymtab::forward_children(obj gc) noexcept + { + { + auto iface + = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&parent_)); + } + + auto iface + = xo::facet::impl_for(); + for (size_type i = 0; i < size_; ++i) { + gc.forward_inplace(&iface, (void **)(&(slots_[i].var_))); + } + + return shallow_size(); + } + + // ----- printable facet ----- + bool DLocalSymtab::pretty(const ppindentinfo & ppii) const { diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 67944a08..16bfac2a 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -17,28 +17,16 @@ #include #include - -#include -#include -#include - +#include #include - -#include -//#include -#include - -#include -#include -#include +#include +#include #include #include #include -#include -//#include -#include +#include #include #include @@ -70,6 +58,10 @@ namespace xo { // +- IfElseExpr // \- SequenceExpr + // SymbolTable + // +- LocalSymtab + // \- GlobalSymtab + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -91,7 +83,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); - //FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -103,7 +95,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); - //FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); log && log(xtag("DUniqueString.tseq", typeseq::id())); diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index b0b3c63a..7bda6388 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -127,6 +127,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/interpreter2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-localenv + FACET_PKG xo_printable2 + FACET Printable + REPR LocalEnv + INPUT idl/IPrintable_DLocalEnv.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + # ---------------------------------------------------------------- xo_add_genfacet_all(xo-interpreter2-genfacet-all) diff --git a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 new file mode 100644 index 00000000..0302834d --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DLocalEnv", + using_doxygen: true, + repr: "DLocalEnv", + doc: [ "implement APrintable for DLocalEnv" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp index 5563fb3a..234db71f 100644 --- a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp @@ -58,6 +58,12 @@ namespace xo { std::size_t forward_children(obj gc) noexcept; ///@} + /** @defgroup scm-localenv-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const noexcept; + + ///@} private: /** parent environment (from closure) **/ diff --git a/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp index a709e006..8955e35d 100644 --- a/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/LocalEnv.hpp @@ -7,6 +7,6 @@ #include "DLocalEnv.hpp" #include "detail/IGCObject_DLocalEnv.hpp" -//#include "detail/IPrintable_DLocalEnv.hpp" +#include "detail/IPrintable_DLocalEnv.hpp" /* end LocalEnv.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 1aebed2c..f28c5bef 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -216,6 +216,7 @@ namespace xo { * in execution **/ DLocalEnv * local_env_ = nullptr; + protected: // temporarily, to appease compiler /** environment pointer. Maintains bindings * for global variables. diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DLocalEnv.hpp new file mode 100644 index 00000000..c0ddb7f8 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DLocalEnv.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DLocalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLocalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLocalEnv.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DLocalEnv.hpp" + +namespace xo { namespace scm { class IPrintable_DLocalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DLocalEnv + **/ + class IPrintable_DLocalEnv { + public: + /** @defgroup scm-printable-dlocalenv-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dlocalenv-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DLocalEnv & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index e7493775..373f6138 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -17,10 +17,12 @@ set(SELF_SRCS IPrintable_DVsmApplyFrame.cpp DClosure.cpp - IGCObject_DClosure.cpp IProcedure_DClosure.cpp + IGCObject_DClosure.cpp + IPrintable_DClosure.cpp IGCObject_DLocalEnv.cpp + IPrintable_DLocalEnv.cpp DLocalEnv.cpp VsmInstr.cpp diff --git a/xo-interpreter2/src/interpreter2/DClosure.cpp b/xo-interpreter2/src/interpreter2/DClosure.cpp index b1868950..d1baa172 100644 --- a/xo-interpreter2/src/interpreter2/DClosure.cpp +++ b/xo-interpreter2/src/interpreter2/DClosure.cpp @@ -10,6 +10,7 @@ namespace xo { using xo::mm::AGCObject; + using xo::print::APrintable; namespace scm { @@ -69,6 +70,24 @@ namespace xo { return shallow_size(); } + // ----- printable facet ----- + + bool + DClosure::pretty(const ppindentinfo & ppii) const + { + obj lambda_pr(const_cast(lambda_)); + obj env_pr(const_cast(env_)); + + bool lambda_present = lambda_pr; + bool env_present = env_pr; + + return ppii.pps()->pretty_struct + (ppii, + "DClosure", + refrtag("lambda", lambda_pr, lambda_present), + refrtag("env", env_pr, env_present)); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp index 9ba65085..9ee0911a 100644 --- a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp @@ -121,6 +121,22 @@ namespace xo { return shallow_size(); } + // ----- printable facet ----- + + bool + DLocalEnv::pretty(const ppindentinfo & ppii) const noexcept + { + // print local bindings, perhaps + // symtab_ + // args_ + + return ppii.pps()->pretty_struct + (ppii, + "DLocalEnv", + refrtag("n_args", args_->size()) + ); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp new file mode 100644 index 00000000..bf701cb6 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DLocalEnv.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLocalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLocalEnv.json5] +**/ + +#include "detail/IPrintable_DLocalEnv.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DLocalEnv::pretty(const DLocalEnv & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DLocalEnv.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index bfd5e09f..c62a723f 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -241,10 +241,9 @@ namespace xo { lambda.data(), local_env_); - this->value_ = obj(obj(closure)); - - // not implemented - assert(false); + this->value_ + = obj(obj(closure)); + this->pc_ = this->cont_; } void diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index 1953bf1d..22757a48 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -8,6 +8,7 @@ #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "Closure.hpp" +#include "LocalEnv.hpp" #include #include @@ -37,9 +38,13 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // Procedure // +- Primitive_gco_2_gco_gco // \- Closure @@ -49,6 +54,7 @@ namespace xo { log && log(xtag("DVsmApplyFrame.tseq", typeseq::id())); log && log(xtag("DVsmEvalArgsFrame.tseq", typeseq::id())); log && log(xtag("DClosure.tseq", typeseq::id())); + log && log(xtag("DLocalEnv.tseq", typeseq::id())); return true; } diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 90805af7..ee4ca351 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -4,10 +4,11 @@ **/ #include -#include -#include -#include -#include +#include +#include +//#include +#include +//#include #ifdef NOT_YET #include @@ -28,6 +29,7 @@ namespace xo { using xo::scm::VirtualSchematikaMachine; using xo::scm::VsmConfig; using xo::scm::VsmResultExt; + using xo::scm::DClosure; using xo::scm::DFloat; using xo::scm::DInteger; using xo::mm::AGCObject; @@ -196,17 +198,17 @@ namespace xo { bool eof_flag = false; vsm.begin_interactive_session(); - VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("lambda (x : i64) -> i64 { x * x; };"), eof_flag); + VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("lambda (x : i64) -> i64 { x * x; }"), eof_flag); REQUIRE(res.is_value()); REQUIRE(res.value()); log && log(xtag("res.tseq", res.value()->_typeseq())); - auto x = obj::from(*res.value()); + auto x = obj::from(*res.value()); REQUIRE(x); - REQUIRE(x.data()->value() == 1.570796325); + //REQUIRE(x.data()->value() == 1.570796325); REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index 401524e0..cee62bca 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -1,5 +1,5 @@ /** @file DArray.cpp -* + * * @author Roland Conybeare, Jan 2026 **/ @@ -121,7 +121,9 @@ namespace xo { constexpr auto c_obj_z = sizeof(obj); /* memcpy sufficient for obj */ - ::memcpy((void*)&(copy->elts_[0]), (void*)&(elts_[0]), capacity_ * c_obj_z); + ::memcpy((void*)&(copy->elts_[0]), + (void*)&(elts_[0]), + capacity_ * c_obj_z); } return copy; From add1b018ac524a20053b49b27502116ebaa3b48d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 10 Feb 2026 15:14:40 -0500 Subject: [PATCH 169/258] xo-reader2 stack: parenthesized expressions [WIP] --- xo-reader2/CMakeLists.txt | 26 ++ xo-reader2/idl/IPrintable_DParenSsm.json5 | 13 + .../idl/ISyntaxStateMachine_DParenSsm.json5 | 13 + xo-reader2/include/xo/reader2/DDefineSsm.hpp | 11 +- .../include/xo/reader2/DExpectExprSsm.hpp | 6 + .../include/xo/reader2/DExprSeqState.hpp | 5 + xo-reader2/include/xo/reader2/DLambdaSsm.hpp | 6 + xo-reader2/include/xo/reader2/DParenSsm.hpp | 127 ++++++ xo-reader2/include/xo/reader2/LambdaSsm.hpp | 10 + xo-reader2/include/xo/reader2/ParenSsm.hpp | 12 + .../xo/reader2/ssm/IPrintable_DParenSsm.hpp | 62 +++ .../ssm/ISyntaxStateMachine_DParenSsm.hpp | 77 ++++ .../include/xo/reader2/syntaxstatetype.hpp | 3 + xo-reader2/src/reader2/CMakeLists.txt | 4 + xo-reader2/src/reader2/DDefineSsm.cpp | 1 - xo-reader2/src/reader2/DExpectExprSsm.cpp | 26 +- xo-reader2/src/reader2/DExprSeqState.cpp | 30 +- xo-reader2/src/reader2/DLambdaSsm.cpp | 40 +- xo-reader2/src/reader2/DParenSsm.cpp | 382 ++++++++++++++++++ .../src/reader2/IPrintable_DParenSsm.cpp | 28 ++ .../reader2/ISyntaxStateMachine_DParenSsm.cpp | 69 ++++ .../src/reader2/reader2_register_facets.cpp | 6 + xo-reader2/src/reader2/syntaxstatetype.cpp | 2 + xo-reader2/utest/SchematikaParser.test.cpp | 171 +++++++- 24 files changed, 1095 insertions(+), 35 deletions(-) create mode 100644 xo-reader2/idl/IPrintable_DParenSsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 create mode 100644 xo-reader2/include/xo/reader2/DParenSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/LambdaSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ParenSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DParenSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DParenSsm.hpp create mode 100644 xo-reader2/src/reader2/DParenSsm.cpp create mode 100644 xo-reader2/src/reader2/IPrintable_DParenSsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index c936619f..d1e807e6 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -114,6 +114,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-parenssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ParenSsm + INPUT idl/ISyntaxStateMachine_DParenSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-parenssm + FACET_PKG xo_printable2 + FACET Printable + REPR ParenSsm + INPUT idl/IPrintable_DParenSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-expectformalarglistssm diff --git a/xo-reader2/idl/IPrintable_DParenSsm.json5 b/xo-reader2/idl/IPrintable_DParenSsm.json5 new file mode 100644 index 00000000..495729b5 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DParenSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DParenSsm", + using_doxygen: true, + repr: "DParenSsm", + doc: [ "implement APrintable for DParenSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 new file mode 100644 index 00000000..521e7ba8 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DParenSsm", + using_doxygen: true, + repr: "DParenSsm", + doc: [ "implement ASyntaxStateMachine for DParenSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index d675090e..f71477dd 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -6,7 +6,6 @@ #pragma once #include "DSyntaxStateMachine.hpp" -//#include "SyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" #include #include @@ -36,7 +35,7 @@ namespace xo { * --on_singleassign_token()--> def_5 * def_3 --on_typedescr()--> def_4 * def_4 --on_singleassign_token()--> def_5 - * def_5 --on_expr()--> def_6 + * def_5 --on_parsed_expression()--> def_6 * def_6 --on_semicolon_token()--> (done) * * def_1:expect_symbol: got 'def' keyword, symbol to follow @@ -104,9 +103,10 @@ namespace xo { /** @defgroup scm-definessm-access-methods **/ ///@{ + /** identify this nested state machine **/ static const char * ssm_classname() { return "DDefineSsm"; } - /** identify this nested state machine **/ + /** internal state **/ defexprstatetype defstate() const noexcept { return defstate_; } ///@} @@ -193,6 +193,9 @@ namespace xo { ///@} private: + /** @defgroup scm-definessm-member-vars **/ + ///@{ + /** identify define-expression state **/ defexprstatetype defstate_; @@ -200,6 +203,8 @@ namespace xo { * This will eventually be the output of this ssm **/ obj def_expr_; + + ///@} }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 9b4bbd98..d6558c1e 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -76,6 +76,12 @@ namespace xo { void on_string_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming lambda token @p tk, + * overall parser state in @p p_psm + **/ + void on_lambda_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectexpr-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 72e26203..83448b5e 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -113,6 +113,11 @@ namespace xo { **/ void on_bool_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming leftparen token @p tk, + * overall parser state in @p p_psm + **/ + void on_leftparen_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on parsed expression @p expr * from nested ssm. * overall parser state in @p p_psm diff --git a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp index d494639c..5ecbecd2 100644 --- a/xo-reader2/include/xo/reader2/DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/DLambdaSsm.hpp @@ -96,6 +96,12 @@ namespace xo { void on_yields_token(const Token & tk, ParserStateMachine * p_psm); + /** update ssm on leftbrace token @p tk, + * with overall parser state in @p p_psm + **/ + void on_leftbrace_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-lambdassm-syntaxstatemachine-facet **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DParenSsm.hpp b/xo-reader2/include/xo/reader2/DParenSsm.hpp new file mode 100644 index 00000000..2ed7f58c --- /dev/null +++ b/xo-reader2/include/xo/reader2/DParenSsm.hpp @@ -0,0 +1,127 @@ +/** @file DParenSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include + +namespace xo { + namespace scm { + + /** + * @pre + * + * ( x * x ) + * ^ ^ ^ ^ + * | | | (done) + * | | | + * | | lparen_2 + * | lparen_1:expect expr + * lparen_0 + * + * lparen_0 --on_leftparen_token()--> lparen_1 + * lparen_1 --on_parsed_expression()--> lparen_2 + * lparen_2 --on_rightparen_token()--> (done) + * + * @endpre + **/ + + enum class parenexprstatetype { + invalid = -1, + + lparen_0, + lparen_1, + lparen_2, + + N, + }; + + extern const char * parenexprstatetype_descr(parenexprstatetype x); + + std::ostream & + operator<<(std::ostream & os, parenexprstatetype x); + + class DParenSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-parenssm-ctors **/ + ///@{ + + DParenSsm(); + + /** create instance using memory from @p parser_mm + **/ + static DParenSsm * make(DArena & parser_mm); + + /** push DParenSsm instance onto @p p_psm stack **/ + static void start(ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-parenssm-access-methods **/ + ///@{ + + /** identify this nested state machine **/ + static const char * ssm_classname() { return "DParenSsm"; } + + /** internal state **/ + parenexprstatetype parenstate() const noexcept { return parenstate_; } + + ///@} + /** @defgroup scm-parenssm-admin-methods admin methods **/ + ///@{ + + /** update ssm state for incoming leftparen token @p tk, + * with overall parser state in @p p_psm + **/ + void on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-parenssm-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies this ssm **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. **/ + std::string_view get_expect_str() const noexcept; + + /** update ssm for token @p tk, with overall state in @p p_psm **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-parenssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** @defgroup scm-parenssm-member-vars **/ + ///@{ + + /** identify paren-expression state **/ + parenexprstatetype parenstate_; + /** scaffold expression (representing parenthesized value) here **/ + obj expr_; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DParenSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/LambdaSsm.hpp b/xo-reader2/include/xo/reader2/LambdaSsm.hpp new file mode 100644 index 00000000..49ac731b --- /dev/null +++ b/xo-reader2/include/xo/reader2/LambdaSsm.hpp @@ -0,0 +1,10 @@ +/** @file LambdaSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DLambdaSsm.hpp" +#include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" +#include "ssm/IPrintable_DLambdaSsm.hpp" + +/* end LambdaSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParenSsm.hpp b/xo-reader2/include/xo/reader2/ParenSsm.hpp new file mode 100644 index 00000000..a9a786fd --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParenSsm.hpp @@ -0,0 +1,12 @@ +/** @file ParenSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DParenSsm.hpp" +#include "ssm/ISyntaxStateMachine_DParenSsm.hpp" +#include "ssm/IPrintable_DParenSsm.hpp" + +/* end ParenSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DParenSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DParenSsm.hpp new file mode 100644 index 00000000..2b4b49c2 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DParenSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DParenSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DParenSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DParenSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DParenSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DParenSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DParenSsm + **/ + class IPrintable_DParenSsm { + public: + /** @defgroup scm-printable-dparenssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dparenssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DParenSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DParenSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DParenSsm.hpp new file mode 100644 index 00000000..33be5e16 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DParenSsm.hpp @@ -0,0 +1,77 @@ +/** @file ISyntaxStateMachine_DParenSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DParenSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DParenSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DParenSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DParenSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DParenSsm + **/ + class ISyntaxStateMachine_DParenSsm { + public: + /** @defgroup scm-syntaxstatemachine-dparenssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dparenssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DParenSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DParenSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DParenSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DParenSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DParenSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DParenSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DParenSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DParenSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DParenSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index a5b4b563..3031a444 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -33,6 +33,9 @@ namespace xo { /** rhs expression. state exists to achieve 1-token lookahead **/ progress, + /** expression enclosed in parentheses. See @ref DParenSsm **/ + paren, + /** toplevel of some translation unit. See @ref DExprSeqState **/ expect_toplevel_expression_sequence, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index d883fa82..4a813900 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -37,6 +37,10 @@ set(SELF_SRCS ISyntaxStateMachine_DLambdaSsm.cpp IPrintable_DLambdaSsm.cpp + DParenSsm.cpp + ISyntaxStateMachine_DParenSsm.cpp + IPrintable_DParenSsm.cpp + DExpectFormalArglistSsm.cpp ISyntaxStateMachine_DExpectFormalArglistSsm.cpp IPrintable_DExpectFormalArglistSsm.cpp diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 26a68224..2d2ecb0b 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -555,7 +555,6 @@ namespace xo { case tokentype::tk_end: case tokentype::N: break; - return; } Super::on_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index c3cb4b31..c763e2a4 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -8,6 +8,7 @@ #include "SyntaxStateMachine.hpp" #include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" #include "DSequenceSsm.hpp" +#include "LambdaSsm.hpp" #include "syntaxstatetype.hpp" #include #include @@ -138,6 +139,10 @@ namespace xo { this->on_bool_token(tk, p_psm); return; + case tokentype::tk_lambda: + this->on_lambda_token(tk, p_psm); + return; + // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_if: @@ -165,7 +170,6 @@ namespace xo { case tokentype::tk_cmpeq: case tokentype::tk_cmpne: case tokentype::tk_type: - case tokentype::tk_lambda: case tokentype::tk_then: case tokentype::tk_else: case tokentype::tk_let: @@ -379,6 +383,15 @@ namespace xo { p_psm); } + void + DExpectExprSsm::on_lambda_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DLambdaSsm::start(p_psm); + } + void DExpectExprSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) @@ -412,17 +425,6 @@ namespace xo { } #ifdef NOT_YET - void - expect_expr_xs::on_lambda_token(const token_type & /*tk*/, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - //constexpr const char * self_name = "exprstate::on_leftparen"; - - lambda_xs::start(p_psm); - } - void expect_expr_xs::on_if_token(const token_type & /*tk*/, parserstatemachine * p_psm) diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 08094655..82eb2f44 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -1,5 +1,5 @@ /** @file DExprSeqState.cpp -* + * * @author Roland Conybeare, Jan 2026 **/ @@ -9,6 +9,8 @@ #include "DLambdaSsm.hpp" #include "DProgressSsm.hpp" #include "DIfElseSsm.hpp" +#include "ParenSsm.hpp" +#include "ExpectExprSsm.hpp" #include #include @@ -152,9 +154,12 @@ namespace xo { this->on_bool_token(tk, p_psm); return; + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + // all the not-yet handled cases case tokentype::tk_invalid: - case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: @@ -389,6 +394,27 @@ namespace xo { Super::on_token(tk, p_psm); } + void + DExprSeqState::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: { + DParenSsm::start(p_psm); + p_psm->on_token(Token::leftparen_token()); + + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::on_token(tk, p_psm); + } + void DExprSeqState::on_parsed_expression(obj expr, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index 286fcfa5..a2c2dfbd 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -136,6 +136,10 @@ namespace xo { this->on_yields_token(tk, p_psm); return; + case tokentype::tk_leftbrace: + this->on_leftbrace_token(tk, p_psm); + return; + // all the not-yet-handled cases case tokentype::tk_def: case tokentype::tk_if: @@ -152,7 +156,6 @@ namespace xo { case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: - case tokentype::tk_leftbrace: case tokentype::tk_rightbrace: case tokentype::tk_leftangle: case tokentype::tk_rightangle: @@ -179,11 +182,6 @@ namespace xo { } Super::on_token(tk, p_psm); -#ifdef OBSOLETE - p_psm->illegal_input_on_token("DLambdaSsm::on_token", - tk, - this->get_expect_str()); -#endif } void @@ -199,11 +197,6 @@ namespace xo { } Super::on_token(tk, p_psm); -#ifdef OBSOLETE - p_psm->illegal_input_on_token("DLambdaSsm::on_lambda_token", - tk, - this->get_expect_str()); -#endif } void @@ -220,13 +213,28 @@ namespace xo { } Super::on_token(tk, p_psm); -#ifdef OBSOLETE - p_psm->illegal_input_on_token("DLambdaSsm::on_yields_token", - tk, - this->get_expect_str()); -#endif } + void + DLambdaSsm::on_leftbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (lmstate_ == lambdastatetype::lm_2) { + // control here when leftbrace immediately follows + // formal param list. + // Otherwise leftbrace arrives in DExpectExprSsm + // pushed via on_parsed_typedescr() + + this->lmstate_ = lambdastatetype::lm_4; + + DExpectExprSsm::start(p_psm); + // precharge ssm for body with leftbrace + p_psm->on_token(Token::leftbrace_token()); + return; + } + + Super::on_token(tk, p_psm); + } void DLambdaSsm::on_parsed_typedescr(TypeDescr td, diff --git a/xo-reader2/src/reader2/DParenSsm.cpp b/xo-reader2/src/reader2/DParenSsm.cpp new file mode 100644 index 00000000..166e96bf --- /dev/null +++ b/xo-reader2/src/reader2/DParenSsm.cpp @@ -0,0 +1,382 @@ +/** @file DParenSsm.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "ParenSsm.hpp" +#include "syntaxstatetype.hpp" +#include + +namespace xo { + using xo::facet::with_facet; + using xo::facet::typeseq; + + namespace scm { + + extern const char * + parenexprstatetype_descr(parenexprstatetype x) + { + switch(x) { + case parenexprstatetype::invalid: return "invalid"; + case parenexprstatetype::lparen_0: return "lparen_0"; + case parenexprstatetype::lparen_1: return "lparen_1"; + case parenexprstatetype::lparen_2: return "lparen_2"; + case parenexprstatetype::N: break; + } + + return "???parenexprstatetype"; + } + + std::ostream & + operator<<(std::ostream & os, parenexprstatetype x) { + os << parenexprstatetype_descr(x); + return os; + } + + DParenSsm::DParenSsm() + : parenstate_(parenexprstatetype::lparen_0), + expr_{} + {} + + DParenSsm * + DParenSsm::make(DArena & mm) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DParenSsm)); + + return new (mem) DParenSsm(); + } + + void + DParenSsm::start(ParserStateMachine * p_psm) + { + DParenSsm * paren_ssm = DParenSsm::make(p_psm->parser_alloc()); + + auto ssm = with_facet::mkobj(paren_ssm); + + p_psm->push_ssm(ssm); + } + + syntaxstatetype + DParenSsm::ssm_type() const noexcept + { + return syntaxstatetype::paren; + } + + std::string_view + DParenSsm::get_expect_str() const noexcept + { + switch (this->parenstate_) { + case parenexprstatetype::invalid: + case parenexprstatetype::N: + break; + case parenexprstatetype::lparen_0: return "lparen_0"; + case parenexprstatetype::lparen_1: return "lparen_1"; + case parenexprstatetype::lparen_2: return "lparen_2"; + } + + return "???parenexprstatetype"; + } + + void + DParenSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (tk.tk_type()) { + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + // all the not-yet handled cases + case tokentype::tk_symbol: + case tokentype::tk_def: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_semicolon: + case tokentype::tk_invalid: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_if: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + Super::on_token(tk, p_psm); + } + + void + DParenSsm::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + Super::on_token(tk, p_psm); + } + +#ifdef OBSOLETE + void + paren_xs::start(parserstatemachine * p_psm) + { + p_psm->push_exprstate(paren_xs::make()); + expect_expr_xs::start(p_psm); + } + + bool + paren_xs::admits_rightparen() const { + switch (parenxs_type_) { + case parenexprstatetype::lparen_0: + /* unreachable */ + assert(false); + return false; + + case parenexprstatetype::lparen_1: + return true; + + case parenexprstatetype::invalid: + case parenexprstatetype::n_parenexprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + + bool + paren_xs::admits_f64() const { + switch (parenxs_type_) { + case parenexprstatetype::lparen_0: + return true; + + case parenexprstatetype::lparen_1: + return false; + + case parenexprstatetype::invalid: + case parenexprstatetype::n_parenexprstatetype: + /* unreachable */ + assert(false); + return false; + } + + return false; + } + + void + paren_xs::on_def_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr const char * c_self_name = "paren_xs::on_def"; + + this->illegal_input_error(c_self_name, tk); + } + + void + paren_xs::on_symbol_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", p_psm->top_exprstate().exs_type())); + + //constexpr const char * self_name = "paren_xs::on_symbol"; + + /* TODO: lparen_0: treat as variable reference */ + + assert(false); + } + + void + paren_xs::on_typedescr(TypeDescr /*td*/, + parserstatemachine * /*p_psm*/) + { + assert(false); + return; + } + + void + paren_xs::on_colon_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr const char * c_self_name = "paren_xs::on_colon"; + + this->illegal_input_error(c_self_name, tk); + } + + void + paren_xs::on_semicolon_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr const char * c_self_name = "paren_xs::on_semicolon"; + + this->illegal_input_error(c_self_name, tk); + } + + void + paren_xs::on_singleassign_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr const char * c_self_name = "paren_xs::on_singleassign"; + + this->illegal_input_error(c_self_name, tk); + } + + void + paren_xs::on_leftparen_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr const char * c_self_name = "paren_xs::on_leftparen"; + + this->illegal_input_error(c_self_name, tk); + } + + void + paren_xs::on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * c_self_name = "paren_xs::on_rightparen"; + + if (!this->admits_rightparen()) + { + this->illegal_input_error(c_self_name, tk); + } + + if (this->parenxs_type_ == parenexprstatetype::lparen_1) { + rp expr = this->gen_expr_; + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->top_exprstate().on_expr(expr, p_psm); + } + } + + void + paren_xs::on_i64_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * c_self_name = "paren_xs::on_i64"; + + this->illegal_input_error(c_self_name, tk); + } + + void + paren_xs::on_f64_token(const token_type & tk, + parserstatemachine * /*p_psm*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * c_self_name = "paren_xs::on_f64"; + + this->illegal_input_error(c_self_name, tk); + } + + void + paren_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("expr", expr)); + + switch (this->parenxs_type_) { + case parenexprstatetype::lparen_0: { + this->parenxs_type_ = parenexprstatetype::lparen_1; /* wants on_rightparen */ + progress_xs::start(expr.promote(), p_psm); + + return; + } + + case parenexprstatetype::lparen_1: { + this->gen_expr_ = expr.promote(); + + /* expect immediate incoming call, this time to on_rightparen() */ + return; + } + + default: + /* unreachable */ + assert(false); + return; + } + } /*on_expr*/ + + void + paren_xs::on_symbol(const std::string & /*symbol_name*/, + parserstatemachine * /*p_psm*/) + { + switch(this->parenxs_type_) { + case parenexprstatetype::lparen_0: + case parenexprstatetype::lparen_1: + /* NOT IMPLEMENTED */ + assert(false); + return; + + default: + /* unreachable */ + assert(false); + return; + } + } + + void + paren_xs::print(std::ostream & os) const { + os << ""; + } +#endif + + bool + DParenSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DParenSsm", + refrtag("parenstate", parenstate_), + refrtag("expect", this->get_expect_str())); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DParenSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DParenSsm.cpp b/xo-reader2/src/reader2/IPrintable_DParenSsm.cpp new file mode 100644 index 00000000..b2228f7f --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DParenSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DParenSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DParenSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DParenSsm.json5] +**/ + +#include "ssm/IPrintable_DParenSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DParenSsm::pretty(const DParenSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DParenSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp new file mode 100644 index 00000000..1bb2ea83 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp @@ -0,0 +1,69 @@ +/** @file ISyntaxStateMachine_DParenSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DParenSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DParenSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DParenSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DParenSsm::ssm_type(const DParenSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DParenSsm::get_expect_str(const DParenSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DParenSsm::on_token(DParenSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DParenSsm::on_parsed_symbol(DParenSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DParenSsm::on_parsed_typedescr(DParenSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DParenSsm::on_parsed_formal(DParenSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DParenSsm::on_parsed_formal_arglist(DParenSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DParenSsm::on_parsed_expression(DParenSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DParenSsm::on_parsed_expression_with_token(DParenSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DParenSsm.cpp */ diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index ef584c44..3955fae3 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -19,6 +19,8 @@ #include +#include "ParenSsm.hpp" + #include #include @@ -85,6 +87,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); log && log(xtag("DLambdaSsm.tseq", typeseq::id())); @@ -95,6 +100,7 @@ namespace xo { log && log(xtag("DExpectTypeSsm.tseq", typeseq::id())); log && log(xtag("DExpectExprSsm.tseq", typeseq::id())); log && log(xtag("DProgressSsm.tseq", typeseq::id())); + log && log(xtag("DParenSsm.tseq", typeseq::id())); log && log(xtag("ASyntaxStateMachine.tseq", typeseq::id())); return true; diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index aff0a87c..18acb000 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -23,6 +23,8 @@ namespace xo { return "sequence"; case syntaxstatetype::progress: return "progress"; + case syntaxstatetype::paren: + return "paren"; case syntaxstatetype::expect_toplevel_expression_sequence: return "expect-toplevel-expression-sequence"; case syntaxstatetype::expect_formal_arglist: diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 740d71f4..870cabd1 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -836,7 +836,7 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-lambda2", "[reader2][SchematikaParser]") { - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag)); ArenaConfig config; @@ -1014,6 +1014,175 @@ namespace xo { } } + + TEST_CASE("SchematikaParser-interactive-apply", "[reader2][SchematikaParser]") + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * (lambda (x : i64) { x * x })(13); + * + **/ + + { + auto & result = parser.on_token(Token::leftparen_token()); + + log && log("after lparen token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::lambda_token()); + + log && log("after lambda token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::leftparen_token()); + + log && log("after lparen token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("x")); + + log && log("after symbol(x) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::colon_token()); + + log && log("after colon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("i64")); + + log && log("after symbol(i64) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::rightparen_token()); + + log && log("after rightparen token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::leftbrace_token()); + + log && log("after leftbrace token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("x")); + + log && log("after symbol(x) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::star_token()); + + log && log("after star(*) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::symbol_token("x")); + + log && log("after symbol(x) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::rightbrace_token()); + + log && log("after rightbrace(}) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } + + } } /*namespace ut*/ } /*namespace xo*/ From 00dc45db9f95bdce85ac028084d41cce99fdd3f3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 10 Feb 2026 23:28:20 -0500 Subject: [PATCH 170/258] xo-reader2 stack: progress towards recognizing function calls [WIP] --- .../include/xo/reader2/DExpectExprSsm.hpp | 4 +- xo-reader2/include/xo/reader2/DParenSsm.hpp | 12 +++ .../include/xo/reader2/DProgressSsm.hpp | 39 +++++--- xo-reader2/include/xo/reader2/ProgressSsm.hpp | 12 +++ xo-reader2/src/reader2/DExprSeqState.cpp | 10 +- xo-reader2/src/reader2/DParenSsm.cpp | 67 ++++++++++++- xo-reader2/src/reader2/DProgressSsm.cpp | 95 +++++++++++++++++-- xo-reader2/src/reader2/ParserStateMachine.cpp | 4 +- xo-reader2/utest/SchematikaParser.test.cpp | 28 +++++- 9 files changed, 234 insertions(+), 37 deletions(-) create mode 100644 xo-reader2/include/xo/reader2/ProgressSsm.hpp diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index d6558c1e..473a89d3 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -27,11 +27,11 @@ namespace xo { static DExpectExprSsm * make(DArena & parser_mm, bool allow_defs, - bool cxl_on_rightparen); + bool cxl_on_rightbrace); static void start(DArena & parser_mm, bool allow_defs, - bool cxl_on_rightparen, + bool cxl_on_rightbrace, ParserStateMachine * p_psm); static void start(ParserStateMachine * p_psm); diff --git a/xo-reader2/include/xo/reader2/DParenSsm.hpp b/xo-reader2/include/xo/reader2/DParenSsm.hpp index 2ed7f58c..6f359b65 100644 --- a/xo-reader2/include/xo/reader2/DParenSsm.hpp +++ b/xo-reader2/include/xo/reader2/DParenSsm.hpp @@ -87,6 +87,12 @@ namespace xo { void on_leftparen_token(const Token & tk, ParserStateMachine * p_psm); + /** update ssm state for incoming rightparen token @p tk + * with overall parser state in @p p_psm + **/ + void on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-parenssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -101,6 +107,12 @@ namespace xo { void on_token(const Token & tk, ParserStateMachine * p_psm); + /** update ssm for expression @p expr (emitted by nested ssm), + * with overall parser state in @p p_psm + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-parenssm-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 3b9dff6f..47ca29b9 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -100,6 +100,8 @@ namespace xo { obj lhs, optype op); + static void start(DArena & parser_mm, + ParserStateMachine * p_psm); static void start(DArena & parser_mm, obj lhs, ParserStateMachine * p_psm); @@ -132,21 +134,9 @@ namespace xo { /** @defgroup scm-progressssm-methods general methods **/ ///@{ - /** token belongs to surrounding syntax, - * -> lock in current progress - **/ - void on_completing_token(const Token & tk, - ParserStateMachine * p_psm); - - ///@} - /** @defgroup scm-progressssm-ssm-facet syntaxstatemachine facet methods **/ - /// @{ - - /** operate state machine for this syntax on incoming token @p tk - * with overall parser state in @p p_psm - **/ - void on_token(const Token & tk, - ParserStateMachine * p_psm); + /** handle leftparen token @p tk. Overall parser state in @p p_psm **/ + void on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm); void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); @@ -168,6 +158,25 @@ namespace xo { ParserStateMachine * p_psm); void on_rightbrace_token(const Token & tk, ParserStateMachine * p_psm); + + /** token belongs to surrounding syntax, + * -> lock in current progress + **/ + void on_completing_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-progressssm-ssm-facet syntaxstatemachine facet methods **/ + /// @{ + + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); void on_parsed_expression_with_token(obj expr, const Token & tk, ParserStateMachine * p_psm); diff --git a/xo-reader2/include/xo/reader2/ProgressSsm.hpp b/xo-reader2/include/xo/reader2/ProgressSsm.hpp new file mode 100644 index 00000000..150c60d9 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ProgressSsm.hpp @@ -0,0 +1,12 @@ +/** @file ProgressSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DProgressSsm.hpp" +#include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" +#include "ssm/IPrintable_DProgressSsm.hpp" + +/* end ProgressSsm.hpp */ diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 82eb2f44..1d9b38a3 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -7,7 +7,7 @@ #include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" #include "DDefineSsm.hpp" #include "DLambdaSsm.hpp" -#include "DProgressSsm.hpp" +#include "ProgressSsm.hpp" #include "DIfElseSsm.hpp" #include "ParenSsm.hpp" #include "ExpectExprSsm.hpp" @@ -400,7 +400,13 @@ namespace xo { { switch (seqtype_) { case exprseqtype::toplevel_interactive: { - DParenSsm::start(p_psm); + // not sufficient to just start a paren-ssm here. + // we want to parse toplevel input like + // (getfunction())(); + // just as C would. + // To wait for token following right paren, use a progress-ssm + + DProgressSsm::start(p_psm->parser_alloc(), p_psm); p_psm->on_token(Token::leftparen_token()); return; diff --git a/xo-reader2/src/reader2/DParenSsm.cpp b/xo-reader2/src/reader2/DParenSsm.cpp index 166e96bf..972d503a 100644 --- a/xo-reader2/src/reader2/DParenSsm.cpp +++ b/xo-reader2/src/reader2/DParenSsm.cpp @@ -4,6 +4,7 @@ **/ #include "ParenSsm.hpp" +#include "ExpectExprSsm.hpp" #include "syntaxstatetype.hpp" #include @@ -70,9 +71,9 @@ namespace xo { case parenexprstatetype::invalid: case parenexprstatetype::N: break; - case parenexprstatetype::lparen_0: return "lparen_0"; - case parenexprstatetype::lparen_1: return "lparen_1"; - case parenexprstatetype::lparen_2: return "lparen_2"; + case parenexprstatetype::lparen_0: return "leftparen"; + case parenexprstatetype::lparen_1: return "expression"; + case parenexprstatetype::lparen_2: return "rightparen"; } return "???parenexprstatetype"; @@ -83,9 +84,15 @@ namespace xo { ParserStateMachine * p_psm) { switch (tk.tk_type()) { + case tokentype::tk_leftparen: this->on_leftparen_token(tk, p_psm); return; + + case tokentype::tk_rightparen: + this->on_rightparen_token(tk, p_psm); + return; + // all the not-yet handled cases case tokentype::tk_symbol: case tokentype::tk_def: @@ -98,7 +105,6 @@ namespace xo { case tokentype::tk_i64: case tokentype::tk_bool: case tokentype::tk_if: - case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: case tokentype::tk_leftbrace: @@ -136,6 +142,25 @@ namespace xo { DParenSsm::on_leftparen_token(const Token & tk, ParserStateMachine * p_psm) { + if (parenstate_ == parenexprstatetype::lparen_0) { + this->parenstate_ = parenexprstatetype::lparen_1; + + /** 1. allow_defs=false not allowing definitions immediately + * within a parenthesized expression. + * e.g. + * (def y : i64 = 4; x + y) // nope + * 2. cxl_on_rightparen=false expression _must_ be followed + * by rightparen. empty parentheses '()' + * do not denote anything, in expression context + **/ + DExpectExprSsm::start(p_psm->parser_alloc(), + false /*!allow_defs*/, + false /*cx_on_rightbrace*/, + p_psm); + + return; + } + Super::on_token(tk, p_psm); } @@ -255,7 +280,24 @@ namespace xo { this->illegal_input_error(c_self_name, tk); } +#endif + void + DParenSsm::on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (this->parenstate_ == parenexprstatetype::lparen_2) { + // parenthesized expression successfully parsed + + p_psm->pop_ssm(); + p_psm->on_parsed_expression(this->expr_); + return; + } + + Super::on_token(tk, p_psm); + } + +#ifdef NOT_YET void paren_xs::on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) @@ -302,7 +344,24 @@ namespace xo { this->illegal_input_error(c_self_name, tk); } +#endif + void + DParenSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + if (parenstate_ == parenexprstatetype::lparen_1) { + this->parenstate_ = parenexprstatetype::lparen_2; + this->expr_ = expr; + + return; + } + + Super::on_parsed_expression(expr, p_psm); + + } + +#ifdef NOT_YET void paren_xs::on_expr(bp expr, parserstatemachine * p_psm) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 751264dd..d774c269 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -9,6 +9,8 @@ #include "DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" +#include "ParenSsm.hpp" + #include #include @@ -185,6 +187,13 @@ namespace xo { start(parser_mm, lhs, optype::invalid, p_psm); } + void + DProgressSsm::start(DArena & parser_mm, + ParserStateMachine * p_psm) + { + start(parser_mm, obj(), p_psm); + } + DProgressSsm::DProgressSsm(obj valex, optype op) : lhs_{valex}, @@ -204,10 +213,12 @@ namespace xo { std::string_view DProgressSsm::get_expect_str() const noexcept { - if (op_type_ == optype::invalid) { + if (!lhs_) { + return "expr1|leftparen"; + } else if (op_type_ == optype::invalid) { return "oper|semicolon|rightparen|righbrace"; } else { - return "expr|leftparen"; + return "expr2|leftparen"; } } @@ -259,11 +270,14 @@ namespace xo { this->on_rightbrace_token(tk, p_psm); return; + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_def: case tokentype::tk_if: - case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: @@ -483,13 +497,48 @@ namespace xo { p_psm->on_parsed_expression_with_token(expr, tk); } + void + DProgressSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + const bool c_debug_flag = p_psm->debug_flag() || true; + + scope log(XO_DEBUG(c_debug_flag)); + + if (!lhs_) { + log && log("accepting expr1"); + + this->lhs_ = expr; + return; + } + + Super::on_parsed_expression(expr, p_psm); + } + void DProgressSsm::on_parsed_expression_with_token(obj expr, const Token & tk, ParserStateMachine * p_psm) { - scope log(XO_DEBUG(p_psm->debug_flag()), - xtag("expr", expr)); + const bool c_debug_flag = p_psm->debug_flag() || true; + + scope log(XO_DEBUG(c_debug_flag), + xtag("expr", expr), + xtag("tk", tk)); + +#ifdef NOT_YET + if (!lhs_) { + log && log("DProgressSsm: accepting expr1"); + + this->lhs_ = expr; + + // now we have to handle tk! + + return; + } +#endif + + // here: have lhs_ expression if (op_type_ == optype::invalid) { // e.g. control here on input like @@ -499,6 +548,7 @@ namespace xo { ("DProgressSsm::on_parsed_expression_with_token", expr, this->get_expect_str()); + return; } @@ -847,7 +897,32 @@ namespace xo { { this->on_operator_token(tk, p_psm); } +#endif + void + DProgressSsm::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (!lhs_) { + // leftparen begins possible lhs expression + DParenSsm::start(p_psm); + + p_psm->on_token(Token::leftparen_token()); + return; + } + + if (optype_ == optype::invalid) { + // leftparen begins function call arguments. + // .lhs_ now understood to be expression that evaluates to a + // function + + + } + + Super::on_token(tk, p_psm); + } + +#ifdef NOT_YET /* editor bait: on_lparen */ void progress_xs::on_leftparen_token(const token_type & tk, @@ -885,8 +960,8 @@ namespace xo { return; } - constexpr const char * c_self_name = "exprstate::on_leftparen"; const char * exp = get_expect_str(); + constexpr const char * c_self_name = "exprstate::on_leftparen"; this->illegal_input_on_token(c_self_name, tk, exp, p_psm); } @@ -1023,18 +1098,20 @@ namespace xo { log && log(xtag("rhs_.tseq", rhs_._typeseq())); obj lhs - = FacetRegistry::instance().variant(lhs_); + = FacetRegistry::instance().try_variant(lhs_); obj rhs = FacetRegistry::instance().try_variant(rhs_); + bool lhs_present = lhs; bool rhs_present = rhs; + bool op_present = (op_type_ != optype::invalid); return ppii.pps()->pretty_struct (ppii, "DProgressSsm", - refrtag("lhs", lhs), - refrtag("op", op_type_), + refrtag("lhs", lhs, lhs_present), + refrtag("op", op_type_, op_present), refrtag("rhs", rhs, rhs_present), refrtag("expect", this->get_expect_str()) ); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 56a4560c..58119789 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -426,8 +426,8 @@ namespace xo { // - want to write error message using DArena // - need something like log_streambuf and/or tostr() that's arena-aware - obj expr_pr - = FacetRegistry::instance().variant(expr); + auto expr_pr = expr.to_facet(); + //= FacetRegistry::instance().variant(expr); assert(expr_pr); /** TODO diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 870cabd1..77d9471c 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -1176,12 +1176,34 @@ namespace xo { log && log(xtag("parser", &parser)); log && log(xtag("result", result)); - REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(!result.is_error()); - REQUIRE(result.is_expression()); - REQUIRE(result.result_expr()); + REQUIRE(result.is_incomplete()); } + { + auto & result = parser.on_token(Token::rightparen_token()); + + log && log("after rightparen token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::leftparen_token()); + + log && log("after leftparen token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } } } /*namespace ut*/ } /*namespace xo*/ From a79f4aef2b7ecf0327c5a752dc52ad809c6336f3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 11 Feb 2026 16:02:41 -0500 Subject: [PATCH 171/258] xo-reader2: DApplySsm for apply expressions [WIP] --- xo-reader2/include/xo/reader2/DApplySsm.hpp | 165 +++++++++++++ xo-reader2/include/xo/reader2/DDefineSsm.hpp | 4 +- .../include/xo/reader2/syntaxstatetype.hpp | 5 +- xo-reader2/src/reader2/CMakeLists.txt | 4 + xo-reader2/src/reader2/DApplySsm.cpp | 221 ++++++++++++++++++ xo-reader2/src/reader2/DProgressSsm.cpp | 7 +- xo-reader2/src/reader2/syntaxstatetype.cpp | 2 + 7 files changed, 402 insertions(+), 6 deletions(-) create mode 100644 xo-reader2/include/xo/reader2/DApplySsm.hpp create mode 100644 xo-reader2/src/reader2/DApplySsm.cpp diff --git a/xo-reader2/include/xo/reader2/DApplySsm.hpp b/xo-reader2/include/xo/reader2/DApplySsm.hpp new file mode 100644 index 00000000..34c78f78 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DApplySsm.hpp @@ -0,0 +1,165 @@ +/** @file DApplySsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +//#include +#include + + +namespace xo { + namespace scm { + /** + * fn ( arg1 , arg2 , .. , argn ) + * ^ ^ ^ ^ ^ ^ ^ ^ ^ + * | | | | | | | | (done) + * | | | | | | | apply_3 + * | | | | | | apply_2:expect_rhs_expression + * | | | | | apply_3 + * | | | | apply_2:expect_rhs_expression + * | | | apply_3 + * | | apply_2:expect_rhs_expression + * | apply_1 + * apply_0:expect_rhs_expression + * + * apply_0 --on_expr()--> apply_1 + * apply_1 --on_leftparen()--> apply_2 + * apply_2 --on_expr()--> apply_3 + * apply_3 --on_comma()--> apply_2 + * --on_rightparen()-> (done) + * + * apply_0: start + * apply_1: leftparen following expr allows parser to recognize apply + * apply_2: expect next argument + * apply_3: got argument, expect comma or rightparen to continue + * (done): apply complete, pop exprstate from stack + * + * In practice will start in state apply_1 + **/ + enum class applyexprstatetype { + invalid = -1, + + apply_0, + apply_1, + apply_2, + apply_3, + + N + }; + + extern const char * applyexprstatetype_descr(applyexprstatetype x); + + std::ostream & + operator<<(std::ostream & os, applyexprstatetype x); + + /** @class DApplySsm + * @brief state machine for parsing a schematika function-call-expression + **/ + class DApplySsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + //using Apply = xo::scm::Apply; + + public: + /** @defgroup scm-applyssm-ctors constructors **/ + ///@{ + + /** construct apply ssm with @p fn_expr + * supplying function to be invoked. + * + * Expect during parsing of input like f(...) + * that we parse f before parser knows that it will be + * followed by leftparen + **/ + explicit DApplySsm(obj fn_expr); + + /** create instance using memory from @p parser_mm. + * with function to be called supplied by @p fn_expr. + **/ + static DApplySsm * make(DArena & parser_mm, + obj fn_expr); + +#ifdef NOT_YET + /** + * Start apply. Will trigger this after input like + * "fn(" + * + * apply_xs remains on expr stack until closing right paren + * fn(arg1-expr, arg2-expr, ...) + * + * @p fnex expression in function position + * @p p_psm parser state machine + **/ + static void start(rp fnex, + parserstatemachine * p_psm); +#endif + + ///@} + /** @defgroup scm-applyssm-access methods **/ + ///@{ + + /** identify this nested state machine **/ + static const char * ssm_classname() { return "DApplySsm"; } + + /** current internal state **/ + applyexprstatetype applystate() const noexcept { return applystate_; } + + ///@} + /** @defgroup ssm-applyssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** mnemonic for expected remaining syntax for current parsing state **/ + std::string_view get_expect_str() const noexcept; + +#ifdef NOT_YET + + virtual void on_expr(bp expr, + parserstatemachine * p_psm) override; + + virtual void on_comma_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_leftparen_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) override; + + virtual void print(std::ostream & os) const override; + virtual bool pretty_print(const print::ppindentinfo & ppii) const final override; + + private: + static std::unique_ptr make(); +#endif + + private: + /** current state of parser for this apply expression **/ + applyexprstatetype applystate_ = applyexprstatetype::apply_0; + /** evaluates to function to be invoked **/ + obj fn_expr_; +#ifdef NOT_YET + /** evaluates to the arguments to pass to @ref fn_ **/ + std::vector> args_expr_v_; +#endif + }; + } /*namespace scm */ + + namespace print { +#ifndef ppdetail_atomic + PPDETAIL_ATOMIC(xo::scm::applyexprstatetype); +#endif + } +} /*namespace xo*/ + +/* end DApplySsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index f71477dd..d42246ef 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -78,7 +78,7 @@ namespace xo { using ppindentinfo = xo::print::ppindentinfo; public: - /** @defgroup scm-define-ssm-facet constructors **/ + /** @defgroup scm-definessm-ctors constructors **/ ///@{ /** constructor; using @p def_expr for initial expression scaffold **/ @@ -110,7 +110,7 @@ namespace xo { defexprstatetype defstate() const noexcept { return defstate_; } ///@} - /** @defgroup scm-define-ssm-facet syntaxstatemachine facet methods **/ + /** @defgroup scm-definessm-facet syntaxstatemachine facet methods **/ ///@{ /** identifies the ssm implemented here **/ diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 3031a444..147b7770 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -27,9 +27,12 @@ namespace xo { /** handle ifelse-expression. See @ref DIfElseSsm **/ ifelseexpr, - /** handle sequence-expression. See @ref DSequenceSsm **/ + /** handle sequence-expression syntax. See @ref DSequenceSsm **/ sequence, + /** handle apply-expression syntax. See @ref DApplySsm **/ + apply, + /** rhs expression. state exists to achieve 1-token lookahead **/ progress, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 4a813900..b6d9bed0 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -37,6 +37,10 @@ set(SELF_SRCS ISyntaxStateMachine_DLambdaSsm.cpp IPrintable_DLambdaSsm.cpp + DApplySsm.cpp + # ISyntaxStateMachine_DApplySsm.cpp + # IPrintable_DApplySsm.cpp + DParenSsm.cpp ISyntaxStateMachine_DParenSsm.cpp IPrintable_DParenSsm.cpp diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp new file mode 100644 index 00000000..f58ce7d4 --- /dev/null +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -0,0 +1,221 @@ +/** @file DApplySsm.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DApplySsm.hpp" +#include + +//#include "parserstatemachine.hpp" +//#include "expect_expr_xs.hpp" + +namespace xo { + using xo::reflect::typeseq; + + namespace scm { + + // ----- applyexprstatetype ----- + + const char * + applyexprstatetype_descr(applyexprstatetype x) { + switch (x) { + case applyexprstatetype::invalid: return "invalid"; + case applyexprstatetype::apply_0: return "apply_0"; + case applyexprstatetype::apply_1: return "apply_1"; + case applyexprstatetype::apply_2: return "apply_2"; + case applyexprstatetype::apply_3: return "apply_3"; + case applyexprstatetype::N: break; + } + + return "???applyexprstatetype"; + } + + std::ostream & + operator<<(std::ostream & os, applyexprstatetype x) { + os << applyexprstatetype_descr(x); + return os; + } + + // ----- DApplySsm ----- + + DApplySsm::DApplySsm(obj fn_expr) + : applystate_{applyexprstatetype::apply_0}, + fn_expr_{fn_expr} + { + if (fn_expr) { + this->applystate_ = applyexprstatetype::apply_1; + } + } + + DApplySsm * + DApplySsm::make(DArena & mm, + obj fn_expr) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DApplySsm)); + + // TODO: revisit if we use flexible array for + // arguments + + return new (mem) DApplySsm(fn_expr); + } + +#ifdef NOT_YET + void + apply_xs::start(rp fn_expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + p_psm->push_exprstate(apply_xs::make()); + p_psm->top_exprstate().on_expr(fn_expr.get(), p_psm); + p_psm->top_exprstate().on_leftparen_token(token_type::leftparen(), p_psm); + } +#endif + + syntaxstatetype + DApplySsm::ssm_type() const noexcept { + return syntaxstatetype::apply; + } + + + std::string_view + DApplySsm::get_expect_str() const noexcept + { + switch(applystate_) { + case applyexprstatetype::invalid: return "invalid"; + case applyexprstatetype::apply_0: return "expr"; + case applyexprstatetype::apply_1: return "lparen"; + case applyexprstatetype::apply_2: return "expr"; + case applyexprstatetype::apply_3: return "comma|rparen"; + case applyexprstatetype::N: break; + } + + return "?expect"; + } + +#ifdef NOT_YET + void + apply_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + switch (applyxs_type_) { + case applyexprstatetype::invalid: + case applyexprstatetype::n_applyexprstatetype: + // unreachable + break; + case applyexprstatetype::apply_0: + log && log("stash fn -> new state apply_1"); + this->fn_expr_ = expr.promote(); + this->applyxs_type_ = applyexprstatetype::apply_1; + return; + case applyexprstatetype::apply_1: + log && log("error: was expecting lparen"); + // error, expecting lparen + break; + case applyexprstatetype::apply_2: + log && log(xtag("expr", expr), xtag("do", "stash expr -> new state apply_3")); + this->args_expr_v_.push_back(expr.promote()); + this->applyxs_type_ = applyexprstatetype::apply_3; + return; + case applyexprstatetype::apply_3: + // error, expecting comma|rparen + break; + } + + /* control here --implies-> error state */ + + constexpr const char * c_self_name = "apply_xs::on_expr"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_expr(c_self_name, expr, exp, p_psm); + } + + void + apply_xs::on_comma_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + if (this->applyxs_type_ == applyexprstatetype::apply_3) { + this->applyxs_type_ = applyexprstatetype::apply_2; + expect_expr_xs::start(p_psm); + } else { + constexpr const char * c_self_name = "apply_xs::on_comma_token"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + } + + void + apply_xs::on_leftparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("applyxs_type", applyxs_type_); + + if (this->applyxs_type_ == applyexprstatetype::apply_1) { + this->applyxs_type_ = applyexprstatetype::apply_2; + expect_expr_xs::start(p_psm); + } else { + constexpr const char * c_self_name = "apply_xs::on_leftparen_token"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + } + + void + apply_xs::on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log("applyxs_type", applyxs_type_); + + if (this->applyxs_type_ == applyexprstatetype::apply_3) { + /* (done) state */ + log("apply complete -> pop + send expr"); + + rp apply_expr = Apply::make(this->fn_expr_, this->args_expr_v_); + + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->top_exprstate().on_expr(apply_expr, p_psm); + return; + } + + constexpr const char * c_self_name = "apply_xs::on_rightparen_token"; + const char * exp = this->get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + apply_xs::print(std::ostream & os) const + { + os << ""; + } + + bool + apply_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, "apply_xs", + refrtag("applyxs_type", applyxs_type_), + refrtag("fn_expr", fn_expr_), + refrtag("args_expr_v", args_expr_v_)); + } + +#endif + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DApplySsm.cpp */ diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index d774c269..0a28fd60 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -538,7 +538,7 @@ namespace xo { } #endif - // here: have lhs_ expression + // here: have lhs_ expression if (op_type_ == optype::invalid) { // e.g. control here on input like @@ -911,12 +911,13 @@ namespace xo { return; } - if (optype_ == optype::invalid) { + if (op_type_ == optype::invalid) { // leftparen begins function call arguments. // .lhs_ now understood to be expression that evaluates to a // function - + + } Super::on_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index 18acb000..01ab1005 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -21,6 +21,8 @@ namespace xo { return "ifelseexpr"; case syntaxstatetype::sequence: return "sequence"; + case syntaxstatetype::apply: + return "apply"; case syntaxstatetype::progress: return "progress"; case syntaxstatetype::paren: From 700c9a19cfcc2a75b1187d5ee365a57ce3d39c23 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 11 Feb 2026 16:53:10 -0500 Subject: [PATCH 172/258] devenv: ghostty + fish + timg + nushell --- default.nix | 20 ++++++++++++++++++++ etc/hostubuntu/libEGL_nvidia.so | 1 - 2 files changed, 20 insertions(+), 1 deletion(-) delete mode 120000 etc/hostubuntu/libEGL_nvidia.so diff --git a/default.nix b/default.nix index 481dd59a..13c087a7 100644 --- a/default.nix +++ b/default.nix @@ -59,6 +59,20 @@ let }); }; + # ghostty tests require ptys + ghostty-overlay = self: super: { + ghostty = super.ghostty.overrideAttrs (old: { + doCheck = false; + }); + }; + + # fish tests require ptys + fish-overlay = self: super: { + fish = super.fish.overrideAttrs (old: { + doCheck = false; + }); + }; + # # nixGL not present in my nixpkgs snapshot # nixgl-overlay = self: super: { # nixGL = import (self.fetchFromGitHub { @@ -192,6 +206,8 @@ let swtpm-overlay mailutils-overlay notmuch-overlay + ghostty-overlay + fish-overlay # nixgl-overlay # llvm-overlay xo-overlay @@ -240,6 +256,10 @@ let pkgs.emacsPackages.notmuch pkgs.inconsolata-lgc pkgs.fontconfig + pkgs.ghostty + pkgs.timg + pkgs.fish + pkgs.nushell ]; # xo general-purpose devutils diff --git a/etc/hostubuntu/libEGL_nvidia.so b/etc/hostubuntu/libEGL_nvidia.so deleted file mode 120000 index 543858c6..00000000 --- a/etc/hostubuntu/libEGL_nvidia.so +++ /dev/null @@ -1 +0,0 @@ -libEGL_nvidia.so.580.95.05 \ No newline at end of file From 49f1eca1f7a2bf51205da3cc85f2f9763925fb57 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 11 Feb 2026 18:07:17 -0500 Subject: [PATCH 173/258] etc/hostubuntu: more host libraries for GPU stack (needed to make ghostty happy) --- etc/hostubuntu/libEGL_mesa.so.0 | 1 + etc/hostubuntu/libEGL_mesa.so.0.0.0 | 1 + etc/hostubuntu/libEGL_nvidia.so.0 | 1 + etc/hostubuntu/libdrm.so | 1 + etc/hostubuntu/libdrm.so.2 | 1 + etc/hostubuntu/libdrm.so.2.4.0 | 1 + etc/hostubuntu/libgbm.so | 1 + etc/hostubuntu/libgbm.so.1 | 1 + etc/hostubuntu/libgbm.so.1.0.0 | 1 + 9 files changed, 9 insertions(+) create mode 120000 etc/hostubuntu/libEGL_mesa.so.0 create mode 120000 etc/hostubuntu/libEGL_mesa.so.0.0.0 create mode 120000 etc/hostubuntu/libEGL_nvidia.so.0 create mode 120000 etc/hostubuntu/libdrm.so create mode 120000 etc/hostubuntu/libdrm.so.2 create mode 120000 etc/hostubuntu/libdrm.so.2.4.0 create mode 120000 etc/hostubuntu/libgbm.so create mode 120000 etc/hostubuntu/libgbm.so.1 create mode 120000 etc/hostubuntu/libgbm.so.1.0.0 diff --git a/etc/hostubuntu/libEGL_mesa.so.0 b/etc/hostubuntu/libEGL_mesa.so.0 new file mode 120000 index 00000000..d53298a5 --- /dev/null +++ b/etc/hostubuntu/libEGL_mesa.so.0 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libEGL_mesa.so.0 \ No newline at end of file diff --git a/etc/hostubuntu/libEGL_mesa.so.0.0.0 b/etc/hostubuntu/libEGL_mesa.so.0.0.0 new file mode 120000 index 00000000..bca1401a --- /dev/null +++ b/etc/hostubuntu/libEGL_mesa.so.0.0.0 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libEGL_mesa.so.0.0.0 \ No newline at end of file diff --git a/etc/hostubuntu/libEGL_nvidia.so.0 b/etc/hostubuntu/libEGL_nvidia.so.0 new file mode 120000 index 00000000..26b761b3 --- /dev/null +++ b/etc/hostubuntu/libEGL_nvidia.so.0 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.0 \ No newline at end of file diff --git a/etc/hostubuntu/libdrm.so b/etc/hostubuntu/libdrm.so new file mode 120000 index 00000000..4b830b64 --- /dev/null +++ b/etc/hostubuntu/libdrm.so @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libdrm.so \ No newline at end of file diff --git a/etc/hostubuntu/libdrm.so.2 b/etc/hostubuntu/libdrm.so.2 new file mode 120000 index 00000000..77111d6e --- /dev/null +++ b/etc/hostubuntu/libdrm.so.2 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libdrm.so.2 \ No newline at end of file diff --git a/etc/hostubuntu/libdrm.so.2.4.0 b/etc/hostubuntu/libdrm.so.2.4.0 new file mode 120000 index 00000000..2b62d18e --- /dev/null +++ b/etc/hostubuntu/libdrm.so.2.4.0 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libdrm.so.2.4.0 \ No newline at end of file diff --git a/etc/hostubuntu/libgbm.so b/etc/hostubuntu/libgbm.so new file mode 120000 index 00000000..c43545cf --- /dev/null +++ b/etc/hostubuntu/libgbm.so @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libgbm.so \ No newline at end of file diff --git a/etc/hostubuntu/libgbm.so.1 b/etc/hostubuntu/libgbm.so.1 new file mode 120000 index 00000000..54b72186 --- /dev/null +++ b/etc/hostubuntu/libgbm.so.1 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libgbm.so.1 \ No newline at end of file diff --git a/etc/hostubuntu/libgbm.so.1.0.0 b/etc/hostubuntu/libgbm.so.1.0.0 new file mode 120000 index 00000000..e64ce8f3 --- /dev/null +++ b/etc/hostubuntu/libgbm.so.1.0.0 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libgbm.so.1.0.0 \ No newline at end of file From 18ae5739c2b5ce4708b7818fd16125bfaad9b91d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 11 Feb 2026 18:07:55 -0500 Subject: [PATCH 174/258] xo-reader2: progress+apply works up to lparen introducing formals --- xo-reader2/CMakeLists.txt | 26 +++++++ xo-reader2/idl/IPrintable_DApplySsm.json5 | 13 ++++ .../idl/ISyntaxStateMachine_DApplySsm.json5 | 13 ++++ xo-reader2/include/xo/reader2/ApplySsm.hpp | 12 +++ xo-reader2/include/xo/reader2/DApplySsm.hpp | 18 ++++- xo-reader2/include/xo/reader2/SequenceSsm.hpp | 13 ++++ .../xo/reader2/ssm/IPrintable_DApplySsm.hpp | 62 +++++++++++++++ .../ssm/ISyntaxStateMachine_DApplySsm.hpp | 77 +++++++++++++++++++ xo-reader2/src/reader2/CMakeLists.txt | 4 +- xo-reader2/src/reader2/DApplySsm.cpp | 36 +++++++-- xo-reader2/src/reader2/DProgressSsm.cpp | 42 +++++++--- .../src/reader2/IPrintable_DApplySsm.cpp | 28 +++++++ .../reader2/ISyntaxStateMachine_DApplySsm.cpp | 69 +++++++++++++++++ .../src/reader2/reader2_register_facets.cpp | 7 +- 14 files changed, 393 insertions(+), 27 deletions(-) create mode 100644 xo-reader2/idl/IPrintable_DApplySsm.json5 create mode 100644 xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 create mode 100644 xo-reader2/include/xo/reader2/ApplySsm.hpp create mode 100644 xo-reader2/include/xo/reader2/SequenceSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/IPrintable_DApplySsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp create mode 100644 xo-reader2/src/reader2/IPrintable_DApplySsm.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DApplySsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index d1e807e6..7bfc86f1 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -244,6 +244,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-applyssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ApplySsm + INPUT idl/ISyntaxStateMachine_DApplySsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-applyssm + FACET_PKG xo_printable2 + FACET Printable + REPR ApplySsm + INPUT idl/IPrintable_DApplySsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-expectsymbolssm diff --git a/xo-reader2/idl/IPrintable_DApplySsm.json5 b/xo-reader2/idl/IPrintable_DApplySsm.json5 new file mode 100644 index 00000000..cdcd32ca --- /dev/null +++ b/xo-reader2/idl/IPrintable_DApplySsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DApplySsm", + using_doxygen: true, + repr: "DApplySsm", + doc: [ "implement APrintable for DApplySsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 new file mode 100644 index 00000000..7806d2cb --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DApplySsm", + using_doxygen: true, + repr: "DApplySsm", + doc: [ "implement ASyntaxStateMachine for DApplySsm" ], +} diff --git a/xo-reader2/include/xo/reader2/ApplySsm.hpp b/xo-reader2/include/xo/reader2/ApplySsm.hpp new file mode 100644 index 00000000..6e9f9a9d --- /dev/null +++ b/xo-reader2/include/xo/reader2/ApplySsm.hpp @@ -0,0 +1,12 @@ +/** @file ApplySsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DApplySsm.hpp" +#include "ssm/ISyntaxStateMachine_DApplySsm.hpp" +#include "ssm/IPrintable_DApplySsm.hpp" + +/* end ApplySsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DApplySsm.hpp b/xo-reader2/include/xo/reader2/DApplySsm.hpp index 34c78f78..46f9097b 100644 --- a/xo-reader2/include/xo/reader2/DApplySsm.hpp +++ b/xo-reader2/include/xo/reader2/DApplySsm.hpp @@ -89,10 +89,11 @@ namespace xo { static DApplySsm * make(DArena & parser_mm, obj fn_expr); -#ifdef NOT_YET /** * Start apply. Will trigger this after input like * "fn(" + * or + * "makefn()()" * * apply_xs remains on expr stack until closing right paren * fn(arg1-expr, arg2-expr, ...) @@ -100,9 +101,8 @@ namespace xo { * @p fnex expression in function position * @p p_psm parser state machine **/ - static void start(rp fnex, - parserstatemachine * p_psm); -#endif + static void start(obj fnex, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-applyssm-access methods **/ @@ -124,6 +124,8 @@ namespace xo { /** mnemonic for expected remaining syntax for current parsing state **/ std::string_view get_expect_str() const noexcept; + ///@} + #ifdef NOT_YET virtual void on_expr(bp expr, @@ -143,6 +145,14 @@ namespace xo { static std::unique_ptr make(); #endif + /** @defgroup ssm-applyssm-printable-facet printable facet **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + private: /** current state of parser for this apply expression **/ applyexprstatetype applystate_ = applyexprstatetype::apply_0; diff --git a/xo-reader2/include/xo/reader2/SequenceSsm.hpp b/xo-reader2/include/xo/reader2/SequenceSsm.hpp new file mode 100644 index 00000000..0e82e081 --- /dev/null +++ b/xo-reader2/include/xo/reader2/SequenceSsm.hpp @@ -0,0 +1,13 @@ +/** @file SequenceSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DSequenceSsm.hpp" +#include "ssm/ISyntaxStateMachine_DSequenceSsm.hpp" +#include "ssm/IPrintable_DSequenceSsm.hpp" + +/* end SequenceSsm.hpp */ + diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DApplySsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DApplySsm.hpp new file mode 100644 index 00000000..3bae71f2 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DApplySsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DApplySsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DApplySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DApplySsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DApplySsm.hpp" + +namespace xo { namespace scm { class IPrintable_DApplySsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DApplySsm + **/ + class IPrintable_DApplySsm { + public: + /** @defgroup scm-printable-dapplyssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dapplyssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DApplySsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp new file mode 100644 index 00000000..d6b1a53e --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp @@ -0,0 +1,77 @@ +/** @file ISyntaxStateMachine_DApplySsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DApplySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DApplySsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DApplySsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DApplySsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DApplySsm + **/ + class ISyntaxStateMachine_DApplySsm { + public: + /** @defgroup scm-syntaxstatemachine-dapplyssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dapplyssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DApplySsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DApplySsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DApplySsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DApplySsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DApplySsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DApplySsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DApplySsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DApplySsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DApplySsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index b6d9bed0..5c98e209 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -38,8 +38,8 @@ set(SELF_SRCS IPrintable_DLambdaSsm.cpp DApplySsm.cpp - # ISyntaxStateMachine_DApplySsm.cpp - # IPrintable_DApplySsm.cpp + ISyntaxStateMachine_DApplySsm.cpp + IPrintable_DApplySsm.cpp DParenSsm.cpp ISyntaxStateMachine_DParenSsm.cpp diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp index f58ce7d4..217c60b2 100644 --- a/xo-reader2/src/reader2/DApplySsm.cpp +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -3,13 +3,14 @@ * @author Roland Conybeare, Feb 2026 **/ -#include "DApplySsm.hpp" +#include "ApplySsm.hpp" #include //#include "parserstatemachine.hpp" //#include "expect_expr_xs.hpp" namespace xo { + using xo::print::APrintable; using xo::reflect::typeseq; namespace scm { @@ -60,18 +61,21 @@ namespace xo { return new (mem) DApplySsm(fn_expr); } -#ifdef NOT_YET void - apply_xs::start(rp fn_expr, - parserstatemachine * p_psm) + DApplySsm::start(obj fn_expr, + ParserStateMachine * p_psm) { scope log(XO_DEBUG(p_psm->debug_flag())); - p_psm->push_exprstate(apply_xs::make()); - p_psm->top_exprstate().on_expr(fn_expr.get(), p_psm); - p_psm->top_exprstate().on_leftparen_token(token_type::leftparen(), p_psm); + DApplySsm * apply_ssm + = DApplySsm::make(p_psm->parser_alloc(), fn_expr); + + obj ssm(apply_ssm); + + p_psm->push_ssm(ssm); + //OBSOLETE //p_psm->top_exprstate().on_expr(fn_expr.get(), p_psm); + //OBSOLETE //p_psm->on_token(token_type::leftparen(), p_psm); } -#endif syntaxstatetype DApplySsm::ssm_type() const noexcept { @@ -194,7 +198,23 @@ namespace xo { this->illegal_input_on_token(c_self_name, tk, exp, p_psm); } +#endif + bool + DApplySsm::pretty(const ppindentinfo & ppii) const + { + // TODO: const-correct version of obj<> template + auto fn_expr = const_cast(this)->fn_expr_.to_facet(); + bool fn_expr_present(fn_expr); + + return ppii.pps()->pretty_struct(ppii, + "DApplySsm", + refrtag("applystate", applystate_), + refrtag("expect", this->get_expect_str()), + refrtag("fn_expr", fn_expr, fn_expr_present)); + } + +#ifdef NOT_YET void apply_xs::print(std::ostream & os) const { diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 0a28fd60..19d318f6 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -9,6 +9,7 @@ #include "DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" +#include "ApplySsm.hpp" #include "ParenSsm.hpp" #include @@ -20,21 +21,13 @@ #include // for xo::scm::Primitives #include -#ifdef NOT_YET -#include "DApplySsm.hpp" -#include "ssm/ISyntaxStateMachine_DApplySsm.hpp" -#endif - #include #include #include #include #ifdef NOT_YET -#include "apply_xs.hpp" -#include "exprstatestack.hpp" #include "expect_expr_xs.hpp" -#include "parserstatemachine.hpp" #include "pretty_exprstatestack.hpp" #include "xo/expression/AssignExpr.hpp" #include "xo/expression/Apply.hpp" @@ -912,12 +905,39 @@ namespace xo { } if (op_type_ == optype::invalid) { - // leftparen begins function call arguments. - // .lhs_ now understood to be expression that evaluates to a - // function + // input: + /// <--- F1 ---> + // (..........)(.. ).. + // <------ A1 -----> + // <------- X1 ------> + // + // F1: expression evaluating to a function, + // parsed as fn_expr + // A1: expression parsed as a function call (i.e. apply-expression) + // X1: operator expression starting with A1 + // + // before: + // [0] ProgressSsm responsible for input beginning with F1 + // .lhs = fn_expr, .op_type empty, .rhs empty + // + // after: + // [0] ApplySsm responsible for function call A1 + // .fn_expr = fn_expr + // [1] ProgressSsm responsible for operator expression X1 + // .lhs empty, .op_type empty, .rhs empty + // + // Remarks: + // 1. keep ProgressSsm on the stack in case input continues like: + // fn_expr(args..) + .. + // i.e. to allow for infix operator following apply + // + obj fn_expr(this->lhs_); + this->lhs_ = obj(); + DApplySsm::start(fn_expr, p_psm); + return; } Super::on_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/IPrintable_DApplySsm.cpp b/xo-reader2/src/reader2/IPrintable_DApplySsm.cpp new file mode 100644 index 00000000..5066b082 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DApplySsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DApplySsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DApplySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DApplySsm.json5] +**/ + +#include "ssm/IPrintable_DApplySsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DApplySsm::pretty(const DApplySsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DApplySsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DApplySsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DApplySsm.cpp new file mode 100644 index 00000000..2164ae04 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DApplySsm.cpp @@ -0,0 +1,69 @@ +/** @file ISyntaxStateMachine_DApplySsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DApplySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DApplySsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DApplySsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DApplySsm::ssm_type(const DApplySsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DApplySsm::get_expect_str(const DApplySsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DApplySsm::on_token(DApplySsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_symbol(DApplySsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_typedescr(DApplySsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_formal(DApplySsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_formal_arglist(DApplySsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_expression(DApplySsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_expression_with_token(DApplySsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DApplySsm.cpp */ diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 3955fae3..eb39f6ac 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -17,8 +17,8 @@ #include #include -#include - +#include "ApplySsm.hpp" +#include "SequenceSsm.hpp" #include "ParenSsm.hpp" #include @@ -67,6 +67,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); From cfd35da0c010d73d1e8264facf7d7bb2e5144a3a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 11 Feb 2026 20:25:24 -0500 Subject: [PATCH 175/258] xo-reader2: more work on apply expressions [WIP] --- xo-reader2/include/xo/reader2/DApplySsm.hpp | 43 ++-- .../include/xo/reader2/DProgressSsm.hpp | 2 + xo-reader2/src/reader2/DApplySsm.cpp | 186 +++++++++++++----- .../src/reader2/DExpectFormalArglistSsm.cpp | 3 +- xo-reader2/src/reader2/DProgressSsm.cpp | 41 +++- xo-reader2/utest/SchematikaParser.test.cpp | 24 +++ 6 files changed, 238 insertions(+), 61 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DApplySsm.hpp b/xo-reader2/include/xo/reader2/DApplySsm.hpp index 46f9097b..e5d59f10 100644 --- a/xo-reader2/include/xo/reader2/DApplySsm.hpp +++ b/xo-reader2/include/xo/reader2/DApplySsm.hpp @@ -46,8 +46,8 @@ namespace xo { apply_0, apply_1, - apply_2, - apply_3, + apply_2, // rename -> apply_2a + apply_3, // rename -> apply_2b N }; @@ -81,7 +81,8 @@ namespace xo { * that we parse f before parser knows that it will be * followed by leftparen **/ - explicit DApplySsm(obj fn_expr); + explicit DApplySsm(obj fn_expr, + DArray * args); /** create instance using memory from @p parser_mm. * with function to be called supplied by @p fn_expr. @@ -103,9 +104,8 @@ namespace xo { **/ static void start(obj fnex, ParserStateMachine * p_psm); - ///@} - /** @defgroup scm-applyssm-access methods **/ + /** @defgroup scm-applyssm-access-methods access methods **/ ///@{ /** identify this nested state machine **/ @@ -114,6 +114,16 @@ namespace xo { /** current internal state **/ applyexprstatetype applystate() const noexcept { return applystate_; } + ///@} + /** @defgroup scm-applyssm-methods general methods **/ + ///@{ + + /** handle leftparen token @p tk for this ssm, + * with overall parser state in @p p_psm + **/ + void on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup ssm-applyssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -124,6 +134,12 @@ namespace xo { /** mnemonic for expected remaining syntax for current parsing state **/ std::string_view get_expect_str() const noexcept; + /** update this apply-ssm for incoming token @p tk, + * with overall parsing state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} #ifdef NOT_YET @@ -133,14 +149,9 @@ namespace xo { virtual void on_comma_token(const token_type & tk, parserstatemachine * p_psm) override; - virtual void on_leftparen_token(const token_type & tk, - parserstatemachine * p_psm) override; virtual void on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) override; - virtual void print(std::ostream & os) const override; - virtual bool pretty_print(const print::ppindentinfo & ppii) const final override; - private: static std::unique_ptr make(); #endif @@ -158,10 +169,14 @@ namespace xo { applyexprstatetype applystate_ = applyexprstatetype::apply_0; /** evaluates to function to be invoked **/ obj fn_expr_; -#ifdef NOT_YET - /** evaluates to the arguments to pass to @ref fn_ **/ - std::vector> args_expr_v_; -#endif + /** args_expr_v_[i] evaluates to the i'th argument to call. + * Not using flexible array here since we don't know size at + * construction time + * + * (though could revisit + realloc this DApplySsm instance in + * place to optimize) + **/ + DArray * args_expr_v_ = nullptr; }; } /*namespace scm */ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 47ca29b9..1a0e7186 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -137,6 +137,8 @@ namespace xo { /** handle leftparen token @p tk. Overall parser state in @p p_psm **/ void on_leftparen_token(const Token & tk, ParserStateMachine * p_psm); + void on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm); void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp index 217c60b2..bdcbe965 100644 --- a/xo-reader2/src/reader2/DApplySsm.cpp +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -4,6 +4,7 @@ **/ #include "ApplySsm.hpp" +#include "ExpectExprSsm.hpp" #include //#include "parserstatemachine.hpp" @@ -39,13 +40,18 @@ namespace xo { // ----- DApplySsm ----- - DApplySsm::DApplySsm(obj fn_expr) - : applystate_{applyexprstatetype::apply_0}, - fn_expr_{fn_expr} + DApplySsm::DApplySsm(applyexprstatetype applystate, + obj fn_expr, + DArray * args) + : applystate_{applystate}, + fn_expr_{fn_expr}, + arg_expr_v_{args} { if (fn_expr) { this->applystate_ = applyexprstatetype::apply_1; } + + assert(args->empty()); } DApplySsm * @@ -55,10 +61,21 @@ namespace xo { void * mem = mm.alloc(typeseq::id(), sizeof(DApplySsm)); - // TODO: revisit if we use flexible array for - // arguments + /* allocate room for 8 arguments (during parsing) + * will reallocate to expand if needed. + * + * See similar code in DExpectFormalArglistSsm::_make + */ + DArray * args = DArray::empty(mm, 8); - return new (mem) DApplySsm(fn_expr); + applyexprstatetype applystate + = (fn_expr + ? applyexprstatetype::apply_1 + : applyexprstatetype::apply_0); + + // TODO: revisit if we decide to use flexible array for arguments + + return new (mem) DApplySsm(applystate, fn_expr, args); } void @@ -98,6 +115,124 @@ namespace xo { return "?expect"; } + void + DApplySsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + case tokentype::tk_symbol: + case tokentype::tk_def: + case tokentype::tk_if: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_semicolon: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_invalid: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + Super::on_token(tk, p_psm); + } + + void + DApplySsm::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (applystate_ == applyexprstatetype::apply_1) { + this->applystate_ = applyexprstatetype::apply_2; + + DExpectExprSsm::start(p_psm); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DApplySsm::on_parsed_expression_with_token(obj expr, + const Token & tk) + { + if (applystate_ == applyexprstatetype::apply_2) { + if (args_expr_v_->size() == args_expr_v_->capacity()) { + // need to expand .args_expr_v_ capacity. + // Could use DArena checkpoint to redo this in place, + // since argument array must be on the top of the stack. + + obj mm(&(p_psm->parser_alloc())); + + DArray * argv_2x = DArray::empty(mm, 2 * args_expr_v_->capacity()); + + for (DArray::size_type i = 0, n = arg_expr_v_->size(); i < n; ++i) { + argv_2x->push_back((*argv_)[i]); + } + + this->args_expr_v_ = argv_2x; + } + + if (args_expr_v_->size() < args_expr_v_->capacity()) { + args_expr_v_->push_back(expr); + + } + + if (tk.tk_type() == tokentype::tk_rightparen) { + // expression completes apply + + // TODO: assemble apply expression.. + + assert(false); + } + + if ((tk.tk_type() == tokentype::tk_comma) + || (tk.tk_type() == tokentype::tk_rightparen)) { + + // do stuff, + //return; + } + + // complain + + assert(false); + } + + Super::on_parsed_expression_with_token(expr, tk); + } + #ifdef NOT_YET void apply_xs::on_expr(bp expr, @@ -154,25 +289,6 @@ namespace xo { } } - void - apply_xs::on_leftparen_token(const token_type & tk, - parserstatemachine * p_psm) - { - scope log(XO_DEBUG(p_psm->debug_flag())); - - log && log("applyxs_type", applyxs_type_); - - if (this->applyxs_type_ == applyexprstatetype::apply_1) { - this->applyxs_type_ = applyexprstatetype::apply_2; - expect_expr_xs::start(p_psm); - } else { - constexpr const char * c_self_name = "apply_xs::on_leftparen_token"; - const char * exp = this->get_expect_str(); - - this->illegal_input_on_token(c_self_name, tk, exp, p_psm); - } - } - void apply_xs::on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) @@ -214,26 +330,6 @@ namespace xo { refrtag("fn_expr", fn_expr, fn_expr_present)); } -#ifdef NOT_YET - void - apply_xs::print(std::ostream & os) const - { - os << ""; - } - - bool - apply_xs::pretty_print(const xo::print::ppindentinfo & ppii) const - { - return ppii.pps()->pretty_struct(ppii, "apply_xs", - refrtag("applyxs_type", applyxs_type_), - refrtag("fn_expr", fn_expr_), - refrtag("args_expr_v", args_expr_v_)); - } - -#endif } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index b34ad135..5f609807 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -182,7 +182,8 @@ namespace xo { if (fastate_ == formalarglstatetype::argl_1a) { this->fastate_ = formalarglstatetype::argl_1b; - TypeRef typeref = TypeRef::dwim(TypeRef::prefix_type::from_chars("formal"), param_type); + TypeRef typeref + = TypeRef::dwim(TypeRef::prefix_type::from_chars("formal"), param_type); DVariable * var = DVariable::make(p_psm->expr_alloc(), param_name, diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 19d318f6..d3b8c3c3 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -267,11 +267,14 @@ namespace xo { this->on_leftparen_token(tk, p_psm); return; + case tokentype::tk_rightparen: + this->on_rightparen_token(tk, p_psm); + return; + // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_def: case tokentype::tk_if: - case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: case tokentype::tk_leftbrace: @@ -937,6 +940,9 @@ namespace xo { this->lhs_ = obj(); DApplySsm::start(fn_expr, p_psm); + // + send leftparen to just-pushed apply + p_psm->on_token(tk); + return; } @@ -986,7 +992,40 @@ namespace xo { this->illegal_input_on_token(c_self_name, tk, exp, p_psm); } +#endif + void + DProgressSsm::on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + /* note: implementation parallels .on_semicolon_token() */ + + scope log(XO_DEBUG(p_psm->debug_flag())); + + /* stack may be something like: + * + * [0] DProgressSsm + * [1] DExpectExprSsm + * [2] DApplySsm + * + * where we want rightparen to resolve in [2] DApplySsm, + * after triggering completion of [0] and [1] + */ + auto expr = this->assemble_expr(p_psm); + + if (expr) { + /* 1. popping self from parser stack.. */ + p_psm->pop_ssm(); + /* 2. report parsed subexpr to parent ssm, along with the triggering rightparen **/ + p_psm->on_parsed_expression_with_token(expr, tk); + + return; + } + + Super::on_token(tk, p_psm); + } + +#ifdef NOT_YET void progress_xs::on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 77d9471c..cbf669fd 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -1204,6 +1204,30 @@ namespace xo { REQUIRE(!result.is_error()); REQUIRE(result.is_incomplete()); } + + { + auto & result = parser.on_token(Token::i64_token("13")); + + log && log("after i64(13) token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::rightparen_token()); + + log && log("after rightparen token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } } } /*namespace ut*/ } /*namespace xo*/ From 2cf7f2744ff964b73abe49310de923b6c27c747b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 12 Feb 2026 00:02:56 -0500 Subject: [PATCH 176/258] xo-reader2: apply expr now parses up to rightparen --- xo-alloc2/include/xo/alloc2/Arena.hpp | 17 ++++ xo-reader2/include/xo/reader2/DApplySsm.hpp | 21 ++++- xo-reader2/src/reader2/DApplySsm.cpp | 89 ++++++++++++++------- 3 files changed, 96 insertions(+), 31 deletions(-) create mode 100644 xo-alloc2/include/xo/alloc2/Arena.hpp diff --git a/xo-alloc2/include/xo/alloc2/Arena.hpp b/xo-alloc2/include/xo/alloc2/Arena.hpp new file mode 100644 index 00000000..fac3f302 --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/Arena.hpp @@ -0,0 +1,17 @@ +/** @file Arena.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +// reminder: we can't put this AAllocator +// (or APrintable for that matter) support in xo-arena, +// because xo-arena is a dependency of xo-facet, which is in turn +// a dependency of xo-alloc2 +// + +#include +#include "arena/IAllocator_DArena.hpp" + +/* end Arena.hpp */ diff --git a/xo-reader2/include/xo/reader2/DApplySsm.hpp b/xo-reader2/include/xo/reader2/DApplySsm.hpp index e5d59f10..b9ff3d8b 100644 --- a/xo-reader2/include/xo/reader2/DApplySsm.hpp +++ b/xo-reader2/include/xo/reader2/DApplySsm.hpp @@ -81,7 +81,8 @@ namespace xo { * that we parse f before parser knows that it will be * followed by leftparen **/ - explicit DApplySsm(obj fn_expr, + explicit DApplySsm(applyexprstatetype applystate, + obj fn_expr, DArray * args); /** create instance using memory from @p parser_mm. @@ -140,6 +141,13 @@ namespace xo { void on_token(const Token & tk, ParserStateMachine * p_psm); + /** update this apply-ssm with data from nested ssm: + * expression @p expr, followed by token @p tk. + **/ + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); + ///@} #ifdef NOT_YET @@ -165,6 +173,15 @@ namespace xo { ///@} private: + /** @defgroup ssm-applyssm-mpl-methods **/ + ///@{ + + ///@} + + private: + /** @defgroup ssm-applyssm-member-variables **/ + ///@{ + /** current state of parser for this apply expression **/ applyexprstatetype applystate_ = applyexprstatetype::apply_0; /** evaluates to function to be invoked **/ @@ -177,6 +194,8 @@ namespace xo { * place to optimize) **/ DArray * args_expr_v_ = nullptr; + + ///@} }; } /*namespace scm */ diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp index bdcbe965..ad2f7fd6 100644 --- a/xo-reader2/src/reader2/DApplySsm.cpp +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -5,12 +5,15 @@ #include "ApplySsm.hpp" #include "ExpectExprSsm.hpp" +#include +#include #include //#include "parserstatemachine.hpp" //#include "expect_expr_xs.hpp" namespace xo { + using xo::mm::AGCObject; using xo::print::APrintable; using xo::reflect::typeseq; @@ -45,21 +48,23 @@ namespace xo { DArray * args) : applystate_{applystate}, fn_expr_{fn_expr}, - arg_expr_v_{args} + args_expr_v_{args} { if (fn_expr) { this->applystate_ = applyexprstatetype::apply_1; } - assert(args->empty()); + assert(args->is_empty()); } DApplySsm * - DApplySsm::make(DArena & mm, + DApplySsm::make(DArena & arena, obj fn_expr) { - void * mem = mm.alloc(typeseq::id(), - sizeof(DApplySsm)); + obj mm(&arena); + + void * mem = arena.alloc(typeseq::id(), + sizeof(DApplySsm)); /* allocate room for 8 arguments (during parsing) * will reallocate to expand if needed. @@ -186,51 +191,75 @@ namespace xo { void DApplySsm::on_parsed_expression_with_token(obj expr, - const Token & tk) + const Token & tk, + ParserStateMachine * p_psm) { + /* maybe we'll find control comes here also on function position? + * hasn't come up when applyssm recognized via leftparen + */ + if (applystate_ == applyexprstatetype::apply_2) { + obj expr_gco = expr.to_facet(); + assert(expr_gco); + + obj mm(&(p_psm->parser_alloc())); + if (args_expr_v_->size() == args_expr_v_->capacity()) { // need to expand .args_expr_v_ capacity. // Could use DArena checkpoint to redo this in place, // since argument array must be on the top of the stack. - obj mm(&(p_psm->parser_alloc())); - DArray * argv_2x = DArray::empty(mm, 2 * args_expr_v_->capacity()); - for (DArray::size_type i = 0, n = arg_expr_v_->size(); i < n; ++i) { - argv_2x->push_back((*argv_)[i]); + for (DArray::size_type i = 0, n = args_expr_v_->size(); i < n; ++i) { + argv_2x->push_back((*args_expr_v_)[i]); } this->args_expr_v_ = argv_2x; } - if (args_expr_v_->size() < args_expr_v_->capacity()) { - args_expr_v_->push_back(expr); - - } + if (args_expr_v_->size() < args_expr_v_->capacity()) + args_expr_v_->push_back(expr_gco); if (tk.tk_type() == tokentype::tk_rightparen) { - // expression completes apply + // begin assemble_expr().. - // TODO: assemble apply expression.. + std::uint32_t n_args = args_expr_v_->size(); - assert(false); + DApplyExpr * apply + = (DApplyExpr::scaffold + (mm, + TypeRef::dwim(TypeRef::prefix_type::from_chars("apply"), + nullptr), + fn_expr_, + n_args)); + + for (std::uint32_t i_arg = 0; i_arg < n_args; ++i_arg) { + auto arg_expr + = args_expr_v_->at(i_arg).to_facet(); + + apply->assign_arg(i_arg, arg_expr); + } + + // ..end assemble_expr() + + obj apply_ex(apply); + + p_psm->pop_ssm(); + p_psm->on_parsed_expression(apply_ex); + + return; + } else if (tk.tk_type() == tokentype::tk_comma) { + // 1. want to remain in state apply_2 + // 2. expr from nested ssm already incorporated + // into .args_expr_v_ + // -> so updated state already achieved. + + return; } - - if ((tk.tk_type() == tokentype::tk_comma) - || (tk.tk_type() == tokentype::tk_rightparen)) { - - // do stuff, - //return; - } - - // complain - - assert(false); } - Super::on_parsed_expression_with_token(expr, tk); + Super::on_parsed_expression_with_token(expr, tk, p_psm); } #ifdef NOT_YET @@ -319,7 +348,7 @@ namespace xo { bool DApplySsm::pretty(const ppindentinfo & ppii) const { - // TODO: const-correct version of obj<> template + // TODO: const-correct version of obj<> template auto fn_expr = const_cast(this)->fn_expr_.to_facet(); bool fn_expr_present(fn_expr); From ee05e5f7b2d7d0b75d686ac32c799bc59b644cba Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 12 Feb 2026 00:06:50 -0500 Subject: [PATCH 177/258] xo-reader2: utest for top-level apply passes --- xo-reader2/utest/SchematikaParser.test.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index cbf669fd..54896a3f 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -1228,6 +1228,19 @@ namespace xo { REQUIRE(!result.is_error()); REQUIRE(result.is_incomplete()); } + + { + auto & result = parser.on_token(Token::semicolon_token()); + + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } } } /*namespace ut*/ } /*namespace xo*/ From 8c3141101b3474b7a3f444d7cf31c82916f0a1d3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 12 Feb 2026 00:43:46 -0500 Subject: [PATCH 178/258] xo-reader2: handle multiple args in apply + streamlined utest --- .../include/xo/reader2/DProgressSsm.hpp | 2 + xo-reader2/src/reader2/DApplySsm.cpp | 2 +- xo-reader2/src/reader2/DProgressSsm.cpp | 6 +- xo-reader2/utest/SchematikaParser.test.cpp | 84 +++++++++++++++++++ 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index 1a0e7186..c43caacd 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -142,6 +142,8 @@ namespace xo { void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); + void on_comma_token(const Token & tk, + ParserStateMachine * p_psm); void on_colon_token(const Token & tk, ParserStateMachine * p_psm); void on_singleassign_token(const Token & tk, diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp index ad2f7fd6..4cd3aaec 100644 --- a/xo-reader2/src/reader2/DApplySsm.cpp +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -253,8 +253,8 @@ namespace xo { // 1. want to remain in state apply_2 // 2. expr from nested ssm already incorporated // into .args_expr_v_ - // -> so updated state already achieved. + DExpectExprSsm::start(p_psm); return; } } diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index d3b8c3c3..20bfb998 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -224,6 +224,7 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_then: case tokentype::tk_else: + case tokentype::tk_comma: this->on_completing_token(tk, p_psm); return; @@ -283,7 +284,6 @@ namespace xo { case tokentype::tk_lessequal: case tokentype::tk_greatequal: case tokentype::tk_dot: - case tokentype::tk_comma: case tokentype::tk_doublecolon: case tokentype::tk_assign: case tokentype::tk_yields: @@ -911,7 +911,7 @@ namespace xo { // input: /// <--- F1 ---> // (..........)(.. ).. - // <------ A1 -----> + // <------ A1 -----> // <------- X1 ------> // // F1: expression evaluating to a function, @@ -933,7 +933,7 @@ namespace xo { // 1. keep ProgressSsm on the stack in case input continues like: // fn_expr(args..) + .. // i.e. to allow for infix operator following apply - // + // obj fn_expr(this->lhs_); diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 54896a3f..0ecaff37 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -1242,6 +1242,90 @@ namespace xo { REQUIRE(result.result_expr()); } } + + TEST_CASE("SchematikaParser-interactive-apply2", "[reader2][SchematikaParser]") + { + // top-level apply, with multiple arguments + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * (lambda (x : i64, y : i64) { x * y })(13, 15); + * + **/ + + std::vector tk_v{ + Token::leftparen_token(), + + /**/ Token::lambda_token(), + /* */ Token::leftparen_token(), + /* */ Token::symbol_token("x"), + /* */ Token::colon_token(), + /* */ Token::symbol_token("i64"), + /* */ Token::comma_token(), + /* */ Token::symbol_token("y"), + /* */ Token::colon_token(), + /* */ Token::symbol_token("i64"), + /* */ Token::rightparen_token(), + + /**/ Token::leftbrace_token(), + /* */ Token::symbol_token("x"), + /* */ Token::star_token(), + /* */ Token::symbol_token("y"), + /**/ Token::rightbrace_token(), + + Token::rightparen_token(), + + Token::leftparen_token(), + /**/ Token::i64_token("13"), + /**/ Token::comma_token(), + /**/ Token::i64_token("15"), + Token::rightparen_token(), + + Token::semicolon_token(), + }; + + size_t i_tk = 0; + size_t n_tk = tk_v.size(); + for (const auto & tk : tk_v) { + INFO(tostr(xtag("i_tk", i_tk), xtag("tk", tk))); + + auto & result = parser.on_token(tk); + + log && log("after token", xtag("i_tk", i_tk), xtag("tk", tk)); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + if (i_tk + 1 < n_tk) { + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } else { + /* last token in tk_v[] */ + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } + + ++i_tk; + } + + } } /*namespace ut*/ } /*namespace xo*/ From 9855d22f35e476d9e316fa03d0b185e3feab96e8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 12 Feb 2026 15:21:35 -0500 Subject: [PATCH 179/258] xo-reader2 utest: less boilerplate! --- xo-reader2/utest/SchematikaParser.test.cpp | 238 ++++----------------- 1 file changed, 41 insertions(+), 197 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 0ecaff37..3bdf94cc 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -1037,209 +1037,53 @@ namespace xo { * **/ - { - auto & result = parser.on_token(Token::leftparen_token()); + std::vector tk_v{ + Token::leftparen_token(), - log && log("after lparen token:"); + /**/ Token::lambda_token(), + /**/ Token::leftparen_token(), + /**/ Token::symbol_token("x"), + /**/ Token::colon_token(), + /**/ Token::symbol_token("i64"), + /**/ Token::rightparen_token(), + /**/ Token::leftbrace_token(), + /**/ Token::symbol_token("x"), + /**/ Token::star_token(), + /**/ Token::symbol_token("x"), + /**/ Token::rightbrace_token(), + /**/ Token::rightparen_token(), + /**/ Token::leftparen_token(), + /**/ Token::i64_token("13"), + /**/ Token::rightparen_token(), + + /**/ Token::semicolon_token(), + }; + + size_t i_tk = 0; + size_t n_tk = tk_v.size(); + for (const auto & tk : tk_v) { + INFO(tostr(xtag("i_tk", i_tk), xtag("tk", tk))); + + auto & result = parser.on_token(tk); + + log && log("after token", xtag("i_tk", i_tk), xtag("tk", tk)); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } + if (i_tk + 1 < n_tk) { + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } else { + /* last token in tk_v[] */ - { - auto & result = parser.on_token(Token::lambda_token()); + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } - log && log("after lambda token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::leftparen_token()); - - log && log("after lparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("x")); - - log && log("after symbol(x) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::colon_token()); - - log && log("after colon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("i64")); - - log && log("after symbol(i64) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::rightparen_token()); - - log && log("after rightparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::leftbrace_token()); - - log && log("after leftbrace token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("x")); - - log && log("after symbol(x) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::star_token()); - - log && log("after star(*) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("x")); - - log && log("after symbol(x) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::rightbrace_token()); - - log && log("after rightbrace(}) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::rightparen_token()); - - log && log("after rightparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::leftparen_token()); - - log && log("after leftparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::i64_token("13")); - - log && log("after i64(13) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::rightparen_token()); - - log && log("after rightparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::semicolon_token()); - - log && log("after semicolon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == false); - REQUIRE(!result.is_error()); - REQUIRE(result.is_expression()); - REQUIRE(result.result_expr()); + ++i_tk; } } From c60a2506fc15c05dc20862982d4e252404424d8e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 12 Feb 2026 16:05:22 -0500 Subject: [PATCH 180/258] xo-interpreter2: + DVsmRcx. runtime context for vsm --- .../include/xo/interpreter2/DVsmRcx.hpp | 36 +++++++++++++++- .../interpreter2/VirtualSchematikaMachine.hpp | 3 ++ .../src/interpreter2/CMakeLists.txt | 5 +-- xo-interpreter2/src/interpreter2/DVsmRcx.cpp | 25 +++++++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 7 ++++ .../utest/VirtualSchematikaMachine.test.cpp | 41 +++++++++++++++++++ 6 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 xo-interpreter2/src/interpreter2/DVsmRcx.cpp diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp index 3506206e..3d6632a3 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp @@ -1,2 +1,36 @@ /** @file DVsmRcx.hpp -n* + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + // see xo-interpreter/ VirtualSchematikaMachine.hpp + class VirtualSchematikaMachine; + + /** @brief Runtime context for schematika interpreter + * + * Provides allocator + **/ + class DVsmRcx { + public: + using AAllocator = xo::mm::AAllocator; + + public: + DVsmRcx(VirtualSchematikaMachine * vsm); + + obj allocator() const noexcept; + + private: + /** schematika interpreter **/ + VirtualSchematikaMachine * vsm_ = nullptr;; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmRcx.hpp */ + diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index f28c5bef..af551d04 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -70,6 +70,9 @@ namespace xo { public: VirtualSchematikaMachine(const VsmConfig & config); + /** allocator for schematika data **/ + obj allocator() const noexcept; + /** visit vsm-owned memory pools; call visitor(info) for each **/ void visit_pools(const MemorySizeVisitor & visitor) const; diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 373f6138..b02a4a7a 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -25,10 +25,9 @@ set(SELF_SRCS IPrintable_DLocalEnv.cpp DLocalEnv.cpp + DVsmRcx.cpp + VsmInstr.cpp - - - #IExpression_Any.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/xo-interpreter2/src/interpreter2/DVsmRcx.cpp b/xo-interpreter2/src/interpreter2/DVsmRcx.cpp new file mode 100644 index 00000000..92e153bc --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DVsmRcx.cpp @@ -0,0 +1,25 @@ +/** @file DVsmRcx.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVsmRcx.hpp" +#include "VirtualSchematikaMachine.hpp" + +namespace xo { + using xo::mm::AAllocator; + + namespace scm { + + DVsmRcx::DVsmRcx(VirtualSchematikaMachine * vsm) : vsm_{vsm} {} + + obj + DVsmRcx::allocator() const noexcept + { + return vsm_->allocator(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmRcx.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index c62a723f..2b07791f 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -24,6 +24,7 @@ namespace xo { using xo::print::ppstate_standalone; using xo::mm::AGCObject; //using xo::mm::MemorySizeInfo; // not used yet + using xo::mm::AAllocator; using xo::mm::DX1Collector; using xo::facet::FacetRegistry; using std::cout; @@ -42,6 +43,12 @@ namespace xo { // TODO: allocate global_env } + obj + VirtualSchematikaMachine::allocator() const noexcept + { + return mm_.to_op(); + } + void VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const { diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index ee4ca351..4213764b 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -225,6 +225,47 @@ namespace xo { vsm.visit_pools(visitor); } +#ifdef NOT_YET + TEST_CASE("VirtualSchematikaMachine-apply2", "[interpreter2][VSM]") + { + scope log(XO_DEBUG(true)); + + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res + = vsm.read_eval_print(span_type::from_cstr + ("(lambda (x : i64, y : i64) { x * y; })(13, 15);"), + eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq())); + + auto x = obj::from(*res.value()); + + REQUIRE(x); + //REQUIRE(x.data()->value() == 1.570796325); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + FacetRegistry::instance().visit_pools(visitor); + vsm.visit_pools(visitor); + } +#endif } /*namespace ut*/ } /*namespace xo*/ From 83156ef2d03456ecbf70166424492bd45c4e63aa Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 12 Feb 2026 16:16:49 -0500 Subject: [PATCH 181/258] xo-interpreter2: vsm uses VsmRcx for runtime context --- xo-interpreter2/CMakeLists.txt | 13 ++++ .../idl/IRuntimeContext_DVsmRcx.json5 | 15 +++++ .../include/xo/interpreter2/VsmRcx.hpp | 11 ++++ .../detail/IRuntimeContext_DVsmRcx.hpp | 59 +++++++++++++++++++ .../src/interpreter2/CMakeLists.txt | 1 + .../interpreter2/IRuntimeContext_DVsmRcx.cpp | 28 +++++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 9 +-- .../interpreter2_register_facets.cpp | 7 +++ xo-procedure2/idl/RuntimeContext.json5 | 1 + 9 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmRcx.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IRuntimeContext_DVsmRcx.hpp create mode 100644 xo-interpreter2/src/interpreter2/IRuntimeContext_DVsmRcx.cpp diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 7bda6388..6f3b14bc 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -141,6 +141,19 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-runtimecontext-vsmrcx + FACET_PKG xo_procedure2 + FACET RuntimeContext + REPR DVsmRcx + INPUT idl/IRuntimeContext_DVsmRcx.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 + ) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-interpreter2-genfacet-all) # ---------------------------------------------------------------- diff --git a/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 b/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 new file mode 100644 index 00000000..8659eb66 --- /dev/null +++ b/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + //"", + //"", + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/RuntimeContext.json5", + brief: "provide ARuntimeContext interface for DVsmRcx", + using_doxygen: true, + repr: "DVsmRcx", + doc: [ "implement ARuntimeContext for DVsmRcx" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/VsmRcx.hpp b/xo-interpreter2/include/xo/interpreter2/VsmRcx.hpp new file mode 100644 index 00000000..c0f015eb --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmRcx.hpp @@ -0,0 +1,11 @@ +/** @file VsmRcx.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVsmRcx.hpp" +#include "detail/IRuntimeContext_DVsmRcx.hpp" + +/* end VsmRcx.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IRuntimeContext_DVsmRcx.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IRuntimeContext_DVsmRcx.hpp new file mode 100644 index 00000000..ecb81f1f --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IRuntimeContext_DVsmRcx.hpp @@ -0,0 +1,59 @@ +/** @file IRuntimeContext_DVsmRcx.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IRuntimeContext_DVsmRcx.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IRuntimeContext_DVsmRcx.json5] + **/ + +#pragma once + +#include "RuntimeContext.hpp" +#include "DVsmRcx.hpp" + +namespace xo { namespace scm { class IRuntimeContext_DVsmRcx; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IRuntimeContext_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IRuntimeContext_DVsmRcx + **/ + class IRuntimeContext_DVsmRcx { + public: + /** @defgroup scm-runtimecontext-dvsmrcx-type-traits **/ + ///@{ + using AAllocator = xo::scm::ARuntimeContext::AAllocator; + using Copaque = xo::scm::ARuntimeContext::Copaque; + using Opaque = xo::scm::ARuntimeContext::Opaque; + ///@} + /** @defgroup scm-runtimecontext-dvsmrcx-methods **/ + ///@{ + // const methods + /** default allocator to use for objects **/ + static obj allocator(const DVsmRcx & self) noexcept; + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index b02a4a7a..f6fbd10b 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -26,6 +26,7 @@ set(SELF_SRCS DLocalEnv.cpp DVsmRcx.cpp + IRuntimeContext_DVsmRcx.cpp VsmInstr.cpp ) diff --git a/xo-interpreter2/src/interpreter2/IRuntimeContext_DVsmRcx.cpp b/xo-interpreter2/src/interpreter2/IRuntimeContext_DVsmRcx.cpp new file mode 100644 index 00000000..3fd3730d --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IRuntimeContext_DVsmRcx.cpp @@ -0,0 +1,28 @@ +/** @file IRuntimeContext_DVsmRcx.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IRuntimeContext_DVsmRcx.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IRuntimeContext_DVsmRcx.json5] +**/ + +#include "detail/IRuntimeContext_DVsmRcx.hpp" + +namespace xo { + namespace scm { + auto + IRuntimeContext_DVsmRcx::allocator(const DVsmRcx & self) noexcept -> obj + { + return self.allocator(); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IRuntimeContext_DVsmRcx.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 2b07791f..1569ccc0 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -6,12 +6,13 @@ #include "VirtualSchematikaMachine.hpp" #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" +#include "VsmRcx.hpp" #include "Closure.hpp" #include #include #include #include -#include +//#include #include #include #include @@ -31,13 +32,13 @@ namespace xo { namespace scm { - // NOTE: using heap for {DX1Collector, DSimpleRcx} instances - // (though allocation from explictly mmap'd memory) + // NOTE: using heap here for {DX1Collector, DVsmRcx} instances + // (though DX1Collector allocations will be from explictly mmap'd memory) // VirtualSchematikaMachine::VirtualSchematikaMachine(const VsmConfig & config) : config_{config}, mm_(box(new DX1Collector(config.x1_config_))), - rcx_(box(new DSimpleRcx(mm_.to_op()))), + rcx_(box(new DVsmRcx(this))), reader_{config.rdr_config_, mm_.to_op()} { // TODO: allocate global_env diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index 22757a48..5d1467e5 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -9,6 +9,7 @@ #include "VsmEvalArgsFrame.hpp" #include "Closure.hpp" #include "LocalEnv.hpp" +#include "VsmRcx.hpp" #include #include @@ -51,10 +52,16 @@ namespace xo { FacetRegistry::register_impl(); + // RuntimeContext + // \- VsmRcx + + FacetRegistry::register_impl(); + log && log(xtag("DVsmApplyFrame.tseq", typeseq::id())); log && log(xtag("DVsmEvalArgsFrame.tseq", typeseq::id())); log && log(xtag("DClosure.tseq", typeseq::id())); log && log(xtag("DLocalEnv.tseq", typeseq::id())); + log && log(xtag("DVsmRcx.tseq", typeseq::id())); return true; } diff --git a/xo-procedure2/idl/RuntimeContext.json5 b/xo-procedure2/idl/RuntimeContext.json5 index 8a1e125f..e80c0bc5 100644 --- a/xo-procedure2/idl/RuntimeContext.json5 +++ b/xo-procedure2/idl/RuntimeContext.json5 @@ -40,4 +40,5 @@ ], nonconst_methods: [ ], + router_facet_explicit_content: [ ], } From ce5232efd923a2caa7d48128a71a2257cfc9233d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 12 Feb 2026 18:46:43 -0500 Subject: [PATCH 182/258] xo-interpreter2 stack: work on runtime error representation [WIP] --- .../interpreter2/VirtualSchematikaMachine.hpp | 26 ++++-- .../include/xo/interpreter2/VsmConfig.hpp | 6 ++ xo-interpreter2/src/interpreter2/DClosure.cpp | 27 +++++- .../interpreter2/VirtualSchematikaMachine.cpp | 38 +++++++-- .../utest/VirtualSchematikaMachine.test.cpp | 2 - xo-object2/CMakeLists.txt | 28 +++++++ xo-object2/idl/IGCObject_DRuntimeError.json5 | 15 ++++ xo-object2/idl/IPrintable_DRuntimeError.json5 | 13 +++ .../include/xo/object2/DRuntimeError.hpp | 61 ++++++++++++++ .../include/xo/object2/RuntimeError.hpp | 12 +++ .../object2/error/IGCObject_DRuntimeError.hpp | 65 +++++++++++++++ .../error/IPrintable_DRuntimeError.hpp | 62 ++++++++++++++ xo-object2/src/object2/CMakeLists.txt | 40 +++++---- xo-object2/src/object2/DList.cpp | 4 +- xo-object2/src/object2/DRuntimeError.cpp | 82 +++++++++++++++++++ .../src/object2/IGCObject_DRuntimeError.cpp | 39 +++++++++ .../src/object2/IPrintable_DRuntimeError.cpp | 28 +++++++ .../src/object2/object2_register_facets.cpp | 5 ++ 18 files changed, 525 insertions(+), 28 deletions(-) create mode 100644 xo-object2/idl/IGCObject_DRuntimeError.json5 create mode 100644 xo-object2/idl/IPrintable_DRuntimeError.json5 create mode 100644 xo-object2/include/xo/object2/DRuntimeError.hpp create mode 100644 xo-object2/include/xo/object2/RuntimeError.hpp create mode 100644 xo-object2/include/xo/object2/error/IGCObject_DRuntimeError.hpp create mode 100644 xo-object2/include/xo/object2/error/IPrintable_DRuntimeError.hpp create mode 100644 xo-object2/src/object2/DRuntimeError.cpp create mode 100644 xo-object2/src/object2/IGCObject_DRuntimeError.cpp create mode 100644 xo-object2/src/object2/IPrintable_DRuntimeError.cpp diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index af551d04..39421981 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -10,6 +10,7 @@ #include "VsmFrame.hpp" #include "DLocalEnv.hpp" #include "DGlobalEnv.hpp" +#include #include #include #include @@ -17,6 +18,10 @@ namespace xo { namespace scm { +#ifdef OBSOLETE // see DVsmError + // TODO: move error to collected space? + // or special arena? + // struct EvaluationError { /** source location (in vsm implementation) at which error identified **/ std::string_view src_function_; @@ -24,6 +29,7 @@ namespace xo { std::string_view error_description_; // TODO: info about location in schematika source }; +#endif /** similar to @ref xo::scm::ReaderResult **/ struct VsmResult { @@ -31,17 +37,17 @@ namespace xo { using span_type = xo::mm::span; VsmResult() = default; - VsmResult(obj value) : result_{value} {} - VsmResult(TokenizerError err) : result_{err} {} + explicit VsmResult(obj value) : result_{value} {} + explicit VsmResult(TokenizerError err) : result_{err} {} bool is_value() const { return std::holds_alternative>(result_); } bool is_tk_error() const { return std::holds_alternative(result_); } - bool is_eval_error() const { return std::holds_alternative(result_); } + bool is_eval_error() const; const obj * value() const { return std::get_if>(&result_); } /** result of evaluating first expression encountered in input **/ - std::variant, TokenizerError, EvaluationError> result_; + std::variant, TokenizerError> result_; }; /** vsm result + reamining span **/ @@ -72,6 +78,8 @@ namespace xo { /** allocator for schematika data **/ obj allocator() const noexcept; + /** allocator for runtime errors **/ + obj error_allocator() const noexcept; /** visit vsm-owned memory pools; call visitor(info) for each **/ void visit_pools(const MemorySizeVisitor & visitor) const; @@ -185,11 +193,19 @@ namespace xo { /** configuration **/ VsmConfig config_; - /** allocator (likely collector) for + /** allocator (likely DX1Collector or similar) for * expressions and values **/ box mm_; + /** Sidecar allocator for error reporting. + * Separate to mitigate interference with @ref mm_ + * (separate memory so we can for example report + * an out-of-memory error). + * Likely DArena or similar + **/ + box error_mm_; + /** runtime context for this vsm. * For example, provides allocator to primitives **/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp index 9d13ab8e..63c4b365 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace xo { namespace scm { @@ -14,6 +15,7 @@ namespace xo { **/ struct VsmConfig { using X1CollectorConfig = xo::mm::X1CollectorConfig; + using ArenaConfig = xo::mm::ArenaConfig; VsmConfig() = default; @@ -26,6 +28,10 @@ namespace xo { * TODO: may want to make CollectorConfig polymorphic **/ X1CollectorConfig x1_config_ = X1CollectorConfig().with_size(4*1024*1024); + /** Configuration for error allocator + * TODO: may want to make ArenaConfig polymorphic + **/ + ArenaConfig error_config_ = ArenaConfig().with_size(64*1024); }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/DClosure.cpp b/xo-interpreter2/src/interpreter2/DClosure.cpp index d1baa172..7fa3698c 100644 --- a/xo-interpreter2/src/interpreter2/DClosure.cpp +++ b/xo-interpreter2/src/interpreter2/DClosure.cpp @@ -6,6 +6,8 @@ #include "Closure.hpp" #include "LambdaExpr.hpp" #include "LocalEnv.hpp" +#include "VsmRcx.hpp" +#include #include namespace xo { @@ -33,7 +35,30 @@ namespace xo { DClosure::apply_nocheck(obj rcx, const DArray * args) { - (void)rcx; + scope log(XO_DEBUG(true)); + + auto vsm_rcx + = obj::from(rcx); + + log && log(xtag("vsm_rcx.data", (void*)vsm_rcx.data())); + + // let's try a not-implemented error + + // don't want to clutter Procedure facet, since it's + // lower-level than xo-interpreter2 + +#ifdef NOT_YET + // TODO: verify arguments against type signature. + // unless we have evidence that program is type correct + + int32_t n_args = this->n_args(); + + if (n_args != args->size()) { + // + } +#endif + + (void)args; assert(false); diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 1569ccc0..abdfb168 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -15,6 +15,7 @@ //#include #include #include +#include #include #include #include @@ -27,12 +28,25 @@ namespace xo { //using xo::mm::MemorySizeInfo; // not used yet using xo::mm::AAllocator; using xo::mm::DX1Collector; + using xo::mm::DArena; using xo::facet::FacetRegistry; using std::cout; namespace scm { - // NOTE: using heap here for {DX1Collector, DVsmRcx} instances + bool + VsmResult::is_eval_error() const + { + if (std::holds_alternative>(result_)) { + auto err = obj::from(*(this->value())); + + return err; + } else { + return false; + } + } + + // NOTE: using heap here for {DX1Collector, DArena, DVsmRcx} instances // (though DX1Collector allocations will be from explictly mmap'd memory) // VirtualSchematikaMachine::VirtualSchematikaMachine(const VsmConfig & config) @@ -41,6 +55,14 @@ namespace xo { rcx_(box(new DVsmRcx(this))), reader_{config.rdr_config_, mm_.to_op()} { + { + DArena * arena = new DArena(); + assert(arena); + *arena = DArena::map(config_.error_config_); + + error_mm_.adopt(obj(arena)); + } + // TODO: allocate global_env } @@ -50,6 +72,12 @@ namespace xo { return mm_.to_op(); } + obj + VirtualSchematikaMachine::error_allocator() const noexcept + { + return error_mm_.to_op(); + } + void VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const { @@ -113,7 +141,7 @@ namespace xo { { this->pc_ = VsmInstr::c_eval; this->expr_ = expr; - this->value_ = obj(); + this->value_ = VsmResult(obj()); this->cont_ = VsmInstr::c_halt; this->run(); @@ -200,7 +228,7 @@ namespace xo { auto expr = obj::from(expr_); - this->value_ = expr.data()->value(); + this->value_ = VsmResult(expr.data()->value()); this->pc_ = this->cont_; } @@ -250,7 +278,7 @@ namespace xo { local_env_); this->value_ - = obj(obj(closure)); + = VsmResult(obj(obj(closure))); this->pc_ = this->cont_; } @@ -341,7 +369,7 @@ namespace xo { // TODO: check argument types - this->value_ = fn_.apply_nocheck(rcx_.to_op(), args_); + this->value_ = VsmResult(fn_.apply_nocheck(rcx_.to_op(), args_)); this->pc_ = cont_; return; diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 4213764b..5ccef226 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -225,7 +225,6 @@ namespace xo { vsm.visit_pools(visitor); } -#ifdef NOT_YET TEST_CASE("VirtualSchematikaMachine-apply2", "[interpreter2][VSM]") { scope log(XO_DEBUG(true)); @@ -265,7 +264,6 @@ namespace xo { FacetRegistry::instance().visit_pools(visitor); vsm.visit_pools(visitor); } -#endif } /*namespace ut*/ } /*namespace xo*/ diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index 83b24223..2fc0ae29 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -208,6 +208,34 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-printable-runtimeerror + FACET_PKG xo_printable2 + FACET Printable + REPR RuntimeError + INPUT idl/IPrintable_DRuntimeError.json5 + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR error + OUTPUT_CPP_DIR src/object2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-gcobject-runtimeerror + FACET_PKG xo_gc + FACET GCObject + REPR RuntimeError + INPUT idl/IGCObject_DRuntimeError.json5 + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR error + OUTPUT_CPP_DIR src/object2 +) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-object2-genfacet-all) # ---------------------------------------------------------------- diff --git a/xo-object2/idl/IGCObject_DRuntimeError.json5 b/xo-object2/idl/IGCObject_DRuntimeError.json5 new file mode 100644 index 00000000..9e416b24 --- /dev/null +++ b/xo-object2/idl/IGCObject_DRuntimeError.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ +// "", +// "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DRuntimeError", + using_doxygen: true, + repr: "DRuntimeError", + doc: [ "implement AGCObject for DRuntimeError" ], +} diff --git a/xo-object2/idl/IPrintable_DRuntimeError.json5 b/xo-object2/idl/IPrintable_DRuntimeError.json5 new file mode 100644 index 00000000..2d0f3eff --- /dev/null +++ b/xo-object2/idl/IPrintable_DRuntimeError.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DRuntimeError", + using_doxygen: true, + repr: "DRuntimeError", + doc: [ "implement APrintable for DRuntimeError" ], +} diff --git a/xo-object2/include/xo/object2/DRuntimeError.hpp b/xo-object2/include/xo/object2/DRuntimeError.hpp new file mode 100644 index 00000000..9da75c68 --- /dev/null +++ b/xo-object2/include/xo/object2/DRuntimeError.hpp @@ -0,0 +1,61 @@ +/** @file DRuntimeError.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "String.hpp" +#include + +namespace xo { + namespace scm { + + /** @brief representation for runtime errors + **/ + class DRuntimeError { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** create instance using memory from allocator @p mm + * @p src_fn identifies the (c++) function/method in which + * error detercted. + * @p error_descr contains human-readable error message; + * will be copied by this function. + **/ + DRuntimeError * _make(obj mm, + DString * src_fn, + DString * error_descr); + + /** @defgroup scm-runtimeerror-printable-facet printable facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-runtimeerror-gcobject-facet gcobject facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DRuntimeError * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} + + private: + DRuntimeError(DString * src_fn, DString * error_descr); + + private: + /** source location at which error identified **/ + DString * src_function_ = nullptr; + /** error description (allocated from ErrorArena) **/ + DString * error_descr_ = nullptr; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DRuntimeError.hpp */ diff --git a/xo-object2/include/xo/object2/RuntimeError.hpp b/xo-object2/include/xo/object2/RuntimeError.hpp new file mode 100644 index 00000000..c2a5f65d --- /dev/null +++ b/xo-object2/include/xo/object2/RuntimeError.hpp @@ -0,0 +1,12 @@ +/** @file RuntimeError.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DRuntimeError.hpp" +#include "error/IGCObject_DRuntimeError.hpp" +#include "error/IPrintable_DRuntimeError.hpp" + +/* end RuntimeError.hpp */ diff --git a/xo-object2/include/xo/object2/error/IGCObject_DRuntimeError.hpp b/xo-object2/include/xo/object2/error/IGCObject_DRuntimeError.hpp new file mode 100644 index 00000000..3bb4d3d8 --- /dev/null +++ b/xo-object2/include/xo/object2/error/IGCObject_DRuntimeError.hpp @@ -0,0 +1,65 @@ +/** @file IGCObject_DRuntimeError.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DRuntimeError.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DRuntimeError.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include "DRuntimeError.hpp" + +namespace xo { namespace scm { class IGCObject_DRuntimeError; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DRuntimeError + **/ + class IGCObject_DRuntimeError { + public: + /** @defgroup scm-gcobject-druntimeerror-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-druntimeerror-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DRuntimeError & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DRuntimeError & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DRuntimeError & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-object2/include/xo/object2/error/IPrintable_DRuntimeError.hpp b/xo-object2/include/xo/object2/error/IPrintable_DRuntimeError.hpp new file mode 100644 index 00000000..8b5a4d17 --- /dev/null +++ b/xo-object2/include/xo/object2/error/IPrintable_DRuntimeError.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DRuntimeError.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DRuntimeError.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DRuntimeError.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DRuntimeError.hpp" + +namespace xo { namespace scm { class IPrintable_DRuntimeError; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DRuntimeError + **/ + class IPrintable_DRuntimeError { + public: + /** @defgroup scm-printable-druntimeerror-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-druntimeerror-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DRuntimeError & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-object2/src/object2/CMakeLists.txt b/xo-object2/src/object2/CMakeLists.txt index 609290e8..a5595246 100644 --- a/xo-object2/src/object2/CMakeLists.txt +++ b/xo-object2/src/object2/CMakeLists.txt @@ -5,29 +5,41 @@ set(SELF_SRCS init_object2.cpp object2_register_types.cpp object2_register_facets.cpp + GCObjectConversion_DFloat.cpp GCObjectConversion_DInteger.cpp - IGCObject_DArray.cpp - IGCObject_DFloat.cpp - IGCObject_DBoolean.cpp - IGCObject_DInteger.cpp - IGCObject_DList.cpp - IGCObject_DString.cpp + ISequence_Any.cpp - ISequence_DArray.cpp - ISequence_DList.cpp - IPrintable_DArray.cpp - IPrintable_DList.cpp - IPrintable_DBoolean.cpp - IPrintable_DFloat.cpp - IPrintable_DInteger.cpp - IPrintable_DString.cpp + DArray.cpp + ISequence_DArray.cpp + IGCObject_DArray.cpp + IPrintable_DArray.cpp + DList.cpp + ISequence_DList.cpp + IGCObject_DList.cpp + IPrintable_DList.cpp + DFloat.cpp + IGCObject_DFloat.cpp + IPrintable_DFloat.cpp + DInteger.cpp + IGCObject_DInteger.cpp + IPrintable_DInteger.cpp + DBoolean.cpp + IGCObject_DBoolean.cpp + IPrintable_DBoolean.cpp + DString.cpp + IGCObject_DString.cpp + IPrintable_DString.cpp + + DRuntimeError.cpp + IGCObject_DRuntimeError.cpp + IPrintable_DRuntimeError.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/xo-object2/src/object2/DList.cpp b/xo-object2/src/object2/DList.cpp index 81512218..73c8cd0d 100644 --- a/xo-object2/src/object2/DList.cpp +++ b/xo-object2/src/object2/DList.cpp @@ -148,6 +148,8 @@ namespace xo { } } + // ----- GCObject facet ------ + auto DList::shallow_size() const noexcept -> size_type { @@ -175,7 +177,7 @@ namespace xo { auto iface = xo::facet::impl_for(); gc.forward_inplace(&iface, (void **)(&rest_)); - return shallow_size(); + return this->shallow_size(); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-object2/src/object2/DRuntimeError.cpp b/xo-object2/src/object2/DRuntimeError.cpp new file mode 100644 index 00000000..972bd0c8 --- /dev/null +++ b/xo-object2/src/object2/DRuntimeError.cpp @@ -0,0 +1,82 @@ +/** @file DRuntimeError.cpp +* + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DRuntimeError.hpp" + +namespace xo { + using xo::mm::AGCObject; + using xo::facet::typeseq; + + namespace scm { + + DRuntimeError * + DRuntimeError::_make(obj mm, + DString * src_fn, + DString * error_descr) + { + void * mem + = mm.alloc(typeseq::id(), + sizeof(DRuntimeError)); + + DRuntimeError * err + = new (mem) DRuntimeError(src_fn, error_descr); + + return err; + } + + DRuntimeError::DRuntimeError(DString * src_fn, + DString * error_descr) : src_function_{src_fn}, + error_descr_{error_descr} + {} + + // ----- GCObject facet ----- + + std::size_t + DRuntimeError::shallow_size() const noexcept + { + return sizeof(DRuntimeError); + } + + DRuntimeError * + DRuntimeError::shallow_copy(obj mm) const noexcept + { + DRuntimeError * copy = (DRuntimeError *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DRuntimeError::forward_children(obj gc) noexcept + { + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&src_function_)); + } + + { + auto iface = xo::facet::impl_for(); + gc.forward_inplace(&iface, (void **)(&error_descr_)); + } + + return this->shallow_size(); + } + + // ----- Printable facet ----- + + bool + DRuntimeError::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DRuntimeError"); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DRuntimeError.cpp */ + diff --git a/xo-object2/src/object2/IGCObject_DRuntimeError.cpp b/xo-object2/src/object2/IGCObject_DRuntimeError.cpp new file mode 100644 index 00000000..d44c4359 --- /dev/null +++ b/xo-object2/src/object2/IGCObject_DRuntimeError.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DRuntimeError.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DRuntimeError.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DRuntimeError.json5] +**/ + +#include "error/IGCObject_DRuntimeError.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DRuntimeError::shallow_size(const DRuntimeError & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DRuntimeError::shallow_copy(const DRuntimeError & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DRuntimeError::forward_children(DRuntimeError & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DRuntimeError.cpp */ diff --git a/xo-object2/src/object2/IPrintable_DRuntimeError.cpp b/xo-object2/src/object2/IPrintable_DRuntimeError.cpp new file mode 100644 index 00000000..eaf084ca --- /dev/null +++ b/xo-object2/src/object2/IPrintable_DRuntimeError.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DRuntimeError.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DRuntimeError.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DRuntimeError.json5] +**/ + +#include "error/IPrintable_DRuntimeError.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DRuntimeError::pretty(const DRuntimeError & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DRuntimeError.cpp */ diff --git a/xo-object2/src/object2/object2_register_facets.cpp b/xo-object2/src/object2/object2_register_facets.cpp index a910e276..c6358474 100644 --- a/xo-object2/src/object2/object2_register_facets.cpp +++ b/xo-object2/src/object2/object2_register_facets.cpp @@ -4,6 +4,7 @@ **/ #include "object2_register_facets.hpp" +#include "RuntimeError.hpp" #include #include @@ -66,6 +67,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DVariantPlaceholder.tseq", typeseq::id())); log && log(xtag("DList.tseq", typeseq::id())); @@ -74,6 +78,7 @@ namespace xo { log && log(xtag("DInteger.tseq", typeseq::id())); log && log(xtag("DString.tseq", typeseq::id())); log && log(xtag("DArray.tseq", typeseq::id())); + log && log(xtag("DRuntimeError.tseq", typeseq::id())); log && log(xtag("AAllocator.tseq", typeseq::id())); log && log(xtag("APrintable.tseq", typeseq::id())); From 5b97cddbcd829074e0a5ec26edc2bdbf70c0e3c5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 12 Feb 2026 20:09:22 -0500 Subject: [PATCH 183/258] xo-interpreter2 stack: work on apply for closures [WIP] --- .../include/xo/interpreter2/DLocalEnv.hpp | 10 +++--- .../include/xo/interpreter2/DVsmRcx.hpp | 1 + .../include/xo/interpreter2/VsmConfig.hpp | 2 +- xo-interpreter2/src/interpreter2/DClosure.cpp | 36 +++++++++++-------- .../src/interpreter2/DLocalEnv.cpp | 8 ++--- xo-interpreter2/src/interpreter2/DVsmRcx.cpp | 6 ++++ .../interpreter2/VirtualSchematikaMachine.cpp | 1 + .../utest/VirtualSchematikaMachine.test.cpp | 10 ++++-- .../include/xo/object2/DRuntimeError.hpp | 16 +++++++-- xo-object2/src/object2/DRuntimeError.cpp | 20 ++++++++++- 10 files changed, 79 insertions(+), 31 deletions(-) diff --git a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp index 234db71f..c99aaad1 100644 --- a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp @@ -26,15 +26,15 @@ namespace xo { /** @defgroup scm-localenv-constructors constructors **/ ///@{ - /** empty instance with parent @p p for variables in @p symtab **/ + /** create instance with parent @p p for variables in @p symtab **/ DLocalEnv(DLocalEnv * parent, DLocalSymtab * symtab, DArray * args); - static DLocalEnv * _make_empty(obj mm, - DLocalEnv * parent, - DLocalSymtab * symtab, - DArray * args); + static DLocalEnv * _make(obj mm, + DLocalEnv * parent, + DLocalSymtab * symtab, + DArray * args); ///@} /** @defgroup scm-local-env-methods methods **/ diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp index 3d6632a3..eeeb7289 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmRcx.hpp @@ -24,6 +24,7 @@ namespace xo { DVsmRcx(VirtualSchematikaMachine * vsm); obj allocator() const noexcept; + obj error_allocator() const noexcept; private: /** schematika interpreter **/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp index 63c4b365..f05ac449 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp @@ -31,7 +31,7 @@ namespace xo { /** Configuration for error allocator * TODO: may want to make ArenaConfig polymorphic **/ - ArenaConfig error_config_ = ArenaConfig().with_size(64*1024); + ArenaConfig error_config_ = ArenaConfig().with_name("error-reserve").with_size(64*1024); }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/DClosure.cpp b/xo-interpreter2/src/interpreter2/DClosure.cpp index 7fa3698c..8aa7997b 100644 --- a/xo-interpreter2/src/interpreter2/DClosure.cpp +++ b/xo-interpreter2/src/interpreter2/DClosure.cpp @@ -7,6 +7,7 @@ #include "LambdaExpr.hpp" #include "LocalEnv.hpp" #include "VsmRcx.hpp" +#include #include #include @@ -35,6 +36,8 @@ namespace xo { DClosure::apply_nocheck(obj rcx, const DArray * args) { + (void)args; + scope log(XO_DEBUG(true)); auto vsm_rcx @@ -42,26 +45,31 @@ namespace xo { log && log(xtag("vsm_rcx.data", (void*)vsm_rcx.data())); - // let's try a not-implemented error - - // don't want to clutter Procedure facet, since it's - // lower-level than xo-interpreter2 + // we already checked this stuff before calling apply_nocheck() + // assert (n_args == args->size()); #ifdef NOT_YET - // TODO: verify arguments against type signature. - // unless we have evidence that program is type correct - - int32_t n_args = this->n_args(); - - if (n_args != args->size()) { - // - } + auto local_env + = DLocalEnv::_make(vsm_rcx->allocator(), + env_, + lambda_->local_symtab(), + args); #endif + // plan: + // 1. push current local environment to vsm stack_ + // 2. set expr_ to lambda body + // 2. set pc_ to eval + // 3. set cont_ to restore local_env_ - (void)args; + auto err_mm + = vsm_rcx->error_allocator(); - assert(false); + auto err + = DRuntimeError::make(err_mm, + "DClosure::apply_nocheck", + "not implemented"); + return err; } size_t diff --git a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp index 9ee0911a..6866fda7 100644 --- a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp @@ -22,10 +22,10 @@ namespace xo { {} DLocalEnv * - DLocalEnv::_make_empty(obj mm, - DLocalEnv * parent, - DLocalSymtab * symtab, - DArray * args) + DLocalEnv::_make(obj mm, + DLocalEnv * parent, + DLocalSymtab * symtab, + DArray * args) { assert(symtab); diff --git a/xo-interpreter2/src/interpreter2/DVsmRcx.cpp b/xo-interpreter2/src/interpreter2/DVsmRcx.cpp index 92e153bc..71916771 100644 --- a/xo-interpreter2/src/interpreter2/DVsmRcx.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmRcx.cpp @@ -19,6 +19,12 @@ namespace xo { return vsm_->allocator(); } + obj + DVsmRcx::error_allocator() const noexcept + { + return vsm_->error_allocator(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index abdfb168..641723f9 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -82,6 +82,7 @@ namespace xo { VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const { mm_.visit_pools(visitor); + error_mm_.visit_pools(visitor); reader_.visit_pools(visitor); } diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 5ccef226..22b50194 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -6,9 +6,8 @@ #include #include #include -//#include #include -//#include +#include #ifdef NOT_YET #include @@ -32,6 +31,7 @@ namespace xo { using xo::scm::DClosure; using xo::scm::DFloat; using xo::scm::DInteger; + using xo::scm::DRuntimeError; using xo::mm::AGCObject; using xo::mm::MemorySizeInfo; using xo::facet::FacetRegistry; @@ -245,9 +245,13 @@ namespace xo { log && log(xtag("res.tseq", res.value()->_typeseq())); - auto x = obj::from(*res.value()); + // currently get not-implemented error + auto x = obj::from(*res.value()); REQUIRE(x); + + log && log("runtime-error", xtag("ex.src", x->src_function()), xtag("ex.descr", x->error_descr())); + //REQUIRE(x.data()->value() == 1.570796325); REQUIRE(res.remaining_.size() == 1); diff --git a/xo-object2/include/xo/object2/DRuntimeError.hpp b/xo-object2/include/xo/object2/DRuntimeError.hpp index 9da75c68..c59de59d 100644 --- a/xo-object2/include/xo/object2/DRuntimeError.hpp +++ b/xo-object2/include/xo/object2/DRuntimeError.hpp @@ -6,6 +6,7 @@ #pragma once #include "String.hpp" +#include #include namespace xo { @@ -15,20 +16,29 @@ namespace xo { **/ class DRuntimeError { public: + using AGCObject = xo::mm::AGCObject; using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using ppindentinfo = xo::print::ppindentinfo; public: + /** convenience shortcut.**/ + static obj make(obj mm, + const char * src_fn, + const char * error_descr); + /** create instance using memory from allocator @p mm * @p src_fn identifies the (c++) function/method in which * error detercted. * @p error_descr contains human-readable error message; * will be copied by this function. **/ - DRuntimeError * _make(obj mm, - DString * src_fn, - DString * error_descr); + static DRuntimeError * _make(obj mm, + DString * src_fn, + DString * error_descr); + + DString * src_function() const noexcept { return src_function_; } + DString * error_descr() const noexcept { return error_descr_; } /** @defgroup scm-runtimeerror-printable-facet printable facet **/ ///@{ diff --git a/xo-object2/src/object2/DRuntimeError.cpp b/xo-object2/src/object2/DRuntimeError.cpp index 972bd0c8..2b9fa62f 100644 --- a/xo-object2/src/object2/DRuntimeError.cpp +++ b/xo-object2/src/object2/DRuntimeError.cpp @@ -3,7 +3,7 @@ * @author Roland Conybeare, Feb 2026 **/ -#include "DRuntimeError.hpp" +#include "RuntimeError.hpp" namespace xo { using xo::mm::AGCObject; @@ -11,6 +11,24 @@ namespace xo { namespace scm { + obj + DRuntimeError::make(obj mm, + const char * src_fn, + const char * error_descr) + { + DRuntimeError * err = DRuntimeError::_make(mm, nullptr, nullptr); + + // pedantic: allocate strings after allocating DRuntimeError instance + + DString * src = DString::from_cstr(mm, src_fn); + DString * err_descr = DString::from_cstr(mm, error_descr); + + err->src_function_ = src; + err->error_descr_ = err_descr; + + return obj(err); + } + DRuntimeError * DRuntimeError::_make(obj mm, DString * src_fn, From 0ab3b63a3847b80b331b63cc87bb141c277c3257 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 00:09:43 -0500 Subject: [PATCH 184/258] xo-interpreter2: + VsmApplyClosureFrame [WIP, not used] --- xo-interpreter2/CMakeLists.txt | 26 +++++++ .../idl/IGCObject_DVsmApplyClosureFrame.json5 | 15 +++++ .../IPrintable_DVsmApplyClosureFrame.json5 | 13 ++++ .../xo/interpreter2/DVsmApplyClosureFrame.hpp | 52 ++++++++++++++ .../xo/interpreter2/DVsmApplyFrame.hpp | 9 ++- .../interpreter2/VirtualSchematikaMachine.hpp | 7 +- .../xo/interpreter2/VsmApplyClosureFrame.hpp | 12 ++++ .../IGCObject_DVsmApplyClosureFrame.hpp | 67 +++++++++++++++++++ .../IPrintable_DVsmApplyClosureFrame.hpp | 62 +++++++++++++++++ .../src/interpreter2/CMakeLists.txt | 4 ++ .../interpreter2/DVsmApplyClosureFrame.cpp | 59 ++++++++++++++++ .../src/interpreter2/DVsmApplyFrame.cpp | 5 +- .../src/interpreter2/DVsmEvalArgsFrame.cpp | 3 +- .../IGCObject_DVsmApplyClosureFrame.cpp | 39 +++++++++++ .../IPrintable_DVsmApplyClosureFrame.cpp | 28 ++++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 2 +- .../interpreter2_register_facets.cpp | 19 ++++-- 17 files changed, 410 insertions(+), 12 deletions(-) create mode 100644 xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 create mode 100644 xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmApplyClosureFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmApplyClosureFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmApplyClosureFrame.hpp create mode 100644 xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DVsmApplyClosureFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DVsmApplyClosureFrame.cpp diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 6f3b14bc..ae8893a6 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -77,6 +77,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-vsmapplyclosureframe + FACET_PKG xo_gc + FACET GCObject + REPR VsmApplyClosureFrame + INPUT idl/IGCObject_DVsmApplyClosureFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-vsmapplyclosureframe + FACET_PKG xo_printable2 + FACET Printable + REPR DVsmApplyClosureFrame + INPUT idl/IPrintable_DVsmApplyClosureFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/interpreter2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-interpreter2-facetimpl-procedure-closure diff --git a/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 new file mode 100644 index 00000000..398d53e9 --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVsmApplyClosureFrame", + using_doxygen: true, + repr: "DVsmApplyClosureFrame", + doc: [ "implement AGCObject for DVsmApplyClosureFrame" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 new file mode 100644 index 00000000..717aa85f --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVsmApplyClosureFrame", + using_doxygen: true, + repr: "DVsmApplyClosureFrame", + doc: [ "implement APrintable for DVsmApplyClosureFrame" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp new file mode 100644 index 00000000..185b818f --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp @@ -0,0 +1,52 @@ +/** @file DVsmApplyClosureFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "VsmInstr.hpp" +#include "DLocalEnv.hpp" +#include + +namespace xo { + namespace scm { + + /** Frame to preserve VSM registers: + * (stack_, parent_, cont_) + * while applying a closure. + **/ + class DVsmApplyClosureFrame { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using ppindentinfo = xo::print::ppindentinfo; + + public: + DVsmApplyClosureFrame(obj stack, + VsmInstr cont, + DLocalEnv * env); + + /** gcobject facet **/ + std::size_t shallow_size() const noexcept; + DVsmApplyClosureFrame * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + protected: + /** saved VSM stack_ register **/ + obj stack_; + /** saved VSM cont_ register **/ + VsmInstr cont_; + /** saved VSM local_env_ register **/ + DLocalEnv * local_env_ = nullptr; + }; + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmApplyClosureFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp index 72900eb2..b4b46de2 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp @@ -9,11 +9,12 @@ namespace xo { namespace scm { - class DVsmApplyFrame : public VsmFrame { + class DVsmApplyFrame { public: using AProcedure = xo::scm::AProcedure; using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; using ppindentinfo = xo::print::ppindentinfo; public: @@ -27,6 +28,8 @@ namespace xo { VsmInstr old_cont, DArray * args); + obj parent() const noexcept { return parent_; } + VsmInstr cont() const noexcept { return cont_; } obj fn() const noexcept { return fn_; } DArray * args() const noexcept { return args_; } @@ -40,6 +43,10 @@ namespace xo { bool pretty(const ppindentinfo & ppii) const; private: + /** saved VSM stack; restore when this frame consumed **/ + obj parent_; + /** saved continuation; restore when this frame consumed **/ + VsmInstr cont_; /** evaluated target procedure. * * note: when initially created, this will be unpopulated; diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 39421981..67307700 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -21,7 +21,7 @@ namespace xo { #ifdef OBSOLETE // see DVsmError // TODO: move error to collected space? // or special arena? - // + // struct EvaluationError { /** source location (in vsm implementation) at which error identified **/ std::string_view src_function_; @@ -182,9 +182,10 @@ namespace xo { * stack_ * cont_ * - * Other registers are not preserved + * Other registers not preserved * pc_ * expr_ + * local_env_ * fn_ * args_ * value_ @@ -200,7 +201,7 @@ namespace xo { /** Sidecar allocator for error reporting. * Separate to mitigate interference with @ref mm_ - * (separate memory so we can for example report + * (separate memory so we can for example report * an out-of-memory error). * Likely DArena or similar **/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmApplyClosureFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmApplyClosureFrame.hpp new file mode 100644 index 00000000..09b68d09 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmApplyClosureFrame.hpp @@ -0,0 +1,12 @@ +/** @file VsmApplyClosureFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVsmApplyClosureFrame.hpp" +#include "detail/IGCObject_DVsmApplyClosureFrame.hpp" +#include "detail/IPrintable_DVsmApplyClosureFrame.hpp" + +/* end VsmApplyClosureFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmApplyClosureFrame.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmApplyClosureFrame.hpp new file mode 100644 index 00000000..2baacd05 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IGCObject_DVsmApplyClosureFrame.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVsmApplyClosureFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmApplyClosureFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmApplyClosureFrame.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVsmApplyClosureFrame.hpp" + +namespace xo { namespace scm { class IGCObject_DVsmApplyClosureFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVsmApplyClosureFrame + **/ + class IGCObject_DVsmApplyClosureFrame { + public: + /** @defgroup scm-gcobject-dvsmapplyclosureframe-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvsmapplyclosureframe-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVsmApplyClosureFrame & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVsmApplyClosureFrame & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVsmApplyClosureFrame & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmApplyClosureFrame.hpp b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmApplyClosureFrame.hpp new file mode 100644 index 00000000..f2e5a072 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/detail/IPrintable_DVsmApplyClosureFrame.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVsmApplyClosureFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmApplyClosureFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmApplyClosureFrame.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVsmApplyClosureFrame.hpp" + +namespace xo { namespace scm { class IPrintable_DVsmApplyClosureFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVsmApplyClosureFrame + **/ + class IPrintable_DVsmApplyClosureFrame { + public: + /** @defgroup scm-printable-dvsmapplyclosureframe-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvsmapplyclosureframe-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVsmApplyClosureFrame & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index f6fbd10b..4a477874 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -16,6 +16,10 @@ set(SELF_SRCS IGCObject_DVsmApplyFrame.cpp IPrintable_DVsmApplyFrame.cpp + DVsmApplyClosureFrame.cpp + IGCObject_DVsmApplyClosureFrame.cpp + IPrintable_DVsmApplyClosureFrame.cpp + DClosure.cpp IProcedure_DClosure.cpp IGCObject_DClosure.cpp diff --git a/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp new file mode 100644 index 00000000..b7962ebd --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp @@ -0,0 +1,59 @@ +/** @file DVsmApplyClosureFrame.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVsmApplyClosureFrame.hpp" + +namespace xo { + using xo::mm::AGCObject; + + namespace scm { + + DVsmApplyClosureFrame::DVsmApplyClosureFrame(obj stack, + VsmInstr cont, + DLocalEnv * local_env) + : stack_{stack}, + cont_{cont}, + local_env_{local_env} + {} + + std::size_t + DVsmApplyClosureFrame::shallow_size() const noexcept + { + return sizeof(DVsmApplyClosureFrame); + } + + DVsmApplyClosureFrame * + DVsmApplyClosureFrame::shallow_copy(obj mm) const noexcept + { + DVsmApplyClosureFrame * copy + = (DVsmApplyClosureFrame *)mm.alloc_copy((std::byte *)this); + + if (copy) + *copy = *this; + + return copy; + } + + std::size_t + DVsmApplyClosureFrame::forward_children(obj gc) noexcept + { + (void)gc; + + return this->shallow_size(); + } + + bool + DVsmApplyClosureFrame::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DVsmApplyClosureFrame", + refrtag("cont", cont_), + refrtag("env", local_env_)); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmApplyClosureFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp index 75da5877..55d59b37 100644 --- a/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp @@ -14,8 +14,9 @@ namespace xo { DVsmApplyFrame::DVsmApplyFrame(obj old_parent, VsmInstr old_cont, DArray * args) - : VsmFrame(old_parent, old_cont), - args_{args} + : parent_{old_parent}, + cont_{old_cont}, + args_{args} {} DVsmApplyFrame * diff --git a/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp index 01391cf2..1ca470e9 100644 --- a/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp @@ -49,7 +49,8 @@ namespace xo { DVsmEvalArgsFrame * DVsmEvalArgsFrame::shallow_copy(obj mm) const noexcept { - DVsmEvalArgsFrame * copy = (DVsmEvalArgsFrame *)mm.alloc_copy((std::byte *)this); + DVsmEvalArgsFrame * copy + = (DVsmEvalArgsFrame *)mm.alloc_copy((std::byte *)this); if (copy) *copy = *this; diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DVsmApplyClosureFrame.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DVsmApplyClosureFrame.cpp new file mode 100644 index 00000000..7a05d47e --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DVsmApplyClosureFrame.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVsmApplyClosureFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmApplyClosureFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmApplyClosureFrame.json5] +**/ + +#include "detail/IGCObject_DVsmApplyClosureFrame.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVsmApplyClosureFrame::shallow_size(const DVsmApplyClosureFrame & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVsmApplyClosureFrame::shallow_copy(const DVsmApplyClosureFrame & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVsmApplyClosureFrame::forward_children(DVsmApplyClosureFrame & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVsmApplyClosureFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DVsmApplyClosureFrame.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DVsmApplyClosureFrame.cpp new file mode 100644 index 00000000..36b89a10 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DVsmApplyClosureFrame.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVsmApplyClosureFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmApplyClosureFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmApplyClosureFrame.json5] +**/ + +#include "detail/IPrintable_DVsmApplyClosureFrame.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVsmApplyClosureFrame::pretty(const DVsmApplyClosureFrame & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVsmApplyClosureFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 641723f9..1242375a 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -62,7 +62,7 @@ namespace xo { error_mm_.adopt(obj(arena)); } - + // TODO: allocate global_env } diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index 5d1467e5..f945956e 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -5,8 +5,11 @@ #include "interpreter2_register_facets.hpp" +#include "DPrimitive_gco_2_gco_gco.hpp" #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" +#include "VsmApplyClosureFrame.hpp" +#include "Primitive_gco_2_gco_gco.hpp" #include "Closure.hpp" #include "LocalEnv.hpp" #include "VsmRcx.hpp" @@ -31,7 +34,8 @@ namespace xo { // VsmStackFrame // +- VsmApplyFrame - // \- VsmEvalArgsFrame + // +- VsmEvalArgsFrame + // \- VsmApplyClosureFrame FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -39,9 +43,10 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); - FacetRegistry::register_impl(); - FacetRegistry::register_impl(); - FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + // LocalEnv FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -50,7 +55,13 @@ namespace xo { // +- Primitive_gco_2_gco_gco // \- Closure + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); // RuntimeContext // \- VsmRcx From af4c37c5756c7cd88aefbacb23f5f7be52f6243e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 02:05:47 -0500 Subject: [PATCH 185/258] xo-interpreter2 stack: invoke closures w/ tail-call opt [WIP] --- .../include/xo/expression2/DLambdaExpr.hpp | 1 + xo-interpreter2/CMakeLists.txt | 21 ++-- .../include/xo/interpreter2/Closure.hpp | 2 +- .../xo/interpreter2/DVsmApplyClosureFrame.hpp | 10 ++ .../xo/interpreter2/DVsmApplyFrame.hpp | 12 ++- .../interpreter2/VirtualSchematikaMachine.hpp | 18 +++- .../include/xo/interpreter2/VsmInstr.hpp | 8 ++ .../include/xo/interpreter2/VsmOpcode.hpp | 5 + .../src/interpreter2/CMakeLists.txt | 1 - xo-interpreter2/src/interpreter2/DClosure.cpp | 25 ++--- .../interpreter2/DVsmApplyClosureFrame.cpp | 13 +++ .../src/interpreter2/IProcedure_DClosure.cpp | 39 -------- .../interpreter2/VirtualSchematikaMachine.cpp | 97 +++++++++++++++++-- xo-interpreter2/src/interpreter2/VsmInstr.cpp | 4 + .../interpreter2_register_facets.cpp | 6 +- 15 files changed, 175 insertions(+), 87 deletions(-) delete mode 100644 xo-interpreter2/src/interpreter2/IProcedure_DClosure.cpp diff --git a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp index b21a37ce..30ed2b74 100644 --- a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp @@ -63,6 +63,7 @@ namespace xo { DLocalSymtab * local_symtab() const noexcept { return local_symtab_; } size_type n_args() const noexcept { return local_symtab_->size(); } + obj body_expr() const noexcept { return body_expr_; } // get_free_variables() // visit_preorder() diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index ae8893a6..8a1b1b3c 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -104,16 +104,17 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- # note: manual target; generated code committed to git -xo_add_genfacetimpl( - TARGET xo-interpreter2-facetimpl-procedure-closure - FACET_PKG xo_procedure2 - FACET Procedure - REPR Closure - INPUT idl/IProcedure_DClosure.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 -) +# +#xo_add_genfacetimpl( +# TARGET xo-interpreter2-facetimpl-procedure-closure +# FACET_PKG xo_procedure2 +# FACET Procedure +# REPR Closure +# INPUT idl/IProcedure_DClosure.json5 +# OUTPUT_HPP_DIR include/xo/interpreter2 +# OUTPUT_IMPL_SUBDIR detail +# OUTPUT_CPP_DIR src/interpreter2 +#) # note: manual target; generated code committed to git xo_add_genfacetimpl( diff --git a/xo-interpreter2/include/xo/interpreter2/Closure.hpp b/xo-interpreter2/include/xo/interpreter2/Closure.hpp index 5bbeb9b8..dc9272fe 100644 --- a/xo-interpreter2/include/xo/interpreter2/Closure.hpp +++ b/xo-interpreter2/include/xo/interpreter2/Closure.hpp @@ -6,7 +6,7 @@ #pragma once #include "DClosure.hpp" -#include "detail/IProcedure_DClosure.hpp" +//#include "detail/IProcedure_DClosure.hpp" #include "detail/IGCObject_DClosure.hpp" #include "detail/IPrintable_DClosure.hpp" diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp index 185b818f..a98d5713 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp @@ -28,6 +28,16 @@ namespace xo { VsmInstr cont, DLocalEnv * env); + /** create instance, using memory from @p mm **/ + static DVsmApplyClosureFrame * make(obj mm, + obj stack, + VsmInstr cont, + DLocalEnv * env); + + obj stack() const { return stack_; } + VsmInstr cont() const { return cont_; } + DLocalEnv * local_env() const { return local_env_; } + /** gcobject facet **/ std::size_t shallow_size() const noexcept; DVsmApplyClosureFrame * shallow_copy(obj mm) const noexcept; diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp index b4b46de2..a5df3504 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp @@ -30,10 +30,10 @@ namespace xo { obj parent() const noexcept { return parent_; } VsmInstr cont() const noexcept { return cont_; } - obj fn() const noexcept { return fn_; } + obj fn() const noexcept { return fn_; } DArray * args() const noexcept { return args_; } - void assign_fn(obj x) { this->fn_ = x; } + void assign_fn(obj x) { this->fn_ = x; } std::size_t shallow_size() const noexcept; DVsmApplyFrame * shallow_copy(obj mm) const noexcept; @@ -51,9 +51,13 @@ namespace xo { * * note: when initially created, this will be unpopulated; * don't know correct value until we evaluate - * expression in head position + * expression in head position. + * + * Must exhibit either: + * 1. AProcedure facet (runs natively) + * 2. AVsmProcedure facet (requires schematika runtime) **/ - obj fn_; + obj fn_; /** evaluated arguments (to target procedure) **/ DArray * args_; }; diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 67307700..569d9d48 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -176,16 +176,28 @@ namespace xo { **/ void _do_evalargs_op(); + /** call closure @ref fn_ with arguments @ref args_ **/ + void _do_call_closure_op(); + /** call primitive @ref fn_ with arguments @ref args_ **/ + void _do_call_primitive_op(); + + /** restore registers from stack frame + * (specifically: local_env_, stack_, cont_) + * after invoking a schematika closure + **/ + void _do_applycoda_op(); + + private: /* * Some registers are preserved by evaluation: * stack_ * cont_ + * local_env_ * * Other registers not preserved * pc_ * expr_ - * local_env_ * fn_ * args_ * value_ @@ -244,8 +256,8 @@ namespace xo { DGlobalEnv * global_env_ = nullptr; private: - /** function to call **/ - obj fn_; + /** evaluated function to call **/ + obj fn_; /** evaluated argument list **/ DArray * args_; diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index ec836c4d..bdde3ab7 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -19,12 +19,20 @@ namespace xo { static VsmInstr c_apply; static VsmInstr c_evalargs; + /** restore registers after calling a schematika closure **/ + static VsmInstr c_applycoda; + vsm_opcode opcode() const noexcept { return opcode_; } private: vsm_opcode opcode_; }; + inline bool + operator==(VsmInstr x, VsmInstr y) noexcept { + return x.opcode() == y.opcode(); + } + inline std::ostream & operator<<(std::ostream & os, VsmInstr x) { os << x.opcode(); diff --git a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp index 2c58c04f..ec21b988 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp @@ -28,6 +28,11 @@ namespace xo { **/ evalargs, + /** Coda to restore vsm registers (local_env, stack, cont) + * after invoking a closure + **/ + applycoda, + /** sentinel, counts number of opcodes **/ N, }; diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 4a477874..1ddb3207 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -21,7 +21,6 @@ set(SELF_SRCS IPrintable_DVsmApplyClosureFrame.cpp DClosure.cpp - IProcedure_DClosure.cpp IGCObject_DClosure.cpp IPrintable_DClosure.cpp diff --git a/xo-interpreter2/src/interpreter2/DClosure.cpp b/xo-interpreter2/src/interpreter2/DClosure.cpp index 8aa7997b..53015068 100644 --- a/xo-interpreter2/src/interpreter2/DClosure.cpp +++ b/xo-interpreter2/src/interpreter2/DClosure.cpp @@ -36,6 +36,14 @@ namespace xo { DClosure::apply_nocheck(obj rcx, const DArray * args) { + // control here only if you try to invoke a closure + // as a procedure. + // + // May support this later, but requires + // nesting VSM (because call consumes c++ stack) + // + // typically prefer trampoline built into VSM + (void)args; scope log(XO_DEBUG(true)); @@ -45,23 +53,6 @@ namespace xo { log && log(xtag("vsm_rcx.data", (void*)vsm_rcx.data())); - // we already checked this stuff before calling apply_nocheck() - // assert (n_args == args->size()); - -#ifdef NOT_YET - auto local_env - = DLocalEnv::_make(vsm_rcx->allocator(), - env_, - lambda_->local_symtab(), - args); -#endif - - // plan: - // 1. push current local environment to vsm stack_ - // 2. set expr_ to lambda body - // 2. set pc_ to eval - // 3. set cont_ to restore local_env_ - auto err_mm = vsm_rcx->error_allocator(); diff --git a/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp index b7962ebd..6a86ce27 100644 --- a/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp @@ -7,6 +7,7 @@ namespace xo { using xo::mm::AGCObject; + using xo::reflect::typeseq; namespace scm { @@ -18,6 +19,18 @@ namespace xo { local_env_{local_env} {} + DVsmApplyClosureFrame * + DVsmApplyClosureFrame::make(obj mm, + obj stack, + VsmInstr cont, + DLocalEnv * local_env) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DVsmApplyClosureFrame)); + + return new (mem) DVsmApplyClosureFrame(stack, cont, local_env); + } + std::size_t DVsmApplyClosureFrame::shallow_size() const noexcept { diff --git a/xo-interpreter2/src/interpreter2/IProcedure_DClosure.cpp b/xo-interpreter2/src/interpreter2/IProcedure_DClosure.cpp deleted file mode 100644 index b41c7be1..00000000 --- a/xo-interpreter2/src/interpreter2/IProcedure_DClosure.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/** @file IProcedure_DClosure.cpp - * - * Generated automagically from ingredients: - * 1. code generator: - * [xo-facet/codegen/genfacet] - * arguments: - * --input [idl/IProcedure_DClosure.json5] - * 2. jinja2 template for abstract facet .hpp file: - * [iface_facet_any.hpp.j2] - * 3. idl for facet methods - * [idl/IProcedure_DClosure.json5] -**/ - -#include "detail/IProcedure_DClosure.hpp" - -namespace xo { - namespace scm { - auto - IProcedure_DClosure::is_nary(const DClosure & self) noexcept -> bool - { - return self.is_nary(); - } - - auto - IProcedure_DClosure::n_args(const DClosure & self) noexcept -> std::int32_t - { - return self.n_args(); - } - - auto - IProcedure_DClosure::apply_nocheck(DClosure & self, obj rcx, const DArray * args) -> obj - { - return self.apply_nocheck(rcx, args); - } - - } /*namespace scm*/ -} /*namespace xo*/ - -/* end IProcedure_DClosure.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 1242375a..8ff78ae0 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -6,6 +6,7 @@ #include "VirtualSchematikaMachine.hpp" #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" +#include "VsmApplyClosureFrame.hpp" #include "VsmRcx.hpp" #include "Closure.hpp" #include @@ -164,9 +165,9 @@ namespace xo { log && log(xtag("pc", pc_), xtag("cont", cont_)); - obj stack_pr - = (FacetRegistry::instance() - .try_variant(stack_)); + obj stack_pr = stack_.to_facet(); +// = (FacetRegistry::instance() +// .try_variant(stack_)); if (stack_pr) log && log(xtag("stack", stack_pr)); @@ -184,6 +185,9 @@ namespace xo { case vsm_opcode::evalargs: _do_evalargs_op(); break; + case vsm_opcode::applycoda: + _do_applycoda_op(); + break; } return true; @@ -370,10 +374,68 @@ namespace xo { // TODO: check argument types - this->value_ = VsmResult(fn_.apply_nocheck(rcx_.to_op(), args_)); - this->pc_ = cont_; + auto closure = obj::from(fn_); - return; + if (closure) { + _do_call_closure_op(); + return; + } else { + _do_call_closure_op(); + return; + } + } + + void + VirtualSchematikaMachine::_do_call_closure_op() + { + // We need to preserve registers while evaluating + // lambda body + + auto closure = obj::from(fn_); + + // TODO: for tail recursion: + // check whether stack_ already refers to a + // DVsmApplyClosureFrame instance, in which case + // we can just refer to it instead of pushing a new one + + if (cont_ == VsmInstr::c_applycoda) { + // we are making a tail call. + // No need to preserve (stack, cont, local_env), + // since continuation will restore on top of them + // frame top stackframe anyway + } else { + obj frame( + DVsmApplyClosureFrame::make(mm_.to_op(), + stack_, + cont_, + local_env_)); + + // push frame w/ saved vsm registers + this->stack_ = frame; + this->cont_ = VsmInstr::c_applycoda; + } + + auto lambda = closure->lambda(); + + auto local_env + = DLocalEnv::_make(mm_.to_op(), + local_env_, + lambda->local_symtab(), + args_); + + this->local_env_ = local_env; + this->expr_ = lambda->body_expr(); + this->pc_ = VsmInstr::c_eval; + } + + void + VirtualSchematikaMachine::_do_call_primitive_op() + { + auto fn = fn_.to_facet(); + + this->value_ = VsmResult(fn.apply_nocheck(rcx_.to_op(), args_)); + this->pc_ = cont_; } void @@ -434,10 +496,11 @@ namespace xo { = evalargs_frame->apply_expr(); if (i_arg == -1) { - auto fn = value.to_facet(); + bool is_native_fn = value.to_facet(); + bool is_closure = obj::from(value); - if (fn) { - apply_frame->assign_fn(fn); + if (is_native_fn || is_closure) { + apply_frame->assign_fn(value); i_arg = evalargs_frame->increment_arg(); @@ -493,6 +556,22 @@ namespace xo { assert(false); } + void + VirtualSchematikaMachine::_do_applycoda_op() + { + // see DVsmApplyClosureFrame + + auto frame = obj::from(stack_); + + assert(frame); + + this->stack_ = frame->stack(); + this->local_env_ = frame->local_env(); + this->pc_ = frame->cont(); + + // not implemented + assert(false); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp index ddcc8c20..02ac8325 100644 --- a/xo-interpreter2/src/interpreter2/VsmInstr.cpp +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -15,6 +15,7 @@ namespace xo { case vsm_opcode::eval: return "eval"; case vsm_opcode::apply: return "apply"; case vsm_opcode::evalargs: return "evalargs"; + case vsm_opcode::applycoda: return "applycoda"; case vsm_opcode::N: break; } @@ -33,6 +34,9 @@ namespace xo { VsmInstr VsmInstr::c_evalargs = VsmInstr(vsm_opcode::evalargs); + + VsmInstr + VsmInstr::c_applycoda = VsmInstr(vsm_opcode::applycoda); } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index f945956e..1548aeaf 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -59,9 +59,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); - FacetRegistry::register_impl(); - FacetRegistry::register_impl(); - FacetRegistry::register_impl(); +// FacetRegistry::register_impl(); +// FacetRegistry::register_impl(); +// FacetRegistry::register_impl(); // RuntimeContext // \- VsmRcx From bfae3931278459f01465787b08e99cd5a24ecc26 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 15:15:08 -0500 Subject: [PATCH 186/258] xo-gc stack: streamline object pointer forwarding --- .../include/xo/alloc2/alloc/RAllocator.hpp | 13 +++++++ xo-facet/include/xo/facet/FacetRegistry.hpp | 39 +++++++++++++++---- xo-facet/include/xo/facet/obj.hpp | 6 +++ xo-gc/idl/GCObject.json5 | 2 +- xo-gc/include/xo/gc/GCObject.hpp | 28 ++++++++++++- xo-gc/include/xo/gc/detail/RCollector.hpp | 10 +++++ 6 files changed, 89 insertions(+), 9 deletions(-) diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index ecd80bb7..62552411 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -36,6 +36,19 @@ namespace xo { return O::iface()->alloc(O::data(), typeseq::id(), sizeof(T)); } + template + T * std_copy_for(const T * src) noexcept { + // TODO: fix alloc_copy(), should take const std::byte * + + T * copy = (T *)O::iface()->alloc_copy(O::data(), (std::byte*)const_cast(src)); + + if (copy) { + *copy = *src; + } + + return copy; + } + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } void _drop() const noexcept { O::iface()->_drop(O::data()); } std::string_view name() const noexcept { return O::iface()->name(O::data()); } diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index d4b15188..9b7e7ade 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -159,7 +159,7 @@ namespace xo { * } **/ template - obj try_variant(obj from) { + obj try_variant(obj from) noexcept { return try_variant(from._typeseq(), from.data()); } @@ -173,7 +173,7 @@ namespace xo { * = FacetRegistry::variant(foo._typeseq(), foo.opaque_data()); **/ template - obj try_variant(typeseq repr_id, void * data) { + obj try_variant(typeseq repr_id, void * data) noexcept { const AFacet * iface = this->lookup(repr_id); if (iface) @@ -246,12 +246,37 @@ namespace xo { obj obj::to_facet() { - if constexpr (std::is_same_v) { - // return type has type-erased data - return FacetRegistry::instance().variant(*this); + if (this->data()) { + if constexpr (std::is_same_v) { + // return type has type-erased data + return FacetRegistry::instance().variant(*this); + } else { + // return type has known data + return obj(this->data()); + } } else { - // return type has known data - return obj(this->data()); + return obj(); + } + } + + // Deferred definitioon of obj::to_facet(), + // since implementation requires FacetRegistry + // + template + template + obj + obj::try_to_facet() noexcept + { + if (this->data()) { + if constexpr (std::is_same_v) { + // return type has type-erased data + return FacetRegistry::instance().try_variant(*this); + } else { + // return type has known data + return obj(this->data()); + } + } else { + return obj(); } } diff --git a/xo-facet/include/xo/facet/obj.hpp b/xo-facet/include/xo/facet/obj.hpp index 3619ae3e..ada5c832 100644 --- a/xo-facet/include/xo/facet/obj.hpp +++ b/xo-facet/include/xo/facet/obj.hpp @@ -137,6 +137,12 @@ namespace xo { template obj to_facet(); + /** like to_facet(), + * but on failure return empty obj instead of throwing exception + **/ + template + obj try_to_facet() noexcept; + /** enabled when RRouter provides _preincrement. * Note we don't need this trick for comparison operators, * since return type is fixed. diff --git a/xo-gc/idl/GCObject.json5 b/xo-gc/idl/GCObject.json5 index bf0d78cd..30fc0d3a 100644 --- a/xo-gc/idl/GCObject.json5 +++ b/xo-gc/idl/GCObject.json5 @@ -76,5 +76,5 @@ attributes: [], }, ], - router_facet_explicit_content: [ ], + router_facet_explicit_content: [] } diff --git a/xo-gc/include/xo/gc/GCObject.hpp b/xo-gc/include/xo/gc/GCObject.hpp index 2eede6b3..970d2c31 100644 --- a/xo-gc/include/xo/gc/GCObject.hpp +++ b/xo-gc/include/xo/gc/GCObject.hpp @@ -18,5 +18,31 @@ #include "detail/IGCObject_Xfer.hpp" #include "detail/RGCObject.hpp" +namespace xo { + namespace mm { + /** defined here to avoid #include cycle, since + * template obj awkward to make available there + **/ + template + template + void + RCollector::forward_inplace(xo::facet::obj * p_obj) + { + this->forward_inplace(p_obj->iface(), (void **)&(p_obj->data_)); + } + + template + template + void + RCollector::forward_inplace(DRepr ** p_repr) + { + // fetch static interface for DRepr + auto iface = xo::facet::impl_for(); + + this->forward_inplace(&iface, (void **)p_repr); + } + } +} + +/* end GCObject.hpp */ -/* end GCObject.hpp */ \ No newline at end of file diff --git a/xo-gc/include/xo/gc/detail/RCollector.hpp b/xo-gc/include/xo/gc/detail/RCollector.hpp index 5e3eddb3..9cce4844 100644 --- a/xo-gc/include/xo/gc/detail/RCollector.hpp +++ b/xo-gc/include/xo/gc/detail/RCollector.hpp @@ -23,6 +23,16 @@ namespace xo { RCollector() = default; RCollector(DataPtr data) : Object{std::move(data)} {} + /** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/ + template + void forward_inplace(obj * p_obj); + + /** another convenience template for forwarding. + * Defined in RGCObject.hpp to avoid #include cycle. + **/ + template + void forward_inplace(DRepr ** pp_repr); + int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } size_type allocated(generation g, role r) const noexcept { return O::iface()->allocated(O::data(), g, r); } size_type reserved(generation g, role r) const noexcept { return O::iface()->reserved(O::data(), g, r); } From 2e5c2e7149d519bd07448e0b6f3d2671fccf794f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 15:15:39 -0500 Subject: [PATCH 187/258] xo-object2: DList: streamline forward_children() --- xo-object2/src/object2/DList.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xo-object2/src/object2/DList.cpp b/xo-object2/src/object2/DList.cpp index 73c8cd0d..0be056d8 100644 --- a/xo-object2/src/object2/DList.cpp +++ b/xo-object2/src/object2/DList.cpp @@ -172,10 +172,12 @@ namespace xo { { //scope log(XO_DEBUG(true)); - gc.forward_inplace(head_.iface(), (void **)&(head_.data_)); + gc.forward_inplace(&head_); + //gc.forward_inplace(head_.iface(), (void **)&(head_.data_)); - auto iface = xo::facet::impl_for(); - gc.forward_inplace(&iface, (void **)(&rest_)); + gc.forward_inplace(&rest_); + //auto iface = xo::facet::impl_for(); + //gc.forward_inplace(&iface, (void **)(&rest_)); return this->shallow_size(); } From 2f770d1c4712598e82bac3076edc488158fef78b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 15:16:05 -0500 Subject: [PATCH 188/258] xo-interpreter2 stack: handle SequenceExpr + gc for frames --- .../include/xo/expression2/SequenceExpr.hpp | 14 +++ .../src/expression2/DSequenceExpr.cpp | 2 +- xo-interpreter2/CMakeLists.txt | 26 ++++++ .../idl/IGCObject_DVsmSeqContFrame.json5 | 15 ++++ .../idl/IPrintable_DVsmSeqContFrame.json5 | 13 +++ .../xo/interpreter2/DVsmApplyFrame.hpp | 4 +- .../xo/interpreter2/DVsmEvalArgsFrame.hpp | 6 +- .../xo/interpreter2/DVsmSeqContFrame.hpp | 89 +++++++++++++++++++ .../interpreter2/VirtualSchematikaMachine.hpp | 2 + .../include/xo/interpreter2/VsmInstr.hpp | 4 +- .../include/xo/interpreter2/VsmOpcode.hpp | 3 + .../xo/interpreter2/VsmSeqContFrame.hpp | 12 +++ .../sequence/IGCObject_DVsmSeqContFrame.hpp | 67 ++++++++++++++ .../sequence/IPrintable_DVsmSeqContFrame.hpp | 62 +++++++++++++ .../src/interpreter2/CMakeLists.txt | 4 + .../interpreter2/DVsmApplyClosureFrame.cpp | 4 +- .../src/interpreter2/DVsmApplyFrame.cpp | 17 ++-- .../src/interpreter2/DVsmEvalArgsFrame.cpp | 18 ++-- .../src/interpreter2/DVsmSeqContFrame.cpp | 70 +++++++++++++++ .../IGCObject_DVsmSeqContFrame.cpp | 39 ++++++++ .../IPrintable_DVsmSeqContFrame.cpp | 28 ++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 84 +++++++++++++++-- xo-interpreter2/src/interpreter2/VsmInstr.cpp | 4 + .../interpreter2_register_facets.cpp | 24 +++-- 24 files changed, 574 insertions(+), 37 deletions(-) create mode 100644 xo-expression2/include/xo/expression2/SequenceExpr.hpp create mode 100644 xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 create mode 100644 xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/DVsmSeqContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmSeqContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/sequence/IGCObject_DVsmSeqContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/sequence/IPrintable_DVsmSeqContFrame.hpp create mode 100644 xo-interpreter2/src/interpreter2/DVsmSeqContFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DVsmSeqContFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DVsmSeqContFrame.cpp diff --git a/xo-expression2/include/xo/expression2/SequenceExpr.hpp b/xo-expression2/include/xo/expression2/SequenceExpr.hpp new file mode 100644 index 00000000..0cfe188c --- /dev/null +++ b/xo-expression2/include/xo/expression2/SequenceExpr.hpp @@ -0,0 +1,14 @@ +/** @file SequenceExpr.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DSequenceExpr.hpp" +#include "detail/IExpression_DSequenceExpr.hpp" +#include "detail/IGCObject_DSequenceExpr.hpp" +#include "detail/IPrintable_DSequenceExpr.hpp" + +/* end SequenceExpr.hpp */ + diff --git a/xo-expression2/src/expression2/DSequenceExpr.cpp b/xo-expression2/src/expression2/DSequenceExpr.cpp index a9783802..22b097fb 100644 --- a/xo-expression2/src/expression2/DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/DSequenceExpr.cpp @@ -135,7 +135,7 @@ namespace xo { gc.forward_inplace(&iface, (void**)&expr_v_); - return shallow_size(); + return this->shallow_size(); } } /*namespace scm*/ diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 8a1b1b3c..26124a21 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -103,6 +103,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-vsmseqcontframe + FACET_PKG xo_gc + FACET GCObject + REPR VsmSeqContFrame + INPUT idl/IGCObject_DVsmSeqContFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR sequence + OUTPUT_CPP_DIR src/interpreter2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-vsmseqcontframe + FACET_PKG xo_printable2 + FACET Printable + REPR DVsmSeqContFrame + INPUT idl/IPrintable_DVsmSeqContFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR sequence + OUTPUT_CPP_DIR src/interpreter2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git # #xo_add_genfacetimpl( diff --git a/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 new file mode 100644 index 00000000..cf7196c6 --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVsmSeqContFrame", + using_doxygen: true, + repr: "DVsmSeqContFrame", + doc: [ "implement AGCObject for DVsmSeqContFrame" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 new file mode 100644 index 00000000..e9ec796e --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVsmSeqContFrame", + using_doxygen: true, + repr: "DVsmSeqContFrame", + doc: [ "implement APrintable for DVsmSeqContFrame" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp index a5df3504..47735afe 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyFrame.hpp @@ -5,7 +5,9 @@ #pragma once -#include "VsmFrame.hpp" +#include "VsmInstr.hpp" +#include +#include namespace xo { namespace scm { diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp index 7131a001..e3b8b2b5 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmEvalArgsFrame.hpp @@ -28,12 +28,12 @@ namespace xo { **/ DVsmEvalArgsFrame(DVsmApplyFrame * parent, VsmInstr cont, - const DApplyExpr * apply_expr); + DApplyExpr * apply_expr); static DVsmEvalArgsFrame * make(obj mm, DVsmApplyFrame * apply_frame, VsmInstr old_cont, - const DApplyExpr * apply_expr); + DApplyExpr * apply_expr); DVsmApplyFrame * parent() const noexcept { return parent_; } VsmInstr cont() const noexcept { return cont_; } @@ -55,7 +55,7 @@ namespace xo { VsmInstr cont_; /** expression being evaluated **/ - const DApplyExpr * apply_expr_ = nullptr; + DApplyExpr * apply_expr_ = nullptr; /** next argument to be evaluated. -1 means function head **/ int32_t i_arg_ = -1; diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmSeqContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmSeqContFrame.hpp new file mode 100644 index 00000000..cb63f0d4 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DVsmSeqContFrame.hpp @@ -0,0 +1,89 @@ +/** @file DVsmSeqContFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "VsmInstr.hpp" +#include +#include + +namespace xo { + namespace scm { + /** @brief saved VSM state during evaluation of a SequenceExpr + **/ + class DVsmSeqContFrame { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-vsmevalsequenceframe-ctors constructors **/ + ///@{ + + DVsmSeqContFrame(obj parent, + VsmInstr cont, + DSequenceExpr * seq_expr, + uint32_t i_seq); + + /** create instance using memory from allocator @p mm **/ + static DVsmSeqContFrame * make(obj mm, + obj parent, + VsmInstr cont, + DSequenceExpr * seq_expr, + uint32_t i_seq); + + ///@} + /** @defgroup scm-vsmevalsequenceframe-access-methods access methods **/ + ///@{ + + obj parent() const noexcept { return parent_; } + VsmInstr cont() const noexcept { return cont_; } + DSequenceExpr * seq_expr() const noexcept { return seq_expr_; } + uint32_t i_seq() const noexcept { return i_seq_; } + + ///@} + /** @defgroup scm-vsmevalsequenceframe-general-methods general methods **/ + ///@{ + + uint32_t incr_i_seq() noexcept { return ++(this->i_seq_); } + + ///@} + /** @defgroup scm-vsmevalsequenceframe-gcobject-facet gcobject facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DVsmSeqContFrame * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} + /** @defgrouop scm-vsmseqcontframe-printable-facet printable facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const noexcept; + + ///@} + + private: + /** @defgroup scm-vsmevalsequenceframe-members member variables **/ + ///@{ + + /** saved VSM stack; restore when this frame consumed **/ + obj parent_; + /** saved continuation; restore when this frame consumed **/ + VsmInstr cont_; + /** saved expr. evaluate elements of this sequence in order **/ + DSequenceExpr * seq_expr_ = nullptr; + /** current sequence element being evaluated **/ + uint32_t i_seq_ = 0; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmSeqContFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 569d9d48..d7e1ec77 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -187,6 +187,8 @@ namespace xo { **/ void _do_applycoda_op(); + /** loop continuation after evaluating element of a SequenceExpr **/ + void _do_seq_cont_op(); private: /* diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index bdde3ab7..4b51361d 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -18,10 +18,12 @@ namespace xo { static VsmInstr c_apply; static VsmInstr c_evalargs; - /** restore registers after calling a schematika closure **/ static VsmInstr c_applycoda; + /** loop to evaluate members of a SequenceExpr **/ + static VsmInstr c_seq_cont; + vsm_opcode opcode() const noexcept { return opcode_; } private: diff --git a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp index ec21b988..06b3d08b 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp @@ -33,6 +33,9 @@ namespace xo { **/ applycoda, + /** Loop over elements of a SequenceExpr **/ + seq_cont, + /** sentinel, counts number of opcodes **/ N, }; diff --git a/xo-interpreter2/include/xo/interpreter2/VsmSeqContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmSeqContFrame.hpp new file mode 100644 index 00000000..96e8d053 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmSeqContFrame.hpp @@ -0,0 +1,12 @@ +/** @file VsmSeqContFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVsmSeqContFrame.hpp" +#include "sequence/IGCObject_DVsmSeqContFrame.hpp" +#include "sequence/IPrintable_DVsmSeqContFrame.hpp" + +/* end VsmSeqContFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/sequence/IGCObject_DVsmSeqContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/sequence/IGCObject_DVsmSeqContFrame.hpp new file mode 100644 index 00000000..1bdbe2ab --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/sequence/IGCObject_DVsmSeqContFrame.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVsmSeqContFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmSeqContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmSeqContFrame.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVsmSeqContFrame.hpp" + +namespace xo { namespace scm { class IGCObject_DVsmSeqContFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVsmSeqContFrame + **/ + class IGCObject_DVsmSeqContFrame { + public: + /** @defgroup scm-gcobject-dvsmseqcontframe-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvsmseqcontframe-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVsmSeqContFrame & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVsmSeqContFrame & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVsmSeqContFrame & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/sequence/IPrintable_DVsmSeqContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/sequence/IPrintable_DVsmSeqContFrame.hpp new file mode 100644 index 00000000..0fb46c45 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/sequence/IPrintable_DVsmSeqContFrame.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVsmSeqContFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmSeqContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmSeqContFrame.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVsmSeqContFrame.hpp" + +namespace xo { namespace scm { class IPrintable_DVsmSeqContFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVsmSeqContFrame + **/ + class IPrintable_DVsmSeqContFrame { + public: + /** @defgroup scm-printable-dvsmseqcontframe-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvsmseqcontframe-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVsmSeqContFrame & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 1ddb3207..64e7dfe8 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -20,6 +20,10 @@ set(SELF_SRCS IGCObject_DVsmApplyClosureFrame.cpp IPrintable_DVsmApplyClosureFrame.cpp + DVsmSeqContFrame.cpp + IGCObject_DVsmSeqContFrame.cpp + IPrintable_DVsmSeqContFrame.cpp + DClosure.cpp IGCObject_DClosure.cpp IPrintable_DClosure.cpp diff --git a/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp index 6a86ce27..26a215a4 100644 --- a/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmApplyClosureFrame.cpp @@ -4,6 +4,7 @@ **/ #include "DVsmApplyClosureFrame.hpp" +#include "LocalEnv.hpp" namespace xo { using xo::mm::AGCObject; @@ -52,7 +53,8 @@ namespace xo { std::size_t DVsmApplyClosureFrame::forward_children(obj gc) noexcept { - (void)gc; + gc.forward_inplace(&stack_); + gc.forward_inplace(&local_env_); return this->shallow_size(); } diff --git a/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp index 55d59b37..72b81405 100644 --- a/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmApplyFrame.cpp @@ -4,6 +4,7 @@ **/ #include "DVsmApplyFrame.hpp" +#include #include namespace xo { @@ -59,9 +60,9 @@ namespace xo { std::size_t DVsmApplyFrame::forward_children(obj gc) noexcept { - // GC needs to locate AGCObject iface for each member - - (void)gc; + gc.forward_inplace(&parent_); + gc.forward_inplace(&fn_); + gc.forward_inplace(&args_); return this->shallow_size(); } @@ -69,12 +70,10 @@ namespace xo { bool DVsmApplyFrame::pretty(const ppindentinfo & ppii) const { - return ppii.pps()->pretty_struct - (ppii, - "DVsmApplyFrame", - refrtag("cont", cont_), - refrtag("n_args", args_->size()) - ); + return ppii.pps()->pretty_struct(ppii, + "DVsmApplyFrame", + refrtag("cont", cont_), + refrtag("n_args", args_->size())); } } /*namespace scm*/ diff --git a/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp index 1ca470e9..09439f2e 100644 --- a/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp +++ b/xo-interpreter2/src/interpreter2/DVsmEvalArgsFrame.cpp @@ -4,6 +4,7 @@ **/ #include "DVsmEvalArgsFrame.hpp" +#include #include namespace xo { @@ -16,7 +17,7 @@ namespace xo { DVsmEvalArgsFrame::DVsmEvalArgsFrame(DVsmApplyFrame * parent, VsmInstr cont, - const DApplyExpr * apply_expr) + DApplyExpr * apply_expr) : parent_{parent}, cont_{cont}, apply_expr_{apply_expr} @@ -26,7 +27,7 @@ namespace xo { DVsmEvalArgsFrame::make(obj mm, DVsmApplyFrame * apply_frame, VsmInstr cont, - const DApplyExpr * apply_expr) + DApplyExpr * apply_expr) { DVsmEvalArgsFrame * result = nullptr; @@ -61,7 +62,8 @@ namespace xo { std::size_t DVsmEvalArgsFrame::forward_children(obj gc) noexcept { - (void)gc; + gc.forward_inplace(&parent_); + gc.forward_inplace(&apply_expr_); return this->shallow_size(); } @@ -69,12 +71,10 @@ namespace xo { bool DVsmEvalArgsFrame::pretty(const ppindentinfo & ppii) const { - return ppii.pps()->pretty_struct - (ppii, - "DVsmEvalArgsFrame", - refrtag("cont", cont_), - refrtag("i_arg", i_arg_) - ); + return ppii.pps()->pretty_struct(ppii, + "DVsmEvalArgsFrame", + refrtag("cont", cont_), + refrtag("i_arg", i_arg_)); } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/DVsmSeqContFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmSeqContFrame.cpp new file mode 100644 index 00000000..80c1665f --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DVsmSeqContFrame.cpp @@ -0,0 +1,70 @@ +/** @file DVsmSeqContFrame.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVsmSeqContFrame.hpp" + +namespace xo { + namespace scm { + + DVsmSeqContFrame::DVsmSeqContFrame(obj parent, + VsmInstr cont, + DSequenceExpr * seq_expr, + uint32_t i_seq) + : parent_{parent}, + cont_{cont}, + seq_expr_{seq_expr}, + i_seq_{i_seq} + {} + + DVsmSeqContFrame * + DVsmSeqContFrame::make(obj mm, + obj parent, + VsmInstr cont, + DSequenceExpr * seq_expr, + uint32_t i_seq) + { + void * mem = mm.alloc_for(); + + return new (mem) DVsmSeqContFrame(parent, cont, seq_expr, i_seq); + } + + // gcobject facet + + std::size_t + DVsmSeqContFrame::shallow_size() const noexcept + { + return sizeof(*this); + } + + DVsmSeqContFrame * + DVsmSeqContFrame::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DVsmSeqContFrame::forward_children(obj gc) noexcept + { + gc.forward_inplace(&parent_); + gc.forward_inplace(&seq_expr_); + + return this->shallow_size(); + } + + // printable facet + + bool + DVsmSeqContFrame::pretty(const ppindentinfo & ppii) const noexcept + { + return ppii.pps()->pretty_struct(ppii, + "DVsmSeqContFrame", + refrtag("cont", cont_), + refrtag("i_seq", i_seq_)); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmSeqContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DVsmSeqContFrame.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DVsmSeqContFrame.cpp new file mode 100644 index 00000000..eecdf291 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DVsmSeqContFrame.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVsmSeqContFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmSeqContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmSeqContFrame.json5] +**/ + +#include "sequence/IGCObject_DVsmSeqContFrame.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVsmSeqContFrame::shallow_size(const DVsmSeqContFrame & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVsmSeqContFrame::shallow_copy(const DVsmSeqContFrame & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVsmSeqContFrame::forward_children(DVsmSeqContFrame & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVsmSeqContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DVsmSeqContFrame.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DVsmSeqContFrame.cpp new file mode 100644 index 00000000..74801873 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DVsmSeqContFrame.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVsmSeqContFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmSeqContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmSeqContFrame.json5] +**/ + +#include "sequence/IPrintable_DVsmSeqContFrame.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVsmSeqContFrame::pretty(const DVsmSeqContFrame & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVsmSeqContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 8ff78ae0..9408c966 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -7,11 +7,13 @@ #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "VsmApplyClosureFrame.hpp" +#include "VsmSeqContFrame.hpp" #include "VsmRcx.hpp" #include "Closure.hpp" #include #include #include +#include #include //#include #include @@ -188,6 +190,9 @@ namespace xo { case vsm_opcode::applycoda: _do_applycoda_op(); break; + case vsm_opcode::seq_cont: + _do_seq_cont_op(); + break; } return true; @@ -328,7 +333,7 @@ namespace xo { auto apply = obj::from(expr_); - // evaluated arguments + // accumulate evaluated arguments here DArray * args = DArray::empty(mm_.to_op(), apply->n_args()); @@ -361,8 +366,42 @@ namespace xo { void VirtualSchematikaMachine::_do_eval_sequence_op() { - // not implemented - assert(false); + // assuming bump allocator: + // + // VsmEvalSequence + // v + // +-------+------+-------+-------+ + // | par x | cont | seq | i_elt | + // +-----|-+------+-------+-------+ + // | + // <-----/ + // + + auto seq_expr = obj::from(expr_); + + if (seq_expr->size() == 0) { + /* empty sequence expression does not produce a value */ + + this->value_ = VsmResult(obj()); + this->pc_ = this->cont_; + return; + } + + auto seqexpr_frame + = obj + (DVsmSeqContFrame::make(mm_.to_op(), + this->stack_ /*saved stack*/, + this->cont_ /*saved cont*/, + seq_expr.data() /*saved expr*/, + 0 /*index of seq element*/)); + + this->stack_ = seqexpr_frame; + + // Setup evaluation of first sequence element + + this->cont_ = VsmInstr::c_seq_cont; + this->expr_ = (*seq_expr.data())[0]; + this->pc_ = VsmInstr::c_eval; } void @@ -380,7 +419,7 @@ namespace xo { _do_call_closure_op(); return; } else { - _do_call_closure_op(); + _do_call_primitive_op(); return; } } @@ -393,6 +432,8 @@ namespace xo { auto closure = obj::from(fn_); + assert(closure); + // TODO: for tail recursion: // check whether stack_ already refers to a // DVsmApplyClosureFrame instance, in which case @@ -496,8 +537,8 @@ namespace xo { = evalargs_frame->apply_expr(); if (i_arg == -1) { - bool is_native_fn = value.to_facet(); bool is_closure = obj::from(value); + bool is_native_fn = value.try_to_facet(); if (is_native_fn || is_closure) { apply_frame->assign_fn(value); @@ -572,6 +613,39 @@ namespace xo { // not implemented assert(false); } + + void + VirtualSchematikaMachine::_do_seq_cont_op() + { + auto frame = obj::from(stack_); + + assert(frame); + + uint32_t i_seq = 1 + frame->i_seq(); + + auto seq_expr = frame->seq_expr(); + + assert(seq_expr); + + if (i_seq == seq_expr->size()) { + /* done with sequence + * value of sequence-expr is the value of the last expression in that sequence, + * which is already in the value_ register + */ + + this->stack_ = frame->parent(); + this->pc_ = frame->cont(); + return; + } else { + frame->incr_i_seq(); + + this->cont_ = VsmInstr::c_seq_cont; + this->expr_ = (*seq_expr)[i_seq]; + this->pc_ = VsmInstr::c_eval; + return; + } + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp index 02ac8325..640ac9fe 100644 --- a/xo-interpreter2/src/interpreter2/VsmInstr.cpp +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -16,6 +16,7 @@ namespace xo { case vsm_opcode::apply: return "apply"; case vsm_opcode::evalargs: return "evalargs"; case vsm_opcode::applycoda: return "applycoda"; + case vsm_opcode::seq_cont: return "seq_cont"; case vsm_opcode::N: break; } @@ -37,6 +38,9 @@ namespace xo { VsmInstr VsmInstr::c_applycoda = VsmInstr(vsm_opcode::applycoda); + + VsmInstr + VsmInstr::c_seq_cont = VsmInstr(vsm_opcode::seq_cont); } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index 1548aeaf..588419a2 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -9,6 +9,7 @@ #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "VsmApplyClosureFrame.hpp" +#include "VsmSeqContFrame.hpp" #include "Primitive_gco_2_gco_gco.hpp" #include "Closure.hpp" #include "LocalEnv.hpp" @@ -32,10 +33,12 @@ namespace xo { { scope log(XO_DEBUG(true)); - // VsmStackFrame + + // VsmStqackFrame // +- VsmApplyFrame // +- VsmEvalArgsFrame - // \- VsmApplyClosureFrame + // +- VsmApplyClosureFrame + // \- VsmSeqContFrame FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -46,22 +49,27 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // LocalEnv FacetRegistry::register_impl(); FacetRegistry::register_impl(); // Procedure - // +- Primitive_gco_2_gco_gco - // \- Closure + // \- Primitive_gco_2_gco_gco FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); -// FacetRegistry::register_impl(); -// FacetRegistry::register_impl(); -// FacetRegistry::register_impl(); + // Closure + +// FacetRegistry::register_impl(); // if/when provided + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // RuntimeContext // \- VsmRcx @@ -70,6 +78,8 @@ namespace xo { log && log(xtag("DVsmApplyFrame.tseq", typeseq::id())); log && log(xtag("DVsmEvalArgsFrame.tseq", typeseq::id())); + log && log(xtag("DVsmApplyClosureFrame.tseq", typeseq::id())); + log && log(xtag("DVsmSeqContFrame.tseq", typeseq::id())); log && log(xtag("DClosure.tseq", typeseq::id())); log && log(xtag("DLocalEnv.tseq", typeseq::id())); log && log(xtag("DVsmRcx.tseq", typeseq::id())); From 20cee5db7de69692a35801b8d2a296defcc05127 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 16:06:19 -0500 Subject: [PATCH 189/258] xo-interpreter2 stack: apply user-defined lambda passes utest --- .../xo/interpreter2/DVsmApplyClosureFrame.hpp | 4 +- .../interpreter2/VirtualSchematikaMachine.hpp | 2 +- .../include/xo/interpreter2/VsmInstr.hpp | 4 +- .../include/xo/interpreter2/VsmOpcode.hpp | 2 +- .../interpreter2/VirtualSchematikaMachine.cpp | 48 ++++++++++++++----- xo-interpreter2/src/interpreter2/VsmInstr.cpp | 4 +- .../utest/VirtualSchematikaMachine.test.cpp | 5 +- xo-object2/src/object2/DArray.cpp | 2 +- 8 files changed, 49 insertions(+), 22 deletions(-) diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp index a98d5713..168fa1a3 100644 --- a/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DVsmApplyClosureFrame.hpp @@ -30,11 +30,11 @@ namespace xo { /** create instance, using memory from @p mm **/ static DVsmApplyClosureFrame * make(obj mm, - obj stack, + obj parent, VsmInstr cont, DLocalEnv * env); - obj stack() const { return stack_; } + obj parent() const { return stack_; } VsmInstr cont() const { return cont_; } DLocalEnv * local_env() const { return local_env_; } diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index d7e1ec77..ce412391 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -185,7 +185,7 @@ namespace xo { * (specifically: local_env_, stack_, cont_) * after invoking a schematika closure **/ - void _do_applycoda_op(); + void _do_apply_cont_op(); /** loop continuation after evaluating element of a SequenceExpr **/ void _do_seq_cont_op(); diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index 4b51361d..d7444b86 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -18,8 +18,8 @@ namespace xo { static VsmInstr c_apply; static VsmInstr c_evalargs; - /** restore registers after calling a schematika closure **/ - static VsmInstr c_applycoda; + /** proceed to continuation after an ApplyExpr **/ + static VsmInstr c_apply_cont; /** loop to evaluate members of a SequenceExpr **/ static VsmInstr c_seq_cont; diff --git a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp index 06b3d08b..2a277a49 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp @@ -31,7 +31,7 @@ namespace xo { /** Coda to restore vsm registers (local_env, stack, cont) * after invoking a closure **/ - applycoda, + apply_cont, /** Loop over elements of a SequenceExpr **/ seq_cont, diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 9408c966..d1b8eacb 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -187,8 +187,8 @@ namespace xo { case vsm_opcode::evalargs: _do_evalargs_op(); break; - case vsm_opcode::applycoda: - _do_applycoda_op(); + case vsm_opcode::apply_cont: + _do_apply_cont_op(); break; case vsm_opcode::seq_cont: _do_seq_cont_op(); @@ -302,8 +302,37 @@ namespace xo { void VirtualSchematikaMachine::_do_eval_varref_op() { - // not implemented - assert(false); + auto var = obj::from(expr_); + + Binding b = var->path(); + + if (!local_env_) { + // need lookup on global_env_ + assert(false); + } + + auto value = local_env_->lookup_value(b); + + if (value) { + this->value_ = VsmResult(value); + this->pc_ = this->cont_; + return; + } + + // no binding + + auto error = DRuntimeError::make(mm_.to_op(), + "_do_eval_varref_op", + "no binding for variable"); + this->value_ = VsmResult(error); + + // for now: halt VSM execution + // TODO: some combination of + // 1. emit stack trace + // 2. go to debugger + // 3. have every vsm instruction check inputs for errors + + this->pc_ = VsmInstr::c_halt; } void @@ -439,7 +468,7 @@ namespace xo { // DVsmApplyClosureFrame instance, in which case // we can just refer to it instead of pushing a new one - if (cont_ == VsmInstr::c_applycoda) { + if (cont_ == VsmInstr::c_apply_cont) { // we are making a tail call. // No need to preserve (stack, cont, local_env), // since continuation will restore on top of them @@ -454,7 +483,7 @@ namespace xo { // push frame w/ saved vsm registers this->stack_ = frame; - this->cont_ = VsmInstr::c_applycoda; + this->cont_ = VsmInstr::c_apply_cont; } auto lambda = closure->lambda(); @@ -598,7 +627,7 @@ namespace xo { } void - VirtualSchematikaMachine::_do_applycoda_op() + VirtualSchematikaMachine::_do_apply_cont_op() { // see DVsmApplyClosureFrame @@ -606,12 +635,9 @@ namespace xo { assert(frame); - this->stack_ = frame->stack(); + this->stack_ = frame->parent(); this->local_env_ = frame->local_env(); this->pc_ = frame->cont(); - - // not implemented - assert(false); } void diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp index 640ac9fe..d1923cbd 100644 --- a/xo-interpreter2/src/interpreter2/VsmInstr.cpp +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -15,7 +15,7 @@ namespace xo { case vsm_opcode::eval: return "eval"; case vsm_opcode::apply: return "apply"; case vsm_opcode::evalargs: return "evalargs"; - case vsm_opcode::applycoda: return "applycoda"; + case vsm_opcode::apply_cont: return "apply_cont"; case vsm_opcode::seq_cont: return "seq_cont"; case vsm_opcode::N: break; @@ -37,7 +37,7 @@ namespace xo { VsmInstr::c_evalargs = VsmInstr(vsm_opcode::evalargs); VsmInstr - VsmInstr::c_applycoda = VsmInstr(vsm_opcode::applycoda); + VsmInstr::c_apply_cont = VsmInstr(vsm_opcode::apply_cont); VsmInstr VsmInstr::c_seq_cont = VsmInstr(vsm_opcode::seq_cont); diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 22b50194..bd456b9d 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -246,11 +246,12 @@ namespace xo { log && log(xtag("res.tseq", res.value()->_typeseq())); // currently get not-implemented error - auto x = obj::from(*res.value()); + auto x = obj::from(*res.value()); REQUIRE(x); + REQUIRE(x->value() == 195); - log && log("runtime-error", xtag("ex.src", x->src_function()), xtag("ex.descr", x->error_descr())); + //log && log("runtime-error", xtag("ex.src", x->src_function()), xtag("ex.descr", x->error_descr())); //REQUIRE(x.data()->value() == 1.570796325); diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index cee62bca..237c9af5 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -135,7 +135,7 @@ namespace xo { for (size_type i = 0; i < size_; ++i) { obj & elt = elts_[i]; - gc.forward_inplace(elt.iface(), (void **)&(elt.data_)); + gc.forward_inplace(&elt); } return shallow_size(); From cf9930a54aa5c22f738b52d5f32574affb5d4798 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 17:24:23 -0500 Subject: [PATCH 190/258] xo-reader2 stack: handle comparison expression (x == y) --- .../utest/VirtualSchematikaMachine.test.cpp | 3 +- .../include/xo/procedure2/init_primitives.hpp | 6 + .../src/procedure2/init_primitives.cpp | 74 ++++++++- .../include/xo/reader2/SchematikaParser.hpp | 3 + xo-reader2/src/reader2/DProgressSsm.cpp | 29 +++- xo-reader2/src/reader2/SchematikaParser.cpp | 6 + xo-reader2/utest/SchematikaParser.test.cpp | 157 ++++++++++++------ xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 3 + 8 files changed, 221 insertions(+), 60 deletions(-) diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index bd456b9d..6b4f9cf8 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -227,7 +227,7 @@ namespace xo { TEST_CASE("VirtualSchematikaMachine-apply2", "[interpreter2][VSM]") { - scope log(XO_DEBUG(true)); + scope log(XO_DEBUG(false)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -269,6 +269,7 @@ namespace xo { FacetRegistry::instance().visit_pools(visitor); vsm.visit_pools(visitor); } + } /*namespace ut*/ } /*namespace xo*/ diff --git a/xo-procedure2/include/xo/procedure2/init_primitives.hpp b/xo-procedure2/include/xo/procedure2/init_primitives.hpp index 48b733df..d2d51a59 100644 --- a/xo-procedure2/include/xo/procedure2/init_primitives.hpp +++ b/xo-procedure2/include/xo/procedure2/init_primitives.hpp @@ -22,6 +22,12 @@ namespace xo { **/ static DPrimitive_gco_2_gco_gco s_mul_gco_gco_pm; + /** polymorphic equality comparison + * + * TODO: this will want to move to x-numeric/ + **/ + static DPrimitive_gco_2_gco_gco s_equal_gco_gco_pm; + #ifdef NOT_YET static Primitive_f64_1_f64 s_neg_f64_pm; diff --git a/xo-procedure2/src/procedure2/init_primitives.cpp b/xo-procedure2/src/procedure2/init_primitives.cpp index dbcb3b35..c1eceada 100644 --- a/xo-procedure2/src/procedure2/init_primitives.cpp +++ b/xo-procedure2/src/procedure2/init_primitives.cpp @@ -5,10 +5,11 @@ #include "init_primitives.hpp" #include "DPrimitive.hpp" -#include -#include -#include -#include +#include +//#include +#include +//#include +#include #include #include #include @@ -54,9 +55,6 @@ namespace xo { // 2. at that point will require polymorphic dispatch // on argument representations, analogous to dispatch // in FacetRegistry - // 3. Need concept of a 'runtime context'. - // This will need to be part of the AProcedure api - // e.g. passed to apply_nocheck typeseq x_tseq = x_gco._typeseq(); typeseq y_tseq = y_gco._typeseq(); @@ -101,6 +99,65 @@ namespace xo { return obj(); } + obj + equal_gco_gco(obj rcx, + obj x_gco, + obj y_gco) + { + using xo::reflect::typeseq; + + obj mm = rcx.allocator(); + + // PLACEHOLDER + + // TODO + // 1. move this to xo-numeric2/ when available + // 2. at that point will require polymorphic dispatch on argument representations. + // + + typeseq x_tseq = x_gco._typeseq(); + typeseq y_tseq = y_gco._typeseq(); + + // FOR NOW: just test runtime values + // + if (x_tseq == typeseq::id()) { + // i64 * .. + long x = GCObjectConversion::from_gco(mm, x_gco); + + if (y_tseq == typeseq::id()) { + // i64 == i64 + long y = GCObjectConversion::from_gco(mm, y_gco); + + return DBoolean::box(mm, x == y); + } else if (y_tseq == typeseq::id()) { + // i64 == f64 + double y = GCObjectConversion::from_gco(mm, y_gco); + + return DFloat::box(mm, static_cast(x) == y); + } + } else if (x_tseq == typeseq::id()) { + if (y_tseq == typeseq::id()) { + // f64 == i64. + double x = GCObjectConversion::from_gco(mm, x_gco); + long y = GCObjectConversion::from_gco(mm, y_gco); + + return DFloat::box(mm, x == static_cast(y)); + } else if (y_tseq == typeseq::id()) { + // f64 * f64. + double x = GCObjectConversion::from_gco(mm, x_gco); + double y = GCObjectConversion::from_gco(mm, y_gco); + + return DFloat::box(mm, x == y); + } + } + + // here: error + throw std::runtime_error(tostr("mul_gco_gco: unexpected argument types xt,yt", + xtag("x.tseq", x_tseq), + xtag("y.tseq", y_tseq))); + return obj(); + } + #ifdef NOT_YET double mul_f64_f64(double x, double y) { @@ -141,6 +198,9 @@ namespace xo { DPrimitive_gco_2_gco_gco Primitives::s_mul_gco_gco_pm("_mul", &mul_gco_gco); + DPrimitive_gco_2_gco_gco + Primitives::s_equal_gco_gco_pm("_equal", &equal_gco_gco); + #ifdef NOT_YET Primitive_f64_1_f64 Primitives::s_neg_f64_pm("_neg_d", diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 8c3f51b1..4be59f04 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -193,6 +193,9 @@ namespace xo { /** top of parser stack **/ obj top_ssm() const; + /** current parser result. Value of last return from @ref on_token **/ + const ParserResult & result() const; + /** visit parser-owned memory pools; invoke visitor(info) for each **/ void visit_pools(const MemorySizeVisitor & visitor) const; diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 20bfb998..acffc851 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -292,11 +292,11 @@ namespace xo { break; case tokentype::tk_star: + case tokentype::tk_cmpeq: this->on_operator_token(tk, p_psm); return; case tokentype::tk_slash: - case tokentype::tk_cmpeq: case tokentype::tk_cmpne: case tokentype::tk_type: case tokentype::tk_lambda: @@ -1177,6 +1177,10 @@ namespace xo { ); } + namespace { + // make_builtin_apply_pm2 + } + obj DProgressSsm::assemble_expr(ParserStateMachine * p_psm) { @@ -1209,7 +1213,28 @@ namespace xo { return this->lhs_; case optype::op_assign: + assert(false); + break; + case optype::op_equal: + { + auto pm_obj = (with_facet::mkobj + (&Primitives::s_equal_gco_gco_pm)); + auto fn_expr = (DConstant::make + (p_psm->expr_alloc(), pm_obj)); + + // see note on op_multiply + + TypeRef tref = TypeRef::dwim + (TypeRef::prefix_type::from_chars("_equal_gco"), + nullptr); + + return DApplyExpr::make2(p_psm->expr_alloc(), + tref, + fn_expr, lhs_, rhs_); + } + break; + case optype::op_not_equal: case optype::op_less: case optype::op_less_equal: @@ -1217,6 +1242,7 @@ namespace xo { case optype::op_great_equal: case optype::op_add: case optype::op_subtract: + assert(false); break; case optype::op_multiply: @@ -1255,6 +1281,7 @@ namespace xo { break; case optype::op_divide: // TODO: implement binary operator expression assembly + assert(false); break; #ifdef NOT_YET diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index c53acc16..1973bbe7 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -47,6 +47,12 @@ namespace xo { return psm_.top_ssm(); } + const ParserResult & + SchematikaParser::result() const + { + return psm_.result(); + } + void SchematikaParser::visit_pools(const MemorySizeVisitor & visitor) const { diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 3bdf94cc..2c36ee96 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -411,6 +411,39 @@ namespace xo { //REQUIRE(result.error_description()); } + void + utest_tokenizer_loop(SchematikaParser * parser, std::vector & tk_v, bool debug_flag) + { + scope log(XO_DEBUG(debug_flag)); + + size_t i_tk = 0; + size_t n_tk = tk_v.size(); + for (const auto & tk : tk_v) { + INFO(tostr(xtag("i_tk", i_tk), xtag("tk", tk))); + + auto & result = parser->on_token(tk); + + log && log("after token", xtag("i_tk", i_tk), xtag("tk", tk)); + log && log(xtag("parser", parser)); + log && log(xtag("result", result)); + + if (i_tk + 1 < n_tk) { + REQUIRE(parser->has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } else { + /* last token in tk_v[] */ + + REQUIRE(parser->has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } + + ++i_tk; + } + } + TEST_CASE("SchematikaParser-interactive-arith", "[reader2][SchematikaParser]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); @@ -435,54 +468,17 @@ namespace xo { * **/ + std::vector tk_v{ + Token::f64_token("3.14159265"), + Token::star_token(), + Token::f64_token("0.5"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + const auto & result = parser.result(); { - auto & result = parser.on_token(Token::f64_token("3.14159265")); - - log && log("after float(3.14159265) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::star_token()); - - log && log("after star token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::f64_token("0.5")); - - log && log("after float(0.5) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::semicolon_token()); - - log && log("after semicolon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == false); - REQUIRE(!result.is_error()); - REQUIRE(result.is_expression()); - REQUIRE(result.result_expr()); - auto expr = obj::from(result.result_expr()); REQUIRE(expr); @@ -509,10 +505,69 @@ namespace xo { REQUIRE(rhs_f64); REQUIRE(rhs_f64->value() == 0.5); } + } - //REQUIRE(result.is_error()); - //// illegal input on token - //REQUIRE(result.error_description()); + TEST_CASE("SchematikaParser-interactive-cmp", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 312 == 312 ; + * + **/ + + std::vector tk_v{ + Token::i64_token("312"), + Token::cmpeq_token(), + Token::i64_token("312"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + const auto & result = parser.result(); + { + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + + REQUIRE(expr->n_args() == 2); + + auto fn = obj::from(expr->fn()); + REQUIRE(fn); + + auto pm = obj::from(fn->value()); + REQUIRE(pm); + REQUIRE(pm->name() == "_equal"); + + auto lhs = obj::from(expr->arg(0)); + REQUIRE(lhs); + + auto lhs_i64 = obj::from(lhs->value()); + REQUIRE(lhs_i64); + REQUIRE(lhs_i64->value() == 312); + + auto rhs = obj::from(expr->arg(1)); + REQUIRE(rhs); + + auto rhs_i64 = obj::from(rhs->value()); + REQUIRE(rhs_i64); + REQUIRE(rhs_i64->value() == 312); + } } TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") @@ -1017,7 +1072,7 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-apply", "[reader2][SchematikaParser]") { - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag)); ArenaConfig config; diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index ab3f0cb7..b211f967 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -129,6 +129,9 @@ namespace xo { /** token for @c "/" **/ static Token slash_token() { return Token(tokentype::tk_slash); } + /** token for @c "==" **/ + static Token cmpeq_token() { return Token(tokentype::tk_cmpeq); } + /** token representing keyword @c type **/ static Token type() { return Token(tokentype::tk_type); } /** token representing keyword @c def **/ From 8462d8a0faf61121a0d82af6ceb4bf1dd274980f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 17:29:49 -0500 Subject: [PATCH 191/258] xo-reader2: streamline utest --- xo-reader2/utest/SchematikaParser.test.cpp | 96 +++------------------- 1 file changed, 10 insertions(+), 86 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 2c36ee96..f9601ad7 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -800,93 +800,17 @@ namespace xo { * **/ - { - auto & result = parser.on_token(Token::if_token()); + std::vector tk_v{ + Token::if_token(), + Token::bool_token("true"), + Token::then_token(), + Token::i64_token("777"), + Token::else_token(), + Token::string_token("fooey"), + Token::semicolon_token(), + }; - log && log("after if token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::bool_token("true")); - - log && log("after true token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::then_token()); - - log && log("after then token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::i64_token("777")); - - log && log("after i64 token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::else_token()); - - log && log("after else token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::string_token("fooey")); - - log && log("after string token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::semicolon_token()); - - log && log("after semicolon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == false); - REQUIRE(!result.is_error()); - REQUIRE(!result.is_incomplete()); - } - - //REQUIRE(result.is_error()); - //// illegal input on token - //REQUIRE(result.error_description()); + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); } TEST_CASE("SchematikaParser-interactive-lambda2", "[reader2][SchematikaParser]") From 985801a9093ce9ef9123b13449ceb97590a1f32b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 17:36:29 -0500 Subject: [PATCH 192/258] xo-reader2: streamline a utest --- xo-reader2/utest/SchematikaParser.test.cpp | 169 ++++++--------------- 1 file changed, 46 insertions(+), 123 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index f9601ad7..b424fb8f 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -47,6 +47,39 @@ namespace xo { static InitEvidence s_init = (InitSubsys::require()); namespace ut { + void + utest_tokenizer_loop(SchematikaParser * parser, std::vector & tk_v, bool debug_flag) + { + scope log(XO_DEBUG(debug_flag)); + + size_t i_tk = 0; + size_t n_tk = tk_v.size(); + for (const auto & tk : tk_v) { + INFO(tostr(xtag("i_tk", i_tk), xtag("tk", tk))); + + auto & result = parser->on_token(tk); + + log && log("after token", xtag("i_tk", i_tk), xtag("tk", tk)); + log && log(xtag("parser", parser)); + log && log(xtag("result", result)); + + if (i_tk + 1 < n_tk) { + REQUIRE(parser->has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } else { + /* last token in tk_v[] */ + + REQUIRE(parser->has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } + + ++i_tk; + } + } + TEST_CASE("SchematikaParser-ctor", "[reader2][SchematikaParser]") { ArenaConfig config; @@ -120,100 +153,23 @@ namespace xo { * **/ + std::vector tk_v{ + Token::def_token(), + Token::symbol_token("foo"), + Token::colon_token(), + Token::symbol_token("f64"), + Token::singleassign_token(), + Token::f64_token("3.141593"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + const auto & result = parser.result(); { - auto & result = parser.on_token(Token::def_token()); - - // after begin_interactive_session, parser has toplevel exprseq - // but is still "at toplevel" in the sense of ready for input - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(result.is_incomplete()); - - log && log("after def token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - } - - { - auto & result = parser.on_token(Token::symbol_token("foo")); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(result.is_incomplete()); - - log && log("after lhs symbol token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - } - - { - auto & result = parser.on_token(Token::colon_token()); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(result.is_incomplete()); - - log && log("after colon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - } - - { - auto & result = parser.on_token(Token::symbol_token("f64")); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(result.is_incomplete()); - - log && log("after typename symbol token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - } - - { - auto & result = parser.on_token(Token::singleassign_token()); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(result.is_incomplete()); - - log && log("after typename symbol token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - auto exp_ssm - = obj::from(parser.top_ssm()); - - REQUIRE(exp_ssm); - REQUIRE(exp_ssm.data()->ssm_type() == syntaxstatetype::expect_rhs_expression); - REQUIRE(exp_ssm.data()->allow_defs() == false); - REQUIRE(exp_ssm.data()->cxl_on_rightbrace() == false); - } - - { - // future-proofing for Token only holding a string_view - const DString * str = DString::from_cstr(expr_alloc, "3.141593"); - - auto & result = parser.on_token(Token::f64_token(std::string(*str))); - - REQUIRE(parser.has_incomplete_expr() == true); - - log && log("after f64 token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - } - - { - auto & result = parser.on_token(Token::semicolon_token()); - - log && log("after semicolon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == false); - auto expr = obj::from(result.result_expr()); REQUIRE(expr); } - - // define-expressions not properly implemented - - //REQUIRE(result.error_description()); } TEST_CASE("SchematikaParser-interactive-integer", "[reader2][SchematikaParser]") @@ -411,39 +367,6 @@ namespace xo { //REQUIRE(result.error_description()); } - void - utest_tokenizer_loop(SchematikaParser * parser, std::vector & tk_v, bool debug_flag) - { - scope log(XO_DEBUG(debug_flag)); - - size_t i_tk = 0; - size_t n_tk = tk_v.size(); - for (const auto & tk : tk_v) { - INFO(tostr(xtag("i_tk", i_tk), xtag("tk", tk))); - - auto & result = parser->on_token(tk); - - log && log("after token", xtag("i_tk", i_tk), xtag("tk", tk)); - log && log(xtag("parser", parser)); - log && log(xtag("result", result)); - - if (i_tk + 1 < n_tk) { - REQUIRE(parser->has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } else { - /* last token in tk_v[] */ - - REQUIRE(parser->has_incomplete_expr() == false); - REQUIRE(!result.is_error()); - REQUIRE(result.is_expression()); - REQUIRE(result.result_expr()); - } - - ++i_tk; - } - } - TEST_CASE("SchematikaParser-interactive-arith", "[reader2][SchematikaParser]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); From b35e607f3e09fa9ec87f372edf7c85a2851d0500 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 17:43:00 -0500 Subject: [PATCH 193/258] xo-reader2: streamline another utest --- xo-reader2/utest/SchematikaParser.test.cpp | 172 ++------------------- 1 file changed, 16 insertions(+), 156 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index b424fb8f..5ea74fd8 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -758,163 +758,23 @@ namespace xo { * **/ - { - auto & result = parser.on_token(Token::lambda_token()); - - log && log("after lambda token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::leftparen_token()); - - log && log("after lparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("x")); - - log && log("after symbol(n) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::colon_token()); - - log && log("after colon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("i64")); - - log && log("after symbol(i64) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::rightparen_token()); - - log && log("after rightparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::yields_token()); - - log && log("after yields token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("i64")); - - log && log("after symbol(i64) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::leftbrace_token()); - - log && log("after leftbrace token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("x")); - - log && log("after symbol(x) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::star_token()); - - log && log("after star(*) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("x")); - - log && log("after symbol(x) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::rightbrace_token()); - - log && log("after rightbrace(}) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == false); - REQUIRE(!result.is_error()); - REQUIRE(result.is_expression()); - REQUIRE(result.result_expr()); - } + std::vector tk_v{ + /**/ Token::lambda_token(), + /**/ Token::leftparen_token(), + /**/ Token::symbol_token("x"), + /**/ Token::colon_token(), + /**/ Token::symbol_token("i64"), + /**/ Token::rightparen_token(), + /**/ Token::yields_token(), + /**/ Token::symbol_token("i64"), + /**/ Token::leftbrace_token(), + /**/ Token::symbol_token("x"), + /**/ Token::star_token(), + /**/ Token::symbol_token("x"), + /**/ Token::rightbrace_token(), + }; + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); } TEST_CASE("SchematikaParser-interactive-apply", "[reader2][SchematikaParser]") From f845dd6a1979119d693071c850530cf1f86d2d3f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 17:49:57 -0500 Subject: [PATCH 194/258] xo-reader2: number token sequence in parser utest --- xo-reader2/utest/SchematikaParser.test.cpp | 32 ++++++++++++---------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 5ea74fd8..189b8e69 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -754,24 +754,26 @@ namespace xo { /** Walkthrough parsing input equivalent to: * - * lambda (x : i64) -> i64 { x * x }; - * + * lambda (x : i64) -> i64 { x * x } + * ^ ^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + * 0 1| 3 4 5 6 7 8 9 a b c + * 2 **/ std::vector tk_v{ - /**/ Token::lambda_token(), - /**/ Token::leftparen_token(), - /**/ Token::symbol_token("x"), - /**/ Token::colon_token(), - /**/ Token::symbol_token("i64"), - /**/ Token::rightparen_token(), - /**/ Token::yields_token(), - /**/ Token::symbol_token("i64"), - /**/ Token::leftbrace_token(), - /**/ Token::symbol_token("x"), - /**/ Token::star_token(), - /**/ Token::symbol_token("x"), - /**/ Token::rightbrace_token(), + /* [ 0] */ Token::lambda_token(), + /* [ 1] */ Token::leftparen_token(), + /* [ 2] */ Token::symbol_token("x"), + /* [ 3] */ Token::colon_token(), + /* [ 4] */ Token::symbol_token("i64"), + /* [ 5] */ Token::rightparen_token(), + /* [ 6] */ Token::yields_token(), + /* [ 7] */ Token::symbol_token("i64"), + /* [ 8] */ Token::leftbrace_token(), + /* [ 9] */ Token::symbol_token("x"), + /* [ a] */ Token::star_token(), + /* [ b] */ Token::symbol_token("x"), + /* [ c] */ Token::rightbrace_token(), }; utest_tokenizer_loop(&parser, tk_v, c_debug_flag); From 76ea5a9c676a32e0e91623c4d105cbdf623c169d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 17:52:06 -0500 Subject: [PATCH 195/258] xo-reader2: utest: label test in console output --- xo-reader2/utest/SchematikaParser.test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 189b8e69..ea301a4c 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -738,8 +738,10 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-lambda2", "[reader2][SchematikaParser]") { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + constexpr bool c_debug_flag = false; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; config.name_ = "test-arena"; From 34b4defd432baccb1fcd885fa827aee45a195620 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 17:58:25 -0500 Subject: [PATCH 196/258] xo-reader2: refactor interactive-if utest to streamline --- xo-reader2/utest/SchematikaParser.test.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index ea301a4c..703cccbf 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -703,8 +703,10 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + constexpr bool c_debug_flag = false; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; config.name_ = "test-arena"; @@ -720,17 +722,18 @@ namespace xo { /** Walkthrough parsing input equivalent to: * * if true then 777 else "fooey" ; - * + * ^ ^ ^ ^ ^ ^ ^ + * 0 1 2 3 4 5 6 **/ std::vector tk_v{ - Token::if_token(), - Token::bool_token("true"), - Token::then_token(), - Token::i64_token("777"), - Token::else_token(), - Token::string_token("fooey"), - Token::semicolon_token(), + /* [0] */ Token::if_token(), + /* [1] */ Token::bool_token("true"), + /* [2] */ Token::then_token(), + /* [3] */ Token::i64_token("777"), + /* [4] */ Token::else_token(), + /* [5] */ Token::string_token("fooey"), + /* [6] */ Token::semicolon_token(), }; utest_tokenizer_loop(&parser, tk_v, c_debug_flag); From 8fe0f9728bf1b924ab2a6a2286b34bcc0f04c0d4 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 18:02:55 -0500 Subject: [PATCH 197/258] xo-reader-2: refactor interactive-apply utest --- xo-reader2/utest/SchematikaParser.test.cpp | 72 ++++++++-------------- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 703cccbf..35afc88c 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -786,8 +786,10 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-apply", "[reader2][SchematikaParser]") { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + constexpr bool c_debug_flag = false; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; config.name_ = "test-arena"; @@ -802,58 +804,34 @@ namespace xo { /** Walkthrough parsing input equivalent to: * - * (lambda (x : i64) { x * x })(13); - * + * (lambda (x : i64) { x * x })(13) ; + * ^^ ^^ ^ ^ ^ ^ ^ ^ ^ ^^^^ ^ ^ + * 0| 2| 4 5 6 7 8 9 a b|d| f g + * 1 3 c e **/ std::vector tk_v{ - Token::leftparen_token(), + /* [ 0] */ Token::leftparen_token(), - /**/ Token::lambda_token(), - /**/ Token::leftparen_token(), - /**/ Token::symbol_token("x"), - /**/ Token::colon_token(), - /**/ Token::symbol_token("i64"), - /**/ Token::rightparen_token(), - /**/ Token::leftbrace_token(), - /**/ Token::symbol_token("x"), - /**/ Token::star_token(), - /**/ Token::symbol_token("x"), - /**/ Token::rightbrace_token(), - /**/ Token::rightparen_token(), - /**/ Token::leftparen_token(), - /**/ Token::i64_token("13"), - /**/ Token::rightparen_token(), - - /**/ Token::semicolon_token(), + /* [ 1] */ Token::lambda_token(), + /* [ 2] */ Token::leftparen_token(), + /* [ 3] */ Token::symbol_token("x"), + /* [ 4] */ Token::colon_token(), + /* [ 5] */ Token::symbol_token("i64"), + /* [ 6] */ Token::rightparen_token(), + /* [ 7] */ Token::leftbrace_token(), + /* [ 8] */ Token::symbol_token("x"), + /* [ 9] */ Token::star_token(), + /* [ a] */ Token::symbol_token("x"), + /* [ b] */ Token::rightbrace_token(), + /* [ c] */ Token::rightparen_token(), + /* [ d] */ Token::leftparen_token(), + /* [ e] */ Token::i64_token("13"), + /* [ f] */ Token::rightparen_token(), + /* [ g] */ Token::semicolon_token(), }; - size_t i_tk = 0; - size_t n_tk = tk_v.size(); - for (const auto & tk : tk_v) { - INFO(tostr(xtag("i_tk", i_tk), xtag("tk", tk))); - - auto & result = parser.on_token(tk); - - log && log("after token", xtag("i_tk", i_tk), xtag("tk", tk)); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - if (i_tk + 1 < n_tk) { - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } else { - /* last token in tk_v[] */ - - REQUIRE(parser.has_incomplete_expr() == false); - REQUIRE(!result.is_error()); - REQUIRE(result.is_expression()); - REQUIRE(result.result_expr()); - } - - ++i_tk; - } + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); } TEST_CASE("SchematikaParser-interactive-apply2", "[reader2][SchematikaParser]") From 90de831992fe16256d006fde6e364447040f32bc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 18:06:38 -0500 Subject: [PATCH 198/258] xo-reader2: utest: refactor w/ syntax annotation for apply2 utest --- xo-reader2/utest/SchematikaParser.test.cpp | 84 ++++++++-------------- 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 35afc88c..0addfb7c 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -838,8 +838,10 @@ namespace xo { { // top-level apply, with multiple arguments + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; config.name_ = "test-arena"; @@ -854,68 +856,44 @@ namespace xo { /** Walkthrough parsing input equivalent to: * - * (lambda (x : i64, y : i64) { x * y })(13, 15); - * + * (lambda (x : i64, y : i64) { x * y })(13, 15) ; + * ^^ ^^ ^ ^ ^ ^^ ^ ^ ^ ^ ^ ^ ^^^^ ^ ^ ^ ^ + * 0| 2| 4 5 6 7| 9 a b c d e f|h| j k l m + * 1 3 8 g i **/ std::vector tk_v{ - Token::leftparen_token(), + /* [ 0] */ Token::leftparen_token(), - /**/ Token::lambda_token(), - /* */ Token::leftparen_token(), - /* */ Token::symbol_token("x"), - /* */ Token::colon_token(), - /* */ Token::symbol_token("i64"), - /* */ Token::comma_token(), - /* */ Token::symbol_token("y"), - /* */ Token::colon_token(), - /* */ Token::symbol_token("i64"), - /* */ Token::rightparen_token(), + /* [ 1] */ Token::lambda_token(), + /* [ 2] */ Token::leftparen_token(), + /* [ 3] */ Token::symbol_token("x"), + /* [ 4] */ Token::colon_token(), + /* [ 5] */ Token::symbol_token("i64"), + /* [ 6] */ Token::comma_token(), + /* [ 7] */ Token::symbol_token("y"), + /* [ 8] */ Token::colon_token(), + /* [ 9] */ Token::symbol_token("i64"), + /* [ a] */ Token::rightparen_token(), - /**/ Token::leftbrace_token(), - /* */ Token::symbol_token("x"), - /* */ Token::star_token(), - /* */ Token::symbol_token("y"), - /**/ Token::rightbrace_token(), + /* [ b] */ Token::leftbrace_token(), + /* [ c] */ Token::symbol_token("x"), + /* [ d] */ Token::star_token(), + /* [ e] */ Token::symbol_token("y"), + /* [ f] */ Token::rightbrace_token(), - Token::rightparen_token(), + /* [ g] */ Token::rightparen_token(), - Token::leftparen_token(), - /**/ Token::i64_token("13"), - /**/ Token::comma_token(), - /**/ Token::i64_token("15"), - Token::rightparen_token(), + /* [ h] */ Token::leftparen_token(), + /* [ i] */ Token::i64_token("13"), + /* [ j] */ Token::comma_token(), + /* [ k] */ Token::i64_token("15"), + /* [ l] */ Token::rightparen_token(), - Token::semicolon_token(), + /* [ m] */ Token::semicolon_token(), }; - size_t i_tk = 0; - size_t n_tk = tk_v.size(); - for (const auto & tk : tk_v) { - INFO(tostr(xtag("i_tk", i_tk), xtag("tk", tk))); - - auto & result = parser.on_token(tk); - - log && log("after token", xtag("i_tk", i_tk), xtag("tk", tk)); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - if (i_tk + 1 < n_tk) { - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } else { - /* last token in tk_v[] */ - - REQUIRE(parser.has_incomplete_expr() == false); - REQUIRE(!result.is_error()); - REQUIRE(result.is_expression()); - REQUIRE(result.result_expr()); - } - - ++i_tk; - } - + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); } } /*namespace ut*/ } /*namespace xo*/ From 5040cef10209f01210d7db7e9c794f9138c50981 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 18:11:08 -0500 Subject: [PATCH 199/258] xo-reader2: utest: refactor w/ syntax annotation etc. --- xo-reader2/utest/SchematikaParser.test.cpp | 209 +++------------------ 1 file changed, 24 insertions(+), 185 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 0addfb7c..609bfe57 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -495,8 +495,10 @@ namespace xo { TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + constexpr bool c_debug_flag = false; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; config.name_ = "test-arena"; @@ -512,193 +514,30 @@ namespace xo { /** Walkthrough parsing input equivalent to: * * lambda (n : i64, r : i64) -> i64 { 123 } - * + * ^ ^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + * 0 1| 3 4 5 6 7 8 9 a b c d e + * 2 **/ - { - auto & result = parser.on_token(Token::lambda_token()); + std::vector tk_v{ + /* [ 0] */ Token::lambda_token(), + /* [ 1] */ Token::leftparen_token(), + /* [ 2] */ Token::symbol_token("n"), + /* [ 3] */ Token::colon_token(), + /* [ 4] */ Token::symbol_token("i64"), + /* [ 5] */ Token::comma_token(), + /* [ 6] */ Token::symbol_token("r"), + /* [ 7] */ Token::colon_token(), + /* [ 8] */ Token::symbol_token("i64"), + /* [ 9] */ Token::rightparen_token(), + /* [ a] */ Token::yields_token(), + /* [ b] */ Token::symbol_token("i64"), + /* [ c] */ Token::leftbrace_token(), + /* [ d] */ Token::i64_token("123"), + /* [ e] */ Token::rightbrace_token(), + }; - log && log("after lambda token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::leftparen_token()); - - log && log("after lparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("n")); - - log && log("after symbol(n) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::colon_token()); - - log && log("after colon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("i64")); - - log && log("after symbol(i64) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::comma_token()); - - log && log("after comma token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("r")); - - log && log("after symbol(r) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::colon_token()); - - log && log("after colon token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("i64")); - - log && log("after symbol(i64) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::rightparen_token()); - - log && log("after rightparen token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::yields_token()); - - log && log("after yields token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::symbol_token("i64")); - - log && log("after symbol(i64) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::leftbrace_token()); - - log && log("after leftbrace token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::i64_token("123")); - - log && log("after f64(123) token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == true); - REQUIRE(!result.is_error()); - REQUIRE(result.is_incomplete()); - } - - { - auto & result = parser.on_token(Token::rightbrace_token()); - - log && log("after rightbrace token:"); - log && log(xtag("parser", &parser)); - log && log(xtag("result", result)); - - REQUIRE(parser.has_incomplete_expr() == false); - REQUIRE(!result.is_error()); - REQUIRE(result.is_expression()); - REQUIRE(result.result_expr()); - } - - //REQUIRE(result.is_error()); - //// illegal input on token - //REQUIRE(result.error_description()); + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); } TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") From f754f51ba5ccdc732dcf5281e4460789b448c049 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 18:13:10 -0500 Subject: [PATCH 200/258] xo-reader2: utest: annotate syntax --- xo-reader2/utest/SchematikaParser.test.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 609bfe57..d6f74edc 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -451,14 +451,15 @@ namespace xo { /** Walkthrough parsing input equivalent to: * * 312 == 312 ; - * + * ^ ^ ^ ^ + * 0 1 2 3 **/ std::vector tk_v{ - Token::i64_token("312"), - Token::cmpeq_token(), - Token::i64_token("312"), - Token::semicolon_token(), + /* [0] */ Token::i64_token("312"), + /* [1] */ Token::cmpeq_token(), + /* [2] */ Token::i64_token("312"), + /* [3] */ Token::semicolon_token(), }; utest_tokenizer_loop(&parser, tk_v, c_debug_flag); From 2c5cf63723d87126a96ad98c3df095cf8fbb02f5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 18:22:19 -0500 Subject: [PATCH 201/258] xo-interpreter2: utest: + VirtualSchematikaMachine-cmp1 --- .../utest/VirtualSchematikaMachine.test.cpp | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 6b4f9cf8..90f18551 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #ifdef NOT_YET @@ -30,6 +31,7 @@ namespace xo { using xo::scm::VsmResultExt; using xo::scm::DClosure; using xo::scm::DFloat; + using xo::scm::DBoolean; using xo::scm::DInteger; using xo::scm::DRuntimeError; using xo::mm::AGCObject; @@ -188,9 +190,50 @@ namespace xo { vsm.visit_pools(visitor); } + TEST_CASE("VirtualSchematikaMachine-cmp1", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + scope log(XO_DEBUG(true), xtag("test", testname)); + + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("123 == 123;"), eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq())); + + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE(x.data()->value() == true); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + FacetRegistry::instance().visit_pools(visitor); + vsm.visit_pools(visitor); + } + TEST_CASE("VirtualSchematikaMachine-lambda1", "[interpreter2][VSM]") { - scope log(XO_DEBUG(true)); + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + scope log(XO_DEBUG(false), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); From 556ed5dd739d32339a5e791b6d9d173c4779fff5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 18:23:43 -0500 Subject: [PATCH 202/258] xo-interpreter2: utest: log test names --- .../utest/VirtualSchematikaMachine.test.cpp | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 90f18551..7c31d645 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -64,7 +64,9 @@ namespace xo { namespace ut { TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]") { - scope log(XO_DEBUG(true)); + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + scope log(XO_DEBUG(true), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -83,7 +85,9 @@ namespace xo { TEST_CASE("VirtualSchematikaMachine-const1", "[interpreter2][VSM]") { - scope log(XO_DEBUG(true)); + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + scope log(XO_DEBUG(true), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -118,7 +122,9 @@ namespace xo { TEST_CASE("VirtualSchematikaMachine-const2", "[interpreter2][VSM]") { - scope log(XO_DEBUG(true)); + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + scope log(XO_DEBUG(true), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -155,7 +161,9 @@ namespace xo { TEST_CASE("VirtualSchematikaMachine-arith1", "[interpreter2][VSM]") { - scope log(XO_DEBUG(true)); + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + scope log(XO_DEBUG(true), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -270,7 +278,9 @@ namespace xo { TEST_CASE("VirtualSchematikaMachine-apply2", "[interpreter2][VSM]") { - scope log(XO_DEBUG(false)); + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + scope log(XO_DEBUG(false), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); From 6ffe3a627d25ed22e495cfeda52eab6600f5a552 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 13 Feb 2026 20:46:53 -0500 Subject: [PATCH 203/258] xo-interpreter2: work on global symtab [WIP] --- .../include/xo/expression2/DGlobalSymtab.hpp | 20 +++++++- .../include/xo/interpreter2/DGlobalEnv.hpp | 25 ++++++++-- .../utest/VirtualSchematikaMachine.test.cpp | 46 ++++++++++++++++++- 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index bb668ff3..91117888 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -6,6 +6,7 @@ #pragma once #include "Binding.hpp" +#include namespace xo { namespace scm { @@ -13,10 +14,21 @@ namespace xo { /** @class DGlobalSymtab * @brief symbol table for toplevel environment + * + * We're using DArenaHashMap to store pairs. + * Both of these are outside GC-space, so we don't need collector + * to traverse these. **/ - struct DGlobalSymtab { + class DGlobalSymtab { public: + using key_type = const DUniqueString *; + using value_type = Binding; + using repr_type = xo::map::DArenaHashMap; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + public: + /** visit symtab-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; public: /** @defgroup xo-expression2-symboltable-facet symboltable facet**/ @@ -31,6 +43,12 @@ namespace xo { ///@} private: + /** next binding will use this global index. See DGlobalEnv **/ + uint32_t next_binding_ix_ = 0; + + /** map symbols -> bindings **/ + repr_type map_; + }; } /*namespace scm*/ diff --git a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp index e9f1a9c8..60fbe461 100644 --- a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp @@ -6,26 +6,43 @@ #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 MemorySizeVisitor = xo::mm::MemorySizeVisitor; + public: DGlobalEnv() = default; + /** visit env-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; + protected: // temporary, to appease compiler // absurd O(n) implementation for now // replace with gc-aware hashtable, when available. - /** globals. Slots in @ref global_v_ are numbered in DLocalSymtab **/ - DArray * global_v_ = nullptr; + /** 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; }; } } diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 7c31d645..960c1771 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -202,7 +202,8 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(true), xtag("test", testname)); + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); @@ -237,11 +238,52 @@ namespace xo { vsm.visit_pools(visitor); } + TEST_CASE("VirtualSchematikaMachine-if", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + VsmConfig cfg; + VirtualSchematikaMachine vsm(cfg); + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("if 123 == 123 then \"equal\" else \"notequal\";"), eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq())); + + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE(x.data()->value() == true); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + auto visitor = [&log](const MemorySizeInfo & info) { + log && log(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + FacetRegistry::instance().visit_pools(visitor); + vsm.visit_pools(visitor); + } + TEST_CASE("VirtualSchematikaMachine-lambda1", "[interpreter2][VSM]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(false), xtag("test", testname)); + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); VsmConfig cfg; VirtualSchematikaMachine vsm(cfg); From e7e9d226dd5ef075d40659cc3547b230612cbde0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 14 Feb 2026 11:15:38 -0500 Subject: [PATCH 204/258] xo-interpreter2: ifelse expressions working + utest --- xo-interpreter2/CMakeLists.txt | 26 ++++++ .../idl/IGCObject_DVsmIfElseContFrame.json5 | 15 ++++ .../idl/IPrintable_DVsmIfElseContFrame.json5 | 13 +++ .../xo/interpreter2/DVsmIfElseContFrame.hpp | 82 +++++++++++++++++++ .../interpreter2/VirtualSchematikaMachine.hpp | 5 ++ .../xo/interpreter2/VsmIfElseContFrame.hpp | 12 +++ .../include/xo/interpreter2/VsmInstr.hpp | 9 +- .../include/xo/interpreter2/VsmOpcode.hpp | 6 +- .../ifelse/IGCObject_DVsmIfElseContFrame.hpp | 67 +++++++++++++++ .../ifelse/IPrintable_DVsmIfElseContFrame.hpp | 62 ++++++++++++++ .../src/interpreter2/CMakeLists.txt | 4 + .../src/interpreter2/DVsmIfElseContFrame.cpp | 66 +++++++++++++++ .../IGCObject_DVsmIfElseContFrame.cpp | 39 +++++++++ .../IPrintable_DVsmIfElseContFrame.cpp | 28 +++++++ .../interpreter2/VirtualSchematikaMachine.cpp | 67 ++++++++++++++- xo-interpreter2/src/interpreter2/VsmInstr.cpp | 4 + .../interpreter2_register_facets.cpp | 5 ++ .../utest/VirtualSchematikaMachine.test.cpp | 5 +- 18 files changed, 508 insertions(+), 7 deletions(-) create mode 100644 xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 create mode 100644 xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/DVsmIfElseContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmIfElseContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/ifelse/IGCObject_DVsmIfElseContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/ifelse/IPrintable_DVsmIfElseContFrame.hpp create mode 100644 xo-interpreter2/src/interpreter2/DVsmIfElseContFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DVsmIfElseContFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DVsmIfElseContFrame.cpp diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 26124a21..0b5431ba 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -103,6 +103,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-vsmifelsecontframe + FACET_PKG xo_gc + FACET GCObject + REPR VsmIfElseContFrame + INPUT idl/IGCObject_DVsmIfElseContFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR ifelse + OUTPUT_CPP_DIR src/interpreter2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-vsmifelsecontframe + FACET_PKG xo_printable2 + FACET Printable + REPR VsmIfElseContFrame + INPUT idl/IPrintable_DVsmIfElseContFrame.json5 + OUTPUT_HPP_DIR include/xo/interpreter2 + OUTPUT_IMPL_SUBDIR ifelse + OUTPUT_CPP_DIR src/interpreter2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-interpreter2-facetimpl-gcobject-vsmseqcontframe diff --git a/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 new file mode 100644 index 00000000..0f78bb6d --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 @@ -0,0 +1,15 @@ +{ + mode: "implementation", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVsmIfElseContFrame", + using_doxygen: true, + repr: "DVsmIfElseContFrame", + doc: [ "implement AGCObject for DVsmIfElseContFrame" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 new file mode 100644 index 00000000..d3d63c4d --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVsmIfElseContFrame", + using_doxygen: true, + repr: "DVsmIfElseContFrame", + doc: [ "implement APrintable for DVsmIfElseContFrame" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmIfElseContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmIfElseContFrame.hpp new file mode 100644 index 00000000..3d4ace12 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DVsmIfElseContFrame.hpp @@ -0,0 +1,82 @@ +/** @file DVsmIfElseContFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "VsmInstr.hpp" +#include +#include + +namespace xo { + namespace scm { + /** @brief saved VSM state during evaluation of a SequenceExpr + **/ + class DVsmIfElseContFrame { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-vsmevalsequenceframe-ctors constructors **/ + ///@{ + + DVsmIfElseContFrame(obj parent, + VsmInstr cont, + DIfElseExpr * ifelse_expr); + + /** create instance using memory from allocator @p mm **/ + static DVsmIfElseContFrame * make(obj mm, + obj parent, + VsmInstr cont, + DIfElseExpr * ifelse_expr); + + ///@} + /** @defgroup scm-vsmevalsequenceframe-access-methods access methods **/ + ///@{ + + obj parent() const noexcept { return parent_; } + VsmInstr cont() const noexcept { return cont_; } + DIfElseExpr * ifelse_expr() const noexcept { return ifelse_expr_; } + + ///@} + /** @defgroup scm-vsmevalsequenceframe-general-methods general methods **/ + ///@{ + + ///@} + /** @defgroup scm-vsmevalsequenceframe-gcobject-facet gcobject facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DVsmIfElseContFrame * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} + /** @defgrouop scm-vsmseqcontframe-printable-facet printable facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const noexcept; + + ///@} + + private: + /** @defgroup scm-vsmevalsequenceframe-members member variables **/ + ///@{ + + /** saved VSM stack; restore when this frame consumed **/ + obj parent_; + /** saved continuation; restore when this frame consumed **/ + VsmInstr cont_; + /** saved expr. evaluate elements of this sequence in order **/ + DIfElseExpr * ifelse_expr_ = nullptr; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmIfElseContFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index ce412391..b809a09d 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -187,6 +187,11 @@ namespace xo { **/ void _do_apply_cont_op(); + /** proceed with if- or else- branch of an if-else expression + * after evaluating test condition + **/ + void _do_ifelse_cont_op(); + /** loop continuation after evaluating element of a SequenceExpr **/ void _do_seq_cont_op(); diff --git a/xo-interpreter2/include/xo/interpreter2/VsmIfElseContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmIfElseContFrame.hpp new file mode 100644 index 00000000..a0494ddf --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmIfElseContFrame.hpp @@ -0,0 +1,12 @@ +/** @file VsmIfElseContFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVsmIfElseContFrame.hpp" +#include "ifelse/IGCObject_DVsmIfElseContFrame.hpp" +#include "ifelse/IPrintable_DVsmIfElseContFrame.hpp" + +/* end VsmIfElseContFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index d7444b86..1279f8b7 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -13,14 +13,21 @@ namespace xo { public: explicit VsmInstr(vsm_opcode oc) : opcode_{oc} {} + // instructions + static VsmInstr c_halt; static VsmInstr c_eval; static VsmInstr c_apply; static VsmInstr c_evalargs; - /** proceed to continuation after an ApplyExpr **/ + /** restore VSM state for continuation of an apply expression **/ static VsmInstr c_apply_cont; + /** proceed to branch of if-else expression after evaluating + * test condition + **/ + static VsmInstr c_ifelse_cont; + /** loop to evaluate members of a SequenceExpr **/ static VsmInstr c_seq_cont; diff --git a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp index 2a277a49..e1000cb3 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp @@ -28,11 +28,14 @@ namespace xo { **/ evalargs, - /** Coda to restore vsm registers (local_env, stack, cont) + /** continuation to restore vsm registers (local_env, stack, cont) * after invoking a closure **/ apply_cont, + /** continuation to act on a branch **/ + ifelse_cont, + /** Loop over elements of a SequenceExpr **/ seq_cont, @@ -55,3 +58,4 @@ namespace xo { } /*namespace xo*/ /* end VsmOpcode.hpp */ + diff --git a/xo-interpreter2/include/xo/interpreter2/ifelse/IGCObject_DVsmIfElseContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/ifelse/IGCObject_DVsmIfElseContFrame.hpp new file mode 100644 index 00000000..293dd70d --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/ifelse/IGCObject_DVsmIfElseContFrame.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVsmIfElseContFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmIfElseContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmIfElseContFrame.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVsmIfElseContFrame.hpp" + +namespace xo { namespace scm { class IGCObject_DVsmIfElseContFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVsmIfElseContFrame + **/ + class IGCObject_DVsmIfElseContFrame { + public: + /** @defgroup scm-gcobject-dvsmifelsecontframe-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvsmifelsecontframe-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVsmIfElseContFrame & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVsmIfElseContFrame & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVsmIfElseContFrame & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/ifelse/IPrintable_DVsmIfElseContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/ifelse/IPrintable_DVsmIfElseContFrame.hpp new file mode 100644 index 00000000..5f0e5a7b --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/ifelse/IPrintable_DVsmIfElseContFrame.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVsmIfElseContFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmIfElseContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmIfElseContFrame.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVsmIfElseContFrame.hpp" + +namespace xo { namespace scm { class IPrintable_DVsmIfElseContFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVsmIfElseContFrame + **/ + class IPrintable_DVsmIfElseContFrame { + public: + /** @defgroup scm-printable-dvsmifelsecontframe-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvsmifelsecontframe-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVsmIfElseContFrame & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index 64e7dfe8..c21821e1 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -20,6 +20,10 @@ set(SELF_SRCS IGCObject_DVsmApplyClosureFrame.cpp IPrintable_DVsmApplyClosureFrame.cpp + DVsmIfElseContFrame.cpp + IGCObject_DVsmIfElseContFrame.cpp + IPrintable_DVsmIfElseContFrame.cpp + DVsmSeqContFrame.cpp IGCObject_DVsmSeqContFrame.cpp IPrintable_DVsmSeqContFrame.cpp diff --git a/xo-interpreter2/src/interpreter2/DVsmIfElseContFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmIfElseContFrame.cpp new file mode 100644 index 00000000..f47419e0 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DVsmIfElseContFrame.cpp @@ -0,0 +1,66 @@ +/** @file DVsmIfElseContFrame.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVsmIfElseContFrame.hpp" + +namespace xo { + namespace scm { + + DVsmIfElseContFrame::DVsmIfElseContFrame(obj parent, + VsmInstr cont, + DIfElseExpr * ifelse_expr) + : parent_{parent}, + cont_{cont}, + ifelse_expr_{ifelse_expr} + {} + + DVsmIfElseContFrame * + DVsmIfElseContFrame::make(obj mm, + obj parent, + VsmInstr cont, + DIfElseExpr * seq_expr) + { + void * mem = mm.alloc_for(); + + return new (mem) DVsmIfElseContFrame(parent, cont, seq_expr); + } + + // gcobject facet + + std::size_t + DVsmIfElseContFrame::shallow_size() const noexcept + { + return sizeof(*this); + } + + DVsmIfElseContFrame * + DVsmIfElseContFrame::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DVsmIfElseContFrame::forward_children(obj gc) noexcept + { + gc.forward_inplace(&parent_); + gc.forward_inplace(&ifelse_expr_); + + return this->shallow_size(); + } + + // printable facet + + bool + DVsmIfElseContFrame::pretty(const ppindentinfo & ppii) const noexcept + { + return ppii.pps()->pretty_struct(ppii, + "DVsmIfElseContFrame", + refrtag("cont", cont_)); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmIfElseContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DVsmIfElseContFrame.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DVsmIfElseContFrame.cpp new file mode 100644 index 00000000..ba66cd8d --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DVsmIfElseContFrame.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVsmIfElseContFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmIfElseContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmIfElseContFrame.json5] +**/ + +#include "ifelse/IGCObject_DVsmIfElseContFrame.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVsmIfElseContFrame::shallow_size(const DVsmIfElseContFrame & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVsmIfElseContFrame::shallow_copy(const DVsmIfElseContFrame & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVsmIfElseContFrame::forward_children(DVsmIfElseContFrame & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVsmIfElseContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DVsmIfElseContFrame.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DVsmIfElseContFrame.cpp new file mode 100644 index 00000000..e8afc908 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DVsmIfElseContFrame.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVsmIfElseContFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmIfElseContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmIfElseContFrame.json5] +**/ + +#include "ifelse/IPrintable_DVsmIfElseContFrame.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVsmIfElseContFrame::pretty(const DVsmIfElseContFrame & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVsmIfElseContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index d1b8eacb..f3473681 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -7,6 +7,7 @@ #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "VsmApplyClosureFrame.hpp" +#include "VsmIfElseContFrame.hpp" #include "VsmSeqContFrame.hpp" #include "VsmRcx.hpp" #include "Closure.hpp" @@ -14,6 +15,7 @@ #include #include #include +#include #include //#include #include @@ -190,6 +192,9 @@ namespace xo { case vsm_opcode::apply_cont: _do_apply_cont_op(); break; + case vsm_opcode::ifelse_cont: + _do_ifelse_cont_op(); + break; case vsm_opcode::seq_cont: _do_seq_cont_op(); break; @@ -388,14 +393,26 @@ namespace xo { void VirtualSchematikaMachine::_do_eval_if_else_op() { - // not implemented - assert(false); + // control: + // self -> eval(test) -> ifelse_cont -> eval(when_true) + // -> eval(when_false) + + auto ifelse_expr = obj::from(expr_); + + obj ifelse_frame + (DVsmIfElseContFrame::make(mm_.to_op(), + stack_, cont_, ifelse_expr.data())); + + this->stack_ = ifelse_frame; + this->cont_ = VsmInstr::c_ifelse_cont; + this->expr_ = ifelse_expr->test(); + this->pc_ = VsmInstr::c_eval; } void VirtualSchematikaMachine::_do_eval_sequence_op() { - // assuming bump allocator: + // stack: // // VsmEvalSequence // v @@ -640,6 +657,50 @@ namespace xo { this->pc_ = frame->cont(); } + void + VirtualSchematikaMachine::_do_ifelse_cont_op() + { + // pre: result of evaluating test condition in value_ register + + auto frame = obj::from(stack_); + + assert(frame); + assert(value_.is_value()); + + auto flag = obj::from(*value_.value()); + + if (flag.data()) { + obj next_expr; + { + if (flag->value()) { + // proceed with if-branch + next_expr = frame->ifelse_expr()->when_true(); + } else { + // proceed with else-branch + next_expr = frame->ifelse_expr()->when_false(); + } + } + + this->stack_ = frame->parent(); + this->cont_ = frame->cont(); + this->expr_ = next_expr; + this->pc_ = VsmInstr::c_eval; + } else { + auto error = DRuntimeError::make(mm_.to_op(), + "_do_ifelse_cont_op", + "expected boolean for test condition"); + this->value_ = VsmResult(error); + + // for now: halt VSM execution + // TODO: some combination of + // 1. emit stack trace + // 2. go to debugger + // 3. have every vsm instruction check inputs for errors + + this->pc_ = VsmInstr::c_halt; + } + } + void VirtualSchematikaMachine::_do_seq_cont_op() { diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp index d1923cbd..b815c079 100644 --- a/xo-interpreter2/src/interpreter2/VsmInstr.cpp +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -16,6 +16,7 @@ namespace xo { case vsm_opcode::apply: return "apply"; case vsm_opcode::evalargs: return "evalargs"; case vsm_opcode::apply_cont: return "apply_cont"; + case vsm_opcode::ifelse_cont: return "ifelse_cont"; case vsm_opcode::seq_cont: return "seq_cont"; case vsm_opcode::N: break; @@ -39,6 +40,9 @@ namespace xo { VsmInstr VsmInstr::c_apply_cont = VsmInstr(vsm_opcode::apply_cont); + VsmInstr + VsmInstr::c_ifelse_cont = VsmInstr(vsm_opcode::ifelse_cont); + VsmInstr VsmInstr::c_seq_cont = VsmInstr(vsm_opcode::seq_cont); } /*namespace scm*/ diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index 588419a2..dc9b31be 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -9,6 +9,7 @@ #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "VsmApplyClosureFrame.hpp" +#include "VsmIfElseContFrame.hpp" #include "VsmSeqContFrame.hpp" #include "Primitive_gco_2_gco_gco.hpp" #include "Closure.hpp" @@ -38,6 +39,7 @@ namespace xo { // +- VsmApplyFrame // +- VsmEvalArgsFrame // +- VsmApplyClosureFrame + // +- VsmIfElseContFrame // \- VsmSeqContFrame FacetRegistry::register_impl(); @@ -49,6 +51,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 960c1771..eb62267e 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -30,6 +30,7 @@ namespace xo { using xo::scm::VsmConfig; using xo::scm::VsmResultExt; using xo::scm::DClosure; + using xo::scm::DString; using xo::scm::DFloat; using xo::scm::DBoolean; using xo::scm::DInteger; @@ -258,10 +259,10 @@ namespace xo { log && log(xtag("res.tseq", res.value()->_typeseq())); - auto x = obj::from(*res.value()); + auto x = obj::from(*res.value()); REQUIRE(x); - REQUIRE(x.data()->value() == true); + REQUIRE(strcmp(x.data()->chars(), "equal") == 0); REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); From 0ad41823256b9fc746cfad87445cae98d1f4499b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 14 Feb 2026 13:06:54 -0500 Subject: [PATCH 205/258] xo-expression2 stack: + mvp DGlobalSymtab impl --- .../include/xo/expression2/Binding.hpp | 4 +- .../include/xo/expression2/DGlobalSymtab.hpp | 23 ++++- .../include/xo/expression2/DLocalSymtab.hpp | 2 +- .../src/expression2/DGlobalSymtab.cpp | 92 ++++++++++++++++++- xo-object2/include/xo/object2/DArray.hpp | 7 ++ xo-object2/src/object2/DArray.cpp | 17 ++++ 6 files changed, 140 insertions(+), 5 deletions(-) diff --git a/xo-expression2/include/xo/expression2/Binding.hpp b/xo-expression2/include/xo/expression2/Binding.hpp index 97f74c27..805ebeb9 100644 --- a/xo-expression2/include/xo/expression2/Binding.hpp +++ b/xo-expression2/include/xo/expression2/Binding.hpp @@ -12,6 +12,8 @@ namespace xo { namespace scm { class Binding { public: + using slot_type = int32_t; + static constexpr int32_t c_link_sentinel = -2; static constexpr int32_t c_link_global = -1; @@ -22,7 +24,7 @@ namespace xo { static Binding null() { return Binding(); } /** global bindings are located by symbol name **/ - static Binding global() { return Binding(c_link_global, 0); } + static Binding global(int32_t j_slot) { return Binding(c_link_global, j_slot); } static Binding local(int32_t j_slot) { return Binding(0, j_slot); } static Binding relative(int32_t i_link, Binding def); diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 91117888..0aca15c6 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -6,6 +6,8 @@ #pragma once #include "Binding.hpp" +#include "DVariable.hpp" +#include #include namespace xo { @@ -23,7 +25,8 @@ namespace xo { public: using key_type = const DUniqueString *; using value_type = Binding; - using repr_type = xo::map::DArenaHashMap; + using repr_type = xo::map::DArenaHashMap; + using AAllocator = xo::mm::AAllocator; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; public: @@ -31,6 +34,17 @@ namespace xo { void visit_pools(const MemorySizeVisitor & visitor) const; public: + /** lookup global symbol with name @p sym **/ + DVariable * lookup_variable(const DUniqueString * sym) const noexcept; + + /** establish binding for @p sym, with type described by @p typeref, + * replacing existing global (if present) with the same name. + * Use memory from @p mm to create variable-expr + **/ + DVariable * establish_variable(obj mm, + const DUniqueString * sym, + TypeRef typeref); + /** @defgroup xo-expression2-symboltable-facet symboltable facet**/ ///@{ @@ -49,6 +63,13 @@ namespace xo { /** map symbols -> bindings **/ repr_type map_; + /** array of variables. + * When S is a unique-string for a global symbol, then: + * 1. map_[S] is unique global index i(S) for S. + * 2. vars_[i(S)] is variable-expr var(S) for S + * 3. var(S)->name == S + **/ + DArray * vars_ = nullptr; }; } /*namespace scm*/ diff --git a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp index 6a75422d..f4073226 100644 --- a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp @@ -73,7 +73,7 @@ namespace xo { return slots_[ix.j_slot()].var_; } - /** increase slot size (provided beleow capacity) to append + /** increase slot size (provided below capacity) to append * binding for one local variable. Local variable will be allocated * from @p mm, named @p name, with type described by @p typeref. **/ diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp index c11761d9..10e1665f 100644 --- a/xo-expression2/src/expression2/DGlobalSymtab.cpp +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -5,20 +5,108 @@ #include "DGlobalSymtab.hpp" #include "DUniqueString.hpp" +#include +#include +#include +#include #include namespace xo { + using xo::mm::AGCObject; + namespace scm { +#ifdef NOT_YET + DVariable * + DGlobalSymtab::lookup_binding(Binding ix) noexcept + { + assert(ix.i_link() == -1); + assert(ix.j_slot() >= 0); + assert(vars_); + assert(std::uint64_t(ix.j_slot()) < vars_->size()); + + auto var_gco = obj::from((*vars_)[ix.j_slot()]);; + auto var = var_gco.to_facet(); + + assert(var.data()); + + return var.data(); + } +#endif + + DVariable * + DGlobalSymtab::lookup_variable(const DUniqueString * sym) const noexcept + { + Binding existing = this->lookup_binding(sym); + + if (existing.is_null()) + return nullptr; + + auto var_gco = obj::from((*vars_)[existing.j_slot()]); + auto var = var_gco.to_facet(); + + assert(var.data()); + + return var.data(); + } + + DVariable * + DGlobalSymtab::establish_variable(obj mm, + const DUniqueString * sym, + TypeRef typeref) + { + DVariable * var = this->lookup_variable(sym); + + if (!var) { + assert(vars_); + + DArray::size_type n = vars_->size(); + + /** make sure vars_ has room **/ + if (n == vars_->capacity()) { + // reallocate with more capacity + DArray * vars_2x = DArray::copy(mm, vars_, vars_->capacity() * 2); + + assert(vars_2x); + + this->vars_ = vars_2x; + } + + /** create new variable **/ + Binding binding = Binding::global(n); + var = DVariable::make(mm, sym, typeref, binding); + + if (!var) { + // something terribly wrong + assert(false); + return var; + } + + map_[sym] = binding.j_slot(); + + bool ok = vars_->push_back(obj(var)); + + if (!ok) + assert(false); + } + + return var; + } + Binding DGlobalSymtab::lookup_binding(const DUniqueString * sym) const noexcept { - (void)sym; + assert(sym); scope log(XO_DEBUG(true), "stub"); log && log(xtag("sym", std::string_view(*sym))); - return Binding(); + auto ix = map_.find(sym); + + if (ix == map_.end()) + return Binding::null(); + + return Binding::global(ix->second); } } /*namespace scm*/ diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index c6f25221..7b758860 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -58,6 +58,13 @@ namespace xo { static DArray * empty(obj mm, size_type cap); + /** create copy of @p src using memory from @p mm + * with capacity for @p new_cap elements + **/ + static DArray * copy(obj mm, + DArray * src, + size_type new_cap); + /** create array containing elements @p args, using memory from @p mm. * Nullptr if space exhausted. * diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index 237c9af5..e1414eec 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -37,6 +37,23 @@ namespace xo { return result; } + DArray * + DArray::copy(obj mm, + DArray * src, + size_type new_cap) + { + DArray * dest = empty(mm, new_cap); + + /** could just memcpy here **/ + for (size_type i = 0, n = src->size(); i < n; ++i) { + dest->elts_[i] = src->elts_[i]; + } + + dest->size_ = src->size(); + + return dest; + } + obj DArray::at(size_type ix) const { From 07dc58c1dc38661170a0b28fefabfbe8690201dc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:03:48 -0500 Subject: [PATCH 206/258] xo-arena: + ArenaHashMapConfig with functional mutators --- .../include/xo/arena/ArenaHashMapConfig.hpp | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 xo-arena/include/xo/arena/ArenaHashMapConfig.hpp diff --git a/xo-arena/include/xo/arena/ArenaHashMapConfig.hpp b/xo-arena/include/xo/arena/ArenaHashMapConfig.hpp new file mode 100644 index 00000000..69174141 --- /dev/null +++ b/xo-arena/include/xo/arena/ArenaHashMapConfig.hpp @@ -0,0 +1,58 @@ +/** @file ArenaHashMapConfig.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include +#include + +namespace xo { + namespace map { + /** @class ArenaHashMapConfig + * + * @brief configuration for a @ref DArenaHashMap instance + **/ + struct ArenaHashMapConfig { + /** @defgroup map-arenahashmapconfig-ctors **/ + ///@{ + + ArenaHashMapConfig with_name(std::string name) const { + ArenaHashMapConfig copy(*this); + copy.name_ = name; + return copy; + } + + ArenaHashMapConfig with_hint_max_capacity(std::size_t z) const { + ArenaHashMapConfig copy(*this); + copy.hint_max_capacity_ = z; + return copy; + } + + ArenaHashMapConfig with_debug_flag(bool x) const { + ArenaHashMapConfig copy(*this); + copy.debug_flag_ = x; + return copy; + } + + ///@} + /** @defgroup mm-arenahashmapconfig-instance-vars ArenaHashMapConfig members **/ + ///@{ + + /** optional name, for diagnostics **/ + std::string name_; + /** desired hard max hashmap size -> reserved virtual memory + * hint: actual max may be larger, because of power-of-2 considerations. + **/ + std::size_t hint_max_capacity_ = 0; + /** true to enable debug logging **/ + bool debug_flag_ = false; + + ///@} + }; + + } /*namespace map*/ +} /*namespace xo*/ + +/* end ArenaHashMapConfig.hpp */ From 4c785e647e1d522072113578ee7d0b2de78c5910 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:06:33 -0500 Subject: [PATCH 207/258] xo-gc: + X1Collector.hpp convenience header --- xo-gc/include/xo/gc/X1Collector.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 xo-gc/include/xo/gc/X1Collector.hpp diff --git a/xo-gc/include/xo/gc/X1Collector.hpp b/xo-gc/include/xo/gc/X1Collector.hpp new file mode 100644 index 00000000..c9d00da3 --- /dev/null +++ b/xo-gc/include/xo/gc/X1Collector.hpp @@ -0,0 +1,11 @@ +/** @file X1Collector.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DX1Collector.hpp" +#include "detail/ICollector_DX1Collector.hpp" + +/* end X1Collector.hpp */ From 38e6588cd90d54d35773c16f33d525de61980696 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:07:10 -0500 Subject: [PATCH 208/258] xo-alloc2: extend alloc_for to accept explicit size --- xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index 62552411..729778e9 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -32,8 +32,8 @@ namespace xo { : Object(iface, data) {} template - void * alloc_for() noexcept { - return O::iface()->alloc(O::data(), typeseq::id(), sizeof(T)); + void * alloc_for(size_type n = sizeof(T)) noexcept { + return O::iface()->alloc(O::data(), typeseq::id(), n); } template From 7813650aea5dddc4eb480307f86f9d423200ca7a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:08:02 -0500 Subject: [PATCH 209/258] xo-arena: doxygen nit --- xo-arena/include/xo/arena/ArenaConfig.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xo-arena/include/xo/arena/ArenaConfig.hpp b/xo-arena/include/xo/arena/ArenaConfig.hpp index d1ecbdca..05904f90 100644 --- a/xo-arena/include/xo/arena/ArenaConfig.hpp +++ b/xo-arena/include/xo/arena/ArenaConfig.hpp @@ -18,6 +18,9 @@ namespace xo { **/ struct ArenaConfig { /** @defgroup mm-arenaconfig-ctors **/ + ///@{ + + /** NOTE: not providing explicit ctors so we can use designated initializers **/ ArenaConfig with_name(std::string name) const { ArenaConfig copy(*this); @@ -37,6 +40,7 @@ namespace xo { return copy; } + ///@} /** @defgroup mm-arenaconfig-instance-vars ArenaConfig members **/ ///@{ From 27b076ee24450012dc85be7316e8f7821101a016 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:09:09 -0500 Subject: [PATCH 210/258] xo-arena: + mapping DArena ctor from ArenaConfig --- xo-arena/include/xo/arena/DArena.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xo-arena/include/xo/arena/DArena.hpp b/xo-arena/include/xo/arena/DArena.hpp index 658d2b1b..24429188 100644 --- a/xo-arena/include/xo/arena/DArena.hpp +++ b/xo-arena/include/xo/arena/DArena.hpp @@ -80,7 +80,9 @@ namespace xo { /** null ctor **/ DArena() = default; - /** ctor from already-mapped (but not committed) address range **/ + /** create arena from @p cfg. Will reserve memory for allocation **/ + DArena(const ArenaConfig & cfg); + /** ctor from already-mapped (but not committed) address range [lo,hi] **/ DArena(const ArenaConfig & cfg, size_type page_z, size_type arena_align_z, From 24757255c7e6d6c136c52175d5fc41101cdc51ea Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:10:40 -0500 Subject: [PATCH 211/258] xo-arena: + DArenaHashMap ctor from ArenaHashMapConfig --- xo-arena/include/xo/arena/DArenaHashMap.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xo-arena/include/xo/arena/DArenaHashMap.hpp b/xo-arena/include/xo/arena/DArenaHashMap.hpp index c52b9894..50e66698 100644 --- a/xo-arena/include/xo/arena/DArenaHashMap.hpp +++ b/xo-arena/include/xo/arena/DArenaHashMap.hpp @@ -5,6 +5,7 @@ #pragma once +#include "ArenaHashMapConfig.hpp" #include "DArenaVector.hpp" #include "hashmap/verify_policy.hpp" #include "hashmap/HashMapStore.hpp" @@ -57,6 +58,7 @@ namespace xo { public: /** create hash map **/ + DArenaHashMap(const ArenaHashMapConfig & cfg); DArenaHashMap(const std::string & name, size_type hint_max_capacity, bool debug_flag = false); @@ -199,6 +201,12 @@ namespace xo { bool debug_flag_ = false; }; + template + DArenaHashMap::DArenaHashMap(const ArenaHashMapConfig & cfg) + : DArenaHashMap(cfg.name_, Hash(), Equal(), cfg.hint_max_capacity_, cfg.debug_flag_) + { + } + template DArenaHashMap::DArenaHashMap(const std::string & name, size_type hint_max_capacity, From 3e6ab92bb3c825560763f6d0db57778040adc2ec Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:12:07 -0500 Subject: [PATCH 212/258] xo-alloc2: + abox convenience template: arena box --- xo-alloc2/include/xo/alloc2/abox.hpp | 116 +++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 xo-alloc2/include/xo/alloc2/abox.hpp diff --git a/xo-alloc2/include/xo/alloc2/abox.hpp b/xo-alloc2/include/xo/alloc2/abox.hpp new file mode 100644 index 00000000..d34271ae --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/abox.hpp @@ -0,0 +1,116 @@ +/** @file abox.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "Allocator.hpp" +#include +#include + +namespace xo { + namespace mm { + + /** object with owned state + * - with default DRepr argument: + * type-erased container (runtime polymorphism). + * - with sepcific DRepr argument: + * typed container (comptime polymorphism). + * + * Similar to box (see box.hpp in xo-facet/): + * 1. inherits fat object pointer with AFacet*, DRepr* pair + * 2. automatically calls polymorphic DRepr::~DRepr when + * abox goes out of scope. + * Unlike box: + * 3. gets memory from explicit arena-like allocator + * 4. calls dtor DRepr::~DRepr(), but not delete. + * Does not retain allocator. + **/ + template + struct abox : public xo::facet::RoutingType> { + using DVariantPlaceholder = xo::facet::DVariantPlaceholder; + using Super = xo::facet::RoutingType>; + + abox() : Super() {} + + /** abox takes ownership of data @p *d; + * will destroy when abox goes out of scope. + * + * Note this is not useful when DRepr=DVariablePlaceholder + **/ + explicit abox(Super::DataPtr d) : Super(d) {} + + /** Adopt instance that has interface @p iface and (type-erased here) + * representation @p data + **/ + abox(const AFacet * iface, void * data) + requires std::is_same_v + : Super(iface, data) + {} + + /** (copy ctor not supported -- ownership is unique) **/ + abox(const abox & other) = delete; + + /** Move constructor **/ + template + abox(abox && other) + requires (std::is_same_v + || std::is_same_v) + : xo::facet::RoutingType>() + { + /* replacing .iface_ along w/ .data_ */ + this->from_obj(other); + + other.reset_opaque(nullptr); + } + + /** allocates for sizeof(DRepr), so DRepr must not use flexible array **/ + template + static abox make(obj alloc, Args&&... args) { + void * mem = alloc.alloc_for(); + if (mem) { + DRepr * data = ::new (mem) DRepr(std::forward(args)...); + + assert(data); + + return abox(data); + } else { + assert(false); + + return abox(); + } + } + + // -------------------------------- + + /** explicit conversion to obj **/ + obj to_op() const noexcept { + return obj(this->iface(), this->data()); + } + + /** Take ownership from unowned object **/ + template + abox & adopt(const obj & other) + requires (std::is_same_v + || std::is_same_v) + { + /* replace .iface_ along w/ .data_ */ + this->from_obj(other); + + return *this; + } + + ~abox() { + auto p = this->data(); + if (p) { + this->_drop(); + } + } + }; + } /*namespace mm*/ + + using mm::abox; +} /*namespace xo*/ + +/* end abox.hpp */ From 5488a7671185d68fc11f475a8ad5c0f2ea66962e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:13:41 -0500 Subject: [PATCH 213/258] xo-arena: impl for DArena ctor w/ ArenaConfig arg --- xo-arena/src/arena/DArena.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xo-arena/src/arena/DArena.cpp b/xo-arena/src/arena/DArena.cpp index 32cb7c8c..cb305f9a 100644 --- a/xo-arena/src/arena/DArena.cpp +++ b/xo-arena/src/arena/DArena.cpp @@ -65,6 +65,11 @@ namespace xo { return DArena(cfg, page_z, align_z, span.lo(), span.hi()); } /*map*/ + DArena::DArena(const ArenaConfig & cfg) + { + *this = std::move(map(cfg)); + } + DArena::DArena(const ArenaConfig & cfg, size_type page_z, size_type arena_align_z, From 1f05a568f577a4e8125df79da5dcb9e582897d74 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:15:11 -0500 Subject: [PATCH 214/258] xo-gc: + X1CollectorConfig.with_name() --- xo-gc/include/xo/gc/X1CollectorConfig.hpp | 7 ++++++- xo-gc/src/gc/DX1Collector.cpp | 22 ++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/xo-gc/include/xo/gc/X1CollectorConfig.hpp b/xo-gc/include/xo/gc/X1CollectorConfig.hpp index 54296e2c..dec9545d 100644 --- a/xo-gc/include/xo/gc/X1CollectorConfig.hpp +++ b/xo-gc/include/xo/gc/X1CollectorConfig.hpp @@ -17,7 +17,12 @@ namespace xo { using size_type = std::size_t; /** copy of this config, - * with @c arena_config_.size_ set to @p gen_z + * but with @ref name_ set to @p name + **/ + X1CollectorConfig with_name(std::string name); + + /** copy of this config, + * but with @c arena_config_.size_ set to @p gen_z **/ X1CollectorConfig with_size(std::size_t gen_z); diff --git a/xo-gc/src/gc/DX1Collector.cpp b/xo-gc/src/gc/DX1Collector.cpp index a4375da5..ede4a734 100644 --- a/xo-gc/src/gc/DX1Collector.cpp +++ b/xo-gc/src/gc/DX1Collector.cpp @@ -25,6 +25,14 @@ namespace xo { namespace mm { + X1CollectorConfig + X1CollectorConfig::with_name(std::string name) + { + X1CollectorConfig copy = *this; + copy.name_ = std::move(name); + return copy; + } + X1CollectorConfig X1CollectorConfig::with_size(std::size_t gen_z) { @@ -33,20 +41,6 @@ namespace xo { return copy; } -#ifdef NOT_USING - constexpr std::uint64_t - X1CollectorConfig::gen_mult() const { - return 1ul << arena_config_.header_size_bits_; - } -#endif - -#ifdef NOT_USING - constexpr std::uint64_t - X1CollectorConfig::tseq_mult() const { - return 1ul << (gen_bits_ + arena_config_.header_size_bits_); - } -#endif - // ----- GCRunState ----- GCRunState::GCRunState(generation gc_upto) From 5560f84deeb3dc144bd4aae7c78895e1a97ff53d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:16:42 -0500 Subject: [PATCH 215/258] xo-object2: streamline DList gc hooks --- xo-object2/src/object2/DList.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/xo-object2/src/object2/DList.cpp b/xo-object2/src/object2/DList.cpp index 0be056d8..35cb7223 100644 --- a/xo-object2/src/object2/DList.cpp +++ b/xo-object2/src/object2/DList.cpp @@ -33,7 +33,7 @@ namespace xo { obj car, DList * cdr) { - void * mem = mm.alloc(typeseq::id(), sizeof(DList)); + void * mem = mm.alloc_for(); return new (mem) DList(car, cdr); } @@ -159,12 +159,7 @@ namespace xo { DList * DList::shallow_copy(obj mm) const noexcept { - DList * copy = (DList *)mm.alloc_copy((std::byte *)this); - - if (copy) - *copy = *this; - - return copy; + return mm.std_copy_for(this); } auto From cb29d009d3348ff77f62e5a59ff7f93619f2ef49 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 13:17:21 -0500 Subject: [PATCH 216/258] xo-expression2: DGlobalSymtab mvp implementation --- .../include/xo/expression2/DGlobalSymtab.hpp | 47 ++++++++-- .../src/expression2/DGlobalSymtab.cpp | 90 +++++++++++++++---- 2 files changed, 112 insertions(+), 25 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 0aca15c6..32fb9570 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -25,18 +25,41 @@ namespace xo { public: using key_type = const DUniqueString *; using value_type = Binding; + using ArenaHashMapConfig = xo::map::ArenaHashMapConfig; using repr_type = xo::map::DArenaHashMap; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; public: + /** @defgroup scm-globalsymtab-ctors constructors **/ + ///@{ + + DGlobalSymtab(repr_type * map, DArray * vars); + + /** create instance. + * Use memory from @p fixed_mm for @ref map_. + * Use memory from @p mm for DGlobalSymtab instance. + * Hashmap configured per @p cfg. + **/ + DGlobalSymtab * make(obj fixed_mm, + obj mm, + const ArenaHashMapConfig & cfg); + + ///@} + /** @defgroup scm-globalsymtab-access-methods access methods **/ + ///@{ + /** visit symtab-owned memory pools; call visitor(info) for each **/ void visit_pools(const MemorySizeVisitor & visitor) const; - public: /** lookup global symbol with name @p sym **/ DVariable * lookup_variable(const DUniqueString * sym) const noexcept; + ///@} + /** @defgroup scm-globalsymtab-general-methods general methods **/ + ///@{ + /** establish binding for @p sym, with type described by @p typeref, * replacing existing global (if present) with the same name. * Use memory from @p mm to create variable-expr @@ -45,7 +68,8 @@ namespace xo { const DUniqueString * sym, TypeRef typeref); - /** @defgroup xo-expression2-symboltable-facet symboltable facet**/ + ///@} + /** @defgroup scm-globalsymtab-symboltable-facet symboltable facet **/ ///@{ /** true for global symbol table **/ @@ -55,13 +79,22 @@ namespace xo { Binding lookup_binding(const DUniqueString * sym) const noexcept; ///@} + /** @defgroup scm-globalsymtab-gcobject-facet gcobject facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DGlobalSymtab * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} + private: - /** next binding will use this global index. See DGlobalEnv **/ - uint32_t next_binding_ix_ = 0; - - /** map symbols -> bindings **/ - repr_type map_; + /** map symbols -> bindings. + * Minor point: storing offsets instead of Variables allows us to omit + * iterating over map elements during GC. Possible savings if map_ slots + * sparsely populated. + **/ + repr_type * map_ = nullptr; /** array of variables. * When S is a unique-string for a global symbol, then: diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp index 10e1665f..85fd6e93 100644 --- a/xo-expression2/src/expression2/DGlobalSymtab.cpp +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -7,32 +7,57 @@ #include "DUniqueString.hpp" #include #include +#include #include #include #include namespace xo { + using xo::map::DArenaHashMap; using xo::mm::AGCObject; namespace scm { -#ifdef NOT_YET - DVariable * - DGlobalSymtab::lookup_binding(Binding ix) noexcept + DGlobalSymtab::DGlobalSymtab(repr_type * map, + DArray * vars) + : map_{map}, vars_{vars} { - assert(ix.i_link() == -1); - assert(ix.j_slot() >= 0); - assert(vars_); - assert(std::uint64_t(ix.j_slot()) < vars_->size()); - - auto var_gco = obj::from((*vars_)[ix.j_slot()]);; - auto var = var_gco.to_facet(); - - assert(var.data()); - - return var.data(); } -#endif + + DGlobalSymtab * + DGlobalSymtab::make(obj global_mm, + obj mm, + const ArenaHashMapConfig & cfg) + { + repr_type * map = nullptr; + { + /** memory DGlobalSymtab::map_ + * (but not counting the mmap()'s that map will make for itself) + **/ + void * global_mem = global_mm.alloc_for(); + + map = new (global_mem) repr_type(cfg); + } + assert(map); + + void * symtab_mem = mm.alloc_for(); + + /* choosing same capacity for hash, vars */ + DArray * vars = DArray::empty(mm, map->capacity()); + assert(vars); + + DGlobalSymtab * symtab = new (symtab_mem) DGlobalSymtab(map, vars); + assert(symtab); + + return symtab; + } + + void + DGlobalSymtab::visit_pools(const MemorySizeVisitor & visitor) const + { + if (map_) + map_->visit_pools(visitor); + } DVariable * DGlobalSymtab::lookup_variable(const DUniqueString * sym) const noexcept @@ -62,6 +87,9 @@ namespace xo { DArray::size_type n = vars_->size(); + // NOTE: expansion here is moot at present (Feb 2026). + // Not implemented in ArenaHashMap + /** make sure vars_ has room **/ if (n == vars_->capacity()) { // reallocate with more capacity @@ -82,7 +110,9 @@ namespace xo { return var; } - map_[sym] = binding.j_slot(); + assert(map_->size() < map_->capacity()); + + (*map_)[sym] = binding.j_slot(); bool ok = vars_->push_back(obj(var)); @@ -101,14 +131,38 @@ namespace xo { scope log(XO_DEBUG(true), "stub"); log && log(xtag("sym", std::string_view(*sym))); - auto ix = map_.find(sym); + auto ix = map_->find(sym); - if (ix == map_.end()) + if (ix == map_->end()) return Binding::null(); return Binding::global(ix->second); } + // ----- gcobject facet ----- + + std::size_t + DGlobalSymtab::shallow_size() const noexcept + { + return sizeof(DGlobalSymtab); + } + + DGlobalSymtab * + DGlobalSymtab::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DGlobalSymtab::forward_children(obj gc) noexcept + { + // map_ doesn't contain any gc-owned data, can skip + + gc.forward_inplace(&vars_); + + return this->shallow_size(); + } + } /*namespace scm*/ } /*namespace xo*/ From 176be07731ab6df01815931c72d2fda67921983f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 14:09:52 -0500 Subject: [PATCH 217/258] xo-alloc2: + RAllocator.alloc_copy_for convenience method --- xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index 729778e9..4d2af7f7 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -36,11 +36,16 @@ namespace xo { return O::iface()->alloc(O::data(), typeseq::id(), n); } + template + void * alloc_copy_for(const T * src) noexcept { + return O::iface()->alloc_copy(O::data(), (std::byte*)const_cast(src)); + } + template T * std_copy_for(const T * src) noexcept { // TODO: fix alloc_copy(), should take const std::byte * - T * copy = (T *)O::iface()->alloc_copy(O::data(), (std::byte*)const_cast(src)); + T * copy = (T *)(this->alloc_copy_for(src)); if (copy) { *copy = *src; From 72ef2c70ff484590270d7b4d434baf0be6a528be Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 14:10:47 -0500 Subject: [PATCH 218/258] xo-reader2: drop temporary debug flag --- xo-reader2/src/reader2/DProgressSsm.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index acffc851..94efb30d 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -497,7 +497,7 @@ namespace xo { DProgressSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { - const bool c_debug_flag = p_psm->debug_flag() || true; + const bool c_debug_flag = p_psm->debug_flag(); scope log(XO_DEBUG(c_debug_flag)); @@ -516,7 +516,7 @@ namespace xo { const Token & tk, ParserStateMachine * p_psm) { - const bool c_debug_flag = p_psm->debug_flag() || true; + const bool c_debug_flag = p_psm->debug_flag(); scope log(XO_DEBUG(c_debug_flag), xtag("expr", expr), @@ -1215,7 +1215,7 @@ namespace xo { case optype::op_assign: assert(false); break; - + case optype::op_equal: { auto pm_obj = (with_facet::mkobj From 6209c812d3b85fcd32ac5527ce0a2f1c6e4d63ac Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 14:12:31 -0500 Subject: [PATCH 219/258] xo-expression2 stack: + dp<> template + robustify DGlobalSymtab --- xo-alloc2/include/xo/alloc2/dp.hpp | 110 ++++++++++++++++++ .../include/xo/expression2/DGlobalSymtab.hpp | 17 +-- .../src/expression2/DGlobalSymtab.cpp | 41 ++++--- 3 files changed, 142 insertions(+), 26 deletions(-) create mode 100644 xo-alloc2/include/xo/alloc2/dp.hpp diff --git a/xo-alloc2/include/xo/alloc2/dp.hpp b/xo-alloc2/include/xo/alloc2/dp.hpp new file mode 100644 index 00000000..6c768ce8 --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/dp.hpp @@ -0,0 +1,110 @@ +/** @file dp.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "Allocator.hpp" +#include +#include + +namespace xo { + namespace mm { + + /** unimorphic "data pointer" with known representation and owned memory. + * runs dtor *but not delete*. Does not store allocator! + * + * Compare with abox + **/ + template + struct dp { + dp() = default; + + /** dp takes ownership of data @p ptr; + * will run dtor when dp goes out of scope. + * + * Note this is not useful when DRepr=DVariablePlaceholder + **/ + explicit dp(DRepr * ptr) : ptr_{ptr} {} + + /** (copy ctor not supported -- ownership is unique) **/ + dp(const dp & other) = delete; + + /** Move constructor **/ + dp(dp && other) + { + ptr_ = other.ptr_; + other.ptr_ = nullptr; + } + + /** allocates for sizeof(DRepr), so DRepr must not use flexible array **/ + template + static dp make(obj alloc, Args&&... args) { + void * mem = alloc.alloc_for(); + + if (mem) { + DRepr * data = ::new (mem) DRepr(std::forward(args)...); + assert(data); + + return dp(data); + } else { + assert(false); + + return dp(); + } + } + + dp & operator=(const dp & x) = delete; + + /** move assignment **/ + dp & operator=(dp && x) { + ptr_ = x.ptr_; + x.ptr_ = nullptr; + } + + // -------------------------------- + + DRepr * data() const noexcept { return ptr_; } + + operator bool() const noexcept { return ptr_ != nullptr; } + + DRepr * operator->() const noexcept { return ptr_; } + DRepr & operator*() const noexcept { return *ptr_; } + +#ifdef NOT_YET + /** explicit conversion to obj **/ + obj to_op() const noexcept { + return obj(this->iface(), this->data()); + } +#endif + +#ifdef NOT_YET + /** Take ownership from unowned object **/ + template + dp & adopt(const obj & other) + requires (std::is_same_v + || std::is_same_v) + { + /* replace .iface_ along w/ .data_ */ + this->from_obj(other); + + return *this; + } +#endif + + ~dp() { + if (ptr_) { + ptr_->~DRepr(); + } + } + + private: + DRepr * ptr_ = nullptr; + }; + } /*namespace mm*/ + + using mm::dp; +} /*namespace xo*/ + +/* end dp.hpp */ diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 32fb9570..566d8981 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -8,6 +8,7 @@ #include "Binding.hpp" #include "DVariable.hpp" #include +#include #include namespace xo { @@ -35,16 +36,16 @@ namespace xo { /** @defgroup scm-globalsymtab-ctors constructors **/ ///@{ - DGlobalSymtab(repr_type * map, DArray * vars); + DGlobalSymtab(dp map, DArray * vars); /** create instance. * Use memory from @p fixed_mm for @ref map_. * Use memory from @p mm for DGlobalSymtab instance. * Hashmap configured per @p cfg. **/ - DGlobalSymtab * make(obj fixed_mm, - obj mm, - const ArenaHashMapConfig & cfg); + dp make(obj fixed_mm, + obj mm, + const ArenaHashMapConfig & cfg); ///@} /** @defgroup scm-globalsymtab-access-methods access methods **/ @@ -81,21 +82,21 @@ namespace xo { ///@} /** @defgroup scm-globalsymtab-gcobject-facet gcobject facet **/ ///@{ - + std::size_t shallow_size() const noexcept; DGlobalSymtab * shallow_copy(obj mm) const noexcept; std::size_t forward_children(obj gc) noexcept; ///@} - + private: /** map symbols -> bindings. * Minor point: storing offsets instead of Variables allows us to omit * iterating over map elements during GC. Possible savings if map_ slots * sparsely populated. **/ - repr_type * map_ = nullptr; - + dp map_; + /** array of variables. * When S is a unique-string for a global symbol, then: * 1. map_[S] is unique global index i(S) for S. diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp index 85fd6e93..b7eb4d73 100644 --- a/xo-expression2/src/expression2/DGlobalSymtab.cpp +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -18,35 +18,25 @@ namespace xo { namespace scm { - DGlobalSymtab::DGlobalSymtab(repr_type * map, + DGlobalSymtab::DGlobalSymtab(dp map, DArray * vars) - : map_{map}, vars_{vars} + : map_{std::move(map)}, vars_{vars} { } - DGlobalSymtab * - DGlobalSymtab::make(obj global_mm, + dp + DGlobalSymtab::make(obj aux_mm, obj mm, const ArenaHashMapConfig & cfg) { - repr_type * map = nullptr; - { - /** memory DGlobalSymtab::map_ - * (but not counting the mmap()'s that map will make for itself) - **/ - void * global_mem = global_mm.alloc_for(); - - map = new (global_mem) repr_type(cfg); - } + auto map = dp::make(aux_mm, cfg); assert(map); - void * symtab_mem = mm.alloc_for(); - /* choosing same capacity for hash, vars */ DArray * vars = DArray::empty(mm, map->capacity()); assert(vars); - DGlobalSymtab * symtab = new (symtab_mem) DGlobalSymtab(map, vars); + auto symtab = dp::make(mm, std::move(map), vars); assert(symtab); return symtab; @@ -133,7 +123,7 @@ namespace xo { auto ix = map_->find(sym); - if (ix == map_->end()) + if (ix == map_->end()) return Binding::null(); return Binding::global(ix->second); @@ -150,7 +140,22 @@ namespace xo { DGlobalSymtab * DGlobalSymtab::shallow_copy(obj mm) const noexcept { - return mm.std_copy_for(this); + /** can't use std_copy_for because of non-copyable dp + * + * TODO: rename to shallow_move() throughout, and have std_copy_for() + * -> std_move_for() + * + **/ + + void * copy_mem = mm.alloc_copy_for(this); + + if (copy_mem) { + DGlobalSymtab * self = const_cast(this); + + return new (copy_mem) DGlobalSymtab(std::move(self->map_), vars_); + } + + return nullptr; } std::size_t From 31c6697467bc201955212580a4a81ec13bea2bff Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 14:13:38 -0500 Subject: [PATCH 220/258] xo-interpreter2 stack: plumbing for aux_mm and use opportunistically --- .../interpreter2/VirtualSchematikaMachine.hpp | 22 +- .../include/xo/interpreter2/VsmConfig.hpp | 15 +- .../interpreter2/VirtualSchematikaMachine.cpp | 26 +-- .../utest/VirtualSchematikaMachine.test.cpp | 211 ++++++++---------- .../example/readerreplxx/readerreplxx.cpp | 22 +- .../include/xo/reader2/ParserStateMachine.hpp | 27 ++- .../include/xo/reader2/SchematikaParser.hpp | 10 +- .../include/xo/reader2/SchematikaReader.hpp | 9 +- xo-reader2/src/reader2/ParserStateMachine.cpp | 9 +- xo-reader2/src/reader2/SchematikaParser.cpp | 5 +- xo-reader2/src/reader2/SchematikaReader.cpp | 4 +- xo-reader2/utest/SchematikaParser.test.cpp | 66 +++--- 12 files changed, 243 insertions(+), 183 deletions(-) diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index b809a09d..2cbd08e4 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include namespace xo { namespace scm { @@ -74,7 +74,12 @@ namespace xo { using span_type = xo::mm::span; public: - VirtualSchematikaMachine(const VsmConfig & config); + /** @p config. configuration + * @p aux_mm. Allocator for miscellaneous dataN + * owned by this VSM. + **/ + VirtualSchematikaMachine(const VsmConfig & config, + obj aux_mm); /** allocator for schematika data **/ obj allocator() const noexcept; @@ -213,10 +218,17 @@ namespace xo { /** configuration **/ VsmConfig config_; +#ifdef NOT_YET + /** allocator (likely DArena) for globals. + * For example DArenaHashMap in global symtab, + **/ + obj aux_mm_; +#endif + /** allocator (likely DX1Collector or similar) for * expressions and values **/ - box mm_; + abox mm_; /** Sidecar allocator for error reporting. * Separate to mitigate interference with @ref mm_ @@ -224,12 +236,12 @@ namespace xo { * an out-of-memory error). * Likely DArena or similar **/ - box error_mm_; + abox error_mm_; /** runtime context for this vsm. * For example, provides allocator to primitives **/ - box rcx_; + abox rcx_; // consider separate allocator (which _may_ turn out to be the same) // for VM stack. Only works for code that doesn't rely on fancy diff --git a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp index f05ac449..bfbe152e 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmConfig.hpp @@ -19,15 +19,28 @@ namespace xo { VsmConfig() = default; + VsmConfig with_debug_flag(bool x) const { + VsmConfig retval = *this; + retval.debug_flag_ = x; + return retval; + } + /** true for interactive parser session; false for batch session **/ bool interactive_flag_ = true; + /** true to enable logging **/ + bool debug_flag_ = false; + /** reader configuration **/ ReaderConfig rdr_config_; /** Configuration for allocator/collector. * TODO: may want to make CollectorConfig polymorphic **/ - X1CollectorConfig x1_config_ = X1CollectorConfig().with_size(4*1024*1024); + X1CollectorConfig x1_config_ = X1CollectorConfig().with_name("gc").with_size(4*1024*1024); + /** Configuration for handful of non-moveable high-level objects + * e.g. DArenaHashMap in global symtab + **/ + ArenaConfig fixed_config_ = ArenaConfig().with_name("fixed").with_size(4*1024); /** Configuration for error allocator * TODO: may want to make ArenaConfig polymorphic **/ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index f3473681..5c2d2c57 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -54,16 +54,16 @@ namespace xo { // NOTE: using heap here for {DX1Collector, DArena, DVsmRcx} instances // (though DX1Collector allocations will be from explictly mmap'd memory) // - VirtualSchematikaMachine::VirtualSchematikaMachine(const VsmConfig & config) + VirtualSchematikaMachine::VirtualSchematikaMachine(const VsmConfig & config, + obj aux_mm) : config_{config}, - mm_(box(new DX1Collector(config.x1_config_))), - rcx_(box(new DVsmRcx(this))), - reader_{config.rdr_config_, mm_.to_op()} + mm_(abox::make(aux_mm, config.x1_config_)), + rcx_(abox::make(aux_mm, this)), + reader_{config.rdr_config_, mm_.to_op(), aux_mm} { { - DArena * arena = new DArena(); + DArena * arena = new DArena(config_.error_config_); assert(arena); - *arena = DArena::map(config_.error_config_); error_mm_.adopt(obj(arena)); } @@ -165,7 +165,7 @@ namespace xo { bool VirtualSchematikaMachine::execute_one() { - scope log(XO_DEBUG(true)); + scope log(XO_DEBUG(config_.debug_flag_)); log && log(xtag("pc", pc_), xtag("cont", cont_)); @@ -333,10 +333,10 @@ namespace xo { // for now: halt VSM execution // TODO: some combination of - // 1. emit stack trace + // 1. emit stack trace // 2. go to debugger // 3. have every vsm instruction check inputs for errors - + this->pc_ = VsmInstr::c_halt; } @@ -396,7 +396,7 @@ namespace xo { // control: // self -> eval(test) -> ifelse_cont -> eval(when_true) // -> eval(when_false) - + auto ifelse_expr = obj::from(expr_); obj ifelse_frame @@ -433,7 +433,7 @@ namespace xo { return; } - auto seqexpr_frame + auto seqexpr_frame = obj (DVsmSeqContFrame::make(mm_.to_op(), this->stack_ /*saved stack*/, @@ -693,10 +693,10 @@ namespace xo { // for now: halt VSM execution // TODO: some combination of - // 1. emit stack trace + // 1. emit stack trace // 2. go to debugger // 3. have every vsm instruction check inputs for errors - + this->pc_ = VsmInstr::c_halt; } } diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index eb62267e..1a50c555 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef NOT_YET #include @@ -37,61 +38,80 @@ namespace xo { using xo::scm::DRuntimeError; using xo::mm::AGCObject; using xo::mm::MemorySizeInfo; + using xo::mm::AAllocator; + using xo::mm::DArena; + using xo::mm::ArenaConfig; using xo::facet::FacetRegistry; using span_type = xo::scm::VirtualSchematikaMachine::span_type; using Catch::Matchers::WithinAbs; -#ifdef NOT_YET - using xo::scm::SchematikaParser; - using xo::scm::ASyntaxStateMachine; - using xo::scm::syntaxstatetype; -// using xo::scm::DDefineSsm; - using xo::scm::DExpectExprSsm; -// using xo::scm::defexprstatetype; - //using xo::scm::ParserResult; - //using xo::scm::parser_result_type; - using xo::scm::Token; - using xo::scm::DString; - using xo::mm::ArenaConfig; - using xo::mm::AAllocator; - using xo::mm::DArena; - using xo::facet::with_facet; -#endif using std::cout; using std::endl; static InitEvidence s_init = (InitSubsys::require()); namespace ut { + struct ArenaShim { + explicit ArenaShim(const std::string & name, std::size_t size = 16*1024) + : arena_(ArenaConfig().with_name(name).with_size(size)) + { + } + + obj to_op() { return obj(&arena_); } + + DArena arena_; + }; + + struct VsmFixture { + explicit VsmFixture(const std::string & testname, + bool debug_flag, + const VsmConfig & cfg = VsmConfig()) + : aux_mm_{testname}, + vsm_{cfg.with_debug_flag(debug_flag), aux_mm_.to_op()} + {} + + bool log_memory_layout(scope * p_log) { + auto visitor = [p_log](const MemorySizeInfo & info) { + *p_log && (*p_log)(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + aux_mm_.arena_.visit_pools(visitor); + FacetRegistry::instance().visit_pools(visitor); + vsm_.visit_pools(visitor); + + return true; + } + + ArenaShim aux_mm_; + VirtualSchematikaMachine vsm_; + }; + TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(true), xtag("test", testname)); + bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - VsmConfig cfg; - VirtualSchematikaMachine vsm(cfg); + VsmFixture vsm_fixture(testname, c_debug_flag); - auto visitor = [&log](const MemorySizeInfo & info) { - log && log(xtag("resource", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), - xtag("commit", info.committed_), - xtag("resv", info.reserved_)); - }; - - FacetRegistry::instance().visit_pools(visitor); - vsm.visit_pools(visitor); + log && vsm_fixture.log_memory_layout(&log); } TEST_CASE("VirtualSchematikaMachine-const1", "[interpreter2][VSM]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(true), xtag("test", testname)); + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - VsmConfig cfg; - VirtualSchematikaMachine vsm(cfg); + VsmFixture vsm_fixture(testname, c_debug_flag); + + auto & vsm = vsm_fixture.vsm_; bool eof_flag = false; @@ -109,26 +129,19 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); - auto visitor = [&log](const MemorySizeInfo & info) { - log && log(xtag("resource", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), - xtag("commit", info.committed_), - xtag("resv", info.reserved_)); - }; - - FacetRegistry::instance().visit_pools(visitor); - vsm.visit_pools(visitor); + log && vsm_fixture.log_memory_layout(&log); } TEST_CASE("VirtualSchematikaMachine-const2", "[interpreter2][VSM]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(true), xtag("test", testname)); + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - VsmConfig cfg; - VirtualSchematikaMachine vsm(cfg); + VsmFixture vsm_fixture(testname, c_debug_flag); + + auto & vsm = vsm_fixture.vsm_; bool eof_flag = false; @@ -148,26 +161,18 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); - auto visitor = [&log](const MemorySizeInfo & info) { - log && log(xtag("resource", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), - xtag("commit", info.committed_), - xtag("resv", info.reserved_)); - }; - - FacetRegistry::instance().visit_pools(visitor); - vsm.visit_pools(visitor); + log && vsm_fixture.log_memory_layout(&log); } TEST_CASE("VirtualSchematikaMachine-arith1", "[interpreter2][VSM]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(true), xtag("test", testname)); + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - VsmConfig cfg; - VirtualSchematikaMachine vsm(cfg); + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; bool eof_flag = false; @@ -187,16 +192,7 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); - auto visitor = [&log](const MemorySizeInfo & info) { - log && log(xtag("resource", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), - xtag("commit", info.committed_), - xtag("resv", info.reserved_)); - }; - - FacetRegistry::instance().visit_pools(visitor); - vsm.visit_pools(visitor); + log && vsm_fixture.log_memory_layout(&log); } TEST_CASE("VirtualSchematikaMachine-cmp1", "[interpreter2][VSM]") @@ -206,13 +202,15 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - VsmConfig cfg; - VirtualSchematikaMachine vsm(cfg); + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; bool eof_flag = false; vsm.begin_interactive_session(); - VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("123 == 123;"), eof_flag); + VsmResultExt res + = vsm.read_eval_print(span_type::from_cstr("123 == 123;"), + eof_flag); REQUIRE(res.is_value()); REQUIRE(res.value()); @@ -227,32 +225,25 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); - auto visitor = [&log](const MemorySizeInfo & info) { - log && log(xtag("resource", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), - xtag("commit", info.committed_), - xtag("resv", info.reserved_)); - }; - - FacetRegistry::instance().visit_pools(visitor); - vsm.visit_pools(visitor); + log && vsm_fixture.log_memory_layout(&log); } TEST_CASE("VirtualSchematikaMachine-if", "[interpreter2][VSM]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - VsmConfig cfg; - VirtualSchematikaMachine vsm(cfg); + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; bool eof_flag = false; vsm.begin_interactive_session(); - VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("if 123 == 123 then \"equal\" else \"notequal\";"), eof_flag); + VsmResultExt res + = vsm.read_eval_print(span_type::from_cstr("if 123 == 123 then \"equal\" else \"notequal\";"), + eof_flag); REQUIRE(res.is_value()); REQUIRE(res.value()); @@ -267,16 +258,7 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); - auto visitor = [&log](const MemorySizeInfo & info) { - log && log(xtag("resource", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), - xtag("commit", info.committed_), - xtag("resv", info.reserved_)); - }; - - FacetRegistry::instance().visit_pools(visitor); - vsm.visit_pools(visitor); + log && vsm_fixture.log_memory_layout(&log); } TEST_CASE("VirtualSchematikaMachine-lambda1", "[interpreter2][VSM]") @@ -286,13 +268,15 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - VsmConfig cfg; - VirtualSchematikaMachine vsm(cfg); + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; bool eof_flag = false; vsm.begin_interactive_session(); - VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("lambda (x : i64) -> i64 { x * x; }"), eof_flag); + VsmResultExt res + = vsm.read_eval_print(span_type::from_cstr("lambda (x : i64) -> i64 { x * x; }"), + eof_flag); REQUIRE(res.is_value()); REQUIRE(res.value()); @@ -307,26 +291,18 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); - auto visitor = [&log](const MemorySizeInfo & info) { - log && log(xtag("resource", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), - xtag("commit", info.committed_), - xtag("resv", info.reserved_)); - }; - - FacetRegistry::instance().visit_pools(visitor); - vsm.visit_pools(visitor); + log && vsm_fixture.log_memory_layout(&log); } TEST_CASE("VirtualSchematikaMachine-apply2", "[interpreter2][VSM]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - scope log(XO_DEBUG(false), xtag("test", testname)); + bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - VsmConfig cfg; - VirtualSchematikaMachine vsm(cfg); + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; bool eof_flag = false; @@ -341,7 +317,7 @@ namespace xo { log && log(xtag("res.tseq", res.value()->_typeseq())); - // currently get not-implemented error + // currently get not-implemented error auto x = obj::from(*res.value()); REQUIRE(x); @@ -354,16 +330,7 @@ namespace xo { REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); - auto visitor = [&log](const MemorySizeInfo & info) { - log && log(xtag("resource", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), - xtag("commit", info.committed_), - xtag("resv", info.reserved_)); - }; - - FacetRegistry::instance().visit_pools(visitor); - vsm.visit_pools(visitor); + log && vsm_fixture.log_memory_layout(&log); } } /*namespace ut*/ diff --git a/xo-reader2/example/readerreplxx/readerreplxx.cpp b/xo-reader2/example/readerreplxx/readerreplxx.cpp index c95dd101..292c3a43 100644 --- a/xo-reader2/example/readerreplxx/readerreplxx.cpp +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -2,8 +2,9 @@ #include #include -#include +#include #include +#include #include #include #include @@ -137,6 +138,7 @@ namespace { struct AppConfig { using ReaderConfig = xo::scm::ReaderConfig; using X1CollectorConfig = xo::mm::X1CollectorConfig; + using ArenaConfig = xo::mm::ArenaConfig; AppConfig() { rdr_config_.reader_debug_flag_ = true; @@ -147,17 +149,24 @@ struct AppConfig { std::size_t max_history_size_ = 1000; std::string repl_history_fname_ = "repl_history.txt";; ReaderConfig rdr_config_; - X1CollectorConfig x1_config_ = (X1CollectorConfig().with_size(4*1024*1024)); + X1CollectorConfig x1_config_ = (X1CollectorConfig().with_name("gc").with_size(4*1024*1024)); + ArenaConfig fixed_config_ = (ArenaConfig().with_name("fixed").with_size(4*1024)); }; struct AppContext { + using AAllocator = xo::mm::AAllocator; using DX1Collector = xo::mm::DX1Collector; using X1CollectorConfig = xo::mm::X1CollectorConfig; + using DArena = xo::mm::DArena; + using ArenaConfig = xo::mm::ArenaConfig; using Replxx = replxx::Replxx; AppContext(const AppConfig & cfg = AppConfig()) : config_{cfg}, - x1_{X1CollectorConfig().with_size(4*1024*1024)}, - rdr_{config_.rdr_config_, x1_.ref()} + x1_{cfg.x1_config_}, + fixed_{cfg.fixed_config_}, + rdr_{config_.rdr_config_, + x1_.ref(), + obj(&fixed_)} { rx_.set_max_history_size(config_.max_history_size_); rx_.history_load(config_.repl_history_fname_); @@ -167,9 +176,12 @@ struct AppContext { AppConfig config_; Replxx rx_; + /** collector/allocator for schematika expressions **/ DX1Collector x1_; + /** e.g. for DArenaHashMap within global symtab **/ + DArena fixed_; SchematikaReader rdr_; -}; +}; int main() diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index d8dc8da9..74a3e9bb 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -41,9 +41,21 @@ namespace xo { using size_type = std::size_t; public: + /** + * @p config arena configuration for parser state + * @p max_stringtable_capacity + * hard max size for unique stringtable + * @p expr_alloc allocator for schematika expressions. + * Probably shared with execution. + * @p aux_alloc auxiliary allocator for non-copyable memory + * (e.g. DArenaHashMap for global symtable). + * If not using X1Collector, this can be the + * same as @p expr_alloc. + **/ ParserStateMachine(const ArenaConfig & config, size_type max_stringtable_capacity, - obj expr_alloc); + obj expr_alloc, + obj aux_alloc); /** @defgroup scm-parserstatemachine-accessors accessor methods **/ ///@{ @@ -280,6 +292,19 @@ namespace xo { **/ obj expr_alloc_; + /** Allocator for data with lifetime bounded by this ParserStateMachine + * + * Cannot be DX1Collector; for example DArenaHashMap will + * for global symtab will be allocated from here, + * and does not support gc. + * + * If @ref expr_alloc_ is an ordinary arena (e.g. DArenaAlloc) + * can have aux_alloc_ = expr_alloc_. + * When expr_alloc_ is a garbage collector (e.g. DX1Collector) + * this needs to be distinct. + **/ + obj aux_alloc_; + /** symbol table with local bindings. * non-null during parsing of lambda expressions. * Always allocated from @p expr_alloc_. diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 4be59f04..13cb18ee 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -164,14 +164,18 @@ namespace xo { /** create parser in initial state; * parser is ready to receive tokens via @ref include_token * - * @p config arena configuration for parser stack - * @p expr_alloc allocator for schematika expressions. - * Probably shared with execution. + * @p config arena configuration for parser stack + * @p expr_alloc allocator for schematika expressions. + * Probably shared with execution. + * @p aux_alloc aux allocator for non-copyable memory + * with lifetime bounded by this + * SchematikeParser itself * @p debug_flag true to enable debug logging **/ SchematikaParser(const ArenaConfig & config, size_t max_stringtable_capacity, obj expr_alloc, + obj aux_alloc, bool debug_flag); /** scm-schematikaparser-access-methods **/ diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index ee3de91f..6f2b325e 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -41,8 +41,15 @@ namespace xo { using size_type = std::size_t; public: + /** + * @p expr_alloc. allocator for Schematika expressions + * @p aux_alloc. allocator for miscellaneous objects + * (e.g. DArenaHashMap for global symtab) + * that have lifetime bounded by Schematika reader itself. + **/ SchematikaReader(const ReaderConfig & config, - obj expr_alloc); + obj expr_alloc, + obj fixed_alloc); /** visit reader-owned memory pools; call visitor(info) for each. * Specifically exclude expr_alloc, since we don't consider diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 58119789..5541e8a0 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -24,13 +24,14 @@ namespace xo { namespace scm { ParserStateMachine::ParserStateMachine(const ArenaConfig & config, size_type max_stringtable_capacity, - obj expr_alloc) + obj expr_alloc, + obj aux_alloc) : stringtable_{max_stringtable_capacity}, parser_alloc_{DArena::map(config)}, expr_alloc_{expr_alloc}, + aux_alloc_{aux_alloc}, debug_flag_{config.debug_flag_} { - } bool @@ -60,8 +61,8 @@ namespace xo { stringtable_.visit_pools(visitor); parser_alloc_.visit_pools(visitor); - // not counting expr_alloc_. We don't consider - // that to be owned by ParserStateMachine + // not counting {expr_alloc_, fixed_alloc_}. We don't consider + // either to be owned by ParserStateMachine } void diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 1973bbe7..1b8b1904 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -23,9 +23,10 @@ namespace xo { SchematikaParser::SchematikaParser(const ArenaConfig & config, size_t max_stringtable_capacity, obj expr_alloc, + obj fixed_alloc, bool debug_flag) - : psm_{config, max_stringtable_capacity, expr_alloc}, - debug_flag_{debug_flag} + : psm_{config, max_stringtable_capacity, expr_alloc, fixed_alloc}, + debug_flag_{debug_flag} { } diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index 47140d63..f2e70824 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -10,12 +10,14 @@ namespace xo { namespace scm { SchematikaReader::SchematikaReader(const ReaderConfig & config, - obj expr_alloc) + obj expr_alloc, + obj fixed_alloc) : tokenizer_{config.tk_buffer_config_, config.tk_debug_flag_}, parser_{config.parser_arena_config_, config.max_stringtable_cap_, expr_alloc, + fixed_alloc, config.parser_debug_flag_}, debug_flag_{config.reader_debug_flag_} { diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index d6f74edc..94e8218d 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -88,8 +88,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); REQUIRE(parser.debug_flag() == false); REQUIRE(parser.is_at_toplevel() == true); @@ -103,8 +104,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -121,8 +123,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_batch_session(); @@ -133,17 +136,20 @@ namespace xo { TEST_CASE("SchematikaParser-batch-def", "[reader2][SchematikaParser]") { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + constexpr bool c_debug_flag = false; - scope log(XO_DEBUG(c_debug_flag)); + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; - config.name_ = "test-arena"; + config.name_ = testname; config.size_ = 16 * 1024; DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_batch_session(); @@ -185,8 +191,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -250,8 +257,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -315,8 +323,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -380,8 +389,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -435,16 +445,17 @@ namespace xo { const auto & testname = Catch::getResultCapture().getCurrentTestName(); constexpr bool c_debug_flag = true; - scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + scope log(XO_DEBUG(c_debug_flag), + xtag("test", testname)); - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; + ArenaConfig config + = (ArenaConfig().with_name(testname).with_size(16 * 1024)); DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); + auto expr_alloc = obj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -507,8 +518,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -517,7 +529,7 @@ namespace xo { * lambda (n : i64, r : i64) -> i64 { 123 } * ^ ^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ * 0 1| 3 4 5 6 7 8 9 a b c d e - * 2 + * 2 **/ std::vector tk_v{ @@ -549,13 +561,14 @@ namespace xo { scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; - config.name_ = "test-arena"; + config.name_ = testname; config.size_ = 16 * 1024; DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -592,8 +605,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -632,13 +646,14 @@ namespace xo { scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ArenaConfig config; - config.name_ = "test-arena"; + config.name_ = testname; config.size_ = 16 * 1024; DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -689,8 +704,9 @@ namespace xo { DArena expr_arena = DArena::map(config); obj expr_alloc = with_facet::mkobj(&expr_arena); + auto aux_alloc = expr_alloc; - SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); parser.begin_interactive_session(); @@ -699,7 +715,7 @@ namespace xo { * (lambda (x : i64, y : i64) { x * y })(13, 15) ; * ^^ ^^ ^ ^ ^ ^^ ^ ^ ^ ^ ^ ^ ^^^^ ^ ^ ^ ^ * 0| 2| 4 5 6 7| 9 a b c d e f|h| j k l m - * 1 3 8 g i + * 1 3 8 g i **/ std::vector tk_v{ From 8aec96199056cb40ad6e428ec00a1aa568c71a70 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 14:26:33 -0500 Subject: [PATCH 221/258] xo-interpreter2 stack: mark non-trivial dtors b/c DGlobalSymtab --- xo-expression2/include/xo/expression2/DGlobalSymtab.hpp | 3 +++ .../include/xo/interpreter2/VirtualSchematikaMachine.hpp | 5 +++++ xo-reader2/include/xo/reader2/ParserStateMachine.hpp | 9 ++++++--- xo-reader2/include/xo/reader2/SchematikaParser.hpp | 3 +++ xo-reader2/include/xo/reader2/SchematikaReader.hpp | 3 +++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 566d8981..8eec6d2e 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -47,6 +47,9 @@ namespace xo { obj mm, const ArenaHashMapConfig & cfg); + /** non-trivial destructor for @ref map_ **/ + ~DGlobalSymtab() = default; + ///@} /** @defgroup scm-globalsymtab-access-methods access methods **/ ///@{ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 2cbd08e4..a34310ab 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -81,6 +81,11 @@ namespace xo { VirtualSchematikaMachine(const VsmConfig & config, obj aux_mm); + /** non-trivial dtor because of @ref reader_ + * indirect dependency on DGlobalSymtab + **/ + ~VirtualSchematikaMachine() = default; + /** allocator for schematika data **/ obj allocator() const noexcept; /** allocator for runtime errors **/ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 74a3e9bb..38cff2b8 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -57,6 +57,9 @@ namespace xo { obj expr_alloc, obj aux_alloc); + /** non-trivial dtor for @ref global_symtab_ **/ + ~ParserStateMachine() = default; + /** @defgroup scm-parserstatemachine-accessors accessor methods **/ ///@{ @@ -313,12 +316,12 @@ namespace xo { **/ DLocalSymtab * local_symtab_ = nullptr; -#ifdef NOT_YET /** global symbol table. * Toplevel definitions go here. + * + * Uses mmap -> non-trivial destructor. **/ - DGlobalSymtab * global_symtab_ = nullptr; -#endif + dp global_symtab_; /** current output from parser **/ ParserResult result_; diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 13cb18ee..ee86e6d5 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -178,6 +178,9 @@ namespace xo { obj aux_alloc, bool debug_flag); + /** non-trivial dtor because of @ref psm_ **/ + ~SchematikaParser() = default; + /** scm-schematikaparser-access-methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index 6f2b325e..73b8166b 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -51,6 +51,9 @@ namespace xo { obj expr_alloc, obj fixed_alloc); + /** non-trivial dtor because of @p parser **/ + ~SchematikaReader() = default; + /** visit reader-owned memory pools; call visitor(info) for each. * Specifically exclude expr_alloc, since we don't consider * that reader-owned From d36f0b77333543337539bd7730f7a3b70336a803 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 16:16:02 -0500 Subject: [PATCH 222/258] xo-reader2 stack: streamline + mem sizing + bugfixes --- xo-alloc2/include/xo/alloc2/dp.hpp | 2 + .../include/xo/expression2/DGlobalSymtab.hpp | 6 +- .../src/expression2/DGlobalSymtab.cpp | 4 +- .../include/xo/reader2/ParserConfig.hpp | 49 ++++ .../include/xo/reader2/ParserStateMachine.hpp | 7 + .../include/xo/reader2/ReaderConfig.hpp | 15 ++ .../include/xo/reader2/SchematikaParser.hpp | 11 +- xo-reader2/src/reader2/ParserStateMachine.cpp | 3 + xo-reader2/src/reader2/SchematikaParser.cpp | 14 +- xo-reader2/src/reader2/SchematikaReader.cpp | 9 +- xo-reader2/utest/SchematikaParser.test.cpp | 238 +++++++++--------- 11 files changed, 217 insertions(+), 141 deletions(-) create mode 100644 xo-reader2/include/xo/reader2/ParserConfig.hpp diff --git a/xo-alloc2/include/xo/alloc2/dp.hpp b/xo-alloc2/include/xo/alloc2/dp.hpp index 6c768ce8..266f42dd 100644 --- a/xo-alloc2/include/xo/alloc2/dp.hpp +++ b/xo-alloc2/include/xo/alloc2/dp.hpp @@ -61,6 +61,8 @@ namespace xo { dp & operator=(dp && x) { ptr_ = x.ptr_; x.ptr_ = nullptr; + + return *this; } // -------------------------------- diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 8eec6d2e..879c7073 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -43,9 +43,9 @@ namespace xo { * Use memory from @p mm for DGlobalSymtab instance. * Hashmap configured per @p cfg. **/ - dp make(obj fixed_mm, - obj mm, - const ArenaHashMapConfig & cfg); + static dp make(obj mm, + obj fixed_mm, + const ArenaHashMapConfig & cfg); /** non-trivial destructor for @ref map_ **/ ~DGlobalSymtab() = default; diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp index b7eb4d73..c9897670 100644 --- a/xo-expression2/src/expression2/DGlobalSymtab.cpp +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -25,8 +25,8 @@ namespace xo { } dp - DGlobalSymtab::make(obj aux_mm, - obj mm, + DGlobalSymtab::make(obj mm, + obj aux_mm, const ArenaHashMapConfig & cfg) { auto map = dp::make(aux_mm, cfg); diff --git a/xo-reader2/include/xo/reader2/ParserConfig.hpp b/xo-reader2/include/xo/reader2/ParserConfig.hpp new file mode 100644 index 00000000..ce781b16 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParserConfig.hpp @@ -0,0 +1,49 @@ +/** @file SchematikaParserConfig.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include +#include + +namespace xo { + namespace scm { + + /** @brief Configuration for SchematikaParser **/ + struct ParserConfig { + using ArenaHashMapConfig = xo::map::ArenaHashMapConfig; + using ArenaConfig = xo::mm::ArenaConfig; + + /** arena configuration for parser stack **/ + ArenaConfig parser_arena_config_ { .name_ = "parser-arena", + .size_ = 2*1024*1024, + .hugepage_z_ = 2*1024*1024, + .store_header_flag_ = false, + .header_{}, + .debug_flag_ = false }; + + /** configuration for hash map for global symbol table + * + * reminder: ownership chain + * SchematikaReader + * ->SchematikaParser + * ->ParserStateMachine + * ->DGlobalSymtab + **/ + ArenaHashMapConfig symtab_config_ { .name_ = "global-symtab", + .hint_max_capacity_ = 64*1024, + .debug_flag_ = false }; + + /** max capacity for unique string table **/ + size_t max_stringtable_capacity_ = 4096; + + /** control SchematikaParser debug logging **/ + bool debug_flag_ = false; + }; + + } +} + +/* end SchematikaParserConfig.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 38cff2b8..97c8c6e5 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace xo { @@ -38,11 +39,14 @@ namespace xo { using ArenaConfig = xo::mm::ArenaConfig; using DArena = xo::mm::DArena; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using ArenaHashMapConfig = xo::map::ArenaHashMapConfig; using size_type = std::size_t; public: /** * @p config arena configuration for parser state + * @p symtab_config configuration for global symtab + * (maps separate dedicated memory) * @p max_stringtable_capacity * hard max size for unique stringtable * @p expr_alloc allocator for schematika expressions. @@ -53,6 +57,7 @@ namespace xo { * same as @p expr_alloc. **/ ParserStateMachine(const ArenaConfig & config, + const ArenaHashMapConfig & symtab_config, size_type max_stringtable_capacity, obj expr_alloc, obj aux_alloc); @@ -320,6 +325,8 @@ namespace xo { * Toplevel definitions go here. * * Uses mmap -> non-trivial destructor. + * + * TODO: may want to move ownership upstairs **/ dp global_symtab_; diff --git a/xo-reader2/include/xo/reader2/ReaderConfig.hpp b/xo-reader2/include/xo/reader2/ReaderConfig.hpp index 62e0e758..e139e9eb 100644 --- a/xo-reader2/include/xo/reader2/ReaderConfig.hpp +++ b/xo-reader2/include/xo/reader2/ReaderConfig.hpp @@ -6,6 +6,7 @@ #pragma once #include +#include #include namespace xo { @@ -14,6 +15,7 @@ namespace xo { /** @brief Configuration for SchematikaReader **/ struct ReaderConfig { + using ArenaHashMapConfig = xo::map::ArenaHashMapConfig; using CircularBufferConfig = xo::mm::CircularBufferConfig; using ArenaConfig = xo::mm::ArenaConfig; using size_t = std::size_t; @@ -34,6 +36,19 @@ namespace xo { .store_header_flag_ = false, .header_{}, .debug_flag_ = false }; + + /** configuration for hash map for global symbol table + * + * reminder: ownership chain + * SchematikaReader + * ->SchematikaParser + * ->ParserStateMachine + * ->DGlobalSymtab + **/ + ArenaHashMapConfig symtab_config_ { .name_ = "global-symtab", + .hint_max_capacity_ = 64*1024, + .debug_flag_ = false }; + /** debug flag for schematika parser **/ bool parser_debug_flag_ = false; diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index ee86e6d5..45b45c19 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -5,6 +5,7 @@ #pragma once +#include "ParserConfig.hpp" #include "ParserStateMachine.hpp" #include "ParserResult.hpp" #include @@ -154,6 +155,7 @@ namespace xo { class SchematikaParser { public: using token_type = Token; + using ArenaHashMapConfig = xo::map::ArenaHashMapConfig; using ArenaConfig = xo::mm::ArenaConfig; using AAllocator = xo::mm::AAllocator; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; @@ -164,19 +166,16 @@ namespace xo { /** create parser in initial state; * parser is ready to receive tokens via @ref include_token * - * @p config arena configuration for parser stack + * @p config parser configuration * @p expr_alloc allocator for schematika expressions. * Probably shared with execution. * @p aux_alloc aux allocator for non-copyable memory * with lifetime bounded by this * SchematikeParser itself - * @p debug_flag true to enable debug logging **/ - SchematikaParser(const ArenaConfig & config, - size_t max_stringtable_capacity, + SchematikaParser(const ParserConfig & config, obj expr_alloc, - obj aux_alloc, - bool debug_flag); + obj aux_alloc); /** non-trivial dtor because of @ref psm_ **/ ~SchematikaParser() = default; diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 5541e8a0..bbb4841e 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -23,6 +23,7 @@ namespace xo { namespace scm { ParserStateMachine::ParserStateMachine(const ArenaConfig & config, + const ArenaHashMapConfig & symtab_config, size_type max_stringtable_capacity, obj expr_alloc, obj aux_alloc) @@ -30,6 +31,7 @@ namespace xo { parser_alloc_{DArena::map(config)}, expr_alloc_{expr_alloc}, aux_alloc_{aux_alloc}, + global_symtab_{DGlobalSymtab::make(expr_alloc, aux_alloc, symtab_config)}, debug_flag_{config.debug_flag_} { } @@ -60,6 +62,7 @@ namespace xo { { stringtable_.visit_pools(visitor); parser_alloc_.visit_pools(visitor); + global_symtab_->visit_pools(visitor); // not counting {expr_alloc_, fixed_alloc_}. We don't consider // either to be owned by ParserStateMachine diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 1b8b1904..48e109da 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -20,13 +20,15 @@ namespace xo { namespace scm { // ----- SchematikaParser ----- - SchematikaParser::SchematikaParser(const ArenaConfig & config, - size_t max_stringtable_capacity, + SchematikaParser::SchematikaParser(const ParserConfig & cfg, obj expr_alloc, - obj fixed_alloc, - bool debug_flag) - : psm_{config, max_stringtable_capacity, expr_alloc, fixed_alloc}, - debug_flag_{debug_flag} + obj fixed_alloc) + : psm_{cfg.parser_arena_config_, + cfg.symtab_config_, + cfg.max_stringtable_capacity_, + expr_alloc, + fixed_alloc}, + debug_flag_{cfg.debug_flag_} { } diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index f2e70824..e02eefa2 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -14,11 +14,12 @@ namespace xo { obj fixed_alloc) : tokenizer_{config.tk_buffer_config_, config.tk_debug_flag_}, - parser_{config.parser_arena_config_, - config.max_stringtable_cap_, + parser_{ParserConfig(config.parser_arena_config_, + config.symtab_config_, + config.max_stringtable_cap_, + config.parser_debug_flag_), expr_alloc, - fixed_alloc, - config.parser_debug_flag_}, + fixed_alloc}, debug_flag_{config.reader_debug_flag_} { } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 94e8218d..5265922a 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -20,6 +20,7 @@ #include namespace xo { + using xo::scm::ParserConfig; using xo::scm::SchematikaParser; using xo::scm::ASyntaxStateMachine; using xo::scm::syntaxstatetype; @@ -39,14 +40,64 @@ namespace xo { using xo::scm::DFloat; using xo::scm::DInteger; + using xo::facet::FacetRegistry; + using xo::mm::ArenaConfig; using xo::mm::AAllocator; using xo::mm::DArena; + using xo::mm::MemorySizeInfo; using xo::facet::with_facet; static InitEvidence s_init = (InitSubsys::require()); namespace ut { + struct ParserFixture { + ParserFixture(const std::string & testname, bool debug_flag) + { + this->aux_arena_ + = std::move(DArena(ArenaConfig().with_name(testname).with_size(4 * 1024))); + obj aux_mm(&aux_arena_); + + this->expr_arena_ + = dp::make(aux_mm, + ArenaConfig().with_name("expr").with_size(16 * 1024)); + obj expr_mm(expr_arena_.data()); + + ParserConfig cfg; + cfg.parser_arena_config_.size_ = 16 * 1024; + cfg.symtab_config_.hint_max_capacity_ = 512; + cfg.max_stringtable_capacity_ = 512; + cfg.debug_flag_ = false; + + this->parser_ + = dp::make(aux_mm, cfg, expr_mm, aux_mm); + } + + ParserFixture(const ParserFixture & other) = delete; + ParserFixture(const ParserFixture && other) = delete; + + bool log_memory_layout(scope * p_log) { + auto visitor = [p_log](const MemorySizeInfo & info) { + *p_log && (*p_log)(xtag("resource", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), + xtag("commit", info.committed_), + xtag("resv", info.reserved_)); + }; + + aux_arena_.visit_pools(visitor); + FacetRegistry::instance().visit_pools(visitor); + expr_arena_->visit_pools(visitor); + parser_->visit_pools(visitor); + + return true; + } + + DArena aux_arena_; + dp expr_arena_; + dp parser_; + }; + void utest_tokenizer_loop(SchematikaParser * parser, std::vector & tk_v, bool debug_flag) { @@ -82,56 +133,56 @@ namespace xo { TEST_CASE("SchematikaParser-ctor", "[reader2][SchematikaParser]") { - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; + const auto & testname = Catch::getResultCapture().getCurrentTestName(); - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); REQUIRE(parser.debug_flag() == false); REQUIRE(parser.is_at_toplevel() == true); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-begin-interactive", "[reader2][SchematikaParser]") { - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; + const auto & testname = Catch::getResultCapture().getCurrentTestName(); - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); // after begin_interactive_session, parser has toplevel exprseq // but is still "at toplevel" in the sense of ready for input REQUIRE(parser.has_incomplete_expr() == false); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-begin-batch", "[reader2][SchematikaParser]") { - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; + const auto & testname = Catch::getResultCapture().getCurrentTestName(); - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_batch_session(); // after begin_translation_unit, parser has toplevel exprseq // but is still "at toplevel" in the sense of ready for input REQUIRE(parser.has_incomplete_expr() == false); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-batch-def", "[reader2][SchematikaParser]") @@ -141,15 +192,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = testname; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_batch_session(); @@ -176,6 +220,8 @@ namespace xo { auto expr = obj::from(result.result_expr()); REQUIRE(expr); } + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-integer", "[reader2][SchematikaParser]") @@ -185,15 +231,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -242,6 +281,8 @@ namespace xo { //REQUIRE(result.is_error()); //// illegal input on token //REQUIRE(result.error_description()); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-float", "[reader2][SchematikaParser]") @@ -251,15 +292,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -308,6 +342,8 @@ namespace xo { //REQUIRE(result.is_error()); //// illegal input on token //REQUIRE(result.error_description()); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-string", "[reader2][SchematikaParser]") @@ -317,15 +353,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -374,6 +403,8 @@ namespace xo { //REQUIRE(result.is_error()); //// illegal input on token //REQUIRE(result.error_description()); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-arith", "[reader2][SchematikaParser]") @@ -383,15 +414,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -438,24 +462,20 @@ namespace xo { REQUIRE(rhs_f64); REQUIRE(rhs_f64->value() == 0.5); } + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-cmp", "[reader2][SchematikaParser]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config - = (ArenaConfig().with_name(testname).with_size(16 * 1024)); - - DArena expr_arena = DArena::map(config); - auto expr_alloc = obj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -503,6 +523,8 @@ namespace xo { REQUIRE(rhs_i64); REQUIRE(rhs_i64->value() == 312); } + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") @@ -512,15 +534,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -551,6 +566,8 @@ namespace xo { }; utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") @@ -560,15 +577,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = testname; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -590,6 +600,8 @@ namespace xo { }; utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-lambda2", "[reader2][SchematikaParser]") @@ -599,15 +611,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -636,6 +641,8 @@ namespace xo { }; utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-apply", "[reader2][SchematikaParser]") @@ -645,15 +652,8 @@ namespace xo { constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = testname; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -687,6 +687,8 @@ namespace xo { }; utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + log && fixture.log_memory_layout(&log); } TEST_CASE("SchematikaParser-interactive-apply2", "[reader2][SchematikaParser]") @@ -698,15 +700,8 @@ namespace xo { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); - ArenaConfig config; - config.name_ = "test-arena"; - config.size_ = 16 * 1024; - - DArena expr_arena = DArena::map(config); - obj expr_alloc = with_facet::mkobj(&expr_arena); - auto aux_alloc = expr_alloc; - - SchematikaParser parser(config, 4096, expr_alloc, aux_alloc, false /*debug_flag*/); + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); parser.begin_interactive_session(); @@ -750,7 +745,10 @@ namespace xo { }; utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + log && fixture.log_memory_layout(&log); } + } /*namespace ut*/ } /*namespace xo*/ From 0023831e4cbc2449f1a2cf0d3e375ce557fe8646 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 15 Feb 2026 22:57:15 -0500 Subject: [PATCH 223/258] xo-reader2 stack: + TypeRegistry --- xo-alloc2/utest/DArenaIterator.test.cpp | 2 +- xo-alloc2/utest/arena.test.cpp | 10 +- xo-alloc2/utest/random_allocs.cpp | 2 +- xo-arena/include/xo/arena/MemorySizeInfo.hpp | 6 +- xo-arena/src/arena/DArena.cpp | 4 +- xo-arena/utest/DArena.test.cpp | 6 +- xo-facet/include/xo/facet/FacetRegistry.hpp | 6 +- xo-facet/include/xo/facet/TypeRegistry.hpp | 137 ++++++++++++++++++ xo-facet/include/xo/facet/typeseq.hpp | 2 +- xo-gc/src/gc/DX1Collector.cpp | 2 +- xo-gc/utest/DX1CollectorIterator.test.cpp | 2 +- xo-gc/utest/random_allocs.cpp | 2 +- xo-reader2/utest/SchematikaParser.test.cpp | 2 +- xo-refcnt/include/xo/cxxutil/demangle.hpp | 87 +---------- xo-refcnt/src/CMakeLists.txt | 1 + .../include/xo/reflectutil/type_name.hpp | 94 ++++++++++++ .../include/xo/reflectutil/typeseq.hpp | 89 ++++++++---- 17 files changed, 318 insertions(+), 136 deletions(-) create mode 100644 xo-facet/include/xo/facet/TypeRegistry.hpp create mode 100644 xo-reflectutil/include/xo/reflectutil/type_name.hpp diff --git a/xo-alloc2/utest/DArenaIterator.test.cpp b/xo-alloc2/utest/DArenaIterator.test.cpp index 8eb1614a..7d26e623 100644 --- a/xo-alloc2/utest/DArenaIterator.test.cpp +++ b/xo-alloc2/utest/DArenaIterator.test.cpp @@ -169,7 +169,7 @@ namespace xo { /* arbitrary alloc size */ size_t req_z = 13; - byte * mem = a1o.alloc(typeseq::anon(), req_z); + byte * mem = a1o.alloc(typeseq::sentinel(), req_z); REQUIRE(arena.error_count_ == 0); REQUIRE(mem != nullptr); diff --git a/xo-alloc2/utest/arena.test.cpp b/xo-alloc2/utest/arena.test.cpp index 42ffa904..e9358a10 100644 --- a/xo-alloc2/utest/arena.test.cpp +++ b/xo-alloc2/utest/arena.test.cpp @@ -159,7 +159,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t z0 = 1; - byte * m0 = a1o.alloc(typeseq::anon(), 1); + byte * m0 = a1o.alloc(typeseq::sentinel(), 1); REQUIRE(m0); REQUIRE(a1o.last_error().error_ == error::ok); @@ -171,7 +171,7 @@ namespace xo { REQUIRE(a1o.committed() <= a1o.reserved()); size_t z1 = 16; - byte * m1 = a1o.alloc(typeseq::anon(), z1); + byte * m1 = a1o.alloc(typeseq::sentinel(), z1); REQUIRE(m1); REQUIRE(a1o.last_error().error_ == error::ok); @@ -209,7 +209,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t z0 = 1; - byte * m0 = a1o.alloc(typeseq::anon(), 1); + byte * m0 = a1o.alloc(typeseq::sentinel(), 1); REQUIRE(m0); @@ -253,7 +253,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t z0 = 1; - byte * m0 = a1o.alloc(typeseq::anon(), 1); + byte * m0 = a1o.alloc(typeseq::sentinel(), 1); REQUIRE(m0); @@ -306,7 +306,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t z0 = cfg.hugepage_z_ + 1; - byte * m0 = a1o.alloc(typeseq::anon(), z0); + byte * m0 = a1o.alloc(typeseq::sentinel(), z0); REQUIRE(!m0); diff --git a/xo-alloc2/utest/random_allocs.cpp b/xo-alloc2/utest/random_allocs.cpp index 1f7f833f..2325140d 100644 --- a/xo-alloc2/utest/random_allocs.cpp +++ b/xo-alloc2/utest/random_allocs.cpp @@ -67,7 +67,7 @@ namespace utest { bool ok_flag = true; - std::byte * mem = mm.alloc(typeseq::anon(), z); + std::byte * mem = mm.alloc(typeseq::sentinel(), z); log && log(xtag("i_alloc", i_alloc), xtag("si", si), diff --git a/xo-arena/include/xo/arena/MemorySizeInfo.hpp b/xo-arena/include/xo/arena/MemorySizeInfo.hpp index 764eae6d..37b5ce08 100644 --- a/xo-arena/include/xo/arena/MemorySizeInfo.hpp +++ b/xo-arena/include/xo/arena/MemorySizeInfo.hpp @@ -16,8 +16,10 @@ namespace xo { using size_type = std::size_t; MemorySizeInfo() = default; - MemorySizeInfo(std::string_view name, std::size_t u, std::size_t a, std::size_t c, std::size_t r) - : resource_name_{name}, used_{u}, allocated_{a}, committed_{c}, reserved_{r} + MemorySizeInfo(std::string_view name, + std::size_t u, std::size_t a, std::size_t c, std::size_t r) + : resource_name_{name}, + used_{u}, allocated_{a}, committed_{c}, reserved_{r} {} static MemorySizeInfo sentinel() { return MemorySizeInfo(); } diff --git a/xo-arena/src/arena/DArena.cpp b/xo-arena/src/arena/DArena.cpp index cb305f9a..72d8cbf7 100644 --- a/xo-arena/src/arena/DArena.cpp +++ b/xo-arena/src/arena/DArena.cpp @@ -67,7 +67,7 @@ namespace xo { DArena::DArena(const ArenaConfig & cfg) { - *this = std::move(map(cfg)); + *this = map(cfg); } DArena::DArena(const ArenaConfig & cfg, @@ -290,7 +290,7 @@ namespace xo { (complete_flag ? alloc_mode::sub_complete : alloc_mode::sub_incomplete), - typeseq::anon() /*typeseq: ignored*/, + typeseq::sentinel() /*typeseq: ignored*/, 0 /*age - ignored */); } diff --git a/xo-arena/utest/DArena.test.cpp b/xo-arena/utest/DArena.test.cpp index e999c35f..03e1633f 100644 --- a/xo-arena/utest/DArena.test.cpp +++ b/xo-arena/utest/DArena.test.cpp @@ -147,7 +147,7 @@ namespace xo { REQUIRE(arena.allocated() == 0); size_t z0 = 1; - byte * m0 = arena.alloc(typeseq::anon(), 1); + byte * m0 = arena.alloc(typeseq::sentinel(), 1); REQUIRE(m0); REQUIRE(arena.last_error().error_ == error::ok); @@ -159,7 +159,7 @@ namespace xo { REQUIRE(arena.committed() <= arena.reserved()); size_t z1 = 16; - byte * m1 = arena.alloc(typeseq::anon(), z1); + byte * m1 = arena.alloc(typeseq::sentinel(), z1); REQUIRE(m1); REQUIRE(arena.last_error().error_ == error::ok); @@ -195,7 +195,7 @@ namespace xo { REQUIRE(arena.allocated() == 0); size_t z0 = 1; - byte * m0 = arena.alloc(typeseq::anon(), 1); + byte * m0 = arena.alloc(typeseq::sentinel(), 1); REQUIRE(m0); diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index 9b7e7ade..a69735a9 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -7,8 +7,9 @@ #pragma once +#include "TypeRegistry.hpp" #include "facet_implementation.hpp" -#include "typeseq.hpp" +//#include "typeseq.hpp" #include "obj.hpp" #include #include @@ -74,6 +75,9 @@ namespace xo { static void register_impl() { static FacetImplType impl; + TypeRegistry::register_type(); + TypeRegistry::register_type(); + instance()._register_impl(typeseq::id(), typeseq::id(), &impl); diff --git a/xo-facet/include/xo/facet/TypeRegistry.hpp b/xo-facet/include/xo/facet/TypeRegistry.hpp new file mode 100644 index 00000000..19091630 --- /dev/null +++ b/xo-facet/include/xo/facet/TypeRegistry.hpp @@ -0,0 +1,137 @@ +/** @file TypeRegistry.hpp + * + * @brief Runtime facet implementation lookup + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "typeseq.hpp" +#include +#include +#include + +namespace xo { + namespace facet { + + /** @class TypeRegistry + * + * @brief Runtime registry for types. + * + * Just assigns ids and remembers names. + * Not a full reflection implementation + **/ + class TypeRegistry { + public: + using ReprType = xo::mm::DArenaVector; + using ArenaConfig = xo::mm::ArenaConfig; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using typeseq = xo::reflect::typeseq; + + /** singleton instance. + * @p hint_max_capacity is a lower bound for registry capacity. + * Only honored the first time instance is called. + **/ + static TypeRegistry & instance(uint32_t hint_max_capacity = 1024) { + static TypeRegistry s_instance(hint_max_capacity); + return s_instance; + } + + /** Type-safe registration + * + * Registers the compile-time FacetImplementation + * for runtime lookup. + * + * @tparam AFacet abstract facet type + * @tparam DRepr data representation type + **/ + template + static void register_type() { + typerecd r = typerecd::recd(); + + instance()._register_type(r); + } + + /** Number of registered (facet, repr) pairs **/ + std::size_t size() const { return registry_.size(); } + + std::string_view id2name(typeseq id) const noexcept { + return instance()._id2name(id); + } + + /** visit memory pools owned by facet registry **/ + void visit_pools(const MemorySizeVisitor & visitor) { + registry_.visit_pools(visitor); + } + + /** Check if type is registered **/ + bool contains(typeseq id) const + { + if ((0 <= id.seqno()) + && (id.seqno() < static_cast(registry_.size()))) + { + return (registry_.at(id.seqno()).seqno() == id.seqno()); + } + + return false; + } + + void dump(std::ostream * p_out) const { + (*p_out) << std::endl; + (*p_out) << " " << item.name() << std::endl; + } + (*p_out) << ">" << std::endl; + } + + private: + /** Register a facet implementation (type-erased) + * + * @param facet_id typeseq for abstract facet (e.g., APrintable) + * @param repr_id typeseq for data representation (e.g., DFloat) + * @param impl pointer to stateless implementation instance + **/ + void _register_type(const typerecd & recd) + { + if ((recd.seqno() >= 0) + && (static_cast(registry_.size()) <= recd.seqno())) + { + registry_.resize(recd.seqno() + 1); + } + + registry_.at(recd.seqno()) = recd; + } + + /** Get typename from @p id. + **/ + std::string_view _id2name(typeseq id) const + { + if ((0 <= id.seqno()) + && (static_cast(id.seqno()) < registry_.size())) + { + return registry_.at(id.seqno()).name(); + } + + return typerecd::sentinel().name(); + } + + private: + TypeRegistry(uint32_t hint_max_capacity) + : registry_(ReprType::map(ArenaConfig() + .with_name("types") + .with_size(hint_max_capacity + * sizeof(typerecd)))) + {} + + /** runtime lookup table (AFacet,DRepr) -> impl **/ + ReprType registry_; + }; + + } /*namespace facet*/ +} /*namespace xo*/ + +/* end TypeRegistry.hpp */ diff --git a/xo-facet/include/xo/facet/typeseq.hpp b/xo-facet/include/xo/facet/typeseq.hpp index 23b84a92..d43d9e68 100644 --- a/xo-facet/include/xo/facet/typeseq.hpp +++ b/xo-facet/include/xo/facet/typeseq.hpp @@ -12,7 +12,7 @@ namespace xo { namespace facet { // Re-export from xo::arena namespace - using xo::reflect::typeseq_impl; + using xo::reflect::typerecd; using xo::reflect::typeseq; } } /*namespace xo*/ diff --git a/xo-gc/src/gc/DX1Collector.cpp b/xo-gc/src/gc/DX1Collector.cpp index ede4a734..8cbd0bbd 100644 --- a/xo-gc/src/gc/DX1Collector.cpp +++ b/xo-gc/src/gc/DX1Collector.cpp @@ -279,7 +279,7 @@ namespace xo { DX1Collector::add_gc_root_poly(obj * p_root) noexcept { std::byte * mem - = roots_.alloc(typeseq::anon(), + = roots_.alloc(typeseq::sentinel(), sizeof(obj*)); assert(mem); diff --git a/xo-gc/utest/DX1CollectorIterator.test.cpp b/xo-gc/utest/DX1CollectorIterator.test.cpp index 314eb4a8..137c07f3 100644 --- a/xo-gc/utest/DX1CollectorIterator.test.cpp +++ b/xo-gc/utest/DX1CollectorIterator.test.cpp @@ -110,7 +110,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t req_z = 13; - byte * mem = gc.alloc(typeseq::anon(), req_z); + byte * mem = gc.alloc(typeseq::sentinel(), req_z); REQUIRE(mem != nullptr); diff --git a/xo-gc/utest/random_allocs.cpp b/xo-gc/utest/random_allocs.cpp index 1f7f833f..2325140d 100644 --- a/xo-gc/utest/random_allocs.cpp +++ b/xo-gc/utest/random_allocs.cpp @@ -67,7 +67,7 @@ namespace utest { bool ok_flag = true; - std::byte * mem = mm.alloc(typeseq::anon(), z); + std::byte * mem = mm.alloc(typeseq::sentinel(), z); log && log(xtag("i_alloc", i_alloc), xtag("si", si), diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 5265922a..2f2272ab 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -78,7 +78,7 @@ namespace xo { bool log_memory_layout(scope * p_log) { auto visitor = [p_log](const MemorySizeInfo & info) { - *p_log && (*p_log)(xtag("resource", info.resource_name_), + *p_log && (*p_log)(xtag("name", info.resource_name_), xtag("used", info.used_), xtag("alloc", info.allocated_), xtag("commit", info.committed_), diff --git a/xo-refcnt/include/xo/cxxutil/demangle.hpp b/xo-refcnt/include/xo/cxxutil/demangle.hpp index e2184f5d..fd7425ba 100644 --- a/xo-refcnt/include/xo/cxxutil/demangle.hpp +++ b/xo-refcnt/include/xo/cxxutil/demangle.hpp @@ -2,91 +2,6 @@ #pragma once -#include -#include -#include // std::array -#include // std::index_sequence - -namespace xo { - namespace reflect { - - template - constexpr auto - substring_as_array(std::string_view str, - std::index_sequence indexes) - { - //return std::array{str[Idxs]..., '\n'}; - return std::array{str[Idxs]...}; - } /*substring_as_array*/ - - template constexpr auto type_name_array() { -#if defined(__clang__) - constexpr auto prefix = std::string_view{"[T = "}; - constexpr auto suffix = std::string_view{"]"}; - constexpr auto function = std::string_view{__PRETTY_FUNCTION__}; -#elif defined(__GNUC__) - constexpr auto prefix = std::string_view{"with T = "}; - constexpr auto suffix = std::string_view{"]"}; - constexpr auto function = std::string_view{__PRETTY_FUNCTION__}; -#elif defined(_MSC_VER) - constexpr auto prefix = std::string_view{"type_name_array<"}; - constexpr auto suffix = std::string_view{">(void)"}; - constexpr auto function = std::string_view{__FUNCSIG__}; -#else -# error type_name_array: Unsupported compiler -#endif - - constexpr auto start = function.find(prefix) + prefix.size(); - constexpr auto end = function.rfind(suffix); - - //static_assert(start < end); - - constexpr auto name = function.substr(start, (end - start)); - - constexpr auto ixseq = std::make_index_sequence{}; - - return substring_as_array(name, ixseq); - } /*type_name_array*/ - - template - struct type_name_holder { - static inline constexpr auto value = type_name_array(); - }; - - template - constexpr auto type_name() -> std::string_view - { - constexpr auto& value = type_name_holder::value; - return std::string_view{value.data(), value.size()}; - } - -#ifdef NOT_IN_USE - template - struct join - { - // Join all strings into a single std::array of chars - static constexpr auto impl() noexcept - { - constexpr std::size_t len = (Strs.size() + ... + 0); - std::array arr{}; - auto append = [i = 0, &arr](auto const& s) mutable { - for (auto c : s) arr[i++] = c; - }; - (append(Strs), ...); - arr[len] = 0; - return arr; - } - // Give the joined string static storage - static constexpr auto arr = impl(); - // View as a std::string_view - static constexpr std::string_view value {arr.data(), arr.size() - 1}; - }; - - // Helper to get the value out - template - static constexpr auto join_v = join::value; -#endif - } /*namespace reflect*/ -} /*namespace xo*/ +#include /* end demangle.hpp */ diff --git a/xo-refcnt/src/CMakeLists.txt b/xo-refcnt/src/CMakeLists.txt index 9cbc92ff..e8b5288f 100644 --- a/xo-refcnt/src/CMakeLists.txt +++ b/xo-refcnt/src/CMakeLists.txt @@ -7,4 +7,5 @@ xo_install_include_tree3(include/xo/cxxutil) # NOTE: # dependency set here must be kept consistent with refcnt/cmake/refcntConfig.cmake.in # +xo_dependency(${SELF_LIB} xo_reflectutil) xo_dependency(${SELF_LIB} indentlog) diff --git a/xo-reflectutil/include/xo/reflectutil/type_name.hpp b/xo-reflectutil/include/xo/reflectutil/type_name.hpp new file mode 100644 index 00000000..bdce1b0a --- /dev/null +++ b/xo-reflectutil/include/xo/reflectutil/type_name.hpp @@ -0,0 +1,94 @@ +/* @file type_name.hpp */ + +#pragma once + +//#include +#include +#include // std::array +#include // std::index_sequence + +namespace xo { + namespace reflect { + + template + constexpr auto + substring_as_array(std::string_view str, + std::index_sequence indexes) + { + //return std::array{str[Idxs]..., '\n'}; + return std::array{str[Idxs]...}; + } /*substring_as_array*/ + + template constexpr auto type_name_array() { +#if defined(__clang__) + constexpr auto prefix = std::string_view{"[T = "}; + constexpr auto suffix = std::string_view{"]"}; + constexpr auto function = std::string_view{__PRETTY_FUNCTION__}; +#elif defined(__GNUC__) + constexpr auto prefix = std::string_view{"with T = "}; + constexpr auto suffix = std::string_view{"]"}; + constexpr auto function = std::string_view{__PRETTY_FUNCTION__}; +#elif defined(_MSC_VER) + constexpr auto prefix = std::string_view{"type_name_array<"}; + constexpr auto suffix = std::string_view{">(void)"}; + constexpr auto function = std::string_view{__FUNCSIG__}; +#else +# error type_name_array: Unsupported compiler +#endif + + constexpr auto start = function.find(prefix) + prefix.size(); + constexpr auto end = function.rfind(suffix); + + //static_assert(start < end); + + constexpr auto name = function.substr(start, (end - start)); + + constexpr auto ixseq = std::make_index_sequence{}; + + return substring_as_array(name, ixseq); + } /*type_name_array*/ + + template + struct type_name_holder { + static inline constexpr auto value = type_name_array(); + }; + + /** report name of type T as a string_view; + * using constexpr deps so runs at **/ + template + constexpr auto type_name() -> std::string_view + { + constexpr auto& value = type_name_holder::value; + return std::string_view{value.data(), value.size()}; + } + +#ifdef NOT_IN_USE + template + struct join + { + // Join all strings into a single std::array of chars + static constexpr auto impl() noexcept + { + constexpr std::size_t len = (Strs.size() + ... + 0); + std::array arr{}; + auto append = [i = 0, &arr](auto const& s) mutable { + for (auto c : s) arr[i++] = c; + }; + (append(Strs), ...); + arr[len] = 0; + return arr; + } + // Give the joined string static storage + static constexpr auto arr = impl(); + // View as a std::string_view + static constexpr std::string_view value {arr.data(), arr.size() - 1}; + }; + + // Helper to get the value out + template + static constexpr auto join_v = join::value; +#endif + } /*namespace reflect*/ +} /*namespace xo*/ + +/* end type_name.hpp */ diff --git a/xo-reflectutil/include/xo/reflectutil/typeseq.hpp b/xo-reflectutil/include/xo/reflectutil/typeseq.hpp index d2f888cd..336f011c 100644 --- a/xo-reflectutil/include/xo/reflectutil/typeseq.hpp +++ b/xo-reflectutil/include/xo/reflectutil/typeseq.hpp @@ -5,22 +5,20 @@ #pragma once +#include "type_name.hpp" #include #include namespace xo { namespace reflect { - /** - * Tag here so we can preserve header-only implementation - * and still have static variable - */ - template - struct typeseq_impl { - /** create sentinel value **/ - typeseq_impl() = default; +// template + struct typerecd { + /** sentinel value **/ + typerecd() = default; - /** typeseq with specific unique id **/ - explicit typeseq_impl(int32_t s) : seqno_{s} {} + /** type-record with specific, unique id **/ + explicit typerecd(int32_t s, + std::string_view n) : seqno_{s}, name_{n} {} /** Can't have this be constexpr. * We need ids in shared libraries to be generated @@ -35,57 +33,88 @@ namespace xo { * when using clang. **/ template - static typeseq_impl id() { - static bool armed = true; + static typerecd recd() { + // reminder: {armed, id} are distint for each T + static bool s_armed = true; static int32_t id = 0; - if (armed) { - armed = false; - id = ++s_next_id; + if (s_armed) { + s_armed = false; + id = require_next_id(); } - return typeseq_impl(id); + return typerecd(id, xo::reflect::type_name()); } + static int32_t require_next_id() { + static int32_t s_next_id = 0; + return s_next_id++; + } + + int32_t seqno() const { return seqno_; } + std::string_view name() const { return name_; } + + /** sentinel typerecd instance **/ + static typerecd sentinel() { + return typerecd(-1, "_%sentinel%_"); + } + + private: + int32_t seqno_ = 0; + std::string_view name_; + }; + + //template + //int32_t typerecd_impl::s_next_id = 0; + + /** + * Tag here so we can preserve header-only implementation + * and still have static variable + */ + struct typeseq { + /** create sentinel value **/ + typeseq() = default; + + /** typeseq with specific unique id **/ + explicit typeseq(int32_t s) : seqno_{s} {} + /** 'anonymous' sentinel type. * Niche uses for this, e.g. untyped allocator **/ - static typeseq_impl anon() { - return typeseq_impl(-1); + static typeseq sentinel() { + return typeseq(typerecd::sentinel().seqno()); + } + + template + static typeseq id() { + return typeseq(xo::reflect::typerecd::recd().seqno()); } int32_t seqno() const { return seqno_; } private: - static int32_t s_next_id; - int32_t seqno_ = 0; }; - template - int32_t typeseq_impl::s_next_id = 0; + //template + //int32_t typeseq_impl::s_next_id = 0; - template inline bool - operator==(const typeseq_impl & lhs, const typeseq_impl & rhs) { + operator==(const typeseq & lhs, const typeseq & rhs) { return lhs.seqno() == rhs.seqno(); } - template inline bool - operator!=(const typeseq_impl & lhs, const typeseq_impl & rhs) { + operator!=(const typeseq & lhs, const typeseq & rhs) { return lhs.seqno() != rhs.seqno(); } - template inline std::ostream & - operator<<(std::ostream & s, const typeseq_impl & x) { + operator<<(std::ostream & s, const typeseq & x) { s << x.seqno(); return s; } - - using typeseq = typeseq_impl<>; } /*namespace reflect*/ } /*namespace xo*/ From 16309dfff629a69ab90a04f21cbfcf94abc47272 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 00:48:00 -0500 Subject: [PATCH 224/258] xo-expression2 stack: expand MemorySizeInfo w/ per-type detail --- xo-arena/include/xo/arena/MemorySizeInfo.hpp | 21 ++++++- xo-arena/src/arena/DArena.cpp | 34 +++++++++- xo-arena/src/arena/DCircularBuffer.cpp | 3 +- .../include/xo/expression2/GlobalSymtab.hpp | 13 ++++ .../expression2_register_facets.cpp | 16 +++-- xo-facet/include/xo/facet/TypeRegistry.hpp | 8 +-- xo-reader2/utest/SchematikaParser.test.cpp | 62 ++++++++++++++++--- .../include/xo/reflectutil/typeseq.hpp | 5 +- 8 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 xo-expression2/include/xo/expression2/GlobalSymtab.hpp diff --git a/xo-arena/include/xo/arena/MemorySizeInfo.hpp b/xo-arena/include/xo/arena/MemorySizeInfo.hpp index 37b5ce08..a9649b3e 100644 --- a/xo-arena/include/xo/arena/MemorySizeInfo.hpp +++ b/xo-arena/include/xo/arena/MemorySizeInfo.hpp @@ -5,6 +5,7 @@ #pragma once +#include #include #include #include @@ -12,14 +13,27 @@ namespace xo { namespace mm { + struct MemorySizeDetail { + using typeseq = xo::reflect::typeseq; + + /** identifies a c++ type T. See xo/facet/TypeRegistry **/ + typeseq tseq_; + /** number of T-instances **/ + uint32_t n_alloc_ = 0; + /** bytes used by T-instances **/ + uint32_t z_alloc_ = 0; + }; + struct MemorySizeInfo { using size_type = std::size_t; + using DetailArrayType = std::array; MemorySizeInfo() = default; MemorySizeInfo(std::string_view name, - std::size_t u, std::size_t a, std::size_t c, std::size_t r) + std::size_t u, std::size_t a, std::size_t c, std::size_t r, + DetailArrayType * detail) : resource_name_{name}, - used_{u}, allocated_{a}, committed_{c}, reserved_{r} + used_{u}, allocated_{a}, committed_{c}, reserved_{r}, detail_{detail} {} static MemorySizeInfo sentinel() { return MemorySizeInfo(); } @@ -36,6 +50,9 @@ namespace xo { * virtual memory addresses range obtained, whether or not committed **/ std::size_t reserved_ = 0; + + /** optional histogram with per-data-type counts **/ + DetailArrayType * detail_ = nullptr; }; /** function that visits MemorySizeInfo for a collection of @p n memory pools. diff --git a/xo-arena/src/arena/DArena.cpp b/xo-arena/src/arena/DArena.cpp index 72d8cbf7..2cd36dc1 100644 --- a/xo-arena/src/arena/DArena.cpp +++ b/xo-arena/src/arena/DArena.cpp @@ -176,11 +176,43 @@ namespace xo { * must assume it's all used **/ + // assemble histogram + MemorySizeInfo::DetailArrayType detail_v; + MemorySizeInfo::DetailArrayType * p_detail = nullptr; + + if (config_.store_header_flag_) { + p_detail = &detail_v; + + for (const auto & ix : *this) { + typeseq ix_tseq(ix.tseq()); + + // totals in detail_v[0] + MemorySizeDetail & d = detail_v[0]; + ++d.n_alloc_; + d.z_alloc_ += ix.size(); + + // O(n) insertion here + for (size_t i = 1; i < detail_v.size(); ++i) { + if (detail_v[i].tseq_.is_sentinel() + || (detail_v[i].tseq_ == ix_tseq)) + { + MemorySizeDetail & d = detail_v[i]; + + d.tseq_ = ix_tseq; + ++d.n_alloc_; + d.z_alloc_ += ix.size(); + break; + } + } + } + } + fn(MemorySizeInfo(config_.name_, this->allocated() /*used*/, this->allocated(), this->committed(), - this->reserved())); + this->reserved(), + p_detail)); } AllocInfo diff --git a/xo-arena/src/arena/DCircularBuffer.cpp b/xo-arena/src/arena/DCircularBuffer.cpp index e5b1c725..bd4dc0cd 100644 --- a/xo-arena/src/arena/DCircularBuffer.cpp +++ b/xo-arena/src/arena/DCircularBuffer.cpp @@ -86,7 +86,8 @@ namespace xo { occupied_range_.size() /*used*/, occupied_range_.size(), mapped_range_.size(), - reserved_range_.size())); + reserved_range_.size(), + nullptr /*detail*/)); pinned_spans_.visit_pools(visitor); } diff --git a/xo-expression2/include/xo/expression2/GlobalSymtab.hpp b/xo-expression2/include/xo/expression2/GlobalSymtab.hpp new file mode 100644 index 00000000..0c0dabf4 --- /dev/null +++ b/xo-expression2/include/xo/expression2/GlobalSymtab.hpp @@ -0,0 +1,13 @@ +/** @file GlobalSymtab.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DGlobalSymtab.hpp" +//#include "symtab/ISymbolTable_DGlobalSymtab.hpp" +//#include "symtab/IGCObject_DGlobalSymtab.hpp" +//#include "symtab/IPrintable_DGlobalSymtab.hpp" + +/* end GlobalSymtab.hpp */ diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 16bfac2a..f14ceae6 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -37,6 +38,7 @@ namespace xo { using xo::mm::AGCObject; using xo::print::APrintable; using xo::facet::FacetRegistry; + using xo::facet::TypeRegistry; using xo::facet::typeseq; namespace scm { @@ -45,6 +47,8 @@ namespace xo { { scope log(XO_DEBUG(true)); + + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -58,10 +62,6 @@ namespace xo { // +- IfElseExpr // \- SequenceExpr - // SymbolTable - // +- LocalSymtab - // \- GlobalSymtab - FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -94,10 +94,17 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + // SymbolTable + // +- LocalSymtab + // \- GlobalSymtab + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); + // until we register facets + TypeRegistry::register_type(); + log && log(xtag("DUniqueString.tseq", typeseq::id())); log && log(xtag("DDefineExpr.tseq", typeseq::id())); log && log(xtag("DVariable.tseq", typeseq::id())); @@ -108,6 +115,7 @@ namespace xo { log && log(xtag("DIfElseExpr.tseq", typeseq::id())); log && log(xtag("DSequenceExpr.tseq", typeseq::id())); + log && log(xtag("DGlobalSymtab.tseq", typeseq::id())); log && log(xtag("DLocalSymtab.tseq", typeseq::id())); log && log(xtag("AExpression.tseq", typeseq::id())); diff --git a/xo-facet/include/xo/facet/TypeRegistry.hpp b/xo-facet/include/xo/facet/TypeRegistry.hpp index 19091630..1f3cb2be 100644 --- a/xo-facet/include/xo/facet/TypeRegistry.hpp +++ b/xo-facet/include/xo/facet/TypeRegistry.hpp @@ -53,13 +53,13 @@ namespace xo { instance()._register_type(r); } - /** Number of registered (facet, repr) pairs **/ - std::size_t size() const { return registry_.size(); } - - std::string_view id2name(typeseq id) const noexcept { + static std::string_view id2name(typeseq id) noexcept { return instance()._id2name(id); } + /** Number of registered (facet, repr) pairs **/ + std::size_t size() const { return registry_.size(); } + /** visit memory pools owned by facet registry **/ void visit_pools(const MemorySizeVisitor & visitor) { registry_.visit_pools(visitor); diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 2f2272ab..46385c56 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace xo { @@ -55,17 +56,23 @@ namespace xo { ParserFixture(const std::string & testname, bool debug_flag) { this->aux_arena_ - = std::move(DArena(ArenaConfig().with_name(testname).with_size(4 * 1024))); + = std::move(DArena(ArenaConfig() + .with_name(testname) + .with_size(4 * 1024))); obj aux_mm(&aux_arena_); this->expr_arena_ = dp::make(aux_mm, - ArenaConfig().with_name("expr").with_size(16 * 1024)); + (ArenaConfig() + .with_name("expr") + .with_size(16 * 1024) + .with_store_header_flag(true))); obj expr_mm(expr_arena_.data()); ParserConfig cfg; cfg.parser_arena_config_.size_ = 16 * 1024; - cfg.symtab_config_.hint_max_capacity_ = 512; + /* editor bait: symbol table */ + cfg.symtab_config_.hint_max_capacity_ = 128; cfg.max_stringtable_capacity_ = 512; cfg.debug_flag_ = false; @@ -77,12 +84,32 @@ namespace xo { ParserFixture(const ParserFixture && other) = delete; bool log_memory_layout(scope * p_log) { + using xo::facet::TypeRegistry; + using xo::mm::MemorySizeDetail; + auto visitor = [p_log](const MemorySizeInfo & info) { - *p_log && (*p_log)(xtag("name", info.resource_name_), - xtag("used", info.used_), - xtag("alloc", info.allocated_), + *p_log && (*p_log)(xtag("name", info.resource_name_), + xtag("used", info.used_), + xtag("alloc", info.allocated_), xtag("commit", info.committed_), - xtag("resv", info.reserved_)); + xtag("resv", info.reserved_)); + if (*p_log && info.detail_) { + (*p_log)("detail", + xtag("n", (*info.detail_)[0].n_alloc_), + xtag("z", (*info.detail_)[0].z_alloc_)); + for (size_t i = 1; i < info.detail_->size(); ++i) { + const MemorySizeDetail & d = (*info.detail_)[i]; + + if (d.tseq_.is_sentinel()) + break; + + (*p_log)("[",i,"]", + xtag("tseq",d.tseq_), + xtag("type", TypeRegistry::id2name(d.tseq_)), + xtag("n", d.n_alloc_), + xtag("z", d.z_alloc_)); + } + } }; aux_arena_.visit_pools(visitor); @@ -144,14 +171,29 @@ namespace xo { REQUIRE(parser.debug_flag() == false); REQUIRE(parser.is_at_toplevel() == true); + // baseline: + // SchematikaParser-ctor :used 1408 + // facets-ctl :used 73 // facet hashtable + // facets-slots :used 1168 // facet hashtable + // expr :used 2056 + // [1] :type xo::scm::DArray :n 1 :z 2056 // DArray of DUniqueString* + // [2] :type ? :n 1 : z 16 + // strings :used 0 + // stringkeys-ctl :used 0 + // strinkeys-slots :used 0 + // parser-arena :used 0 + // global-symtab-ctl :used 0 + // global-symtab-slots :used 0 + log && fixture.log_memory_layout(&log); } - TEST_CASE("SchematikaParser-begin-interactive", "[reader2][SchematikaParser]") + TEST_CASE("SchematikaParser-begin-interactive", + "[reader2][SchematikaParser]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = false; + constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); @@ -697,7 +739,7 @@ namespace xo { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); diff --git a/xo-reflectutil/include/xo/reflectutil/typeseq.hpp b/xo-reflectutil/include/xo/reflectutil/typeseq.hpp index 336f011c..d337cd5b 100644 --- a/xo-reflectutil/include/xo/reflectutil/typeseq.hpp +++ b/xo-reflectutil/include/xo/reflectutil/typeseq.hpp @@ -61,7 +61,7 @@ namespace xo { } private: - int32_t seqno_ = 0; + int32_t seqno_ = -1; std::string_view name_; }; @@ -91,10 +91,11 @@ namespace xo { return typeseq(xo::reflect::typerecd::recd().seqno()); } + bool is_sentinel() const { return seqno_ == -1; } int32_t seqno() const { return seqno_; } private: - int32_t seqno_ = 0; + int32_t seqno_ = -1; }; //template From e87073f9141a7e6471286327ef2e448a9a1a8b08 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 09:31:49 -0500 Subject: [PATCH 225/258] xo-alloc2: register DArena facet + subsystem init --- .../xo/alloc2/alloc2_register_facets.hpp | 15 ++++++++ xo-alloc2/include/xo/alloc2/init_alloc2.hpp | 23 ++++++++++++ xo-alloc2/src/alloc2/CMakeLists.txt | 10 ++---- .../src/alloc2/alloc2_register_facets.cpp | 33 +++++++++++++++++ xo-alloc2/src/alloc2/init_alloc2.cpp | 36 +++++++++++++++++++ xo-object2/src/object2/init_object2.cpp | 3 +- .../src/object2/object2_register_facets.cpp | 31 +++++++++------- 7 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 xo-alloc2/include/xo/alloc2/alloc2_register_facets.hpp create mode 100644 xo-alloc2/include/xo/alloc2/init_alloc2.hpp create mode 100644 xo-alloc2/src/alloc2/alloc2_register_facets.cpp create mode 100644 xo-alloc2/src/alloc2/init_alloc2.cpp diff --git a/xo-alloc2/include/xo/alloc2/alloc2_register_facets.hpp b/xo-alloc2/include/xo/alloc2/alloc2_register_facets.hpp new file mode 100644 index 00000000..a53248a2 --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/alloc2_register_facets.hpp @@ -0,0 +1,15 @@ +/** @file alloc2_register_facets.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +namespace xo { + namespace mm { + /** Register alloc2 (facet,impl) combinations with Facet Registry **/ + bool alloc2_register_facets(); + } +} + +/* end alloc2_register_facets.hpp */ diff --git a/xo-alloc2/include/xo/alloc2/init_alloc2.hpp b/xo-alloc2/include/xo/alloc2/init_alloc2.hpp new file mode 100644 index 00000000..c13160b8 --- /dev/null +++ b/xo-alloc2/include/xo/alloc2/init_alloc2.hpp @@ -0,0 +1,23 @@ +/** @file init_alloc2.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include + +namespace xo { + /* tag to represent the xo-alloc2/ subsystem within ordered initialization */ + enum S_alloc2_tag {}; + + template <> + struct InitSubsys { + static void init(); + static InitEvidence require(); + }; + + +} /*namespace xo*/ + +/* end init_alloc2.hpp */ diff --git a/xo-alloc2/src/alloc2/CMakeLists.txt b/xo-alloc2/src/alloc2/CMakeLists.txt index 7cebc7ae..29890c5f 100644 --- a/xo-alloc2/src/alloc2/CMakeLists.txt +++ b/xo-alloc2/src/alloc2/CMakeLists.txt @@ -3,26 +3,22 @@ set(SELF_LIB xo_alloc2) set(SELF_SRCS -# AllocError.cpp -# AllocInfo.cpp -# cmpresult.cpp + init_alloc2.cpp + alloc2_register_facets.cpp AAllocator.cpp -# ArenaConfig.cpp -# DArena.cpp IAllocator_Any.cpp IAllocator_DArena.cpp IAllocIterator_Any.cpp -# DArenaIterator.cpp IAllocIterator_DArenaIterator.cpp IResourceVisitor_Any.cpp - ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) # note: deps here must also appear in cmake/xo_alloc2Config.cmake.in xo_dependency(${SELF_LIB} xo_arena) xo_dependency(${SELF_LIB} xo_facet) +xo_dependency(${SELF_LIB} subsys) xo_dependency(${SELF_LIB} indentlog) diff --git a/xo-alloc2/src/alloc2/alloc2_register_facets.cpp b/xo-alloc2/src/alloc2/alloc2_register_facets.cpp new file mode 100644 index 00000000..e03afde0 --- /dev/null +++ b/xo-alloc2/src/alloc2/alloc2_register_facets.cpp @@ -0,0 +1,33 @@ +/** @file alloc2_register_facets.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "alloc2_register_facets.hpp" +#include +#include +#include + +namespace xo { + using xo::facet::FacetRegistry; + //using xo::facet::TypeRegistry; + using xo::reflect::typeseq; + + namespace mm { + + bool + alloc2_register_facets() + { + scope log(XO_DEBUG(true)); + + FacetRegistry::register_impl(); + + log && log(xtag("DArena.tseq", typeseq::id())); + + return true; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end alloc2_register_facets.cpp */ diff --git a/xo-alloc2/src/alloc2/init_alloc2.cpp b/xo-alloc2/src/alloc2/init_alloc2.cpp new file mode 100644 index 00000000..d3fb73fa --- /dev/null +++ b/xo-alloc2/src/alloc2/init_alloc2.cpp @@ -0,0 +1,36 @@ +/** @file init_alloc2.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "init_alloc2.hpp" +#include "alloc2_register_facets.hpp" + +namespace xo { + using xo::mm::alloc2_register_facets; + // using xo::mm::alloc2_register_types; + // using xo::mm::CollectorTypeRegistry; + + void + InitSubsys::init() + { + alloc2_register_facets(); + } + + InitEvidence + InitSubsys::require() + { + InitEvidence retval; + + /* direct subsystem deps for xo-alloc2/ (if/when) */ + //retval ^= InitSubsys>::require(); + + /* xo-alloc2/'s own initialization code */ + retval ^= Subsystem::provide("alloc2", &init); + + return retval; + } + +} /*namespace xo*/ + +/* end init_alloc2.cpp */ diff --git a/xo-object2/src/object2/init_object2.cpp b/xo-object2/src/object2/init_object2.cpp index 0f804fe0..bcf7608c 100644 --- a/xo-object2/src/object2/init_object2.cpp +++ b/xo-object2/src/object2/init_object2.cpp @@ -7,6 +7,7 @@ #include "object2_register_facets.hpp" #include "object2_register_types.hpp" #include +#include namespace xo { using xo::scm::object2_register_facets; @@ -27,7 +28,7 @@ namespace xo { InitEvidence retval; /* direct subsystem deps for xo-object2/ */ - // retval ^= InitSubsys::require(); + retval ^= InitSubsys::require(); /* xo-expression2/'s own initialization code */ retval ^= Subsystem::provide("object2", &init); diff --git a/xo-object2/src/object2/object2_register_facets.cpp b/xo-object2/src/object2/object2_register_facets.cpp index c6358474..01d6ef04 100644 --- a/xo-object2/src/object2/object2_register_facets.cpp +++ b/xo-object2/src/object2/object2_register_facets.cpp @@ -6,22 +6,29 @@ #include "object2_register_facets.hpp" #include "RuntimeError.hpp" -#include -#include -#include -#include -#include -#include +#include +//#include +#include +#include +#include +#include -#include +//#include +#include +//#include +//#include +//#include +//#include + +//#include #include -#include -#include -#include -#include +//#include +//#include +//#include +//#include #include -#include +//#include #include #include From 323a7cf9d300ba2d91d3f051427abbed778b6a1f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 09:32:53 -0500 Subject: [PATCH 226/258] xo-expression2: register DGlobalSymtab type + rename --- .../src/expression2/expression2_register_facets.cpp | 5 +++-- xo-reader2/include/xo/reader2/SchematikaReader.hpp | 2 +- xo-reader2/src/reader2/SchematikaParser.cpp | 4 ++-- xo-reader2/src/reader2/SchematikaReader.cpp | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index f14ceae6..a3a4b520 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -5,6 +5,7 @@ #include "expression2_register_facets.hpp" +#include #include #include @@ -47,8 +48,6 @@ namespace xo { { scope log(XO_DEBUG(true)); - - FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -105,6 +104,8 @@ namespace xo { // until we register facets TypeRegistry::register_type(); + TypeRegistry::register_type(); + log && log(xtag("DUniqueString.tseq", typeseq::id())); log && log(xtag("DDefineExpr.tseq", typeseq::id())); log && log(xtag("DVariable.tseq", typeseq::id())); diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index 73b8166b..5a4243a1 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -49,7 +49,7 @@ namespace xo { **/ SchematikaReader(const ReaderConfig & config, obj expr_alloc, - obj fixed_alloc); + obj aux_alloc); /** non-trivial dtor because of @p parser **/ ~SchematikaReader() = default; diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 48e109da..37ebdd05 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -22,12 +22,12 @@ namespace xo { SchematikaParser::SchematikaParser(const ParserConfig & cfg, obj expr_alloc, - obj fixed_alloc) + obj aux_alloc) : psm_{cfg.parser_arena_config_, cfg.symtab_config_, cfg.max_stringtable_capacity_, expr_alloc, - fixed_alloc}, + aux_alloc}, debug_flag_{cfg.debug_flag_} { } diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index e02eefa2..98d44112 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -11,7 +11,7 @@ namespace xo { namespace scm { SchematikaReader::SchematikaReader(const ReaderConfig & config, obj expr_alloc, - obj fixed_alloc) + obj aux_alloc) : tokenizer_{config.tk_buffer_config_, config.tk_debug_flag_}, parser_{ParserConfig(config.parser_arena_config_, @@ -19,7 +19,7 @@ namespace xo { config.max_stringtable_cap_, config.parser_debug_flag_), expr_alloc, - fixed_alloc}, + aux_alloc}, debug_flag_{config.reader_debug_flag_} { } From ec59384d13577eb1c263d14efa350d5fb1ec9a45 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 09:33:51 -0500 Subject: [PATCH 227/258] xo-reader2: register SchematikaParser type --- xo-reader2/src/reader2/reader2_register_facets.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index eb39f6ac..e45d542f 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -47,6 +47,7 @@ namespace xo { using xo::print::APrintable; using xo::facet::FacetRegistry; + using xo::facet::TypeRegistry; using xo::facet::typeseq; namespace scm { @@ -93,6 +94,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + // misc types showing up in aux arena + TypeRegistry::register_type(); + log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); log && log(xtag("DLambdaSsm.tseq", typeseq::id())); From ced30862d8f48b7d16ce581af339b45ab11ef6d5 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 09:34:06 -0500 Subject: [PATCH 228/258] xo-reader2: use alloc headers in utest for visibility --- xo-reader2/src/reader2/reader2_register_facets.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index e45d542f..39e51a07 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -21,23 +21,29 @@ #include "SequenceSsm.hpp" #include "ParenSsm.hpp" +//#include #include #include +//#include #include #include +//#include #include #include +//#include #include #include -#include -#include +#include +//#include +//#include -#include -#include +#include +//#include +//#include #include #include From 44ecf581f058e1d0a46be4c0f79f500a02655bfc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 09:34:40 -0500 Subject: [PATCH 229/258] xo-reader2: use alloc headers in utest for visibility --- xo-reader2/src/reader2/reader2_register_facets.cpp | 10 ++++++++-- xo-reader2/utest/SchematikaParser.test.cpp | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 39e51a07..ab279f56 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -5,15 +5,21 @@ #include "reader2_register_facets.hpp" +#include + +//#include #include #include +//#include #include #include -#include -#include +#include +//#include +//#include +//#include #include #include diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 46385c56..5d831b13 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -58,7 +58,8 @@ namespace xo { this->aux_arena_ = std::move(DArena(ArenaConfig() .with_name(testname) - .with_size(4 * 1024))); + .with_size(4 * 1024) + .with_store_header_flag(true))); obj aux_mm(&aux_arena_); this->expr_arena_ From 516ad5207bc6605ecf7dd280a14d108de2ba8d99 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 09:45:36 -0500 Subject: [PATCH 230/258] xo-reader2: + convenience headers --- xo-reader2/include/xo/reader2/DefineSsm.hpp | 12 ++++++ .../include/xo/reader2/ExpectFormalArgSsm.hpp | 12 ++++++ .../xo/reader2/ExpectFormalArglistSsm.hpp | 12 ++++++ .../include/xo/reader2/ExpectSymbolSsm.hpp | 12 ++++++ .../include/xo/reader2/ExpectTypeSsm.hpp | 12 ++++++ .../include/xo/reader2/ExprSeqState.hpp | 12 ++++++ xo-reader2/include/xo/reader2/IfElseSsm.hpp | 12 ++++++ .../src/reader2/reader2_register_facets.cpp | 42 ++++--------------- 8 files changed, 91 insertions(+), 35 deletions(-) create mode 100644 xo-reader2/include/xo/reader2/DefineSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ExpectFormalArgSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ExpectFormalArglistSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ExpectSymbolSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ExpectTypeSsm.hpp create mode 100644 xo-reader2/include/xo/reader2/ExprSeqState.hpp create mode 100644 xo-reader2/include/xo/reader2/IfElseSsm.hpp diff --git a/xo-reader2/include/xo/reader2/DefineSsm.hpp b/xo-reader2/include/xo/reader2/DefineSsm.hpp new file mode 100644 index 00000000..4a4489a0 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DefineSsm.hpp @@ -0,0 +1,12 @@ +/** @file DefineSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DDefineSsm.hpp" +#include "ssm/ISyntaxStateMachine_DDefineSsm.hpp" +#include "ssm/IPrintable_DDefineSsm.hpp" + +/* end DefineSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ExpectFormalArgSsm.hpp new file mode 100644 index 00000000..f0aaa9ed --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectFormalArgSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectFormalArgSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DExpectFormalArgSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp" +#include "ssm/IPrintable_DExpectFormalArgSsm.hpp" + +/* end ExpectFormalArgSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..35ffcf04 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectFormalArglistSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectFormalArglistSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DExpectFormalArglistSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" +#include "ssm/IPrintable_DExpectFormalArglistSsm.hpp" + +/* end ExpectFormalArglistSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ExpectSymbolSsm.hpp new file mode 100644 index 00000000..66e44aef --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectSymbolSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectSymbolSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DExpectSymbolSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp" +#include "ssm/IPrintable_DExpectSymbolSsm.hpp" + +/* end ExpectSymbolSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ExpectTypeSsm.hpp new file mode 100644 index 00000000..2c189551 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectTypeSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectTypeSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DExpectTypeSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp" +#include "ssm/IPrintable_DExpectTypeSsm.hpp" + +/* end ExpectTypeSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExprSeqState.hpp b/xo-reader2/include/xo/reader2/ExprSeqState.hpp new file mode 100644 index 00000000..912650b9 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExprSeqState.hpp @@ -0,0 +1,12 @@ +/** @file ExprSeqState.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DExprSeqState.hpp" +#include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" +#include "ssm/IPrintable_DExprSeqState.hpp" + +/* end ExprSeqState.hpp */ diff --git a/xo-reader2/include/xo/reader2/IfElseSsm.hpp b/xo-reader2/include/xo/reader2/IfElseSsm.hpp new file mode 100644 index 00000000..eaa6948d --- /dev/null +++ b/xo-reader2/include/xo/reader2/IfElseSsm.hpp @@ -0,0 +1,12 @@ +/** @file IfElseSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DIfElseSsm.hpp" +#include "ssm/ISyntaxStateMachine_DIfElseSsm.hpp" +#include "ssm/IPrintable_DIfElseSsm.hpp" + +/* end IfElseSsm.hpp */ diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index ab279f56..4f5784e5 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -7,49 +7,21 @@ #include -//#include -#include -#include - -//#include -#include -#include - +#include +#include #include -//#include -//#include - -//#include -#include -#include +#include #include "ApplySsm.hpp" #include "SequenceSsm.hpp" #include "ParenSsm.hpp" -//#include -#include -#include - -//#include -#include -#include - -//#include -#include -#include - -//#include -#include -#include - +#include +#include +#include +#include #include -//#include -//#include - #include -//#include -//#include #include #include From 1c943839ebbe58a514a08aaba22f069bbef1ce8e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 09:49:11 -0500 Subject: [PATCH 231/258] xo-reader2: code layout - include file spelling --- xo-reader2/include/xo/reader2/.gitkeep | 0 .../src/reader2/reader2_register_facets.cpp | 27 +++++++++---------- 2 files changed, 12 insertions(+), 15 deletions(-) delete mode 100644 xo-reader2/include/xo/reader2/.gitkeep diff --git a/xo-reader2/include/xo/reader2/.gitkeep b/xo-reader2/include/xo/reader2/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 4f5784e5..7a653954 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -5,25 +5,22 @@ #include "reader2_register_facets.hpp" -#include - -#include -#include -#include -#include - +#include "SchematikaParser.hpp" +#include "ExprSeqState.hpp" +#include "DefineSsm.hpp" +#include "LambdaSsm.hpp" +#include "IfElseSsm.hpp" #include "ApplySsm.hpp" #include "SequenceSsm.hpp" #include "ParenSsm.hpp" +#include "ExpectFormalArglistSsm.hpp" +#include "ExpectFormalArgSsm.hpp" +#include "ExpectSymbolSsm.hpp" +#include "ExpectTypeSsm.hpp" +#include "ExpectExprSsm.hpp" +#include "ProgressSsm.hpp" +#include "SyntaxStateMachine.hpp" -#include -#include -#include -#include -#include -#include - -#include #include #include #include From f7f21a439229f2c67412c8616c218d546ceb5991 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 11:03:09 -0500 Subject: [PATCH 232/258] xo-reader2: bugfix: checkpoint before allocating SSMs --- xo-reader2/include/xo/reader2/DDefineSsm.hpp | 8 ++++++-- xo-reader2/include/xo/reader2/DParenSsm.hpp | 5 ++++- xo-reader2/include/xo/reader2/ParserStack.hpp | 4 +++- .../include/xo/reader2/ParserStateMachine.hpp | 6 ++++-- xo-reader2/src/reader2/DApplySsm.cpp | 6 +++--- xo-reader2/src/reader2/DDefineSsm.cpp | 20 ++++++++++++------- xo-reader2/src/reader2/DExpectExprSsm.cpp | 4 +++- .../src/reader2/DExpectFormalArgSsm.cpp | 4 +++- .../src/reader2/DExpectFormalArglistSsm.cpp | 4 +++- xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 4 +++- xo-reader2/src/reader2/DExpectTypeSsm.cpp | 4 +++- xo-reader2/src/reader2/DIfElseSsm.cpp | 4 +++- xo-reader2/src/reader2/DLambdaSsm.cpp | 4 +++- xo-reader2/src/reader2/DParenSsm.cpp | 14 +++++++++---- xo-reader2/src/reader2/DProgressSsm.cpp | 6 +++--- xo-reader2/src/reader2/DSequenceSsm.cpp | 6 ++++-- xo-reader2/src/reader2/ParserStack.cpp | 3 ++- xo-reader2/src/reader2/ParserStateMachine.cpp | 8 +++++--- 18 files changed, 78 insertions(+), 36 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index d42246ef..6380a233 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -87,8 +87,12 @@ namespace xo { /** create instance using memory from @p parser_mm. * Initial expression scaffold @p def_expr **/ - static DDefineSsm * make(DArena & parser_mm, - DDefineExpr * def_expr); + static DDefineSsm * _make(DArena & parser_mm, + DDefineExpr * def_expr); + + /** create fop referring to new DDefineSsm **/ + static obj make(DArena & parser_mm, + DDefineExpr * def_expr); /** start nested parser for a define-expression, * on top of parser state machine @p p_psm diff --git a/xo-reader2/include/xo/reader2/DParenSsm.hpp b/xo-reader2/include/xo/reader2/DParenSsm.hpp index 6f359b65..818e0470 100644 --- a/xo-reader2/include/xo/reader2/DParenSsm.hpp +++ b/xo-reader2/include/xo/reader2/DParenSsm.hpp @@ -62,7 +62,10 @@ namespace xo { /** create instance using memory from @p parser_mm **/ - static DParenSsm * make(DArena & parser_mm); + static DParenSsm * _make(DArena & parser_mm); + + /** create fop pointing with new DParenSsm using memory from @p parser_mm **/ + static obj make(DArena & parser_mm); /** push DParenSsm instance onto @p p_psm stack **/ static void start(ParserStateMachine * p_psm); diff --git a/xo-reader2/include/xo/reader2/ParserStack.hpp b/xo-reader2/include/xo/reader2/ParserStack.hpp index 936c57e5..ef5705e9 100644 --- a/xo-reader2/include/xo/reader2/ParserStack.hpp +++ b/xo-reader2/include/xo/reader2/ParserStack.hpp @@ -30,9 +30,11 @@ namespace xo { ParserStack * parent); /** create new top of stack for syntax @p ssm, using memory from @p mm. - * previous stack given by @p parent + * previous stack given by @p parent. + * Checkpoint @p ckp will refer to stack _before_ allocating @p ssm **/ static ParserStack * push(ParserStack * stack, + DArena::Checkpoint ckp, DArena & mm, obj ssm); diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 97c8c6e5..2dfba437 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -97,8 +97,10 @@ namespace xo { /** establish toplevel @p ssm. Must have empty stack **/ void establish_toplevel_ssm(obj ssm); - /** push syntax @p ssm onto @ref stack_ **/ - void push_ssm(obj ssm); + /** push syntax @p ssm onto @ref stack_, restore parser stack to @p ckp + * when popped + **/ + void push_ssm(DArena::Checkpoint ckp, obj ssm); /** pop syntax state machine from top of @ref stack_ **/ void pop_ssm(); diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp index 4cd3aaec..a741ce4b 100644 --- a/xo-reader2/src/reader2/DApplySsm.cpp +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -89,14 +89,14 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + DApplySsm * apply_ssm = DApplySsm::make(p_psm->parser_alloc(), fn_expr); obj ssm(apply_ssm); - p_psm->push_ssm(ssm); - //OBSOLETE //p_psm->top_exprstate().on_expr(fn_expr.get(), p_psm); - //OBSOLETE //p_psm->on_token(token_type::leftparen(), p_psm); + p_psm->push_ssm(ckp, ssm); } syntaxstatetype diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 2d2ecb0b..78e29250 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -343,8 +343,8 @@ namespace xo { {} DDefineSsm * - DDefineSsm::make(DArena & mm, - DDefineExpr * def_expr) + DDefineSsm::_make(DArena & mm, + DDefineExpr * def_expr) { void * mem = mm.alloc(typeseq::id(), sizeof(DDefineSsm)); @@ -352,6 +352,13 @@ namespace xo { return new (mem) DDefineSsm(def_expr); } + obj + DDefineSsm::make(DArena & mm, + DDefineExpr * def_expr) + { + return obj(_make(mm, def_expr)); + } + void DDefineSsm::start(DArena & mm, obj expr_mm, @@ -361,14 +368,13 @@ namespace xo { assert(p_psm->stack()); + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + DDefineExpr * def_expr = DDefineExpr::make_empty(expr_mm); - DDefineSsm * define_ssm = DDefineSsm::make(mm, def_expr); + auto define_ssm = DDefineSsm::make(mm, def_expr); - obj ssm - = with_facet::mkobj(define_ssm); - - p_psm->push_ssm(ssm); + p_psm->push_ssm(ckp, define_ssm); // note: triggers poly dispatch p_psm->on_token(Token::def_token()); diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index c763e2a4..767df9bf 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -69,6 +69,8 @@ namespace xo { bool cxl_on_rightbrace, ParserStateMachine * p_psm) { + DArena::Checkpoint ckp = mm.checkpoint(); + DExpectExprSsm * exp_expr = DExpectExprSsm::make(mm, allow_defs, @@ -76,7 +78,7 @@ namespace xo { obj ssm = with_facet::mkobj(exp_expr); - p_psm->push_ssm(ssm); + p_psm->push_ssm(ckp, ssm); } void diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index d865cd71..47d55f6a 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -56,7 +56,9 @@ namespace xo { void DExpectFormalArgSsm::start(ParserStateMachine * p_psm) { - p_psm->push_ssm(DExpectFormalArgSsm::make(p_psm->parser_alloc())); + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectFormalArgSsm::make(p_psm->parser_alloc())); DExpectSymbolSsm::start(p_psm); } diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index 5f609807..3ce11ae8 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -87,7 +87,9 @@ namespace xo { void DExpectFormalArglistSsm::start(ParserStateMachine * p_psm) { - p_psm->push_ssm(DExpectFormalArglistSsm::make(p_psm->parser_alloc())); + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectFormalArglistSsm::make(p_psm->parser_alloc())); } syntaxstatetype diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index b252055b..6f289edd 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -31,6 +31,8 @@ namespace xo { void DExpectSymbolSsm::start(ParserStateMachine * p_psm) { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + DExpectSymbolSsm * sym_ssm = DExpectSymbolSsm::make(p_psm->parser_alloc()); @@ -40,7 +42,7 @@ namespace xo { obj ssm = with_facet::mkobj(sym_ssm); - p_psm->push_ssm(ssm); + p_psm->push_ssm(ckp, ssm); } syntaxstatetype diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index f7ee3689..412a5cab 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -34,13 +34,15 @@ namespace xo { void DExpectTypeSsm::start(ParserStateMachine * p_psm) { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + DExpectTypeSsm * expect_type_ssm = DExpectTypeSsm::make(p_psm->parser_alloc()); auto ssm = with_facet::mkobj(expect_type_ssm); - p_psm->push_ssm(ssm); + p_psm->push_ssm(ckp, ssm); } syntaxstatetype diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index ccf4705f..521a59a1 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -70,13 +70,15 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); + DArena::Checkpoint ckp = parser_mm.checkpoint(); + DIfElseExpr * if_expr = DIfElseExpr::_make_empty(expr_mm); DIfElseSsm * if_ssm = DIfElseSsm::_make(parser_mm, if_expr); obj ssm = with_facet::mkobj(if_ssm); - p_psm->push_ssm(ssm); + p_psm->push_ssm(ckp, ssm); // note: triggers poly dispatch p_psm->on_token(Token::if_token()); diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index a2c2dfbd..6308ae08 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -78,7 +78,9 @@ namespace xo { void DLambdaSsm::start(ParserStateMachine * p_psm) { - p_psm->push_ssm(DLambdaSsm::make(p_psm->parser_alloc())); + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DLambdaSsm::make(p_psm->parser_alloc())); p_psm->on_token(Token::lambda_token()); } diff --git a/xo-reader2/src/reader2/DParenSsm.cpp b/xo-reader2/src/reader2/DParenSsm.cpp index 972d503a..ad86ddd5 100644 --- a/xo-reader2/src/reader2/DParenSsm.cpp +++ b/xo-reader2/src/reader2/DParenSsm.cpp @@ -40,7 +40,7 @@ namespace xo { {} DParenSsm * - DParenSsm::make(DArena & mm) + DParenSsm::_make(DArena & mm) { void * mem = mm.alloc(typeseq::id(), sizeof(DParenSsm)); @@ -48,14 +48,20 @@ namespace xo { return new (mem) DParenSsm(); } + obj + DParenSsm::make(DArena & mm) + { + return obj(_make(mm)); + } + void DParenSsm::start(ParserStateMachine * p_psm) { - DParenSsm * paren_ssm = DParenSsm::make(p_psm->parser_alloc()); + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); - auto ssm = with_facet::mkobj(paren_ssm); + auto paren_ssm = DParenSsm::make(p_psm->parser_alloc()); - p_psm->push_ssm(ssm); + p_psm->push_ssm(ckp, paren_ssm); } syntaxstatetype diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 94efb30d..e4cdf46b 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -164,12 +164,14 @@ namespace xo { optype op, ParserStateMachine * p_psm) { + DArena::Checkpoint ckp = parser_mm.checkpoint(); + DProgressSsm * progress_ssm = DProgressSsm::make(parser_mm, lhs, op); obj ssm(progress_ssm); - p_psm->push_ssm(ssm); + p_psm->push_ssm(ckp, ssm); } void @@ -324,8 +326,6 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); - (void)tk; - obj expr = this->assemble_expr(p_psm); p_psm->pop_ssm(); // completes self diff --git a/xo-reader2/src/reader2/DSequenceSsm.cpp b/xo-reader2/src/reader2/DSequenceSsm.cpp index 7a65d60d..87460804 100644 --- a/xo-reader2/src/reader2/DSequenceSsm.cpp +++ b/xo-reader2/src/reader2/DSequenceSsm.cpp @@ -22,8 +22,10 @@ namespace xo { void DSequenceSsm::start(ParserStateMachine * p_psm) { - p_psm->push_ssm(DSequenceSsm::make(p_psm->parser_alloc(), - p_psm->expr_alloc())); + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DSequenceSsm::make(p_psm->parser_alloc(), + p_psm->expr_alloc())); /* want to accept anything that starts an expression, * except that rightbrace '}' ends it */ diff --git a/xo-reader2/src/reader2/ParserStack.cpp b/xo-reader2/src/reader2/ParserStack.cpp index e3ffb290..9ab919b2 100644 --- a/xo-reader2/src/reader2/ParserStack.cpp +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -22,11 +22,12 @@ namespace xo { ParserStack * ParserStack::push(ParserStack * stack, + DArena::Checkpoint ckp, DArena & mm, obj ssm) { - DArena::Checkpoint ckp = mm.checkpoint(); + //DArena::Checkpoint ckp = mm.checkpoint(); // wrong, must precede allocation of ssm void * mem = mm.alloc(typeseq::id(), sizeof(ParserStack)); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index bbb4841e..1223abe2 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -75,18 +75,20 @@ namespace xo { assert(stack_ == nullptr); - this->stack_ = ParserStack::push(nullptr /*stack*/, parser_alloc_, ssm); + DArena::Checkpoint ckp = parser_alloc_.checkpoint(); + + this->stack_ = ParserStack::push(nullptr /*stack*/, ckp, parser_alloc_, ssm); this->parser_alloc_ckp_ = parser_alloc_.checkpoint(); } void - ParserStateMachine::push_ssm(obj ssm) + ParserStateMachine::push_ssm(DArena::Checkpoint ckp, obj ssm) { scope log(XO_DEBUG(debug_flag_)); // note: using parser_alloc_ for parser stack, since stacklike behavior - this->stack_ = ParserStack::push(stack_, parser_alloc_, ssm); + this->stack_ = ParserStack::push(stack_, ckp, parser_alloc_, ssm); } void From 02b33d13beafc81dd19ee12a8d923edd605c627b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 11:03:36 -0500 Subject: [PATCH 233/258] xo-reader2: enable alloc headers for parser stack --- xo-arena/include/xo/arena/AllocHeader.hpp | 7 +++++++ xo-reader2/include/xo/reader2/ParserConfig.hpp | 2 +- xo-reader2/src/reader2/reader2_register_facets.cpp | 2 ++ xo-reader2/utest/SchematikaParser.test.cpp | 4 ++-- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/xo-arena/include/xo/arena/AllocHeader.hpp b/xo-arena/include/xo/arena/AllocHeader.hpp index ec99f599..db8b6785 100644 --- a/xo-arena/include/xo/arena/AllocHeader.hpp +++ b/xo-arena/include/xo/arena/AllocHeader.hpp @@ -11,6 +11,13 @@ namespace xo { namespace mm { + /** @brief per-alloc header + * + * Appears immediately before each allocation when + * ArenaConfig.store_header_flag_ is set. + * + * See AllocInfo.hpp for encoding of @ref repr_ + **/ struct AllocHeader { using repr_type = std::uintptr_t; using size_type = std::size_t; diff --git a/xo-reader2/include/xo/reader2/ParserConfig.hpp b/xo-reader2/include/xo/reader2/ParserConfig.hpp index ce781b16..080238c7 100644 --- a/xo-reader2/include/xo/reader2/ParserConfig.hpp +++ b/xo-reader2/include/xo/reader2/ParserConfig.hpp @@ -20,7 +20,7 @@ namespace xo { ArenaConfig parser_arena_config_ { .name_ = "parser-arena", .size_ = 2*1024*1024, .hugepage_z_ = 2*1024*1024, - .store_header_flag_ = false, + .store_header_flag_ = true, .header_{}, .debug_flag_ = false }; diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 7a653954..845b8d8e 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -77,6 +77,8 @@ namespace xo { // misc types showing up in aux arena TypeRegistry::register_type(); + // misc types showing up in parser stack arena + TypeRegistry::register_type(); log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 5d831b13..a0557fa6 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -194,7 +194,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); @@ -740,7 +740,7 @@ namespace xo { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = false; + constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); From f48927a4be2b7e2e4be0b7b4359daa7f2e34584f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 11:08:21 -0500 Subject: [PATCH 234/258] xo-reader2: bugfix: move toplevel ExprSeqState to parser stack --- xo-reader2/include/xo/reader2/DExprSeqState.hpp | 5 +++-- xo-reader2/src/reader2/DExprSeqState.cpp | 9 +++++---- xo-reader2/src/reader2/SchematikaParser.cpp | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index 83448b5e..150303c6 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -41,16 +41,17 @@ namespace xo { using Super = DSyntaxStateMachine; using TypeDescr = xo::reflect::TypeDescr; using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; public: explicit DExprSeqState(exprseqtype ty); /** start interactive top-level session **/ - static void establish_interactive(obj mm, + static void establish_interactive(DArena & mm, ParserStateMachine * p_psm); /** start non-interactive top-level session **/ - static void establish_batch(obj mm, + static void establish_batch(DArena & mm, ParserStateMachine * p_psm); public: diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index 1d9b38a3..8261b506 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -35,6 +35,7 @@ namespace xo { using xo::scm::DFloat; using xo::mm::AGCObject; using xo::mm::AAllocator; + using xo::mm::DArena; using xo::facet::with_facet; using xo::reflect::typeseq; @@ -59,7 +60,7 @@ namespace xo { namespace { obj - make_exprseq_ssm(obj mm, + make_exprseq_ssm(DArena & mm, exprseqtype seqtype) { void * mem = mm.alloc(typeseq::id(), @@ -67,12 +68,12 @@ namespace xo { DExprSeqState * ssm = new (mem) DExprSeqState(seqtype); - return with_facet::mkobj(ssm); + return obj(ssm); } } void - DExprSeqState::establish_interactive(obj mm, + DExprSeqState::establish_interactive(DArena & mm, ParserStateMachine * p_psm) { p_psm->establish_toplevel_ssm(make_exprseq_ssm @@ -81,7 +82,7 @@ namespace xo { } void - DExprSeqState::establish_batch(obj mm, + DExprSeqState::establish_batch(DArena & mm, ParserStateMachine * p_psm) { p_psm->establish_toplevel_ssm(make_exprseq_ssm diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 37ebdd05..3a30b18a 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -65,14 +65,14 @@ namespace xo { void SchematikaParser::begin_interactive_session() { - DExprSeqState::establish_interactive(psm_.expr_alloc(), &psm_); + DExprSeqState::establish_interactive(psm_.parser_alloc(), &psm_); } void SchematikaParser::begin_batch_session() { - DExprSeqState::establish_batch(psm_.expr_alloc(), &psm_); + DExprSeqState::establish_batch(psm_.parser_alloc(), &psm_); } const ParserResult & From 44e6bac3b290011337d97075f16186f877334fe9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 11:15:30 -0500 Subject: [PATCH 235/258] xo-reader2: rename DExprSeqState -> DToplevelSeqSsm --- xo-reader2/CMakeLists.txt | 12 ++-- xo-reader2/DESIGN.md | 2 +- ...json5 => IPrintable_DToplevelSeqSsm.json5} | 6 +- ...ISyntaxStateMachine_DToplevelSeqSsm.json5} | 6 +- ...{DExprSeqState.hpp => DToplevelSeqSsm.hpp} | 14 ++-- .../include/xo/reader2/ExprSeqState.hpp | 12 ---- .../include/xo/reader2/ToplevelSeqSsm.hpp | 12 ++++ ...ate.hpp => IPrintable_DToplevelSeqSsm.hpp} | 22 +++--- ...> ISyntaxStateMachine_DToplevelSeqSsm.hpp} | 38 +++++----- .../include/xo/reader2/syntaxstatetype.hpp | 2 +- xo-reader2/src/reader2/CMakeLists.txt | 6 +- ...{DExprSeqState.cpp => DToplevelSeqSsm.cpp} | 64 ++++++++--------- ...ate.cpp => IPrintable_DToplevelSeqSsm.cpp} | 12 ++-- .../ISyntaxStateMachine_DExprSeqState.cpp | 69 ------------------- .../ISyntaxStateMachine_DToplevelSeqSsm.cpp | 69 +++++++++++++++++++ xo-reader2/src/reader2/SchematikaParser.cpp | 6 +- .../src/reader2/reader2_register_facets.cpp | 8 +-- 17 files changed, 180 insertions(+), 180 deletions(-) rename xo-reader2/idl/{IPrintable_DExprSeqState.json5 => IPrintable_DToplevelSeqSsm.json5} (64%) rename xo-reader2/idl/{ISyntaxStateMachine_DExprSeqState.json5 => ISyntaxStateMachine_DToplevelSeqSsm.json5} (62%) rename xo-reader2/include/xo/reader2/{DExprSeqState.hpp => DToplevelSeqSsm.hpp} (93%) delete mode 100644 xo-reader2/include/xo/reader2/ExprSeqState.hpp create mode 100644 xo-reader2/include/xo/reader2/ToplevelSeqSsm.hpp rename xo-reader2/include/xo/reader2/ssm/{IPrintable_DExprSeqState.hpp => IPrintable_DToplevelSeqSsm.hpp} (68%) rename xo-reader2/include/xo/reader2/ssm/{ISyntaxStateMachine_DExprSeqState.hpp => ISyntaxStateMachine_DToplevelSeqSsm.hpp} (54%) rename xo-reader2/src/reader2/{DExprSeqState.cpp => DToplevelSeqSsm.cpp} (87%) rename xo-reader2/src/reader2/{IPrintable_DExprSeqState.cpp => IPrintable_DToplevelSeqSsm.cpp} (54%) delete mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp create mode 100644 xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 7bfc86f1..b2153df4 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -38,11 +38,11 @@ xo_add_genfacet( # note: manual target; generated code committed to git xo_add_genfacetimpl( - TARGET xo-reader2-facetimpl-syntaxstatemachine-exprseqstate + TARGET xo-reader2-facetimpl-syntaxstatemachine-toplevelseqssm FACET_PKG xo_reader2 FACET SyntaxStateMachine - REPR ExprSeqState - INPUT idl/ISyntaxStateMachine_DExprSeqState.json5 + REPR ToplevelSeqSsm + INPUT idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm OUTPUT_CPP_DIR src/reader2 @@ -50,11 +50,11 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( - TARGET xo-reader2-facetimpl-printable-exprseqstate + TARGET xo-reader2-facetimpl-printable-toplevelseqssm FACET_PKG xo_printable2 FACET Printable - REPR ExprSeqState - INPUT idl/IPrintable_DExprSeqState.json5 + REPR ToplevelSeqSsm + INPUT idl/IPrintable_DToplevelSeqSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm OUTPUT_CPP_DIR src/reader2 diff --git a/xo-reader2/DESIGN.md b/xo-reader2/DESIGN.md index 69596c44..73e863e3 100644 --- a/xo-reader2/DESIGN.md +++ b/xo-reader2/DESIGN.md @@ -7,6 +7,6 @@ Composition of nested state machines. a state machine dedicated to some particular Schematika syntax. Examples: if-expression, type declaration, function call -## DExprSeqState +## DToplevelSeqSsm top-level expression sequence diff --git a/xo-reader2/idl/IPrintable_DExprSeqState.json5 b/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 similarity index 64% rename from xo-reader2/idl/IPrintable_DExprSeqState.json5 rename to xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 index d0315c58..0c0f0200 100644 --- a/xo-reader2/idl/IPrintable_DExprSeqState.json5 +++ b/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 @@ -6,8 +6,8 @@ namespace1: "xo", namespace2: "scm", facet_idl: "idl/Printable.json5", - brief: "provide APrintable interface for DExprSeqState", + brief: "provide APrintable interface for DToplevelSeqSsm", using_doxygen: true, - repr: "DExprSeqState", - doc: [ "implement APrintable for DExprSeqState" ], + repr: "DToplevelSeqSsm", + doc: [ "implement APrintable for DToplevelSeqSsm" ], } diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExprSeqState.json5 b/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 similarity index 62% rename from xo-reader2/idl/ISyntaxStateMachine_DExprSeqState.json5 rename to xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 index 0d0cdcac..f13b3137 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExprSeqState.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 @@ -6,8 +6,8 @@ namespace1: "xo", namespace2: "scm", facet_idl: "idl/SyntaxStateMachine.json5", - brief: "provide ASyntaxStateMachine interface for DExprSeqState", + brief: "provide ASyntaxStateMachine interface for DToplevelSeqSsm", using_doxygen: true, - repr: "DExprSeqState", - doc: [ "implement ASyntaxStateMachine for DExprSeqState" ], + repr: "DToplevelSeqSsm", + doc: [ "implement ASyntaxStateMachine for DToplevelSeqSsm" ], } diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp similarity index 93% rename from xo-reader2/include/xo/reader2/DExprSeqState.hpp rename to xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp index 150303c6..743d2133 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp @@ -1,4 +1,4 @@ -/** @file DExprSeqState.hpp +/** @file DToplevelSeqSsm.hpp * * @author Roland Conybeare, Jan 2026 **/ @@ -31,21 +31,21 @@ namespace xo { return os; } - /** @class DExprSeqState + /** @class DToplevelSeqSsm * @brief state machine for parsing a sequence of expression * * Similar to exprseq_xs in xo-expresion **/ - class DExprSeqState : public DSyntaxStateMachine { + class DToplevelSeqSsm : public DSyntaxStateMachine { public: - using Super = DSyntaxStateMachine; + using Super = DSyntaxStateMachine; using TypeDescr = xo::reflect::TypeDescr; using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; public: - explicit DExprSeqState(exprseqtype ty); + explicit DToplevelSeqSsm(exprseqtype ty); /** start interactive top-level session **/ static void establish_interactive(DArena & mm, @@ -55,7 +55,7 @@ namespace xo { ParserStateMachine * p_psm); public: - static const char * ssm_classname() { return "DExprSeqState"; } + static const char * ssm_classname() { return "DToplevelSeqSsm"; } /** @defgroup scm-exprseq-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -152,4 +152,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end DExprSeqState.hpp */ +/* end DToplevelSeqSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExprSeqState.hpp b/xo-reader2/include/xo/reader2/ExprSeqState.hpp deleted file mode 100644 index 912650b9..00000000 --- a/xo-reader2/include/xo/reader2/ExprSeqState.hpp +++ /dev/null @@ -1,12 +0,0 @@ -/** @file ExprSeqState.hpp - * - * @author Roland Conybeare, Feb 2026 - **/ - -#pragma once - -#include "DExprSeqState.hpp" -#include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" -#include "ssm/IPrintable_DExprSeqState.hpp" - -/* end ExprSeqState.hpp */ diff --git a/xo-reader2/include/xo/reader2/ToplevelSeqSsm.hpp b/xo-reader2/include/xo/reader2/ToplevelSeqSsm.hpp new file mode 100644 index 00000000..35cd8362 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ToplevelSeqSsm.hpp @@ -0,0 +1,12 @@ +/** @file ToplevelSeqSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DToplevelSeqSsm.hpp" +#include "ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp" +#include "ssm/IPrintable_DToplevelSeqSsm.hpp" + +/* end ToplevelSeqSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp similarity index 68% rename from xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp rename to xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp index 0dd14190..d411a87e 100644 --- a/xo-reader2/include/xo/reader2/ssm/IPrintable_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp @@ -1,14 +1,14 @@ -/** @file IPrintable_DExprSeqState.hpp +/** @file IPrintable_DToplevelSeqSsm.hpp * * Generated automagically from ingredients: * 1. code generator: * [xo-facet/codegen/genfacet] * arguments: - * --input [idl/IPrintable_DExprSeqState.json5] + * --input [idl/IPrintable_DToplevelSeqSsm.json5] * 2. jinja2 template for abstract facet .hpp file: * [iface_facet_repr.hpp.j2] * 3. idl for facet methods - * [idl/IPrintable_DExprSeqState.json5] + * [idl/IPrintable_DToplevelSeqSsm.json5] **/ #pragma once @@ -16,28 +16,28 @@ #include "Printable.hpp" #include #include -#include "DExprSeqState.hpp" +#include "DToplevelSeqSsm.hpp" -namespace xo { namespace scm { class IPrintable_DExprSeqState; } } +namespace xo { namespace scm { class IPrintable_DToplevelSeqSsm; } } namespace xo { namespace facet { template <> struct FacetImplementation + xo::scm::DToplevelSeqSsm> { using ImplType = xo::print::IPrintable_Xfer - ; + ; }; } } namespace xo { namespace scm { - /** @class IPrintable_DExprSeqState + /** @class IPrintable_DToplevelSeqSsm **/ - class IPrintable_DExprSeqState { + class IPrintable_DToplevelSeqSsm { public: /** @defgroup scm-printable-dexprseqstate-type-traits **/ ///@{ @@ -50,7 +50,7 @@ namespace xo { // const methods /** Pretty-printing support for this object. See [xo-indentlog/xo/indentlog/pretty.hpp] **/ - static bool pretty(const DExprSeqState & self, const ppindentinfo & ppii); + static bool pretty(const DToplevelSeqSsm & self, const ppindentinfo & ppii); // non-const methods ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp similarity index 54% rename from xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp rename to xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp index cfb92548..3bf58e17 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp @@ -1,14 +1,14 @@ -/** @file ISyntaxStateMachine_DExprSeqState.hpp +/** @file ISyntaxStateMachine_DToplevelSeqSsm.hpp * * Generated automagically from ingredients: * 1. code generator: * [xo-facet/codegen/genfacet] * arguments: - * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] + * --input [idl/ISyntaxStateMachine_DToplevelSeqSsm.json5] * 2. jinja2 template for abstract facet .hpp file: * [iface_facet_repr.hpp.j2] * 3. idl for facet methods - * [idl/ISyntaxStateMachine_DExprSeqState.json5] + * [idl/ISyntaxStateMachine_DToplevelSeqSsm.json5] **/ #pragma once @@ -16,28 +16,28 @@ #include "SyntaxStateMachine.hpp" #include "SyntaxStateMachine.hpp" #include "ssm/ISyntaxStateMachine_Xfer.hpp" -#include "DExprSeqState.hpp" +#include "DToplevelSeqSsm.hpp" -namespace xo { namespace scm { class ISyntaxStateMachine_DExprSeqState; } } +namespace xo { namespace scm { class ISyntaxStateMachine_DToplevelSeqSsm; } } namespace xo { namespace facet { template <> struct FacetImplementation + xo::scm::DToplevelSeqSsm> { using ImplType = xo::scm::ISyntaxStateMachine_Xfer - ; + ; }; } } namespace xo { namespace scm { - /** @class ISyntaxStateMachine_DExprSeqState + /** @class ISyntaxStateMachine_DToplevelSeqSsm **/ - class ISyntaxStateMachine_DExprSeqState { + class ISyntaxStateMachine_DToplevelSeqSsm { public: /** @defgroup scm-syntaxstatemachine-dexprseqstate-type-traits **/ ///@{ @@ -49,25 +49,25 @@ namespace xo { ///@{ // const methods /** identify a type of syntax state machine **/ - static syntaxstatetype ssm_type(const DExprSeqState & self) noexcept; + static syntaxstatetype ssm_type(const DToplevelSeqSsm & self) noexcept; /** text describing expected/allowed input to this ssm in current state **/ - static std::string_view get_expect_str(const DExprSeqState & self) noexcept; + static std::string_view get_expect_str(const DToplevelSeqSsm & self) noexcept; // non-const methods /** operate state machine for incoming token @p tk **/ - static void on_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); + static void on_token(DToplevelSeqSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update stat machine for incoming parsed symbol @p sym **/ - static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); + static void on_parsed_symbol(DToplevelSeqSsm & self, std::string_view sym, ParserStateMachine * p_psm); /** operate state machine for incoming type description @p td **/ - static void on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm); + static void on_parsed_typedescr(DToplevelSeqSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ - static void on_parsed_formal(DExprSeqState & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + static void on_parsed_formal(DToplevelSeqSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ - static void on_parsed_formal_arglist(DExprSeqState & self, DArray * arglist, ParserStateMachine * p_psm); + static void on_parsed_formal_arglist(DToplevelSeqSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ - static void on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); + static void on_parsed_expression(DToplevelSeqSsm & self, obj expr, ParserStateMachine * p_psm); /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ - static void on_parsed_expression_with_token(DExprSeqState & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + static void on_parsed_expression_with_token(DToplevelSeqSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 147b7770..957272e8 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -39,7 +39,7 @@ namespace xo { /** expression enclosed in parentheses. See @ref DParenSsm **/ paren, - /** toplevel of some translation unit. See @ref DExprSeqState **/ + /** toplevel of some translation unit. See @ref DToplevelSeqSsm **/ expect_toplevel_expression_sequence, /** expecting a formal argument list (sub-syntax within lambda-expression) **/ diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 5c98e209..6ad71cdf 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -17,9 +17,9 @@ set(SELF_SRCS syntaxstatetype.cpp ISyntaxStateMachine_Any.cpp - DExprSeqState.cpp - ISyntaxStateMachine_DExprSeqState.cpp - IPrintable_DExprSeqState.cpp + DToplevelSeqSsm.cpp + ISyntaxStateMachine_DToplevelSeqSsm.cpp + IPrintable_DToplevelSeqSsm.cpp DDefineSsm.cpp ISyntaxStateMachine_DDefineSsm.cpp diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DToplevelSeqSsm.cpp similarity index 87% rename from xo-reader2/src/reader2/DExprSeqState.cpp rename to xo-reader2/src/reader2/DToplevelSeqSsm.cpp index 8261b506..e294d078 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DToplevelSeqSsm.cpp @@ -1,10 +1,10 @@ -/** @file DExprSeqState.cpp +/** @file DToplevelSeqSsm.cpp * * @author Roland Conybeare, Jan 2026 **/ -#include "DExprSeqState.hpp" -#include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" +#include "DToplevelSeqSsm.hpp" +#include "ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp" #include "DDefineSsm.hpp" #include "DLambdaSsm.hpp" #include "ProgressSsm.hpp" @@ -55,7 +55,7 @@ namespace xo { return "exprseqtype?"; } - DExprSeqState::DExprSeqState(exprseqtype ty) : seqtype_{ty} + DToplevelSeqSsm::DToplevelSeqSsm(exprseqtype ty) : seqtype_{ty} {} namespace { @@ -63,17 +63,17 @@ namespace xo { make_exprseq_ssm(DArena & mm, exprseqtype seqtype) { - void * mem = mm.alloc(typeseq::id(), - sizeof(DExprSeqState)); + void * mem = mm.alloc(typeseq::id(), + sizeof(DToplevelSeqSsm)); - DExprSeqState * ssm = new (mem) DExprSeqState(seqtype); + DToplevelSeqSsm * ssm = new (mem) DToplevelSeqSsm(seqtype); - return obj(ssm); + return obj(ssm); } } void - DExprSeqState::establish_interactive(DArena & mm, + DToplevelSeqSsm::establish_interactive(DArena & mm, ParserStateMachine * p_psm) { p_psm->establish_toplevel_ssm(make_exprseq_ssm @@ -82,7 +82,7 @@ namespace xo { } void - DExprSeqState::establish_batch(DArena & mm, + DToplevelSeqSsm::establish_batch(DArena & mm, ParserStateMachine * p_psm) { p_psm->establish_toplevel_ssm(make_exprseq_ssm @@ -93,13 +93,13 @@ namespace xo { // SyntaxStateMachine facet methods syntaxstatetype - DExprSeqState::ssm_type() const noexcept + DToplevelSeqSsm::ssm_type() const noexcept { return syntaxstatetype::expect_toplevel_expression_sequence; } std::string_view - DExprSeqState::get_expect_str() const noexcept + DToplevelSeqSsm::get_expect_str() const noexcept { // TODO: provisional. Will expand as more syntax implemented @@ -113,11 +113,11 @@ namespace xo { } assert(false); - return "impossible-DExprSeqState::get_expr_str"; + return "impossible-DToplevelSeqSsm::get_expr_str"; } void - DExprSeqState::on_token(const Token & tk, + DToplevelSeqSsm::on_token(const Token & tk, ParserStateMachine * p_psm) { scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); @@ -197,13 +197,13 @@ namespace xo { break; } - p_psm->illegal_input_on_token("DExprSeqState::on_token", + p_psm->illegal_input_on_token("DToplevelSeqSsm::on_token", tk, this->get_expect_str()); } void - DExprSeqState::on_symbol_token(const Token & tk, + DToplevelSeqSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { switch (seqtype_) { @@ -215,7 +215,7 @@ namespace xo { if (var) { DProgressSsm::start(var, p_psm); } else { - p_psm->unknown_variable_error("DExprSeqState::on_symbol_token", + p_psm->unknown_variable_error("DToplevelSeqSsm::on_symbol_token", tk, this->get_expect_str(), p_psm); @@ -234,7 +234,7 @@ namespace xo { } void - DExprSeqState::on_def_token(const Token & tk, + DToplevelSeqSsm::on_def_token(const Token & tk, ParserStateMachine * p_psm) { (void)tk; @@ -250,7 +250,7 @@ namespace xo { } void - DExprSeqState::on_lambda_token(const Token & tk, + DToplevelSeqSsm::on_lambda_token(const Token & tk, ParserStateMachine * p_psm) { (void)tk; @@ -271,7 +271,7 @@ namespace xo { } void - DExprSeqState::on_if_token(const Token & tk, + DToplevelSeqSsm::on_if_token(const Token & tk, ParserStateMachine * p_psm) { switch (seqtype_) { @@ -291,7 +291,7 @@ namespace xo { } void - DExprSeqState::on_string_token(const Token & tk, + DToplevelSeqSsm::on_string_token(const Token & tk, ParserStateMachine * p_psm) { switch (seqtype_) { @@ -318,7 +318,7 @@ namespace xo { } void - DExprSeqState::on_f64_token(const Token & tk, + DToplevelSeqSsm::on_f64_token(const Token & tk, ParserStateMachine * p_psm) { switch (seqtype_) { @@ -344,7 +344,7 @@ namespace xo { } void - DExprSeqState::on_i64_token(const Token & tk, + DToplevelSeqSsm::on_i64_token(const Token & tk, ParserStateMachine * p_psm) { switch (seqtype_) { @@ -370,7 +370,7 @@ namespace xo { } void - DExprSeqState::on_bool_token(const Token & tk, + DToplevelSeqSsm::on_bool_token(const Token & tk, ParserStateMachine * p_psm) { switch (seqtype_) { @@ -396,7 +396,7 @@ namespace xo { } void - DExprSeqState::on_leftparen_token(const Token & tk, + DToplevelSeqSsm::on_leftparen_token(const Token & tk, ParserStateMachine * p_psm) { switch (seqtype_) { @@ -423,21 +423,21 @@ namespace xo { } void - DExprSeqState::on_parsed_expression(obj expr, + DToplevelSeqSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { // toplevel expr sequence accepts an arbitrary number of expressions. - p_psm->capture_result("DExprSeqState::on_parsed_expression", expr); + p_psm->capture_result("DToplevelSeqSsm::on_parsed_expression", expr); } void - DExprSeqState::on_parsed_expression_with_token(obj expr, + DToplevelSeqSsm::on_parsed_expression_with_token(obj expr, const Token & tk, ParserStateMachine * p_psm) { if (tk.tk_type() == tokentype::tk_semicolon) { - p_psm->capture_result("DExprSeqState::on_parsed_expression_with_token", expr); + p_psm->capture_result("DToplevelSeqSsm::on_parsed_expression_with_token", expr); return; } @@ -445,14 +445,14 @@ namespace xo { } bool - DExprSeqState::pretty(const ppindentinfo & ppii) const + DToplevelSeqSsm::pretty(const ppindentinfo & ppii) const { return ppii.pps()->pretty_struct (ppii, - "DExprSeqState", + "DToplevelSeqSsm", refrtag("seqtype", seqtype_)); } } /*namespace scm*/ } /*namespace xo*/ -/* end DExprSeqState.cpp */ +/* end DToplevelSeqSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp b/xo-reader2/src/reader2/IPrintable_DToplevelSeqSsm.cpp similarity index 54% rename from xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp rename to xo-reader2/src/reader2/IPrintable_DToplevelSeqSsm.cpp index 36cfbd78..7a958fa8 100644 --- a/xo-reader2/src/reader2/IPrintable_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/IPrintable_DToplevelSeqSsm.cpp @@ -1,22 +1,22 @@ -/** @file IPrintable_DExprSeqState.cpp +/** @file IPrintable_DToplevelSeqSsm.cpp * * Generated automagically from ingredients: * 1. code generator: * [xo-facet/codegen/genfacet] * arguments: - * --input [idl/IPrintable_DExprSeqState.json5] + * --input [idl/IPrintable_DToplevelSeqSsm.json5] * 2. jinja2 template for abstract facet .hpp file: * [iface_facet_any.hpp.j2] * 3. idl for facet methods - * [idl/IPrintable_DExprSeqState.json5] + * [idl/IPrintable_DToplevelSeqSsm.json5] **/ -#include "ssm/IPrintable_DExprSeqState.hpp" +#include "ssm/IPrintable_DToplevelSeqSsm.hpp" namespace xo { namespace scm { auto - IPrintable_DExprSeqState::pretty(const DExprSeqState & self, const ppindentinfo & ppii) -> bool + IPrintable_DToplevelSeqSsm::pretty(const DToplevelSeqSsm & self, const ppindentinfo & ppii) -> bool { return self.pretty(ppii); } @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DExprSeqState.cpp */ +/* end IPrintable_DToplevelSeqSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp deleted file mode 100644 index 71b0cc1a..00000000 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/** @file ISyntaxStateMachine_DExprSeqState.cpp - * - * Generated automagically from ingredients: - * 1. code generator: - * [xo-facet/codegen/genfacet] - * arguments: - * --input [idl/ISyntaxStateMachine_DExprSeqState.json5] - * 2. jinja2 template for abstract facet .hpp file: - * [iface_facet_any.hpp.j2] - * 3. idl for facet methods - * [idl/ISyntaxStateMachine_DExprSeqState.json5] -**/ - -#include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" - -namespace xo { - namespace scm { - auto - ISyntaxStateMachine_DExprSeqState::ssm_type(const DExprSeqState & self) noexcept -> syntaxstatetype - { - return self.ssm_type(); - } - - auto - ISyntaxStateMachine_DExprSeqState::get_expect_str(const DExprSeqState & self) noexcept -> std::string_view - { - return self.get_expect_str(); - } - - auto - ISyntaxStateMachine_DExprSeqState::on_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_token(tk, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void - { - self.on_parsed_symbol(sym, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm) -> void - { - self.on_parsed_typedescr(td, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_parsed_formal(DExprSeqState & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void - { - self.on_parsed_formal(param_name, param_type, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_parsed_formal_arglist(DExprSeqState & self, DArray * arglist, ParserStateMachine * p_psm) -> void - { - self.on_parsed_formal_arglist(arglist, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_parsed_expression(DExprSeqState & self, obj expr, ParserStateMachine * p_psm) -> void - { - self.on_parsed_expression(expr, p_psm); - } - auto - ISyntaxStateMachine_DExprSeqState::on_parsed_expression_with_token(DExprSeqState & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void - { - self.on_parsed_expression_with_token(expr, tk, p_psm); - } - - } /*namespace scm*/ -} /*namespace xo*/ - -/* end ISyntaxStateMachine_DExprSeqState.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp new file mode 100644 index 00000000..4dfe35a8 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp @@ -0,0 +1,69 @@ +/** @file ISyntaxStateMachine_DToplevelSeqSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DToplevelSeqSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DToplevelSeqSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DToplevelSeqSsm::ssm_type(const DToplevelSeqSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DToplevelSeqSsm::get_expect_str(const DToplevelSeqSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DToplevelSeqSsm::on_token(DToplevelSeqSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DToplevelSeqSsm::on_parsed_symbol(DToplevelSeqSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DToplevelSeqSsm::on_parsed_typedescr(DToplevelSeqSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DToplevelSeqSsm::on_parsed_formal(DToplevelSeqSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DToplevelSeqSsm::on_parsed_formal_arglist(DToplevelSeqSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DToplevelSeqSsm::on_parsed_expression(DToplevelSeqSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DToplevelSeqSsm::on_parsed_expression_with_token(DToplevelSeqSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DToplevelSeqSsm.cpp */ diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 3a30b18a..9272cfc2 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -6,7 +6,7 @@ #include "SchematikaParser.hpp" #include "ParserStateMachine.hpp" #include "ParserStack.hpp" -#include "DExprSeqState.hpp" +#include "DToplevelSeqSsm.hpp" #include #include #include @@ -65,14 +65,14 @@ namespace xo { void SchematikaParser::begin_interactive_session() { - DExprSeqState::establish_interactive(psm_.parser_alloc(), &psm_); + DToplevelSeqSsm::establish_interactive(psm_.parser_alloc(), &psm_); } void SchematikaParser::begin_batch_session() { - DExprSeqState::establish_batch(psm_.parser_alloc(), &psm_); + DToplevelSeqSsm::establish_batch(psm_.parser_alloc(), &psm_); } const ParserResult & diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 845b8d8e..59d91907 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -6,7 +6,7 @@ #include "reader2_register_facets.hpp" #include "SchematikaParser.hpp" -#include "ExprSeqState.hpp" +#include "ToplevelSeqSsm.hpp" #include "DefineSsm.hpp" #include "LambdaSsm.hpp" #include "IfElseSsm.hpp" @@ -37,8 +37,8 @@ namespace xo { { scope log(XO_DEBUG(true)); - FacetRegistry::register_impl(); - FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -80,7 +80,7 @@ namespace xo { // misc types showing up in parser stack arena TypeRegistry::register_type(); - log && log(xtag("DExprSeqState.tseq", typeseq::id())); + log && log(xtag("DToplevelSeqSsm.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); log && log(xtag("DLambdaSsm.tseq", typeseq::id())); log && log(xtag("DIfElseSsm.tseq", typeseq::id())); From 045bdbf525f8e1320b2a96f8b42243fb3928d683 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 16:50:57 -0500 Subject: [PATCH 236/258] xo-reader2: refactor: make() + _make() pair for each ssm --- xo-reader2/include/xo/reader2/DApplySsm.hpp | 8 +++++-- .../include/xo/reader2/DExpectExprSsm.hpp | 11 +++++++--- .../include/xo/reader2/DExpectSymbolSsm.hpp | 5 ++++- .../include/xo/reader2/DExpectTypeSsm.hpp | 6 +++++- xo-reader2/include/xo/reader2/DIfElseSsm.hpp | 12 ++++------- .../include/xo/reader2/DProgressSsm.hpp | 11 +++++++--- xo-reader2/src/reader2/DApplySsm.cpp | 16 ++++++++------ xo-reader2/src/reader2/DExpectExprSsm.cpp | 21 +++++++++++-------- xo-reader2/src/reader2/DExpectSymbolSsm.cpp | 17 +++++++-------- xo-reader2/src/reader2/DExpectTypeSsm.cpp | 14 +++++++------ xo-reader2/src/reader2/DIfElseSsm.cpp | 11 +++++++--- xo-reader2/src/reader2/DProgressSsm.cpp | 19 ++++++++++------- 12 files changed, 92 insertions(+), 59 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DApplySsm.hpp b/xo-reader2/include/xo/reader2/DApplySsm.hpp index b9ff3d8b..d53b3c5c 100644 --- a/xo-reader2/include/xo/reader2/DApplySsm.hpp +++ b/xo-reader2/include/xo/reader2/DApplySsm.hpp @@ -88,8 +88,12 @@ namespace xo { /** create instance using memory from @p parser_mm. * with function to be called supplied by @p fn_expr. **/ - static DApplySsm * make(DArena & parser_mm, - obj fn_expr); + static DApplySsm * _make(DArena & parser_mm, + obj fn_expr); + + /** create fop referring to new DApplySsm **/ + static obj make(DArena & parser_mm, + obj fn_expr); /** * Start apply. Will trigger this after input like diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 473a89d3..c963c9c1 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -25,9 +25,14 @@ namespace xo { explicit DExpectExprSsm(bool allow_defs, bool cxl_on_rightparen); - static DExpectExprSsm * make(DArena & parser_mm, - bool allow_defs, - bool cxl_on_rightbrace); + static DExpectExprSsm * _make(DArena & parser_mm, + bool allow_defs, + bool cxl_on_rightbrace); + + /** create fop referring to new DExpectExprSsm **/ + static obj make(DArena & parser_mm, + bool allow_defs, + bool cxl_on_rightbrace); static void start(DArena & parser_mm, bool allow_defs, diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index d1cf3a3c..b621985b 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -29,7 +29,10 @@ namespace xo { DExpectSymbolSsm(); /** create instance using memory from @p parser_mm **/ - static DExpectSymbolSsm * make(DArena & parser_mm); + static DExpectSymbolSsm * _make(DArena & parser_mm); + + /** create fop referring to new DExpectSymbolSsm **/ + static obj make(DArena & parser_mm); /** start nested parser expecting a symbol, * on top of parser state machine @p p_psm. diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 6719bfb8..8d67b448 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -6,6 +6,7 @@ #pragma once #include "DSyntaxStateMachine.hpp" +#include #include namespace xo { @@ -31,7 +32,10 @@ namespace xo { public: DExpectTypeSsm(); - static DExpectTypeSsm * make(DArena & parser_mm); + static DExpectTypeSsm * _make(DArena & parser_mm); + + /** create fop referring to new DExpectTypeSsm **/ + static obj make(DArena & parser_mm); static void start(ParserStateMachine * p_psm); diff --git a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp index 986ffcd7..345f3fa5 100644 --- a/xo-reader2/include/xo/reader2/DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/DIfElseSsm.hpp @@ -65,20 +65,16 @@ namespace xo { ///@{ explicit DIfElseSsm(DIfElseExpr * ifelse_expr); -#ifdef NOT_YET - /** create instance using memory from @p parser_mm - * with initial scaffold @p ifelse_expr - **/ - static obj make(DArena & parser_mm, - DIfElseExpr * ifelse_expr); -#endif - /** create instance using memory from @p parser_mm * with initial scaffold @p ifelse_expr. **/ static DIfElseSsm * _make(DArena & parser_mm, DIfElseExpr * ifelse_expr); + /** create fop referring to new DIfElseSsm **/ + static obj make(DArena & parser_mm, + DIfElseExpr * ifelse_expr); + /** start nested parser for an if-else expression * on top of parser state machine @p p_psm. * Use @p parser_mm to allocate syntax state machines diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index c43caacd..cc0eb0c5 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -96,9 +96,14 @@ namespace xo { public: DProgressSsm(obj lhs, optype op); - static DProgressSsm * make(DArena & parser_mm, - obj lhs, - optype op); + static DProgressSsm * _make(DArena & parser_mm, + obj lhs, + optype op); + + /** create fop referring to new DProgressSsm **/ + static obj make(DArena & parser_mm, + obj lhs, + optype op); static void start(DArena & parser_mm, ParserStateMachine * p_psm); diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp index a741ce4b..d6f5e151 100644 --- a/xo-reader2/src/reader2/DApplySsm.cpp +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -58,8 +58,8 @@ namespace xo { } DApplySsm * - DApplySsm::make(DArena & arena, - obj fn_expr) + DApplySsm::_make(DArena & arena, + obj fn_expr) { obj mm(&arena); @@ -83,6 +83,13 @@ namespace xo { return new (mem) DApplySsm(applystate, fn_expr, args); } + obj + DApplySsm::make(DArena & arena, + obj fn_expr) + { + return obj(_make(arena, fn_expr)); + } + void DApplySsm::start(obj fn_expr, ParserStateMachine * p_psm) @@ -91,10 +98,7 @@ namespace xo { DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); - DApplySsm * apply_ssm - = DApplySsm::make(p_psm->parser_alloc(), fn_expr); - - obj ssm(apply_ssm); + auto ssm = DApplySsm::make(p_psm->parser_alloc(), fn_expr); p_psm->push_ssm(ckp, ssm); } diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 767df9bf..a2db5967 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -52,9 +52,9 @@ namespace xo { } DExpectExprSsm * - DExpectExprSsm::make(DArena & mm, - bool allow_defs, - bool cxl_on_rightbrace) + DExpectExprSsm::_make(DArena & mm, + bool allow_defs, + bool cxl_on_rightbrace) { void * mem = mm.alloc(typeseq::id(), sizeof(DExpectExprSsm)); @@ -63,6 +63,14 @@ namespace xo { cxl_on_rightbrace); } + obj + DExpectExprSsm::make(DArena & mm, + bool allow_defs, + bool cxl_on_rightbrace) + { + return obj(_make(mm, allow_defs, cxl_on_rightbrace)); + } + void DExpectExprSsm::start(DArena & mm, bool allow_defs, @@ -71,12 +79,7 @@ namespace xo { { DArena::Checkpoint ckp = mm.checkpoint(); - DExpectExprSsm * exp_expr - = DExpectExprSsm::make(mm, - allow_defs, - cxl_on_rightbrace); - obj ssm - = with_facet::mkobj(exp_expr); + auto ssm = DExpectExprSsm::make(mm, allow_defs, cxl_on_rightbrace); p_psm->push_ssm(ckp, ssm); } diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 6f289edd..8a750751 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -20,7 +20,7 @@ namespace xo { {} DExpectSymbolSsm * - DExpectSymbolSsm::make(DArena & mm) + DExpectSymbolSsm::_make(DArena & mm) { void * mem = mm.alloc(typeseq::id(), sizeof(DExpectSymbolSsm)); @@ -28,19 +28,18 @@ namespace xo { return new (mem) DExpectSymbolSsm(); } + obj + DExpectSymbolSsm::make(DArena & mm) + { + return obj(_make(mm)); + } + void DExpectSymbolSsm::start(ParserStateMachine * p_psm) { DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); - DExpectSymbolSsm * sym_ssm - = DExpectSymbolSsm::make(p_psm->parser_alloc()); - - // note: - // relying on [ISyntaxStateMachine_DExpectedSymbolSsm.hpp] - // - obj ssm - = with_facet::mkobj(sym_ssm); + auto ssm = DExpectSymbolSsm::make(p_psm->parser_alloc()); p_psm->push_ssm(ckp, ssm); } diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 412a5cab..b4fa8819 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -23,7 +23,7 @@ namespace xo { {} DExpectTypeSsm * - DExpectTypeSsm::make(DArena & mm) + DExpectTypeSsm::_make(DArena & mm) { void * mem = mm.alloc(typeseq::id(), sizeof(DArena)); @@ -31,16 +31,18 @@ namespace xo { return new (mem) DExpectTypeSsm(); } + obj + DExpectTypeSsm::make(DArena & mm) + { + return obj(_make(mm)); + } + void DExpectTypeSsm::start(ParserStateMachine * p_psm) { DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); - DExpectTypeSsm * expect_type_ssm - = DExpectTypeSsm::make(p_psm->parser_alloc()); - - auto ssm - = with_facet::mkobj(expect_type_ssm); + auto ssm = DExpectTypeSsm::make(p_psm->parser_alloc()); p_psm->push_ssm(ckp, ssm); } diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index 521a59a1..e78d187b 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -63,6 +63,13 @@ namespace xo { return new (mem) DIfElseSsm(ifelse_expr); } + obj + DIfElseSsm::make(DArena & mm, + DIfElseExpr * ifelse_expr) + { + return obj(_make(mm, ifelse_expr)); + } + void DIfElseSsm::start(DArena & parser_mm, obj expr_mm, @@ -73,10 +80,8 @@ namespace xo { DArena::Checkpoint ckp = parser_mm.checkpoint(); DIfElseExpr * if_expr = DIfElseExpr::_make_empty(expr_mm); - DIfElseSsm * if_ssm = DIfElseSsm::_make(parser_mm, if_expr); - obj ssm - = with_facet::mkobj(if_ssm); + auto ssm = DIfElseSsm::make(parser_mm, if_expr); p_psm->push_ssm(ckp, ssm); diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index e4cdf46b..4af449c0 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -146,16 +146,22 @@ namespace xo { } DProgressSsm * - DProgressSsm::make(DArena & mm, - obj lhs, - optype op) + DProgressSsm::_make(DArena & mm, + obj lhs, + optype op) { void * mem = mm.alloc(typeseq::id(), sizeof(DProgressSsm)); return new (mem) DProgressSsm(lhs, op); + } - //return std::make_unique(progress_xs(std::move(valex), op)); + obj + DProgressSsm::make(DArena & mm, + obj lhs, + optype op) + { + return obj(_make(mm, lhs, op)); } void @@ -166,10 +172,7 @@ namespace xo { { DArena::Checkpoint ckp = parser_mm.checkpoint(); - DProgressSsm * progress_ssm - = DProgressSsm::make(parser_mm, lhs, op); - - obj ssm(progress_ssm); + auto ssm = DProgressSsm::make(parser_mm, lhs, op); p_psm->push_ssm(ckp, ssm); } From 8871b149e47855720dc81104a55f1df0e7f61e57 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 17:15:02 -0500 Subject: [PATCH 237/258] xo-procedure2 xo-cmake: move OUTPUT_CPP_DIR to idl/*.json5 --- xo-facet/codegen/genfacet | 9 +++++++-- .../idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 | 1 + .../idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 | 1 + .../idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 | 1 + xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 | 1 + xo-procedure2/idl/Procedure.json5 | 1 + xo-procedure2/idl/RuntimeContext.json5 | 1 + .../include/xo/procedure2/detail/RProcedure.hpp | 2 ++ .../include/xo/procedure2/detail/RRuntimeContext.hpp | 2 ++ 9 files changed, 17 insertions(+), 2 deletions(-) diff --git a/xo-facet/codegen/genfacet b/xo-facet/codegen/genfacet index 8edadc1c..062683be 100755 --- a/xo-facet/codegen/genfacet +++ b/xo-facet/codegen/genfacet @@ -458,7 +458,7 @@ def main(): # --output-impl-hpp: putting this in .json5, will be able to drop this. parser.add_argument('--output-impl-hpp', required=True, help='.hpp detail subdir') parser.add_argument('--output-hpp', required=True, help='.hpp output directory') - parser.add_argument('--output-cpp', required=True, help='.cpp output directory') + parser.add_argument('--output-cpp', required=False, help='.cpp output directory') args = parser.parse_args() @@ -473,7 +473,12 @@ def main(): output_impl_hpp_dir = Path(args.output_hpp) / output_impl_hpp_subdir output_impl_hpp_dir.mkdir(parents=False, exist_ok=True) - output_cpp_dir = Path(args.output_cpp) + if 'output_cpp_dir' in idl: + output_cpp_dir = Path(idl['output_cpp_dir']) + elif args.output_cpp: + output_cpp_dir = Path(args.output_cpp) + else: + parser.error("--output-cpp required when .json5 lacks output_cpp_dir") output_cpp_dir.mkdir(parents=False, exist_ok=True) # setup jinja2 diff --git a/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 index b2fb4014..79ee61d4 100644 --- a/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 +++ b/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/procedure2", includes: [ // "", diff --git a/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 index 15cff1b4..5eb7bf34 100644 --- a/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 +++ b/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/procedure2", includes: [ "", "", diff --git a/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 index fb22bad5..b0a770fd 100644 --- a/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 +++ b/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/procedure2", includes: [ "", "", diff --git a/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 b/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 index ed838629..4765285d 100644 --- a/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 +++ b/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/procedure2", includes: [ //"", //"", diff --git a/xo-procedure2/idl/Procedure.json5 b/xo-procedure2/idl/Procedure.json5 index 449414f0..7933c3a2 100644 --- a/xo-procedure2/idl/Procedure.json5 +++ b/xo-procedure2/idl/Procedure.json5 @@ -4,6 +4,7 @@ { mode: "facet", + output_cpp_dir: "src/procedure2", // includes in ASyntaxStateMachine.hpp includes: [ "\"RuntimeContext.hpp\"", diff --git a/xo-procedure2/idl/RuntimeContext.json5 b/xo-procedure2/idl/RuntimeContext.json5 index e80c0bc5..c896cc64 100644 --- a/xo-procedure2/idl/RuntimeContext.json5 +++ b/xo-procedure2/idl/RuntimeContext.json5 @@ -1,5 +1,6 @@ { mode: "facet", + output_cpp_dir: "src/procedure2", // includes in ARuntimeContext.hpp includes: [ "" diff --git a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp index 61bcb7f7..191bd37e 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RProcedure.hpp @@ -46,6 +46,8 @@ public: /** @defgroup scm-procedure-router-methods **/ ///@{ + // explicit injected content + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } void _drop() const noexcept { O::iface()->_drop(O::data()); } diff --git a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp index a6df812e..a9e161ed 100644 --- a/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp +++ b/xo-procedure2/include/xo/procedure2/detail/RRuntimeContext.hpp @@ -46,6 +46,8 @@ public: /** @defgroup scm-runtimecontext-router-methods **/ ///@{ + // explicit injected content + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } void _drop() const noexcept { O::iface()->_drop(O::data()); } From 908060ea6d0ba17dc28e693dcbb43db8f0e18948 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 17:23:12 -0500 Subject: [PATCH 238/258] xo-procedure2 xo-cmake: drop unnecessary output-cpp-dir cmdline arg --- xo-cmake/cmake/xo_macros/xo_cxx.cmake | 30 ++++++++++++++------------- xo-procedure2/CMakeLists.txt | 6 ------ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/xo-cmake/cmake/xo_macros/xo_cxx.cmake b/xo-cmake/cmake/xo_macros/xo_cxx.cmake index fbce80bd..11d3560e 100644 --- a/xo-cmake/cmake/xo_macros/xo_cxx.cmake +++ b/xo-cmake/cmake/xo_macros/xo_cxx.cmake @@ -1699,10 +1699,6 @@ function(xo_add_genfacet) if(NOT DEFINED GF_OUTPUT_IMPL_SUBDIR) message(FATAL_ERROR "xo_add_genfacet: OUTPUT_IMPL_SUBDIR is required") endif() - if(NOT DEFINED GF_OUTPUT_CPP_DIR) - message(FATAL_ERROR "xo_add_genfacet: OUTPUT_CPP_DIR is required") - endif() - find_program(GENFACET_EXECUTABLE NAMES genfacet HINTS ${CMAKE_SOURCE_DIR}/xo-facet/codegen DOC "path to xo genfacet code generator" @@ -1714,8 +1710,13 @@ function(xo_add_genfacet) ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/A${GF_FACET}.hpp ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_Any.hpp ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_Xfer.hpp - ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/R${GF_FACET}.hpp - ${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_Any.cpp) + ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/R${GF_FACET}.hpp) + + set(_output_cpp_args "") + if(DEFINED GF_OUTPUT_CPP_DIR) + list(APPEND generatedFiles ${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_Any.cpp) + set(_output_cpp_args --output-cpp ${GF_OUTPUT_CPP_DIR}) + endif() #message(STATUS "generatedFiles=${generatedFiles}") @@ -1726,7 +1727,7 @@ function(xo_add_genfacet) --input ${GF_INPUT} --output-hpp ${GF_OUTPUT_HPP_DIR} --output-impl-hpp ${GF_OUTPUT_IMPL_SUBDIR} - --output-cpp ${GF_OUTPUT_CPP_DIR} + ${_output_cpp_args} DEPENDS ${GF_INPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Generating facet source files from ${GF_INPUT}" @@ -1775,10 +1776,6 @@ function(xo_add_genfacetimpl) if(NOT DEFINED GF_OUTPUT_IMPL_SUBDIR) message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_IMPL_SUBDIR is required") endif() - if(NOT DEFINED GF_OUTPUT_CPP_DIR) - message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_CPP_DIR is required") - endif() - if(NOT DEFINED GF_FACET_DIR) if (NOT DEFINED GF_FACET_PKG) message(FATAL_ERROR "xo_add_genfacetimpl: FACET_PKG or FACET_DIR required") @@ -1795,8 +1792,13 @@ function(xo_add_genfacetimpl) message(STATUS "GENFACET_EXECUTABLE=${GENFACET_EXECUTABLE}") set(generatedFiles - ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_D${GF_REPR}.hpp - ${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_D${GF_REPR}.cpp) + ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_D${GF_REPR}.hpp) + + set(_output_cpp_args "") + if(DEFINED GF_OUTPUT_CPP_DIR) + list(APPEND generatedFiles ${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_D${GF_REPR}.cpp) + set(_output_cpp_args --output-cpp ${GF_OUTPUT_CPP_DIR}) + endif() # Build the genfacet command. # But careful: can't have the same generated files in two different rules, @@ -1808,7 +1810,7 @@ function(xo_add_genfacetimpl) --facet-dir ${GF_FACET_DIR} --output-hpp ${GF_OUTPUT_HPP_DIR} --output-impl-hpp ${GF_OUTPUT_IMPL_SUBDIR} - --output-cpp ${GF_OUTPUT_CPP_DIR} + ${_output_cpp_args} DEPENDS ${GF_INPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Generating facet source files from ${GF_INPUT}" diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt index a6fd4d21..1eced319 100644 --- a/xo-procedure2/CMakeLists.txt +++ b/xo-procedure2/CMakeLists.txt @@ -27,7 +27,6 @@ xo_add_genfacet( INPUT idl/Procedure.json5 OUTPUT_HPP_DIR include/xo/procedure2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/procedure2 ) # note: manual target; generated code committed to git @@ -37,7 +36,6 @@ xo_add_genfacet( INPUT idl/RuntimeContext.json5 OUTPUT_HPP_DIR include/xo/procedure2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/procedure2 ) # ---------------------------------------------------------------- @@ -50,7 +48,6 @@ xo_add_genfacetimpl( INPUT idl/IRuntimeContext_DSimpleRcx.json5 OUTPUT_HPP_DIR include/xo/procedure2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/procedure2 ) # ---------------------------------------------------------------- @@ -64,7 +61,6 @@ xo_add_genfacetimpl( INPUT idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 OUTPUT_HPP_DIR include/xo/procedure2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/procedure2 ) # note: manual target; generated code committed to git @@ -76,7 +72,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 OUTPUT_HPP_DIR include/xo/procedure2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/procedure2 ) # note: manual target; generated code committed to git @@ -88,7 +83,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 OUTPUT_HPP_DIR include/xo/procedure2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/procedure2 ) xo_add_genfacet_all(xo-procedure2-genfacet-all) From 28348e46ec674ac74c869bd98c248fa13edd2744 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 17:46:51 -0500 Subject: [PATCH 239/258] xo-interpreter2 stack: OUTPUT_CPP_DIR cmake->idl/ --- xo-alloc2/CMakeLists.txt | 1 - xo-alloc2/idl/ResourceVisitor.json5 | 1 + .../xo/alloc2/visitor/AResourceVisitor.hpp | 2 ++ .../alloc2/visitor/IResourceVisitor_Any.hpp | 5 +++- .../alloc2/visitor/IResourceVisitor_Xfer.hpp | 5 +++- .../xo/alloc2/visitor/RResourceVisitor.hpp | 7 ++++- xo-expression2/CMakeLists.txt | 30 ------------------- xo-expression2/idl/Expression.json5 | 1 + .../idl/IExpression_DApplyExpr.json5 | 1 + .../idl/IExpression_DConstant.json5 | 1 + .../idl/IExpression_DDefineExpr.json5 | 1 + .../idl/IExpression_DIfElseExpr.json5 | 1 + .../idl/IExpression_DLambdaExpr.json5 | 1 + .../idl/IExpression_DSequenceExpr.json5 | 1 + xo-expression2/idl/IExpression_DVarRef.json5 | 1 + .../idl/IExpression_DVariable.json5 | 1 + xo-expression2/idl/IGCObject_DApplyExpr.json5 | 1 + xo-expression2/idl/IGCObject_DConstant.json5 | 1 + .../idl/IGCObject_DIfElseExpr.json5 | 1 + .../idl/IGCObject_DLambdaExpr.json5 | 1 + .../idl/IGCObject_DLocalSymtab.json5 | 1 + .../idl/IGCObject_DSequenceExpr.json5 | 1 + .../idl/IGCObject_DUniqueString.json5 | 1 + xo-expression2/idl/IGCObject_DVarRef.json5 | 1 + xo-expression2/idl/IGCObject_DVariable.json5 | 1 + .../idl/IPrintable_DApplyExpr.json5 | 1 + xo-expression2/idl/IPrintable_DConstant.json5 | 1 + .../idl/IPrintable_DDefineExpr.json5 | 1 + .../idl/IPrintable_DIfElseExpr.json5 | 1 + .../idl/IPrintable_DLambdaExpr.json5 | 1 + .../idl/IPrintable_DLocalSymtab.json5 | 1 + .../idl/IPrintable_DSequenceExpr.json5 | 1 + .../idl/IPrintable_DUniqueString.json5 | 1 + xo-expression2/idl/IPrintable_DVarRef.json5 | 1 + xo-expression2/idl/IPrintable_DVariable.json5 | 1 + .../idl/ISymbolTable_DLocalSymtab.json5 | 1 + xo-expression2/idl/SymbolTable.json5 | 1 + xo-gc/CMakeLists.txt | 1 - xo-gc/idl/GCObject.json5 | 1 + xo-gc/include/xo/gc/GCObject.hpp | 3 +- xo-gc/include/xo/gc/detail/AGCObject.hpp | 6 ++-- xo-gc/include/xo/gc/detail/IGCObject_Any.hpp | 9 ++++-- xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp | 9 ++++-- xo-gc/include/xo/gc/detail/RGCObject.hpp | 9 ++++-- xo-gc/src/gc/IGCObject_Any.cpp | 2 +- xo-interpreter2/CMakeLists.txt | 16 ---------- xo-interpreter2/idl/IGCObject_DClosure.json5 | 1 + xo-interpreter2/idl/IGCObject_DLocalEnv.json5 | 1 + .../idl/IGCObject_DVsmApplyClosureFrame.json5 | 1 + .../idl/IGCObject_DVsmApplyFrame.json5 | 1 + .../idl/IGCObject_DVsmEvalArgsFrame.json5 | 1 + .../idl/IGCObject_DVsmIfElseContFrame.json5 | 1 + .../idl/IGCObject_DVsmSeqContFrame.json5 | 1 + xo-interpreter2/idl/IPrintable_DClosure.json5 | 1 + .../idl/IPrintable_DLocalEnv.json5 | 1 + .../IPrintable_DVsmApplyClosureFrame.json5 | 1 + .../idl/IPrintable_DVsmApplyFrame.json5 | 1 + .../idl/IPrintable_DVsmEvalArgsFrame.json5 | 1 + .../idl/IPrintable_DVsmIfElseContFrame.json5 | 1 + .../idl/IPrintable_DVsmSeqContFrame.json5 | 1 + .../idl/IRuntimeContext_DVsmRcx.json5 | 1 + xo-object2/CMakeLists.txt | 17 ----------- xo-object2/idl/IGCObject_DArray.json5 | 1 + xo-object2/idl/IGCObject_DBoolean.json5 | 1 + xo-object2/idl/IGCObject_DFloat.json5 | 1 + xo-object2/idl/IGCObject_DInteger.json5 | 1 + xo-object2/idl/IGCObject_DList.json5 | 1 + xo-object2/idl/IGCObject_DRuntimeError.json5 | 1 + xo-object2/idl/IGCObject_DString.json5 | 1 + xo-object2/idl/IPrintable_DArray.json5 | 1 + xo-object2/idl/IPrintable_DBoolean.json5 | 1 + xo-object2/idl/IPrintable_DFloat.json5 | 1 + xo-object2/idl/IPrintable_DInteger.json5 | 1 + xo-object2/idl/IPrintable_DList.json5 | 1 + xo-object2/idl/IPrintable_DRuntimeError.json5 | 1 + xo-object2/idl/IPrintable_DString.json5 | 1 + xo-object2/idl/ISequence_DArray.json5 | 1 + xo-object2/idl/ISequence_DList.json5 | 1 + xo-object2/idl/Sequence.json5 | 2 ++ xo-object2/include/xo/object2/Sequence.hpp | 4 +-- .../xo/object2/array/IGCObject_DArray.hpp | 2 +- .../xo/object2/array/IPrintable_DArray.hpp | 2 +- .../xo/object2/array/ISequence_DArray.hpp | 2 +- .../xo/object2/boolean/IGCObject_DBoolean.hpp | 2 +- .../object2/boolean/IPrintable_DBoolean.hpp | 2 +- .../xo/object2/list/IGCObject_DList.hpp | 2 +- .../xo/object2/list/IPrintable_DList.hpp | 2 +- .../xo/object2/list/ISequence_DList.hpp | 2 +- .../xo/object2/number/IGCObject_DFloat.hpp | 2 +- .../xo/object2/number/IGCObject_DInteger.hpp | 2 +- .../xo/object2/number/IPrintable_DFloat.hpp | 2 +- .../xo/object2/number/IPrintable_DInteger.hpp | 2 +- .../include/xo/object2/sequence/ASequence.hpp | 6 ++-- .../xo/object2/sequence/ISequence_Any.hpp | 9 ++++-- .../xo/object2/sequence/ISequence_Xfer.hpp | 9 ++++-- .../include/xo/object2/sequence/RSequence.hpp | 11 +++++-- .../xo/object2/string/IGCObject_DString.hpp | 2 +- .../xo/object2/string/IPrintable_DString.hpp | 2 +- xo-object2/src/object2/IGCObject_DArray.cpp | 4 +-- xo-object2/src/object2/IGCObject_DBoolean.cpp | 4 +-- xo-object2/src/object2/IGCObject_DFloat.cpp | 4 +-- xo-object2/src/object2/IGCObject_DInteger.cpp | 4 +-- xo-object2/src/object2/IGCObject_DList.cpp | 4 +-- xo-object2/src/object2/IGCObject_DString.cpp | 4 +-- xo-object2/src/object2/IPrintable_DArray.cpp | 4 +-- .../src/object2/IPrintable_DBoolean.cpp | 4 +-- xo-object2/src/object2/IPrintable_DFloat.cpp | 4 +-- .../src/object2/IPrintable_DInteger.cpp | 4 +-- xo-object2/src/object2/IPrintable_DList.cpp | 4 +-- xo-object2/src/object2/IPrintable_DString.cpp | 4 +-- xo-object2/src/object2/ISequence_Any.cpp | 2 +- xo-object2/src/object2/ISequence_DArray.cpp | 4 +-- xo-object2/src/object2/ISequence_DList.cpp | 4 +-- xo-printable2/CMakeLists.txt | 1 - xo-printable2/idl/Printable.json5 | 1 + xo-reader2/CMakeLists.txt | 27 ----------------- xo-reader2/idl/IPrintable_DApplySsm.json5 | 1 + xo-reader2/idl/IPrintable_DDefineSsm.json5 | 1 + .../idl/IPrintable_DExpectExprSsm.json5 | 1 + .../idl/IPrintable_DExpectFormalArgSsm.json5 | 1 + .../IPrintable_DExpectFormalArglistSsm.json5 | 1 + .../idl/IPrintable_DExpectSymbolSsm.json5 | 1 + .../idl/IPrintable_DExpectTypeSsm.json5 | 1 + xo-reader2/idl/IPrintable_DIfElseSsm.json5 | 1 + xo-reader2/idl/IPrintable_DLambdaSsm.json5 | 1 + xo-reader2/idl/IPrintable_DParenSsm.json5 | 1 + xo-reader2/idl/IPrintable_DProgressSsm.json5 | 1 + xo-reader2/idl/IPrintable_DSequenceSsm.json5 | 1 + .../idl/IPrintable_DToplevelSeqSsm.json5 | 1 + .../idl/ISyntaxStateMachine_DApplySsm.json5 | 1 + .../idl/ISyntaxStateMachine_DDefineSsm.json5 | 1 + .../ISyntaxStateMachine_DExpectExprSsm.json5 | 1 + ...ntaxStateMachine_DExpectFormalArgSsm.json5 | 1 + ...StateMachine_DExpectFormalArglistSsm.json5 | 1 + ...ISyntaxStateMachine_DExpectSymbolSsm.json5 | 1 + .../ISyntaxStateMachine_DExpectTypeSsm.json5 | 1 + .../idl/ISyntaxStateMachine_DIfElseSsm.json5 | 1 + .../idl/ISyntaxStateMachine_DLambdaSsm.json5 | 1 + .../idl/ISyntaxStateMachine_DParenSsm.json5 | 1 + .../ISyntaxStateMachine_DProgressSsm.json5 | 1 + .../ISyntaxStateMachine_DSequenceSsm.json5 | 1 + .../ISyntaxStateMachine_DToplevelSeqSsm.json5 | 1 + xo-reader2/idl/SyntaxStateMachine.json5 | 1 + .../ssm/IPrintable_DToplevelSeqSsm.hpp | 4 +-- .../ISyntaxStateMachine_DToplevelSeqSsm.hpp | 4 +-- 145 files changed, 207 insertions(+), 169 deletions(-) diff --git a/xo-alloc2/CMakeLists.txt b/xo-alloc2/CMakeLists.txt index 54a2cc4c..b4b03193 100644 --- a/xo-alloc2/CMakeLists.txt +++ b/xo-alloc2/CMakeLists.txt @@ -25,7 +25,6 @@ xo_add_genfacet( INPUT idl/ResourceVisitor.json5 OUTPUT_HPP_DIR include/xo/alloc2 OUTPUT_IMPL_SUBDIR visitor - OUTPUT_CPP_DIR src/alloc2 ) # ---------------------------------------------------------------- diff --git a/xo-alloc2/idl/ResourceVisitor.json5 b/xo-alloc2/idl/ResourceVisitor.json5 index a3369649..79c9d81b 100644 --- a/xo-alloc2/idl/ResourceVisitor.json5 +++ b/xo-alloc2/idl/ResourceVisitor.json5 @@ -1,5 +1,6 @@ { mode: "facet", + output_cpp_dir: "src/alloc2", includes: [ "\"Allocator.hpp\"" ], diff --git a/xo-alloc2/include/xo/alloc2/visitor/AResourceVisitor.hpp b/xo-alloc2/include/xo/alloc2/visitor/AResourceVisitor.hpp index 1466474a..c8ab3744 100644 --- a/xo-alloc2/include/xo/alloc2/visitor/AResourceVisitor.hpp +++ b/xo-alloc2/include/xo/alloc2/visitor/AResourceVisitor.hpp @@ -48,6 +48,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; /** report memory consumption **/ virtual void on_allocator(Copaque data, obj mm) const noexcept = 0; diff --git a/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Any.hpp b/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Any.hpp index a0d3e3c3..18ae11a0 100644 --- a/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Any.hpp +++ b/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Any.hpp @@ -54,8 +54,11 @@ namespace mm { // from AResourceVisitor - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods [[noreturn]] void on_allocator(Copaque, obj) const noexcept override { _fatal(); } // nonconst methods diff --git a/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Xfer.hpp b/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Xfer.hpp index 2ff8abdb..ded806e4 100644 --- a/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Xfer.hpp +++ b/xo-alloc2/include/xo/alloc2/visitor/IResourceVisitor_Xfer.hpp @@ -39,8 +39,11 @@ namespace mm { // from AResourceVisitor - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods void on_allocator(Copaque data, obj mm) const noexcept override { return I::on_allocator(_dcast(data), mm); } diff --git a/xo-alloc2/include/xo/alloc2/visitor/RResourceVisitor.hpp b/xo-alloc2/include/xo/alloc2/visitor/RResourceVisitor.hpp index 3396e6e7..6fa7a633 100644 --- a/xo-alloc2/include/xo/alloc2/visitor/RResourceVisitor.hpp +++ b/xo-alloc2/include/xo/alloc2/visitor/RResourceVisitor.hpp @@ -46,8 +46,13 @@ public: /** @defgroup mm-resourcevisitor-router-methods **/ ///@{ - // const methods + // explicit injected content + + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods void on_allocator(obj mm) const noexcept { return O::iface()->on_allocator(O::data(), mm); } diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 382769ba..dd7ee89a 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -29,7 +29,6 @@ xo_add_genfacet( INPUT idl/SymbolTable.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -43,7 +42,6 @@ xo_add_genfacetimpl( INPUT idl/ISymbolTable_DLocalSymtab.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR symtab - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -55,7 +53,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DLocalSymtab.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR symtab - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -67,7 +64,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DLocalSymtab.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR symtab - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -79,7 +75,6 @@ xo_add_genfacet( INPUT idl/Expression.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -93,7 +88,6 @@ xo_add_genfacetimpl( INPUT idl/IExpression_DConstant.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -105,7 +99,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DConstant.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -117,7 +110,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DConstant.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -131,7 +123,6 @@ xo_add_genfacetimpl( INPUT idl/IExpression_DVariable.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -143,7 +134,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DVariable.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -155,7 +145,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DVariable.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -169,7 +158,6 @@ xo_add_genfacetimpl( INPUT idl/IExpression_DVarRef.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -181,7 +169,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DVarRef.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -193,7 +180,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DVarRef.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -207,7 +193,6 @@ xo_add_genfacetimpl( INPUT idl/IExpression_DDefineExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -219,7 +204,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DDefineExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -233,7 +217,6 @@ xo_add_genfacetimpl( INPUT idl/IExpression_DApplyExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -245,7 +228,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DApplyExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -257,7 +239,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DApplyExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -271,7 +252,6 @@ xo_add_genfacetimpl( INPUT idl/IExpression_DLambdaExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -283,7 +263,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DLambdaExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -295,7 +274,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DLambdaExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -309,7 +287,6 @@ xo_add_genfacetimpl( INPUT idl/IExpression_DIfElseExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -321,7 +298,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DIfElseExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -333,7 +309,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DIfElseExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -347,7 +322,6 @@ xo_add_genfacetimpl( INPUT idl/IExpression_DSequenceExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -359,7 +333,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DSequenceExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -371,7 +344,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DSequenceExpr.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- @@ -385,7 +357,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DUniqueString.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # note: manual target; generated code committed to git @@ -397,7 +368,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DUniqueString.json5 OUTPUT_HPP_DIR include/xo/expression2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/expression2 ) # ---------------------------------------------------------------- diff --git a/xo-expression2/idl/Expression.json5 b/xo-expression2/idl/Expression.json5 index 83ae1402..5391e89a 100644 --- a/xo-expression2/idl/Expression.json5 +++ b/xo-expression2/idl/Expression.json5 @@ -1,5 +1,6 @@ { mode: "facet", + output_cpp_dir: "src/expression2", includes: [ "\"TypeRef.hpp\"", "\"exprtype.hpp\"", ""], diff --git a/xo-expression2/idl/IExpression_DApplyExpr.json5 b/xo-expression2/idl/IExpression_DApplyExpr.json5 index 6814547c..353a7147 100644 --- a/xo-expression2/idl/IExpression_DApplyExpr.json5 +++ b/xo-expression2/idl/IExpression_DApplyExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DConstant.json5 b/xo-expression2/idl/IExpression_DConstant.json5 index d7628f81..3e491f2b 100644 --- a/xo-expression2/idl/IExpression_DConstant.json5 +++ b/xo-expression2/idl/IExpression_DConstant.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DDefineExpr.json5 b/xo-expression2/idl/IExpression_DDefineExpr.json5 index ff35d6d6..28940c7b 100644 --- a/xo-expression2/idl/IExpression_DDefineExpr.json5 +++ b/xo-expression2/idl/IExpression_DDefineExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DIfElseExpr.json5 b/xo-expression2/idl/IExpression_DIfElseExpr.json5 index ed2fb1e8..39c6cd70 100644 --- a/xo-expression2/idl/IExpression_DIfElseExpr.json5 +++ b/xo-expression2/idl/IExpression_DIfElseExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DLambdaExpr.json5 b/xo-expression2/idl/IExpression_DLambdaExpr.json5 index ef1b6704..675d6d9f 100644 --- a/xo-expression2/idl/IExpression_DLambdaExpr.json5 +++ b/xo-expression2/idl/IExpression_DLambdaExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DSequenceExpr.json5 b/xo-expression2/idl/IExpression_DSequenceExpr.json5 index 451d39f1..5c5f1b9a 100644 --- a/xo-expression2/idl/IExpression_DSequenceExpr.json5 +++ b/xo-expression2/idl/IExpression_DSequenceExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DVarRef.json5 b/xo-expression2/idl/IExpression_DVarRef.json5 index 8dea30e5..89ee50d8 100644 --- a/xo-expression2/idl/IExpression_DVarRef.json5 +++ b/xo-expression2/idl/IExpression_DVarRef.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DVariable.json5 b/xo-expression2/idl/IExpression_DVariable.json5 index 6e7993d3..f22f7d4b 100644 --- a/xo-expression2/idl/IExpression_DVariable.json5 +++ b/xo-expression2/idl/IExpression_DVariable.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IGCObject_DApplyExpr.json5 b/xo-expression2/idl/IGCObject_DApplyExpr.json5 index 4bf4304b..9946116a 100644 --- a/xo-expression2/idl/IGCObject_DApplyExpr.json5 +++ b/xo-expression2/idl/IGCObject_DApplyExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DConstant.json5 b/xo-expression2/idl/IGCObject_DConstant.json5 index f67c5b52..1c97456e 100644 --- a/xo-expression2/idl/IGCObject_DConstant.json5 +++ b/xo-expression2/idl/IGCObject_DConstant.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DIfElseExpr.json5 b/xo-expression2/idl/IGCObject_DIfElseExpr.json5 index 1c5d0661..751c0b9f 100644 --- a/xo-expression2/idl/IGCObject_DIfElseExpr.json5 +++ b/xo-expression2/idl/IGCObject_DIfElseExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DLambdaExpr.json5 b/xo-expression2/idl/IGCObject_DLambdaExpr.json5 index b35ad45e..506feb48 100644 --- a/xo-expression2/idl/IGCObject_DLambdaExpr.json5 +++ b/xo-expression2/idl/IGCObject_DLambdaExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DLocalSymtab.json5 b/xo-expression2/idl/IGCObject_DLocalSymtab.json5 index 03705f5e..ca815ee0 100644 --- a/xo-expression2/idl/IGCObject_DLocalSymtab.json5 +++ b/xo-expression2/idl/IGCObject_DLocalSymtab.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DSequenceExpr.json5 b/xo-expression2/idl/IGCObject_DSequenceExpr.json5 index d3bf4aef..c3bd7458 100644 --- a/xo-expression2/idl/IGCObject_DSequenceExpr.json5 +++ b/xo-expression2/idl/IGCObject_DSequenceExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DUniqueString.json5 b/xo-expression2/idl/IGCObject_DUniqueString.json5 index 8cf516b2..cb16d6a2 100644 --- a/xo-expression2/idl/IGCObject_DUniqueString.json5 +++ b/xo-expression2/idl/IGCObject_DUniqueString.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DVarRef.json5 b/xo-expression2/idl/IGCObject_DVarRef.json5 index 3101a035..1a46f47e 100644 --- a/xo-expression2/idl/IGCObject_DVarRef.json5 +++ b/xo-expression2/idl/IGCObject_DVarRef.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DVariable.json5 b/xo-expression2/idl/IGCObject_DVariable.json5 index 7327507f..84a47d01 100644 --- a/xo-expression2/idl/IGCObject_DVariable.json5 +++ b/xo-expression2/idl/IGCObject_DVariable.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" diff --git a/xo-expression2/idl/IPrintable_DApplyExpr.json5 b/xo-expression2/idl/IPrintable_DApplyExpr.json5 index fe743b0b..88a3fef7 100644 --- a/xo-expression2/idl/IPrintable_DApplyExpr.json5 +++ b/xo-expression2/idl/IPrintable_DApplyExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DConstant.json5 b/xo-expression2/idl/IPrintable_DConstant.json5 index 1d955d79..9e4e1ad0 100644 --- a/xo-expression2/idl/IPrintable_DConstant.json5 +++ b/xo-expression2/idl/IPrintable_DConstant.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DDefineExpr.json5 b/xo-expression2/idl/IPrintable_DDefineExpr.json5 index 351f8caf..89c2fdff 100644 --- a/xo-expression2/idl/IPrintable_DDefineExpr.json5 +++ b/xo-expression2/idl/IPrintable_DDefineExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DIfElseExpr.json5 b/xo-expression2/idl/IPrintable_DIfElseExpr.json5 index a8011385..90f02307 100644 --- a/xo-expression2/idl/IPrintable_DIfElseExpr.json5 +++ b/xo-expression2/idl/IPrintable_DIfElseExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DLambdaExpr.json5 b/xo-expression2/idl/IPrintable_DLambdaExpr.json5 index 02a09424..60e0397e 100644 --- a/xo-expression2/idl/IPrintable_DLambdaExpr.json5 +++ b/xo-expression2/idl/IPrintable_DLambdaExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DLocalSymtab.json5 b/xo-expression2/idl/IPrintable_DLocalSymtab.json5 index 3f17e64e..5d48e5f4 100644 --- a/xo-expression2/idl/IPrintable_DLocalSymtab.json5 +++ b/xo-expression2/idl/IPrintable_DLocalSymtab.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DSequenceExpr.json5 b/xo-expression2/idl/IPrintable_DSequenceExpr.json5 index 34154a1e..1b45094f 100644 --- a/xo-expression2/idl/IPrintable_DSequenceExpr.json5 +++ b/xo-expression2/idl/IPrintable_DSequenceExpr.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DUniqueString.json5 b/xo-expression2/idl/IPrintable_DUniqueString.json5 index 540f7b71..d640ce9c 100644 --- a/xo-expression2/idl/IPrintable_DUniqueString.json5 +++ b/xo-expression2/idl/IPrintable_DUniqueString.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DVarRef.json5 b/xo-expression2/idl/IPrintable_DVarRef.json5 index d525886c..0d73c1d9 100644 --- a/xo-expression2/idl/IPrintable_DVarRef.json5 +++ b/xo-expression2/idl/IPrintable_DVarRef.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DVariable.json5 b/xo-expression2/idl/IPrintable_DVariable.json5 index 52c301b2..8e88cde0 100644 --- a/xo-expression2/idl/IPrintable_DVariable.json5 +++ b/xo-expression2/idl/IPrintable_DVariable.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 b/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 index 026c0ed1..ff46c622 100644 --- a/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 +++ b/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/expression2", includes: [ ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/SymbolTable.json5 b/xo-expression2/idl/SymbolTable.json5 index 4d7dc2a4..9cd6e45b 100644 --- a/xo-expression2/idl/SymbolTable.json5 +++ b/xo-expression2/idl/SymbolTable.json5 @@ -1,5 +1,6 @@ { mode: "facet", + output_cpp_dir: "src/expression2", includes: [ "\"Binding.hpp\"", "\"DUniqueString.hpp\"" diff --git a/xo-gc/CMakeLists.txt b/xo-gc/CMakeLists.txt index c0bf8418..59f13d7e 100644 --- a/xo-gc/CMakeLists.txt +++ b/xo-gc/CMakeLists.txt @@ -25,7 +25,6 @@ xo_add_genfacet( INPUT idl/GCObject.json5 OUTPUT_HPP_DIR include/xo/gc OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/gc ) # ---------------------------------------------------------------- diff --git a/xo-gc/idl/GCObject.json5 b/xo-gc/idl/GCObject.json5 index 30fc0d3a..242bea1e 100644 --- a/xo-gc/idl/GCObject.json5 +++ b/xo-gc/idl/GCObject.json5 @@ -1,5 +1,6 @@ { mode: "facet", + output_cpp_dir: "src/gc", includes: [ "", "", diff --git a/xo-gc/include/xo/gc/GCObject.hpp b/xo-gc/include/xo/gc/GCObject.hpp index 970d2c31..c40ffb3a 100644 --- a/xo-gc/include/xo/gc/GCObject.hpp +++ b/xo-gc/include/xo/gc/GCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for facet .hpp file: @@ -45,4 +45,3 @@ namespace xo { } /* end GCObject.hpp */ - diff --git a/xo-gc/include/xo/gc/detail/AGCObject.hpp b/xo-gc/include/xo/gc/detail/AGCObject.hpp index ab6b4096..98f7e258 100644 --- a/xo-gc/include/xo/gc/detail/AGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/AGCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -55,6 +55,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; /** memory consumption for this instance **/ virtual size_type shallow_size(Copaque data) const noexcept = 0; /** copy instance using allocator **/ @@ -82,4 +84,4 @@ using IGCObject_ImplType = xo::facet::FacetImplType; } /*namespace mm*/ } /*namespace xo*/ -/* AGCObject.hpp */ \ No newline at end of file +/* AGCObject.hpp */ diff --git a/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp b/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp index e1b274a7..9ff7bb2e 100644 --- a/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -56,8 +56,11 @@ namespace mm { // from AGCObject - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods [[noreturn]] size_type shallow_size(Copaque) const noexcept override { _fatal(); } [[noreturn]] Opaque shallow_copy(Copaque, obj) const noexcept override { _fatal(); } @@ -87,4 +90,4 @@ namespace mm { } /*namespace mm */ } /*namespace xo */ -/* IGCObject_Any.hpp */ \ No newline at end of file +/* IGCObject_Any.hpp */ diff --git a/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp b/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp index d25eb81e..7f094ab7 100644 --- a/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -44,8 +44,11 @@ namespace mm { // from AGCObject - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods size_type shallow_size(Copaque data) const noexcept override { return I::shallow_size(_dcast(data)); } @@ -89,4 +92,4 @@ namespace mm { } /*namespace mm */ } /*namespace xo*/ -/* end IGCObject_Xfer.hpp */ \ No newline at end of file +/* end IGCObject_Xfer.hpp */ diff --git a/xo-gc/include/xo/gc/detail/RGCObject.hpp b/xo-gc/include/xo/gc/detail/RGCObject.hpp index ab4bcc54..d24994a8 100644 --- a/xo-gc/include/xo/gc/detail/RGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/RGCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -48,8 +48,13 @@ public: /** @defgroup mm-gcobject-router-methods **/ ///@{ - // const methods + // explicit injected content + + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods size_type shallow_size() const noexcept { return O::iface()->shallow_size(O::data()); } diff --git a/xo-gc/src/gc/IGCObject_Any.cpp b/xo-gc/src/gc/IGCObject_Any.cpp index ff6d395d..778760ad 100644 --- a/xo-gc/src/gc/IGCObject_Any.cpp +++ b/xo-gc/src/gc/IGCObject_Any.cpp @@ -44,4 +44,4 @@ IGCObject_Any::forward_children(Opaque, obj) const noexcept -> siz } /*namespace mm*/ } /*namespace xo*/ -/* end IGCObject_Any.cpp */ \ No newline at end of file +/* end IGCObject_Any.cpp */ diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 0b5431ba..28debaa0 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -34,7 +34,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DVsmApplyFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # note: manual target; generated code committed to git @@ -46,7 +45,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DVsmApplyFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # ---------------------------------------------------------------- @@ -60,7 +58,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DVsmEvalArgsFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # note: manual target; generated code committed to git @@ -72,7 +69,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DVsmEvalArgsFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # ---------------------------------------------------------------- @@ -86,7 +82,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DVsmApplyClosureFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # note: manual target; generated code committed to git @@ -98,7 +93,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DVsmApplyClosureFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # ---------------------------------------------------------------- @@ -112,7 +106,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DVsmIfElseContFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR ifelse - OUTPUT_CPP_DIR src/interpreter2 ) # note: manual target; generated code committed to git @@ -124,7 +117,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DVsmIfElseContFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR ifelse - OUTPUT_CPP_DIR src/interpreter2 ) # ---------------------------------------------------------------- @@ -138,7 +130,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DVsmSeqContFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR sequence - OUTPUT_CPP_DIR src/interpreter2 ) # note: manual target; generated code committed to git @@ -150,7 +141,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DVsmSeqContFrame.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR sequence - OUTPUT_CPP_DIR src/interpreter2 ) # ---------------------------------------------------------------- @@ -165,7 +155,6 @@ xo_add_genfacetimpl( # INPUT idl/IProcedure_DClosure.json5 # OUTPUT_HPP_DIR include/xo/interpreter2 # OUTPUT_IMPL_SUBDIR detail -# OUTPUT_CPP_DIR src/interpreter2 #) # note: manual target; generated code committed to git @@ -177,7 +166,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DClosure.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # note: manual target; generated code committed to git @@ -189,7 +177,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DClosure.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # ---------------------------------------------------------------- @@ -203,7 +190,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DLocalEnv.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # note: manual target; generated code committed to git @@ -215,7 +201,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DLocalEnv.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # ---------------------------------------------------------------- @@ -228,7 +213,6 @@ xo_add_genfacetimpl( INPUT idl/IRuntimeContext_DVsmRcx.json5 OUTPUT_HPP_DIR include/xo/interpreter2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/interpreter2 ) # ---------------------------------------------------------------- diff --git a/xo-interpreter2/idl/IGCObject_DClosure.json5 b/xo-interpreter2/idl/IGCObject_DClosure.json5 index ec9f32fd..9e99a16b 100644 --- a/xo-interpreter2/idl/IGCObject_DClosure.json5 +++ b/xo-interpreter2/idl/IGCObject_DClosure.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 index 3c747621..fe8670f1 100644 --- a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 +++ b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 index 398d53e9..4cced151 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 index 979c14bf..175b229e 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 index 8bebc6ec..7d89a5ed 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 index 0f78bb6d..537c9860 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 index cf7196c6..6945f3df 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" diff --git a/xo-interpreter2/idl/IPrintable_DClosure.json5 b/xo-interpreter2/idl/IPrintable_DClosure.json5 index d4b16a69..2cfb3d33 100644 --- a/xo-interpreter2/idl/IPrintable_DClosure.json5 +++ b/xo-interpreter2/idl/IPrintable_DClosure.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 index 0302834d..0a1205f5 100644 --- a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 +++ b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 index 717aa85f..ee4e8e64 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 index f5957d7e..c78e0b88 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 index 24df6cbd..1dd1672a 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 index d3d63c4d..b9f70e6d 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 index e9ec796e..96b9c071 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 b/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 index 8659eb66..9fa3fe40 100644 --- a/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 +++ b/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/interpreter2", includes: [ //"", //"", diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index 2fc0ae29..09faf6b7 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -25,7 +25,6 @@ xo_add_genfacet( INPUT idl/Sequence.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR sequence - OUTPUT_CPP_DIR src/object2 ) # ---------------------------------------------------------------- @@ -39,7 +38,6 @@ xo_add_genfacetimpl( INPUT idl/ISequence_DList.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR list - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -51,7 +49,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DList.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR list - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -63,7 +60,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DList.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR list - OUTPUT_CPP_DIR src/object2 ) # ---------------------------------------------------------------- @@ -77,7 +73,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DBoolean.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR boolean - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -89,7 +84,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DBoolean.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR boolean - OUTPUT_CPP_DIR src/object2 ) # ---------------------------------------------------------------- @@ -103,7 +97,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DFloat.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR number - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -115,7 +108,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DFloat.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR number - OUTPUT_CPP_DIR src/object2 ) # ---------------------------------------------------------------- @@ -129,7 +121,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DInteger.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR number - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -141,7 +132,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DInteger.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR number - OUTPUT_CPP_DIR src/object2 ) # ---------------------------------------------------------------- @@ -155,7 +145,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DString.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR string - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -167,7 +156,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DString.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR string - OUTPUT_CPP_DIR src/object2 ) # ---------------------------------------------------------------- @@ -181,7 +169,6 @@ xo_add_genfacetimpl( INPUT idl/ISequence_DArray.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR array - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -193,7 +180,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DArray.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR array - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -205,7 +191,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DArray.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR array - OUTPUT_CPP_DIR src/object2 ) # ---------------------------------------------------------------- @@ -219,7 +204,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DRuntimeError.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR error - OUTPUT_CPP_DIR src/object2 ) # note: manual target; generated code committed to git @@ -231,7 +215,6 @@ xo_add_genfacetimpl( INPUT idl/IGCObject_DRuntimeError.json5 OUTPUT_HPP_DIR include/xo/object2 OUTPUT_IMPL_SUBDIR error - OUTPUT_CPP_DIR src/object2 ) # ---------------------------------------------------------------- diff --git a/xo-object2/idl/IGCObject_DArray.json5 b/xo-object2/idl/IGCObject_DArray.json5 index e8aeed3b..3e1115e0 100644 --- a/xo-object2/idl/IGCObject_DArray.json5 +++ b/xo-object2/idl/IGCObject_DArray.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" diff --git a/xo-object2/idl/IGCObject_DBoolean.json5 b/xo-object2/idl/IGCObject_DBoolean.json5 index de3663c4..be131a38 100644 --- a/xo-object2/idl/IGCObject_DBoolean.json5 +++ b/xo-object2/idl/IGCObject_DBoolean.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" diff --git a/xo-object2/idl/IGCObject_DFloat.json5 b/xo-object2/idl/IGCObject_DFloat.json5 index 9aba2a34..2791de0b 100644 --- a/xo-object2/idl/IGCObject_DFloat.json5 +++ b/xo-object2/idl/IGCObject_DFloat.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "", diff --git a/xo-object2/idl/IGCObject_DInteger.json5 b/xo-object2/idl/IGCObject_DInteger.json5 index 65f24371..6b865a4c 100644 --- a/xo-object2/idl/IGCObject_DInteger.json5 +++ b/xo-object2/idl/IGCObject_DInteger.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" diff --git a/xo-object2/idl/IGCObject_DList.json5 b/xo-object2/idl/IGCObject_DList.json5 index 342fc299..e660b0c1 100644 --- a/xo-object2/idl/IGCObject_DList.json5 +++ b/xo-object2/idl/IGCObject_DList.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ // "", // "" diff --git a/xo-object2/idl/IGCObject_DRuntimeError.json5 b/xo-object2/idl/IGCObject_DRuntimeError.json5 index 9e416b24..60d30cc7 100644 --- a/xo-object2/idl/IGCObject_DRuntimeError.json5 +++ b/xo-object2/idl/IGCObject_DRuntimeError.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ // "", // "" diff --git a/xo-object2/idl/IGCObject_DString.json5 b/xo-object2/idl/IGCObject_DString.json5 index 8d0e14e0..60c2165e 100644 --- a/xo-object2/idl/IGCObject_DString.json5 +++ b/xo-object2/idl/IGCObject_DString.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" diff --git a/xo-object2/idl/IPrintable_DArray.json5 b/xo-object2/idl/IPrintable_DArray.json5 index df0ef171..eee19b52 100644 --- a/xo-object2/idl/IPrintable_DArray.json5 +++ b/xo-object2/idl/IPrintable_DArray.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DBoolean.json5 b/xo-object2/idl/IPrintable_DBoolean.json5 index 599a1923..09245363 100644 --- a/xo-object2/idl/IPrintable_DBoolean.json5 +++ b/xo-object2/idl/IPrintable_DBoolean.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DFloat.json5 b/xo-object2/idl/IPrintable_DFloat.json5 index 7351c1b2..427c5dce 100644 --- a/xo-object2/idl/IPrintable_DFloat.json5 +++ b/xo-object2/idl/IPrintable_DFloat.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DInteger.json5 b/xo-object2/idl/IPrintable_DInteger.json5 index 1a2e5490..92c74376 100644 --- a/xo-object2/idl/IPrintable_DInteger.json5 +++ b/xo-object2/idl/IPrintable_DInteger.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DList.json5 b/xo-object2/idl/IPrintable_DList.json5 index 640d7d1d..58b8ea82 100644 --- a/xo-object2/idl/IPrintable_DList.json5 +++ b/xo-object2/idl/IPrintable_DList.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DRuntimeError.json5 b/xo-object2/idl/IPrintable_DRuntimeError.json5 index 2d0f3eff..b9e291e0 100644 --- a/xo-object2/idl/IPrintable_DRuntimeError.json5 +++ b/xo-object2/idl/IPrintable_DRuntimeError.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DString.json5 b/xo-object2/idl/IPrintable_DString.json5 index f032ca46..8caffaab 100644 --- a/xo-object2/idl/IPrintable_DString.json5 +++ b/xo-object2/idl/IPrintable_DString.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/ISequence_DArray.json5 b/xo-object2/idl/ISequence_DArray.json5 index 198410da..1f09b0bb 100644 --- a/xo-object2/idl/ISequence_DArray.json5 +++ b/xo-object2/idl/ISequence_DArray.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ ], local_types: [ ], namespace1: "xo", diff --git a/xo-object2/idl/ISequence_DList.json5 b/xo-object2/idl/ISequence_DList.json5 index 677285da..edf0e8dc 100644 --- a/xo-object2/idl/ISequence_DList.json5 +++ b/xo-object2/idl/ISequence_DList.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/object2", includes: [ "" ], local_types: [ ], namespace1: "xo", diff --git a/xo-object2/idl/Sequence.json5 b/xo-object2/idl/Sequence.json5 index 9ceda9ea..5c5139da 100644 --- a/xo-object2/idl/Sequence.json5 +++ b/xo-object2/idl/Sequence.json5 @@ -1,5 +1,6 @@ { mode: "facet", + output_cpp_dir: "src/object2", includes: [""], // extra includes in Sequence.hpp, if any user_hpp_includes: [], @@ -67,4 +68,5 @@ ], nonconst_methods: [ ], + router_facet_explicit_content: [] } diff --git a/xo-object2/include/xo/object2/Sequence.hpp b/xo-object2/include/xo/object2/Sequence.hpp index 7866f91b..0478fa8b 100644 --- a/xo-object2/include/xo/object2/Sequence.hpp +++ b/xo-object2/include/xo/object2/Sequence.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for facet .hpp file: @@ -19,4 +19,4 @@ #include "sequence/RSequence.hpp" -/* end Sequence.hpp */ \ No newline at end of file +/* end Sequence.hpp */ diff --git a/xo-object2/include/xo/object2/array/IGCObject_DArray.hpp b/xo-object2/include/xo/object2/array/IGCObject_DArray.hpp index 0b2279f1..9af6d3c7 100644 --- a/xo-object2/include/xo/object2/array/IGCObject_DArray.hpp +++ b/xo-object2/include/xo/object2/array/IGCObject_DArray.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DArray.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/array/IPrintable_DArray.hpp b/xo-object2/include/xo/object2/array/IPrintable_DArray.hpp index 1b3a4663..890cbab5 100644 --- a/xo-object2/include/xo/object2/array/IPrintable_DArray.hpp +++ b/xo-object2/include/xo/object2/array/IPrintable_DArray.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DArray.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/array/ISequence_DArray.hpp b/xo-object2/include/xo/object2/array/ISequence_DArray.hpp index 27f47db3..3b756b94 100644 --- a/xo-object2/include/xo/object2/array/ISequence_DArray.hpp +++ b/xo-object2/include/xo/object2/array/ISequence_DArray.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISequence_DArray.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/boolean/IGCObject_DBoolean.hpp b/xo-object2/include/xo/object2/boolean/IGCObject_DBoolean.hpp index e075874c..1d90b60e 100644 --- a/xo-object2/include/xo/object2/boolean/IGCObject_DBoolean.hpp +++ b/xo-object2/include/xo/object2/boolean/IGCObject_DBoolean.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DBoolean.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/boolean/IPrintable_DBoolean.hpp b/xo-object2/include/xo/object2/boolean/IPrintable_DBoolean.hpp index e17f169a..b650c435 100644 --- a/xo-object2/include/xo/object2/boolean/IPrintable_DBoolean.hpp +++ b/xo-object2/include/xo/object2/boolean/IPrintable_DBoolean.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DBoolean.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/list/IGCObject_DList.hpp b/xo-object2/include/xo/object2/list/IGCObject_DList.hpp index 19000df6..7e1f1428 100644 --- a/xo-object2/include/xo/object2/list/IGCObject_DList.hpp +++ b/xo-object2/include/xo/object2/list/IGCObject_DList.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/list/IPrintable_DList.hpp b/xo-object2/include/xo/object2/list/IPrintable_DList.hpp index d068bda1..77e7b1d3 100644 --- a/xo-object2/include/xo/object2/list/IPrintable_DList.hpp +++ b/xo-object2/include/xo/object2/list/IPrintable_DList.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/list/ISequence_DList.hpp b/xo-object2/include/xo/object2/list/ISequence_DList.hpp index d7c44e3b..ac468764 100644 --- a/xo-object2/include/xo/object2/list/ISequence_DList.hpp +++ b/xo-object2/include/xo/object2/list/ISequence_DList.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISequence_DList.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp b/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp index a5a01fff..9a1dcbdc 100644 --- a/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp +++ b/xo-object2/include/xo/object2/number/IGCObject_DFloat.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DFloat.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/number/IGCObject_DInteger.hpp b/xo-object2/include/xo/object2/number/IGCObject_DInteger.hpp index 6aa3c9fc..1136b577 100644 --- a/xo-object2/include/xo/object2/number/IGCObject_DInteger.hpp +++ b/xo-object2/include/xo/object2/number/IGCObject_DInteger.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DInteger.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/number/IPrintable_DFloat.hpp b/xo-object2/include/xo/object2/number/IPrintable_DFloat.hpp index 2bcaf1d2..9506055a 100644 --- a/xo-object2/include/xo/object2/number/IPrintable_DFloat.hpp +++ b/xo-object2/include/xo/object2/number/IPrintable_DFloat.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DFloat.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/number/IPrintable_DInteger.hpp b/xo-object2/include/xo/object2/number/IPrintable_DInteger.hpp index a13334d6..1b5df6c4 100644 --- a/xo-object2/include/xo/object2/number/IPrintable_DInteger.hpp +++ b/xo-object2/include/xo/object2/number/IPrintable_DInteger.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DInteger.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/sequence/ASequence.hpp b/xo-object2/include/xo/object2/sequence/ASequence.hpp index 5281e0ea..53d112e7 100644 --- a/xo-object2/include/xo/object2/sequence/ASequence.hpp +++ b/xo-object2/include/xo/object2/sequence/ASequence.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -51,6 +51,8 @@ public: // const methods /** RTTI: unique id# for actual runtime data representation **/ virtual typeseq _typeseq() const noexcept = 0; + /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ + virtual void _drop(Opaque d) const noexcept = 0; /** true iff sequence is empty **/ virtual bool is_empty(Copaque data) const noexcept = 0; /** true iff sequence is finite **/ @@ -78,4 +80,4 @@ using ISequence_ImplType = xo::facet::FacetImplType; } /*namespace scm*/ } /*namespace xo*/ -/* ASequence.hpp */ \ No newline at end of file +/* ASequence.hpp */ diff --git a/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp b/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp index 0e7c5c10..e878f729 100644 --- a/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp +++ b/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -55,8 +55,11 @@ namespace scm { // from ASequence - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } + + // const methods [[noreturn]] bool is_empty(Copaque) const noexcept override { _fatal(); } [[noreturn]] bool is_finite(Copaque) const noexcept override { _fatal(); } [[noreturn]] obj at(Copaque, size_type) const override { _fatal(); } @@ -86,4 +89,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo */ -/* ISequence_Any.hpp */ \ No newline at end of file +/* ISequence_Any.hpp */ diff --git a/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp b/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp index f3dc8b35..42d6cb1b 100644 --- a/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp +++ b/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -40,8 +40,11 @@ namespace scm { // from ASequence - // const methods + // builtin methods typeseq _typeseq() const noexcept override { return s_typeseq; } + void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } + + // const methods bool is_empty(Copaque data) const noexcept override { return I::is_empty(_dcast(data)); } @@ -85,4 +88,4 @@ namespace scm { } /*namespace scm */ } /*namespace xo*/ -/* end ISequence_Xfer.hpp */ \ No newline at end of file +/* end ISequence_Xfer.hpp */ diff --git a/xo-object2/include/xo/object2/sequence/RSequence.hpp b/xo-object2/include/xo/object2/sequence/RSequence.hpp index be4fafb0..76f60059 100644 --- a/xo-object2/include/xo/object2/sequence/RSequence.hpp +++ b/xo-object2/include/xo/object2/sequence/RSequence.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/Sequence.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -47,8 +47,13 @@ public: /** @defgroup scm-sequence-router-methods **/ ///@{ - // const methods + // explicit injected content + + // builtin methods typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + void _drop() const noexcept { O::iface()->_drop(O::data()); } + + // const methods bool is_empty() const noexcept { return O::iface()->is_empty(O::data()); } @@ -84,4 +89,4 @@ namespace xo { namespace facet { }; } } -/* end RSequence.hpp */ \ No newline at end of file +/* end RSequence.hpp */ diff --git a/xo-object2/include/xo/object2/string/IGCObject_DString.hpp b/xo-object2/include/xo/object2/string/IGCObject_DString.hpp index 95a19483..159b9e49 100644 --- a/xo-object2/include/xo/object2/string/IGCObject_DString.hpp +++ b/xo-object2/include/xo/object2/string/IGCObject_DString.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/include/xo/object2/string/IPrintable_DString.hpp b/xo-object2/include/xo/object2/string/IPrintable_DString.hpp index f1be1374..f898a17c 100644 --- a/xo-object2/include/xo/object2/string/IPrintable_DString.hpp +++ b/xo-object2/include/xo/object2/string/IPrintable_DString.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DString.json5] * 2. jinja2 template for abstract facet .hpp file: diff --git a/xo-object2/src/object2/IGCObject_DArray.cpp b/xo-object2/src/object2/IGCObject_DArray.cpp index a2ee4bc1..1063bd45 100644 --- a/xo-object2/src/object2/IGCObject_DArray.cpp +++ b/xo-object2/src/object2/IGCObject_DArray.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DArray.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DArray.cpp */ \ No newline at end of file +/* end IGCObject_DArray.cpp */ diff --git a/xo-object2/src/object2/IGCObject_DBoolean.cpp b/xo-object2/src/object2/IGCObject_DBoolean.cpp index 72aa0b1b..3ef60aea 100644 --- a/xo-object2/src/object2/IGCObject_DBoolean.cpp +++ b/xo-object2/src/object2/IGCObject_DBoolean.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DBoolean.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DBoolean.cpp */ \ No newline at end of file +/* end IGCObject_DBoolean.cpp */ diff --git a/xo-object2/src/object2/IGCObject_DFloat.cpp b/xo-object2/src/object2/IGCObject_DFloat.cpp index 3c44db5d..9e31cf68 100644 --- a/xo-object2/src/object2/IGCObject_DFloat.cpp +++ b/xo-object2/src/object2/IGCObject_DFloat.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DFloat.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DFloat.cpp */ \ No newline at end of file +/* end IGCObject_DFloat.cpp */ diff --git a/xo-object2/src/object2/IGCObject_DInteger.cpp b/xo-object2/src/object2/IGCObject_DInteger.cpp index 91d8e4a1..55e1fae7 100644 --- a/xo-object2/src/object2/IGCObject_DInteger.cpp +++ b/xo-object2/src/object2/IGCObject_DInteger.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DInteger.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DInteger.cpp */ \ No newline at end of file +/* end IGCObject_DInteger.cpp */ diff --git a/xo-object2/src/object2/IGCObject_DList.cpp b/xo-object2/src/object2/IGCObject_DList.cpp index b9d36cc5..f4e9472b 100644 --- a/xo-object2/src/object2/IGCObject_DList.cpp +++ b/xo-object2/src/object2/IGCObject_DList.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DList.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DList.cpp */ \ No newline at end of file +/* end IGCObject_DList.cpp */ diff --git a/xo-object2/src/object2/IGCObject_DString.cpp b/xo-object2/src/object2/IGCObject_DString.cpp index 1eff4da5..d34f0eaf 100644 --- a/xo-object2/src/object2/IGCObject_DString.cpp +++ b/xo-object2/src/object2/IGCObject_DString.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IGCObject_DString.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -36,4 +36,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IGCObject_DString.cpp */ \ No newline at end of file +/* end IGCObject_DString.cpp */ diff --git a/xo-object2/src/object2/IPrintable_DArray.cpp b/xo-object2/src/object2/IPrintable_DArray.cpp index d444800b..b9248516 100644 --- a/xo-object2/src/object2/IPrintable_DArray.cpp +++ b/xo-object2/src/object2/IPrintable_DArray.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DArray.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DArray.cpp */ \ No newline at end of file +/* end IPrintable_DArray.cpp */ diff --git a/xo-object2/src/object2/IPrintable_DBoolean.cpp b/xo-object2/src/object2/IPrintable_DBoolean.cpp index d8fddd87..3b85aa27 100644 --- a/xo-object2/src/object2/IPrintable_DBoolean.cpp +++ b/xo-object2/src/object2/IPrintable_DBoolean.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DBoolean.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DBoolean.cpp */ \ No newline at end of file +/* end IPrintable_DBoolean.cpp */ diff --git a/xo-object2/src/object2/IPrintable_DFloat.cpp b/xo-object2/src/object2/IPrintable_DFloat.cpp index 0c0a6789..f1e8be6d 100644 --- a/xo-object2/src/object2/IPrintable_DFloat.cpp +++ b/xo-object2/src/object2/IPrintable_DFloat.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DFloat.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DFloat.cpp */ \ No newline at end of file +/* end IPrintable_DFloat.cpp */ diff --git a/xo-object2/src/object2/IPrintable_DInteger.cpp b/xo-object2/src/object2/IPrintable_DInteger.cpp index 8924a72c..7a9bbdaa 100644 --- a/xo-object2/src/object2/IPrintable_DInteger.cpp +++ b/xo-object2/src/object2/IPrintable_DInteger.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DInteger.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DInteger.cpp */ \ No newline at end of file +/* end IPrintable_DInteger.cpp */ diff --git a/xo-object2/src/object2/IPrintable_DList.cpp b/xo-object2/src/object2/IPrintable_DList.cpp index 095b323d..a8f9b657 100644 --- a/xo-object2/src/object2/IPrintable_DList.cpp +++ b/xo-object2/src/object2/IPrintable_DList.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DList.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DList.cpp */ \ No newline at end of file +/* end IPrintable_DList.cpp */ diff --git a/xo-object2/src/object2/IPrintable_DString.cpp b/xo-object2/src/object2/IPrintable_DString.cpp index 86d4565e..f5ec4967 100644 --- a/xo-object2/src/object2/IPrintable_DString.cpp +++ b/xo-object2/src/object2/IPrintable_DString.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/IPrintable_DString.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -25,4 +25,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end IPrintable_DString.cpp */ \ No newline at end of file +/* end IPrintable_DString.cpp */ diff --git a/xo-object2/src/object2/ISequence_Any.cpp b/xo-object2/src/object2/ISequence_Any.cpp index 8461d750..372571f7 100644 --- a/xo-object2/src/object2/ISequence_Any.cpp +++ b/xo-object2/src/object2/ISequence_Any.cpp @@ -38,4 +38,4 @@ ISequence_Any::_valid } /*namespace scm*/ } /*namespace xo*/ -/* end ISequence_Any.cpp */ \ No newline at end of file +/* end ISequence_Any.cpp */ diff --git a/xo-object2/src/object2/ISequence_DArray.cpp b/xo-object2/src/object2/ISequence_DArray.cpp index 40ffe36a..abeeaeee 100644 --- a/xo-object2/src/object2/ISequence_DArray.cpp +++ b/xo-object2/src/object2/ISequence_DArray.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISequence_DArray.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -37,4 +37,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISequence_DArray.cpp */ \ No newline at end of file +/* end ISequence_DArray.cpp */ diff --git a/xo-object2/src/object2/ISequence_DList.cpp b/xo-object2/src/object2/ISequence_DList.cpp index 3c9c2437..2bc21862 100644 --- a/xo-object2/src/object2/ISequence_DList.cpp +++ b/xo-object2/src/object2/ISequence_DList.cpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * [xo-facet/codegen/genfacet] * arguments: * --input [idl/ISequence_DList.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -37,4 +37,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISequence_DList.cpp */ \ No newline at end of file +/* end ISequence_DList.cpp */ diff --git a/xo-printable2/CMakeLists.txt b/xo-printable2/CMakeLists.txt index 32034af1..7d3990be 100644 --- a/xo-printable2/CMakeLists.txt +++ b/xo-printable2/CMakeLists.txt @@ -24,7 +24,6 @@ xo_add_genfacet( INPUT idl/Printable.json5 OUTPUT_HPP_DIR include/xo/printable2 OUTPUT_IMPL_SUBDIR detail - OUTPUT_CPP_DIR src/printable2 ) # ---------------------------------------------------------------- diff --git a/xo-printable2/idl/Printable.json5 b/xo-printable2/idl/Printable.json5 index 12925bbc..41799c43 100644 --- a/xo-printable2/idl/Printable.json5 +++ b/xo-printable2/idl/Printable.json5 @@ -1,5 +1,6 @@ { mode: "facet", + output_cpp_dir: "src/printable2", includes: [""], // extra includes in Printable.hpp user_hpp_includes: ["\"detail/ppdetail_Printable.hpp\""], diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index b2153df4..f098bd5e 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -31,7 +31,6 @@ xo_add_genfacet( INPUT idl/SyntaxStateMachine.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -45,7 +44,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -57,7 +55,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DToplevelSeqSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -71,7 +68,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DDefineSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -83,7 +79,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DDefineSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -97,7 +92,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DLambdaSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -109,7 +103,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DLambdaSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -123,7 +116,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DParenSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -135,7 +127,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DParenSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -149,7 +140,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -161,7 +151,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DExpectFormalArglistSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -175,7 +164,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -187,7 +175,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DExpectFormalArgSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -201,7 +188,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DIfElseSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -213,7 +199,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DIfElseSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -227,7 +212,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DSequenceSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -239,7 +223,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DSequenceSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -253,7 +236,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DApplySsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -265,7 +247,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DApplySsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -279,7 +260,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -291,7 +271,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DExpectSymbolSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -305,7 +284,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DExpectTypeSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -317,7 +295,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DExpectTypeSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -331,7 +308,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DExpectExprSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -343,7 +319,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DExpectExprSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- @@ -357,7 +332,6 @@ xo_add_genfacetimpl( INPUT idl/ISyntaxStateMachine_DProgressSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # note: manual target; generated code committed to git @@ -369,7 +343,6 @@ xo_add_genfacetimpl( INPUT idl/IPrintable_DProgressSsm.json5 OUTPUT_HPP_DIR include/xo/reader2 OUTPUT_IMPL_SUBDIR ssm - OUTPUT_CPP_DIR src/reader2 ) # ---------------------------------------------------------------- diff --git a/xo-reader2/idl/IPrintable_DApplySsm.json5 b/xo-reader2/idl/IPrintable_DApplySsm.json5 index cdcd32ca..5895578d 100644 --- a/xo-reader2/idl/IPrintable_DApplySsm.json5 +++ b/xo-reader2/idl/IPrintable_DApplySsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DDefineSsm.json5 b/xo-reader2/idl/IPrintable_DDefineSsm.json5 index e79017f8..3975396e 100644 --- a/xo-reader2/idl/IPrintable_DDefineSsm.json5 +++ b/xo-reader2/idl/IPrintable_DDefineSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 b/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 index 72d19cd7..b6b0caa1 100644 --- a/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 b/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 index 854a458e..6b1bf863 100644 --- a/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 b/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 index 44f474dd..7f566150 100644 --- a/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 b/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 index 1d662986..1d003791 100644 --- a/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 b/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 index 1a4ddca2..4c3b8964 100644 --- a/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DIfElseSsm.json5 b/xo-reader2/idl/IPrintable_DIfElseSsm.json5 index 28fab147..9c54fc71 100644 --- a/xo-reader2/idl/IPrintable_DIfElseSsm.json5 +++ b/xo-reader2/idl/IPrintable_DIfElseSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DLambdaSsm.json5 b/xo-reader2/idl/IPrintable_DLambdaSsm.json5 index 63fad901..9f2187df 100644 --- a/xo-reader2/idl/IPrintable_DLambdaSsm.json5 +++ b/xo-reader2/idl/IPrintable_DLambdaSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DParenSsm.json5 b/xo-reader2/idl/IPrintable_DParenSsm.json5 index 495729b5..9af85828 100644 --- a/xo-reader2/idl/IPrintable_DParenSsm.json5 +++ b/xo-reader2/idl/IPrintable_DParenSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DProgressSsm.json5 b/xo-reader2/idl/IPrintable_DProgressSsm.json5 index cc5a8dda..eb420da3 100644 --- a/xo-reader2/idl/IPrintable_DProgressSsm.json5 +++ b/xo-reader2/idl/IPrintable_DProgressSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DSequenceSsm.json5 b/xo-reader2/idl/IPrintable_DSequenceSsm.json5 index a217b24c..929060b0 100644 --- a/xo-reader2/idl/IPrintable_DSequenceSsm.json5 +++ b/xo-reader2/idl/IPrintable_DSequenceSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 b/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 index 0c0f0200..8349bb04 100644 --- a/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 +++ b/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 index 7806d2cb..2f08ccc5 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 index 11d2c5f7..7aef2f5a 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 index 068ac481..0b04e3d6 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 index 4b83866e..83627a07 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 index d3e16953..535e713f 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 index 24b754e4..288b8256 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 index d46aaff4..04617d60 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 index 5e7e828b..23a4e35d 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 index a24f0147..bd32a95b 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 index 521e7ba8..9d24338d 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 index 807e5ec3..9a141775 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 index 7538c09b..c9319948 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 index f13b3137..e94779f5 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 @@ -1,5 +1,6 @@ { mode: "implementation", + output_cpp_dir: "src/reader2", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 4e33e468..d204a265 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -1,5 +1,6 @@ { mode: "facet", + output_cpp_dir: "src/reader2", // includes in ASyntaxStateMachine.hpp includes: [ "\"ParserStateMachine.hpp\"", diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp index d411a87e..b219b589 100644 --- a/xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp @@ -39,13 +39,13 @@ namespace xo { **/ class IPrintable_DToplevelSeqSsm { public: - /** @defgroup scm-printable-dexprseqstate-type-traits **/ + /** @defgroup scm-printable-dtoplevelseqssm-type-traits **/ ///@{ using ppindentinfo = xo::print::APrintable::ppindentinfo; using Copaque = xo::print::APrintable::Copaque; using Opaque = xo::print::APrintable::Opaque; ///@} - /** @defgroup scm-printable-dexprseqstate-methods **/ + /** @defgroup scm-printable-dtoplevelseqssm-methods **/ ///@{ // const methods /** Pretty-printing support for this object. diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp index 3bf58e17..1d91c13d 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp @@ -39,13 +39,13 @@ namespace xo { **/ class ISyntaxStateMachine_DToplevelSeqSsm { public: - /** @defgroup scm-syntaxstatemachine-dexprseqstate-type-traits **/ + /** @defgroup scm-syntaxstatemachine-dtoplevelseqssm-type-traits **/ ///@{ using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; using Copaque = xo::scm::ASyntaxStateMachine::Copaque; using Opaque = xo::scm::ASyntaxStateMachine::Opaque; ///@} - /** @defgroup scm-syntaxstatemachine-dexprseqstate-methods **/ + /** @defgroup scm-syntaxstatemachine-dtoplevelseqssm-methods **/ ///@{ // const methods /** identify a type of syntax state machine **/ From b0966570c03c7d96ae670b6e76417deb5ee249e9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 18:21:03 -0500 Subject: [PATCH 240/258] xo-expression2: + DGlobalSymtab facet support gen + files --- xo-expression2/CMakeLists.txt | 35 ++++++++++ .../idl/IGCObject_DGlobalSymtab.json5 | 16 +++++ .../idl/IPrintable_DGlobalSymtab.json5 | 14 ++++ .../idl/ISymbolTable_DGlobalSymtab.json5 | 13 ++++ .../include/xo/expression2/DGlobalSymtab.hpp | 8 +++ .../include/xo/expression2/GlobalSymtab.hpp | 6 +- .../symtab/IGCObject_DGlobalSymtab.hpp | 67 +++++++++++++++++++ .../symtab/IPrintable_DGlobalSymtab.hpp | 62 +++++++++++++++++ .../symtab/ISymbolTable_DGlobalSymtab.hpp | 60 +++++++++++++++++ xo-expression2/src/expression2/CMakeLists.txt | 3 + .../src/expression2/DGlobalSymtab.cpp | 12 ++++ .../expression2/IGCObject_DGlobalSymtab.cpp | 39 +++++++++++ .../expression2/IPrintable_DGlobalSymtab.cpp | 28 ++++++++ .../ISymbolTable_DGlobalSymtab.cpp | 34 ++++++++++ .../expression2_register_facets.cpp | 8 ++- 15 files changed, 400 insertions(+), 5 deletions(-) create mode 100644 xo-expression2/idl/IGCObject_DGlobalSymtab.json5 create mode 100644 xo-expression2/idl/IPrintable_DGlobalSymtab.json5 create mode 100644 xo-expression2/idl/ISymbolTable_DGlobalSymtab.json5 create mode 100644 xo-expression2/include/xo/expression2/symtab/IGCObject_DGlobalSymtab.hpp create mode 100644 xo-expression2/include/xo/expression2/symtab/IPrintable_DGlobalSymtab.hpp create mode 100644 xo-expression2/include/xo/expression2/symtab/ISymbolTable_DGlobalSymtab.hpp create mode 100644 xo-expression2/src/expression2/IGCObject_DGlobalSymtab.cpp create mode 100644 xo-expression2/src/expression2/IPrintable_DGlobalSymtab.cpp create mode 100644 xo-expression2/src/expression2/ISymbolTable_DGlobalSymtab.cpp diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index dd7ee89a..1b84df8d 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -68,6 +68,41 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-symboltable-globalsymtab + FACET_PKG xo_expression2 + FACET SymbolTable + REPR GlobalSymtab + INPUT idl/ISymbolTable_DGlobalSymtab.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR symtab +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-globalsymtab + FACET_PKG xo_gc + FACET GCObject + REPR GlobalSymtab + INPUT idl/IGCObject_DGlobalSymtab.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR symtab +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-globalsymtab + FACET_PKG xo_printable2 + FACET Printable + REPR GlobalSymtab + INPUT idl/IPrintable_DGlobalSymtab.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR symtab +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacet( TARGET xo-expression2-facet-expression diff --git a/xo-expression2/idl/IGCObject_DGlobalSymtab.json5 b/xo-expression2/idl/IGCObject_DGlobalSymtab.json5 new file mode 100644 index 00000000..dac8ebac --- /dev/null +++ b/xo-expression2/idl/IGCObject_DGlobalSymtab.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/expression2", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DGlobalSymtab", + using_doxygen: true, + repr: "DGlobalSymtab", + doc: [ "implement AGCObject for DGlobalSymtab" ], +} diff --git a/xo-expression2/idl/IPrintable_DGlobalSymtab.json5 b/xo-expression2/idl/IPrintable_DGlobalSymtab.json5 new file mode 100644 index 00000000..151f8a90 --- /dev/null +++ b/xo-expression2/idl/IPrintable_DGlobalSymtab.json5 @@ -0,0 +1,14 @@ +{ + mode: "implementation", + output_cpp_dir: "src/expression2", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DGlobalSymtab", + using_doxygen: true, + repr: "DGlobalSymtab", + doc: [ "implement APrintable for DGlobalSymtab" ], +} diff --git a/xo-expression2/idl/ISymbolTable_DGlobalSymtab.json5 b/xo-expression2/idl/ISymbolTable_DGlobalSymtab.json5 new file mode 100644 index 00000000..8cc1035b --- /dev/null +++ b/xo-expression2/idl/ISymbolTable_DGlobalSymtab.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + output_cpp_dir: "src/expression2", + includes: [ ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SymbolTable.json5", + brief: "provide ASymbolTable interface for DGlobalSymtab", + using_doxygen: true, + repr: "DGlobalSymtab", + doc: [ "implement ASymbolTable for DGlobalSymtab" ], +} diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 879c7073..6ae8895b 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -31,6 +31,7 @@ namespace xo { using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using ppindentinfo = xo::print::ppindentinfo; public: /** @defgroup scm-globalsymtab-ctors constructors **/ @@ -91,6 +92,13 @@ namespace xo { std::size_t forward_children(obj gc) noexcept; ///@} + /** @defgroup scm-globalsymtab-printable-facet printable facet **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} private: /** map symbols -> bindings. diff --git a/xo-expression2/include/xo/expression2/GlobalSymtab.hpp b/xo-expression2/include/xo/expression2/GlobalSymtab.hpp index 0c0dabf4..05ad9f4b 100644 --- a/xo-expression2/include/xo/expression2/GlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/GlobalSymtab.hpp @@ -6,8 +6,8 @@ #pragma once #include "DGlobalSymtab.hpp" -//#include "symtab/ISymbolTable_DGlobalSymtab.hpp" -//#include "symtab/IGCObject_DGlobalSymtab.hpp" -//#include "symtab/IPrintable_DGlobalSymtab.hpp" +#include "symtab/ISymbolTable_DGlobalSymtab.hpp" +#include "symtab/IGCObject_DGlobalSymtab.hpp" +#include "symtab/IPrintable_DGlobalSymtab.hpp" /* end GlobalSymtab.hpp */ diff --git a/xo-expression2/include/xo/expression2/symtab/IGCObject_DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/IGCObject_DGlobalSymtab.hpp new file mode 100644 index 00000000..92149015 --- /dev/null +++ b/xo-expression2/include/xo/expression2/symtab/IGCObject_DGlobalSymtab.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DGlobalSymtab.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DGlobalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DGlobalSymtab.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DGlobalSymtab.hpp" + +namespace xo { namespace scm { class IGCObject_DGlobalSymtab; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DGlobalSymtab + **/ + class IGCObject_DGlobalSymtab { + public: + /** @defgroup scm-gcobject-dglobalsymtab-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dglobalsymtab-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DGlobalSymtab & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DGlobalSymtab & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DGlobalSymtab & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/symtab/IPrintable_DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/IPrintable_DGlobalSymtab.hpp new file mode 100644 index 00000000..3e6d065c --- /dev/null +++ b/xo-expression2/include/xo/expression2/symtab/IPrintable_DGlobalSymtab.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DGlobalSymtab.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DGlobalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DGlobalSymtab.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DGlobalSymtab.hpp" + +namespace xo { namespace scm { class IPrintable_DGlobalSymtab; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DGlobalSymtab + **/ + class IPrintable_DGlobalSymtab { + public: + /** @defgroup scm-printable-dglobalsymtab-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dglobalsymtab-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DGlobalSymtab & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DGlobalSymtab.hpp new file mode 100644 index 00000000..64f90528 --- /dev/null +++ b/xo-expression2/include/xo/expression2/symtab/ISymbolTable_DGlobalSymtab.hpp @@ -0,0 +1,60 @@ +/** @file ISymbolTable_DGlobalSymtab.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISymbolTable_DGlobalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISymbolTable_DGlobalSymtab.json5] + **/ + +#pragma once + +#include "SymbolTable.hpp" +#include "DGlobalSymtab.hpp" + +namespace xo { namespace scm { class ISymbolTable_DGlobalSymtab; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISymbolTable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISymbolTable_DGlobalSymtab + **/ + class ISymbolTable_DGlobalSymtab { + public: + /** @defgroup scm-symboltable-dglobalsymtab-type-traits **/ + ///@{ + using Copaque = xo::scm::ASymbolTable::Copaque; + using Opaque = xo::scm::ASymbolTable::Opaque; + ///@} + /** @defgroup scm-symboltable-dglobalsymtab-methods **/ + ///@{ + // const methods + /** true iff this is toplevel (global) symbol table. **/ + static bool is_global_symtab(const DGlobalSymtab & self) noexcept; + /** report ingredients needed to address variable at runtime. **/ + static Binding lookup_binding(const DGlobalSymtab & self, const DUniqueString * sym) noexcept; + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 749910e4..8aafa01a 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -58,6 +58,9 @@ set(SELF_SRCS IPrintable_DLocalSymtab.cpp DGlobalSymtab.cpp + ISymbolTable_DGlobalSymtab.cpp + IGCObject_DGlobalSymtab.cpp + IPrintable_DGlobalSymtab.cpp StringTable.cpp diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp index c9897670..70b953dd 100644 --- a/xo-expression2/src/expression2/DGlobalSymtab.cpp +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -168,6 +168,18 @@ namespace xo { return this->shallow_size(); } + // ----- printable facet ----- + + bool + DGlobalSymtab::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DGlobalSymtab", + refrtag("nsym", vars_->size()), + refrtag("capacity", vars_->capacity())); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/src/expression2/IGCObject_DGlobalSymtab.cpp b/xo-expression2/src/expression2/IGCObject_DGlobalSymtab.cpp new file mode 100644 index 00000000..d59e6bbf --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DGlobalSymtab.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DGlobalSymtab.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DGlobalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DGlobalSymtab.json5] +**/ + +#include "symtab/IGCObject_DGlobalSymtab.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DGlobalSymtab::shallow_size(const DGlobalSymtab & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DGlobalSymtab::shallow_copy(const DGlobalSymtab & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DGlobalSymtab::forward_children(DGlobalSymtab & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DGlobalSymtab.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DGlobalSymtab.cpp b/xo-expression2/src/expression2/IPrintable_DGlobalSymtab.cpp new file mode 100644 index 00000000..35ecf6e7 --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DGlobalSymtab.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DGlobalSymtab.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DGlobalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DGlobalSymtab.json5] +**/ + +#include "symtab/IPrintable_DGlobalSymtab.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DGlobalSymtab::pretty(const DGlobalSymtab & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DGlobalSymtab.cpp */ diff --git a/xo-expression2/src/expression2/ISymbolTable_DGlobalSymtab.cpp b/xo-expression2/src/expression2/ISymbolTable_DGlobalSymtab.cpp new file mode 100644 index 00000000..b735a6fb --- /dev/null +++ b/xo-expression2/src/expression2/ISymbolTable_DGlobalSymtab.cpp @@ -0,0 +1,34 @@ +/** @file ISymbolTable_DGlobalSymtab.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISymbolTable_DGlobalSymtab.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISymbolTable_DGlobalSymtab.json5] +**/ + +#include "symtab/ISymbolTable_DGlobalSymtab.hpp" + +namespace xo { + namespace scm { + auto + ISymbolTable_DGlobalSymtab::is_global_symtab(const DGlobalSymtab & self) noexcept -> bool + { + return self.is_global_symtab(); + } + + auto + ISymbolTable_DGlobalSymtab::lookup_binding(const DGlobalSymtab & self, const DUniqueString * sym) noexcept -> Binding + { + return self.lookup_binding(sym); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISymbolTable_DGlobalSymtab.cpp */ diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index a3a4b520..c563c9da 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -6,8 +6,8 @@ #include "expression2_register_facets.hpp" #include -#include -#include +//#include +//#include #include //#include @@ -101,6 +101,10 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // until we register facets TypeRegistry::register_type(); From 9fd5bebae9a3e20afcb183b0f4447cd8bc5e1d35 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 19:07:37 -0500 Subject: [PATCH 241/258] xo-reader2: bugfix: detecting toplevel for upsert global var --- xo-reader2/src/reader2/DDefineSsm.cpp | 2 + xo-reader2/src/reader2/ParserStateMachine.cpp | 44 +++++++++++++++++-- xo-reader2/src/reader2/SchematikaParser.cpp | 2 +- xo-reader2/utest/SchematikaParser.test.cpp | 2 +- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 78e29250..aae07b90 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -678,6 +678,8 @@ namespace xo { Super::on_parsed_expression_with_token(expr, tk, p_psm); } + // ----- printable facet ----- + bool DDefineSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 1223abe2..0b2367ad 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -6,6 +6,8 @@ #include "ParserStateMachine.hpp" #include "ParserStack.hpp" #include "SyntaxStateMachine.hpp" +#include "ToplevelSeqSsm.hpp" +#include "DefineSsm.hpp" #include #include #include @@ -39,16 +41,52 @@ namespace xo { bool ParserStateMachine::is_at_toplevel() const noexcept { - return ((stack_ == nullptr) - || (stack_->parent() == nullptr)); + /* top-level alwyas has DToplevelSeqSsm */ + + ParserStack * s = stack_; + + if (s) { + auto def = obj::from(s->top()); + + if (def) { + /* carve-out for top-level DefineSsm: report 'at top-level' when + * that top-level DefineSsm is on the stack, so we detect + * this condition inside DefineSsm's event handling + */ + s = stack_->parent(); + } + + if (s && s->parent() == nullptr) { + auto top = obj::from(s->top()); + + return top; + } + } else { + /** this isn't a normal operating state, still need a batch/interactive toplevel seq. + * just the same seems better to call it top-level + **/ + return true; + } + + return false; } bool ParserStateMachine::has_incomplete_expr() const noexcept { + scope log(XO_DEBUG(debug_flag_)); + // don't count toplevel expression - return !(this->is_at_toplevel()); + ParserStack * s = stack_; + + if (s) { + auto top = obj::from(s->top()); + + return !top; + } else { + return false; + } } obj diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 9272cfc2..1bb188cb 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -41,7 +41,7 @@ namespace xo { bool SchematikaParser::has_incomplete_expr() const { - return !(this->is_at_toplevel()); + return psm_.has_incomplete_expr(); } obj diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index a0557fa6..665342dc 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -232,7 +232,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = false; + constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); From 1f85d0bbbf029266de6a7b8df4386e444b2e6d19 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 19:48:14 -0500 Subject: [PATCH 242/258] xo-expression2: upsert global vars works in DDefineSsm --- .../include/xo/expression2/DGlobalSymtab.hpp | 11 +-- .../include/xo/expression2/DVariable.hpp | 1 + .../src/expression2/DGlobalSymtab.cpp | 94 ++++++++++++------- xo-reader2/src/reader2/ParserStateMachine.cpp | 5 +- 4 files changed, 70 insertions(+), 41 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 6ae8895b..63a2a91f 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -65,13 +65,12 @@ namespace xo { /** @defgroup scm-globalsymtab-general-methods general methods **/ ///@{ - /** establish binding for @p sym, with type described by @p typeref, - * replacing existing global (if present) with the same name. - * Use memory from @p mm to create variable-expr + /** update this symtab to associate @p var with @c var->name(). + * If there was a previous variable with the same name, + * replace it with @p var. **/ - DVariable * establish_variable(obj mm, - const DUniqueString * sym, - TypeRef typeref); + void upsert_variable(obj mm, + DVariable * var); ///@} /** @defgroup scm-globalsymtab-symboltable-facet symboltable facet **/ diff --git a/xo-expression2/include/xo/expression2/DVariable.hpp b/xo-expression2/include/xo/expression2/DVariable.hpp index 3c89cc58..29253097 100644 --- a/xo-expression2/include/xo/expression2/DVariable.hpp +++ b/xo-expression2/include/xo/expression2/DVariable.hpp @@ -48,6 +48,7 @@ namespace xo { Binding path() const { return path_; } void assign_name(const DUniqueString * name) { this->name_ = name; } + void assign_path(Binding b) { this->path_ = b; } /** @defgroup scm-variable-expression-facet **/ ///@{ diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp index 70b953dd..89d10f32 100644 --- a/xo-expression2/src/expression2/DGlobalSymtab.cpp +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -65,6 +65,65 @@ namespace xo { return var.data(); } + void + DGlobalSymtab::upsert_variable(obj mm, + DVariable * var) + { + // It's possible there's already a global variable + // with the same name. + // + // For example redefining a variable in an interactive session. + // In this case use the established binding. + // + DVariable * existing = this->lookup_variable(var->name()); + + if (existing) { + if (existing == var) { + // impossible, but.. noop, right? + return; + } + + // adopt the existing binding + var->assign_path(existing->path()); + + // stash new definition (possibly has different type), + // replacing previous one + // + (*vars_)[existing->path().j_slot()] = obj(var); + } else { + DArray::size_type n = vars_->size(); + + // NOTE: expansion of var_ array here is moot at present (Feb 2026), + // since the feature isn't yet implemented in ArenaHashMap + + /** make sure vars_ has room **/ + if (n == vars_->capacity()) { + // DArray is out of room. Reallocate with more capacity + DArray * vars_2x = DArray::copy(mm, vars_, vars_->capacity() * 2); + + if (!vars_2x) { + assert(false); + + // in any case, we can't make progress + return; + } + + this->vars_ = vars_2x; + } + + /** now we know binding for var **/ + Binding binding = Binding::global(n); + + var->assign_path(binding); + + // need slot# in .map_ for this unique symbol + (*map_)[var->name()] = binding.j_slot(); + + vars_->push_back(obj(var)); + } + } + +#ifdef NOT_USING // don't know if we need this path DVariable * DGlobalSymtab::establish_variable(obj mm, const DUniqueString * sym, @@ -75,43 +134,12 @@ namespace xo { if (!var) { assert(vars_); - DArray::size_type n = vars_->size(); - - // NOTE: expansion here is moot at present (Feb 2026). - // Not implemented in ArenaHashMap - - /** make sure vars_ has room **/ - if (n == vars_->capacity()) { - // reallocate with more capacity - DArray * vars_2x = DArray::copy(mm, vars_, vars_->capacity() * 2); - - assert(vars_2x); - - this->vars_ = vars_2x; - } - - /** create new variable **/ - Binding binding = Binding::global(n); - var = DVariable::make(mm, sym, typeref, binding); - - if (!var) { - // something terribly wrong - assert(false); - return var; - } - - assert(map_->size() < map_->capacity()); - - (*map_)[sym] = binding.j_slot(); - - bool ok = vars_->push_back(obj(var)); - - if (!ok) - assert(false); + xxx; } return var; } +#endif Binding DGlobalSymtab::lookup_binding(const DUniqueString * sym) const noexcept diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 0b2367ad..6df9133b 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -229,8 +229,9 @@ namespace xo { void ParserStateMachine::upsert_var(DVariable * var) { - scope log(XO_DEBUG(true), "stub impl"); - log && log(xtag("var", std::string_view(*(var->name())))); + assert(global_symtab_); + + global_symtab_->upsert_variable(this->expr_alloc(), var); } void From 9c33fa5d9f1eee29a9bf90993c19592d3b27adee Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 22:33:32 -0500 Subject: [PATCH 243/258] xo-facet: move output-hpp-dir + subdir to idl/*.json5 --- xo-alloc2/idl/ResourceVisitor.json5 | 2 ++ xo-expression2/idl/Expression.json5 | 2 ++ .../idl/IExpression_DApplyExpr.json5 | 2 ++ .../idl/IExpression_DConstant.json5 | 2 ++ .../idl/IExpression_DDefineExpr.json5 | 2 ++ .../idl/IExpression_DIfElseExpr.json5 | 2 ++ .../idl/IExpression_DLambdaExpr.json5 | 2 ++ .../idl/IExpression_DSequenceExpr.json5 | 2 ++ xo-expression2/idl/IExpression_DVarRef.json5 | 2 ++ .../idl/IExpression_DVariable.json5 | 2 ++ xo-expression2/idl/IGCObject_DApplyExpr.json5 | 2 ++ xo-expression2/idl/IGCObject_DConstant.json5 | 2 ++ .../idl/IGCObject_DGlobalSymtab.json5 | 2 ++ .../idl/IGCObject_DIfElseExpr.json5 | 2 ++ .../idl/IGCObject_DLambdaExpr.json5 | 2 ++ .../idl/IGCObject_DLocalSymtab.json5 | 2 ++ .../idl/IGCObject_DSequenceExpr.json5 | 2 ++ .../idl/IGCObject_DUniqueString.json5 | 2 ++ xo-expression2/idl/IGCObject_DVarRef.json5 | 2 ++ xo-expression2/idl/IGCObject_DVariable.json5 | 2 ++ .../idl/IPrintable_DApplyExpr.json5 | 2 ++ xo-expression2/idl/IPrintable_DConstant.json5 | 2 ++ .../idl/IPrintable_DDefineExpr.json5 | 2 ++ .../idl/IPrintable_DGlobalSymtab.json5 | 2 ++ .../idl/IPrintable_DIfElseExpr.json5 | 2 ++ .../idl/IPrintable_DLambdaExpr.json5 | 2 ++ .../idl/IPrintable_DLocalSymtab.json5 | 2 ++ .../idl/IPrintable_DSequenceExpr.json5 | 2 ++ .../idl/IPrintable_DUniqueString.json5 | 2 ++ xo-expression2/idl/IPrintable_DVarRef.json5 | 2 ++ xo-expression2/idl/IPrintable_DVariable.json5 | 2 ++ .../idl/ISymbolTable_DGlobalSymtab.json5 | 2 ++ .../idl/ISymbolTable_DLocalSymtab.json5 | 2 ++ xo-expression2/idl/SymbolTable.json5 | 2 ++ xo-facet/codegen/genfacet | 22 +++++++++++++------ xo-gc/idl/GCObject.json5 | 2 ++ xo-interpreter2/idl/IGCObject_DClosure.json5 | 2 ++ xo-interpreter2/idl/IGCObject_DLocalEnv.json5 | 2 ++ .../idl/IGCObject_DVsmApplyClosureFrame.json5 | 2 ++ .../idl/IGCObject_DVsmApplyFrame.json5 | 2 ++ .../idl/IGCObject_DVsmEvalArgsFrame.json5 | 2 ++ .../idl/IGCObject_DVsmIfElseContFrame.json5 | 2 ++ .../idl/IGCObject_DVsmSeqContFrame.json5 | 2 ++ xo-interpreter2/idl/IPrintable_DClosure.json5 | 2 ++ .../idl/IPrintable_DLocalEnv.json5 | 2 ++ .../IPrintable_DVsmApplyClosureFrame.json5 | 2 ++ .../idl/IPrintable_DVsmApplyFrame.json5 | 2 ++ .../idl/IPrintable_DVsmEvalArgsFrame.json5 | 2 ++ .../idl/IPrintable_DVsmIfElseContFrame.json5 | 2 ++ .../idl/IPrintable_DVsmSeqContFrame.json5 | 2 ++ xo-interpreter2/idl/IProcedure_DClosure.json5 | 2 ++ .../idl/IRuntimeContext_DVsmRcx.json5 | 2 ++ xo-object2/idl/IGCObject_DArray.json5 | 2 ++ xo-object2/idl/IGCObject_DBoolean.json5 | 2 ++ xo-object2/idl/IGCObject_DFloat.json5 | 2 ++ xo-object2/idl/IGCObject_DInteger.json5 | 2 ++ xo-object2/idl/IGCObject_DList.json5 | 2 ++ xo-object2/idl/IGCObject_DRuntimeError.json5 | 2 ++ xo-object2/idl/IGCObject_DString.json5 | 2 ++ xo-object2/idl/IPrintable_DArray.json5 | 2 ++ xo-object2/idl/IPrintable_DBoolean.json5 | 2 ++ xo-object2/idl/IPrintable_DFloat.json5 | 2 ++ xo-object2/idl/IPrintable_DInteger.json5 | 2 ++ xo-object2/idl/IPrintable_DList.json5 | 2 ++ xo-object2/idl/IPrintable_DRuntimeError.json5 | 2 ++ xo-object2/idl/IPrintable_DString.json5 | 2 ++ xo-object2/idl/ISequence_DArray.json5 | 2 ++ xo-object2/idl/ISequence_DList.json5 | 2 ++ xo-object2/idl/Sequence.json5 | 2 ++ xo-printable2/idl/Printable.json5 | 2 ++ .../IGCObject_DPrimitive_gco_2_gco_gco.json5 | 2 ++ .../IPrintable_DPrimitive_gco_2_gco_gco.json5 | 2 ++ .../IProcedure_DPrimitive_gco_2_gco_gco.json5 | 2 ++ .../idl/IRuntimeContext_DSimpleRcx.json5 | 2 ++ xo-procedure2/idl/Procedure.json5 | 2 ++ xo-procedure2/idl/RuntimeContext.json5 | 2 ++ xo-reader2/idl/IPrintable_DApplySsm.json5 | 2 ++ xo-reader2/idl/IPrintable_DDefineSsm.json5 | 2 ++ .../idl/IPrintable_DExpectExprSsm.json5 | 2 ++ .../idl/IPrintable_DExpectFormalArgSsm.json5 | 2 ++ .../IPrintable_DExpectFormalArglistSsm.json5 | 2 ++ .../idl/IPrintable_DExpectSymbolSsm.json5 | 2 ++ .../idl/IPrintable_DExpectTypeSsm.json5 | 2 ++ xo-reader2/idl/IPrintable_DIfElseSsm.json5 | 2 ++ xo-reader2/idl/IPrintable_DLambdaSsm.json5 | 2 ++ xo-reader2/idl/IPrintable_DParenSsm.json5 | 2 ++ xo-reader2/idl/IPrintable_DProgressSsm.json5 | 2 ++ xo-reader2/idl/IPrintable_DSequenceSsm.json5 | 2 ++ .../idl/IPrintable_DToplevelSeqSsm.json5 | 2 ++ .../idl/ISyntaxStateMachine_DApplySsm.json5 | 2 ++ .../idl/ISyntaxStateMachine_DDefineSsm.json5 | 2 ++ .../ISyntaxStateMachine_DExpectExprSsm.json5 | 2 ++ ...ntaxStateMachine_DExpectFormalArgSsm.json5 | 2 ++ ...StateMachine_DExpectFormalArglistSsm.json5 | 2 ++ ...ISyntaxStateMachine_DExpectSymbolSsm.json5 | 2 ++ .../ISyntaxStateMachine_DExpectTypeSsm.json5 | 2 ++ .../idl/ISyntaxStateMachine_DIfElseSsm.json5 | 2 ++ .../idl/ISyntaxStateMachine_DLambdaSsm.json5 | 2 ++ .../idl/ISyntaxStateMachine_DParenSsm.json5 | 2 ++ .../ISyntaxStateMachine_DProgressSsm.json5 | 2 ++ .../ISyntaxStateMachine_DSequenceSsm.json5 | 2 ++ .../ISyntaxStateMachine_DToplevelSeqSsm.json5 | 2 ++ xo-reader2/idl/SyntaxStateMachine.json5 | 2 ++ 103 files changed, 219 insertions(+), 7 deletions(-) diff --git a/xo-alloc2/idl/ResourceVisitor.json5 b/xo-alloc2/idl/ResourceVisitor.json5 index 79c9d81b..54effc41 100644 --- a/xo-alloc2/idl/ResourceVisitor.json5 +++ b/xo-alloc2/idl/ResourceVisitor.json5 @@ -1,6 +1,8 @@ { mode: "facet", output_cpp_dir: "src/alloc2", + output_hpp_dir: "include/xo/alloc2", + output_impl_subdir: "visitor", includes: [ "\"Allocator.hpp\"" ], diff --git a/xo-expression2/idl/Expression.json5 b/xo-expression2/idl/Expression.json5 index 5391e89a..66c60def 100644 --- a/xo-expression2/idl/Expression.json5 +++ b/xo-expression2/idl/Expression.json5 @@ -1,6 +1,8 @@ { mode: "facet", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"TypeRef.hpp\"", "\"exprtype.hpp\"", ""], diff --git a/xo-expression2/idl/IExpression_DApplyExpr.json5 b/xo-expression2/idl/IExpression_DApplyExpr.json5 index 353a7147..29762364 100644 --- a/xo-expression2/idl/IExpression_DApplyExpr.json5 +++ b/xo-expression2/idl/IExpression_DApplyExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DConstant.json5 b/xo-expression2/idl/IExpression_DConstant.json5 index 3e491f2b..bbbcc402 100644 --- a/xo-expression2/idl/IExpression_DConstant.json5 +++ b/xo-expression2/idl/IExpression_DConstant.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DDefineExpr.json5 b/xo-expression2/idl/IExpression_DDefineExpr.json5 index 28940c7b..8fd6149f 100644 --- a/xo-expression2/idl/IExpression_DDefineExpr.json5 +++ b/xo-expression2/idl/IExpression_DDefineExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DIfElseExpr.json5 b/xo-expression2/idl/IExpression_DIfElseExpr.json5 index 39c6cd70..431fd60a 100644 --- a/xo-expression2/idl/IExpression_DIfElseExpr.json5 +++ b/xo-expression2/idl/IExpression_DIfElseExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DLambdaExpr.json5 b/xo-expression2/idl/IExpression_DLambdaExpr.json5 index 675d6d9f..36aa9bb4 100644 --- a/xo-expression2/idl/IExpression_DLambdaExpr.json5 +++ b/xo-expression2/idl/IExpression_DLambdaExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DSequenceExpr.json5 b/xo-expression2/idl/IExpression_DSequenceExpr.json5 index 5c5f1b9a..71b13aba 100644 --- a/xo-expression2/idl/IExpression_DSequenceExpr.json5 +++ b/xo-expression2/idl/IExpression_DSequenceExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DVarRef.json5 b/xo-expression2/idl/IExpression_DVarRef.json5 index 89ee50d8..7b50c7fb 100644 --- a/xo-expression2/idl/IExpression_DVarRef.json5 +++ b/xo-expression2/idl/IExpression_DVarRef.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IExpression_DVariable.json5 b/xo-expression2/idl/IExpression_DVariable.json5 index f22f7d4b..c68a9609 100644 --- a/xo-expression2/idl/IExpression_DVariable.json5 +++ b/xo-expression2/idl/IExpression_DVariable.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "\"Expression.hpp\"" ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/IGCObject_DApplyExpr.json5 b/xo-expression2/idl/IGCObject_DApplyExpr.json5 index 9946116a..60f997c8 100644 --- a/xo-expression2/idl/IGCObject_DApplyExpr.json5 +++ b/xo-expression2/idl/IGCObject_DApplyExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DConstant.json5 b/xo-expression2/idl/IGCObject_DConstant.json5 index 1c97456e..961f39bb 100644 --- a/xo-expression2/idl/IGCObject_DConstant.json5 +++ b/xo-expression2/idl/IGCObject_DConstant.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DGlobalSymtab.json5 b/xo-expression2/idl/IGCObject_DGlobalSymtab.json5 index dac8ebac..ac779ec2 100644 --- a/xo-expression2/idl/IGCObject_DGlobalSymtab.json5 +++ b/xo-expression2/idl/IGCObject_DGlobalSymtab.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "symtab", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DIfElseExpr.json5 b/xo-expression2/idl/IGCObject_DIfElseExpr.json5 index 751c0b9f..6fb8c07a 100644 --- a/xo-expression2/idl/IGCObject_DIfElseExpr.json5 +++ b/xo-expression2/idl/IGCObject_DIfElseExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DLambdaExpr.json5 b/xo-expression2/idl/IGCObject_DLambdaExpr.json5 index 506feb48..a0f494ff 100644 --- a/xo-expression2/idl/IGCObject_DLambdaExpr.json5 +++ b/xo-expression2/idl/IGCObject_DLambdaExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DLocalSymtab.json5 b/xo-expression2/idl/IGCObject_DLocalSymtab.json5 index ca815ee0..ec8260a0 100644 --- a/xo-expression2/idl/IGCObject_DLocalSymtab.json5 +++ b/xo-expression2/idl/IGCObject_DLocalSymtab.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "symtab", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DSequenceExpr.json5 b/xo-expression2/idl/IGCObject_DSequenceExpr.json5 index c3bd7458..1fc67e48 100644 --- a/xo-expression2/idl/IGCObject_DSequenceExpr.json5 +++ b/xo-expression2/idl/IGCObject_DSequenceExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DUniqueString.json5 b/xo-expression2/idl/IGCObject_DUniqueString.json5 index cb16d6a2..4f79e9de 100644 --- a/xo-expression2/idl/IGCObject_DUniqueString.json5 +++ b/xo-expression2/idl/IGCObject_DUniqueString.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DVarRef.json5 b/xo-expression2/idl/IGCObject_DVarRef.json5 index 1a46f47e..6c1bad33 100644 --- a/xo-expression2/idl/IGCObject_DVarRef.json5 +++ b/xo-expression2/idl/IGCObject_DVarRef.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-expression2/idl/IGCObject_DVariable.json5 b/xo-expression2/idl/IGCObject_DVariable.json5 index 84a47d01..6bea1dc3 100644 --- a/xo-expression2/idl/IGCObject_DVariable.json5 +++ b/xo-expression2/idl/IGCObject_DVariable.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-expression2/idl/IPrintable_DApplyExpr.json5 b/xo-expression2/idl/IPrintable_DApplyExpr.json5 index 88a3fef7..f9d3f17d 100644 --- a/xo-expression2/idl/IPrintable_DApplyExpr.json5 +++ b/xo-expression2/idl/IPrintable_DApplyExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DConstant.json5 b/xo-expression2/idl/IPrintable_DConstant.json5 index 9e4e1ad0..ca9d7948 100644 --- a/xo-expression2/idl/IPrintable_DConstant.json5 +++ b/xo-expression2/idl/IPrintable_DConstant.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DDefineExpr.json5 b/xo-expression2/idl/IPrintable_DDefineExpr.json5 index 89c2fdff..c706817d 100644 --- a/xo-expression2/idl/IPrintable_DDefineExpr.json5 +++ b/xo-expression2/idl/IPrintable_DDefineExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DGlobalSymtab.json5 b/xo-expression2/idl/IPrintable_DGlobalSymtab.json5 index 151f8a90..d0242e8c 100644 --- a/xo-expression2/idl/IPrintable_DGlobalSymtab.json5 +++ b/xo-expression2/idl/IPrintable_DGlobalSymtab.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "symtab", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DIfElseExpr.json5 b/xo-expression2/idl/IPrintable_DIfElseExpr.json5 index 90f02307..208e7b06 100644 --- a/xo-expression2/idl/IPrintable_DIfElseExpr.json5 +++ b/xo-expression2/idl/IPrintable_DIfElseExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DLambdaExpr.json5 b/xo-expression2/idl/IPrintable_DLambdaExpr.json5 index 60e0397e..89b07d1c 100644 --- a/xo-expression2/idl/IPrintable_DLambdaExpr.json5 +++ b/xo-expression2/idl/IPrintable_DLambdaExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DLocalSymtab.json5 b/xo-expression2/idl/IPrintable_DLocalSymtab.json5 index 5d48e5f4..15087c3d 100644 --- a/xo-expression2/idl/IPrintable_DLocalSymtab.json5 +++ b/xo-expression2/idl/IPrintable_DLocalSymtab.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "symtab", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DSequenceExpr.json5 b/xo-expression2/idl/IPrintable_DSequenceExpr.json5 index 1b45094f..0cfe76c9 100644 --- a/xo-expression2/idl/IPrintable_DSequenceExpr.json5 +++ b/xo-expression2/idl/IPrintable_DSequenceExpr.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DUniqueString.json5 b/xo-expression2/idl/IPrintable_DUniqueString.json5 index d640ce9c..ba094879 100644 --- a/xo-expression2/idl/IPrintable_DUniqueString.json5 +++ b/xo-expression2/idl/IPrintable_DUniqueString.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DVarRef.json5 b/xo-expression2/idl/IPrintable_DVarRef.json5 index 0d73c1d9..106b41d1 100644 --- a/xo-expression2/idl/IPrintable_DVarRef.json5 +++ b/xo-expression2/idl/IPrintable_DVarRef.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/IPrintable_DVariable.json5 b/xo-expression2/idl/IPrintable_DVariable.json5 index 8e88cde0..779afd25 100644 --- a/xo-expression2/idl/IPrintable_DVariable.json5 +++ b/xo-expression2/idl/IPrintable_DVariable.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-expression2/idl/ISymbolTable_DGlobalSymtab.json5 b/xo-expression2/idl/ISymbolTable_DGlobalSymtab.json5 index 8cc1035b..ff148a2f 100644 --- a/xo-expression2/idl/ISymbolTable_DGlobalSymtab.json5 +++ b/xo-expression2/idl/ISymbolTable_DGlobalSymtab.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "symtab", includes: [ ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 b/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 index ff46c622..7cfcd75f 100644 --- a/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 +++ b/xo-expression2/idl/ISymbolTable_DLocalSymtab.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "symtab", includes: [ ], local_types: [ ], namespace1: "xo", diff --git a/xo-expression2/idl/SymbolTable.json5 b/xo-expression2/idl/SymbolTable.json5 index 9cd6e45b..b299bfe7 100644 --- a/xo-expression2/idl/SymbolTable.json5 +++ b/xo-expression2/idl/SymbolTable.json5 @@ -1,6 +1,8 @@ { mode: "facet", output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "symtab", includes: [ "\"Binding.hpp\"", "\"DUniqueString.hpp\"" diff --git a/xo-facet/codegen/genfacet b/xo-facet/codegen/genfacet index 062683be..6b2c6069 100755 --- a/xo-facet/codegen/genfacet +++ b/xo-facet/codegen/genfacet @@ -455,9 +455,6 @@ def main(): parser.add_argument('--input', required=True, help='input IDL JSON5 file') # --facet-dir: only with mode=implementation parser.add_argument('--facet-dir', required=False, help='base dir for facet json') - # --output-impl-hpp: putting this in .json5, will be able to drop this. - parser.add_argument('--output-impl-hpp', required=True, help='.hpp detail subdir') - parser.add_argument('--output-hpp', required=True, help='.hpp output directory') parser.add_argument('--output-cpp', required=False, help='.cpp output directory') args = parser.parse_args() @@ -465,12 +462,23 @@ def main(): idl_fname = args.input idl = load_idl(idl_fname) - output_hpp_dir = Path(args.output_hpp) + # output_hpp_dir: prefer IDL, fall back to CLI + if 'output_hpp_dir' in idl: + output_hpp_dir = Path(idl['output_hpp_dir']) + elif args.output_hpp: + output_hpp_dir = Path(args.output_hpp) + else: + parser.error("--output-hpp required when .json5 lacks output_hpp_dir") output_hpp_dir.mkdir(parents=False, exist_ok=True) - # TODO: output_impl_hpp_subdir: use idl['detail_subdir'] instead - output_impl_hpp_subdir = Path(args.output_impl_hpp) - output_impl_hpp_dir = Path(args.output_hpp) / output_impl_hpp_subdir + # output_impl_hpp_subdir: prefer IDL, fall back to CLI + if 'output_impl_subdir' in idl: + output_impl_hpp_subdir = Path(idl['output_impl_subdir']) + elif args.output_impl_hpp: + output_impl_hpp_subdir = Path(args.output_impl_hpp) + else: + parser.error("--output-impl-hpp required when .json5 lacks output_impl_subdir") + output_impl_hpp_dir = output_hpp_dir / output_impl_hpp_subdir output_impl_hpp_dir.mkdir(parents=False, exist_ok=True) if 'output_cpp_dir' in idl: diff --git a/xo-gc/idl/GCObject.json5 b/xo-gc/idl/GCObject.json5 index 242bea1e..7056f0b8 100644 --- a/xo-gc/idl/GCObject.json5 +++ b/xo-gc/idl/GCObject.json5 @@ -1,6 +1,8 @@ { mode: "facet", output_cpp_dir: "src/gc", + output_hpp_dir: "include/xo/gc", + output_impl_subdir: "detail", includes: [ "", "", diff --git a/xo-interpreter2/idl/IGCObject_DClosure.json5 b/xo-interpreter2/idl/IGCObject_DClosure.json5 index 9e99a16b..a9b5616a 100644 --- a/xo-interpreter2/idl/IGCObject_DClosure.json5 +++ b/xo-interpreter2/idl/IGCObject_DClosure.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 index fe8670f1..1fbce208 100644 --- a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 +++ b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 index 4cced151..2b68d579 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmApplyClosureFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 index 175b229e..ae284287 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmApplyFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 index 7d89a5ed..d36304b8 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmEvalArgsFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 index 537c9860..63617067 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmIfElseContFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "ifelse", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 index 6945f3df..d2b68020 100644 --- a/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 +++ b/xo-interpreter2/idl/IGCObject_DVsmSeqContFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "sequence", includes: [ "", "" diff --git a/xo-interpreter2/idl/IPrintable_DClosure.json5 b/xo-interpreter2/idl/IPrintable_DClosure.json5 index 2cfb3d33..2a1e2db9 100644 --- a/xo-interpreter2/idl/IPrintable_DClosure.json5 +++ b/xo-interpreter2/idl/IPrintable_DClosure.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 index 0a1205f5..79ef4c74 100644 --- a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 +++ b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 index ee4e8e64..45927399 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmApplyClosureFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 index c78e0b88..bef2fb62 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmApplyFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 index 1dd1672a..c43c5160 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmEvalArgsFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 index b9f70e6d..6490d444 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmIfElseContFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "ifelse", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 index 96b9c071..7b8e7ddd 100644 --- a/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 +++ b/xo-interpreter2/idl/IPrintable_DVsmSeqContFrame.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "sequence", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IProcedure_DClosure.json5 b/xo-interpreter2/idl/IProcedure_DClosure.json5 index d503f5c6..eec40c0c 100644 --- a/xo-interpreter2/idl/IProcedure_DClosure.json5 +++ b/xo-interpreter2/idl/IProcedure_DClosure.json5 @@ -1,5 +1,7 @@ { mode: "implementation", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ "", "", diff --git a/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 b/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 index 9fa3fe40..b52517ee 100644 --- a/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 +++ b/xo-interpreter2/idl/IRuntimeContext_DVsmRcx.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "detail", includes: [ //"", //"", diff --git a/xo-object2/idl/IGCObject_DArray.json5 b/xo-object2/idl/IGCObject_DArray.json5 index 3e1115e0..bef5bd62 100644 --- a/xo-object2/idl/IGCObject_DArray.json5 +++ b/xo-object2/idl/IGCObject_DArray.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "array", includes: [ "", "" diff --git a/xo-object2/idl/IGCObject_DBoolean.json5 b/xo-object2/idl/IGCObject_DBoolean.json5 index be131a38..c9aaf26b 100644 --- a/xo-object2/idl/IGCObject_DBoolean.json5 +++ b/xo-object2/idl/IGCObject_DBoolean.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "boolean", includes: [ "", "" diff --git a/xo-object2/idl/IGCObject_DFloat.json5 b/xo-object2/idl/IGCObject_DFloat.json5 index 2791de0b..eec1e3e3 100644 --- a/xo-object2/idl/IGCObject_DFloat.json5 +++ b/xo-object2/idl/IGCObject_DFloat.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "number", includes: [ "", "", diff --git a/xo-object2/idl/IGCObject_DInteger.json5 b/xo-object2/idl/IGCObject_DInteger.json5 index 6b865a4c..37d603e5 100644 --- a/xo-object2/idl/IGCObject_DInteger.json5 +++ b/xo-object2/idl/IGCObject_DInteger.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "number", includes: [ "", "" diff --git a/xo-object2/idl/IGCObject_DList.json5 b/xo-object2/idl/IGCObject_DList.json5 index e660b0c1..28fb3352 100644 --- a/xo-object2/idl/IGCObject_DList.json5 +++ b/xo-object2/idl/IGCObject_DList.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "list", includes: [ // "", // "" diff --git a/xo-object2/idl/IGCObject_DRuntimeError.json5 b/xo-object2/idl/IGCObject_DRuntimeError.json5 index 60d30cc7..cfcbe9f6 100644 --- a/xo-object2/idl/IGCObject_DRuntimeError.json5 +++ b/xo-object2/idl/IGCObject_DRuntimeError.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "error", includes: [ // "", // "" diff --git a/xo-object2/idl/IGCObject_DString.json5 b/xo-object2/idl/IGCObject_DString.json5 index 60c2165e..caf33fae 100644 --- a/xo-object2/idl/IGCObject_DString.json5 +++ b/xo-object2/idl/IGCObject_DString.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "string", includes: [ "", "" diff --git a/xo-object2/idl/IPrintable_DArray.json5 b/xo-object2/idl/IPrintable_DArray.json5 index eee19b52..b9bde4f4 100644 --- a/xo-object2/idl/IPrintable_DArray.json5 +++ b/xo-object2/idl/IPrintable_DArray.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "array", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DBoolean.json5 b/xo-object2/idl/IPrintable_DBoolean.json5 index 09245363..db949258 100644 --- a/xo-object2/idl/IPrintable_DBoolean.json5 +++ b/xo-object2/idl/IPrintable_DBoolean.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "boolean", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DFloat.json5 b/xo-object2/idl/IPrintable_DFloat.json5 index 427c5dce..d28680f0 100644 --- a/xo-object2/idl/IPrintable_DFloat.json5 +++ b/xo-object2/idl/IPrintable_DFloat.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "number", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DInteger.json5 b/xo-object2/idl/IPrintable_DInteger.json5 index 92c74376..478da579 100644 --- a/xo-object2/idl/IPrintable_DInteger.json5 +++ b/xo-object2/idl/IPrintable_DInteger.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "number", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DList.json5 b/xo-object2/idl/IPrintable_DList.json5 index 58b8ea82..a7a6bfb6 100644 --- a/xo-object2/idl/IPrintable_DList.json5 +++ b/xo-object2/idl/IPrintable_DList.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "list", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DRuntimeError.json5 b/xo-object2/idl/IPrintable_DRuntimeError.json5 index b9e291e0..a8404925 100644 --- a/xo-object2/idl/IPrintable_DRuntimeError.json5 +++ b/xo-object2/idl/IPrintable_DRuntimeError.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "error", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/IPrintable_DString.json5 b/xo-object2/idl/IPrintable_DString.json5 index 8caffaab..8510938b 100644 --- a/xo-object2/idl/IPrintable_DString.json5 +++ b/xo-object2/idl/IPrintable_DString.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "string", includes: [ "", "" ], local_types: [ ], diff --git a/xo-object2/idl/ISequence_DArray.json5 b/xo-object2/idl/ISequence_DArray.json5 index 1f09b0bb..265c3795 100644 --- a/xo-object2/idl/ISequence_DArray.json5 +++ b/xo-object2/idl/ISequence_DArray.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "array", includes: [ ], local_types: [ ], namespace1: "xo", diff --git a/xo-object2/idl/ISequence_DList.json5 b/xo-object2/idl/ISequence_DList.json5 index edf0e8dc..2ff69f04 100644 --- a/xo-object2/idl/ISequence_DList.json5 +++ b/xo-object2/idl/ISequence_DList.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "list", includes: [ "" ], local_types: [ ], namespace1: "xo", diff --git a/xo-object2/idl/Sequence.json5 b/xo-object2/idl/Sequence.json5 index 5c5139da..20271697 100644 --- a/xo-object2/idl/Sequence.json5 +++ b/xo-object2/idl/Sequence.json5 @@ -1,6 +1,8 @@ { mode: "facet", output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "sequence", includes: [""], // extra includes in Sequence.hpp, if any user_hpp_includes: [], diff --git a/xo-printable2/idl/Printable.json5 b/xo-printable2/idl/Printable.json5 index 41799c43..9926e73e 100644 --- a/xo-printable2/idl/Printable.json5 +++ b/xo-printable2/idl/Printable.json5 @@ -1,6 +1,8 @@ { mode: "facet", output_cpp_dir: "src/printable2", + output_hpp_dir: "include/xo/printable2", + output_impl_subdir: "detail", includes: [""], // extra includes in Printable.hpp user_hpp_includes: ["\"detail/ppdetail_Printable.hpp\""], diff --git a/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 index 79ee61d4..cd17ae4f 100644 --- a/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 +++ b/xo-procedure2/idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/procedure2", + output_hpp_dir: "include/xo/procedure2", + output_impl_subdir: "detail", includes: [ // "", diff --git a/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 index 5eb7bf34..ee3a1951 100644 --- a/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 +++ b/xo-procedure2/idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/procedure2", + output_hpp_dir: "include/xo/procedure2", + output_impl_subdir: "detail", includes: [ "", "", diff --git a/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 b/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 index b0a770fd..b50a8634 100644 --- a/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 +++ b/xo-procedure2/idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/procedure2", + output_hpp_dir: "include/xo/procedure2", + output_impl_subdir: "detail", includes: [ "", "", diff --git a/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 b/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 index 4765285d..324526f7 100644 --- a/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 +++ b/xo-procedure2/idl/IRuntimeContext_DSimpleRcx.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/procedure2", + output_hpp_dir: "include/xo/procedure2", + output_impl_subdir: "detail", includes: [ //"", //"", diff --git a/xo-procedure2/idl/Procedure.json5 b/xo-procedure2/idl/Procedure.json5 index 7933c3a2..b45227d0 100644 --- a/xo-procedure2/idl/Procedure.json5 +++ b/xo-procedure2/idl/Procedure.json5 @@ -5,6 +5,8 @@ { mode: "facet", output_cpp_dir: "src/procedure2", + output_hpp_dir: "include/xo/procedure2", + output_impl_subdir: "detail", // includes in ASyntaxStateMachine.hpp includes: [ "\"RuntimeContext.hpp\"", diff --git a/xo-procedure2/idl/RuntimeContext.json5 b/xo-procedure2/idl/RuntimeContext.json5 index c896cc64..07ed5b00 100644 --- a/xo-procedure2/idl/RuntimeContext.json5 +++ b/xo-procedure2/idl/RuntimeContext.json5 @@ -1,6 +1,8 @@ { mode: "facet", output_cpp_dir: "src/procedure2", + output_hpp_dir: "include/xo/procedure2", + output_impl_subdir: "detail", // includes in ARuntimeContext.hpp includes: [ "" diff --git a/xo-reader2/idl/IPrintable_DApplySsm.json5 b/xo-reader2/idl/IPrintable_DApplySsm.json5 index 5895578d..6f2a531d 100644 --- a/xo-reader2/idl/IPrintable_DApplySsm.json5 +++ b/xo-reader2/idl/IPrintable_DApplySsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DDefineSsm.json5 b/xo-reader2/idl/IPrintable_DDefineSsm.json5 index 3975396e..28463e92 100644 --- a/xo-reader2/idl/IPrintable_DDefineSsm.json5 +++ b/xo-reader2/idl/IPrintable_DDefineSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 b/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 index b6b0caa1..f5465709 100644 --- a/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 b/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 index 6b1bf863..73389166 100644 --- a/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 b/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 index 7f566150..1aa3c951 100644 --- a/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 b/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 index 1d003791..fee89873 100644 --- a/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 b/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 index 4c3b8964..463cb399 100644 --- a/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 +++ b/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DIfElseSsm.json5 b/xo-reader2/idl/IPrintable_DIfElseSsm.json5 index 9c54fc71..dbcdbb0a 100644 --- a/xo-reader2/idl/IPrintable_DIfElseSsm.json5 +++ b/xo-reader2/idl/IPrintable_DIfElseSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DLambdaSsm.json5 b/xo-reader2/idl/IPrintable_DLambdaSsm.json5 index 9f2187df..035f71f1 100644 --- a/xo-reader2/idl/IPrintable_DLambdaSsm.json5 +++ b/xo-reader2/idl/IPrintable_DLambdaSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DParenSsm.json5 b/xo-reader2/idl/IPrintable_DParenSsm.json5 index 9af85828..9750cb31 100644 --- a/xo-reader2/idl/IPrintable_DParenSsm.json5 +++ b/xo-reader2/idl/IPrintable_DParenSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DProgressSsm.json5 b/xo-reader2/idl/IPrintable_DProgressSsm.json5 index eb420da3..d3d298b1 100644 --- a/xo-reader2/idl/IPrintable_DProgressSsm.json5 +++ b/xo-reader2/idl/IPrintable_DProgressSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DSequenceSsm.json5 b/xo-reader2/idl/IPrintable_DSequenceSsm.json5 index 929060b0..f5c89aca 100644 --- a/xo-reader2/idl/IPrintable_DSequenceSsm.json5 +++ b/xo-reader2/idl/IPrintable_DSequenceSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 b/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 index 8349bb04..d3c78474 100644 --- a/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 +++ b/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "", "" ], local_types: [], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 index 2f08ccc5..bc433fdf 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 index 7aef2f5a..8b3fff2a 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 index 0b04e3d6..d1c78ad2 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 index 83627a07..e3486759 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 index 535e713f..019573d0 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 index 288b8256..49248b62 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 index 04617d60..68883ef0 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 index 23a4e35d..25feadde 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 index bd32a95b..413c64c8 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 index 9d24338d..7ea19fc0 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 index 9a141775..83c10717 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 index c9319948..e497ef7f 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 index e94779f5..7a91622f 100644 --- a/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 +++ b/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 @@ -1,6 +1,8 @@ { mode: "implementation", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", includes: [ "\"SyntaxStateMachine.hpp\"", "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], local_types: [ ], diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index d204a265..210a43a4 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -1,6 +1,8 @@ { mode: "facet", output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", // includes in ASyntaxStateMachine.hpp includes: [ "\"ParserStateMachine.hpp\"", From ff5186ed55af63743854f49fddc0dbcb7ec905f9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 22:43:24 -0500 Subject: [PATCH 244/258] xo-gc xo-cmake: simplify idl -> *.*pp codegen --- xo-cmake/cmake/xo_macros/xo_cxx.cmake | 58 +++------------------------ xo-facet/codegen/genfacet | 23 ++--------- xo-gc/CMakeLists.txt | 2 - 3 files changed, 9 insertions(+), 74 deletions(-) diff --git a/xo-cmake/cmake/xo_macros/xo_cxx.cmake b/xo-cmake/cmake/xo_macros/xo_cxx.cmake index 11d3560e..1550e282 100644 --- a/xo-cmake/cmake/xo_macros/xo_cxx.cmake +++ b/xo-cmake/cmake/xo_macros/xo_cxx.cmake @@ -1677,9 +1677,6 @@ function(xo_add_genfacet) TARGET # Name for this generation target FACET # facet name INPUT # Input .json5 file - OUTPUT_HPP_DIR # Directory for .hpp files - OUTPUT_IMPL_SUBDIR # Subdirectory name for impl headers - OUTPUT_CPP_DIR # Directory for .cpp files ) set(multiValueArgs "") @@ -1693,41 +1690,18 @@ function(xo_add_genfacet) if(NOT DEFINED GF_FACET) message(FATAL_ERROR "xo_add_genfacet: FACET is required") endif() - if(NOT DEFINED GF_OUTPUT_HPP_DIR) - message(FATAL_ERROR "xo_add_genfacet: OUTPUT_HPP_DIR is required") - endif() - if(NOT DEFINED GF_OUTPUT_IMPL_SUBDIR) - message(FATAL_ERROR "xo_add_genfacet: OUTPUT_IMPL_SUBDIR is required") - endif() find_program(GENFACET_EXECUTABLE NAMES genfacet HINTS ${CMAKE_SOURCE_DIR}/xo-facet/codegen DOC "path to xo genfacet code generator" REQUIRED) message(STATUS "GENFACET_EXECUTABLE=${GENFACET_EXECUTABLE}") - set(generatedFiles - ${GF_OUTPUT_HPP_DIR}/${GF_FACET}.hpp - ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/A${GF_FACET}.hpp - ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_Any.hpp - ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_Xfer.hpp - ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/R${GF_FACET}.hpp) - - set(_output_cpp_args "") - if(DEFINED GF_OUTPUT_CPP_DIR) - list(APPEND generatedFiles ${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_Any.cpp) - set(_output_cpp_args --output-cpp ${GF_OUTPUT_CPP_DIR}) - endif() - #message(STATUS "generatedFiles=${generatedFiles}") # Build the genfacet command add_custom_command( - OUTPUT ${generatedFiles} - COMMAND ${GENFACET_EXECUTABLE} - --input ${GF_INPUT} - --output-hpp ${GF_OUTPUT_HPP_DIR} - --output-impl-hpp ${GF_OUTPUT_IMPL_SUBDIR} - ${_output_cpp_args} + OUTPUT ${GF_INPUT}.out + COMMAND ${GENFACET_EXECUTABLE} --input ${GF_INPUT} DEPENDS ${GF_INPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Generating facet source files from ${GF_INPUT}" @@ -1735,7 +1709,7 @@ function(xo_add_genfacet) ) # Create a target for this generation - add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles}) + add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}) set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET}) endfunction() @@ -1770,12 +1744,6 @@ function(xo_add_genfacetimpl) if(NOT DEFINED GF_INPUT) message(FATAL_ERROR "xo_add_genfacetimpl: INPUT is required") endif() - if(NOT DEFINED GF_OUTPUT_HPP_DIR) - message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_HPP_DIR is required") - endif() - if(NOT DEFINED GF_OUTPUT_IMPL_SUBDIR) - message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_IMPL_SUBDIR is required") - endif() if(NOT DEFINED GF_FACET_DIR) if (NOT DEFINED GF_FACET_PKG) message(FATAL_ERROR "xo_add_genfacetimpl: FACET_PKG or FACET_DIR required") @@ -1791,26 +1759,12 @@ function(xo_add_genfacetimpl) REQUIRED) message(STATUS "GENFACET_EXECUTABLE=${GENFACET_EXECUTABLE}") - set(generatedFiles - ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_D${GF_REPR}.hpp) - - set(_output_cpp_args "") - if(DEFINED GF_OUTPUT_CPP_DIR) - list(APPEND generatedFiles ${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_D${GF_REPR}.cpp) - set(_output_cpp_args --output-cpp ${GF_OUTPUT_CPP_DIR}) - endif() - # Build the genfacet command. # But careful: can't have the same generated files in two different rules, # so need to remove overlaps here add_custom_command( - OUTPUT ${generatedFiles} - COMMAND ${GENFACET_EXECUTABLE} - --input ${GF_INPUT} - --facet-dir ${GF_FACET_DIR} - --output-hpp ${GF_OUTPUT_HPP_DIR} - --output-impl-hpp ${GF_OUTPUT_IMPL_SUBDIR} - ${_output_cpp_args} + OUTPUT ${GF_INPUT}.out + COMMAND ${GENFACET_EXECUTABLE} --input ${GF_INPUT} --facet-dir ${GF_FACET_DIR} DEPENDS ${GF_INPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Generating facet source files from ${GF_INPUT}" @@ -1818,7 +1772,7 @@ function(xo_add_genfacetimpl) ) # Create a target for this generation - add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles}) + add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}) set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET}) endfunction() diff --git a/xo-facet/codegen/genfacet b/xo-facet/codegen/genfacet index 6b2c6069..0d632ba0 100755 --- a/xo-facet/codegen/genfacet +++ b/xo-facet/codegen/genfacet @@ -455,38 +455,21 @@ def main(): parser.add_argument('--input', required=True, help='input IDL JSON5 file') # --facet-dir: only with mode=implementation parser.add_argument('--facet-dir', required=False, help='base dir for facet json') - parser.add_argument('--output-cpp', required=False, help='.cpp output directory') args = parser.parse_args() idl_fname = args.input idl = load_idl(idl_fname) - # output_hpp_dir: prefer IDL, fall back to CLI - if 'output_hpp_dir' in idl: - output_hpp_dir = Path(idl['output_hpp_dir']) - elif args.output_hpp: - output_hpp_dir = Path(args.output_hpp) - else: - parser.error("--output-hpp required when .json5 lacks output_hpp_dir") + output_hpp_dir = Path(idl['output_hpp_dir']) output_hpp_dir.mkdir(parents=False, exist_ok=True) # output_impl_hpp_subdir: prefer IDL, fall back to CLI - if 'output_impl_subdir' in idl: - output_impl_hpp_subdir = Path(idl['output_impl_subdir']) - elif args.output_impl_hpp: - output_impl_hpp_subdir = Path(args.output_impl_hpp) - else: - parser.error("--output-impl-hpp required when .json5 lacks output_impl_subdir") + output_impl_hpp_subdir = Path(idl['output_impl_subdir']) output_impl_hpp_dir = output_hpp_dir / output_impl_hpp_subdir output_impl_hpp_dir.mkdir(parents=False, exist_ok=True) - if 'output_cpp_dir' in idl: - output_cpp_dir = Path(idl['output_cpp_dir']) - elif args.output_cpp: - output_cpp_dir = Path(args.output_cpp) - else: - parser.error("--output-cpp required when .json5 lacks output_cpp_dir") + output_cpp_dir = Path(idl['output_cpp_dir']) output_cpp_dir.mkdir(parents=False, exist_ok=True) # setup jinja2 diff --git a/xo-gc/CMakeLists.txt b/xo-gc/CMakeLists.txt index 59f13d7e..df57b1e3 100644 --- a/xo-gc/CMakeLists.txt +++ b/xo-gc/CMakeLists.txt @@ -23,8 +23,6 @@ xo_add_genfacet( TARGET xo-gc-facet-gcobject FACET GCObject INPUT idl/GCObject.json5 - OUTPUT_HPP_DIR include/xo/gc - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- From 4653be78083a5cd8fffc786c1c76e8a5d1f9d49d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 22:45:05 -0500 Subject: [PATCH 245/258] xo-procedure2: simplify facet codegen --- xo-procedure2/CMakeLists.txt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/xo-procedure2/CMakeLists.txt b/xo-procedure2/CMakeLists.txt index 1eced319..a8b29a22 100644 --- a/xo-procedure2/CMakeLists.txt +++ b/xo-procedure2/CMakeLists.txt @@ -25,8 +25,6 @@ xo_add_genfacet( TARGET xo-procedure2-facet-procedure FACET Procedure INPUT idl/Procedure.json5 - OUTPUT_HPP_DIR include/xo/procedure2 - OUTPUT_IMPL_SUBDIR detail ) # note: manual target; generated code committed to git @@ -34,8 +32,6 @@ xo_add_genfacet( TARGET xo-procedure2-facet-runtimecontext FACET RuntimeContext INPUT idl/RuntimeContext.json5 - OUTPUT_HPP_DIR include/xo/procedure2 - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- @@ -46,8 +42,6 @@ xo_add_genfacetimpl( FACET RuntimeContext REPR DSimpleRcx INPUT idl/IRuntimeContext_DSimpleRcx.json5 - OUTPUT_HPP_DIR include/xo/procedure2 - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- @@ -59,8 +53,6 @@ xo_add_genfacetimpl( FACET Procedure REPR DPrimitive_gco_2_gco_gco INPUT idl/IProcedure_DPrimitive_gco_2_gco_gco.json5 - OUTPUT_HPP_DIR include/xo/procedure2 - OUTPUT_IMPL_SUBDIR detail ) # note: manual target; generated code committed to git @@ -70,8 +62,6 @@ xo_add_genfacetimpl( FACET GCObject REPR Primitive_gco_2_gco_gco INPUT idl/IGCObject_DPrimitive_gco_2_gco_gco.json5 - OUTPUT_HPP_DIR include/xo/procedure2 - OUTPUT_IMPL_SUBDIR detail ) # note: manual target; generated code committed to git @@ -81,8 +71,6 @@ xo_add_genfacetimpl( FACET Printable REPR Primitive_gco_2_gco_gco INPUT idl/IPrintable_DPrimitive_gco_2_gco_gco.json5 - OUTPUT_HPP_DIR include/xo/procedure2 - OUTPUT_IMPL_SUBDIR detail ) xo_add_genfacet_all(xo-procedure2-genfacet-all) From fec4ecd63048c066d707a5641a2199ab27a258da Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 22:46:34 -0500 Subject: [PATCH 246/258] xo-object2: simplify facet codegen --- xo-object2/CMakeLists.txt | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index 09faf6b7..4b0962de 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -23,8 +23,6 @@ xo_add_genfacet( TARGET xo-object2-facet-sequence FACET Sequence INPUT idl/Sequence.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR sequence ) # ---------------------------------------------------------------- @@ -36,8 +34,6 @@ xo_add_genfacetimpl( FACET Sequence REPR List INPUT idl/ISequence_DList.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR list ) # note: manual target; generated code committed to git @@ -47,8 +43,6 @@ xo_add_genfacetimpl( FACET Printable REPR List INPUT idl/IPrintable_DList.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR list ) # note: manual target; generated code committed to git @@ -58,8 +52,6 @@ xo_add_genfacetimpl( FACET GCObject REPR List INPUT idl/IGCObject_DList.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR list ) # ---------------------------------------------------------------- @@ -71,8 +63,6 @@ xo_add_genfacetimpl( FACET Printable REPR Boolean INPUT idl/IPrintable_DBoolean.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR boolean ) # note: manual target; generated code committed to git @@ -82,8 +72,6 @@ xo_add_genfacetimpl( FACET GCObject REPR Boolean INPUT idl/IGCObject_DBoolean.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR boolean ) # ---------------------------------------------------------------- @@ -95,8 +83,6 @@ xo_add_genfacetimpl( FACET Printable REPR Float INPUT idl/IPrintable_DFloat.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR number ) # note: manual target; generated code committed to git @@ -106,8 +92,6 @@ xo_add_genfacetimpl( FACET GCObject REPR Float INPUT idl/IGCObject_DFloat.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR number ) # ---------------------------------------------------------------- @@ -119,8 +103,6 @@ xo_add_genfacetimpl( FACET Printable REPR Integer INPUT idl/IPrintable_DInteger.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR number ) # note: manual target; generated code committed to git @@ -130,8 +112,6 @@ xo_add_genfacetimpl( FACET GCObject REPR Integer INPUT idl/IGCObject_DInteger.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR number ) # ---------------------------------------------------------------- @@ -143,8 +123,6 @@ xo_add_genfacetimpl( FACET Printable REPR String INPUT idl/IPrintable_DString.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR string ) # note: manual target; generated code committed to git @@ -154,8 +132,6 @@ xo_add_genfacetimpl( FACET GCObject REPR String INPUT idl/IGCObject_DString.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR string ) # ---------------------------------------------------------------- @@ -167,8 +143,6 @@ xo_add_genfacetimpl( FACET Sequence REPR Array INPUT idl/ISequence_DArray.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR array ) # note: manual target; generated code committed to git @@ -178,8 +152,6 @@ xo_add_genfacetimpl( FACET Printable REPR Array INPUT idl/IPrintable_DArray.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR array ) # note: manual target; generated code committed to git @@ -189,8 +161,6 @@ xo_add_genfacetimpl( FACET GCObject REPR Array INPUT idl/IGCObject_DArray.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR array ) # ---------------------------------------------------------------- @@ -202,9 +172,7 @@ xo_add_genfacetimpl( FACET Printable REPR RuntimeError INPUT idl/IPrintable_DRuntimeError.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR error -) + ) # note: manual target; generated code committed to git xo_add_genfacetimpl( @@ -213,8 +181,6 @@ xo_add_genfacetimpl( FACET GCObject REPR RuntimeError INPUT idl/IGCObject_DRuntimeError.json5 - OUTPUT_HPP_DIR include/xo/object2 - OUTPUT_IMPL_SUBDIR error ) # ---------------------------------------------------------------- From f9f770110e4faf4f4190c1c674b8251b13893f9f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 22:48:27 -0500 Subject: [PATCH 247/258] xo-reader2: streamline facet codegen --- xo-reader2/CMakeLists.txt | 54 --------------------------------------- 1 file changed, 54 deletions(-) diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index f098bd5e..9f05802f 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -29,8 +29,6 @@ xo_add_genfacet( TARGET xo-reader2-facet-syntaxstatemachine FACET SyntaxStateMachine INPUT idl/SyntaxStateMachine.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -42,8 +40,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ToplevelSeqSsm INPUT idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -53,8 +49,6 @@ xo_add_genfacetimpl( FACET Printable REPR ToplevelSeqSsm INPUT idl/IPrintable_DToplevelSeqSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -66,8 +60,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR DefineSsm INPUT idl/ISyntaxStateMachine_DDefineSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -77,8 +69,6 @@ xo_add_genfacetimpl( FACET Printable REPR DefineSsm INPUT idl/IPrintable_DDefineSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -90,8 +80,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR LambdaSsm INPUT idl/ISyntaxStateMachine_DLambdaSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -101,8 +89,6 @@ xo_add_genfacetimpl( FACET Printable REPR LambdaSsm INPUT idl/IPrintable_DLambdaSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -114,8 +100,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ParenSsm INPUT idl/ISyntaxStateMachine_DParenSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -125,8 +109,6 @@ xo_add_genfacetimpl( FACET Printable REPR ParenSsm INPUT idl/IPrintable_DParenSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -138,8 +120,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ExpectFormalArglistSsm INPUT idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -149,8 +129,6 @@ xo_add_genfacetimpl( FACET Printable REPR ExpectFormalArglistSsm INPUT idl/IPrintable_DExpectFormalArglistSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -162,8 +140,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ExpectFormalArgSsm INPUT idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -173,8 +149,6 @@ xo_add_genfacetimpl( FACET Printable REPR ExpectFormalArgSsm INPUT idl/IPrintable_DExpectFormalArgSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -186,8 +160,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR IfElseSsm INPUT idl/ISyntaxStateMachine_DIfElseSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -197,8 +169,6 @@ xo_add_genfacetimpl( FACET Printable REPR IfElseSsm INPUT idl/IPrintable_DIfElseSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -210,8 +180,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR SequenceSsm INPUT idl/ISyntaxStateMachine_DSequenceSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -221,8 +189,6 @@ xo_add_genfacetimpl( FACET Printable REPR SequenceSsm INPUT idl/IPrintable_DSequenceSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -234,8 +200,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ApplySsm INPUT idl/ISyntaxStateMachine_DApplySsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -245,8 +209,6 @@ xo_add_genfacetimpl( FACET Printable REPR ApplySsm INPUT idl/IPrintable_DApplySsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -258,8 +220,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ExpectSymbolSsm INPUT idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -269,8 +229,6 @@ xo_add_genfacetimpl( FACET Printable REPR ExpectSymbolSsm INPUT idl/IPrintable_DExpectSymbolSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -282,8 +240,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ExpectTypeSsm INPUT idl/ISyntaxStateMachine_DExpectTypeSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -293,8 +249,6 @@ xo_add_genfacetimpl( FACET Printable REPR ExpectTypeSsm INPUT idl/IPrintable_DExpectTypeSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -306,8 +260,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ExpectExprSsm INPUT idl/ISyntaxStateMachine_DExpectExprSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -317,8 +269,6 @@ xo_add_genfacetimpl( FACET Printable REPR ExpectExprSsm INPUT idl/IPrintable_DExpectExprSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- @@ -330,8 +280,6 @@ xo_add_genfacetimpl( FACET SyntaxStateMachine REPR ProgressSsm INPUT idl/ISyntaxStateMachine_DProgressSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # note: manual target; generated code committed to git @@ -341,8 +289,6 @@ xo_add_genfacetimpl( FACET Printable REPR ProgressSsm INPUT idl/IPrintable_DProgressSsm.json5 - OUTPUT_HPP_DIR include/xo/reader2 - OUTPUT_IMPL_SUBDIR ssm ) # ---------------------------------------------------------------- From a737b988536b85247504932f46fd38b4660cd7a1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 22:49:27 -0500 Subject: [PATCH 248/258] xo-interpreter2: streamline facet codegen --- xo-interpreter2/CMakeLists.txt | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 28debaa0..7ffbebc3 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -32,8 +32,6 @@ xo_add_genfacetimpl( FACET GCObject REPR VsmApplyFrame INPUT idl/IGCObject_DVsmApplyFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # note: manual target; generated code committed to git @@ -43,8 +41,6 @@ xo_add_genfacetimpl( FACET Printable REPR VsmApplyFrame INPUT idl/IPrintable_DVsmApplyFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- @@ -56,8 +52,6 @@ xo_add_genfacetimpl( FACET GCObject REPR VsmEvalArgsFrame INPUT idl/IGCObject_DVsmEvalArgsFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # note: manual target; generated code committed to git @@ -67,8 +61,6 @@ xo_add_genfacetimpl( FACET Printable REPR DVsmEvalArgsFrame INPUT idl/IPrintable_DVsmEvalArgsFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- @@ -80,8 +72,6 @@ xo_add_genfacetimpl( FACET GCObject REPR VsmApplyClosureFrame INPUT idl/IGCObject_DVsmApplyClosureFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # note: manual target; generated code committed to git @@ -91,8 +81,6 @@ xo_add_genfacetimpl( FACET Printable REPR DVsmApplyClosureFrame INPUT idl/IPrintable_DVsmApplyClosureFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- @@ -104,8 +92,6 @@ xo_add_genfacetimpl( FACET GCObject REPR VsmIfElseContFrame INPUT idl/IGCObject_DVsmIfElseContFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR ifelse ) # note: manual target; generated code committed to git @@ -115,8 +101,6 @@ xo_add_genfacetimpl( FACET Printable REPR VsmIfElseContFrame INPUT idl/IPrintable_DVsmIfElseContFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR ifelse ) # ---------------------------------------------------------------- @@ -128,8 +112,6 @@ xo_add_genfacetimpl( FACET GCObject REPR VsmSeqContFrame INPUT idl/IGCObject_DVsmSeqContFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR sequence ) # note: manual target; generated code committed to git @@ -139,8 +121,6 @@ xo_add_genfacetimpl( FACET Printable REPR DVsmSeqContFrame INPUT idl/IPrintable_DVsmSeqContFrame.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR sequence ) # ---------------------------------------------------------------- @@ -153,8 +133,6 @@ xo_add_genfacetimpl( # FACET Procedure # REPR Closure # INPUT idl/IProcedure_DClosure.json5 -# OUTPUT_HPP_DIR include/xo/interpreter2 -# OUTPUT_IMPL_SUBDIR detail #) # note: manual target; generated code committed to git @@ -164,8 +142,6 @@ xo_add_genfacetimpl( FACET GCObject REPR Closure INPUT idl/IGCObject_DClosure.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # note: manual target; generated code committed to git @@ -175,8 +151,6 @@ xo_add_genfacetimpl( FACET Printable REPR Closure INPUT idl/IPrintable_DClosure.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- @@ -188,8 +162,6 @@ xo_add_genfacetimpl( FACET GCObject REPR LocalEnv INPUT idl/IGCObject_DLocalEnv.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # note: manual target; generated code committed to git @@ -199,8 +171,6 @@ xo_add_genfacetimpl( FACET Printable REPR LocalEnv INPUT idl/IPrintable_DLocalEnv.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- @@ -211,8 +181,6 @@ xo_add_genfacetimpl( FACET RuntimeContext REPR DVsmRcx INPUT idl/IRuntimeContext_DVsmRcx.json5 - OUTPUT_HPP_DIR include/xo/interpreter2 - OUTPUT_IMPL_SUBDIR detail ) # ---------------------------------------------------------------- From 57f6f9073e2a9b7158b63f5b4f0255d76b9af9cf Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 16 Feb 2026 23:25:34 -0500 Subject: [PATCH 249/258] xo-reader2: utest with variable reference. Works ! --- xo-expression2/src/expression2/Binding.cpp | 2 +- .../src/expression2/DGlobalSymtab.cpp | 9 ++- xo-reader2/src/reader2/DToplevelSeqSsm.cpp | 21 +++--- xo-reader2/src/reader2/ParserStateMachine.cpp | 70 ++++++++++--------- xo-reader2/utest/SchematikaParser.test.cpp | 70 ++++++++++++++++++- 5 files changed, 125 insertions(+), 47 deletions(-) diff --git a/xo-expression2/src/expression2/Binding.cpp b/xo-expression2/src/expression2/Binding.cpp index 6802ba69..94be9b6b 100644 --- a/xo-expression2/src/expression2/Binding.cpp +++ b/xo-expression2/src/expression2/Binding.cpp @@ -27,7 +27,7 @@ namespace xo { Binding::print(std::ostream & os) const { if (i_link_ == c_link_global) { - os << "{path:global}"; + os << "{path:global:" << j_slot_ << "}"; } else if (i_link_ == c_link_sentinel) { os << "{path}"; } else { diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp index 89d10f32..38809a38 100644 --- a/xo-expression2/src/expression2/DGlobalSymtab.cpp +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -69,6 +69,8 @@ namespace xo { DGlobalSymtab::upsert_variable(obj mm, DVariable * var) { + scope log(XO_DEBUG(true), std::string_view(*var->name())); + // It's possible there's already a global variable // with the same name. // @@ -78,6 +80,8 @@ namespace xo { DVariable * existing = this->lookup_variable(var->name()); if (existing) { + log && log("variable with this symbol already exists"); + if (existing == var) { // impossible, but.. noop, right? return; @@ -91,6 +95,8 @@ namespace xo { // (*vars_)[existing->path().j_slot()] = obj(var); } else { + log && log("variable is new"); + DArray::size_type n = vars_->size(); // NOTE: expansion of var_ array here is moot at present (Feb 2026), @@ -146,8 +152,7 @@ namespace xo { { assert(sym); - scope log(XO_DEBUG(true), "stub"); - log && log(xtag("sym", std::string_view(*sym))); + scope log(XO_DEBUG(true), std::string_view(*sym)); auto ix = map_->find(sym); diff --git a/xo-reader2/src/reader2/DToplevelSeqSsm.cpp b/xo-reader2/src/reader2/DToplevelSeqSsm.cpp index e294d078..42c870b6 100644 --- a/xo-reader2/src/reader2/DToplevelSeqSsm.cpp +++ b/xo-reader2/src/reader2/DToplevelSeqSsm.cpp @@ -11,6 +11,7 @@ #include "DIfElseSsm.hpp" #include "ParenSsm.hpp" #include "ExpectExprSsm.hpp" +#include "VarRef.hpp" #include #include @@ -204,23 +205,23 @@ namespace xo { void DToplevelSeqSsm::on_symbol_token(const Token & tk, - ParserStateMachine * p_psm) + ParserStateMachine * p_psm) { switch (seqtype_) { case exprseqtype::toplevel_interactive: { -#ifdef NOT_YET - obj var = p_psm->lookup_var(tk.text()); + auto varref = obj(p_psm->lookup_varref(tk.text())); - if (var) { - DProgressSsm::start(var, p_psm); + if (varref) { + DProgressSsm::start(p_psm->parser_alloc(), + varref, + p_psm); + return; } else { - p_psm->unknown_variable_error("DToplevelSeqSsm::on_symbol_token", - tk, - this->get_expect_str(), - p_psm); + p_psm->error_unbound_variable("DToplevelSeqSsm", + tk.text()); + return; } -#endif } break; case exprseqtype::toplevel_batch: diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 6df9133b..856a8215 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -156,6 +156,16 @@ namespace xo { { scope log(XO_DEBUG(debug_flag_)); + const DUniqueString * ustr = stringtable_.lookup(symbolname); + + if (!ustr) { + // if we don't already know the symbol, + // -> can't be a valid variable reference + // (whether global or local) + + return nullptr; + } + // TODO: // 1. check global symtab // 2. combine local+global symtab into indept struct @@ -163,52 +173,46 @@ namespace xo { // if (local_symtab_) { - const DUniqueString * ustr = stringtable_.lookup(symbolname); + DLocalSymtab * symtab = local_symtab_; - if (ustr) { - DLocalSymtab * symtab = local_symtab_; + // count #of nested scopes to cross, to reach symbol + // + int32_t link_count = 0; - // count #of nested scopes to cross, to reach symbol - // - int32_t link_count = 0; + while (symtab) { + Binding b = symtab->lookup_binding(ustr); - while (symtab) { - Binding b = symtab->lookup_binding(ustr); + if (b.is_local()) { + assert(b.i_link() == 0); - if (b.is_local()) { - assert(b.i_link() == 0); + DVariable * vardef = symtab->lookup_var(b); + assert(vardef); - DVariable * vardef = symtab->lookup_var(b); - assert(vardef); + /** ascii diagram here + **/ - - /** ascii diagram here - **/ - - return DVarRef::make(expr_alloc_, - vardef, - link_count); - } else { - assert(b.is_null()); - } - - ++link_count; - symtab = symtab->parent(); + return DVarRef::make(expr_alloc_, + vardef, + link_count); + } else { + assert(b.is_null()); } - } else { - // if we don't already know the symbol, - // -> can't be a valid variable reference - // (whether global or local) - return nullptr; + ++link_count; + symtab = symtab->parent(); } } - // TODO: check global symtab also + DVariable * vardef = global_symtab_->lookup_variable(ustr); - log.retroactively_enable(); - log("STUB: check global symtab"); + if (vardef) { + return DVarRef::make(expr_alloc_, + vardef, + 0 /*link_count -- n/a for globals*/); + } + + // symbol not found return nullptr; } diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 665342dc..e4a0e1de 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ namespace xo { using xo::scm::AExpression; using xo::scm::DDefineExpr; using xo::scm::DApplyExpr; + using xo::scm::DVarRef; using xo::scm::DConstant; //using xo::scm::ParserResult; @@ -232,7 +234,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); @@ -267,6 +269,72 @@ namespace xo { log && fixture.log_memory_layout(&log); } + TEST_CASE("SchematikaParser-interactive-def2", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); + + parser.begin_interactive_session(); + + { + /** Walkthrough parsing input equivalent to: + * + * def foo : f64 = 3.141593 ; + * + **/ + + std::vector tk_v{ + Token::def_token(), + Token::symbol_token("foo"), + Token::colon_token(), + Token::symbol_token("f64"), + Token::singleassign_token(), + Token::f64_token("3.141593"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + const auto & result = parser.result(); + { + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + } + + parser.reset_result(); + } + + { + /** Walkthrough parsing input equivalent to: + * + * foo ; + * + **/ + + std::vector tk_v{ +// Token::f64_token("2.0"), +// Token::star_token(), + Token::symbol_token("foo"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + const auto & result = parser.result(); + { + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + } + } + + log && fixture.log_memory_layout(&log); + } + TEST_CASE("SchematikaParser-interactive-integer", "[reader2][SchematikaParser]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); From 6f3833d6fbf7f2f7cd03597e353cff70116e4d8e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 17 Feb 2026 14:42:17 -0500 Subject: [PATCH 250/258] xo-interpreter2 stack: define-expr's work at top-level --- .../include/xo/alloc2/alloc/RAllocator.hpp | 2 - xo-cmake/cmake/xo_macros/xo_cxx.cmake | 2 +- xo-expression2/CMakeLists.txt | 11 ++ .../idl/IGCObject_DDefineExpr.json5 | 18 +++ .../include/xo/expression2/DDefineExpr.hpp | 11 +- .../include/xo/expression2/DGlobalSymtab.hpp | 4 + .../include/xo/expression2/DefineExpr.hpp | 2 +- .../define/IGCObject_DDefineExpr.hpp | 67 +++++++++ xo-expression2/src/expression2/CMakeLists.txt | 3 +- .../src/expression2/DDefineExpr.cpp | 32 ++++- .../src/expression2/IGCObject_DDefineExpr.cpp | 39 ++++++ .../expression2_register_facets.cpp | 9 +- xo-gc/include/xo/gc/PolyForwarderUtil.hpp | 66 +++++++++ xo-interpreter2/CMakeLists.txt | 40 ++++++ .../idl/IGCObject_DGlobalEnv.json5 | 18 +++ xo-interpreter2/idl/IGCObject_DLocalEnv.json5 | 2 +- .../idl/IGCObject_DVsmDefContFrame.json5 | 18 +++ .../idl/IPrintable_DGlobalEnv.json5 | 16 +++ .../idl/IPrintable_DLocalEnv.json5 | 2 +- .../idl/IPrintable_DVsmDefContFrame.json5 | 16 +++ .../include/xo/interpreter2/DGlobalEnv.hpp | 49 ++++++- .../include/xo/interpreter2/DLocalEnv.hpp | 2 +- .../xo/interpreter2/DVsmDefContFrame.hpp | 82 +++++++++++ .../include/xo/interpreter2/GlobalEnv.hpp | 12 ++ .../interpreter2/VirtualSchematikaMachine.hpp | 21 +-- .../xo/interpreter2/VsmDefContFrame.hpp | 12 ++ .../include/xo/interpreter2/VsmInstr.hpp | 10 ++ .../include/xo/interpreter2/VsmOpcode.hpp | 8 +- .../define/IGCObject_DVsmDefContFrame.hpp | 67 +++++++++ .../define/IPrintable_DVsmDefContFrame.hpp | 62 +++++++++ .../interpreter2/env/IGCObject_DGlobalEnv.hpp | 67 +++++++++ .../interpreter2/env/IGCObject_DLocalEnv.hpp | 67 +++++++++ .../env/IPrintable_DGlobalEnv.hpp | 62 +++++++++ .../interpreter2/env/IPrintable_DLocalEnv.hpp | 62 +++++++++ .../src/interpreter2/CMakeLists.txt | 10 +- .../src/interpreter2/DGlobalEnv.cpp | 128 ++++++++++++++++++ .../src/interpreter2/DLocalEnv.cpp | 4 + .../src/interpreter2/DVsmDefContFrame.cpp | 68 ++++++++++ .../src/interpreter2/IGCObject_DGlobalEnv.cpp | 39 ++++++ .../src/interpreter2/IGCObject_DLocalEnv.cpp | 2 +- .../IGCObject_DVsmDefContFrame.cpp | 39 ++++++ .../interpreter2/IPrintable_DGlobalEnv.cpp | 28 ++++ .../src/interpreter2/IPrintable_DLocalEnv.cpp | 2 +- .../IPrintable_DVsmDefContFrame.cpp | 28 ++++ .../interpreter2/VirtualSchematikaMachine.cpp | 120 ++++++++++++++-- xo-interpreter2/src/interpreter2/VsmInstr.cpp | 10 +- .../interpreter2_register_facets.cpp | 15 ++ .../utest/VirtualSchematikaMachine.test.cpp | 97 ++++++++++++- xo-object2/include/xo/object2/DArray.hpp | 12 +- xo-object2/src/object2/DArray.cpp | 13 ++ .../include/xo/reader2/ParserStateMachine.hpp | 21 +-- .../include/xo/reader2/SchematikaParser.hpp | 2 + .../include/xo/reader2/SchematikaReader.hpp | 3 + xo-reader2/src/reader2/SchematikaParser.cpp | 6 + xo-reader2/src/reader2/SchematikaReader.cpp | 6 + xo-reader2/utest/SchematikaParser.test.cpp | 1 + 56 files changed, 1550 insertions(+), 65 deletions(-) create mode 100644 xo-expression2/idl/IGCObject_DDefineExpr.json5 create mode 100644 xo-expression2/include/xo/expression2/define/IGCObject_DDefineExpr.hpp create mode 100644 xo-expression2/src/expression2/IGCObject_DDefineExpr.cpp create mode 100644 xo-gc/include/xo/gc/PolyForwarderUtil.hpp create mode 100644 xo-interpreter2/idl/IGCObject_DGlobalEnv.json5 create mode 100644 xo-interpreter2/idl/IGCObject_DVsmDefContFrame.json5 create mode 100644 xo-interpreter2/idl/IPrintable_DGlobalEnv.json5 create mode 100644 xo-interpreter2/idl/IPrintable_DVsmDefContFrame.json5 create mode 100644 xo-interpreter2/include/xo/interpreter2/DVsmDefContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/GlobalEnv.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/VsmDefContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/define/IGCObject_DVsmDefContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/define/IPrintable_DVsmDefContFrame.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/env/IGCObject_DGlobalEnv.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/env/IGCObject_DLocalEnv.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/env/IPrintable_DGlobalEnv.hpp create mode 100644 xo-interpreter2/include/xo/interpreter2/env/IPrintable_DLocalEnv.hpp create mode 100644 xo-interpreter2/src/interpreter2/DGlobalEnv.cpp create mode 100644 xo-interpreter2/src/interpreter2/DVsmDefContFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DGlobalEnv.cpp create mode 100644 xo-interpreter2/src/interpreter2/IGCObject_DVsmDefContFrame.cpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DGlobalEnv.cpp create mode 100644 xo-interpreter2/src/interpreter2/IPrintable_DVsmDefContFrame.cpp diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index 4d2af7f7..b5252f49 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -43,8 +43,6 @@ namespace xo { template T * std_copy_for(const T * src) noexcept { - // TODO: fix alloc_copy(), should take const std::byte * - T * copy = (T *)(this->alloc_copy_for(src)); if (copy) { diff --git a/xo-cmake/cmake/xo_macros/xo_cxx.cmake b/xo-cmake/cmake/xo_macros/xo_cxx.cmake index 1550e282..9d94e9b7 100644 --- a/xo-cmake/cmake/xo_macros/xo_cxx.cmake +++ b/xo-cmake/cmake/xo_macros/xo_cxx.cmake @@ -1772,7 +1772,7 @@ function(xo_add_genfacetimpl) ) # Create a target for this generation - add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}) + add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}.out) set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET}) endfunction() diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 1b84df8d..c9180ad8 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -230,6 +230,17 @@ xo_add_genfacetimpl( OUTPUT_IMPL_SUBDIR detail ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-defineexpr + FACET_PKG xo_gc + FACET GCObject + REPR DefineExpr + INPUT idl/IGCObject_DDefineExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR define +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-defineexpr diff --git a/xo-expression2/idl/IGCObject_DDefineExpr.json5 b/xo-expression2/idl/IGCObject_DDefineExpr.json5 new file mode 100644 index 00000000..6b0eba68 --- /dev/null +++ b/xo-expression2/idl/IGCObject_DDefineExpr.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "define", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DDefineExpr", + using_doxygen: true, + repr: "DDefineExpr", + doc: [ "implement AGCObject for DDefineExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp index 6b7716e3..6ad8494f 100644 --- a/xo-expression2/include/xo/expression2/DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -1,5 +1,5 @@ /** @file DDefineExpr.hpp -* + * * @author Roland Conybeare, Jan 2026 **/ @@ -23,6 +23,7 @@ namespace xo { class DDefineExpr { public: using ppindentinfo = xo::print::ppindentinfo; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; @@ -67,6 +68,14 @@ namespace xo { TypeDescr valuetype() const noexcept { return lhs_var_->typeref().td(); } void assign_valuetype(TypeDescr td) noexcept; + ///@} + /** @defgroup scm-defineexpr-gcobject-facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DDefineExpr * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} /** @defgroup scm-defineexpr-printable-facet **/ ///@{ diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 63a2a91f..5cd03fb2 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -32,6 +32,7 @@ namespace xo { using AAllocator = xo::mm::AAllocator; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; public: /** @defgroup scm-globalsymtab-ctors constructors **/ @@ -55,6 +56,9 @@ namespace xo { /** @defgroup scm-globalsymtab-access-methods access methods **/ ///@{ + size_type size() const noexcept { return map_->size(); } + size_type capacity() const noexcept { return map_->capacity(); } + /** visit symtab-owned memory pools; call visitor(info) for each **/ void visit_pools(const MemorySizeVisitor & visitor) const; diff --git a/xo-expression2/include/xo/expression2/DefineExpr.hpp b/xo-expression2/include/xo/expression2/DefineExpr.hpp index 37a77c03..4a0c42c2 100644 --- a/xo-expression2/include/xo/expression2/DefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DefineExpr.hpp @@ -7,7 +7,7 @@ #include "DDefineExpr.hpp" #include "detail/IExpression_DDefineExpr.hpp" -//#include "detail/IGCObject_DDefineExpr.hpp" +#include "define/IGCObject_DDefineExpr.hpp" #include "detail/IPrintable_DDefineExpr.hpp" /* end DefineExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/define/IGCObject_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/define/IGCObject_DDefineExpr.hpp new file mode 100644 index 00000000..216dd18b --- /dev/null +++ b/xo-expression2/include/xo/expression2/define/IGCObject_DDefineExpr.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DDefineExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DDefineExpr.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DDefineExpr.hpp" + +namespace xo { namespace scm { class IGCObject_DDefineExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DDefineExpr + **/ + class IGCObject_DDefineExpr { + public: + /** @defgroup scm-gcobject-ddefineexpr-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-ddefineexpr-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DDefineExpr & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DDefineExpr & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DDefineExpr & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 8aafa01a..f05cf2f1 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -9,7 +9,6 @@ set(SELF_SRCS DConstant.cpp DVariable.cpp DVarRef.cpp - DDefineExpr.cpp DApplyExpr.cpp TypeRef.cpp @@ -30,7 +29,9 @@ set(SELF_SRCS IGCObject_DVarRef.cpp IPrintable_DVarRef.cpp + DDefineExpr.cpp IExpression_DDefineExpr.cpp + IGCObject_DDefineExpr.cpp IPrintable_DDefineExpr.cpp IExpression_DApplyExpr.cpp diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index 961fbecc..aee6ccf9 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -4,13 +4,16 @@ **/ #include "DDefineExpr.hpp" -#include "detail/IPrintable_DVariable.hpp" +#include "Variable.hpp" +#include +#include #include #include #include #include namespace xo { + using xo::mm::poly_forward_inplace; using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::facet::typeseq; @@ -68,10 +71,35 @@ namespace xo { } void - DDefineExpr::assign_rhs(obj x) { + DDefineExpr::assign_rhs(obj x) + { this->rhs_ = x; } + // ----- GCObject facet ----- + + std::size_t + DDefineExpr::shallow_size() const noexcept + { + return sizeof(*this); + } + + DDefineExpr * + DDefineExpr::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DDefineExpr::forward_children(obj gc) noexcept + { + gc.forward_inplace(&lhs_var_); + //gc.forward_inplace(&rhs_); // complicated - need to access via GCObject facet + poly_forward_inplace(gc, &rhs_); + + return this->shallow_size(); + } + bool DDefineExpr::pretty(const ppindentinfo & ppii) const { diff --git a/xo-expression2/src/expression2/IGCObject_DDefineExpr.cpp b/xo-expression2/src/expression2/IGCObject_DDefineExpr.cpp new file mode 100644 index 00000000..eb43932b --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DDefineExpr.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DDefineExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DDefineExpr.json5] +**/ + +#include "define/IGCObject_DDefineExpr.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DDefineExpr::shallow_size(const DDefineExpr & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DDefineExpr::shallow_copy(const DDefineExpr & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DDefineExpr::forward_children(DDefineExpr & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DDefineExpr.cpp */ diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index c563c9da..82bff638 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -6,17 +6,12 @@ #include "expression2_register_facets.hpp" #include -//#include -//#include - -#include -//#include -#include #include #include #include +#include #include #include #include @@ -74,7 +69,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); - //FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); diff --git a/xo-gc/include/xo/gc/PolyForwarderUtil.hpp b/xo-gc/include/xo/gc/PolyForwarderUtil.hpp new file mode 100644 index 00000000..19f99c9b --- /dev/null +++ b/xo-gc/include/xo/gc/PolyForwarderUtil.hpp @@ -0,0 +1,66 @@ +/** @file PolyForwarderUtil.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "Collector.hpp" +#include + +namespace xo { + namespace mm { + + /** Utility class for forwarding support on + * faceted object pointers that have some primary + * facet _other_ than AGCObject. + * + * For fop with AGCObject facet, with collector gc: + * + * obj gc = ..; + * obj ptr = ..; + * + * gc.forward_inplace(&ptr); + * + * for fop with some other facet: + * + * obj ptr = ..; + * PolyForwarderUtil::forward_inplace(gc, &ptr); + * + * or + * poly_forward_inplace(gc, &ptr); + **/ + class PolyForwarderUtil { + public: + template + static void forward_inplace(obj gc, obj * p_ptr) { + using xo::facet::FacetRegistry; + + /** + * p_ptr + * v FacetRegistry + * +--------+---------+ .variant() +-----------+---------+ + * | AFacet | DRepr x | -----------------> | AGCobject | DRepr x | + * +--------+-------|-+ +-----------+-------|-+ + * | | + * | /-------------------------------------------/ + * | | + * v v + * +-------+ + * | DRepr | + * +-------+ + **/ + + auto gco = FacetRegistry::instance().variant(*p_ptr); + gc.forward_inplace(gco.iface(), (void **)&(p_ptr->data_)); + } + }; + + template + void poly_forward_inplace(obj gc, obj * p_ptr) { + PolyForwarderUtil::forward_inplace(gc, p_ptr); + } + } /*namespace mm*/ +} /*namespace xo*/ + +/* end PolyForwarderUtil.hpp */ diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 7ffbebc3..2d1a6db8 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -25,6 +25,26 @@ add_subdirectory(utest) # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-vsmdefcontframe + FACET_PKG xo_gc + FACET GCObject + REPR VsmDefContFrame + INPUT idl/IGCObject_DVsmDefContFrame.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-vsmdefcontframe + FACET_PKG xo_printable2 + FACET Printable + REPR VsmDefContFrame + INPUT idl/IPrintable_DVsmDefContFrame.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-interpreter2-facetimpl-gcobject-vsmapplyframe @@ -155,6 +175,26 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-globalenv + FACET_PKG xo_gc + FACET GCObject + REPR GlobalEnv + INPUT idl/IGCObject_DGlobalEnv.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-globalenv + FACET_PKG xo_printable2 + FACET Printable + REPR GlobalEnv + INPUT idl/IPrintable_DGlobalEnv.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-interpreter2-facetimpl-gcobject-localenv diff --git a/xo-interpreter2/idl/IGCObject_DGlobalEnv.json5 b/xo-interpreter2/idl/IGCObject_DGlobalEnv.json5 new file mode 100644 index 00000000..ce0bc090 --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DGlobalEnv.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "env", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for GlobalEnv", + using_doxygen: true, + repr: "DGlobalEnv", + doc: [ "implement AGCObject for DGlobalEnv" ], +} diff --git a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 index 1fbce208..252bfbd7 100644 --- a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 +++ b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 @@ -2,7 +2,7 @@ mode: "implementation", output_cpp_dir: "src/interpreter2", output_hpp_dir: "include/xo/interpreter2", - output_impl_subdir: "detail", + output_impl_subdir: "env", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmDefContFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmDefContFrame.json5 new file mode 100644 index 00000000..061fca5d --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DVsmDefContFrame.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "define", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVsmDefContFrame", + using_doxygen: true, + repr: "DVsmDefContFrame", + doc: [ "implement AGCObject for DVsmDefContFrame" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DGlobalEnv.json5 b/xo-interpreter2/idl/IPrintable_DGlobalEnv.json5 new file mode 100644 index 00000000..541146ae --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DGlobalEnv.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "env", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DGlobalEnv", + using_doxygen: true, + repr: "DGlobalEnv", + doc: [ "implement APrintable for DGlobalEnv" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 index 79ef4c74..dfc6a644 100644 --- a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 +++ b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 @@ -2,7 +2,7 @@ mode: "implementation", output_cpp_dir: "src/interpreter2", output_hpp_dir: "include/xo/interpreter2", - output_impl_subdir: "detail", + output_impl_subdir: "env", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmDefContFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmDefContFrame.json5 new file mode 100644 index 00000000..58410fd6 --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DVsmDefContFrame.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "define", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVsmDefContFrame", + using_doxygen: true, + repr: "DVsmDefContFrame", + doc: [ "implement APrintable for DVsmDefContFrame" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp index 60fbe461..e68ad55d 100644 --- a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp @@ -25,18 +25,55 @@ namespace xo { **/ class DGlobalEnv { public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; public: - DGlobalEnv() = default; + /** @defgroup scm-globalenv-ctors constructors **/ + ///@{ - /** visit env-owned memory pools; call visitor(info) for each **/ - void visit_pools(const MemorySizeVisitor & visitor) const; + DGlobalEnv(DGlobalSymtab * symtab, DArray * values); - protected: // temporary, to appease compiler + static DGlobalEnv * _make(obj mm, + DGlobalSymtab * symtab); - // absurd O(n) implementation for now - // replace with gc-aware hashtable, when available. + + ///@} + /** @defgroup scm-globalenv-methods methods **/ + ///@{ + + /** symbol-table size. Is the number of distinct global symbols **/ + size_type size() const noexcept { return symtab_->size(); } + + /** 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); + + ///@} + /** @defgroup scm-globalenv-gcobject-facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DGlobalEnv * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(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_; diff --git a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp index c99aaad1..eaef71c2 100644 --- a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp @@ -37,7 +37,7 @@ namespace xo { DArray * args); ///@} - /** @defgroup scm-local-env-methods methods **/ + /** @defgroup scm-localenv-methods methods **/ ///@{ DLocalEnv * parent() const noexcept { return parent_; } diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmDefContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmDefContFrame.hpp new file mode 100644 index 00000000..68c2510a --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DVsmDefContFrame.hpp @@ -0,0 +1,82 @@ +/** @file DVsmDefContFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "VsmInstr.hpp" +#include +#include + +namespace xo { + namespace scm { + /** @brief saved VSM state during evaluation of a SequenceExpr + **/ + class DVsmDefContFrame { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-vsmdefcontframe-ctors constructors **/ + ///@{ + + DVsmDefContFrame(obj parent, + VsmInstr cont, + DDefineExpr * def_expr); + + /** create instance using memory from allocator @p mm **/ + static DVsmDefContFrame * make(obj mm, + obj parent_stack, + VsmInstr cont, + DDefineExpr * def_expr); + + ///@} + /** @defgroup scm-vsmdefcontframe-access-methods access methods **/ + ///@{ + + obj parent() const noexcept { return parent_; } + VsmInstr cont() const noexcept { return cont_; } + DDefineExpr * def_expr() const noexcept { return def_expr_; } + + ///@} + /** @defgroup scm-vsmdefcontframe-general-methods general methods **/ + ///@{ + + ///@} + /** @defgroup scm-vsmdefcontframe-gcobject-facet gcobject facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DVsmDefContFrame * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} + /** @defgrouop scm-vsmseqcontframe-printable-facet printable facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const noexcept; + + ///@} + + private: + /** @defgroup scm-vsmdefcontframe-members member variables **/ + ///@{ + + /** saved VSM stack; restore when this frame consumed **/ + obj parent_; + /** saved continuation; restore when this frame consumed **/ + VsmInstr cont_; + /** saved expr. evaluate elements of this sequence in order **/ + DDefineExpr * def_expr_ = nullptr; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmDefContFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/GlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/GlobalEnv.hpp new file mode 100644 index 00000000..94bafc42 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/GlobalEnv.hpp @@ -0,0 +1,12 @@ +/** @file GlobalEnv.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DGlobalEnv.hpp" +#include "env/IGCObject_DGlobalEnv.hpp" +#include "env/IPrintable_DGlobalEnv.hpp" + +/* end GlobalEnv.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index a34310ab..724e1c33 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -191,6 +191,11 @@ namespace xo { /** call primitive @ref fn_ with arguments @ref args_ **/ void _do_call_primitive_op(); + /** perform assignment after evaluating + * the rhs of a define-expr + **/ + void _do_def_cont_op(); + /** restore registers from stack frame * (specifically: local_env_, stack_, cont_) * after invoking a schematika closure @@ -225,13 +230,13 @@ namespace xo { #ifdef NOT_YET /** allocator (likely DArena) for globals. - * For example DArenaHashMap in global symtab, + * For example DArenaHashMap in global symta. **/ obj aux_mm_; #endif /** allocator (likely DX1Collector or similar) for - * expressions and values + * expressions and values. Schemaatika reader will use this also **/ abox mm_; @@ -267,19 +272,17 @@ namespace xo { /** expression register **/ obj expr_; + /** environment pointer. Maintains bindings + * for global variables. + **/ + DGlobalEnv * global_env_ = nullptr; + /** environment pointer. Provides bindings * for surrounding lexical scope at this point * in execution **/ DLocalEnv * local_env_ = nullptr; - protected: // temporarily, to appease compiler - /** environment pointer. Maintains bindings - * for global variables. - **/ - DGlobalEnv * global_env_ = nullptr; - - private: /** evaluated function to call **/ obj fn_; /** evaluated argument list **/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmDefContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmDefContFrame.hpp new file mode 100644 index 00000000..5ea2bad6 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmDefContFrame.hpp @@ -0,0 +1,12 @@ +/** @file VsmDefContFrame.hpp +* + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVsmDefContFrame.hpp" +#include "define/IGCObject_DVsmDefContFrame.hpp" +#include "define/IPrintable_DVsmDefContFrame.hpp" + +/* end VsmDefContFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index 1279f8b7..2417757f 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -9,15 +9,25 @@ namespace xo { namespace scm { + /** + * Thin instruction wrapper for VSM (virtual schematika machine) instructions. + * For exeuction see VirtualSchematikaMachine.cpp + **/ class VsmInstr { public: explicit VsmInstr(vsm_opcode oc) : opcode_{oc} {} // instructions + static VsmInstr c_sentinel; static VsmInstr c_halt; static VsmInstr c_eval; + /** proceed to assignment after evaluating rhs + * of define-expression + **/ + static VsmInstr c_def_cont; + static VsmInstr c_apply; static VsmInstr c_evalargs; /** restore VSM state for continuation of an apply expression **/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp index e1000cb3..161b352e 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp @@ -14,6 +14,8 @@ namespace xo { * exeucted by VirtualSchematikaMachine **/ enum class vsm_opcode { + /** Flags bad state (defect in VSM itself) **/ + sentinel, /** Immediately halt virtual schematika machine. **/ halt, /** Evaluate expression in expr register **/ @@ -28,6 +30,11 @@ namespace xo { **/ evalargs, + /** continuation to complete execution of define-expression, + * after evaluting rhs expression + **/ + def_cont, + /** continuation to restore vsm registers (local_env, stack, cont) * after invoking a closure **/ @@ -58,4 +65,3 @@ namespace xo { } /*namespace xo*/ /* end VsmOpcode.hpp */ - diff --git a/xo-interpreter2/include/xo/interpreter2/define/IGCObject_DVsmDefContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/define/IGCObject_DVsmDefContFrame.hpp new file mode 100644 index 00000000..309a6ac7 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/define/IGCObject_DVsmDefContFrame.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVsmDefContFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmDefContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmDefContFrame.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVsmDefContFrame.hpp" + +namespace xo { namespace scm { class IGCObject_DVsmDefContFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVsmDefContFrame + **/ + class IGCObject_DVsmDefContFrame { + public: + /** @defgroup scm-gcobject-dvsmdefcontframe-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvsmdefcontframe-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVsmDefContFrame & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVsmDefContFrame & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVsmDefContFrame & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/define/IPrintable_DVsmDefContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/define/IPrintable_DVsmDefContFrame.hpp new file mode 100644 index 00000000..46ab4ee7 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/define/IPrintable_DVsmDefContFrame.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVsmDefContFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmDefContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmDefContFrame.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVsmDefContFrame.hpp" + +namespace xo { namespace scm { class IPrintable_DVsmDefContFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVsmDefContFrame + **/ + class IPrintable_DVsmDefContFrame { + public: + /** @defgroup scm-printable-dvsmdefcontframe-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvsmdefcontframe-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVsmDefContFrame & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DGlobalEnv.hpp new file mode 100644 index 00000000..1f0f9281 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DGlobalEnv.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DGlobalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DGlobalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DGlobalEnv.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DGlobalEnv.hpp" + +namespace xo { namespace scm { class IGCObject_DGlobalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DGlobalEnv + **/ + class IGCObject_DGlobalEnv { + public: + /** @defgroup scm-gcobject-dglobalenv-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dglobalenv-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DGlobalEnv & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DGlobalEnv & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DGlobalEnv & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DLocalEnv.hpp new file mode 100644 index 00000000..d318bb61 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DLocalEnv.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DLocalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DLocalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DLocalEnv.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DLocalEnv.hpp" + +namespace xo { namespace scm { class IGCObject_DLocalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DLocalEnv + **/ + class IGCObject_DLocalEnv { + public: + /** @defgroup scm-gcobject-dlocalenv-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dlocalenv-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DLocalEnv & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DLocalEnv & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DLocalEnv & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DGlobalEnv.hpp new file mode 100644 index 00000000..6efcd963 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DGlobalEnv.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DGlobalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DGlobalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DGlobalEnv.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DGlobalEnv.hpp" + +namespace xo { namespace scm { class IPrintable_DGlobalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DGlobalEnv + **/ + class IPrintable_DGlobalEnv { + public: + /** @defgroup scm-printable-dglobalenv-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dglobalenv-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DGlobalEnv & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DLocalEnv.hpp new file mode 100644 index 00000000..c0ddb7f8 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DLocalEnv.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DLocalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLocalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLocalEnv.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DLocalEnv.hpp" + +namespace xo { namespace scm { class IPrintable_DLocalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DLocalEnv + **/ + class IPrintable_DLocalEnv { + public: + /** @defgroup scm-printable-dlocalenv-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dlocalenv-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DLocalEnv & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index c21821e1..c15ddef6 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -8,6 +8,10 @@ set(SELF_SRCS VirtualSchematikaMachine.cpp + DVsmDefContFrame.cpp + IGCObject_DVsmDefContFrame.cpp + IPrintable_DVsmDefContFrame.cpp + DVsmEvalArgsFrame.cpp IGCObject_DVsmEvalArgsFrame.cpp IPrintable_DVsmEvalArgsFrame.cpp @@ -32,9 +36,13 @@ set(SELF_SRCS IGCObject_DClosure.cpp IPrintable_DClosure.cpp + DGlobalEnv.cpp + IGCObject_DGlobalEnv.cpp + IPrintable_DGlobalEnv.cpp + + DLocalEnv.cpp IGCObject_DLocalEnv.cpp IPrintable_DLocalEnv.cpp - DLocalEnv.cpp DVsmRcx.cpp IRuntimeContext_DVsmRcx.cpp diff --git a/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp b/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp new file mode 100644 index 00000000..a9285b73 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp @@ -0,0 +1,128 @@ +/** @file DGlobalEnv.cpp + * + * @author Roland Conybeare, Feb 2026 +**/ + +#include "GlobalEnv.hpp" +#include +#include + +namespace xo { + using xo::mm::AAllocator; + using xo::mm::AGCObject; + + namespace scm { + + DGlobalEnv::DGlobalEnv(DGlobalSymtab * symtab, DArray * values) + : symtab_{symtab}, values_{values} + {} + + DGlobalEnv * + DGlobalEnv::_make(obj mm, + DGlobalSymtab * symtab) + { + DArray * values = DArray::empty(mm, symtab->capacity()); + + void * mem = mm.alloc_for(); + + return new (mem) DGlobalEnv(symtab, values); + } + + obj + DGlobalEnv::lookup_value(Binding ix) const noexcept + { + if (!ix.is_global()) { + assert(false); + return obj(); + } + + if (ix.j_slot() >= static_cast(values_->size())) { + assert(false); + return obj(); + } + + return (*values_)[ix.j_slot()]; + } + + void + DGlobalEnv::assign_value(obj mm, Binding ix, obj x) + { + scope log(XO_DEBUG(true), + xtag("ix.j_slot", ix.j_slot()), + xtag("values.cap", values_->capacity())); + + assert(ix.is_global()); + + if (ix.j_slot() >= static_cast(values_->size())) { + // Control will come here in interpreter as new definitions are introduced. + // After seeing + // def foo = 1.2345; + // introducing new symbol foo: + // GlobalSymtab extends to include foo without this GlobalEnv + // knowing about it. + + if (ix.j_slot() + 1 > static_cast(values_->capacity())) { + // realloc global array for more size + + size_t cap_2x = 2 * values_->capacity(); + + while (cap_2x < static_cast(ix.j_slot() + 1)) + cap_2x = 2 * cap_2x; + + DArray * values_2x = DArray::copy(mm, values_, cap_2x); + assert(values_2x); + + if (values_2x) { + log && log("STUB: need write barrier for GC (also in GlobalSymtab!)"); + this->values_ = values_2x; + } else { + return; + } + } + + /** expand size sot that j_slot is valid **/ + values_->resize(ix.j_slot() + 1); + } + + log && log("STUB: need write barrier for GC here"); + (*values_)[ix.j_slot()] = x; + } + + // ----- AGCObject facet ----- + + std::size_t + DGlobalEnv::shallow_size() const noexcept + { + return sizeof(*this); + } + + DGlobalEnv * + DGlobalEnv::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DGlobalEnv::forward_children(obj gc) noexcept + { + gc.forward_inplace(&symtab_); + gc.forward_inplace(&values_); + + return this->shallow_size(); + } + + // ----- APrintable facet ----- + + bool + DGlobalEnv::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DGlobalEnv", + refrtag("size", symtab_->size())); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalEnv.cpp */ diff --git a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp index 6866fda7..8f45b38a 100644 --- a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp @@ -6,6 +6,7 @@ #include "LocalEnv.hpp" #include #include +#include namespace xo { using xo::mm::AGCObject; @@ -64,6 +65,8 @@ namespace xo { void DLocalEnv::assign_value(Binding ix, obj x) { + scope log(XO_DEBUG(true)); + assert(!ix.is_global()); const DLocalEnv * env = this; @@ -76,6 +79,7 @@ namespace xo { auto j = ix.j_slot(); if (j < static_cast(env->size())) { + log && log("STUB: need write barrier for GC here"); (*(env->args_))[j] = x; } else { assert(false); diff --git a/xo-interpreter2/src/interpreter2/DVsmDefContFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmDefContFrame.cpp new file mode 100644 index 00000000..7b3b9e7a --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DVsmDefContFrame.cpp @@ -0,0 +1,68 @@ +/** @file DVsmDefContFrame.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVsmDefContFrame.hpp" +#include +#include + +namespace xo { + namespace scm { + + DVsmDefContFrame::DVsmDefContFrame(obj parent, + VsmInstr cont, + DDefineExpr * def_expr) + : parent_{parent}, + cont_{cont}, + def_expr_{def_expr} + {} + + DVsmDefContFrame * + DVsmDefContFrame::make(obj mm, + obj parent, + VsmInstr cont, + DDefineExpr * def_expr) + { + void * mem = mm.alloc_for(); + + return new (mem) DVsmDefContFrame(parent, cont, def_expr); + } + + // gcobject facet + + std::size_t + DVsmDefContFrame::shallow_size() const noexcept + { + return sizeof(*this); + } + + DVsmDefContFrame * + DVsmDefContFrame::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DVsmDefContFrame::forward_children(obj gc) noexcept + { + gc.forward_inplace(&parent_); + gc.forward_inplace(&def_expr_); + + return this->shallow_size(); + } + + // printable facet + + bool + DVsmDefContFrame::pretty(const ppindentinfo & ppii) const noexcept + { + return ppii.pps()->pretty_struct(ppii, + "DVsmDefContFrame", + refrtag("cont", cont_)); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmDefContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DGlobalEnv.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DGlobalEnv.cpp new file mode 100644 index 00000000..76606d6f --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DGlobalEnv.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DGlobalEnv.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DGlobalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DGlobalEnv.json5] +**/ + +#include "env/IGCObject_DGlobalEnv.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DGlobalEnv::shallow_size(const DGlobalEnv & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DGlobalEnv::shallow_copy(const DGlobalEnv & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DGlobalEnv::forward_children(DGlobalEnv & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DGlobalEnv.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp index 3ee3b7c7..3b6cd5f7 100644 --- a/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp @@ -11,7 +11,7 @@ * [idl/IGCObject_DLocalEnv.json5] **/ -#include "detail/IGCObject_DLocalEnv.hpp" +#include "env/IGCObject_DLocalEnv.hpp" namespace xo { namespace scm { diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DVsmDefContFrame.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DVsmDefContFrame.cpp new file mode 100644 index 00000000..26a23611 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DVsmDefContFrame.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVsmDefContFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmDefContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmDefContFrame.json5] +**/ + +#include "define/IGCObject_DVsmDefContFrame.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVsmDefContFrame::shallow_size(const DVsmDefContFrame & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVsmDefContFrame::shallow_copy(const DVsmDefContFrame & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVsmDefContFrame::forward_children(DVsmDefContFrame & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVsmDefContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DGlobalEnv.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DGlobalEnv.cpp new file mode 100644 index 00000000..84fc561c --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DGlobalEnv.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DGlobalEnv.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DGlobalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DGlobalEnv.json5] +**/ + +#include "env/IPrintable_DGlobalEnv.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DGlobalEnv::pretty(const DGlobalEnv & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DGlobalEnv.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp index bf701cb6..6fe745b2 100644 --- a/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp @@ -11,7 +11,7 @@ * [idl/IPrintable_DLocalEnv.json5] **/ -#include "detail/IPrintable_DLocalEnv.hpp" +#include "env/IPrintable_DLocalEnv.hpp" namespace xo { namespace scm { diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DVsmDefContFrame.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DVsmDefContFrame.cpp new file mode 100644 index 00000000..f73b7dd6 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DVsmDefContFrame.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVsmDefContFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmDefContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmDefContFrame.json5] +**/ + +#include "define/IPrintable_DVsmDefContFrame.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVsmDefContFrame::pretty(const DVsmDefContFrame & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVsmDefContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 5c2d2c57..aa0861f5 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -4,6 +4,7 @@ **/ #include "VirtualSchematikaMachine.hpp" +#include "VsmDefContFrame.hpp" #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "VsmApplyClosureFrame.hpp" @@ -11,10 +12,12 @@ #include "VsmSeqContFrame.hpp" #include "VsmRcx.hpp" #include "Closure.hpp" +#include #include #include #include #include +#include #include #include //#include @@ -65,10 +68,10 @@ namespace xo { DArena * arena = new DArena(config_.error_config_); assert(arena); - error_mm_.adopt(obj(arena)); + this->error_mm_.adopt(obj(arena)); } - // TODO: allocate global_env + this->global_env_ = DGlobalEnv::_make(mm_.to_op(), reader_.global_symtab()); } obj @@ -166,17 +169,20 @@ namespace xo { VirtualSchematikaMachine::execute_one() { scope log(XO_DEBUG(config_.debug_flag_)); + log && log(xtag("pc", pc_), xtag("cont", cont_)); - obj stack_pr = stack_.to_facet(); -// = (FacetRegistry::instance() -// .try_variant(stack_)); + auto expr_pr = expr_.to_facet(); + if (expr_pr) + log && log(xtag("expr", expr_pr)); + auto stack_pr = stack_.to_facet(); if (stack_pr) log && log(xtag("stack", stack_pr)); switch (pc_.opcode()) { + case vsm_opcode::sentinel: case vsm_opcode::halt: case vsm_opcode::N: return false; @@ -189,6 +195,9 @@ namespace xo { case vsm_opcode::evalargs: _do_evalargs_op(); break; + case vsm_opcode::def_cont: + _do_def_cont_op(); + break; case vsm_opcode::apply_cont: _do_apply_cont_op(); break; @@ -244,14 +253,84 @@ namespace xo { = obj::from(expr_); this->value_ = VsmResult(expr.data()->value()); + this->pc_ = this->cont_; + this->cont_ = VsmInstr::c_sentinel; } void VirtualSchematikaMachine::_do_eval_define_op() { - // not implemented - assert(false); + scope log(XO_DEBUG(true)); + + auto def_expr + = obj::from(expr_); + + if (local_env_ == nullptr) { + // top-level define + + // .stack_ --+ + // | + // v + // +------DVsmDefContFrame------+ + // | .parent x | .cont | .def x | + // +---------|-+-------+------|-+ + // | | + // ParserStack* <-----/ | + // | + // v + // DDefineExpr + + /* stack frame for nested continuation + * (to perform assignment) + */ + auto defcont_frame + = obj + (DVsmDefContFrame::make(mm_.to_op(), + this->stack_ /*saved stack*/, + this->cont_ /*saved cont*/, + def_expr.data() /*saved expr*/)); + + this->stack_ = defcont_frame; + + // setup evaluation of rhs + + this->expr_ = def_expr->rhs(); + this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_def_cont; + } else { + // nested defines implemented by rewriting, + // so this branch should be unreachable + + assert(false); + } + } + + void + VirtualSchematikaMachine::_do_def_cont_op() + { + // see DVsmDefContFrame + + auto frame = obj::from(stack_); + + assert(frame); + assert(value_.is_value()); + + // TODO: verify that value satisfies expected type ? + + DVariable * lhs = frame->def_expr()->lhs(); + obj rhs = *value_.value(); + + assert(lhs->path().is_global()); + + global_env_->assign_value(mm_.to_op(), lhs->path(), rhs); + + // TODO: unfortunate const_cast here, because obj<> doesn't support const DRepr yet + this->value_ = VsmResult(obj(const_cast(lhs->name()))); + + this->stack_ = frame->parent(); + this->pc_ = frame->cont(); + this->cont_ = VsmInstr::c_sentinel; } void @@ -294,7 +373,9 @@ namespace xo { this->value_ = VsmResult(obj(obj(closure))); + this->pc_ = this->cont_; + this->cont_ = VsmInstr::c_sentinel; } void @@ -320,7 +401,9 @@ namespace xo { if (value) { this->value_ = VsmResult(value); + this->pc_ = this->cont_; + this->cont_ = VsmInstr::c_sentinel; return; } @@ -338,6 +421,7 @@ namespace xo { // 3. have every vsm instruction check inputs for errors this->pc_ = VsmInstr::c_halt; + this->cont_ = VsmInstr::c_sentinel; } void @@ -385,9 +469,9 @@ namespace xo { // Setup evaluation of first argument. No new stack for this. - this->cont_ = VsmInstr::c_evalargs; this->expr_ = apply->fn(); this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_evalargs; } void @@ -404,9 +488,9 @@ namespace xo { stack_, cont_, ifelse_expr.data())); this->stack_ = ifelse_frame; - this->cont_ = VsmInstr::c_ifelse_cont; this->expr_ = ifelse_expr->test(); this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_ifelse_cont; } void @@ -445,9 +529,9 @@ namespace xo { // Setup evaluation of first sequence element - this->cont_ = VsmInstr::c_seq_cont; this->expr_ = (*seq_expr.data())[0]; this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_seq_cont; } void @@ -514,6 +598,7 @@ namespace xo { this->local_env_ = local_env; this->expr_ = lambda->body_expr(); this->pc_ = VsmInstr::c_eval; + // cont_ already established } void @@ -523,6 +608,7 @@ namespace xo { this->value_ = VsmResult(fn.apply_nocheck(rcx_.to_op(), args_)); this->pc_ = cont_; + this->cont_ = VsmInstr::c_sentinel; } void @@ -537,6 +623,7 @@ namespace xo { log && log("error in apply -> terminating app"); this->pc_ = VsmInstr::c_halt; + this->cont_ = VsmInstr::c_sentinel; return; } @@ -595,7 +682,7 @@ namespace xo { this->expr_ = apply_expr->arg(i_arg); this->pc_ = VsmInstr::c_eval; - //this->cont_ = VsmInstra::c_evalargs; // redundant, since preserved + this->cont_ = VsmInstr::c_evalargs; return; } else { @@ -633,7 +720,7 @@ namespace xo { } else { this->expr_ = apply_expr->arg(i_arg); this->pc_ = VsmInstr::c_eval; - //this->cont_ = VsmInstra::c_evalargs; // redundant, since preserved + this->cont_ = VsmInstr::c_evalargs; return; } @@ -655,6 +742,7 @@ namespace xo { this->stack_ = frame->parent(); this->local_env_ = frame->local_env(); this->pc_ = frame->cont(); + this->cont_ = VsmInstr::c_sentinel; } void @@ -682,9 +770,9 @@ namespace xo { } this->stack_ = frame->parent(); - this->cont_ = frame->cont(); this->expr_ = next_expr; this->pc_ = VsmInstr::c_eval; + this->cont_ = frame->cont(); } else { auto error = DRuntimeError::make(mm_.to_op(), "_do_ifelse_cont_op", @@ -698,6 +786,7 @@ namespace xo { // 3. have every vsm instruction check inputs for errors this->pc_ = VsmInstr::c_halt; + this->cont_ = VsmInstr::c_sentinel; } } @@ -722,13 +811,16 @@ namespace xo { this->stack_ = frame->parent(); this->pc_ = frame->cont(); + this->cont_ = VsmInstr::c_sentinel; + return; } else { frame->incr_i_seq(); - this->cont_ = VsmInstr::c_seq_cont; this->expr_ = (*seq_expr)[i_seq]; this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_seq_cont; + return; } } diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp index b815c079..852b6332 100644 --- a/xo-interpreter2/src/interpreter2/VsmInstr.cpp +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -11,10 +11,12 @@ namespace xo { vsm_opcode_descr(vsm_opcode x) { switch (x) { + case vsm_opcode::sentinel: return "sentinel"; case vsm_opcode::halt: return "halt"; case vsm_opcode::eval: return "eval"; case vsm_opcode::apply: return "apply"; case vsm_opcode::evalargs: return "evalargs"; + case vsm_opcode::def_cont: return "def_cont"; case vsm_opcode::apply_cont: return "apply_cont"; case vsm_opcode::ifelse_cont: return "ifelse_cont"; case vsm_opcode::seq_cont: return "seq_cont"; @@ -25,6 +27,9 @@ namespace xo { return "opcode?"; } + VsmInstr + VsmInstr::c_sentinel = VsmInstr(vsm_opcode::sentinel); + VsmInstr VsmInstr::c_halt = VsmInstr(vsm_opcode::halt); @@ -37,12 +42,15 @@ namespace xo { VsmInstr VsmInstr::c_evalargs = VsmInstr(vsm_opcode::evalargs); + VsmInstr + VsmInstr::c_def_cont = VsmInstr(vsm_opcode::def_cont); + VsmInstr VsmInstr::c_apply_cont = VsmInstr(vsm_opcode::apply_cont); VsmInstr VsmInstr::c_ifelse_cont = VsmInstr(vsm_opcode::ifelse_cont); - + VsmInstr VsmInstr::c_seq_cont = VsmInstr(vsm_opcode::seq_cont); } /*namespace scm*/ diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index dc9b31be..22c9bfb9 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -6,6 +6,7 @@ #include "interpreter2_register_facets.hpp" #include "DPrimitive_gco_2_gco_gco.hpp" +#include "VsmDefContFrame.hpp" #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "VsmApplyClosureFrame.hpp" @@ -13,6 +14,7 @@ #include "VsmSeqContFrame.hpp" #include "Primitive_gco_2_gco_gco.hpp" #include "Closure.hpp" +#include "GlobalEnv.hpp" #include "LocalEnv.hpp" #include "VsmRcx.hpp" @@ -39,6 +41,7 @@ namespace xo { // +- VsmApplyFrame // +- VsmEvalArgsFrame // +- VsmApplyClosureFrame + // +- VsmDefContFrame // +- VsmIfElseContFrame // \- VsmSeqContFrame @@ -51,12 +54,20 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); + // GlobalEnv + + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // LocalEnv FacetRegistry::register_impl(); @@ -84,8 +95,12 @@ namespace xo { log && log(xtag("DVsmApplyFrame.tseq", typeseq::id())); log && log(xtag("DVsmEvalArgsFrame.tseq", typeseq::id())); log && log(xtag("DVsmApplyClosureFrame.tseq", typeseq::id())); + log && log(xtag("DVsmDefContFrame.tseq", typeseq::id())); + log && log(xtag("DVsmDefContFrame.tseq", typeseq::id())); + log && log(xtag("DVsmIfElseContFrame.tseq", typeseq::id())); log && log(xtag("DVsmSeqContFrame.tseq", typeseq::id())); log && log(xtag("DClosure.tseq", typeseq::id())); + log && log(xtag("DGlobalEnv.tseq", typeseq::id())); log && log(xtag("DLocalEnv.tseq", typeseq::id())); log && log(xtag("DVsmRcx.tseq", typeseq::id())); diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 1a50c555..1af15c86 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -5,11 +5,13 @@ #include #include +#include #include #include #include #include #include +#include #ifdef NOT_YET #include @@ -32,6 +34,7 @@ namespace xo { using xo::scm::VsmResultExt; using xo::scm::DClosure; using xo::scm::DString; + using xo::scm::DUniqueString; // aks Symbol in lisp using xo::scm::DFloat; using xo::scm::DBoolean; using xo::scm::DInteger; @@ -42,6 +45,7 @@ namespace xo { using xo::mm::DArena; using xo::mm::ArenaConfig; using xo::facet::FacetRegistry; + using xo::facet::TypeRegistry; using span_type = xo::scm::VirtualSchematikaMachine::span_type; using Catch::Matchers::WithinAbs; @@ -81,6 +85,7 @@ namespace xo { aux_mm_.arena_.visit_pools(visitor); FacetRegistry::instance().visit_pools(visitor); + TypeRegistry::instance().visit_pools(visitor); vsm_.visit_pools(visitor); return true; @@ -298,7 +303,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - bool c_debug_flag = true; + bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); VsmFixture vsm_fixture(testname, c_debug_flag); @@ -333,6 +338,96 @@ namespace xo { log && vsm_fixture.log_memory_layout(&log); } + TEST_CASE("VirtualSchematikaMachine-def1", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res + = vsm.read_eval_print(span_type::from_cstr("def foo = 3.14159;"), + eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq()), + xtag("res.type", TypeRegistry::id2name(res.value()->_typeseq()))); + + // currently get not-implemented error + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE(strcmp(x->chars(), "foo") == 0); + + //log && log("runtime-error", xtag("ex.src", x->src_function()), xtag("ex.descr", x->error_descr())); + + //REQUIRE(x.data()->value() == 1.570796325); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + log && vsm_fixture.log_memory_layout(&log); + } + + TEST_CASE("VirtualSchematikaMachine-def2", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; + + bool eof_flag = false; + + vsm.begin_interactive_session(); + + span_type input = span_type::from_cstr("def foo = 3.14159; foo"); + + for (int i_expr = 0; i_expr < 2; ++i_expr) { + VsmResultExt res + = vsm.read_eval_print(input, eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq()), + xtag("res.type", TypeRegistry::id2name(res.value()->_typeseq()))); + + if (i_expr == 0) { + auto x = obj::from(*res.value()); + REQUIRE(x); + REQUIRE(strcmp(x->chars(), "foo") == 0); + + REQUIRE(res.remaining_.size() > 1); + + input = res.remaining_; + } else if (i_expr == 1) { + auto x = obj::from(*res.value()); + REQUIRE(x); + REQUIRE(x->value() == 3.14159); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + input = res.remaining_; + } + + ++i_expr; + } + + log && vsm_fixture.log_memory_layout(&log); + + } + } /*namespace ut*/ } /*namespace xo*/ diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index 7b758860..8d7248e5 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -75,9 +75,6 @@ namespace xo { requires (std::same_as> && ...) static DArray * array(obj mm, Args... args); - const obj & operator[](size_type index) const noexcept { return elts_[index]; } - obj & operator[](size_type index) noexcept { return elts_[index]; } - ///@} /** @defgroup darray-access acecss methods **/ ///@{ @@ -91,6 +88,10 @@ namespace xo { size_type size() const noexcept { return size_; } /** return element @p index of this array (0-based) **/ obj at(size_type index) const; + + const obj & operator[](size_type index) const noexcept { return elts_[index]; } + obj & operator[](size_type index) noexcept { return elts_[index]; } + ///@} /** @defgroup darray-iterators iterators **/ ///@{ @@ -106,6 +107,11 @@ namespace xo { /** @defgroup darray-general general methods **/ ///@{ + /** resize to @p new_size. @p new_size may not be larger than capacity + * Return true if resize was accomplished; false otherwise. + **/ + bool resize(size_type new_size) noexcept; + ///@} /** @defgroup darray-conversion-operators conversion operators **/ ///@{ diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index e1414eec..31ced92e 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -84,6 +84,19 @@ namespace xo { } } + bool + DArray::resize(size_type new_z) noexcept { + if (new_z >= capacity_) { + return false; + } else if (new_z > size_) { + // ensure new size is zeroed (we/re not zeroing if/when we shrink) + ::memset((std::byte *)(&elts_[size_]), 0, (std::byte *)(&elts_[new_z]) - (std::byte *)(&elts_[size_])); + } + + this->size_ = new_z; + return true; + } + // printing support bool diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 2dfba437..f2654e1c 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -71,6 +71,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_; } + DGlobalSymtab * global_symtab() const noexcept { return global_symtab_.data(); } DLocalSymtab * local_symtab() const noexcept { return local_symtab_; } const ParserResult & result() const noexcept { return result_; } @@ -315,6 +316,17 @@ namespace xo { **/ obj aux_alloc_; + /** global symbol table. + * Toplevel definitions go here. + * + * Uses mmap -> non-trivial destructor. + * + * TODO: may want to move ownership upstairs. + * if so, along with stringtable_. + * maybe new struct ParserState? + **/ + dp global_symtab_; + /** symbol table with local bindings. * non-null during parsing of lambda expressions. * Always allocated from @p expr_alloc_. @@ -323,15 +335,6 @@ namespace xo { **/ DLocalSymtab * local_symtab_ = nullptr; - /** global symbol table. - * Toplevel definitions go here. - * - * Uses mmap -> non-trivial destructor. - * - * TODO: may want to move ownership upstairs - **/ - dp global_symtab_; - /** current output from parser **/ ParserResult result_; diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 45b45c19..96de8628 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -183,6 +183,8 @@ namespace xo { /** scm-schematikaparser-access-methods **/ ///@{ + DGlobalSymtab * global_symtab() const noexcept; + bool debug_flag() const { return debug_flag_; } /** true if parser is at top-level, diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index 5a4243a1..efd031ca 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -54,6 +54,9 @@ namespace xo { /** non-trivial dtor because of @p parser **/ ~SchematikaReader() = default; + /** top-level symbol table **/ + DGlobalSymtab * global_symtab() const 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/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 1bb188cb..25b3bc7f 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -32,6 +32,12 @@ namespace xo { { } + DGlobalSymtab * + SchematikaParser::global_symtab() const noexcept + { + return psm_.global_symtab(); + } + bool SchematikaParser::is_at_toplevel() const { diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index 98d44112..c3e13254 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -24,6 +24,12 @@ namespace xo { { } + DGlobalSymtab * + SchematikaReader::global_symtab() const noexcept + { + return parser_.global_symtab(); + } + void SchematikaReader::visit_pools(const MemorySizeVisitor & visitor) const { diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index e4a0e1de..6153ecb7 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -117,6 +117,7 @@ namespace xo { aux_arena_.visit_pools(visitor); FacetRegistry::instance().visit_pools(visitor); + TypeRegistry::instance().visit_pools(visitor); expr_arena_->visit_pools(visitor); parser_->visit_pools(visitor); From 6bf4378132793740560a404f07b302622491bd7e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 17 Feb 2026 15:01:46 -0500 Subject: [PATCH 251/258] xo-interpreter2: global variable refs working in utest --- .../interpreter2/VirtualSchematikaMachine.cpp | 21 ++++++++++++++----- .../utest/VirtualSchematikaMachine.test.cpp | 8 +++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index aa0861f5..e7964ab4 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -113,6 +113,8 @@ namespace xo { return VsmResultExt(); } + reader_.reset_result(); + auto [expr, remaining, error1] = reader_.read_expr(input, eof); @@ -392,12 +394,21 @@ namespace xo { Binding b = var->path(); - if (!local_env_) { - // need lookup on global_env_ - assert(false); + if (local_env_) { + auto value = local_env_->lookup_value(b); + + if (value) { + this->value_ = VsmResult(value); + + this->pc_ = this->cont_; + this->cont_ = VsmInstr::c_sentinel; + return; + } } - auto value = local_env_->lookup_value(b); + // no local binding. perhaps there's a global binding + + auto value = global_env_->lookup_value(b); if (value) { this->value_ = VsmResult(value); @@ -407,7 +418,7 @@ namespace xo { return; } - // no binding + // no local or global binding auto error = DRuntimeError::make(mm_.to_op(), "_do_eval_varref_op", diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 1af15c86..3d1a76a8 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -391,9 +391,11 @@ namespace xo { vsm.begin_interactive_session(); - span_type input = span_type::from_cstr("def foo = 3.14159; foo"); + span_type input = span_type::from_cstr("def foo = 3.14159; foo;"); for (int i_expr = 0; i_expr < 2; ++i_expr) { + log && log(xtag("input", input)); + VsmResultExt res = vsm.read_eval_print(input, eof_flag); @@ -414,14 +416,12 @@ namespace xo { } else if (i_expr == 1) { auto x = obj::from(*res.value()); REQUIRE(x); - REQUIRE(x->value() == 3.14159); + REQUIRE_THAT(x->value(), WithinAbs(3.14159, 1e-6)); REQUIRE(res.remaining_.size() == 1); REQUIRE(*res.remaining_.lo() == '\n'); input = res.remaining_; } - - ++i_expr; } log && vsm_fixture.log_memory_layout(&log); From ec0c8feb36c37c3e4362328da96039ca71cc5413 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 17 Feb 2026 15:55:11 -0500 Subject: [PATCH 252/258] xo-cmake: bugfix: dependency for genfacet target --- xo-cmake/cmake/xo_macros/xo_cxx.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xo-cmake/cmake/xo_macros/xo_cxx.cmake b/xo-cmake/cmake/xo_macros/xo_cxx.cmake index 9d94e9b7..38d01df3 100644 --- a/xo-cmake/cmake/xo_macros/xo_cxx.cmake +++ b/xo-cmake/cmake/xo_macros/xo_cxx.cmake @@ -1709,7 +1709,7 @@ function(xo_add_genfacet) ) # Create a target for this generation - add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}) + add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}.out) set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET}) endfunction() From 4a5d924676b6c8de8193682204737fb9f75375ca Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 17 Feb 2026 16:48:20 -0500 Subject: [PATCH 253/258] xo-reader2: allow formals w/out explicit type --- xo-reader2/idl/SyntaxStateMachine.json5 | 11 ++ .../xo/reader2/DExpectFormalArgSsm.hpp | 6 ++ .../xo/reader2/DExpectFormalArglistSsm.hpp | 24 +++++ .../xo/reader2/DSyntaxStateMachine.hpp | 17 +++ .../include/xo/reader2/ParserStateMachine.hpp | 19 +++- .../xo/reader2/ssm/ASyntaxStateMachine.hpp | 2 + .../reader2/ssm/ISyntaxStateMachine_Any.hpp | 1 + .../ssm/ISyntaxStateMachine_DApplySsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DDefineSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectExprSsm.hpp | 2 + ...SyntaxStateMachine_DExpectFormalArgSsm.hpp | 2 + ...axStateMachine_DExpectFormalArglistSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectSymbolSsm.hpp | 2 + .../ISyntaxStateMachine_DExpectTypeSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DIfElseSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DLambdaSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DParenSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DProgressSsm.hpp | 2 + .../ssm/ISyntaxStateMachine_DSequenceSsm.hpp | 2 + .../ISyntaxStateMachine_DToplevelSeqSsm.hpp | 2 + .../reader2/ssm/ISyntaxStateMachine_Xfer.hpp | 3 + .../xo/reader2/ssm/RSyntaxStateMachine.hpp | 3 + .../src/reader2/DExpectFormalArgSsm.cpp | 23 +++- .../src/reader2/DExpectFormalArglistSsm.cpp | 102 ++++++++++++------ .../src/reader2/ISyntaxStateMachine_Any.cpp | 6 ++ .../reader2/ISyntaxStateMachine_DApplySsm.cpp | 5 + .../ISyntaxStateMachine_DDefineSsm.cpp | 5 + .../ISyntaxStateMachine_DExpectExprSsm.cpp | 5 + ...SyntaxStateMachine_DExpectFormalArgSsm.cpp | 5 + ...axStateMachine_DExpectFormalArglistSsm.cpp | 5 + .../ISyntaxStateMachine_DExpectSymbolSsm.cpp | 5 + .../ISyntaxStateMachine_DExpectTypeSsm.cpp | 5 + .../ISyntaxStateMachine_DIfElseSsm.cpp | 5 + .../ISyntaxStateMachine_DLambdaSsm.cpp | 5 + .../reader2/ISyntaxStateMachine_DParenSsm.cpp | 5 + .../ISyntaxStateMachine_DProgressSsm.cpp | 5 + .../ISyntaxStateMachine_DSequenceSsm.cpp | 5 + .../ISyntaxStateMachine_DToplevelSeqSsm.cpp | 5 + xo-reader2/src/reader2/ParserStateMachine.cpp | 39 +++++++ 39 files changed, 311 insertions(+), 36 deletions(-) diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 210a43a4..4cafd9c3 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -85,6 +85,17 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_formal_with_token", + doc: ["operate state machine for formal emitted by nested ssm"], + return_type: "void", + args: [ + {type: "const DUniqueString *", name: "param_name"}, + {type: "TypeDescr", name: "param_type"}, + {type: "const Token &", name: "tk"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, { name: "on_parsed_formal_arglist", doc: ["consume formal arglist emitted by nested ssm"], diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp index 62f5ae34..f1bd7867 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArgSsm.hpp @@ -79,6 +79,12 @@ namespace xo { void on_colon_token(const Token & tk, ParserStateMachine * p_psm); + /** update state on incoming rightparen token @p tk; + * with overall parser state in @p p_psm + **/ + void on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectformalargssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index 203c7293..3129f0dc 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -55,6 +55,7 @@ namespace xo { class DExpectFormalArglistSsm : public DSyntaxStateMachine { public: using Super = DSyntaxStateMachine; + using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; @@ -108,6 +109,14 @@ namespace xo { void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** update state to consume parsed formal (name,type) emitted + * by nested ssm, that's followed immediately by token @p tk. + * overall parser state in @p *p_psm + **/ + void on_parsed_formal_with_token(const DUniqueString * param_name, + TypeDescr param_type, + const Token & tk, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-expectformalarglistssm-printable-facet printable facet methods **/ @@ -117,6 +126,21 @@ namespace xo { ///@} + private: + /** @defgroup scm-expectformalarglistssm-impl-methods **/ + ///@{ + + /** update local state to include parsed formal (param_name, param_type). + * If stack memory needed, get from @p parser_alloc. + * Lifetime until formal arglist completely parsed + **/ + void _accept_formal(obj expr_alloc, + DArena & parser_alloc, + const DUniqueString * param_name, + TypeDescr param_type); + + ///@} + private: /** parsing state-machine state **/ formalarglstatetype fastate_ = formalarglstatetype::argl_0; diff --git a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp index 947d3b84..5851390b 100644 --- a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp @@ -83,6 +83,23 @@ namespace xo { self.get_expect_str()); } + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_parsed_formal_with_token(const DUniqueString * param_name, + TypeDescr param_type, + const Token & tk, + ParserStateMachine * p_psm) + { + // starting with c++23 can use "this auto&& self" instead + Derived & self = reinterpret_cast(*this); + + p_psm->illegal_parsed_formal_with_token(Derived::ssm_classname(), + param_name, + param_type, + tk, + self.get_expect_str()); + } + /** Default implementation for required SyntaxStateMachine facet method * * arglist is DArray of obj diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index f2654e1c..bec90ae8 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -149,12 +149,20 @@ namespace xo { **/ void on_parsed_typedescr(TypeDescr td); - /** update state to consume param (name, value) emitted by + /** update state to consume param (name, type) emitted by * nested (expired) parsing state **/ void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type); + /** update state to consume formal parameter (name, type) + * emitted by nested (now expired) parsing state, + * with trailing token @p tk + **/ + void on_parsed_formal_with_token(const DUniqueString * param_name, + TypeDescr param_type, + const Token & tk); + /** update state to consume formal arugment list * emitted by nested (expired) parsing state **/ @@ -231,6 +239,15 @@ namespace xo { TypeDescr param_type, std::string_view expect_str); + /** report illegal parsed formal (param_name, param_type) from nested ssm; + * presented with immediately-following input token @p tk. + **/ + void illegal_parsed_formal_with_token(std::string_view ssm_name, + const DUniqueString * param_name, + TypeDescr param_type, + const Token & tk, + std::string_view expect_str); + /** @p arglist stores obj pointers. **/ void illegal_parsed_formal_arglist(std::string_view ssm_name, diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index 93a0e402..6b2976e1 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -67,6 +67,8 @@ public: virtual void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) = 0; /** operate state machine for formal emitted by nested ssm **/ virtual void on_parsed_formal(Opaque data, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) = 0; + /** operate state machine for formal emitted by nested ssm **/ + virtual void on_parsed_formal_with_token(Opaque data, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) = 0; /** consume formal arglist emitted by nested ssm **/ virtual void on_parsed_formal_arglist(Opaque data, DArray * arglist, ParserStateMachine * p_psm) = 0; /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 05d292cc..8eb513c9 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -67,6 +67,7 @@ namespace scm { [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; [[noreturn]] void on_parsed_formal(Opaque, const DUniqueString *, TypeDescr, ParserStateMachine *) override; + [[noreturn]] void on_parsed_formal_with_token(Opaque, const DUniqueString *, TypeDescr, const Token &, ParserStateMachine *) override; [[noreturn]] void on_parsed_formal_arglist(Opaque, DArray *, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression(Opaque, obj, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression_with_token(Opaque, obj, const Token &, ParserStateMachine *) override; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp index d6b1a53e..eb9b10fa 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DApplySsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DApplySsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DApplySsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DApplySsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index 0a8ff60d..8fee27fd 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DDefineSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DDefineSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DDefineSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index e425386e..b452860f 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectExprSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DExpectExprSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DExpectExprSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp index 4c8e8c44..466dce8b 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectFormalArgSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectFormalArgSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DExpectFormalArgSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DExpectFormalArgSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp index 2540684c..571255f9 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectFormalArglistSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectFormalArglistSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DExpectFormalArglistSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DExpectFormalArglistSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index 4b4ea7dd..d8367631 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectSymbolSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DExpectSymbolSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DExpectSymbolSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index 49c0ffe4..87b5db71 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DExpectTypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DExpectTypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DExpectTypeSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp index f1594b02..d1373a1a 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DIfElseSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DIfElseSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DIfElseSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DIfElseSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DIfElseSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp index 062de20c..3c945b94 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DLambdaSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DLambdaSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DLambdaSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DLambdaSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DLambdaSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DParenSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DParenSsm.hpp index 33be5e16..19e4a89b 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DParenSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DParenSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DParenSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DParenSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DParenSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DParenSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index 0d776976..13a2d461 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DProgressSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DProgressSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DProgressSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp index 90c17b36..7e0cfb42 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DSequenceSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DSequenceSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DSequenceSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DSequenceSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp index 1d91c13d..69a3c71f 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp @@ -62,6 +62,8 @@ namespace xo { static void on_parsed_typedescr(DToplevelSeqSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** operate state machine for formal emitted by nested ssm **/ static void on_parsed_formal(DToplevelSeqSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DToplevelSeqSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); /** consume formal arglist emitted by nested ssm **/ static void on_parsed_formal_arglist(DToplevelSeqSsm & self, DArray * arglist, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index 971f08b8..30c87269 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -67,6 +67,9 @@ namespace scm { void on_parsed_formal(Opaque data, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) override { return I::on_parsed_formal(_dcast(data), param_name, param_type, p_psm); } + void on_parsed_formal_with_token(Opaque data, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_parsed_formal_with_token(_dcast(data), param_name, param_type, tk, p_psm); + } void on_parsed_formal_arglist(Opaque data, DArray * arglist, ParserStateMachine * p_psm) override { return I::on_parsed_formal_arglist(_dcast(data), arglist, p_psm); } diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 28be39be..8012b657 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -73,6 +73,9 @@ public: void on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) { return O::iface()->on_parsed_formal(O::data(), param_name, param_type, p_psm); } + void on_parsed_formal_with_token(const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_formal_with_token(O::data(), param_name, param_type, tk, p_psm); + } void on_parsed_formal_arglist(DArray * arglist, ParserStateMachine * p_psm) { return O::iface()->on_parsed_formal_arglist(O::data(), arglist, p_psm); } diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index 47d55f6a..bbb9048e 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -97,6 +97,10 @@ namespace xo { case tokentype::tk_colon: this->on_colon_token(tk, p_psm); return; + case tokentype::tk_rightparen: + this->on_rightparen_token(tk, p_psm); + return; + // all the not-yet-handled cases case tokentype::tk_leftparen: case tokentype::tk_lambda: @@ -110,7 +114,6 @@ namespace xo { case tokentype::tk_bool: case tokentype::tk_semicolon: case tokentype::tk_invalid: - case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: case tokentype::tk_leftbrace: @@ -159,6 +162,24 @@ namespace xo { Super::on_token(tk, p_psm); } + void + DExpectFormalArgSsm::on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (fstate_ == formalstatetype::formal_1) { + // formal with no type annotation + + assert(name_); + + p_psm->pop_ssm(); + p_psm->on_parsed_formal_with_token(name_, nullptr, tk); + + return; + } + + Super::on_token(tk, p_psm); + } + void DExpectFormalArgSsm::on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index 3ce11ae8..53dcf30c 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -176,6 +176,49 @@ namespace xo { Super::on_token(tk, p_psm); } + + void + DExpectFormalArglistSsm::_accept_formal(obj expr_alloc, + DArena & parser_alloc, + const DUniqueString * param_name, + TypeDescr param_type) + { + /* note: param_type can be nullptr */ + TypeRef typeref + = TypeRef::dwim(TypeRef::prefix_type::from_chars("formal"), param_type); + + DVariable * var = DVariable::make(expr_alloc, + param_name, + typeref); + + // need AGCObject facet to use DArray here. + // May want to have gc feature that allows it to use + // FacetRegistry on memory that stores obj + // + // In this case doesn't matter since DExpectFormalArglistSsm not actually collected! + + obj var_o(var); + + if (argl_->size() == argl_->capacity()) { + // need to expand argl_ capacity. + // If DArena were to allow it (i.e. offer a realloc() feature, + // could do this in place since this SSM is at the top of the parser stack. + + obj mm(&parser_alloc); + DArray * argl_2x = DArray::empty(mm, 2 * argl_->capacity()); + + for (DArray::size_type i = 0, n = argl_->size(); i < n; ++i) { + // TODO: prefer non-bounds-checked access here + argl_2x->push_back(argl_->at(i)); + } + + // update in place + this->argl_ = argl_2x; + } + + this->argl_->push_back(var_o); + } + void DExpectFormalArglistSsm::on_parsed_formal(const DUniqueString * param_name, TypeDescr param_type, @@ -184,46 +227,37 @@ namespace xo { if (fastate_ == formalarglstatetype::argl_1a) { this->fastate_ = formalarglstatetype::argl_1b; - TypeRef typeref - = TypeRef::dwim(TypeRef::prefix_type::from_chars("formal"), param_type); - - DVariable * var = DVariable::make(p_psm->expr_alloc(), - param_name, - typeref); - - // need AGCObject facet to use DArray here. - // May want to have gc feature that allows it to use - // FacetRegistry on memory that stores obj - // - // In this case doesn't matter since DExpectFormalArglistSsm not actually collected! - - obj var_o(var); - - if (argl_->size() == argl_->capacity()) { - // need to expand argl_ capacity. - // If DArena were to allow it (i.e. offer a realloc() feature, - // could do this in place since this SSM is at the top of the parser stack. - - obj mm(&(p_psm->parser_alloc())); - - DArray * argl_2x = DArray::empty(mm, 2 * argl_->capacity()); - - for (DArray::size_type i = 0, n = argl_->size(); i < n; ++i) { - // TODO: prefer non-bounds-checked access here - argl_2x->push_back(argl_->at(i)); - } - - // update in place - this->argl_ = argl_2x; - } - - this->argl_->push_back(var_o); + this->_accept_formal(p_psm->expr_alloc(), + p_psm->parser_alloc(), + param_name, + param_type); return; } Super::on_parsed_formal(param_name, param_type, p_psm); } + void + DExpectFormalArglistSsm::on_parsed_formal_with_token(const DUniqueString * param_name, + TypeDescr param_type, + const Token & tk, + ParserStateMachine * p_psm) + { + if (fastate_ == formalarglstatetype::argl_1a) { + this->fastate_ = formalarglstatetype::argl_1b; + + this->_accept_formal(p_psm->expr_alloc(), + p_psm->parser_alloc(), + param_name, + param_type); + + this->on_token(tk, p_psm); + return; + } + + Super::on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + void DExpectFormalArglistSsm::on_leftparen_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index 6a78fa5e..393fea04 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -58,6 +58,12 @@ ISyntaxStateMachine_Any::on_parsed_formal(Opaque, const DUniqueString *, TypeDes _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_formal_with_token(Opaque, const DUniqueString *, TypeDescr, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_parsed_formal_arglist(Opaque, DArray *, ParserStateMachine *) -> void { diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DApplySsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DApplySsm.cpp index 2164ae04..bcc672a4 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DApplySsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DApplySsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DApplySsm::on_parsed_formal_with_token(DApplySsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DApplySsm::on_parsed_formal_arglist(DApplySsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index 8940c1b5..dad9d0e8 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DDefineSsm::on_parsed_formal_with_token(DDefineSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DDefineSsm::on_parsed_formal_arglist(DDefineSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index 17f0ec3f..855135e6 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_formal_with_token(DExpectExprSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DExpectExprSsm::on_parsed_formal_arglist(DExpectExprSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp index 77afbe60..948a4fe2 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArgSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_formal_with_token(DExpectFormalArgSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DExpectFormalArgSsm::on_parsed_formal_arglist(DExpectFormalArgSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp index 619f2ceb..f56a90d2 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_formal_with_token(DExpectFormalArglistSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_formal_arglist(DExpectFormalArglistSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index efd7b893..77f0fd10 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_formal_with_token(DExpectSymbolSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_formal_arglist(DExpectSymbolSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 32e07aaa..f5f650ae 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_formal_with_token(DExpectTypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DExpectTypeSsm::on_parsed_formal_arglist(DExpectTypeSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp index 3dbd66a8..d5a78844 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DIfElseSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DIfElseSsm::on_parsed_formal_with_token(DIfElseSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DIfElseSsm::on_parsed_formal_arglist(DIfElseSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp index 967e328a..f99ab05d 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DLambdaSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DLambdaSsm::on_parsed_formal_with_token(DLambdaSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DLambdaSsm::on_parsed_formal_arglist(DLambdaSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp index 1bb2ea83..0773ff3f 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DParenSsm::on_parsed_formal_with_token(DParenSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DParenSsm::on_parsed_formal_arglist(DParenSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 4cb25bf4..0e1e4a4c 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DProgressSsm::on_parsed_formal_with_token(DProgressSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DProgressSsm::on_parsed_formal_arglist(DProgressSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp index b27f25ba..bc6ab823 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DSequenceSsm::on_parsed_formal_with_token(DSequenceSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DSequenceSsm::on_parsed_formal_arglist(DSequenceSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp index 4dfe35a8..6850aee1 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp @@ -48,6 +48,11 @@ namespace xo { self.on_parsed_formal(param_name, param_type, p_psm); } auto + ISyntaxStateMachine_DToplevelSeqSsm::on_parsed_formal_with_token(DToplevelSeqSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto ISyntaxStateMachine_DToplevelSeqSsm::on_parsed_formal_arglist(DToplevelSeqSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void { self.on_parsed_formal_arglist(arglist, p_psm); diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 856a8215..dee9e4b2 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -286,6 +286,18 @@ namespace xo { this->stack_->top().on_parsed_formal(sym, td, this); } + void + ParserStateMachine::on_parsed_formal_with_token(const DUniqueString * sym, + TypeDescr td, + const Token & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("sym", std::string_view(*sym)), xtag("td", td), xtag("tk", tk)); + + assert(stack_); + + this->stack_->top().on_parsed_formal_with_token(sym, td, tk, this); + } + void ParserStateMachine::on_parsed_formal_arglist(DArray * arglist) { @@ -446,6 +458,33 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + void + ParserStateMachine::illegal_parsed_formal_with_token(std::string_view ssm_name, + const DUniqueString * param_name, + TypeDescr param_type, + const Token & tk, + std::string_view expect_str) + { + // TODO: + // - want to write error message using DArena + // - need something like log_streambuf and/or tostr() that's arena-aware + + auto errmsg_string = tostr("Unexpected formal", + xtag("param_name", std::string_view(*param_name)), + xtag("param_type", param_type), + xtag("tk", tk), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_parsed_formal")); + + assert(expr_alloc_); + + auto errmsg = DString::from_view(expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } + void ParserStateMachine::illegal_parsed_formal_arglist(std::string_view ssm_name, DArray * arglist, From c7d820a92b0434964e09960a5572bebf0a867362 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 17 Feb 2026 18:32:14 -0500 Subject: [PATCH 254/258] xo-procedure2: + generic subtract primitive --- .../include/xo/procedure2/init_primitives.hpp | 9 ++- .../src/procedure2/init_primitives.cpp | 67 ++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/xo-procedure2/include/xo/procedure2/init_primitives.hpp b/xo-procedure2/include/xo/procedure2/init_primitives.hpp index d2d51a59..6747fa6b 100644 --- a/xo-procedure2/include/xo/procedure2/init_primitives.hpp +++ b/xo-procedure2/include/xo/procedure2/init_primitives.hpp @@ -15,13 +15,20 @@ namespace xo { #endif struct Primitives { - /** polymorphich multiply + /** polymorphic multiply * * TODO: this will want to move to xo-numeric/ * so we can dispatch on vector, matrix, function types **/ static DPrimitive_gco_2_gco_gco s_mul_gco_gco_pm; + /** polymorphic subtract + * + * TODO: this will want to move to xo-numeric/ + * so we can dispatch on vector, matrix, function types + **/ + static DPrimitive_gco_2_gco_gco s_sub_gco_gco_pm; + /** polymorphic equality comparison * * TODO: this will want to move to x-numeric/ diff --git a/xo-procedure2/src/procedure2/init_primitives.cpp b/xo-procedure2/src/procedure2/init_primitives.cpp index c1eceada..f3759f4b 100644 --- a/xo-procedure2/src/procedure2/init_primitives.cpp +++ b/xo-procedure2/src/procedure2/init_primitives.cpp @@ -99,6 +99,66 @@ namespace xo { return obj(); } + obj + sub_gco_gco(obj rcx, + obj x_gco, + obj y_gco) + { + using xo::reflect::typeseq; + + obj mm = rcx.allocator(); + + // PLACEHOLDER + + // TODO: + // 1. move this to xo-numeric2/ when available + // 2. at that point will require polymorphic dispatch + // on argument representations, analogous to dispatch + // in FacetRegistry + + typeseq x_tseq = x_gco._typeseq(); + typeseq y_tseq = y_gco._typeseq(); + + // FOR NOW: just test runtime values + // + if (x_tseq == typeseq::id()) { + // i64 * .. + long x = GCObjectConversion::from_gco(mm, x_gco); + + if (y_tseq == typeseq::id()) { + // i64 * i64 + long y = GCObjectConversion::from_gco(mm, y_gco); + + return DInteger::box(mm, x - y); + } else if (y_tseq == typeseq::id()) { + // i64 * f64 + double y = GCObjectConversion::from_gco(mm, y_gco); + + return DFloat::box(mm, x - y); + } + } else if (x_tseq == typeseq::id()) { + if (y_tseq == typeseq::id()) { + // f64 * i64. + double x = GCObjectConversion::from_gco(mm, x_gco); + long y = GCObjectConversion::from_gco(mm, y_gco); + + return DFloat::box(mm, x - y); + } else if (y_tseq == typeseq::id()) { + // f64 * f64. + double x = GCObjectConversion::from_gco(mm, x_gco); + double y = GCObjectConversion::from_gco(mm, y_gco); + + return DFloat::box(mm, x - y); + } + } + + // here: error + throw std::runtime_error(tostr("sub_gco_gco: unexpected argument types xt,yt", + xtag("x.tseq", x_tseq), + xtag("y.tseq", y_tseq))); + return obj(); + } + obj equal_gco_gco(obj rcx, obj x_gco, @@ -113,7 +173,7 @@ namespace xo { // TODO // 1. move this to xo-numeric2/ when available // 2. at that point will require polymorphic dispatch on argument representations. - // + // typeseq x_tseq = x_gco._typeseq(); typeseq y_tseq = y_gco._typeseq(); @@ -150,7 +210,7 @@ namespace xo { return DFloat::box(mm, x == y); } } - + // here: error throw std::runtime_error(tostr("mul_gco_gco: unexpected argument types xt,yt", xtag("x.tseq", x_tseq), @@ -198,6 +258,9 @@ namespace xo { DPrimitive_gco_2_gco_gco Primitives::s_mul_gco_gco_pm("_mul", &mul_gco_gco); + DPrimitive_gco_2_gco_gco + Primitives::s_sub_gco_gco_pm("_sub", &sub_gco_gco); + DPrimitive_gco_2_gco_gco Primitives::s_equal_gco_gco_pm("_equal", &equal_gco_gco); From 4a3c8e794aed8556a1abd7026b4ce8d82c0305f8 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 17 Feb 2026 18:32:41 -0500 Subject: [PATCH 255/258] xo-reader2: recursive top-level function definition works --- .../include/xo/reader2/DExpectExprSsm.hpp | 16 +++++ xo-reader2/include/xo/reader2/DParenSsm.hpp | 8 +++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 43 ++++++++++-- xo-reader2/src/reader2/DIfElseSsm.cpp | 65 +++++++++++++++++-- xo-reader2/src/reader2/DParenSsm.cpp | 16 +++++ xo-reader2/src/reader2/DProgressSsm.cpp | 25 ++++++- xo-reader2/utest/SchematikaParser.test.cpp | 62 +++++++++++++++++- 7 files changed, 222 insertions(+), 13 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index c963c9c1..7600948c 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -51,6 +51,12 @@ namespace xo { /** @defgroup scm-expectexpr-methods general methods **/ ///@{ + /** update state for this syntax on incoming leftparen token @p tk, + * with overall parser state in @p p_psm + **/ + void on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming leftbrace token @p tk, * with overall parser state in @p p_psm **/ @@ -81,8 +87,18 @@ namespace xo { void on_string_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming if-token @p tk, + * overall parser state in @p p_psm. + * + * action: start nested if-else ssm + **/ + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming lambda token @p tk, * overall parser state in @p p_psm + * + * action: start nested lambda ssm **/ void on_lambda_token(const Token & tk, ParserStateMachine * p_psm); diff --git a/xo-reader2/include/xo/reader2/DParenSsm.hpp b/xo-reader2/include/xo/reader2/DParenSsm.hpp index 818e0470..05c3926b 100644 --- a/xo-reader2/include/xo/reader2/DParenSsm.hpp +++ b/xo-reader2/include/xo/reader2/DParenSsm.hpp @@ -116,6 +116,14 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update ssm for expression @p expr (emitted by nested ssm) + * that's immediately followed by token @p tk + * with overall parser state in @p p_psm + **/ + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psmn); + ///@} /** @defgroup scm-parenssm-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index a2db5967..445ee76d 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -8,6 +8,7 @@ #include "SyntaxStateMachine.hpp" #include "ssm/ISyntaxStateMachine_DProgressSsm.hpp" #include "DSequenceSsm.hpp" +#include "IfElseSsm.hpp" #include "LambdaSsm.hpp" #include "syntaxstatetype.hpp" #include @@ -103,9 +104,9 @@ namespace xo { DExpectExprSsm::get_expect_str() const noexcept { if (allow_defs_) { - return "def|lambda|lparen|lbrace|literal|var"; + return "def|if|lambda|lparen|lbrace|literal|var"; } else { - return "lambda|lparen|lbrace|literal|var"; + return "if|lambda|lparen|lbrace|literal|var"; } } @@ -116,6 +117,10 @@ namespace xo { scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); switch (tk.tk_type()) { + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + case tokentype::tk_leftbrace: this->on_leftbrace_token(tk, p_psm); return; @@ -144,17 +149,19 @@ namespace xo { this->on_bool_token(tk, p_psm); return; + case tokentype::tk_if: + this->on_if_token(tk, p_psm); + return; + case tokentype::tk_lambda: this->on_lambda_token(tk, p_psm); return; // all the not-yet handled cases case tokentype::tk_invalid: - case tokentype::tk_if: case tokentype::tk_singleassign: case tokentype::tk_colon: case tokentype::tk_semicolon: - case tokentype::tk_leftparen: case tokentype::tk_rightparen: case tokentype::tk_leftbracket: case tokentype::tk_rightbracket: @@ -187,6 +194,22 @@ namespace xo { Super::on_token(tk, p_psm); } + void + DExpectExprSsm::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + // need progress ssm here because this is allowed: + // + // if (foo) > 5 then ... + // + // Start progress ssm, delegate incoming token thereto + // + + DProgressSsm::start(p_psm->parser_alloc(), + p_psm); + p_psm->on_token(tk); + } + void DExpectExprSsm::on_leftbrace_token(const Token & tk, ParserStateMachine * p_psm) @@ -388,6 +411,18 @@ namespace xo { p_psm); } + void + DExpectExprSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DIfElseSsm::start(p_psm->parser_alloc(), + p_psm->expr_alloc(), + p_psm); + // TODO: should send if-token here + } + void DExpectExprSsm::on_lambda_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index e78d187b..b7d150af 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -423,14 +423,71 @@ namespace xo { // TODO: may consider allowing if-else to terminate on other particular tokens // e.g. ')' - if ((tk.tk_type() == tokentype::tk_then) - || (tk.tk_type() == tokentype::tk_else) - || (tk.tk_type() == tokentype::tk_semicolon)) - { + switch (ifstate_) { + case ifexprstatetype::invalid: + case ifexprstatetype::N: + // impossible + assert(false); + break; + case ifexprstatetype::if_0: + // also unreachable + break; + case ifexprstatetype::if_1: + // only ok if tk-type is tk_then. + if (tk.tk_type() == tokentype::tk_then) { + // advance to if_2 -then-> if_3 this->on_parsed_expression(expr, p_psm); this->on_token(tk, p_psm); return; } + break; + case ifexprstatetype::if_2: + // illegal, not expecting expression + break; + case ifexprstatetype::if_3: + // incoming expr argument is sufficient to complete this if-else + // but may continue on else-token + if (tk.tk_type() == tokentype::tk_else) { + // advance to if_4 -else-> if_5 + this->on_parsed_expression(expr, p_psm); + this->on_token(tk, p_psm); + return; + } else if ((tk.tk_type() == tokentype::tk_semicolon) + || (tk.tk_type() == tokentype::tk_rightparen) + || (tk.tk_type() == tokentype::tk_rightbrace)) { + + this->on_parsed_expression(expr, p_psm); + p_psm->pop_ssm(); + p_psm->on_parsed_expression_with_token(if_expr_, tk); + return; + } + + break; + case ifexprstatetype::if_4: + // illegal, not expecting expression + break; + + case ifexprstatetype::if_5: + // incoming expr argument completes this if-else + // advance to if_6 + if ((tk.tk_type() == tokentype::tk_semicolon) + || (tk.tk_type() == tokentype::tk_rightparen) + || (tk.tk_type() == tokentype::tk_rightbrace)) + { + // attaches expr as else- branch + this->on_parsed_expression(expr, p_psm); + + p_psm->pop_ssm(); + p_psm->on_parsed_expression_with_token(if_expr_, tk); + return; + } + break; + + case ifexprstatetype::if_6: + // illegal, not expecting expression + break; + + } Super::on_parsed_expression_with_token(expr, tk, p_psm); } diff --git a/xo-reader2/src/reader2/DParenSsm.cpp b/xo-reader2/src/reader2/DParenSsm.cpp index ad86ddd5..b89dec52 100644 --- a/xo-reader2/src/reader2/DParenSsm.cpp +++ b/xo-reader2/src/reader2/DParenSsm.cpp @@ -364,7 +364,23 @@ namespace xo { } Super::on_parsed_expression(expr, p_psm); + } + void + DParenSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) + { + if (parenstate_ == parenexprstatetype::lparen_1) { + this->parenstate_ = parenexprstatetype::lparen_2; + this->expr_ = expr; + + this->on_token(tk, p_psm); + + return; + } + + Super::on_parsed_expression(expr, p_psm); } #ifdef NOT_YET diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 4af449c0..72ec3e93 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -41,6 +41,7 @@ namespace xo { using xo::scm::Variable; using xo::scm::Apply; #endif + using xo::mm::AGCObject; using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::facet::with_facet; @@ -214,7 +215,7 @@ namespace xo { if (!lhs_) { return "expr1|leftparen"; } else if (op_type_ == optype::invalid) { - return "oper|semicolon|rightparen|righbrace"; + return "oper|semicolon|rightparen|rightbrace"; } else { return "expr2|leftparen"; } @@ -293,10 +294,10 @@ namespace xo { case tokentype::tk_assign: case tokentype::tk_yields: case tokentype::tk_plus: - case tokentype::tk_minus: break; case tokentype::tk_star: + case tokentype::tk_minus: case tokentype::tk_cmpeq: this->on_operator_token(tk, p_psm); return; @@ -1244,7 +1245,6 @@ namespace xo { case optype::op_great: case optype::op_great_equal: case optype::op_add: - case optype::op_subtract: assert(false); break; @@ -1286,6 +1286,24 @@ namespace xo { // TODO: implement binary operator expression assembly assert(false); break; + case optype::op_subtract: /* editor bait: op_minus */ + { + auto pm_obj = (with_facet::mkobj + (&Primitives::s_sub_gco_gco_pm)); + auto fn_expr = (DConstant::make + (p_psm->expr_alloc(), pm_obj)); + + // see comment on op_multiply re need for poly impl + + TypeRef tref = TypeRef::dwim + (TypeRef::prefix_type::from_chars("_sub_gco"), + nullptr); + + return DApplyExpr::make2(p_psm->expr_alloc(), + tref, fn_expr, lhs_, rhs_); + } + + break; #ifdef NOT_YET case optype::op_assign: @@ -1308,6 +1326,7 @@ case optype::op_equal: if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { return Apply::make_cmp_eq_i64(lhs_, rhs_); } else { + this->apply_type_error(c_self_name, op_type_, lhs_, rhs_, p_psm); return nullptr; diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 6153ecb7..2b92161a 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -274,7 +274,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); @@ -809,7 +809,7 @@ namespace xo { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); @@ -861,6 +861,64 @@ namespace xo { log && fixture.log_memory_layout(&log); } + TEST_CASE("SchematikaParser-batch-def2", "[reader2][SchematikaParser]") + { + // top-level recursive function definition + + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * def fact = lambda (n) { if (n == 0) then 1 else n * fact(n - 1) }; + * ^ ^ ^ ^ ^^^ ^ ^ ^^ ^ ^^ ^ ^ ^ ^ ^ ^ ^^ ^ ^^ ^^ + * 0 1 2 3 4|6 7 8 9| b c| e f g h i j k| m n| p| + * 5 a d l o q + **/ + + std::vector tk_v{ + /* [ 0] */ Token::def_token(), + + /* [ 1] */ Token::symbol_token("fact"), + /* [ 2] */ Token::singleassign_token(), + /* [ 3] */ Token::lambda_token(), + /* [ 4] */ Token::leftparen_token(), + /* [ 5] */ Token::symbol_token("n"), + /* [ 6] */ Token::rightparen_token(), + /* [ 7] */ Token::leftbrace_token(), + /* [ 8] */ Token::if_token(), + /* [ 9] */ Token::leftparen_token(), + /* [ a] */ Token::symbol_token("n"), + /* [ b] */ Token::cmpeq_token(), + /* [ c] */ Token::i64_token("0"), + /* [ d] */ Token::rightparen_token(), + /* [ e] */ Token::then_token(), + /* [ f] */ Token::i64_token("1"), + /* [ g] */ Token::else_token(), + /* [ h] */ Token::symbol_token("n"), + /* [ i] */ Token::star_token(), + /* [ j] */ Token::symbol_token("fact"), + /* [ k] */ Token::leftparen_token(), + /* [ l] */ Token::symbol_token("n"), + /* [ m] */ Token::minus_token(), + /* [ n] */ Token::i64_token("1"), + /* [ o] */ Token::rightparen_token(), + /* [ p] */ Token::rightbrace_token(), + /* [ q] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + log && fixture.log_memory_layout(&log); + } + } /*namespace ut*/ } /*namespace xo*/ From ce8663bcfaddabb9b3c2baf8c41f8b72c6be607a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 17 Feb 2026 20:07:43 -0500 Subject: [PATCH 256/258] xo-interpreter2: recursive factorial utest. working! --- .../interpreter2/VirtualSchematikaMachine.cpp | 18 ++-- .../utest/VirtualSchematikaMachine.test.cpp | 89 +++++++++++++++++++ 2 files changed, 94 insertions(+), 13 deletions(-) diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index e7964ab4..dc8844e2 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -394,22 +394,14 @@ namespace xo { Binding b = var->path(); - if (local_env_) { - auto value = local_env_->lookup_value(b); + obj value; - if (value) { - this->value_ = VsmResult(value); - - this->pc_ = this->cont_; - this->cont_ = VsmInstr::c_sentinel; - return; - } + if (b.is_local() && local_env_) { + value = local_env_->lookup_value(b); + } else if (b.is_global()) { + value = global_env_->lookup_value(b); } - // no local binding. perhaps there's a global binding - - auto value = global_env_->lookup_value(b); - if (value) { this->value_ = VsmResult(value); diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 3d1a76a8..8d4188a6 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -428,6 +428,95 @@ namespace xo { } + TEST_CASE("VirtualSchematikaMachine-def3", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; + + bool eof_flag = true; + + vsm.begin_interactive_session(); + + span_type input = span_type::from_cstr("def fact = lambda (n) { if (n == 0) then 1 else n * fact(n - 1) };"); + + for (int i_expr = 0; i_expr < 1; ++i_expr) { + log && log(xtag("input", input)); + + VsmResultExt res + = vsm.read_eval_print(input, eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq()), + xtag("res.type", TypeRegistry::id2name(res.value()->_typeseq()))); + + if (i_expr == 0) { + auto x = obj::from(*res.value()); + REQUIRE(x); + REQUIRE(strcmp(x->chars(), "fact") == 0); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + input = res.remaining_; + } + } + + log && vsm_fixture.log_memory_layout(&log); + } + + TEST_CASE("VirtualSchematikaMachine-fact0", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; + + bool eof_flag = true; + + vsm.begin_interactive_session(); + + span_type input = span_type::from_cstr("def fact = lambda (n) { if (n == 0) then 1 else n * fact(n - 1) }; fact(4);"); + + for (int i_expr = 0; i_expr < 2; ++i_expr) { + log && log(xtag("input", input)); + + VsmResultExt res + = vsm.read_eval_print(input, eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq()), + xtag("res.type", TypeRegistry::id2name(res.value()->_typeseq()))); + + if (i_expr == 0) { + auto x = obj::from(*res.value()); + REQUIRE(x); + REQUIRE(strcmp(x->chars(), "fact") == 0); + input = res.remaining_; + } else if (i_expr == 1) { + auto x = obj::from(*res.value()); + REQUIRE(x); + REQUIRE(x->value() == 24); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + input = res.remaining_; + } + } + + log && vsm_fixture.log_memory_layout(&log); + } + } /*namespace ut*/ } /*namespace xo*/ From f26c05d64f1c45539225f6a3110422eb63ee80ac Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 18 Feb 2026 01:46:45 -0500 Subject: [PATCH 257/258] xo-interpreter2: + skrepl (read eval print loop) --- xo-interpreter2/CMakeLists.txt | 1 + .../interpreter2/VirtualSchematikaMachine.hpp | 5 + .../interpreter2/VirtualSchematikaMachine.cpp | 6 + xo-interpreter2/src/skrepl/CMakeLists.txt | 13 + xo-interpreter2/src/skrepl/skreplxx.cpp | 242 ++++++++++++++++++ .../utest/VirtualSchematikaMachine.test.cpp | 13 +- 6 files changed, 268 insertions(+), 12 deletions(-) create mode 100644 xo-interpreter2/src/skrepl/CMakeLists.txt create mode 100644 xo-interpreter2/src/skrepl/skreplxx.cpp diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 2d1a6db8..426e4112 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -21,6 +21,7 @@ add_definitions(${PROJECT_CXX_FLAGS}) # output targets add_subdirectory(src/interpreter2) +add_subdirectory(src/skrepl) add_subdirectory(utest) # ---------------------------------------------------------------- diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 724e1c33..75fb968f 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -91,6 +91,11 @@ namespace xo { /** allocator for runtime errors **/ obj error_allocator() const noexcept; + /** true iff parser is at top-level -> does not contain + * state for a incomplete/partial expression + **/ + bool is_at_toplevel() const noexcept; + /** visit vsm-owned memory pools; call visitor(info) for each **/ void visit_pools(const MemorySizeVisitor & visitor) const; diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index dc8844e2..9104fa2f 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -86,6 +86,12 @@ namespace xo { return error_mm_.to_op(); } + bool + VirtualSchematikaMachine::is_at_toplevel() const noexcept + { + return reader_.is_at_toplevel(); + } + void VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const { diff --git a/xo-interpreter2/src/skrepl/CMakeLists.txt b/xo-interpreter2/src/skrepl/CMakeLists.txt new file mode 100644 index 00000000..b5511114 --- /dev/null +++ b/xo-interpreter2/src/skrepl/CMakeLists.txt @@ -0,0 +1,13 @@ +# xo-interpreter2/src/repl/CMakeLists.txt + +set(SELF_EXE skrepl) +set(SELF_SRCS skreplxx.cpp) + +xo_add_executable(${SELF_EXE} ${SELF_SRCS}) +xo_self_dependency(${SELF_EXE} xo_interpreter2) +xo_external_target_dependency(${SELF_EXE} replxx replxx::replxx) + +# replxx requires this +find_package(Threads REQUIRED) +target_link_libraries(${SELF_EXE} PUBLIC Threads::Threads) + diff --git a/xo-interpreter2/src/skrepl/skreplxx.cpp b/xo-interpreter2/src/skrepl/skreplxx.cpp new file mode 100644 index 00000000..df6be29d --- /dev/null +++ b/xo-interpreter2/src/skrepl/skreplxx.cpp @@ -0,0 +1,242 @@ +/** @file skreplxx.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include +#include +#include +#include +#include +#include + +namespace xo { + using xo::scm::VirtualSchematikaMachine; + using xo::scm::VsmResultExt; + using xo::mm::AAllocator; + using xo::mm::ArenaConfig; + using xo::mm::DArena; + using span_type = xo::mm::span; + using xo::facet::FacetRegistry; + using xo::facet::TypeRegistry; + using std::cerr; + + // presumeably replxx assumes input is a tty anyway? + // + bool replxx_getline(bool interactive, + bool is_at_toplevel, + replxx::Replxx & rx, + span_type * p_input + //const char ** p_input + ) + { + using namespace std; + + char const * prompt = ""; + + if (interactive) { + prompt = ((is_at_toplevel) ? "> " : ". "); + } + + const char * input_cstr = rx.input(prompt); + + bool retval = (input_cstr != nullptr); + + if (retval) + *p_input = span_type::from_cstr(input_cstr); + + if (input_cstr) + rx.history_add(input_cstr); + + return retval; + } + + void + welcome(std::ostream & os) + { + using namespace std; + + os << "schematika repl" << endl; + os << " ctrl-a/ctrl-e beginning/end of line" << endl; + os << " ctrl-u delete entire line" << endl; + os << " ctrl-k delete to end of line" << endl; + os << " meta- backward delete word" << endl; + os << " |meta-p previous command from history" << endl; + os << " |meta-n next command from history" << endl; + os << " / page through history faster" << endl; + os << " ctrl-s/ctrl-r forward/backward history search" << endl; + os << endl; + } + + struct ReplConfig { + ReplConfig() = default; + + std::size_t max_history_size_ = 1000; + std::string repl_history_fname_ = "skrepl_history.txt"; + bool debug_flag_ = false; + }; + + struct AppConfig { + using VsmConfig = xo::scm::VsmConfig; + + //using ReaderConfig = xo::scm::ReaderConfig; + //using X1CollectorConfig = xo::mm::X1CollectorConfig; + //using ArenaConfig = xo::mm::ArenaConfig; + + AppConfig(const ReplConfig & repl_cfg = ReplConfig(), + const ArenaConfig & app_arena_cfg = ArenaConfig().with_name("skreplxx").with_size(16 * 1024), + const VsmConfig & vsm_cfg = VsmConfig()) + : repl_config_{repl_cfg}, app_arena_config_{app_arena_cfg}, vsm_config_{vsm_cfg} + { + //rdr_config_.reader_debug_flag_ = true; + //rdr_config.parser_debug_flag_ = true; + //rdr_config.tk_debug_flag_ = true; + } + + ReplConfig repl_config_; + ArenaConfig app_arena_config_; + VsmConfig vsm_config_; + //ReaderConfig rdr_config_; + //X1CollectorConfig x1_config_ = (X1CollectorConfig().with_name("gc").with_size(4*1024*1024)); + //ArenaConfig fixed_config_ = (ArenaConfig().with_name("fixed").with_size(4*1024)); + }; + + struct App { + //using AAllocator = xo::mm::AAllocator; + //using DX1Collector = xo::mm::DX1Collector; + //using X1CollectorConfig = xo::mm::X1CollectorConfig; + //using DArena = xo::mm::DArena; + //using ArenaConfig = xo::mm::ArenaConfig; + using Replxx = replxx::Replxx; + using span_type = VirtualSchematikaMachine::span_type; + + App(const AppConfig & cfg = AppConfig()) + : repl_config_{cfg.repl_config_}, + app_arena_{cfg.app_arena_config_}, + vsm_{cfg.vsm_config_, obj(&app_arena_)} + { + this->interactive_ = isatty(STDIN_FILENO); + + rx_.set_max_history_size(repl_config_.max_history_size_); + rx_.history_load(repl_config_.repl_history_fname_); + // rx.bind_key_internal(Replxx::KEY::control('p'), "history_previous"); + // rx.bind_key_internal(Replxx::KEY::control('n'), "history_next"); + } + + /** borrows calling thread to run application **/ + void run(); + + private: + void _init(); + void _start(); + void _repl(); + bool _read_eval_print(span_type * p_input, bool eof); + + private: + InitEvidence init_evidence_ = 0; + ReplConfig repl_config_; + bool interactive_ = false; + Replxx rx_; + ///** collector/allocator for schematika expressions **/ + //DX1Collector x1_; + ///** e.g. for DArenaHashMap within global symtab **/ + //DArena fixed_; + + /** arena with same lifetime as this application **/ + DArena app_arena_; + /** schematika virtual machine **/ + VirtualSchematikaMachine vsm_; + }; + + void + App::run() + { + this->_init(); + this->_start(); + this->_repl(); + } + + void + App::_init() + { + // window to contorl size of registries ends as soon as we init other subsystems + TypeRegistry::instance(1024); + FacetRegistry::instance(1024); + + InitEvidence init_evidence_ = (InitSubsys::require()); + + Subsystem::initialize_all(); + } + + void + App::_start() + { + welcome(cerr); + + vsm_.begin_interactive_session(); + } + + void + App::_repl() + { + bool eof = false; + span_type input; + + // outer loop: fetch one line of interactive input + while (replxx_getline(interactive_, vsm_.is_at_toplevel(), rx_, &input)) { + + // inner lo9op: consume up to one expression at a time. + while (!input.empty() && this->_read_eval_print(&input, false /*eof*/)) + { + ; + } + + /* here: either: + * 1. input.empty() or + * 2. error encountered + */ + } + + /* reminder: eof can complete at most one token */ + this->_read_eval_print(&input, true /*eof*/); + } + + /** body of read-parse-print loop + * + * true -> no errors; + * false -> reader encountered error + **/ + bool + App::_read_eval_print(span_type * p_input, + bool eof) + { + scope log(XO_DEBUG(repl_config_.debug_flag_)); + + if (!p_input || p_input->empty()) + return true; + + VsmResultExt res = vsm_.read_eval_print(*p_input, eof); + + *p_input = res.remaining_; + + return !res.is_tk_error() && !res.is_eval_error(); + } + +} /*namespace xo*/ + +int +main (int argc, char * argv[]) +{ + using xo::AppConfig; + using xo::App; + + AppConfig cfg; + // [cmdline options here] + + App app(cfg); + + app.run(); +} /*main*/ + +/* end skreplxx.cpp */ + diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 8d4188a6..77b3a30b 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -3,6 +3,7 @@ * @author Roland Conybeare, Jan 2026 **/ +#include #include #include #include @@ -12,18 +13,6 @@ #include #include #include - -#ifdef NOT_YET -#include -#include -#include -#include -#include -#endif -#include -#ifdef NOT_YET -#include -#endif #include #include From 1870c0cc830d33bdb0cccddc858abf9d594b5210 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 18 Feb 2026 12:18:42 -0500 Subject: [PATCH 258/258] etc/hostubuntu: update nvidia driver symlinks for 580.126.09 --- etc/hostubuntu/libEGL_nvidia.so.580.126.09 | 1 + etc/hostubuntu/libEGL_nvidia.so.580.95.05 | 1 - etc/hostubuntu/libGLX_nvidia.so.580.126.09 | 1 + etc/hostubuntu/libGLX_nvidia.so.580.95.05 | 1 - etc/hostubuntu/libnvidia-glcore.so.580.126.09 | 1 + etc/hostubuntu/libnvidia-glcore.so.580.95.05 | 1 - etc/hostubuntu/libnvidia-glsi.so.580.126.09 | 1 + etc/hostubuntu/libnvidia-glsi.so.580.95.05 | 1 - etc/hostubuntu/libnvidia-glvkspirv.so.580.126.09 | 1 + etc/hostubuntu/libnvidia-glvkspirv.so.580.95.05 | 1 - etc/hostubuntu/libnvidia-gpucomp.so.580.126.09 | 1 + etc/hostubuntu/libnvidia-gpucomp.so.580.95.05 | 1 - etc/hostubuntu/libnvidia-tls.so.580.126.09 | 1 + etc/hostubuntu/libnvidia-tls.so.580.95.05 | 1 - 14 files changed, 7 insertions(+), 7 deletions(-) create mode 120000 etc/hostubuntu/libEGL_nvidia.so.580.126.09 delete mode 120000 etc/hostubuntu/libEGL_nvidia.so.580.95.05 create mode 120000 etc/hostubuntu/libGLX_nvidia.so.580.126.09 delete mode 120000 etc/hostubuntu/libGLX_nvidia.so.580.95.05 create mode 120000 etc/hostubuntu/libnvidia-glcore.so.580.126.09 delete mode 120000 etc/hostubuntu/libnvidia-glcore.so.580.95.05 create mode 120000 etc/hostubuntu/libnvidia-glsi.so.580.126.09 delete mode 120000 etc/hostubuntu/libnvidia-glsi.so.580.95.05 create mode 120000 etc/hostubuntu/libnvidia-glvkspirv.so.580.126.09 delete mode 120000 etc/hostubuntu/libnvidia-glvkspirv.so.580.95.05 create mode 120000 etc/hostubuntu/libnvidia-gpucomp.so.580.126.09 delete mode 120000 etc/hostubuntu/libnvidia-gpucomp.so.580.95.05 create mode 120000 etc/hostubuntu/libnvidia-tls.so.580.126.09 delete mode 120000 etc/hostubuntu/libnvidia-tls.so.580.95.05 diff --git a/etc/hostubuntu/libEGL_nvidia.so.580.126.09 b/etc/hostubuntu/libEGL_nvidia.so.580.126.09 new file mode 120000 index 00000000..f9e88f8a --- /dev/null +++ b/etc/hostubuntu/libEGL_nvidia.so.580.126.09 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.580.126.09 \ No newline at end of file diff --git a/etc/hostubuntu/libEGL_nvidia.so.580.95.05 b/etc/hostubuntu/libEGL_nvidia.so.580.95.05 deleted file mode 120000 index 5c3d156a..00000000 --- a/etc/hostubuntu/libEGL_nvidia.so.580.95.05 +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.580.95.05 \ No newline at end of file diff --git a/etc/hostubuntu/libGLX_nvidia.so.580.126.09 b/etc/hostubuntu/libGLX_nvidia.so.580.126.09 new file mode 120000 index 00000000..c1a66d6d --- /dev/null +++ b/etc/hostubuntu/libGLX_nvidia.so.580.126.09 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.580.126.09 \ No newline at end of file diff --git a/etc/hostubuntu/libGLX_nvidia.so.580.95.05 b/etc/hostubuntu/libGLX_nvidia.so.580.95.05 deleted file mode 120000 index c5fd2bf6..00000000 --- a/etc/hostubuntu/libGLX_nvidia.so.580.95.05 +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.580.95.05 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-glcore.so.580.126.09 b/etc/hostubuntu/libnvidia-glcore.so.580.126.09 new file mode 120000 index 00000000..1b738450 --- /dev/null +++ b/etc/hostubuntu/libnvidia-glcore.so.580.126.09 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.580.126.09 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-glcore.so.580.95.05 b/etc/hostubuntu/libnvidia-glcore.so.580.95.05 deleted file mode 120000 index f8475532..00000000 --- a/etc/hostubuntu/libnvidia-glcore.so.580.95.05 +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.580.95.05 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-glsi.so.580.126.09 b/etc/hostubuntu/libnvidia-glsi.so.580.126.09 new file mode 120000 index 00000000..0324b15e --- /dev/null +++ b/etc/hostubuntu/libnvidia-glsi.so.580.126.09 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libnvidia-glsi.so.580.126.09 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-glsi.so.580.95.05 b/etc/hostubuntu/libnvidia-glsi.so.580.95.05 deleted file mode 120000 index 55dc4271..00000000 --- a/etc/hostubuntu/libnvidia-glsi.so.580.95.05 +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/x86_64-linux-gnu/libnvidia-glsi.so.580.95.05 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-glvkspirv.so.580.126.09 b/etc/hostubuntu/libnvidia-glvkspirv.so.580.126.09 new file mode 120000 index 00000000..1e055f84 --- /dev/null +++ b/etc/hostubuntu/libnvidia-glvkspirv.so.580.126.09 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libnvidia-glvkspirv.so.580.126.09 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-glvkspirv.so.580.95.05 b/etc/hostubuntu/libnvidia-glvkspirv.so.580.95.05 deleted file mode 120000 index 58140c09..00000000 --- a/etc/hostubuntu/libnvidia-glvkspirv.so.580.95.05 +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/x86_64-linux-gnu/libnvidia-glvkspirv.so.580.95.05 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-gpucomp.so.580.126.09 b/etc/hostubuntu/libnvidia-gpucomp.so.580.126.09 new file mode 120000 index 00000000..e97ad8cf --- /dev/null +++ b/etc/hostubuntu/libnvidia-gpucomp.so.580.126.09 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libnvidia-gpucomp.so.580.126.09 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-gpucomp.so.580.95.05 b/etc/hostubuntu/libnvidia-gpucomp.so.580.95.05 deleted file mode 120000 index a2021093..00000000 --- a/etc/hostubuntu/libnvidia-gpucomp.so.580.95.05 +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/x86_64-linux-gnu/libnvidia-gpucomp.so.580.95.05 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-tls.so.580.126.09 b/etc/hostubuntu/libnvidia-tls.so.580.126.09 new file mode 120000 index 00000000..734a7a02 --- /dev/null +++ b/etc/hostubuntu/libnvidia-tls.so.580.126.09 @@ -0,0 +1 @@ +/usr/lib/x86_64-linux-gnu/libnvidia-tls.so.580.126.09 \ No newline at end of file diff --git a/etc/hostubuntu/libnvidia-tls.so.580.95.05 b/etc/hostubuntu/libnvidia-tls.so.580.95.05 deleted file mode 120000 index a5cf63b6..00000000 --- a/etc/hostubuntu/libnvidia-tls.so.580.95.05 +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/x86_64-linux-gnu/libnvidia-tls.so.580.95.05 \ No newline at end of file