diff --git a/xo-reader2/.gitrepo b/xo-reader2/.gitrepo new file mode 100644 index 00000000..aef8aa09 --- /dev/null +++ b/xo-reader2/.gitrepo @@ -0,0 +1,12 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/ingydotnet/git-subrepo#readme +; +[subrepo] + remote = git@github.com:Rconybea/xo-reader2.git + branch = main + commit = 70943b8e0866aba722729998428d2546c84d2eb6 + parent = 685581c750698acbac5a62db721a729e61ffe88e + method = merge + cmdver = 0.4.9 diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt new file mode 100644 index 00000000..4675de3c --- /dev/null +++ b/xo-reader2/CMakeLists.txt @@ -0,0 +1,400 @@ +# xo-reader2/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +#set(CMAKE_CXX_STANDARD 23) + +project(xo_reader2 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 + +add_subdirectory(utest) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-gcobject-schematikaparser + FACET_PKG xo_alloc2 + INPUT idl/IGCObject_DSchematikaParser.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacet( + TARGET xo-reader2-facet-syntaxstatemachine + FACET SyntaxStateMachine + INPUT idl/SyntaxStateMachine.json5 + ) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-toplevelseqssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-toplevelseqssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DToplevelSeqSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-definessm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DDefineSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-definessm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DDefineSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-deftypessm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DDeftypeSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-deftypessm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DDeftypeSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-lambdassm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DLambdaSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-lambdassm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DLambdaSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-parenssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DParenSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-parenssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DParenSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectformalarglistssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectformalarglistssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectFormalArglistSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectformalargssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectformalargssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectFormalArgSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-ifelsessm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DIfElseSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-ifelsessm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DIfElseSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-sequencessm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DSequenceSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-sequencessm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DSequenceSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-applyssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DApplySsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-applyssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DApplySsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectsymbolssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectsymbolssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectSymbolSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expecttypessm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectTypeSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expecttypessm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectTypeSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectlisttypessm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectListTypeSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectlisttypessm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectListTypeSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectexprssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectExprSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectexprssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectExprSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-progressssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DProgressSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-progressssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DProgressSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-quotessm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DQuoteSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-quotessm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DQuoteSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectqliteralssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectQLiteralSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectqliteralssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectQLiteralSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectqlistssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectQListSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectqlistssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectQListSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectqdictssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectQDictSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectqdictssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectQDictSsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectqarrayssm + FACET_PKG xo_reader2 + INPUT idl/ISyntaxStateMachine_DExpectQArraySsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectqarrayssm + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DExpectQArraySsm.json5 +) + +# ---------------------------------------------------------------- + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-gcobject-globalenv + FACET_PKG xo_alloc2 + INPUT idl/IGCObject_DGlobalEnv.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-globalenv + FACET_PKG xo_printable2 + INPUT idl/IPrintable_DGlobalEnv.json5 +) + +# ---------------------------------------------------------------- + +xo_add_genfacet_all(xo-reader2-genfacet-all) + +# ---------------------------------------------------------------- +# shared library + +add_subdirectory(src/reader2) + +# ---------------------------------------------------------------- +# example programs + +add_subdirectory(example) + +# ---------------------------------------------------------------- +# cmake helper (for external xo-reader2 users) + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +# end CMakeLists.txt diff --git a/xo-reader2/DESIGN.md b/xo-reader2/DESIGN.md new file mode 100644 index 00000000..11a8a6ef --- /dev/null +++ b/xo-reader2/DESIGN.md @@ -0,0 +1,21 @@ +Uses arena allocators for fast+efficient parsing. + +Composition of nested state machines. + +## SchematikaParser + +Parser to convert schematika text to expressions. + +### Details + +Partial GCObject facet support, so a SchmeatikaParser instance can +be a gc root. + +## SyntaxStateMachine + +a state machine dedicated to some particular Schematika syntax. +Examples: if-expression, type declaration, function call + +## DToplevelSeqSsm + +top-level expression sequence diff --git a/xo-reader2/cmake/xo-bootstrap-macros.cmake b/xo-reader2/cmake/xo-bootstrap-macros.cmake new file mode 100644 index 00000000..2cf387e5 --- /dev/null +++ b/xo-reader2/cmake/xo-bootstrap-macros.cmake @@ -0,0 +1,33 @@ +# ---------------------------------------------------------------- +# 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 (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL "prefix")) + message(FATAL "could not find xo-cmake-config executable") +endif() + +if (NOT XO_SUBMODULE_BUILD) + 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-reader2/cmake/xo_reader2Config.cmake.in b/xo-reader2/cmake/xo_reader2Config.cmake.in new file mode 100644 index 00000000..6d032cb1 --- /dev/null +++ b/xo-reader2/cmake/xo_reader2Config.cmake.in @@ -0,0 +1,19 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +# note: changes to find_dependency() calls here +# must coordinate with xo_dependency() calls +# in CMakeLists.txt +# +find_dependency(xo_numeric) +find_dependency(xo_procedure2) +find_dependency(xo_gc) +find_dependency(xo_type) +find_dependency(xo_tokenizer2) +find_dependency(xo_expression2) +find_dependency(subsys) + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Share.cmake") +check_required_components("@PROJECT_NAME@") 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/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 new file mode 100644 index 00000000..292c3a43 --- /dev/null +++ b/xo-reader2/example/readerreplxx/readerreplxx.cpp @@ -0,0 +1,248 @@ +/** @file readerreplxx.cpp **/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for isatty + +// presumeably replxx assumes input is a tty +// +bool replxx_getline(bool interactive, + bool is_at_toplevel, + replxx::Replxx & rx, + 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 = input_cstr; + + if (input_cstr) + rx.history_add(input_cstr); + + 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; +} + +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; + + /** 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, + 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_pr); + + p_reader->reset_result(); + + *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 { + *p_input = remaining; + + /* partial expression or whitespace input, no error */ + return true; + } + } +} + +struct AppConfig { + using ReaderConfig = xo::scm::ReaderConfig; + using X1CollectorConfig = xo::mm::X1CollectorConfig; + using ArenaConfig = xo::mm::ArenaConfig; + + 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";; + 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 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_{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_); + // rx.bind_key_internal(Replxx::KEY::control('p'), "history_previous"); + // rx.bind_key_internal(Replxx::KEY::control('n'), "history_next"); + } + + AppConfig config_; + Replxx rx_; + /** collector/allocator for schematika expressions **/ + DX1Collector x1_; + /** e.g. for DArenaHashMap within global symtab **/ + DArena fixed_; + SchematikaReader rdr_; +}; + +int +main() +{ + using namespace replxx; + + using xo::scm::SchematikaReader; + using xo::scm::ReaderConfig; + using xo::mm::AAllocator; + using xo::mm::DX1Collector; + using xo::mm::DArena; + 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(); + + AppConfig cfg; + AppContext cx(cfg); + + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag)); + + using span_type = SchematikaReader::span_type; + + welcome(cerr); + + cx.rdr_.begin_interactive_session(); + + bool eof = false; + const char * input_str = nullptr; + span_type input; + + 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(&cx.rdr_, &input, false /*eof*/, c_debug_flag)) + { + ; + } + + /* here: either: + * 1. input.empty() or + * 2. error encountered + */ + } + } + + /* reminder: eof can complete at most one token */ + reader_seq(&cx.rdr_, &input, true /*eof*/, c_debug_flag); + + cx.rx_.history_save(cx.config_.repl_history_fname_); +} + +/* end readerreplxx.cpp */ diff --git a/xo-reader2/idl/IGCObject_DGlobalEnv.json5 b/xo-reader2/idl/IGCObject_DGlobalEnv.json5 new file mode 100644 index 00000000..c3d666dd --- /dev/null +++ b/xo-reader2/idl/IGCObject_DGlobalEnv.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + 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-reader2/idl/IGCObject_DSchematikaParser.json5 b/xo-reader2/idl/IGCObject_DSchematikaParser.json5 new file mode 100644 index 00000000..cbb2d09a --- /dev/null +++ b/xo-reader2/idl/IGCObject_DSchematikaParser.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "parser", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for SchematikaParser", + using_doxygen: true, + repr: "DSchematikaParser", + doc: [ "implement AGCObject for DSchematikaParser" ], +} diff --git a/xo-reader2/idl/IPrintable_DApplySsm.json5 b/xo-reader2/idl/IPrintable_DApplySsm.json5 new file mode 100644 index 00000000..37330b12 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DApplySsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "apply", + 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/IPrintable_DDefineSsm.json5 b/xo-reader2/idl/IPrintable_DDefineSsm.json5 new file mode 100644 index 00000000..fbac5a89 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DDefineSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "define", + 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/idl/IPrintable_DDeftypeSsm.json5 b/xo-reader2/idl/IPrintable_DDeftypeSsm.json5 new file mode 100644 index 00000000..00b81fdb --- /dev/null +++ b/xo-reader2/idl/IPrintable_DDeftypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "deftype", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DDeftypeSsm", + using_doxygen: true, + repr: "DDeftypeSsm", + doc: [ "implement APrintable for DDeftypeSsm" ], +} diff --git a/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 b/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 new file mode 100644 index 00000000..f5465709 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectExprSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + 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/IPrintable_DExpectFormalArgSsm.json5 b/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 new file mode 100644 index 00000000..2c2dbaab --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectFormalArgSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "expect_formal_arg", + 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/idl/IPrintable_DExpectFormalArglistSsm.json5 b/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 new file mode 100644 index 00000000..1aa3c951 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectFormalArglistSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + 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/IPrintable_DExpectListTypeSsm.json5 b/xo-reader2/idl/IPrintable_DExpectListTypeSsm.json5 new file mode 100644 index 00000000..2403eb59 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectListTypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "expect_listtype", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectListTypeSsm", + using_doxygen: true, + repr: "DExpectListTypeSsm", + doc: [ "implement APrintable for DExpectListTypeSsm" ], +} diff --git a/xo-reader2/idl/IPrintable_DExpectQArraySsm.json5 b/xo-reader2/idl/IPrintable_DExpectQArraySsm.json5 new file mode 100644 index 00000000..9ba8c712 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectQArraySsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectQArraySsm", + using_doxygen: true, + repr: "DExpectQArraySsm", + doc: [ "implement APrintable for DExpectQArraySsm" ], +} diff --git a/xo-reader2/idl/IPrintable_DExpectQDictSsm.json5 b/xo-reader2/idl/IPrintable_DExpectQDictSsm.json5 new file mode 100644 index 00000000..0569712d --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectQDictSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "expect_qdict", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectQDictSsm", + using_doxygen: true, + repr: "DExpectQDictSsm", + doc: [ "implement APrintable for DExpectQDictSsm" ], +} diff --git a/xo-reader2/idl/IPrintable_DExpectQListSsm.json5 b/xo-reader2/idl/IPrintable_DExpectQListSsm.json5 new file mode 100644 index 00000000..91f98f8f --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectQListSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectQListSsm", + using_doxygen: true, + repr: "DExpectQListSsm", + doc: [ "implement APrintable for DExpectQListSsm" ], +} diff --git a/xo-reader2/idl/IPrintable_DExpectQLiteralSsm.json5 b/xo-reader2/idl/IPrintable_DExpectQLiteralSsm.json5 new file mode 100644 index 00000000..ae3f9dd6 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectQLiteralSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectQLiteralSsm", + using_doxygen: true, + repr: "DExpectQLiteralSsm", + doc: [ "implement APrintable for DExpectQLiteralSsm" ], +} diff --git a/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 b/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 new file mode 100644 index 00000000..fee89873 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectSymbolSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + 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/idl/IPrintable_DExpectTypeSsm.json5 b/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 new file mode 100644 index 00000000..463cb399 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DExpectTypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + 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/IPrintable_DGlobalEnv.json5 b/xo-reader2/idl/IPrintable_DGlobalEnv.json5 new file mode 100644 index 00000000..9e48847e --- /dev/null +++ b/xo-reader2/idl/IPrintable_DGlobalEnv.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + 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-reader2/idl/IPrintable_DIfElseSsm.json5 b/xo-reader2/idl/IPrintable_DIfElseSsm.json5 new file mode 100644 index 00000000..7c57eb7a --- /dev/null +++ b/xo-reader2/idl/IPrintable_DIfElseSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ifelse", + 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/IPrintable_DLambdaSsm.json5 b/xo-reader2/idl/IPrintable_DLambdaSsm.json5 new file mode 100644 index 00000000..3f625a27 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DLambdaSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "lambda", + 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/IPrintable_DParenSsm.json5 b/xo-reader2/idl/IPrintable_DParenSsm.json5 new file mode 100644 index 00000000..6735436c --- /dev/null +++ b/xo-reader2/idl/IPrintable_DParenSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "paren", + 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/IPrintable_DProgressSsm.json5 b/xo-reader2/idl/IPrintable_DProgressSsm.json5 new file mode 100644 index 00000000..d3d298b1 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DProgressSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + 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/IPrintable_DQuoteSsm.json5 b/xo-reader2/idl/IPrintable_DQuoteSsm.json5 new file mode 100644 index 00000000..d7c41b0a --- /dev/null +++ b/xo-reader2/idl/IPrintable_DQuoteSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "quote", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DQuoteSsm", + using_doxygen: true, + repr: "DQuoteSsm", + doc: [ "implement APrintable for DQuoteSsm" ], +} diff --git a/xo-reader2/idl/IPrintable_DSequenceSsm.json5 b/xo-reader2/idl/IPrintable_DSequenceSsm.json5 new file mode 100644 index 00000000..f5c89aca --- /dev/null +++ b/xo-reader2/idl/IPrintable_DSequenceSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + 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/IPrintable_DToplevelSeqSsm.json5 b/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 new file mode 100644 index 00000000..d3c78474 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DToplevelSeqSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DToplevelSeqSsm", + using_doxygen: true, + repr: "DToplevelSeqSsm", + doc: [ "implement APrintable for DToplevelSeqSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 new file mode 100644 index 00000000..80df12c7 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DApplySsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "apply", + 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/idl/ISyntaxStateMachine_DDefineSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 new file mode 100644 index 00000000..c4f7d357 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DDefineSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "define", + 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/idl/ISyntaxStateMachine_DDeftypeSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DDeftypeSsm.json5 new file mode 100644 index 00000000..722e3409 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DDeftypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "deftype", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DDeftypeSsm", + using_doxygen: true, + repr: "DDeftypeSsm", + doc: [ "implement ASyntaxStateMachine for DDeftypeSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 new file mode 100644 index 00000000..d1c78ad2 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectExprSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + 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/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 new file mode 100644 index 00000000..e3ae1ac5 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArgSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "expect_formal_arg", + 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/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 new file mode 100644 index 00000000..019573d0 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + 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/idl/ISyntaxStateMachine_DExpectListTypeSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectListTypeSsm.json5 new file mode 100644 index 00000000..9a616675 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectListTypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "expect_listtype", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectListTypeSsm", + using_doxygen: true, + repr: "DExpectListTypeSsm", + doc: [ "implement ASyntaxStateMachine for DExpectListTypeSsm" ], +} \ No newline at end of file diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectQArraySsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectQArraySsm.json5 new file mode 100644 index 00000000..0ace11e7 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectQArraySsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectQArraySsm", + using_doxygen: true, + repr: "DExpectQArraySsm", + doc: [ "implement ASyntaxStateMachine for DExpectQArraySsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectQDictSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectQDictSsm.json5 new file mode 100644 index 00000000..ee440bcd --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectQDictSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "expect_qdict", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectQDictSsm", + using_doxygen: true, + repr: "DExpectQDictSsm", + doc: [ "implement ASyntaxStateMachine for DExpectQDictSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectQListSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectQListSsm.json5 new file mode 100644 index 00000000..94d59ba0 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectQListSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectQListSsm", + using_doxygen: true, + repr: "DExpectQListSsm", + doc: [ "implement ASyntaxStateMachine for DExpectQListSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectQLiteralSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectQLiteralSsm.json5 new file mode 100644 index 00000000..58310939 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectQLiteralSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectQLiteralSsm", + using_doxygen: true, + repr: "DExpectQLiteralSsm", + doc: [ "implement ASyntaxStateMachine for DExpectQLiteralSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 new file mode 100644 index 00000000..49248b62 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + 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/ISyntaxStateMachine_DExpectTypeSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 new file mode 100644 index 00000000..68883ef0 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DExpectTypeSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + 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/idl/ISyntaxStateMachine_DIfElseSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 new file mode 100644 index 00000000..eb2ea371 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DIfElseSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ifelse", + 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/idl/ISyntaxStateMachine_DLambdaSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 new file mode 100644 index 00000000..951c511f --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DLambdaSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "lambda", + 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/idl/ISyntaxStateMachine_DParenSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 new file mode 100644 index 00000000..dcdb298c --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DParenSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "paren", + 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/idl/ISyntaxStateMachine_DProgressSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 new file mode 100644 index 00000000..83c10717 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DProgressSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + 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/ISyntaxStateMachine_DQuoteSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DQuoteSsm.json5 new file mode 100644 index 00000000..60d41730 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DQuoteSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2/facet", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "quote", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DQuoteSsm", + using_doxygen: true, + repr: "DQuoteSsm", + doc: [ "implement ASyntaxStateMachine for DQuoteSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 new file mode 100644 index 00000000..e497ef7f --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DSequenceSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + 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/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 new file mode 100644 index 00000000..7a91622f --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DToplevelSeqSsm.json5 @@ -0,0 +1,16 @@ +{ + 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: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DToplevelSeqSsm", + using_doxygen: true, + repr: "DToplevelSeqSsm", + doc: [ "implement ASyntaxStateMachine for DToplevelSeqSsm" ], +} diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 new file mode 100644 index 00000000..c2d8aff1 --- /dev/null +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -0,0 +1,160 @@ +{ + mode: "facet", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + // 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: ["// {pretext} 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: "TypeDescr", doc: [ "reflected c++ type" ], definition: "xo::reflect::TypeDescr" }, + { name: "AGCObjectVisitor", doc: [ "gc visitor interface" ], definition: "xo::mm::AGCObjectVisitor" }, + { name: "AGCObject", doc: [ "gc-aware object" ], definition: "xo::mm::AGCObject" }, + { name: "VisitReason", doc: [ "hint when traversing gco graph" ], definition: "xo::mm::VisitReason" }, + ], + 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_token", + doc: ["operate state machine for incoming 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"], + return_type: "void", + args: [ + {type: "std::string_view", name: "sym"}, + {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"}, + ], + }, + { + name: "on_parsed_type", + doc: ["update state machine for type emitted by nested ssm"], + return_type: "void", + args: [ + {type: "obj", name: "type"}, + {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_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"], + return_type: "void", + args: [ + {type: "DArray *", name: "arglist"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, + { + name: "on_parsed_expression", + doc: ["update state machine for nested parsed expression @p expr"], + return_type: "void", + args: [ + {type: "obj", name: "expr"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, + { + 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"}, + ], + }, + { + name: "on_quoted_literal", + doc: ["update state machine for nested quoted literal @p lit"], + return_type: "void", + args: [ + {type: "obj", name: "lit"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, + { + name: "visit_gco_children", + doc: ["gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each"], + return_type: "void", + args: [ + {type: "VisitReason", name: "reason"}, + {type: "obj", name: "gc"}, + ], + } + ], + router_facet_explicit_content: [ ], +} diff --git a/xo-reader2/include/xo/reader2/ApplySsm.hpp b/xo-reader2/include/xo/reader2/ApplySsm.hpp new file mode 100644 index 00000000..9ddc5b5a --- /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 "apply/DApplySsm.hpp" +#include "apply/ISyntaxStateMachine_DApplySsm.hpp" +#include "apply/IPrintable_DApplySsm.hpp" + +/* end ApplySsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp new file mode 100644 index 00000000..36afb4b4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -0,0 +1,226 @@ +/** @file DDefineSsm.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include +#include +#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_parsed_expression()--> 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 DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-definessm-ctors constructors **/ + ///@{ + + /** constructor; using @p def_expr for initial expression scaffold **/ + explicit DDefineSsm(DDefineExpr * def_expr); + + /** create instance using memory from @p parser_mm. + * Initial expression scaffold @p 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 + * 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); + + ///@} + /** @defgroup scm-definessm-access-methods **/ + ///@{ + + /** identify this nested state machine **/ + static const char * ssm_classname() { return "DDefineSsm"; } + + /** internal state **/ + defexprstatetype defstate() const noexcept { return defstate_; } + + ///@} + /** @defgroup scm-definessm-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 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 + **/ + 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 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 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 token @p tk, + * with overall parser state in @p p_psm + **/ + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-define-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-define-gc-support **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + private: + /** @defgroup scm-definessm-member-vars **/ + ///@{ + + /** 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*/ + +/* end DDefineSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp new file mode 100644 index 00000000..b0d4b5f3 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -0,0 +1,221 @@ +/** @file DExpectExprSsm.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include + +namespace xo { + namespace scm { + + class DExpectExprSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + DExpectExprSsm(bool allow_defs, + bool cxl_on_rightbrace, + bool cxl_on_rightparen); + + static DExpectExprSsm * _make(DArena & parser_mm, + bool allow_defs, + bool cxl_on_rightbrace, + bool cxl_on_rightparen); + + /** create fop referring to new DExpectExprSsm **/ + static obj make(DArena & parser_mm, + bool allow_defs, + bool cxl_on_rightbrace, + bool cxl_on_rightparen); + + static void start(bool allow_defs, + bool cxl_on_rightbrace, + bool cxl_on_rightparen, + ParserStateMachine * p_psm); + static void start(ParserStateMachine * p_psm); + + /** @defgroup scm-expectexpr-access-methods access methods **/ + ///@{ + + 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_; } + bool cxl_on_rightparen() const noexcept { return cxl_on_rightparen_; } + + ///@} + /** @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 rightparen token @p tk, + * with overall parser state in @p p_psm. + * + * Generally treats as illegal, but cancels gracefully when + * @ref cxl_on_rightparen_ set. + **/ + void on_rightparen_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 + **/ + void on_leftbrace_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on quote token @p tk, + * with overall parser state in @p p_psm. + * + * Starts nested {progress-ssm, quote-ssm} combination. + **/ + void on_quote_token(const Token & tk, + ParserStateMachine * p_psm); + + /** step state machine for this syntax on incoming boolean literal token @p tk + * with overall parser state in @p p_psm + **/ + void on_bool_token(const Token & tk, + ParserStateMachine * p_psm); + + /** step state machine for this syntax on incoming nil literal token @p tk + * with overall parser state in @p p_psm. + **/ + void on_nil_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); + + /** 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); + + ///@} + /** @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 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 + **/ + 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 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 token @p tk + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + /** update state for literal @p lit with overall state in @p p_psm. + * wraps literal as constant-expr + starts progress-ssm for possible + * operator expression. + **/ + void on_quoted_literal(obj lit, + ParserStateMachine * p_psm); +#endif + + ///@} + /** @defgroup scm-define-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectexprssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + ///@} + + 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; + /** if true: expecting either: + * 1a. expression + * 1b. right paren ')', in which case no expression + **/ + bool cxl_on_rightparen_ = false; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectExprSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..c321b135 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -0,0 +1,167 @@ +/** @file DExpectFormalArglistSsm.hpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#pragma once + +#include "DSyntaxStateMachine.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 DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + 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-methods general methods **/ + ///@{ + + 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, + ParserStateMachine * 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 **/ + ///@{ + + /** 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, + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + 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 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 **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectformalarglistssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + 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; + /** 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 + **/ + DArray * argl_ = nullptr; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectFormalArglistSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectQArraySsm.hpp b/xo-reader2/include/xo/reader2/DExpectQArraySsm.hpp new file mode 100644 index 00000000..fcd1a14e --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectQArraySsm.hpp @@ -0,0 +1,147 @@ +/** @file DExpectQArraySsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include +#include + +namespace xo { + namespace scm { + /** + * Already in quoted-literal context + * + * [ quote-expr ... ] + * ^ ^ ^ ^ + * | qarray_1a | qarray_2(done) + * qarray_0 qarray_1a + * + * qarray_0 --on_leftbracket_token()--> qarray_1a [push ExpectQLiteralSsm] + * qarray_1a --on_quoted_literal()--> qarray_1a [append literal] + * qarray_1a --on_rightbracket_token()--> qarray_2(done) [report quoted array] + **/ + class QArrayXst { + public: + enum class code { + invalid = -1, + + qarray_0, + qarray_1a, + qarray_2, + + N + }; + + explicit QArrayXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + inline std::ostream & + operator<< (std::ostream & os, QArrayXst x) { + os << QArrayXst::_descr(x.code_); + return os; + } + + /** @class DExpectQArraySsm + * @brief parser state-machine for a literal array + **/ + class DExpectQArraySsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; + + public: + /** @defgroup scm-expectqarrayssm-ctors constructors **/ + ///@{ + + DExpectQArraySsm(); + + /** create instance, using memory from @parser_mm **/ + static obj make(DArena & parser_mm); + static DExpectQArraySsm * _make(DArena & parser_mm); + + /** start nested syntax for a quoted literal **/ + static void start(ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectformalargarrayssm-methods general methods **/ + ///@{ + + static const char * ssm_classname() { return "DExpectQArraySsm"; } + + /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ + void on_leftbracket_token(const Token & tk, + ParserStateMachine * p_psm); + + void on_rightbracket_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqarrayssm-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, + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for nested qliteral @p lit, with overall parser state in @p p_psm. + * Appends @p lit to target array + **/ + void on_quoted_literal(obj lit, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqarrayssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectqarrayssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + private: + /** @defgroup scm-expectqarrayssm-member-vars **/ + ///@{ + + /** identifies qarray parsing state **/ + QArrayXst state_; + + /** target array **/ + DArray * array_ = nullptr; + + ///@} + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectQArraySsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectQListSsm.hpp b/xo-reader2/include/xo/reader2/DExpectQListSsm.hpp new file mode 100644 index 00000000..8c9185ca --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectQListSsm.hpp @@ -0,0 +1,149 @@ +/** @file DExpectQListSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include +#include + +namespace xo { + namespace scm { + /** + * Already in quoted-literal context + * + * ( quote-expr ... ) + * ^ ^ ^ ^ + * | qlist_1a | qlist_2(done) + * qlist_0 qlist_1a + * + * qlist_0 --on_leftparen_token()--> qlist_1a [push ExpectQLiteralSsm] + * qlist_1a --on_quoted_literal()--> qlist_1a [append literal] + * qlist_1a --on_rightparen_token()--> qlist_2(done) [report quoted list] + * qlist_2 end state + **/ + class QListXst { + public: + enum class code { + invalid = -1, + + qlist_0, + qlist_1a, + qlist_2, + + N + }; + + explicit QListXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + inline std::ostream & + operator<< (std::ostream & os, QListXst x) { + os << QListXst::_descr(x.code_); + return os; + } + + /** @class DExpectQListSsm + * @brief parser state-machine for a literal list + **/ + class DExpectQListSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; + + public: + /** @defgroup scm-expectqlistssm-ctors constructors **/ + ///@{ + + DExpectQListSsm(); + + /** create instance, using memory from @parser_mm **/ + static obj make(DArena & parser_mm); + static DExpectQListSsm * _make(DArena & parser_mm); + + /** start nested syntax for a quoted literal **/ + static void start(ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectformalarglistssm-methods general methods **/ + ///@{ + + static const char * ssm_classname() { return "DExpectQListSsm"; } + + /** 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); + + void on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqlistssm-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, + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for nested qliteral @p lit, with overall parser state in @p p_psm. + * Appends @p lit to target list + **/ + void on_quoted_literal(obj lit, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqlistssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectqlistssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + ///@} + + private: + /** @defgroup scm-expectqlistssm-member-vars **/ + ///@{ + + /** identifies qlist parsing state **/ + QListXst state_; + + /** first node in literal list **/ + DList * start_ = nullptr; + /** last node in literal list **/ + DList * end_ = nullptr; + + ///@} + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectQListSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectQLiteralSsm.hpp b/xo-reader2/include/xo/reader2/DExpectQLiteralSsm.hpp new file mode 100644 index 00000000..58d7a0b4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectQLiteralSsm.hpp @@ -0,0 +1,161 @@ +/** @file DExpectQLiteralSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" + +namespace xo { + namespace scm { + /** @class DExpectQLiteralSsm + * @brief parser state-machine for a formal parameter list + **/ + class DExpectQLiteralSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; + + public: + explicit DExpectQLiteralSsm(bool cxl_on_rightparen, + bool cxl_on_rightbracket); + + /** create instance, using memory from @parser_mm **/ + static obj make(DArena & parser_mm, + bool cxl_on_rightparen, + bool cxl_on_rightbracket); + static DExpectQLiteralSsm * _make(DArena & parser_mm, + bool cxl_on_rightparen, + bool cxl_on_rightbracket); + + /** start nested syntax for a quoted literal **/ + static void start(ParserStateMachine * p_psm, + bool cxl_on_rightparen = false, + bool cxl_on_rightbracket = false); + + /** @defgroup scm-expectformalarglistssm-methods general methods **/ + ///@{ + + static const char * ssm_classname() { return "DExpectQLiteralSsm"; } + + /** update state for f64 token @p tk, with overall parser state in @p p_psm. + * completes syntax + delegates to parent ssm via @ref on_quoted_literal + **/ + void on_f64_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for i64 token @p tk, with overall parser state in @p p_psm. + * completes syntax + delegates to parent ssm via @ref on_quoted_literal + **/ + void on_i64_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for string token @p tk, with overall parser state in @p p_psm. + * completes syntax + delegates to parent ssm via @ref on_quoted_literal + **/ + void on_string_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on incoming token @p tk, + * with overall parser state in @p p_psm. + * + * Forward in-place to ExpectQListSsm. + **/ + void on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on incoming rightparen token @p tk, + * with overall parser state in @p p_psm + * + * Error unless @ref cxl_on_rightparen_ + **/ + void on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on incoming leftbracket token @p tk, + * with overall parser state in @p p_psm. + * + * Forward in-place to ExpectQArraySsm + **/ + void on_leftbracket_token(const Token &tk, + ParserStateMachine * p_psm); + + /** update state on incoming rightbracket token @p tk, + * with overall parser state in @p p_psm. + * + * Error unless @ref cxl_on_rightbracket_ + **/ + void on_rightbracket_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on incoming leftbrace token @p tk, + * with overall parser state in @p p_psm. + * + * Forward in-place to ExpectQDictSsm + **/ + void on_leftbrace_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, + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectformalarglistssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectqliteralssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + ///@} + + 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: + /** if true rightparen pops + delegates to parent ssm **/ + bool cxl_on_rightparen_ = false; + /** if true rightbracket pops + delegates to parent ssm **/ + bool cxl_on_rightbracket_ = false; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectQLiteralSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp new file mode 100644 index 00000000..0acd75c3 --- /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 "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#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 DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + + public: + DExpectSymbolSsm(); + + /** create instance using memory from @p 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. + * 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(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); + + static const char * ssm_classname() { return "DExpectSymbolSsm"; } + + /** @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; + + /** 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); + + ///@} + /** @defgroup scm-expectsymbol-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectsymbolssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + ///@} + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectSymbolSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp new file mode 100644 index 00000000..fd65a3ec --- /dev/null +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -0,0 +1,107 @@ +/** @file expect_type_xs.hpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include +#include + +namespace xo { + namespace scm { + /** @class DExpectTypeSsm + * @brief syntax state-machine for accepting a Schemtika typename-expression + * + * @pre + * any universal polymorphic type + * unit empty type (like c/c++ void) + * f64 64-bit float + * i32 32-bit signed integer + * list parameterized list (polymorphic if T is any) + * array parameterized array (polymorphic if T is any) + * function function (U x ...) -> T + * @endpre + **/ + class DExpectTypeSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-expecttype-ctors constructors **/ + ///@{ + + explicit DExpectTypeSsm(bool corrected); + + /** create instance **/ + static DExpectTypeSsm * _make(DArena & parser_mm, bool corrected); + + /** create fop referring to new DExpectTypeSsm **/ + static obj make(DArena & parser_mm, bool corrected); + + ///@} + /** @defgroup scm-expecttype-general-methods general methods **/ + ///@{ + + static void start(bool corrected, ParserStateMachine * p_psm); + + static const char * ssm_classname() { return "DExpectTypeSsm"; } + + ///@} + /** @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 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 + **/ + void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expecttype-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expecttypessm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + private: + /** temporary shim. + * if true, construct obj + * if false, construct TypeDescr + **/ + bool corrected_ = false; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DExpectTypeSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DGlobalEnv.hpp b/xo-reader2/include/xo/reader2/DGlobalEnv.hpp new file mode 100644 index 00000000..02a4679a --- /dev/null +++ b/xo-reader2/include/xo/reader2/DGlobalEnv.hpp @@ -0,0 +1,95 @@ +/** @file DGlobalEnv.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#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 TypeDescr = xo::reflect::TypeDescr; + using AGCObject = xo::mm::AGCObject; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; + + public: + /** @defgroup scm-globalenv-ctors constructors **/ + ///@{ + + DGlobalEnv(DGlobalSymtab * symtab, DArray * values); + + static DGlobalEnv * _make(obj mm, + DGlobalSymtab * symtab); + + + ///@} + /** @defgroup scm-globalenv-methods methods **/ + ///@{ + + /** symbol-table size. Is the number of distinct global variables **/ + size_type n_vars() const noexcept { return symtab_->n_vars(); } + + /** 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); + + /** create/establish global for symbol @p sym with resolved type @p td + * and associate with @p value. + **/ + DVariable * _upsert_value(obj mm, + const DUniqueString * sym, + TypeDescr td, + obj value); + + ///@} + /** @defgroup scm-globalenv-gcobject-facet **/ + ///@{ + + DGlobalEnv * gco_shallow_move(obj gc) noexcept; + void visit_gco_children(VisitReason reason, 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_; + + /** value for a symbol S will be in values_[symtab->lookup_binding(S)] **/ + DArray * values_ = nullptr; + }; + } +} diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp new file mode 100644 index 00000000..3abc38ea --- /dev/null +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -0,0 +1,253 @@ +/** @file DProgressSsm.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#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 DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + 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); + + /** 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); + static void start(DArena & parser_mm, + obj lhs, + ParserStateMachine * p_psm); + static void start(DArena & parsermm, + obj lhs, + optype optype, + ParserStateMachine * p_psm); + + 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 + + static const char * ssm_classname() { return "DProgressSsm"; } + + std::string_view get_expect_str() const noexcept; + + /** assemble expression from collected inputs. + * Usually triggered by syntax like ';' or ')' + **/ + obj assemble_expr(ParserStateMachine * p_psm); + + /** @defgroup scm-progressssm-methods general methods **/ + ///@{ + + /** 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); + 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, + 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, + 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, + 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); + + ///@} + /** @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_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 print(std::ostream & os) const override; +#endif + + /** @defgroup scm-progressssm-gc-support gc support methods **/ + ///@{ + + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + 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, 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*/ + +#ifndef ppdetail_atomic + namespace print { + PPDETAIL_ATOMIC(xo::scm::optype); + } +#endif +} /*namespace xo*/ + + +/* end DProgressSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DQuoteSsm.hpp b/xo-reader2/include/xo/reader2/DQuoteSsm.hpp new file mode 100644 index 00000000..0874b549 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DQuoteSsm.hpp @@ -0,0 +1,172 @@ +/** @file DQuoteSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include + +namespace xo { + namespace scm { + + /** + * @pre + * + * #q{ quote-expr } + * ^ ^ ^ ^ ^ + * | | | | (done) + * | | | | + * | | | quote_3:expect_rightbrace + * | | quote_2:expect_parsed_expression + * | quote_1:expect_leftbrace + * quote_0 + * + * quote_0 --on_quote_token()--> quote_1 + * quote_1 --on_leftbrace_token()--> quote_2 + * quote_2 --on_parsed_expression()--> quote_3 [will be constant expression] + * quote_3 --on_rightparen_token()--> (done) + * + * @endpre + **/ + class QuoteXst { + public: + enum class code { + invalid = -1, + + quote_0, + quote_1, + quote_2, + quote_3, + + N, + }; + + explicit QuoteXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + inline std::ostream & + operator<<(std::ostream & os, QuoteXst x) { + os << QuoteXst::_descr(x.code_); + return os; + } + + class DQuoteSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-parenssm-ctors **/ + ///@{ + + DQuoteSsm(); + + /** create instance using memory from @p parser_mm + **/ + static DQuoteSsm * _make(DArena & parser_mm); + + /** create fop pointing with new DQuoteSsm using memory from @p parser_mm **/ + static obj make(DArena & parser_mm); + + /** push DQuoteSsm 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 "DQuoteSsm"; } + + /** internal state **/ + QuoteXst quotestate() const noexcept { return quote_xst_; } + + ///@} + /** @defgroup scm-parenssm-admin-methods admin methods **/ + ///@{ + + /** update ssm for incoming quote token @p tk. + * with overall parser state in @p p_psm. + * advances from quote_0 -> quote_1. Otherwise error + **/ + void on_quote_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update ssm state for incoming leftparen token @p tk, + * with overall parser state in @p p_psm + **/ + void on_leftbrace_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_rightbrace_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); + + /** update ssm for expression @p expr (emitted by nested ssm), + * with overall parser state in @p p_psm + **/ + void on_quoted_literal(obj literal, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-parenssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-quotessm-gc-support gc support methods */ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + ///@} + private: + /** @defgroup scm-parenssm-member-vars **/ + ///@{ + + /** identify quote-expression state **/ + QuoteXst quote_xst_; + /** scaffold expression (representing parenthesized value) here **/ + obj expr_; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DQuoteSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp new file mode 100644 index 00000000..c153d76e --- /dev/null +++ b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp @@ -0,0 +1,119 @@ +/** @file DSequenceSsm.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#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 Super = DSyntaxStateMachine; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + static const char * ssm_classname() { return "DSequenceSsm"; } + + /** start parsing a sequence-expr. + * input begins with first expression in the sequence. + **/ + static void start(ParserStateMachine * p_psm); + + /** 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_with_semicolon(bp expr, + 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 **/ + ///@{ + + /** 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; + + /** 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); + + /** 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 methods **/ + ///@{ + + /** pretty printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-sequencessm-gcobject-facet gcobject facet methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + private: + 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*/ + + +/* end DSequenceSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp new file mode 100644 index 00000000..66852170 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp @@ -0,0 +1,210 @@ +/** @file DSyntaxStateMachine.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "ParserStateMachine.hpp" +#include + +namespace xo { + namespace scm { + + /** @class DSyntaxStateMachine + * @brief static helper interface for ASyntaxStateMachine implementations + * + * Using CRTP. + * + * 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 { + public: + using TypeDescr = xo::reflect::TypeDescr; + using AGCObject = xo::mm::AGCObject; + + /** Explicit error path **/ + void illegal_token(const Token & tk, + ParserStateMachine * p_psm) + { + // 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()); + } + + /** Explicit error path **/ + void illegal_type(obj type, + ParserStateMachine * p_psm) + { + // starting with c++23 can use "this auto&& self" instead + Derived & self = static_cast(*this); + + p_psm->illegal_input_on_type(Derived::ssm_classname(), + type, + self.get_expect_str()); + } + + /** Explicit error path **/ + void illegal_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + // starting with c++23 can use "this auto&& self" instead + Derived & self = static_cast(*this); + + p_psm->illegal_input_on_symbol(Derived::ssm_classname(), + sym, + self.get_expect_str()); + } + + /** Explicit error path **/ + void illegal_quoted_literal(obj lit, + ParserStateMachine * p_psm) + { + // starting with c++23 can use "this auto&& self" instead + Derived & self = static_cast(*this); + + p_psm->illegal_quoted_literal(Derived::ssm_classname(), + lit, + self.get_expect_str()); + } + + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm) + { + this->illegal_token(tk, p_psm); + } + + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + this->illegal_parsed_symbol(sym, p_psm); + } + + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + // 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 require SyntaxStateMachine facet method + **/ + void on_parsed_type(obj type, + ParserStateMachine * p_psm) + { + this->illegal_type(type, p_psm); + } + + /** Default implementation for required SyntaxStateMachine facet method + **/ + void on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + ParserStateMachine * p_psm) + { + // 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()); + } + + /** 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 + **/ + void on_parsed_formal_arglist(DArray * arglist, + ParserStateMachine * p_psm) + { + // 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(obj expr, + ParserStateMachine * p_psm) + { + // 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()); + + } + + /** Default implementation for required SyntaxStateMachine facet method + **/ + 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); + + // We don't need a separate entry point, + // since the semicolon isn't relevant to problem with syntax + // + + p_psm->illegal_parsed_expression_with_token(Derived::ssm_classname(), + expr, + tk, + self.get_expect_str()); + + } + + /** Default impplementation for required SyntaxStateMachine facet method **/ + void on_quoted_literal(obj lit, + ParserStateMachine * p_psm) + { + this->illegal_quoted_literal(lit, p_psm); + } + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DSyntaxStateMachine.hpp */ diff --git a/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp b/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp new file mode 100644 index 00000000..5df90f4d --- /dev/null +++ b/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp @@ -0,0 +1,179 @@ +/** @file DToplevelSeqSsm.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.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 + }; + + const char * exprseqtype_descr(exprseqtype x); + + inline std::ostream & operator<<(std::ostream & os, exprseqtype x) { + os << exprseqtype_descr(x); + return os; + } + + /** @class DToplevelSeqSsm + * @brief state machine for parsing a sequence of expression + * + * Similar to exprseq_xs in xo-expresion + **/ + class DToplevelSeqSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + explicit DToplevelSeqSsm(exprseqtype ty); + + /** start interactive top-level session **/ + static void establish_interactive(DArena & mm, + ParserStateMachine * p_psm); + /** start non-interactive top-level session **/ + static void establish_batch(DArena & mm, + ParserStateMachine * p_psm); + + public: + static const char * ssm_classname() { return "DToplevelSeqSsm"; } + + /** @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; + + /** 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 + **/ + 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 @c deftype token @p tk, + * with overall parser state in @p p_psm + **/ + void on_deftype_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 + **/ + void on_if_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 nil token @p tk, + * overall parser state in @p p_psm + **/ + void on_nil_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 ssm for incoming quote token @p tk, overall parser state in @p p_psm + * starts nested syntax for quoted literal + **/ + void on_quote_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 + **/ + void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + + /** update state for this syntax on parsed expression @p expr + * followed by token @p tk from nested ssm. + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-exprseq-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printing driver; combine layout+printing **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-toplevelseqssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + ///@} + + private: + /** sequence type. accept rvalue expressions when + * this is toplevel_interactive. + * Always accept definitions and declarations. + **/ + exprseqtype seqtype_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DToplevelSeqSsm.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..7ccdd2db --- /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 "define/ISyntaxStateMachine_DDefineSsm.hpp" +#include "define/IPrintable_DDefineSsm.hpp" + +/* end DefineSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DeftypeSsm.hpp b/xo-reader2/include/xo/reader2/DeftypeSsm.hpp new file mode 100644 index 00000000..324875ba --- /dev/null +++ b/xo-reader2/include/xo/reader2/DeftypeSsm.hpp @@ -0,0 +1,12 @@ +/** @file DeftypeSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "deftype/DDeftypeSsm.hpp" +#include "deftype/ISyntaxStateMachine_DDeftypeSsm.hpp" +#include "deftype/IPrintable_DDeftypeSsm.hpp" + +/* end DeftypeSsm.hpp */ 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/ExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/ExpectFormalArgSsm.hpp new file mode 100644 index 00000000..fc3dbe52 --- /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 "expect_formal_arg/DExpectFormalArgSsm.hpp" +#include "expect_formal_arg/ISyntaxStateMachine_DExpectFormalArgSsm.hpp" +#include "expect_formal_arg/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/ExpectListTypeSsm.hpp b/xo-reader2/include/xo/reader2/ExpectListTypeSsm.hpp new file mode 100644 index 00000000..63f388a3 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectListTypeSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectListTypeSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "expect_listtype/DExpectListTypeSsm.hpp" +#include "expect_listtype/ISyntaxStateMachine_DExpectListTypeSsm.hpp" +#include "expect_listtype/IPrintable_DExpectListTypeSsm.hpp" + +/* end ExpectListTypeSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpectQArraySsm.hpp b/xo-reader2/include/xo/reader2/ExpectQArraySsm.hpp new file mode 100644 index 00000000..78dcf1cb --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectQArraySsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectQArraySsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DExpectQArraySsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp" +#include "ssm/IPrintable_DExpectQArraySsm.hpp" + +/* end ExpectQArraySsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpectQDictSsm.hpp b/xo-reader2/include/xo/reader2/ExpectQDictSsm.hpp new file mode 100644 index 00000000..447e5cc7 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectQDictSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectQDictSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "expect_qdict/DExpectQDictSsm.hpp" +#include "expect_qdict/ISyntaxStateMachine_DExpectQDictSsm.hpp" +#include "expect_qdict/IPrintable_DExpectQDictSsm.hpp" + +/* end ExpectQDictSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpectQListSsm.hpp b/xo-reader2/include/xo/reader2/ExpectQListSsm.hpp new file mode 100644 index 00000000..82a3c0ab --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectQListSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectQListSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DExpectQListSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectQListSsm.hpp" +#include "ssm/IPrintable_DExpectQListSsm.hpp" + +/* end ExpectQListSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ExpectQLiteralSsm.hpp b/xo-reader2/include/xo/reader2/ExpectQLiteralSsm.hpp new file mode 100644 index 00000000..562387dc --- /dev/null +++ b/xo-reader2/include/xo/reader2/ExpectQLiteralSsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectQLiteralSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DExpectQLiteralSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectQLiteralSsm.hpp" +#include "ssm/IPrintable_DExpectQLiteralSsm.hpp" + +/* end ExpectQLiteralSsm.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/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/GlobalEnv.hpp b/xo-reader2/include/xo/reader2/GlobalEnv.hpp new file mode 100644 index 00000000..94bafc42 --- /dev/null +++ b/xo-reader2/include/xo/reader2/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-reader2/include/xo/reader2/IfElseSsm.hpp b/xo-reader2/include/xo/reader2/IfElseSsm.hpp new file mode 100644 index 00000000..7fa7fcc5 --- /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 "ifelse/DIfElseSsm.hpp" +#include "ifelse/ISyntaxStateMachine_DIfElseSsm.hpp" +#include "ifelse/IPrintable_DIfElseSsm.hpp" + +/* end IfElseSsm.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..25e7a2e4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/LambdaSsm.hpp @@ -0,0 +1,10 @@ +/** @file LambdaSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "lambda/DLambdaSsm.hpp" +#include "lambda/ISyntaxStateMachine_DLambdaSsm.hpp" +#include "lambda/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..ff03da9b --- /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 "paren/DParenSsm.hpp" +#include "paren/ISyntaxStateMachine_DParenSsm.hpp" +#include "paren/IPrintable_DParenSsm.hpp" + +/* end ParenSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserConfig.hpp b/xo-reader2/include/xo/reader2/ParserConfig.hpp new file mode 100644 index 00000000..2804be7b --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParserConfig.hpp @@ -0,0 +1,69 @@ +/** @file SchematikaParserConfig.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include +#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_ = true, + .header_{}, + .debug_flag_ = false }; + + /** configuration for hash map for global symbol table (variables) + * + * reminder: ownership chain + * SchematikaReader + * ->SchematikaParser + * ->ParserStateMachine + * ->DGlobalSymtab + **/ + ArenaHashMapConfig symtab_var_config_ { + .name_ = "global-vars", + .hint_max_capacity_ = 64*1024, + .debug_flag_ = false + }; + + /** configuration for hash map for global symbol table (types) + * + * reminder: ownership chain + * SchematikaReader + * ->SchematikaParser + * ->ParserStateMachine + * ->DGlobalSymtab + **/ + ArenaHashMapConfig symtab_types_config_ { + .name_ = "global-types", + .hint_max_capacity_ = 32*1024, + .debug_flag_ = false + }; + + /** max capacity for unique string table **/ + size_t max_stringtable_capacity_ = 4096; + + /** flags controlling which primitives to install **/ + InstallFlags pm_install_flags_ = InstallFlags::f_all; + + /** control SchematikaParser debug logging **/ + bool debug_flag_ = false; + }; + + } +} + +/* end SchematikaParserConfig.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..c8976da4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -0,0 +1,119 @@ +/** @file ParserResult.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include +#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 + }; + + /** @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 AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using ppindentinfo = xo::print::ppindentinfo; + + public: + ParserResult() = default; + ParserResult(parser_result_type type, + obj expr, + 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 + **/ + 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_; } + + 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; } + + /** ordinary not-pretty printer **/ + void print(std::ostream & os) const; + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + /** gc support: forward gc-eligible children **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + public: + /** 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/include/xo/reader2/ParserStack.hpp b/xo-reader2/include/xo/reader2/ParserStack.hpp new file mode 100644 index 00000000..fade2079 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParserStack.hpp @@ -0,0 +1,100 @@ +/** @file ParserStack.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include +#include +#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 ACollector = xo::mm::ACollector; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + 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. + * Checkpoint @p ckp will refer to stack _before_ allocating @p ssm + **/ + static ParserStack * push(ParserStack * stack, + DArena::Checkpoint ckp, + DArena & mm, + obj ssm); + + /** unwind effect of last call to @ref push **/ + static ParserStack * pop(ParserStack * stack, + DArena & mm); + + static constexpr bool is_gc_eligible() { return false; } + + DArena::Checkpoint ckp() const noexcept { return ckp_; } + 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; + + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + 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 **/ + 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 new file mode 100644 index 00000000..b73eac0b --- /dev/null +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -0,0 +1,478 @@ +/** @file ParserStateMachine.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ParserResult.hpp" +#include "GlobalEnv.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xo { + namespace scm { + // defined in ssm/ASyntaxStateMachine.hpp, but + // including here would create include cycle + // + class ASyntaxStateMachine; + + // 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; + + /** @brief State machine embodying Schematika parser + **/ + class ParserStateMachine { + public: + using TypeDescr = xo::reflect::TypeDescr; + using ACollector = xo::mm::ACollector; + using AGCObject = xo::mm::AGCObject; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + 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: + /** @defgroup scm-parserstatemachine-ctors constructors **/ + ///@{ + + /** + * @p config arena configuration for parser state + * @p symtab_var_config configuration for global symtab variables + * (maps separate dedicated memory) + * @p symtab_type_config configuration for global symtab types + * (maps to separate dedicated memory) + * @p max_stringtable_capacity + * hard max size for unique stringtable + * @p pm_install_flags + * flags controlling primitives to install + * @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. + * + * NOTE: + * When @p expr_alloc supports the Collector facet: + * ParserStateMachine isn't itself in gc-space + * (i.e. isn't expected to belong to @p expr_alloc). + * To update pointers to gc-owned objects, must have forward_children() + * called as part of @p expr_alloc's gc cycle. + **/ + ParserStateMachine(const ArenaConfig & config, + const ArenaHashMapConfig & symtab_var_config, + const ArenaHashMapConfig & symtab_type_config, + size_type max_stringtable_capacity, + InstallFlags pm_install_flags, + obj expr_alloc, + obj aux_alloc); + + /** not copyable (need to put global_env into gc **/ + ParserStateMachine(const ParserStateMachine & other) = delete; + + /** non-trivial dtor for @ref global_symtab_ **/ + ~ParserStateMachine(); + + static constexpr bool is_gc_eligible() { return false; } + + ///@} + /** @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_; } + StringTable * stringtable() noexcept { return &stringtable_; } + DGlobalSymtab * global_symtab() const noexcept { return global_symtab_.data(); } + DLocalSymtab * local_symtab() const noexcept { return local_symtab_.data(); } + DGlobalEnv * global_env() const noexcept { return global_env_.data(); } + const ParserResult & result() const noexcept { return result_; } + + /** polymoprhihc multiply primitive. Use to implement infix op* **/ + obj multiply_pm() const; + /** polymorphic divide primitive. Use to implement infix op/ **/ + obj divide_pm() const; + /** polymorphic add primitive. Use to implement infix op+ **/ + obj add_pm() const; + /** polymorphic subtract primitive. Use to implement infix op- **/ + obj subtract_pm() const; + /** polymorphic equality comparison. Use to implement infix op== **/ + obj cmpeq_pm() const; + /** polymorphic inequality comparison. Use to implement infix op!= **/ + obj cmpne_pm() const; + /** polymorphic less-than comparison. Use to implement infix op< **/ + obj cmplt_pm() const; + /** polymorphic less-or-equal comparison. Use to implement infix op<= **/ + obj cmple_pm() const; + /** polymorphic greater comparison. Use to implement infix op> **/ + obj cmpgt_pm() const; + /** polymorphic greater-or-equal comparison. Use to implement infix op>= **/ + obj cmpge_pm() const; + + /** 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; + + /** top of parser stack **/ + obj top_ssm() const; + + /** visit psm-owned memory pools; call visitor(info) for each **/ + void visit_pools(const MemorySizeVisitor & visitor) const; + + ///@} + + /** @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); + + /** 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(); + + /** get unique string copy of @p str. Idempotent for each @p str. + **/ + const DUniqueString * intern_string(std::string_view str); + + /** get unique (within stringtable) string, beginning with @p prefix **/ + const DUniqueString * gensym(std::string_view prefix); + + /** 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. + * 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); + + /** reset result to none **/ + void reset_result(); + + /** reset after reporting error **/ + void clear_error_reset(); + + ///@} + /** @defgroup scm-parserstatemachine-inputmethods input methods **/ + ///@{ + + /** 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); + + /** respond to type emitted by nested ssm **/ + void on_parsed_type(obj type); + + /** 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 + **/ + void on_parsed_formal_arglist(DArray * arglist); + + /** 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 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 consume quoted literal @p lit **/ + void on_quoted_literal(obj lit); + + /** update state to respond to input token @p tk. + * record output (if any) in @ref result_ + **/ + void on_token(const Token & tk); + + ///@} + /** @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. + * + * @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 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); + + /** 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); + + /** report illegal input arriving in syntax state machine (ssm) @p ssm_name + * when receiving type definition @p ty. + * @p expect_str sketches expected input in current ssm state + **/ + void illegal_input_on_type(std::string_view ssm_name, + obj ty, + 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 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, + 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 + **/ + void illegal_parsed_expression(std::string_view ssm_name, + 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 illegal quoted literal @p lit from nested ssm @p ssm_name. + * Possibly unreachable. + **/ + void illegal_quoted_literal(std::string_view ssm_name, + obj lit, + 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); + + ///@} + /** @defgroup scm-parserstatemachine-gcobject-facet gc support **/ + ///@{ + + /** update gc-aware exit pointers from this ParserStateMachine **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + private: +#ifdef OBSOLETE + /** @defgroup scm-parserstatemachine-impl-methods implementation methods **/ + ///@{ + + /** record gc-mutable state vars so they're updated when gc runs **/ + void _add_gc_roots(); + + ///@} +#endif + + private: + /** @defgroup scm-parserstatemachine-instance-vars instance variables **/ + ///@{ + + /** 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 + * + * Contents will be a stack of ExprState instances + **/ + 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 always from @ref parser_alloc_; + * elements that should survive parsing allocate from + * @ref expr_alloc_, see below. + **/ + 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_; + + /** 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_; + + /** 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? + **/ + obj global_symtab_; + + /** 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. + **/ + obj local_symtab_; + + /** global variable bindings (builtin primitives) **/ + obj global_env_; + + /** bindings for special builtin primitives + * (asociated with hardwired operator syntax) + **/ + Binding multiply_binding_; + Binding divide_binding_; + Binding add_binding_; + Binding subtract_binding_; + Binding cmpeq_binding_; + Binding cmpne_binding_; + Binding cmplt_binding_; + Binding cmple_binding_; + Binding cmpgt_binding_; + Binding cmpge_binding_; + + /** 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/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/include/xo/reader2/QuoteSsm.hpp b/xo-reader2/include/xo/reader2/QuoteSsm.hpp new file mode 100644 index 00000000..801179e9 --- /dev/null +++ b/xo-reader2/include/xo/reader2/QuoteSsm.hpp @@ -0,0 +1,12 @@ +/** @file QuoteSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DQuoteSsm.hpp" +#include "quote/ISyntaxStateMachine_DQuoteSsm.hpp" +#include "quote/IPrintable_DQuoteSsm.hpp" + +/* end QuoteSsm.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/ReaderConfig.hpp b/xo-reader2/include/xo/reader2/ReaderConfig.hpp new file mode 100644 index 00000000..9af06879 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ReaderConfig.hpp @@ -0,0 +1,85 @@ +/** @file ReaderConfig.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include +#include +#include +#include + +namespace xo { + namespace scm { + + /** @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; + + /** 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_ = "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 (variables) + * + * reminder: ownership chain + * SchematikaReader + * ->SchematikaParser + * ->ParserStateMachine + * ->DGlobalSymtab + **/ + ArenaHashMapConfig symtab_var_config_ { + .name_ = "global-vars", + .hint_max_capacity_ = 64*1024, + .debug_flag_ = false, + }; + + /** configuration for hash map for global symbol table (types) + * + * reminder: ownership chain + * SchematikaReader + * ->SchematikaParser + * ->ParserStateMachine + * ->DGlobalSymtab + **/ + ArenaHashMapConfig symtab_types_config_ { + .name_ = "global-types", + .hint_max_capacity_ = 32*1024, + .debug_flag_ = false, + }; + + /** debug flag for schematika parser **/ + bool parser_debug_flag_ = false; + + /** max size (in bytes) of stringtable **/ + size_t max_stringtable_cap_ = 64*1024; + + /** flags controlling which primitives to install **/ + InstallFlags pm_install_flags_ = InstallFlags::f_all; + + /** debug flag for schematika_reader **/ + bool reader_debug_flag_ = false; + }; + + } /*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 new file mode 100644 index 00000000..c93bfb19 --- /dev/null +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -0,0 +1,11 @@ +/** @file SchematikaParser.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "parser/DSchematikaParser.hpp" +#include "parser/IGCObject_DSchematikaParser.hpp" + +/* end SchemtikaParser.hpp */ diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp new file mode 100644 index 00000000..fd2f5cc9 --- /dev/null +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -0,0 +1,139 @@ +/** @file SchematikaReader.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ReaderConfig.hpp" +#include "SchematikaParser.hpp" +#include +#include + +namespace xo { + namespace scm { + struct ReaderResult { + using ACollector = xo::mm::ACollector; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using span_type = xo::mm::span; + + bool is_tk_error() const { return tk_error_.is_error(); } + + /** forward gc-aware pointers (called during gc cycle) **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + /** schematika expression parsed from input **/ + obj expr_; + /** unconsumed portion of input span + * only relevant when result type is expression. + * (otherwise input consumed) + **/ + span_type remaining_input_; + + /** {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 ACollector = xo::mm::ACollector; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using span_type = xo::mm::span; + 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 aux_alloc); + + /** non-trivial dtor because of @p parser **/ + ~SchematikaReader() = default; + + /** top-level symbol table **/ + DGlobalSymtab * global_symtab() const noexcept; + + /** top-level global environment (e.g. contains built-in primitives) **/ + DGlobalEnv * global_env() const noexcept; + + /** global unique-string table **/ + StringTable * stringtable() noexcept; + + /** visit reader-owned memory pools; call visitor(info) for each. + * Specifically exclude expr_alloc, since we don't consider + * that reader-owned + **/ + void visit_pools(const MemorySizeVisitor & visitor) const; + + /** 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(); + + /** prepare batch session + * (limits expression types at toplevel) + **/ + void begin_batch_session(); + + /** intern string @p str in global string table + **/ + const DUniqueString * intern_string(std::string_view str); + + /** 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. + * - current parsing state + **/ + void reset_to_idle_toplevel(); + + /** update gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + 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 + **/ + DSchematikaParser parser_; + + /** current output from reader **/ + ReaderResult result_; + + /** true to enable reader debug logging **/ + bool debug_flag_ = false; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end SchematikaReader.hpp */ 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/SetupReader2.hpp b/xo-reader2/include/xo/reader2/SetupReader2.hpp new file mode 100644 index 00000000..574bc296 --- /dev/null +++ b/xo-reader2/include/xo/reader2/SetupReader2.hpp @@ -0,0 +1,25 @@ +/** @file SetupReader2.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + struct SetupReader2 { + public: + using ACollector = xo::mm::ACollector; + + public: + /** Register reader2 (facet,impl) combinations with FacetRegistry **/ + static bool register_facets(); + /** Register object types with @p gc **/ + static bool register_types(obj gc); + }; + } +} + +/* end SetupReader2.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..c9c37ee1 --- /dev/null +++ b/xo-reader2/include/xo/reader2/SyntaxStateMachine.hpp @@ -0,0 +1,22 @@ +/** @file SyntaxStateMachine.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 */ 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/apply/DApplySsm.hpp b/xo-reader2/include/xo/reader2/apply/DApplySsm.hpp new file mode 100644 index 00000000..dd724066 --- /dev/null +++ b/xo-reader2/include/xo/reader2/apply/DApplySsm.hpp @@ -0,0 +1,235 @@ +/** @file DApplySsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#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 + * --on_rightparen()--> (done) + * 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, or rightparent to continue + * 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, // rename -> apply_2a + apply_3, // rename -> apply_2b + + 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 AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + 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(applyexprstatetype applystate, + obj fn_expr, + DArray * args); + + /** 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); + + /** create fop referring to new DApplySsm **/ + static obj make(DArena & parser_mm, + obj fn_expr); + + /** + * 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, ...) + * + * @p fnex expression in function position + * @p p_psm parser state machine + **/ + static void start(obj fnex, + ParserStateMachine * p_psm); + ///@} + /** @defgroup scm-applyssm-access-methods access methods **/ + ///@{ + + /** identify this nested state machine **/ + static const char * ssm_classname() { return "DApplySsm"; } + + /** 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); + + /** handle rightparen token @p tk for this ssm, + * with overall parser state in @p p_psm. + * + * Rightparen will complete apply-expression, + * terminating this syntax. + **/ + void on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @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; + + /** 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); + + /** 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 + + 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_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) override; + + private: + static std::unique_ptr make(); +#endif + + /** @defgroup ssm-applyssm-printable-facet printable facet **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-applyssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + private: + /** @defgroup ssm-applyssm-impl-methods **/ + ///@{ + + /** create final apply-expression for this syntax, + * using @p mm for memory + **/ + obj assemble_expr(obj mm); + + ///@} + + 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 **/ + obj fn_expr_; + /** 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 */ + + namespace print { +#ifndef ppdetail_atomic + PPDETAIL_ATOMIC(xo::scm::applyexprstatetype); +#endif + } +} /*namespace xo*/ + +/* end DApplySsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/apply/IPrintable_DApplySsm.hpp b/xo-reader2/include/xo/reader2/apply/IPrintable_DApplySsm.hpp new file mode 100644 index 00000000..3bae71f2 --- /dev/null +++ b/xo-reader2/include/xo/reader2/apply/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/apply/ISyntaxStateMachine_DApplySsm.hpp b/xo-reader2/include/xo/reader2/apply/ISyntaxStateMachine_DApplySsm.hpp new file mode 100644 index 00000000..a50740f5 --- /dev/null +++ b/xo-reader2/include/xo/reader2/apply/ISyntaxStateMachine_DApplySsm.hpp @@ -0,0 +1,88 @@ +/** @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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DApplySsm & self, obj type, 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 nested 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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DApplySsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DApplySsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/define/IPrintable_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/define/IPrintable_DDefineSsm.hpp new file mode 100644 index 00000000..d50b0394 --- /dev/null +++ b/xo-reader2/include/xo/reader2/define/IPrintable_DDefineSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DDefineSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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/include/xo/reader2/define/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/define/ISyntaxStateMachine_DDefineSsm.hpp new file mode 100644 index 00000000..35df5ded --- /dev/null +++ b/xo-reader2/include/xo/reader2/define/ISyntaxStateMachine_DDefineSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DDefineSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 + /** 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 **/ + static void on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DDefineSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DDefineSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DDefineSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/deftype/DDeftypeSsm.hpp b/xo-reader2/include/xo/reader2/deftype/DDeftypeSsm.hpp new file mode 100644 index 00000000..8bbe3ea1 --- /dev/null +++ b/xo-reader2/include/xo/reader2/deftype/DDeftypeSsm.hpp @@ -0,0 +1,195 @@ +/** @file DDeftypeSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include + +namespace xo { + namespace scm { + /** + * @pre + * + * deftype foo :: f64 ; + * ^ ^ ^ ^ ^ ^ + * | | | | | (done) + * | | | | def_4 + * | | | def_3 + * | | def_2 + * | def_1 + * def_0 + * + * def_0 --on_deftype_token()--> def_1 [expect symbol] + * def_1 --on_symbol_token()--> def_2 [expect ::] + * def_2 --on_doublecolon_token()--> def_3 [start ExpectTypeSsm] + * def_3 --on_parsed_type()--> def_4 [++ symbol table] + * def_4 --on_semicolon_token()--> (done) [pop] + * + * @endpre + **/ + class DeftypeXst { + public: + enum class code { + invalid = -1, + + def_0, + def_1, + def_2, + def_3, + def_4, + + N, + }; + + explicit DeftypeXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + std::ostream & + operator<<(std::ostream & os, DeftypeXst x); + + /** @class DDeftypeSsm + * @brief state machine for parsing a deftype expression + **/ + class DDeftypeSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-deftypessm-ctors constructors **/ + ///@{ + + /** constructor; using @p def_expr for initial expression scaffold **/ + explicit DDeftypeSsm(); + + /** Create instance using memory from @p parser_mm **/ + static DDeftypeSsm * _make(DArena & parser_mm); + + /** create fop referring to new DDeftypeSsm **/ + static obj make(DArena & parser_mm); + + /** 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); + + ///@} + /** @defgroup scm-definessm-access-methods **/ + ///@{ + + /** identify this nested state machine **/ + static const char * ssm_classname() { return "DDeftypeSsm"; } + + /** internal state **/ + DeftypeXst deftypestate() const noexcept { return deftype_xst_; } + + ///@} + /** @defgroup scm-definessm-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 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 @c deftype token @p tk, + * overall parser state in @p p_psm + **/ + void on_deftype_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming double-colon token @p tk, + * overall parser state in @p p_psm + **/ + void on_doublecolon_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 type @p type emitted by nested + * state machine, with overall parser state in @p p_psm + **/ + void on_parsed_type(obj type, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + /** 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); +#endif + + /** update state for this syntax after parsing semicolon token @p tk, + * overall parser state in @p p_psm. + * if state def_4 completes deftype statement. + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-define-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-deftypessm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + ///@} + + private: + /** @defgroup scm-deftypessm-member-vars **/ + ///@{ + + /** identify deftype ssm state **/ + DeftypeXst deftype_xst_; + + /** lhs symbol for type definition **/ + const DUniqueString * lhs_symbol_ = nullptr; + + ///@} + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/deftype/IPrintable_DDeftypeSsm.hpp b/xo-reader2/include/xo/reader2/deftype/IPrintable_DDeftypeSsm.hpp new file mode 100644 index 00000000..df8820c0 --- /dev/null +++ b/xo-reader2/include/xo/reader2/deftype/IPrintable_DDeftypeSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DDeftypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDeftypeSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DDeftypeSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DDeftypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DDeftypeSsm + **/ + class IPrintable_DDeftypeSsm { + public: + /** @defgroup scm-printable-ddeftypessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-ddeftypessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DDeftypeSsm & 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/deftype/ISyntaxStateMachine_DDeftypeSsm.hpp b/xo-reader2/include/xo/reader2/deftype/ISyntaxStateMachine_DDeftypeSsm.hpp new file mode 100644 index 00000000..b984bc7d --- /dev/null +++ b/xo-reader2/include/xo/reader2/deftype/ISyntaxStateMachine_DDeftypeSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DDeftypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DDeftypeSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DDeftypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DDeftypeSsm + **/ + class ISyntaxStateMachine_DDeftypeSsm { + public: + /** @defgroup scm-syntaxstatemachine-ddeftypessm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-ddeftypessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DDeftypeSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DDeftypeSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DDeftypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DDeftypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DDeftypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DDeftypeSsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DDeftypeSsm & 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(DDeftypeSsm & 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(DDeftypeSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DDeftypeSsm & 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(DDeftypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DDeftypeSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DDeftypeSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/env/IGCObject_DGlobalEnv.hpp b/xo-reader2/include/xo/reader2/env/IGCObject_DGlobalEnv.hpp new file mode 100644 index 00000000..b8fb15f0 --- /dev/null +++ b/xo-reader2/include/xo/reader2/env/IGCObject_DGlobalEnv.hpp @@ -0,0 +1,69 @@ +/** @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 AGCObjectVisitor = xo::mm::AGCObject::AGCObjectVisitor; + using VisitReason = xo::mm::AGCObject::VisitReason; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dglobalenv-methods **/ + ///@{ + // const methods + + // non-const methods + /** move instance using object visitor. +Arguably abusing the word 'visitor' here **/ + static Opaque gco_shallow_move(DGlobalEnv & self, obj gc) noexcept; + /** Invoke fn.visit_child(iface,data) for each child GCObject pointer. +Context: provides address of data pointer so it can be updated in place +when @p fn invokes garbage collector reentry point **/ + static void visit_gco_children(DGlobalEnv & self, VisitReason reason, obj fn) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/env/IGCObject_DSchematikaParser.hpp b/xo-reader2/include/xo/reader2/env/IGCObject_DSchematikaParser.hpp new file mode 100644 index 00000000..03832e87 --- /dev/null +++ b/xo-reader2/include/xo/reader2/env/IGCObject_DSchematikaParser.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DSchematikaParser.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DSchematikaParser.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DSchematikaParser.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DSchematikaParser.hpp" + +namespace xo { namespace scm { class IGCObject_DSchematikaParser; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DSchematikaParser + **/ + class IGCObject_DSchematikaParser { + public: + /** @defgroup scm-gcobject-dschematikaparser-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-dschematikaparser-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DSchematikaParser & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_move(const DSchematikaParser & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DSchematikaParser & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ diff --git a/xo-reader2/include/xo/reader2/env/IPrintable_DGlobalEnv.hpp b/xo-reader2/include/xo/reader2/env/IPrintable_DGlobalEnv.hpp new file mode 100644 index 00000000..6efcd963 --- /dev/null +++ b/xo-reader2/include/xo/reader2/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-reader2/include/xo/reader2/expect_formal_arg/DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/expect_formal_arg/DExpectFormalArgSsm.hpp new file mode 100644 index 00000000..38a4bb3e --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_formal_arg/DExpectFormalArgSsm.hpp @@ -0,0 +1,151 @@ +/** @file DExpectFormalSsm.hpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#pragma once + +#include "DSyntaxStateMachine.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 DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroupo scm-expectfromalargssm-ctors constructors **/ + ///@{ + + DExpectFormalArgSsm(); + + /** create empty instance using memory from @p 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-methods general methods **/ + ///@{ + + static const char * ssm_classname() { return "DExpectFormalArgSsm"; } + + /** 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); + + /** 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 **/ + ///@{ + + /** 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); + + ///@} + /** @defgroup scm-expectformalargssm-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectformalargssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + +#ifdef PROBABLY_NOT + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; +#endif + + private: + /** parsing state-machine state **/ + formalstatetype fstate_ = formalstatetype::formal_0; + + /** formal parameter name **/ + const DUniqueString * name_ = nullptr; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectFormalArgSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/expect_formal_arg/IPrintable_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/expect_formal_arg/IPrintable_DExpectFormalArgSsm.hpp new file mode 100644 index 00000000..6467a0d4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_formal_arg/IPrintable_DExpectFormalArgSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectFormalArgSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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/include/xo/reader2/expect_formal_arg/ISyntaxStateMachine_DExpectFormalArgSsm.hpp b/xo-reader2/include/xo/reader2/expect_formal_arg/ISyntaxStateMachine_DExpectFormalArgSsm.hpp new file mode 100644 index 00000000..ccdfc0bd --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_formal_arg/ISyntaxStateMachine_DExpectFormalArgSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectFormalArgSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 type emitted by nested ssm **/ + static void on_parsed_type(DExpectFormalArgSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectFormalArgSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectFormalArgSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/expect_listtype/DExpectListTypeSsm.hpp b/xo-reader2/include/xo/reader2/expect_listtype/DExpectListTypeSsm.hpp new file mode 100644 index 00000000..ce69f929 --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_listtype/DExpectListTypeSsm.hpp @@ -0,0 +1,159 @@ +/** @file DExpectListTypeSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" + +namespace xo { + namespace scm { + + /** + * list < type-expr > + * ^ ^ ^ ^ ^ + * | | | | (done) + * | | | type_3 --on_rightangle_token() --> (done) [pop + report listtype] + * | | type_2 --on_parsed_type()--> type_3 + * | type_1 --on_leftangle_token() --> type_2 [push ExpectTypeSsm] + * type_0 --on_symbol_token()--> type_1 + * + **/ + class ListTypeXst { + public: + enum class code { + invalid = -1, + + type_0, + type_1, + type_2, + type_3, + + N, + }; + + explicit ListTypeXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + inline std::ostream & + operator<<(std::ostream & os, ListTypeXst x) { + os << ListTypeXst::_descr(x.code_); + return os; + } + + /** @class DExpectListTypeSsm + * @brief parser state-machine for a list type + * + * Examples: + * @pre + * list + * list> + * @endpre + **/ + class DExpectListTypeSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** default ctor **/ + explicit DExpectListTypeSsm(); + + /** create instance. Get memory from @p parser_mm **/ + static DExpectListTypeSsm * _make(DArena & parser_mm); + + /** create instance as fop. Get memory from @p parser_mm **/ + static obj make(DArena & parser_mm); + + /** start nested state machine to parse a list type **/ + static void start(ParserStateMachine * p_psm); + + /** @defgroup scm-expectlisttypessm-expression-methods general methods **/ + ///@{ + + static const char * ssm_classname() { return "DExpectListTypeSsm"; } + + syntaxstatetype ssm_type() const noexcept; + + std::string_view get_expect_str() const noexcept; + + /** update ssm for symbol token @p tk, with overall parsing state in @p p_psm. + * in state type_0: advance to type_1. + * otherwise error + **/ + void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update ssm for leftangle (<) token @p tk, with overall parser state in @p p_psm. + * in state type_1: advance to type_2, pushing nested ExpectTypeSsm. + * otherwise error. + **/ + void on_leftangle_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update ssm for rightangle (>) token @p tk, with overall parser state in @p p_psm. + * in state type_3: aseemble list type, report completed syntax to parent ssm + **/ + void on_rightangle_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectlisttypessm-expression-facet expression facet methods **/ + ///@{ + + /** update ssm for token @p tk, with overall state in @p p_psm **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update ssm for type @p type produced by nested ssm, with overall parser + * state in @p p_psm. + * in state type_2: @p type is element type for target list type. + * otherwise error. + **/ + void on_parsed_type(obj type, ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectlisttypessm-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectlisttypessm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + private: + /** @defgroup scm-expectlisttypessm-instance-vars instance variables **/ + ///@{ + + /** local parsing state **/ + ListTypeXst state_{ListTypeXst::code::type_0}; + + /** element type for target list type **/ + obj elt_type_; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectListTypeSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/expect_listtype/IPrintable_DExpectListTypeSsm.hpp b/xo-reader2/include/xo/reader2/expect_listtype/IPrintable_DExpectListTypeSsm.hpp new file mode 100644 index 00000000..b799d6ca --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_listtype/IPrintable_DExpectListTypeSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectListTypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectListTypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectListTypeSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectListTypeSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectListTypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectListTypeSsm + **/ + class IPrintable_DExpectListTypeSsm { + public: + /** @defgroup scm-printable-dexpectlisttypessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectlisttypessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectListTypeSsm & 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/expect_listtype/ISyntaxStateMachine_DExpectListTypeSsm.hpp b/xo-reader2/include/xo/reader2/expect_listtype/ISyntaxStateMachine_DExpectListTypeSsm.hpp new file mode 100644 index 00000000..b320b9c9 --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_listtype/ISyntaxStateMachine_DExpectListTypeSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectListTypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectListTypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectListTypeSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectListTypeSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectListTypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectListTypeSsm + **/ + class ISyntaxStateMachine_DExpectListTypeSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectlisttypessm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectlisttypessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectListTypeSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectListTypeSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectListTypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectListTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectListTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DExpectListTypeSsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectListTypeSsm & 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(DExpectListTypeSsm & 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(DExpectListTypeSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DExpectListTypeSsm & 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(DExpectListTypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectListTypeSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectListTypeSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/expect_qdict/DExpectQDictSsm.hpp b/xo-reader2/include/xo/reader2/expect_qdict/DExpectQDictSsm.hpp new file mode 100644 index 00000000..18c52bac --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_qdict/DExpectQDictSsm.hpp @@ -0,0 +1,188 @@ +/** @file DExpectQDictSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include +#include + +namespace xo { + namespace scm { + /** + * When this syntax is active, parser is already in a quoted-literal context + * + * { key(1) : value(1) ; ... ; } + * ^ ^ ^ ^ ^ ^ ^ ^ + * | | | qdict_1c | | | qdict_2(done) + * | | qdict_1b | | qdict_1d + * | qdict_1a | qdict_1a + * qdict_0 qdict_1d + * + * qdict_0 --on_leftbrace_token()--> qdict_1a [push ExpectSymbolSsm] + * qdict_1a --on_parsed_symbol()--> qdict_1b [remember key] + * qdict_1a --onrightbace_token()--> qdictZ(done) + * qdict_1b --on_colon_token()--> qdict_1c [push ExpectQLiteralSsm] + * qdict_1c --on_quoted_literal()--> qdict_1d [remember value] + * qdict_1d --on_semicolon_token()--> qdict_1a [loop] + * qdict_1d --on_rightbrace_token()--> qdict_2(done) + **/ + class QDictXst { + public: + enum class code { + invalid = -1, + + qdict_0, + qdict_1a, + qdict_1b, + qdict_1c, + qdict_1d, + qdict_2, + + N + }; + + explicit QDictXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + inline std::ostream & + operator<< (std::ostream & os, QDictXst x) { + os << QDictXst::_descr(x.code_); + return os; + } + + class DExpectQDictSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-expectqdictssm-ctors constructors **/ + ///@{ + + DExpectQDictSsm(); + + /** create instance using memory from @parser_mm **/ + static obj make(DArena & parser_mm); + /** create instance using memory from @parser_mm **/ + static DExpectQDictSsm * _make(DArena & parser_mm); + + /** start nested syntax for a quoted dictionary **/ + static void start(ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqdictssm-methods general methods **/ + ///@{ + + static const char * ssm_classname() { return "DExpectQDictSsm"; } + + /** update state on incoming leftbrace token @p tk, + * with overall parser state in @p p_psm + * + * in qdict_0 advance state to qdict_1a; otherwise error + **/ + void on_leftbrace_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 + * + * in qdict_1a capture key string + advance to qdict_1b; otherwise error + **/ + void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on incoming colon token @p tk, + * with overall parser state in @p p_psm + * + * in qdict_1b advance to qdict_1c + push ExpectQLiteralSsm; otherwise error + **/ + void on_colon_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state in on incoming semicolon token @p tk, + * with overall parser state in @p p_psm. + * + * in qdict_1d advance to qdict_1a (ready for another (key,value) pair); otherwise error + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on incoming rightbrace token @p tk, + * with overall parser state in @p p_psm + * + * in qdict_1a complete syntax + report literal to parent ssm; otherwise error + **/ + void on_rightbrace_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqdictssm-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, with overall parser state in @p p_psm **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state on quoted literal @p lit, with overall parser state in @p p_psm + * + * in qdict_1c capture (key,value) pair into dictionary + advance to qdict_1d; otherwise error + **/ + void on_quoted_literal(obj lit, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqdictssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-expectqdictssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + private: + /** @defgroup ssm-expectqdictssm-member-vars **/ + ///@{ + + /** iddentifies qdict parsing state **/ + QDictXst state_; + + /** captured key in next (key,value) pair; + * expect to include in @ref dict_ + **/ + const DString * key_ = nullptr; + + /** literal dictionary (assembled incrementally) **/ + DDictionary * dict_ = nullptr; + + ///@} + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectQDictSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/expect_qdict/IPrintable_DExpectQDictSsm.hpp b/xo-reader2/include/xo/reader2/expect_qdict/IPrintable_DExpectQDictSsm.hpp new file mode 100644 index 00000000..b5bb39d9 --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_qdict/IPrintable_DExpectQDictSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectQDictSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQDictSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQDictSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectQDictSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectQDictSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectQDictSsm + **/ + class IPrintable_DExpectQDictSsm { + public: + /** @defgroup scm-printable-dexpectqdictssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectqdictssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectQDictSsm & 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/expect_qdict/ISyntaxStateMachine_DExpectQDictSsm.hpp b/xo-reader2/include/xo/reader2/expect_qdict/ISyntaxStateMachine_DExpectQDictSsm.hpp new file mode 100644 index 00000000..006e43b1 --- /dev/null +++ b/xo-reader2/include/xo/reader2/expect_qdict/ISyntaxStateMachine_DExpectQDictSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectQDictSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQDictSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQDictSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectQDictSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectQDictSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectQDictSsm + **/ + class ISyntaxStateMachine_DExpectQDictSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectqdictssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectqdictssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectQDictSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectQDictSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectQDictSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectQDictSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectQDictSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DExpectQDictSsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectQDictSsm & 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(DExpectQDictSsm & 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(DExpectQDictSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DExpectQDictSsm & 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(DExpectQDictSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectQDictSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectQDictSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ifelse/DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ifelse/DIfElseSsm.hpp new file mode 100644 index 00000000..3b63cdb7 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ifelse/DIfElseSsm.hpp @@ -0,0 +1,208 @@ +/** @file DIfElseSsm.hpp + * + * @author Roland Conybeare, Jul 2025 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include +#include "syntaxstatetype.hpp" +#include +#include +#include + +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 DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + 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); + + /** 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 + * (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 **/ + ///@{ + + static const char * ssm_classname() { return "DIfElseSsm"; } + + DSyntaxStateMachine * super() { return this; } + + /** 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 an expression @p expr, + * followed by semicolon, + * with overall parser state in @p p_psm. + **/ + void on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-ifelsessm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + +#ifdef NOT_YET + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; +#endif + + /** @defgroup scm-ifelsessm-gc-support gc support methods **/ + ///@{ + + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + 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: + /** @defgroup scm-expectlisttypessm-instance-vars instance variables **/ + ///@{ + + 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_; + + ///@} + + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DIfElseSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ifelse/IPrintable_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ifelse/IPrintable_DIfElseSsm.hpp new file mode 100644 index 00000000..39f009ef --- /dev/null +++ b/xo-reader2/include/xo/reader2/ifelse/IPrintable_DIfElseSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DIfElseSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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/ifelse/ISyntaxStateMachine_DIfElseSsm.hpp b/xo-reader2/include/xo/reader2/ifelse/ISyntaxStateMachine_DIfElseSsm.hpp new file mode 100644 index 00000000..a88e9af1 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ifelse/ISyntaxStateMachine_DIfElseSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DIfElseSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 type emitted by nested ssm **/ + static void on_parsed_type(DIfElseSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DIfElseSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DIfElseSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file 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/lambda/DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/lambda/DLambdaSsm.hpp new file mode 100644 index 00000000..93642f5f --- /dev/null +++ b/xo-reader2/include/xo/reader2/lambda/DLambdaSsm.hpp @@ -0,0 +1,223 @@ +/** @file DLambdaSsm.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "DSyntaxStateMachine.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 DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using DLocalSymtab = xo::scm::DLocalSymtab; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + 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 const char * ssm_classname() { return "DLambdaSsm"; } + + 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); + + /** 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); + + /** 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 **/ + ///@{ + + /** 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); + +#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. + **/ + 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. + **/ + void on_parsed_formal_arglist(DArray * arglist, + 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_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + virtual const char * get_expect_str() const 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; + + ///@} + /** @defgroup scm-lambdassm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit gc-aware child pointers **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + + private: + /** parsing state-machine state **/ + lambdastatetype lmstate_ = lambdastatetype::lm_0; + + /** 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; + + /** body expression **/ + obj body_; + + /** parent environment **/ + obj parent_symtab_; + + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLambdaSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/lambda/IPrintable_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/lambda/IPrintable_DLambdaSsm.hpp new file mode 100644 index 00000000..9385be7c --- /dev/null +++ b/xo-reader2/include/xo/reader2/lambda/IPrintable_DLambdaSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DLambdaSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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/lambda/ISyntaxStateMachine_DLambdaSsm.hpp b/xo-reader2/include/xo/reader2/lambda/ISyntaxStateMachine_DLambdaSsm.hpp new file mode 100644 index 00000000..baeb5af4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/lambda/ISyntaxStateMachine_DLambdaSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DLambdaSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 type emitted by nested ssm **/ + static void on_parsed_type(DLambdaSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DLambdaSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DLambdaSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/paren/DParenSsm.hpp b/xo-reader2/include/xo/reader2/paren/DParenSsm.hpp new file mode 100644 index 00000000..9da3ba42 --- /dev/null +++ b/xo-reader2/include/xo/reader2/paren/DParenSsm.hpp @@ -0,0 +1,160 @@ +/** @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 AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + 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); + + /** 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); + + ///@} + /** @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); + + /** 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 **/ + ///@{ + + /** 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); + + /** 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); + + /** 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 **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup scm-parenssm-gc-support gc support methods **/ + ///@{ + + /** gc support: visit immediate gc-aware children **/ + void visit_gco_children(VisitReason reason, + obj gc) noexcept; + + ///@} + + 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/paren/IPrintable_DParenSsm.hpp b/xo-reader2/include/xo/reader2/paren/IPrintable_DParenSsm.hpp new file mode 100644 index 00000000..2b4b49c2 --- /dev/null +++ b/xo-reader2/include/xo/reader2/paren/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/paren/ISyntaxStateMachine_DParenSsm.hpp b/xo-reader2/include/xo/reader2/paren/ISyntaxStateMachine_DParenSsm.hpp new file mode 100644 index 00000000..dc1a826d --- /dev/null +++ b/xo-reader2/include/xo/reader2/paren/ISyntaxStateMachine_DParenSsm.hpp @@ -0,0 +1,88 @@ +/** @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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DParenSsm & self, obj type, 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 nested 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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DParenSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DParenSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/parser/DSchematikaParser.hpp b/xo-reader2/include/xo/reader2/parser/DSchematikaParser.hpp new file mode 100644 index 00000000..f699c30b --- /dev/null +++ b/xo-reader2/include/xo/reader2/parser/DSchematikaParser.hpp @@ -0,0 +1,345 @@ +/** @file DSchematikaParser.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "ParserConfig.hpp" +#include "ParserStateMachine.hpp" +#include "ParserResult.hpp" +#include +#include +#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 = + + * | - + * | * + * | / + * | | + * | & + * | ^ + * | == + * | != + * | < + * | <= + * | => + * | > + * + * ---------------------------------------------------------------- + * NOTES: + * - SchematikaParser partially supports the gcobject facet so it can be a collector root node. + * It's not actually moveable (since its ParserStateMachine member isn't moveable), + * Only the forward_children method is load-bearing. + * + **/ + class DSchematikaParser { + public: + using token_type = Token; + using ArenaHashMapConfig = xo::map::ArenaHashMapConfig; + using ArenaConfig = xo::mm::ArenaConfig; + using AGCObject = xo::mm::AGCObject; + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + using VisitReason = xo::mm::VisitReason; + using AAllocator = xo::mm::AAllocator; + using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::size_t; + + public: + /** create parser in initial state; + * parser is ready to receive tokens via @ref include_token + * + * @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 + **/ + DSchematikaParser(const ParserConfig & config, + obj expr_alloc, + obj aux_alloc); + + /** non-trivial dtor because of @ref psm_ **/ + ~DSchematikaParser() = default; + + /** create parser in initial state. + * + * @p mm allocate SchematikaParser instance from here. + * (likely the same as aux_alloc) + * @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 + **/ + static DSchematikaParser * _make(obj mm, + const ParserConfig & config, + obj expr_alloc, + obj aux_alloc); + + /** like _make(mm,config,expr_alloc,aux_alloc), + * but as fop + **/ + static obj make(obj mm, + const ParserConfig & config, + obj expr_alloc, + obj aux_alloc); + + /** scm-schematikaparser-access-methods **/ + ///@{ + + DGlobalSymtab * global_symtab() const noexcept; + DGlobalEnv * global_env() const noexcept; + StringTable * stringtable() noexcept { return psm_.stringtable(); } + + 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; + + /** 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; + + ///@} + /** scm-schematikaparser-general-methods **/ + ///@{ + + /** 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_batch_session(); + + /** intern string @p str in global string table + **/ + const DUniqueString * intern_string(std::string_view str); + + /** 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 & 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 + * 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(); + + ///@} + /** @defgroup 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; + + ///@} + /** @defgroup scm-schematikaparser-gcobject-methods **/ + ///@{ + + /** not implemented (SchematikaParser not designed to be copyable) **/ + DSchematikaParser * gco_shallow_move(obj gc) noexcept; + /** forward gc-aware children **/ + void visit_gco_children(VisitReason reason, obj gc) noexcept; + + ///@} + private: + /** @defgroup scm-schematikaparser-member-variables member variables **/ + ///@{ + + /** state machine **/ + ParserStateMachine psm_; + + /** debug flag (also stored in psm_) **/ + bool debug_flag_ = false; + + ///@} + }; /*DSchematikaParser*/ + + inline std::ostream & + operator<< (std::ostream & os, + const DSchematikaParser * 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::DSchematikaParser* p) { + if (p) + return p->pretty(ppii); + else + return ppii.pps()->print_upto("nullptr"); + } + }; + } +} /*namespace xo*/ + +/* end DSchematikaParser.hpp */ diff --git a/xo-reader2/include/xo/reader2/parser/IGCObject_DSchematikaParser.hpp b/xo-reader2/include/xo/reader2/parser/IGCObject_DSchematikaParser.hpp new file mode 100644 index 00000000..0143ba76 --- /dev/null +++ b/xo-reader2/include/xo/reader2/parser/IGCObject_DSchematikaParser.hpp @@ -0,0 +1,69 @@ +/** @file IGCObject_DSchematikaParser.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DSchematikaParser.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DSchematikaParser.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DSchematikaParser.hpp" + +namespace xo { namespace scm { class IGCObject_DSchematikaParser; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DSchematikaParser + **/ + class IGCObject_DSchematikaParser { + public: + /** @defgroup scm-gcobject-dschematikaparser-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using AGCObjectVisitor = xo::mm::AGCObject::AGCObjectVisitor; + using VisitReason = xo::mm::AGCObject::VisitReason; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dschematikaparser-methods **/ + ///@{ + // const methods + + // non-const methods + /** move instance using object visitor. +Arguably abusing the word 'visitor' here **/ + static Opaque gco_shallow_move(DSchematikaParser & self, obj gc) noexcept; + /** Invoke fn.visit_child(iface,data) for each child GCObject pointer. +Context: provides address of data pointer so it can be updated in place +when @p fn invokes garbage collector reentry point **/ + static void visit_gco_children(DSchematikaParser & self, VisitReason reason, obj fn) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/quote/IPrintable_DQuoteSsm.hpp b/xo-reader2/include/xo/reader2/quote/IPrintable_DQuoteSsm.hpp new file mode 100644 index 00000000..2b969c50 --- /dev/null +++ b/xo-reader2/include/xo/reader2/quote/IPrintable_DQuoteSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DQuoteSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DQuoteSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DQuoteSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DQuoteSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DQuoteSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DQuoteSsm + **/ + class IPrintable_DQuoteSsm { + public: + /** @defgroup scm-printable-dquotessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dquotessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DQuoteSsm & 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/quote/ISyntaxStateMachine_DQuoteSsm.hpp b/xo-reader2/include/xo/reader2/quote/ISyntaxStateMachine_DQuoteSsm.hpp new file mode 100644 index 00000000..0f01d967 --- /dev/null +++ b/xo-reader2/include/xo/reader2/quote/ISyntaxStateMachine_DQuoteSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DQuoteSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DQuoteSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DQuoteSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DQuoteSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DQuoteSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DQuoteSsm + **/ + class ISyntaxStateMachine_DQuoteSsm { + public: + /** @defgroup scm-syntaxstatemachine-dquotessm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dquotessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DQuoteSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DQuoteSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DQuoteSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DQuoteSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DQuoteSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DQuoteSsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DQuoteSsm & 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(DQuoteSsm & 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(DQuoteSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DQuoteSsm & 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(DQuoteSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DQuoteSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DQuoteSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ 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..fc71175b --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -0,0 +1,116 @@ +/** @file ASyntaxStateMachine.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 +#include +#include +#include + +// {pretext} 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 *; + /** reflected c++ type **/ + using TypeDescr = xo::reflect::TypeDescr; + /** gc visitor interface **/ + using AGCObjectVisitor = xo::mm::AGCObjectVisitor; + /** gc-aware object **/ + using AGCObject = xo::mm::AGCObject; + /** hint when traversing gco graph **/ + using VisitReason = xo::mm::VisitReason; + ///@} + + /** @defgroup scm-syntaxstatemachine-methods **/ + ///@{ + // const methods + /** An uninitialized ASyntaxStateMachine instance will have zero vtable pointer (per {linux,osx} abi). + * Use case for this is narrow. We go to some lengths to avoid null vtable pointers. For example + * obj will have non-null vtable (via IFacet_Any) with all methods terminating. + **/ + bool _has_null_vptr() const noexcept { return *reinterpret_cast(this) == nullptr; } + /** 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 **/ + virtual std::string_view get_expect_str(Copaque data) const noexcept = 0; + + // nonconst methods + /** 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 **/ + virtual void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) = 0; + /** update state machine for type emitted by nested ssm **/ + virtual void on_parsed_type(Opaque data, obj type, 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 nested parsed expression @p expr **/ + virtual void on_parsed_expression(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; + /** update state machine for nested quoted literal @p lit **/ + virtual void on_quoted_literal(Opaque data, obj lit, ParserStateMachine * p_psm) = 0; + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + virtual void visit_gco_children(Opaque data, VisitReason reason, obj gc) = 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 */ 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..c61011ed --- /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: + * [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/IPrintable_DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..0e7802ca --- /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: + * [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/IPrintable_DExpectQArraySsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectQArraySsm.hpp new file mode 100644 index 00000000..8c9b2c4a --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectQArraySsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectQArraySsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQArraySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQArraySsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectQArraySsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectQArraySsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectQArraySsm + **/ + class IPrintable_DExpectQArraySsm { + public: + /** @defgroup scm-printable-dexpectqarrayssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectqarrayssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectQArraySsm & 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/IPrintable_DExpectQListSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectQListSsm.hpp new file mode 100644 index 00000000..45d72c07 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectQListSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectQListSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQListSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQListSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectQListSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectQListSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectQListSsm + **/ + class IPrintable_DExpectQListSsm { + public: + /** @defgroup scm-printable-dexpectqlistssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectqlistssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectQListSsm & 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/IPrintable_DExpectQLiteralSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectQLiteralSsm.hpp new file mode 100644 index 00000000..ec20bbc4 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectQLiteralSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectQLiteralSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQLiteralSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQLiteralSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectQLiteralSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectQLiteralSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectQLiteralSsm + **/ + class IPrintable_DExpectQLiteralSsm { + public: + /** @defgroup scm-printable-dexpectqliteralssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectqliteralssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectQLiteralSsm & 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/IPrintable_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectSymbolSsm.hpp new file mode 100644 index 00000000..45d90eeb --- /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: + * [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/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DExpectTypeSsm.hpp new file mode 100644 index 00000000..d0fa9c34 --- /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: + * [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/IPrintable_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DProgressSsm.hpp new file mode 100644 index 00000000..85779cb6 --- /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: + * [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/IPrintable_DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DSequenceSsm.hpp new file mode 100644 index 00000000..e5555c7f --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DSequenceSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DSequenceSsm.hpp + * + * 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_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DSequenceSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#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/IPrintable_DToplevelSeqSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp new file mode 100644 index 00000000..b219b589 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DToplevelSeqSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DToplevelSeqSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --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_DToplevelSeqSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DToplevelSeqSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DToplevelSeqSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DToplevelSeqSsm + **/ + class IPrintable_DToplevelSeqSsm { + public: + /** @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-dtoplevelseqssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DToplevelSeqSsm & 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 new file mode 100644 index 00000000..88b0cde2 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -0,0 +1,104 @@ +/** @file ISyntaxStateMachine_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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; + using TypeDescr = ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = ASyntaxStateMachine::AGCObject; + using VisitReason = ASyntaxStateMachine::VisitReason; + + ///@} + /** @defgroup scm-syntaxstatemachine-any-methods **/ + ///@{ + + const ASyntaxStateMachine * iface() const { return std::launder(this); } + + // from ASyntaxStateMachine + + // 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(); } + + // nonconst methods + [[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_type(Opaque, obj, 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; + [[noreturn]] void on_quoted_literal(Opaque, obj, ParserStateMachine *) override; + [[noreturn]] void visit_gco_children(Opaque, VisitReason, obj) 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 */ 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..63210b94 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectExprSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 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 **/ + static void on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DExpectExprSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectExprSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectExprSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*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..8b9d4083 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectFormalArglistSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 type emitted by nested ssm **/ + static void on_parsed_type(DExpectFormalArglistSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectFormalArglistSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectFormalArglistSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp new file mode 100644 index 00000000..e4b15c21 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectQArraySsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQArraySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQArraySsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectQArraySsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectQArraySsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectQArraySsm + **/ + class ISyntaxStateMachine_DExpectQArraySsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectqarrayssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectqarrayssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectQArraySsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectQArraySsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectQArraySsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectQArraySsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectQArraySsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DExpectQArraySsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectQArraySsm & 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(DExpectQArraySsm & 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(DExpectQArraySsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DExpectQArraySsm & 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(DExpectQArraySsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectQArraySsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectQArraySsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQListSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQListSsm.hpp new file mode 100644 index 00000000..42fdc804 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQListSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectQListSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQListSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQListSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectQListSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectQListSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectQListSsm + **/ + class ISyntaxStateMachine_DExpectQListSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectqlistssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectqlistssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectQListSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectQListSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectQListSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectQListSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectQListSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DExpectQListSsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectQListSsm & 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(DExpectQListSsm & 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(DExpectQListSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DExpectQListSsm & 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(DExpectQListSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectQListSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectQListSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQLiteralSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQLiteralSsm.hpp new file mode 100644 index 00000000..5dc2130b --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQLiteralSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectQLiteralSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQLiteralSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQLiteralSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectQLiteralSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectQLiteralSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectQLiteralSsm + **/ + class ISyntaxStateMachine_DExpectQLiteralSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectqliteralssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectqliteralssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectQLiteralSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectQLiteralSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectQLiteralSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectQLiteralSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectQLiteralSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DExpectQLiteralSsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectQLiteralSsm & 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(DExpectQLiteralSsm & 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(DExpectQLiteralSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DExpectQLiteralSsm & 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(DExpectQLiteralSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectQLiteralSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectQLiteralSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file 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..dfc0d6bb --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectSymbolSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 + /** 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 **/ + static void on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DExpectSymbolSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectSymbolSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectSymbolSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*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..b8607deb --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DExpectTypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 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 **/ + static void on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DExpectTypeSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectTypeSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DExpectTypeSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file 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..3a2b3aaf --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DProgressSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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 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 **/ + static void on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DProgressSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DProgressSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DProgressSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of 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..74183d99 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DSequenceSsm.hpp @@ -0,0 +1,88 @@ +/** @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 AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + 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); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DSequenceSsm & self, obj type, 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 nested parsed expression @p expr **/ + static void on_parsed_expression(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); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DSequenceSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DSequenceSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp new file mode 100644 index 00000000..55da530d --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp @@ -0,0 +1,88 @@ +/** @file ISyntaxStateMachine_DToplevelSeqSsm.hpp + * + * 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_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DToplevelSeqSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DToplevelSeqSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DToplevelSeqSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DToplevelSeqSsm + **/ + class ISyntaxStateMachine_DToplevelSeqSsm { + public: + /** @defgroup scm-syntaxstatemachine-dtoplevelseqssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = xo::scm::ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using VisitReason = xo::scm::ASyntaxStateMachine::VisitReason; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dtoplevelseqssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + 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 DToplevelSeqSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + 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(DToplevelSeqSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DToplevelSeqSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DToplevelSeqSsm & self, obj type, 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 nested parsed expression @p expr **/ + 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(DToplevelSeqSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DToplevelSeqSsm & self, obj lit, ParserStateMachine * p_psm); + /** gc support: visit immediate gc-aware child pointers with @p gc. Call gc.visit_child() for each **/ + static void visit_gco_children(DToplevelSeqSsm & self, VisitReason reason, obj gc); + ///@} + }; + + } /*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..e0c3bee5 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -0,0 +1,136 @@ +/** @file ISyntaxStateMachine_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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] + * + * variables: + * {facet_hpp_fname} -> SyntaxStateMachine.hpp + * {impl_hpp_subdir} -> ssm + * {facet_ns1} -> xo + * {facet_detail_subdir} -> ssm + * {abstract_facet_fname} -> ASyntaxStateMachine.hpp + **/ + +#pragma once + +#include "ASyntaxStateMachine.hpp" +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include +#include +#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; + using TypeDescr = ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = ASyntaxStateMachine::AGCObject; + using VisitReason = ASyntaxStateMachine::VisitReason; + ///@} + + /** @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 + + // 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)); + } + std::string_view get_expect_str(Copaque data) const noexcept override { + return I::get_expect_str(_dcast(data)); + } + + // non-const methods + 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); + } + 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_type(Opaque data, obj type, ParserStateMachine * p_psm) override { + return I::on_parsed_type(_dcast(data), type, 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_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); + } + 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_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); + } + void on_quoted_literal(Opaque data, obj lit, ParserStateMachine * p_psm) override { + return I::on_quoted_literal(_dcast(data), lit, p_psm); + } + void visit_gco_children(Opaque data, VisitReason reason, obj gc) override { + return I::visit_gco_children(_dcast(data), reason, gc); + } + + ///@} + + 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 */ 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..2f5b9fb0 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -0,0 +1,124 @@ +/** @file RSyntaxStateMachine.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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; + using TypeDescr = ASyntaxStateMachine::TypeDescr; + using AGCObjectVisitor = ASyntaxStateMachine::AGCObjectVisitor; + using AGCObject = ASyntaxStateMachine::AGCObject; + using VisitReason = ASyntaxStateMachine::VisitReason; + ///@} + + /** @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 **/ + ///@{ + + // 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()); + } + 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_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); + } + void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_typedescr(O::data(), td, p_psm); + } + void on_parsed_type(obj type, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_type(O::data(), type, 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_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); + } + 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_token(obj expr, const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_expression_with_token(O::data(), expr, tk, p_psm); + } + void on_quoted_literal(obj lit, ParserStateMachine * p_psm) { + return O::iface()->on_quoted_literal(O::data(), lit, p_psm); + } + void visit_gco_children(VisitReason reason, obj gc) { + return O::iface()->visit_gco_children(O::data(), reason, gc); + } + + ///@} + /** @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 */ diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp new file mode 100644 index 00000000..c1dbfae6 --- /dev/null +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -0,0 +1,95 @@ +/** @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, + + /** handle define-expression. See @ref DDefineSsm **/ + defexpr, + + /** handle deftype-expression. See @ref DDeftypeSsm **/ + deftypeexpr, + + /** handle lambda-expression. See @ref DLambdaSsm **/ + lambdaexpr, + + /** handle ifelse-expression. See @ref DIfElseSsm **/ + ifelseexpr, + + /** 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, + + /** expression enclosed in parentheses. See @ref DParenSsm **/ + paren, + + /** quoted literal using #q{..} syntax. See @ref DQuoteSsm **/ + quote, + + /** toplevel of some translation unit. See @ref DToplevelSeqSsm **/ + expect_toplevel_expression_sequence, + + /** 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, + + /** expecting a type. See @ref DExpectTypeSsm **/ + expect_type, + + /** expecting a list type. See @ref DExpectListTypeSsm **/ + expect_listtype, + + /** expecting a rhs expression. See @ref DExpectExprSsm **/ + expect_rhs_expression, + + /** expecting a quoted literal. See @ref DExpectQLiteralSsm **/ + expect_qliteral, + + /** expecting a quoted list. See @ref DExpectQListSsm **/ + expect_qlist, + + /** expecting a quoted array. See @ref DExpectQArraySsm **/ + expect_qarray, + + /** expecting a quoted dictionary. See @ref DExpectQDictSsm **/ + expect_qdict, + + /** comes last, 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..55aba46f --- /dev/null +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -0,0 +1,115 @@ +# reader2/CMakeLists.txt + +set(SELF_LIB xo_reader2) +set(SELF_SRCS + init_reader2.cpp + SetupReader2.cpp + + SchematikaReader.cpp + ReaderConfig.cpp + + DSchematikaParser.cpp + facet/IGCObject_DSchematikaParser.cpp + + ParserStateMachine.cpp + ParserStack.cpp + ParserResult.cpp + + DGlobalEnv.cpp + facet/IGCObject_DGlobalEnv.cpp + facet/IPrintable_DGlobalEnv.cpp + + syntaxstatetype.cpp + ISyntaxStateMachine_Any.cpp + + DToplevelSeqSsm.cpp + ISyntaxStateMachine_DToplevelSeqSsm.cpp + IPrintable_DToplevelSeqSsm.cpp + + DDefineSsm.cpp + facet/ISyntaxStateMachine_DDefineSsm.cpp + facet/IPrintable_DDefineSsm.cpp + + DDeftypeSsm.cpp + facet/ISyntaxStateMachine_DDeftypeSsm.cpp + facet/IPrintable_DDeftypeSsm.cpp + + DIfElseSsm.cpp + facet/ISyntaxStateMachine_DIfElseSsm.cpp + facet/IPrintable_DIfElseSsm.cpp + + DSequenceSsm.cpp + ISyntaxStateMachine_DSequenceSsm.cpp + IPrintable_DSequenceSsm.cpp + + DLambdaSsm.cpp + facet/ISyntaxStateMachine_DLambdaSsm.cpp + facet/IPrintable_DLambdaSsm.cpp + + DApplySsm.cpp + facet/ISyntaxStateMachine_DApplySsm.cpp + facet/IPrintable_DApplySsm.cpp + + DParenSsm.cpp + ISyntaxStateMachine_DParenSsm.cpp + IPrintable_DParenSsm.cpp + + DExpectFormalArglistSsm.cpp + ISyntaxStateMachine_DExpectFormalArglistSsm.cpp + IPrintable_DExpectFormalArglistSsm.cpp + + DExpectFormalArgSsm.cpp + facet/ISyntaxStateMachine_DExpectFormalArgSsm.cpp + facet/IPrintable_DExpectFormalArgSsm.cpp + + DExpectSymbolSsm.cpp + ISyntaxStateMachine_DExpectSymbolSsm.cpp + IPrintable_DExpectSymbolSsm.cpp + + DExpectTypeSsm.cpp + ISyntaxStateMachine_DExpectTypeSsm.cpp + IPrintable_DExpectTypeSsm.cpp + + DExpectListTypeSsm.cpp + facet/ISyntaxStateMachine_DExpectListTypeSsm.cpp + facet/IPrintable_DExpectListTypeSsm.cpp + + DExpectExprSsm.cpp + ISyntaxStateMachine_DExpectExprSsm.cpp + IPrintable_DExpectExprSsm.cpp + + DExpectQLiteralSsm.cpp + ISyntaxStateMachine_DExpectQLiteralSsm.cpp + IPrintable_DExpectQLiteralSsm.cpp + + DExpectQListSsm.cpp + ISyntaxStateMachine_DExpectQListSsm.cpp + IPrintable_DExpectQListSsm.cpp + + DExpectQArraySsm.cpp + ISyntaxStateMachine_DExpectQArraySsm.cpp + IPrintable_DExpectQArraySsm.cpp + + DExpectQDictSsm.cpp + facet/ISyntaxStateMachine_DExpectQDictSsm.cpp + facet/IPrintable_DExpectQDictSsm.cpp + + DProgressSsm.cpp + ISyntaxStateMachine_DProgressSsm.cpp + IPrintable_DProgressSsm.cpp + + DQuoteSsm.cpp + facet/ISyntaxStateMachine_DQuoteSsm.cpp + facet/IPrintable_DQuoteSsm.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_numeric) +xo_dependency(${SELF_LIB} xo_procedure2) +xo_dependency(${SELF_LIB} xo_gc) +xo_dependency(${SELF_LIB} xo_type) +xo_dependency(${SELF_LIB} xo_tokenizer2) +xo_dependency(${SELF_LIB} xo_expression2) +xo_dependency(${SELF_LIB} subsys) diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp new file mode 100644 index 00000000..0a616e9a --- /dev/null +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -0,0 +1,412 @@ +/** @file DApplySsm.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "ApplySsm.hpp" +#include "ExpectExprSsm.hpp" +#include +#include +#include +#include +#include + +//#include "parserstatemachine.hpp" +//#include "expect_expr_xs.hpp" + +namespace xo { + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::print::APrintable; + 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(applyexprstatetype applystate, + obj fn_expr, + DArray * args) + : applystate_{applystate}, + fn_expr_{fn_expr}, + args_expr_v_{args} + { + if (fn_expr) { + this->applystate_ = applyexprstatetype::apply_1; + } + + assert(args->is_empty()); + } + + DApplySsm * + DApplySsm::_make(DArena & arena, + obj fn_expr) + { + obj mm(&arena); + + void * mem = arena.alloc(typeseq::id(), + sizeof(DApplySsm)); + + /* 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); + + 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); + } + + obj + DApplySsm::make(DArena & arena, + obj fn_expr) + { + return obj(_make(arena, fn_expr)); + } + + void + DApplySsm::start(obj fn_expr, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + auto ssm = DApplySsm::make(p_psm->parser_alloc(), fn_expr); + + p_psm->push_ssm(ckp, ssm); + } + + 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|rparen"; + case applyexprstatetype::apply_3: return "comma|rparen"; + case applyexprstatetype::N: break; + } + + 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_rightparen: + this->on_rightparen_token(tk, p_psm); + return; + case tokentype::tk_symbol: + case tokentype::tk_def: + case tokentype::tk_deftype: + 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_quote: + 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_cmple: + case tokentype::tk_cmpge: + 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_nil: + 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(false /*!allow_defs*/, + false /*!cxl_on_rightbrace*/, + true /*cxl_on_rightparen*/, + p_psm); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DApplySsm::on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (applystate_ == applyexprstatetype::apply_2) { + obj apply = this->assemble_expr(p_psm->expr_alloc()); + + p_psm->pop_ssm(); + p_psm->on_parsed_expression(apply); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DApplySsm::on_parsed_expression_with_token(obj expr, + 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. + + DArray * argv_2x = DArray::_empty(mm, 2 * args_expr_v_->capacity()); + + for (DArray::size_type i = 0, n = args_expr_v_->size(); i < n; ++i) { + argv_2x->push_back(mm, (*args_expr_v_)[i]); + } + + this->args_expr_v_ = argv_2x; + } + + if (args_expr_v_->size() < args_expr_v_->capacity()) + args_expr_v_->push_back(mm, expr_gco); + + if (tk.tk_type() == tokentype::tk_rightparen) { + obj apply_ex = this->assemble_expr(p_psm->expr_alloc()); + + 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_ + + DExpectExprSsm::start(p_psm); + return; + } + } + + Super::on_parsed_expression_with_token(expr, tk, p_psm); + } + + obj + DApplySsm::assemble_expr(obj mm) + { + // begin assemble_expr().. + + std::uint32_t n_args = args_expr_v_->size(); + + 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); + + return apply_ex; + } + +#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_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); + } +#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)); + } + + void + DApplySsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_poly_child(reason, &fn_expr_); + gc.visit_child(reason, &args_expr_v_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DApplySsm.cpp */ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp new file mode 100644 index 00000000..59388820 --- /dev/null +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -0,0 +1,703 @@ + /** @file DDefineSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DDefineSsm.hpp" +#include "DExpectSymbolSsm.hpp" +#include "DExpectTypeSsm.hpp" +#include "DExpectExprSsm.hpp" +#include "DefineSsm.hpp" +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + using xo::facet::typeseq; + + 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 ----- + + // DDefineSsm::make + + // DDefineSsm::start + +#ifdef NOT_YET + 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 + + //////////////////////////////////////////////////////////////// + + DDefineSsm::DDefineSsm(DDefineExpr * def_expr) + : defstate_{defexprstatetype::def_0}, + def_expr_{def_expr} + {} + + DDefineSsm * + DDefineSsm::_make(DArena & mm, + DDefineExpr * def_expr) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DDefineSsm)); + + 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, + ParserStateMachine * p_psm) + { + //scope log(XO_DEBUG(p_psm->debug_flag())); + + assert(p_psm->stack()); + + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + DDefineExpr * def_expr = DDefineExpr::make_empty(expr_mm); + + auto define_ssm = DDefineSsm::make(mm, def_expr); + + p_psm->push_ssm(ckp, define_ssm); + + // note: triggers poly dispatch + p_psm->on_token(Token::def_token()); + } + + 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 "impossible!?"; + 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_parsed_symbol(std::string_view sym_name, + ParserStateMachine * p_psm) + { + if (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), + // 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_name, + this->get_expect_str()); + } + + void + DDefineSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), 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_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); + return; + + case tokentype::tk_def: + this->on_def_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_semicolon: + this->on_semicolon_token(tk, p_psm); + return; + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_deftype: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_if: + case tokentype::tk_quote: + 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_cmple: + case tokentype::tk_cmpge: + 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_nil: + 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 + 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 + + Super::on_token(tk, p_psm); + } + + void + DDefineSsm::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (defstate_ == defexprstatetype::def_0) { + this->defstate_ = defexprstatetype::def_1; + + DExpectSymbolSsm::start(p_psm); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DDefineSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (defstate_ == defexprstatetype::def_2) { + this->defstate_ = defexprstatetype::def_3; + + DExpectTypeSsm::start(false /*!corrected*/, p_psm); + + return; + } + + Super::on_token(tk, p_psm); + } + + void + DDefineSsm::on_singleassign_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("defstate", defstate_)); + + if ((defstate_ == defexprstatetype::def_2) + || (defstate_ == defexprstatetype::def_4)) + { + this->defstate_ = defexprstatetype::def_5; + + DExpectExprSsm::start(p_psm); + return; + } + + Super::on_token(tk, p_psm); + } + + void + 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_token(def_expr_, tk); + return; + } + + Super::on_token(tk, p_psm); + } + + void + 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; + } + + Super::on_parsed_expression(expr, p_psm); + } + + void + DDefineSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * 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); + } + + // ----- printable facet ----- + + bool + DDefineSsm::pretty(const ppindentinfo & ppii) const + { + auto expr + = FacetRegistry::instance().variant(def_expr_); + assert(expr.data()); + + return ppii.pps()->pretty_struct(ppii, + "DDefineSsm", + refrtag("defstate", defstate_), + refrtag("expect", this->get_expect_str()), + refrtag("def_expr", expr)); + } + + // ----- gc support ----- + + void + DDefineSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_child(reason, &def_expr_.data_); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineSsm.cpp */ diff --git a/xo-reader2/src/reader2/DDeftypeSsm.cpp b/xo-reader2/src/reader2/DDeftypeSsm.cpp new file mode 100644 index 00000000..108f6be7 --- /dev/null +++ b/xo-reader2/src/reader2/DDeftypeSsm.cpp @@ -0,0 +1,282 @@ +/** @file DDeftypeSsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "DeftypeSsm.hpp" +#include "syntaxstatetype.hpp" +#include "ExpectSymbolSsm.hpp" +#include "ExpectTypeSsm.hpp" +#include "Constant.hpp" +#include +#include + +namespace xo { + namespace scm { + + extern const char * + DeftypeXst::_descr(enum DeftypeXst::code x) + { + switch (x) { + case code::invalid: return "invalid"; + case code::def_0: return "def_0"; + case code::def_1: return "def_1"; + case code::def_2: return "def_2"; + case code::def_3: return "def_3"; + case code::def_4: return "def_4"; + case code::N: break; + } + + return "?DeftypeXst"; + } + + std::ostream & + operator<<(std::ostream & os, DeftypeXst x) + { + os << DeftypeXst::_descr(x.code()); + return os; + } + + DDeftypeSsm::DDeftypeSsm() + : deftype_xst_{DeftypeXst::code::def_0} + {} + + DDeftypeSsm * + DDeftypeSsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc_for(); + + return new (mem) DDeftypeSsm(); + } + + obj + DDeftypeSsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + void + DDeftypeSsm::start(DArena & mm, + ParserStateMachine * p_psm) + { + assert(p_psm->stack()); + + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + auto deftype_ssm = DDeftypeSsm::make(mm); + + p_psm->push_ssm(ckp, deftype_ssm); + } + + syntaxstatetype + DDeftypeSsm::ssm_type() const noexcept + { + return syntaxstatetype::deftypeexpr; + } + + std::string_view + DDeftypeSsm::get_expect_str() const noexcept + { + switch (this->deftype_xst_.code()) { + case DeftypeXst::code::invalid: + break; + case DeftypeXst::code::def_0: + return "deftype"; + case DeftypeXst::code::def_1: + return "symbol"; + case DeftypeXst::code::def_2: + return "doublecolon"; + case DeftypeXst::code::def_3: + return "type"; + case DeftypeXst::code::def_4: + return "semicolon"; + case DeftypeXst::code::N: + break; + + } + + return "?expect"; + } + + void + DDeftypeSsm::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_deftype: + this->on_deftype_token(tk, p_psm); + return; + + case tokentype::tk_doublecolon: + this->on_doublecolon_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_symbol: + case tokentype::tk_def: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + 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_quote: + 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_cmple: + case tokentype::tk_cmpge: + case tokentype::tk_dot: + case tokentype::tk_comma: + 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_nil: + 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::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_deftype_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_0) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_1); + + DExpectSymbolSsm::start(p_psm); + + /* continue in .on_parsed_symbol() */ + + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_parsed_symbol(std::string_view sym_name, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_1) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_2); + this->lhs_symbol_ = p_psm->intern_string(sym_name); + + return; + } + + Super::illegal_parsed_symbol(sym_name, p_psm); + } + + void + DDeftypeSsm::on_doublecolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_2) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_3); + + DExpectTypeSsm::start(true /*corrected*/, p_psm); + + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_parsed_type(obj type, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_3) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_4); + + DLocalSymtab * local = p_psm->local_symtab(); + + if (local) { + local->append_type(p_psm->expr_alloc(), + lhs_symbol_, + type); + } else { + DGlobalSymtab * global = p_psm->global_symtab(); + + DTypename * tname = DTypename::_make(p_psm->expr_alloc(), + lhs_symbol_, + type); + + global->upsert_typename(p_psm->expr_alloc(), tname); + } + + return; + } + + Super::illegal_type(type, p_psm); + } + + void + DDeftypeSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_4) { + p_psm->pop_ssm(); + + // Reporting a placeholder expression to preserve policy + // that 'every toplevel statement produces an expression' + // + auto result_expr + = DConstant::make(p_psm->expr_alloc(), + DBoolean::box(p_psm->expr_alloc(), + true)); + p_psm->on_parsed_expression(result_expr); + + return; + } + + Super::illegal_token(tk, p_psm); + } + + bool + DDeftypeSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DDeftypeSsm", + refrtag("deftypestate", deftype_xst_), + refrtag("expect", this->get_expect_str())); + } + void + DDeftypeSsm::visit_gco_children(VisitReason, obj) noexcept + { + static_assert(!DUniqueString::is_gc_eligible()); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDeftypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp new file mode 100644 index 00000000..9526aaea --- /dev/null +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -0,0 +1,637 @@ +/** @file DExpectExprSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ExpectExprSsm.hpp" +#include "ParserStateMachine.hpp" +#include "ParserStack.hpp" +#include "SyntaxStateMachine.hpp" +#include "ProgressSsm.hpp" +#include "DSequenceSsm.hpp" +#include "IfElseSsm.hpp" +#include "LambdaSsm.hpp" +#include "QuoteSsm.hpp" +#include "syntaxstatetype.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef NOT_YET +#include "define_xs.hpp" +#include "paren_xs.hpp" +#endif + +namespace xo { + using xo::scm::DFloat; + using xo::mm::AGCObject; + + using xo::reflect::typeseq; + using xo::facet::with_facet; + + namespace scm { + + DExpectExprSsm::DExpectExprSsm(bool allow_defs, + bool cxl_on_rightbrace, + bool cxl_on_rightparen) + : allow_defs_{allow_defs}, + cxl_on_rightbrace_{cxl_on_rightbrace}, + cxl_on_rightparen_{cxl_on_rightparen} + { + } + + DExpectExprSsm * + DExpectExprSsm::_make(DArena & mm, + bool allow_defs, + bool cxl_on_rightbrace, + bool cxl_on_rightparen) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DExpectExprSsm)); + + return new (mem) DExpectExprSsm(allow_defs, + cxl_on_rightbrace, + cxl_on_rightparen); + } + + obj + DExpectExprSsm::make(DArena & mm, + bool allow_defs, + bool cxl_on_rightbrace, + bool cxl_on_rightparen) + { + return obj(_make(mm, allow_defs, cxl_on_rightbrace, cxl_on_rightparen)); + } + + void + DExpectExprSsm::start(bool allow_defs, + bool cxl_on_rightbrace, + bool cxl_on_rightparen, + ParserStateMachine * p_psm) + { + auto & mm = p_psm->parser_alloc(); + + DArena::Checkpoint ckp = mm.checkpoint(); + + auto ssm = DExpectExprSsm::make(mm, allow_defs, cxl_on_rightbrace, cxl_on_rightparen); + + p_psm->push_ssm(ckp, ssm); + } + + void + DExpectExprSsm::start(ParserStateMachine * p_psm) + { + start(false /*!allow_defs*/, + false /*!cxl_on_rightbrace*/, + false /*cxl_on_rightparen*/, + p_psm); + } + + syntaxstatetype + DExpectExprSsm::ssm_type() const noexcept + { + return syntaxstatetype::expect_rhs_expression; + } + + std::string_view + DExpectExprSsm::get_expect_str() const noexcept + { + if (allow_defs_) { + return "def|if|lambda|lparen|lbrace|literal|var"; + } else { + return "if|lambda|lparen|lbrace|literal|var"; + } + } + + 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_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + + case tokentype::tk_rightparen: + this->on_rightparen_token(tk, p_psm); + return; + + case tokentype::tk_leftbrace: + this->on_leftbrace_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_quote: + this->on_quote_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_nil: + this->on_nil_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_deftype: + case tokentype::tk_singleassign: + case tokentype::tk_colon: + case tokentype::tk_semicolon: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_cmple: + case tokentype::tk_cmpge: + 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; + } + + 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_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (cxl_on_rightparen_) { + /* abandon expression, delegate rightparen to parent */ + + p_psm->pop_ssm(); + p_psm->on_token(tk); + return; + } + + 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) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("tk", tk)); + + DVarRef * var = p_psm->lookup_varref(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(var), + p_psm); + } + +#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) + { + Super::on_token(tk, p_psm); + } + + void + DExpectExprSsm::on_quote_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DProgressSsm::start(p_psm->parser_alloc(), p_psm); + DQuoteSsm::start(p_psm); + p_psm->on_token(Token::quote_token()); + } + + void + DExpectExprSsm::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) + { + 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 + DExpectExprSsm::on_nil_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + auto nil = DList::nil(); + auto expr = DConstant::make(p_psm->expr_alloc(), nil); + + // DProgressSsm responsible for resolving cases like + // nil ++ nil; + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + } + + void + DExpectExprSsm::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + auto f64o = DFloat::box(p_psm->expr_alloc(), + tk.f64_value()); + + auto expr = 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_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + auto i64o = DInteger::box(p_psm->expr_alloc(), + tk.i64_value()); + + auto expr = DConstant::make(p_psm->expr_alloc(), i64o); + + // Consider parser stack, with control here at b + // + // a * b - c + // ^ + // + // [1] ExpectExpr <-- this + // [0] ProgressSsm :lhs k(b) :op * :rhs _ + // + // if parent is ProgressSsm [0], need to deliver k(b) to it; + // Then let that ProgressSsm [0] establish whether next token + // is operator. + // + assert((void*)p_psm->stack()->top().data() == (void*)this); + + if (p_psm->stack()->parent()) { + auto parent_ssm = (obj::from + (p_psm->stack()->parent()->top())); + + if (parent_ssm) { + // parent is-a DProgressSsm instance + p_psm->pop_ssm(); + p_psm->on_parsed_expression(expr); + return; + } + } + + // 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_string_token(const Token & tk, + ParserStateMachine * p_psm) + { + 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 + 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) + { + (void)tk; + + DLambdaSsm::start(p_psm); + } + + void + DExpectExprSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->pop_ssm(); + p_psm->on_parsed_expression(expr); + } + + void + 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_token(expr, tk); + } + +#ifdef NOT_YET + void + DExpectExprSsm::on_quoted_literal(obj lit, + ParserStateMachine * p_psm) + { + // note: impl here parallels .on_f64_token() .on_i64_token() etc. + + auto expr = DConstant::make(p_psm->expr_alloc(), lit); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + } +#endif + + 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_), + refrtag("cxl_on_rightparen", cxl_on_rightparen_), + refrtag("expect", this->get_expect_str())); + } + +#ifdef NOT_YET + 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_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_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 << ""; + } +#endif + + void + DExpectExprSsm::visit_gco_children(VisitReason, + obj) noexcept + { + // all members POD, skip + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectExprSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp new file mode 100644 index 00000000..f1bdd81d --- /dev/null +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -0,0 +1,278 @@ +/** @file DExpectFormalArgSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ExpectFormalArgSsm.hpp" +#include "ExpectSymbolSsm.hpp" +#include "ExpectTypeSsm.hpp" + +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; + + obj + DExpectFormalArgSsm::make(DArena & mm) + { + return obj(_make(mm)); + } + + DExpectFormalArgSsm * + DExpectFormalArgSsm::_make(DArena & mm) + { + void * mem = mm.alloc(typeseq::id(), sizeof(DExpectFormalArgSsm)); + + return new (mem) DExpectFormalArgSsm(); + } + + void + DExpectFormalArgSsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectFormalArgSsm::make(p_psm->parser_alloc())); + + DExpectSymbolSsm::start(p_psm); + } + + 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()) { + 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: + case tokentype::tk_def: + case tokentype::tk_deftype: + case tokentype::tk_if: + case tokentype::tk_symbol: + 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_quote: + 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_cmple: + case tokentype::tk_cmpge: + 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_nil: + 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; + } + + Super::on_token(tk, p_psm); + } + + void + DExpectFormalArgSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (fstate_ == formalstatetype::formal_1) { + this->fstate_ = formalstatetype::formal_2; + + DExpectTypeSsm::start(false /*!corrected*/, p_psm); + + /* control reenters via DExpectFormalArgSsm::on_parsed_typedescr() */ + return; + } + + 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) + { + 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; + } + + Super::on_parsed_symbol(sym, p_psm); + } + + void + 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; + } + + Super::on_parsed_typedescr(td, p_psm); + } + +#ifdef NOT_YET + 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_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); + } + } +#endif + + bool + DExpectFormalArgSsm::pretty(const ppindentinfo & ppii) const { + if (name_) { + return ppii.pps()->pretty_struct + (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("expect", this->get_expect_str()) + ); + } + } + + void + DExpectFormalArgSsm::visit_gco_children(VisitReason, + obj) noexcept + { + static_assert(!DUniqueString::is_gc_eligible()); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DExpectFormalArgSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..7036ffb5 --- /dev/null +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -0,0 +1,372 @@ +/* @file DExpectFormalArglistSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + */ + +#include "ExpectFormalArglistSsm.hpp" +#include "ExpectFormalArgSsm.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::print::ppstate; + using xo::print::ppindentinfo; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::mm::AAllocator; + using xo::facet::FacetRegistry; + 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) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, 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) + { + switch (tk.tk_type()) { + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + + case tokentype::tk_comma: + 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: + case tokentype::tk_deftype: + 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_quote: + 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_cmple: + case tokentype::tk_cmpge: + case tokentype::tk_dot: + 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_nil: + 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; + } + + 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(mm, argl_->at(i)); + } + + // update in place + this->argl_ = argl_2x; + } + + this->argl_->push_back(expr_alloc, var_o); + } + + void + DExpectFormalArglistSsm::on_parsed_formal(const DUniqueString * param_name, + TypeDescr param_type, + 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); + 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) + { + if (fastate_ == formalarglstatetype::argl_0) { + this->fastate_ = formalarglstatetype::argl_1a; + + DExpectFormalArgSsm::start(p_psm); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DExpectFormalArglistSsm::on_comma_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (fastate_ == formalarglstatetype::argl_1b) { + this->fastate_ = formalarglstatetype::argl_1a; + + DExpectFormalArgSsm::start(p_psm); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DExpectFormalArglistSsm::on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (fastate_ == formalarglstatetype::argl_1b) { + DArray * args = argl_; + + p_psm->pop_ssm(); + p_psm->on_parsed_formal_arglist(args); + return; + } + + Super::on_token(tk, p_psm); + } + + bool + DExpectFormalArglistSsm::pretty(const ppindentinfo & ppii) const + { + ppstate * pps = ppii.pps(); + + if (ppii.upto()) { + if (!pps->print_upto("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", argl_->size()))) + return false; + + for (size_type i_arg = 0; i_arg < argl_->size(); ++i_arg) { + char buf[80]; + snprintf(buf, sizeof(buf), "arg[%u]", 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("expect", this->get_expect_str())); + + pps->newline_indent(ppii.ci1()); + pps->pretty(refrtag("n_args", argl_->size())); + + for (size_type i_arg = 0, n_arg = argl_->size(); i_arg < n_arg; ++i_arg) { + char buf[80]; + snprintf(buf, sizeof(buf), "arg[%u]", 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; + } + } + + void + DExpectFormalArglistSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_child(reason, &argl_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DExpectFormalArglistSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectListTypeSsm.cpp b/xo-reader2/src/reader2/DExpectListTypeSsm.cpp new file mode 100644 index 00000000..e94e299b --- /dev/null +++ b/xo-reader2/src/reader2/DExpectListTypeSsm.cpp @@ -0,0 +1,216 @@ +/** @file DExpectListTypeSsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "ExpectListTypeSsm.hpp" +#include "ExpectTypeSsm.hpp" +#include "syntaxstatetype.hpp" +#include +#include +#include + +namespace xo { + namespace scm { + + const char * + ListTypeXst::_descr(enum code x) + { + switch (x) { + case code::invalid: return "?invalid"; + case code::type_0: return "type_0"; + case code::type_1: return "type_1"; + case code::type_2: return "type_2"; + case code::type_3: return "type_3"; + case code::N: break; + } + + return "?ListTypeXst"; + } + + DExpectListTypeSsm::DExpectListTypeSsm() = default; + + DExpectListTypeSsm * + DExpectListTypeSsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc_for(); + + return new (mem) DExpectListTypeSsm(); + } + + obj + DExpectListTypeSsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + void + DExpectListTypeSsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectListTypeSsm::make(p_psm->parser_alloc())); + } + + syntaxstatetype + DExpectListTypeSsm::ssm_type() const noexcept + { + return syntaxstatetype::expect_listtype; + } + + std::string_view + DExpectListTypeSsm::get_expect_str() const noexcept + { + switch(state_.code()) { + case ListTypeXst::code::invalid: + case ListTypeXst::code::N: + break; + case ListTypeXst::code::type_0: + return "list"; + case ListTypeXst::code::type_1: + return "leftangle"; + case ListTypeXst::code::type_2: + return "type"; + case ListTypeXst::code::type_3: + return "rightangle"; + } + + return "?ExpectListTypeSsm"; + } + + void + DExpectListTypeSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (tk.tk_type()) { + + case tokentype::tk_symbol: + this->on_symbol_token(tk, p_psm); + return; + + case tokentype::tk_leftangle: + this->on_leftangle_token(tk, p_psm); + return; + + case tokentype::tk_rightangle: + this->on_rightangle_token(tk, p_psm); + return; + + // all the {not-yet-handled, illegal} cases + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_quote: + case tokentype::tk_def: + case tokentype::tk_deftype: + 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_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_cmple: + case tokentype::tk_cmpge: + 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_nil: + 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::illegal_token(tk, p_psm); + } + + void + DExpectListTypeSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == ListTypeXst::code::type_0) { + this->state_ = ListTypeXst(ListTypeXst::code::type_1); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectListTypeSsm::on_leftangle_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == ListTypeXst::code::type_1) { + this->state_ = ListTypeXst(ListTypeXst::code::type_2); + DExpectTypeSsm::start(true /*corrected*/, p_psm); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectListTypeSsm::on_parsed_type(obj type, ParserStateMachine * p_psm) + { + if (state_.code() == ListTypeXst::code::type_2) { + this->state_ = ListTypeXst(ListTypeXst::code::type_3); + this->elt_type_ = type; + return; + } + + Super::illegal_type(type, p_psm); + } + + void + DExpectListTypeSsm::on_rightangle_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == ListTypeXst::code::type_3) { + obj result = DListType::make(p_psm->expr_alloc(), + elt_type_); + p_psm->pop_ssm(); + p_psm->on_parsed_type(result); + return; + } + + Super::illegal_token(tk, p_psm); + } + + bool + DExpectListTypeSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DExpectListTypeSsm"); + } + + void + DExpectListTypeSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_poly_child(reason, &elt_type_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectListTypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectQArraySsm.cpp b/xo-reader2/src/reader2/DExpectQArraySsm.cpp new file mode 100644 index 00000000..d871347c --- /dev/null +++ b/xo-reader2/src/reader2/DExpectQArraySsm.cpp @@ -0,0 +1,233 @@ +/** @file DExpectQArraySsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "ExpectQArraySsm.hpp" +#include "ExpectQLiteralSsm.hpp" +#include +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::mm::ACollector; + using xo::mm::AGCObject; + + namespace scm { + const char * + QArrayXst::_descr(enum code x) + { + switch (x) { + case code::invalid: break; + case code::qarray_0: return "qarray_0"; + case code::qarray_1a: return "qarray_1a"; + case code::qarray_2: return "qarray_2"; + case code::N: break; + } + + return "?QArrayXst"; + } + + DExpectQArraySsm::DExpectQArraySsm() : state_{QArrayXst::code::qarray_0} {} + + obj + DExpectQArraySsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + DExpectQArraySsm * + DExpectQArraySsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc_for(); + + return new (mem) DExpectQArraySsm(); + } + + void + DExpectQArraySsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectQArraySsm::make(p_psm->parser_alloc())); + } + + syntaxstatetype + DExpectQArraySsm::ssm_type() const noexcept { + return syntaxstatetype::expect_qarray; + } + + std::string_view + DExpectQArraySsm::get_expect_str() const { + switch (state_.code()) { + case QArrayXst::code::qarray_0: + return "leftparen"; + case QArrayXst::code::qarray_1a: + return "qliteral|rightparen"; + case QArrayXst::code::qarray_2: + return "(done)"; + case QArrayXst::code::invalid: + case QArrayXst::code::N: + break; + } + + return "?DExpectQArraySsm"; + } + + void + DExpectQArraySsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch(tk.tk_type()) + { + case tokentype::tk_leftbracket: + this->on_leftbracket_token(tk, p_psm); + return; + + case tokentype::tk_rightbracket: + this->on_rightbracket_token(tk, p_psm); + return; + + case tokentype::tk_comma: + case tokentype::tk_lambda: + case tokentype::tk_def: + case tokentype::tk_deftype: + 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_quote: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_cmple: + case tokentype::tk_cmpge: + case tokentype::tk_dot: + 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_nil: + 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; + } + } + + void + DExpectQArraySsm::on_leftbracket_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QArrayXst::code::qarray_0) { + this->state_ = QArrayXst(QArrayXst::code::qarray_1a); + + this->array_ = DArray::_empty(p_psm->expr_alloc(), + 8 /*heuristic starting capacity*/); + + DExpectQLiteralSsm::start(p_psm, + false /*cxl_on_rightparen*/, + true /*cxl_on_rightbracket*/); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQArraySsm::on_rightbracket_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QArrayXst::code::qarray_1a) { + this->state_ = QArrayXst(QArrayXst::code::qarray_2); + + array_->shrink_to_fit(); + + obj lit = obj(array_); + + p_psm->pop_ssm(); + p_psm->on_quoted_literal(lit); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQArraySsm::on_quoted_literal(obj lit, + ParserStateMachine * p_psm) + { + if(state_.code() == QArrayXst::code::qarray_1a) { + // append lit at the end of array_ + { + assert(array_); + + // ensure sufficient capacity + if (array_->size() == array_->capacity()) { + assert(array_->capacity() > 0); + + /* reallocate w/ 2x capacity */ + this->array_ = DArray::copy(p_psm->expr_alloc(), + array_, + 2 * array_->capacity()); + } + + bool ok = array_->push_back(p_psm->expr_alloc(), lit); + + if (!ok) assert(false); + } + + // start syntax to receive next literal + DExpectQLiteralSsm::start(p_psm, + false /*cxl_on_rightparen*/, + true /*cxl_on_rightbracket*/); + return; + } + + Super::illegal_quoted_literal(lit, p_psm); + } + + bool + DExpectQArraySsm::pretty(const ppindentinfo & ppii) const + { + obj array(array_); + auto array_pr = FacetRegistry::instance().variant(array); + + return ppii.pps()->pretty_struct(ppii, + "DExpectQArraySsm", + refrtag("state", state_), + refrtag("expect", this->get_expect_str()), + refrtag("array", array_pr)); + } + void + DExpectQArraySsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_child(reason, &array_); + } + + } +} + +/* end DExpectQArraySsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectQDictSsm.cpp b/xo-reader2/src/reader2/DExpectQDictSsm.cpp new file mode 100644 index 00000000..2dd68ef3 --- /dev/null +++ b/xo-reader2/src/reader2/DExpectQDictSsm.cpp @@ -0,0 +1,280 @@ +/** @file DExpectQDictSsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "ExpectQDictSsm.hpp" +#include "ExpectQLiteralSsm.hpp" +#include +#include + +namespace xo { + using xo::print::APrintable; + + namespace scm { + + const char * + QDictXst::_descr(enum code x) + { + switch (x) { + case code::invalid: break; + case code::qdict_0: return "qdict_0"; + case code::qdict_1a: return "qdict_1a"; + case code::qdict_1b: return "qdict_1b"; + case code::qdict_1c: return "qdict_1c"; + case code::qdict_1d: return "qdict_1d"; + case code::qdict_2: return "qdict_2"; + case code::N: break; + } + + return "?QDictXst"; + } + + DExpectQDictSsm::DExpectQDictSsm() : state_{QDictXst::code::qdict_0} {} + + obj + DExpectQDictSsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + DExpectQDictSsm * + DExpectQDictSsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc_for(); + + return new (mem) DExpectQDictSsm(); + } + + void + DExpectQDictSsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectQDictSsm::make(p_psm->parser_alloc())); + } + + syntaxstatetype + DExpectQDictSsm::ssm_type() const noexcept { + return syntaxstatetype::expect_qdict; + } + + std::string_view + DExpectQDictSsm::get_expect_str() const { + switch (state_.code()) { + case QDictXst::code::qdict_0: + return "leftbrace"; + case QDictXst::code::qdict_1a: + return "symbol|rightbrace"; + case QDictXst::code::qdict_1b: + return "colon"; + case QDictXst::code::qdict_1c: + return "literal"; + case QDictXst::code::qdict_1d: + return "semicolon|rightbrace"; + case QDictXst::code::qdict_2: + return "(done)"; + case QDictXst::code::invalid: + case QDictXst::code::N: + break; + } + + return "?DExpectQDictSsm"; + } + + void + DExpectQDictSsm::on_leftbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QDictXst::code::qdict_0) { + constexpr DDictionary::size_type hint_cap = 8; + + this->state_ = QDictXst(QDictXst::code::qdict_1a); + this->dict_ = DDictionary::empty(p_psm->expr_alloc(), hint_cap); + + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQDictSsm::on_rightbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + if ((state_.code() == QDictXst::code::qdict_1a) + || (state_.code() == QDictXst::code::qdict_1d)) + { + + this->state_ = QDictXst(QDictXst::code::qdict_2); + + obj lit = obj(dict_); + + p_psm->pop_ssm(); + p_psm->on_quoted_literal(lit); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQDictSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QDictXst::code::qdict_1a) { + this->state_ = QDictXst(QDictXst::code::qdict_1b); + this->key_ = DString::from_view(p_psm->expr_alloc(), std::string_view(tk.text())); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQDictSsm::on_colon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QDictXst::code::qdict_1b) { + this->state_ = QDictXst(QDictXst::code::qdict_1c); + + DExpectQLiteralSsm::start(p_psm, + false /*!cxl_on_rightparen*/); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQDictSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QDictXst::code::qdict_1d) { + this->state_ = QDictXst(QDictXst::code::qdict_1a); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQDictSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + 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; + + case tokentype::tk_rightbrace: + this->on_rightbrace_token(tk, p_psm); + return; + + case tokentype::tk_colon: + this->on_colon_token(tk, p_psm); + return; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + return; + + case tokentype::tk_rightparen: + case tokentype::tk_comma: + case tokentype::tk_lambda: + case tokentype::tk_def: + case tokentype::tk_deftype: + case tokentype::tk_if: + 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_quote: + case tokentype::tk_leftparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_cmple: + case tokentype::tk_cmpge: + case tokentype::tk_dot: + 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_nil: + 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; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQDictSsm::on_quoted_literal(obj lit, + ParserStateMachine * p_psm) + { + if (state_.code() == QDictXst::code::qdict_1c) { + // adjoin (key,value) pair into dictionary + + this->state_ = QDictXst(QDictXst::code::qdict_1d); + + assert(dict_); + + bool ok = dict_->upsert(p_psm->expr_alloc(), DDictionary::pair_type(key_, lit)); + + this->key_ = nullptr; + + if (!ok) assert(false); + + return; + } + + Super::illegal_quoted_literal(lit, p_psm); + } + + bool + DExpectQDictSsm::pretty(const ppindentinfo & ppii) const + { + obj dict(dict_); + obj dict_pr(dict_); + + return ppii.pps()->pretty_struct(ppii, + "DExpectQDictSsm", + refrtag("state", state_), + refrtag("expect", this->get_expect_str()), + refrtag("key", key_, key_), + refrtag("dict", dict_pr)); + } + + + void + DExpectQDictSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_child(reason, &key_); + gc.visit_child(reason, &dict_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectQDictSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectQListSsm.cpp b/xo-reader2/src/reader2/DExpectQListSsm.cpp new file mode 100644 index 00000000..8ea243ca --- /dev/null +++ b/xo-reader2/src/reader2/DExpectQListSsm.cpp @@ -0,0 +1,230 @@ +/** @file DExpectQListSsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "ExpectQListSsm.hpp" +#include "ExpectQLiteralSsm.hpp" +#include +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::mm::AGCObject; + + namespace scm { + const char * + QListXst::_descr(enum code x) + { + switch (x) { + case code::invalid: break; + case code::qlist_0: return "qlist_0"; + case code::qlist_1a: return "qlist_1a"; + case code::qlist_2: return "qlist_2"; + case code::N: break; + } + + return "?QListXst"; + } + + DExpectQListSsm::DExpectQListSsm() : state_{QListXst::code::qlist_0} {} + + obj + DExpectQListSsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + DExpectQListSsm * + DExpectQListSsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc_for(); + + return new (mem) DExpectQListSsm(); + } + + void + DExpectQListSsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectQListSsm::make(p_psm->parser_alloc())); + } + + syntaxstatetype + DExpectQListSsm::ssm_type() const noexcept { + return syntaxstatetype::expect_qlist; + } + + std::string_view + DExpectQListSsm::get_expect_str() const { + switch (state_.code()) { + case QListXst::code::qlist_0: + return "leftparen"; + case QListXst::code::qlist_1a: + return "qliteral|rightparen"; + case QListXst::code::qlist_2: + return "(done)"; + case QListXst::code::invalid: + case QListXst::code::N: + break; + } + + return "?DExpectQListSsm"; + } + + void + DExpectQListSsm::on_token(const Token & tk, + 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; + + case tokentype::tk_comma: + case tokentype::tk_lambda: + case tokentype::tk_def: + case tokentype::tk_deftype: + 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_quote: + 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_cmple: + case tokentype::tk_cmpge: + case tokentype::tk_dot: + 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_nil: + 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; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQListSsm::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QListXst::code::qlist_0) { + this->state_ = QListXst(QListXst::code::qlist_1a); + this->start_ = DList::_nil(); + this->end_ = nullptr; + + DExpectQLiteralSsm::start(p_psm, + true /*cxl_on_rightparen*/); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQListSsm::on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QListXst::code::qlist_1a) { + this->state_ = QListXst(QListXst::code::qlist_2); + + obj lit = obj(start_); + + p_psm->pop_ssm(); + p_psm->on_quoted_literal(lit); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQListSsm::on_quoted_literal(obj lit, + ParserStateMachine * p_psm) + { + if(state_.code() == QListXst::code::qlist_1a) { + // append lit at the end of list start_ .. end_ + { + DList * new_last + = DList::_cons(p_psm->expr_alloc(), lit, DList::_nil()); + + if (this->end_) { + /* DExpectQListSsm owns {start_, end_} -> preserves acyclic property */ + + end_->_assign_rest(p_psm->expr_alloc(), new_last); + + this->end_ = new_last; + } else { + this->start_ = DList::_cons(p_psm->expr_alloc(), + lit, + DList::_nil()); + this->end_ = this->start_; + } + } + + // start syntax to receive next literal + DExpectQLiteralSsm::start(p_psm, + true /*cxl_on_rightparen*/); + return; + } + + Super::illegal_quoted_literal(lit, p_psm); + } + + bool + DExpectQListSsm::pretty(const ppindentinfo & ppii) const + { + obj list(start_); + auto list_pr = FacetRegistry::instance().variant(list); + + return ppii.pps()->pretty_struct(ppii, + "DExpectQListSsm", + refrtag("state", state_), + refrtag("expect", this->get_expect_str()), + refrtag("list", list_pr)); + } + void + DExpectQListSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_child(reason, &start_); + gc.visit_child(reason, &end_); + } + + } +} + +/* end DExpectQListSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectQLiteralSsm.cpp b/xo-reader2/src/reader2/DExpectQLiteralSsm.cpp new file mode 100644 index 00000000..5265aeb7 --- /dev/null +++ b/xo-reader2/src/reader2/DExpectQLiteralSsm.cpp @@ -0,0 +1,268 @@ +/* @file DExpectQLiteralSsm.cpp + * + * @author Roland Conybeare, Mar 2026 + */ + +#include "ExpectQLiteralSsm.hpp" +#include "ExpectQListSsm.hpp" +#include "ExpectQArraySsm.hpp" +#include "ExpectQDictSsm.hpp" +#include +#include +#include +#include + +namespace xo { +// 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 { + DExpectQLiteralSsm::DExpectQLiteralSsm(bool cxl_on_rightparen, + bool cxl_on_rightbracket) + : cxl_on_rightparen_{cxl_on_rightparen}, + cxl_on_rightbracket_{cxl_on_rightbracket} + {} + + DExpectQLiteralSsm * + DExpectQLiteralSsm::_make(DArena & arena, + bool cxl_on_rightparen, + bool cxl_on_rightbracket) + { + /* 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_for(); + + return new (mem) DExpectQLiteralSsm(cxl_on_rightparen, cxl_on_rightbracket); + } + + obj + DExpectQLiteralSsm::make(DArena & arena, + bool cxl_on_rightparen, + bool cxl_on_rightbracket) + { + obj retval(_make(arena, + cxl_on_rightparen, + cxl_on_rightbracket)); + return retval; + } + + void + DExpectQLiteralSsm::start(ParserStateMachine * p_psm, + bool cxl_on_rightparen, + bool cxl_on_rightbracket) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectQLiteralSsm::make(p_psm->parser_alloc(), + cxl_on_rightparen, + cxl_on_rightbracket)); + } + + syntaxstatetype + DExpectQLiteralSsm::ssm_type() const noexcept { + return syntaxstatetype::expect_qliteral; + } + + std::string_view + DExpectQLiteralSsm::get_expect_str() const + { + return "leftparen|leftbracket|leftbrace|string|f64|i64|bool"; + } + + void + DExpectQLiteralSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (tk.tk_type()) { + + 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_string: + this->on_string_token(tk, p_psm); + return; + + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + + case tokentype::tk_rightparen: + this->on_rightparen_token(tk, p_psm); + return; + + case tokentype::tk_leftbracket: + this->on_leftbracket_token(tk, p_psm); + return; + + case tokentype::tk_rightbracket: + this->on_rightbracket_token(tk, p_psm); + return; + + case tokentype::tk_leftbrace: + this->on_leftbrace_token(tk, p_psm); + return; + + case tokentype::tk_comma: + case tokentype::tk_lambda: + case tokentype::tk_def: + case tokentype::tk_deftype: + case tokentype::tk_if: + case tokentype::tk_symbol: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_bool: + case tokentype::tk_semicolon: + case tokentype::tk_invalid: + case tokentype::tk_quote: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_cmple: + case tokentype::tk_cmpge: + case tokentype::tk_dot: + 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_nil: + 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; + } + + Super::on_token(tk, p_psm); + } + + void + DExpectQLiteralSsm::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + auto literal = DFloat::box(p_psm->expr_alloc(), + tk.f64_value()); + + p_psm->pop_ssm(); + p_psm->on_quoted_literal(literal); + } + + void + DExpectQLiteralSsm::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + auto literal = DInteger::box(p_psm->expr_alloc(), + tk.i64_value()); + + p_psm->pop_ssm(); + p_psm->on_quoted_literal(literal); + } + + void + DExpectQLiteralSsm::on_string_token(const Token & tk, + ParserStateMachine * p_psm) + { + auto literal = obj(DString::from_view(p_psm->expr_alloc(), + std::string_view(tk.text()))); + + p_psm->pop_ssm(); + p_psm->on_quoted_literal(literal); + } + + void + DExpectQLiteralSsm::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + // replace self with specialized version for parsing a literal list + + p_psm->pop_ssm(); + DExpectQListSsm::start(p_psm); + p_psm->on_token(tk); + } + + void + DExpectQLiteralSsm::on_rightparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (cxl_on_rightparen_) { + p_psm->pop_ssm(); + p_psm->on_token(tk); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQLiteralSsm::on_leftbracket_token(const Token & tk, + ParserStateMachine * p_psm) + { + // replace self with specialized version for parsing a literal array + + p_psm->pop_ssm(); + DExpectQArraySsm::start(p_psm); + p_psm->on_token(tk); + } + + void + DExpectQLiteralSsm::on_rightbracket_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (cxl_on_rightbracket_) { + p_psm->pop_ssm(); + p_psm->on_token(tk); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQLiteralSsm::on_leftbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + // replace self with specialized version for parsing a literal dict + + p_psm->pop_ssm(); + DExpectQDictSsm::start(p_psm); + p_psm->on_token(tk); + } + + bool + DExpectQLiteralSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DExpectQLiteralSsm", + refrtag("expect", this->get_expect_str())); + } + void + DExpectQLiteralSsm::visit_gco_children(VisitReason, obj) noexcept + { + // cxl_on_rightparen_, cxl_on_rightbracket_: POD, skip + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DExpectQLiteralSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp new file mode 100644 index 00000000..6847a776 --- /dev/null +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -0,0 +1,158 @@ +/** @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(); + } + + obj + DExpectSymbolSsm::make(DArena & mm) + { + return obj(_make(mm)); + } + + void + DExpectSymbolSsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + auto ssm = DExpectSymbolSsm::make(p_psm->parser_alloc()); + + p_psm->push_ssm(ckp, 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_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); + 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_deftype: + case tokentype::tk_if: + case tokentype::tk_singleassign: + case tokentype::tk_colon: + case tokentype::tk_semicolon: + case tokentype::tk_quote: + 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_cmple: + case tokentype::tk_cmpge: + 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_nil: + 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 + 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())); + } + + bool + DExpectSymbolSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DExpectSymbolSsm" + //refrtag("member", member_) + ); + } + void + DExpectSymbolSsm::visit_gco_children(VisitReason, + obj) noexcept + { + // no gc-aware members + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectSymbolSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp new file mode 100644 index 00000000..7a5d55a3 --- /dev/null +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -0,0 +1,210 @@ +/** @file DExpectTypeSsm.cpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#include "ExpectTypeSsm.hpp" +#include "ExpectListTypeSsm.hpp" +#include "SyntaxStateMachine.hpp" +#include +#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(bool corrected) + : corrected_{corrected} + {} + + DExpectTypeSsm * + DExpectTypeSsm::_make(DArena & mm, bool corrected) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DArena)); + + return new (mem) DExpectTypeSsm(corrected); + } + + obj + DExpectTypeSsm::make(DArena & mm, bool corrected) + { + return obj(_make(mm, corrected)); + } + + void + DExpectTypeSsm::start(bool corrected, + ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + auto ssm = DExpectTypeSsm::make(p_psm->parser_alloc(), corrected); + + p_psm->push_ssm(ckp, ssm); + } + + syntaxstatetype + DExpectTypeSsm::ssm_type() const noexcept + { + return syntaxstatetype::expect_type; + } + + std::string_view + DExpectTypeSsm::get_expect_str() const noexcept + { + 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; + + // all the not-yet handled cases + case tokentype::tk_invalid: + case tokentype::tk_def: + case tokentype::tk_deftype: + case tokentype::tk_if: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_string: + case tokentype::tk_quote: + 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_cmple: + case tokentype::tk_cmpge: + 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: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_nil: + 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: + p_psm->illegal_input_on_token("DExpectTypeSsm::on_token", + tk, + this->get_expect_str()); + break; + } + } + + void + DExpectTypeSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + if (corrected_) { + obj type; + obj mm = p_psm->expr_alloc(); + + if (tk.text() == "list") { + /* replace top ssm with specialized list-type ssm parser */ + p_psm->pop_ssm(); + DExpectListTypeSsm::start(p_psm); + p_psm->on_token(tk); + } else { + if (tk.text() == "unit") + type = DAtomicType::make(mm, Metatype::t_unit()); + if (tk.text() == "bool") + type = DAtomicType::make(mm, Metatype::t_bool()); + else if (tk.text() == "str") + type = DAtomicType::make(mm, Metatype::t_str()); + else if (tk.text() == "f64") + type = DAtomicType::make(mm, Metatype::t_f64()); + else if(tk.text() == "f32") + type = DAtomicType::make(mm, Metatype::t_f32()); + else if(tk.text() == "i16") + type = DAtomicType::make(mm, Metatype::t_i16()); + else if(tk.text() == "i32") + type = DAtomicType::make(mm, Metatype::t_i32()); + else if(tk.text() == "i64") + type = DAtomicType::make(mm, Metatype::t_i64()); + + p_psm->pop_ssm(); + p_psm->on_parsed_type(type); + } + } else { + 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) { + Super::on_token(tk, p_psm); + return; + } + + p_psm->pop_ssm(); + p_psm->on_parsed_typedescr(td); + } + } + + bool + DExpectTypeSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DExpectTypeSsm"); + } + + void + DExpectTypeSsm::visit_gco_children(VisitReason, + obj) noexcept + { + // corrected_: POD, skip + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectTypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/DGlobalEnv.cpp b/xo-reader2/src/reader2/DGlobalEnv.cpp new file mode 100644 index 00000000..0343d2c2 --- /dev/null +++ b/xo-reader2/src/reader2/DGlobalEnv.cpp @@ -0,0 +1,140 @@ +/** @file DGlobalEnv.cpp + * + * @author Roland Conybeare, Feb 2026 +**/ + +#include "GlobalEnv.hpp" +#include +#include + +namespace xo { + using xo::mm::ACollector; + 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->var_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(false), + 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); + } + + values_->assign_at(mm, + ix.j_slot(), + x); + } + + DVariable * + DGlobalEnv::_upsert_value(obj mm, + const DUniqueString * sym, + TypeDescr td, + obj value) + { + DVariable * var + = DVariable::make(mm, sym, TypeRef::resolved(td)); + + assert(var); + + symtab_->upsert_variable(mm, var); + this->assign_value(mm, var->path(), value); + + return var; + } + + // ----- AGCObject facet ----- + + DGlobalEnv * + DGlobalEnv::gco_shallow_move(obj gc) noexcept + { + return gc.std_move_for(this); + } + + void + DGlobalEnv::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_child(reason, &symtab_); + gc.visit_child(reason, &values_); + } + + // ----- APrintable facet ----- + + bool + DGlobalEnv::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DGlobalEnv", + refrtag("n_vars", symtab_->n_vars())); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalEnv.cpp */ diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp new file mode 100644 index 00000000..5efd9289 --- /dev/null +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -0,0 +1,519 @@ +/** @file DIfElseSsm.cpp + * + * @author Roland Conybeare, Jul 2025 + **/ + +#include "ifelse/DIfElseSsm.hpp" +#include "ifelse/ISyntaxStateMachine_DIfElseSsm.hpp" +#include "DefineSsm.hpp" +//#include "define/IPrintable_DDefineSsm.hpp" +#include "DExpectExprSsm.hpp" +#include +#include +#include +#include + +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); + } + + obj + DIfElseSsm::make(DArena & mm, + DIfElseExpr * ifelse_expr) + { + return obj(_make(mm, ifelse_expr)); + } + + void + DIfElseSsm::start(DArena & parser_mm, + obj expr_mm, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + DArena::Checkpoint ckp = parser_mm.checkpoint(); + + DIfElseExpr * if_expr = DIfElseExpr::_make_empty(expr_mm); + + auto ssm = DIfElseSsm::make(parser_mm, if_expr); + + p_psm->push_ssm(ckp, 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: + case tokentype::tk_deftype: + 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_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_invalid: + case tokentype::tk_quote: + 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_cmple: + case tokentype::tk_cmpge: + 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_nil: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + DSyntaxStateMachine::on_token(tk, p_psm); + } + + 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); + return; + } + + DSyntaxStateMachine::on_token(tk, p_psm); + } + + 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); + return; + } + + DSyntaxStateMachine::on_token(tk, p_psm); + } + + 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); + return; + } + + DSyntaxStateMachine::on_token(tk, p_psm); + } + +#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); + } + +#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; + } + + DSyntaxStateMachine::on_token(tk, p_psm); + } + +#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; + } + + DSyntaxStateMachine::on_parsed_expression(expr, p_psm); + } + + void + DIfElseSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + // TODO: may consider allowing if-else to terminate on other particular tokens + // e.g. ')' + + 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); + } + + 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)); + } + + void + DIfElseSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_poly_child(reason, &if_expr_); + } + } /*namespace scm*/ +} /*namespace xo*/ diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp new file mode 100644 index 00000000..cb184670 --- /dev/null +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -0,0 +1,489 @@ +/** @file DLambdaSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "LambdaSsm.hpp" +#include "ExpectFormalArglistSsm.hpp" +#include "DExpectTypeSsm.hpp" +#include "DExpectExprSsm.hpp" +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include +//#include +#include +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::mm::AAllocator; + using xo::mm::AGCObject; + 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) + { + 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()); + } + + 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 "yields|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) + { + switch (tk.tk_type()) { + case tokentype::tk_lambda: + this->on_lambda_token(tk, p_psm); + return; + + case tokentype::tk_yields: + 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_deftype: + 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_quote: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_cmple: + case tokentype::tk_cmpge: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + 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_nil: + 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; + } + + Super::on_token(tk, p_psm); + } + + 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; + } + + Super::on_token(tk, p_psm); + } + + void + DLambdaSsm::on_yields_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (lmstate_ == lambdastatetype::lm_2) { + this->lmstate_ = lambdastatetype::lm_3; + + DExpectTypeSsm::start(false /*!corrected*/, p_psm); + + /* control reenters via .on_parsed_typedescr() */ + return; + } + + Super::on_token(tk, p_psm); + } + + 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, + 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; + } + + Super::on_parsed_typedescr(td, p_psm); + } + +#ifdef NOT_YET + 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_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_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(), + 0 /*ntypes*/); + assert(symtab); + + 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 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()); + + if (!b.is_local()) assert(false); + + 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; + } + + 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) + { + if (lmstate_ == lambdastatetype::lm_4) { + this->lmstate_ = lambdastatetype::lm_5; + this->body_ = expr; + + // assemble lambda + + 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); + return; + } + + Super::on_parsed_expression(expr, p_psm); + } + + void + DLambdaSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) + { + Super::on_parsed_expression_with_token(expr, tk, p_psm); + } + +#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 + +#endif + + bool + DLambdaSsm::pretty(const ppindentinfo & ppii) const + { + obj body + = FacetRegistry::instance().try_variant(body_); + + if (body) { + return ppii.pps()->pretty_struct + (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("expect", this->get_expect_str())); + } + } + + void + DLambdaSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_child(reason, &local_symtab_); + + // explicit_return_td not gcobject + // lambda_td not gcobject + + gc.visit_poly_child(reason, &body_); + gc.visit_poly_child(reason, &parent_symtab_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLambdaSsm.cpp */ diff --git a/xo-reader2/src/reader2/DParenSsm.cpp b/xo-reader2/src/reader2/DParenSsm.cpp new file mode 100644 index 00000000..a832bd15 --- /dev/null +++ b/xo-reader2/src/reader2/DParenSsm.cpp @@ -0,0 +1,470 @@ +/** @file DParenSsm.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "ParenSsm.hpp" +#include "ExpectExprSsm.hpp" +#include "syntaxstatetype.hpp" +#include +#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(); + } + + obj + DParenSsm::make(DArena & mm) + { + return obj(_make(mm)); + } + + void + DParenSsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + auto paren_ssm = DParenSsm::make(p_psm->parser_alloc()); + + p_psm->push_ssm(ckp, paren_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 "leftparen"; + case parenexprstatetype::lparen_1: return "expression"; + case parenexprstatetype::lparen_2: return "rightparen"; + } + + 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; + + 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: + case tokentype::tk_deftype: + 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_quote: + 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_cmple: + case tokentype::tk_cmpge: + 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_nil: + 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) + { + 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); + + return; + } + + 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); + } +#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) + { + 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); + } +#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); + } + + 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 + 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())); + } + + void + DParenSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_poly_child(reason, &expr_); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DParenSsm.cpp */ diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp new file mode 100644 index 00000000..00ce5f61 --- /dev/null +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -0,0 +1,1257 @@ +/** @file DProgressSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ProgressSsm.hpp" + +#include "DExpectExprSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" + +#include "ApplySsm.hpp" +#include "ParenSsm.hpp" + +#include + +#include +#include + +#include +#include + +#include // for xo::scm::Primitives +#include + +#include +#include +#include +#include +#include + +#ifdef NOT_YET +#include "expect_expr_xs.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::mm::AAllocator; + using xo::mm::AGCObject; + using xo::print::APrintable; + using xo::facet::FacetRegistry; + 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 "???"; + } + + /** higher-precedence operators bind before lower-preference operators **/ + 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; + } + + 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_cmple: // [<=] + return optype::op_less_equal; + case tokentype::tk_rightangle: // [>] + return optype::op_great; + case tokentype::tk_cmpge: // [>=] + return optype::op_great_equal; + default: + assert(false); + return optype::invalid; + } + return optype::invalid; + } + } + + DProgressSsm * + DProgressSsm::_make(DArena & mm, + obj lhs, + optype op) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DProgressSsm)); + + return new (mem) DProgressSsm(lhs, op); + } + + obj + DProgressSsm::make(DArena & mm, + obj lhs, + optype op) + { + return obj(_make(mm, lhs, op)); + } + + void + DProgressSsm::start(DArena & parser_mm, + obj lhs, + optype op, + ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = parser_mm.checkpoint(); + + auto ssm = DProgressSsm::make(parser_mm, lhs, op); + + p_psm->push_ssm(ckp, ssm); + } + + void + DProgressSsm::start(DArena & parser_mm, + obj lhs, + ParserStateMachine * p_psm) + { + 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}, + 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 (!lhs_) { + return "expr1|leftparen"; + } else if (op_type_ == optype::invalid) { + return "oper|semicolon|leftparen|rightparen|rightbrace"; + } else { + return "expr2|leftparen"; + } + } + + 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_then: + case tokentype::tk_else: + case tokentype::tk_comma: + this->on_completing_token(tk, p_psm); + return; + + case tokentype::tk_symbol: + this->on_symbol_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; + + 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; + + case tokentype::tk_rightbrace: + this->on_rightbrace_token(tk, p_psm); + return; + + 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_invalid: + case tokentype::tk_def: + case tokentype::tk_deftype: + case tokentype::tk_if: + case tokentype::tk_quote: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_dot: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + break; + + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_cmple: + case tokentype::tk_cmpge: + this->on_operator_token(tk, p_psm); + return; + + case tokentype::tk_nil: + case tokentype::tk_type: + case tokentype::tk_lambda: + break; + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + Super::on_token(tk, p_psm); + } + + void + DProgressSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + Super::on_token(tk, p_psm); + } + + void + DProgressSsm::on_completing_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + obj expr = this->assemble_expr(p_psm); + + p_psm->pop_ssm(); // completes self + p_psm->on_parsed_expression_with_token(expr, tk); + } + + 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_operator_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (op_type_ == optype::invalid) { + // tk is the operator this instance was waiting for. + // But need to consider precedence. + // possibly need to take lhs_ expression and rotate it into new lhs of + // surrounding ProgressSsm + + + this->op_type_ = tk2op(tk.tk_type()); + + DExpectExprSsm::start(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); + DExpectExprSsm::start(p_psm); + return; + } else { + /* associate to the right + * + * parse like + * a + b * ... (a + (b * ...)) + */ + + obj lhs1 = lhs_; + optype op_type1 = op_type_; + obj rhs1 = rhs_; + + assert(lhs1); + assert(op_type1 != optype::invalid); + assert(rhs1); + + p_psm->pop_ssm(); + + /* (a + ..) */ + DProgressSsm::start(p_psm->parser_alloc(), + lhs1, + op_type1, + p_psm); + DExpectExprSsm::start(p_psm); + /* (b * ..) */ + DProgressSsm::start(p_psm->parser_alloc(), + rhs1, + op_type2, + p_psm); + DExpectExprSsm::start(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) + { + Super::on_token(tk, p_psm); + } + + void + DProgressSsm::on_f64_token(const Token & tk, + ParserStateMachine * p_psm) + { + Super::on_token(tk, p_psm); + } + + void + DProgressSsm::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + Super::on_token(tk, p_psm); + } + + void + DProgressSsm::on_bool_token(const Token & tk, + ParserStateMachine * p_psm) + { + Super::on_token(tk, p_psm); + } + + void + DProgressSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->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_token(expr, tk); + } + + 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); + + if (expr) { + obj expr_pr + = 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(); + 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(); + + scope log(XO_DEBUG(c_debug_flag)); + + if (!lhs_) { + log && log("accepting expr1"); + + this->lhs_ = expr; + + return; + } + + assert (op_type_ != optype::invalid); + + if (!rhs_) { + this->rhs_ = expr; + + // need next token before we know whether this DProgressSsm + // is complete. Consider input like 7 + 2 * 3 vs 7 * 2 + 3 + // + + return; + } + + Super::on_parsed_expression(expr, p_psm); + } + + void + DProgressSsm::on_parsed_expression_with_token(obj expr, + const Token & tk, + ParserStateMachine * p_psm) + { + const bool c_debug_flag = p_psm->debug_flag(); + + 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 + // x : = 4 4 + + p_psm->illegal_parsed_expression + ("DProgressSsm::on_parsed_expression_with_token", + 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_token(expr2, tk); + } + } + +#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)); + } + + 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_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); + } +#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 (op_type_ == optype::invalid) { + // 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); + // + send leftparen to just-pushed apply + p_psm->on_token(tk); + + return; + } + + Super::on_token(tk, p_psm); + } + +#ifdef NOT_YET + /* 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; + } + + 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); + } +#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) + { + /* 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_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 } + */ + } +#endif + +#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, + 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); + } + } +#endif + + bool + DProgressSsm::pretty(const xo::print::ppindentinfo & ppii) const + { + scope log(XO_DEBUG(false)); + log && log(xtag("lhs_.tseq", lhs_._typeseq())); + log && log(xtag("rhs_.tseq", rhs_._typeseq())); + + obj 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, lhs_present), + refrtag("op", op_type_, op_present), + refrtag("rhs", rhs, rhs_present), + refrtag("expect", this->get_expect_str()) + ); + } + + namespace { + // make_builtin_apply_pm2 + + // helper function for making apply expression that invokes + // a binary primitive. Use for numeric operators: + // {*, /, +, -, ==} + // + obj + assemble_numeric_expr_aux(obj expr_alloc, + const TypeRef::prefix_type & prefix, + obj pm_obj, + obj lhs, + obj rhs) + { + auto fn_expr = DConstant::make(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 + */ + + TypeRef tref = TypeRef::dwim(prefix, nullptr); + + return DApplyExpr::make2(expr_alloc, + tref, fn_expr, lhs, rhs); + + } + +#ifdef OBSOLETE + obj + assemble_numeric_expr_aux(obj expr_alloc, + const TypeRef::prefix_type & prefix, + DPrimitive_gco_2_gco_gco * p_gco_pm, + obj lhs, + obj rhs) + { + auto pm_obj = with_facet::mkobj(p_gco_pm); + + return assemble_numeric_expr_aux(expr_alloc, + prefix, + pm_obj, + lhs, rhs); + } +#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); + return obj(); + } + + /* 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: + assert(false); + break; + + case optype::op_equal: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_cmpeq_gco"), + p_psm->cmpeq_pm(), + lhs_, rhs_); + + case optype::op_not_equal: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_cmpne_gco"), + p_psm->cmpne_pm(), + lhs_, rhs_); + + case optype::op_less: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_cmplt_gco"), + p_psm->cmplt_pm(), + lhs_, rhs_); + + case optype::op_less_equal: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_cmple_gco"), + p_psm->cmple_pm(), + lhs_, rhs_); + + case optype::op_great: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_cmpgt_gco"), + p_psm->cmpgt_pm(), + lhs_, rhs_); + break; + + case optype::op_great_equal: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_cmpge_gco"), + p_psm->cmpge_pm(), + lhs_, rhs_); + + case optype::op_multiply: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_mul_gco"), + p_psm->multiply_pm(), + lhs_, rhs_); + + case optype::op_divide: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_div_gco"), + p_psm->divide_pm(), + lhs_, rhs_); + + case optype::op_add: + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_add_gco"), + p_psm->add_pm(), + lhs_, rhs_); + + break; + + case optype::op_subtract: /* editor bait: op_minus */ + return assemble_numeric_expr_aux + (p_psm->expr_alloc(), + TypeRef::prefix_type::from_chars("_sub_gco"), + p_psm->subtract_pm(), + lhs_, rhs_); + +#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_); + } + +#endif + + case optype::n_optype: + /* unreachable */ + assert(false); + break; + } + + return obj(); + } + + void + DProgressSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_poly_child(reason, &lhs_); + gc.visit_poly_child(reason, &rhs_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DProgressSsm.cpp */ diff --git a/xo-reader2/src/reader2/DQuoteSsm.cpp b/xo-reader2/src/reader2/DQuoteSsm.cpp new file mode 100644 index 00000000..af5d08e3 --- /dev/null +++ b/xo-reader2/src/reader2/DQuoteSsm.cpp @@ -0,0 +1,224 @@ +/** @file DQuoterSsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "QuoteSsm.hpp" +#include "ExpectQLiteralSsm.hpp" +#include "syntaxstatetype.hpp" +#include +//#include + +namespace xo { + using xo::facet::with_facet; + using xo::facet::typeseq; + + namespace scm { + + extern const char * + QuoteXst::_descr(enum QuoteXst::code x) + { + switch (x) { + case code::invalid: return "invalid"; + case code::quote_0: return "quote_0"; + case code::quote_1: return "quote_1"; + case code::quote_2: return "quote_2"; + case code::quote_3: return "quote_3"; + case code::N: break; + } + + return "?QuoteXst"; + } + + DQuoteSsm::DQuoteSsm() + : quote_xst_(QuoteXst::code::quote_0), + expr_{} + {} + + DQuoteSsm * + DQuoteSsm::_make(DArena & mm) + { + void * mem = mm.alloc_for(); + + return new (mem) DQuoteSsm(); + } + + obj + DQuoteSsm::make(DArena & mm) + { + return obj(_make(mm)); + } + + void + DQuoteSsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + auto paren_ssm = DQuoteSsm::make(p_psm->parser_alloc()); + + p_psm->push_ssm(ckp, paren_ssm); + } + + syntaxstatetype + DQuoteSsm::ssm_type() const noexcept + { + return syntaxstatetype::paren; + } + + std::string_view + DQuoteSsm::get_expect_str() const noexcept + { + switch (this->quote_xst_.code()) { + case QuoteXst::code::invalid: + case QuoteXst::code::N: + break; + case QuoteXst::code::quote_0: return "#q"; + case QuoteXst::code::quote_1: return "leftbrace"; + case QuoteXst::code::quote_2: return "qliteral"; + case QuoteXst::code::quote_3: return "rightbrace"; + } + + assert(false); + + return "?quotexst"; + } + + void + DQuoteSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (tk.tk_type()) { + + case tokentype::tk_quote: + this->on_quote_token(tk, p_psm); + return; + + case tokentype::tk_leftbrace: + this->on_leftbrace_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_symbol: + case tokentype::tk_def: + case tokentype::tk_deftype: + 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_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_cmple: + case tokentype::tk_cmpge: + 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_nil: + 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 + DQuoteSsm::on_quote_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (quote_xst_.code() == QuoteXst::code::quote_0) { + this->quote_xst_ = QuoteXst(QuoteXst::code::quote_1); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DQuoteSsm::on_leftbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (quote_xst_.code() == QuoteXst::code::quote_1) { + this->quote_xst_ = QuoteXst(QuoteXst::code::quote_2); + DExpectQLiteralSsm::start(p_psm); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DQuoteSsm::on_rightbrace_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (quote_xst_.code() == QuoteXst::code::quote_3) { + // quoted literal (reported as constant expr) successfully parsed + + p_psm->pop_ssm(); + p_psm->on_parsed_expression(this->expr_); + return; + } + + Super::on_token(tk, p_psm); + } + + void + DQuoteSsm::on_quoted_literal(obj literal, + ParserStateMachine * p_psm) + { + if (quote_xst_.code() == QuoteXst::code::quote_2) { + this->quote_xst_ = QuoteXst(QuoteXst::code::quote_3); + this->expr_ = DConstant::make(p_psm->expr_alloc(), literal); + + return; + } + + Super::illegal_quoted_literal(literal, p_psm); + } + + bool + DQuoteSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DQuoteSsm", + refrtag("quote_xst", quote_xst_), + refrtag("expect", this->get_expect_str())); + } + + void + DQuoteSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_poly_child(reason, &expr_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DQuoteSsm.cpp */ diff --git a/xo-reader2/src/reader2/DSchematikaParser.cpp b/xo-reader2/src/reader2/DSchematikaParser.cpp new file mode 100644 index 00000000..c1a92c5b --- /dev/null +++ b/xo-reader2/src/reader2/DSchematikaParser.cpp @@ -0,0 +1,209 @@ +/** @file DSchematikaParser.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "SchematikaParser.hpp" +#include "ParserStateMachine.hpp" +#include "ParserStack.hpp" +#include "DToplevelSeqSsm.hpp" +#include +#include +#include + +namespace xo { + using xo::mm::ACollector; + using xo::mm::AAllocator; + using xo::mm::AGCObject; + using xo::mm::MemorySizeInfo; + using xo::tostr; + using xo::xtag; + + namespace scm { + // ----- SchematikaParser ----- + + DSchematikaParser::DSchematikaParser(const ParserConfig & cfg, + obj expr_alloc, + obj aux_alloc) + : psm_{ + cfg.parser_arena_config_, + cfg.symtab_var_config_, + cfg.symtab_types_config_, + cfg.max_stringtable_capacity_, + cfg.pm_install_flags_, + expr_alloc, + aux_alloc + }, + debug_flag_{cfg.debug_flag_} + { + } + + DSchematikaParser * + DSchematikaParser::_make(obj mm, + const ParserConfig & cfg, + obj expr_alloc, + obj aux_alloc) + { + void * mem = mm.alloc_for(); + + return new (mem) DSchematikaParser(cfg, expr_alloc, aux_alloc); + } + + obj + DSchematikaParser::make(obj mm, + const ParserConfig & cfg, + obj expr_alloc, + obj aux_alloc) + { + return obj(_make(mm, cfg, expr_alloc, aux_alloc)); + } + + DGlobalSymtab * + DSchematikaParser::global_symtab() const noexcept + { + return psm_.global_symtab(); + } + + DGlobalEnv * + DSchematikaParser::global_env() const noexcept + { + return psm_.global_env(); + } + + bool + DSchematikaParser::is_at_toplevel() const + { + return psm_.is_at_toplevel(); + } + + bool + DSchematikaParser::has_incomplete_expr() const + { + return psm_.has_incomplete_expr(); + } + + obj + DSchematikaParser::top_ssm() const + { + return psm_.top_ssm(); + } + + const ParserResult & + DSchematikaParser::result() const + { + return psm_.result(); + } + + void + DSchematikaParser::visit_pools(const MemorySizeVisitor & visitor) const + { + return psm_.visit_pools(visitor); + } + + void + DSchematikaParser::begin_interactive_session() + { + DToplevelSeqSsm::establish_interactive(psm_.parser_alloc(), &psm_); + + } + + void + DSchematikaParser::begin_batch_session() + { + DToplevelSeqSsm::establish_batch(psm_.parser_alloc(), &psm_); + } + + const DUniqueString * + DSchematikaParser::intern_string(std::string_view str) + { + return psm_.intern_string(str); + } + + const ParserResult & + DSchematikaParser::on_token(const token_type & tk) + { + scope log(XO_DEBUG(debug_flag_), xtag("tk", tk)); + + if (psm_.stack() == nullptr) { + throw std::runtime_error(tostr("DSchematikaParser::include_token", + ": parser not expecting input" + "(call parser.begin_translation_unit()..?)", + xtag("token", tk))); + } + + /* stack is non-empty */ + + psm_.on_token(tk); + + log && log(xtag("parser", this)); + log && log(xtag("result", psm_.result())); + + return psm_.result(); + } /*include_token*/ + + void + DSchematikaParser::reset_result() + { + psm_.reset_result(); + } + + void + DSchematikaParser::reset_to_idle_toplevel() + { + psm_.clear_error_reset(); + } /*reset_to_idle_toplevel*/ + + void + DSchematikaParser::print(std::ostream & os) const { + os << "" << std::endl; + } + + bool + DSchematikaParser::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()) + ); + } + + DSchematikaParser * + DSchematikaParser::gco_shallow_move(obj gc) noexcept + { + (void)gc; + + /** TODO: may be feasible to use gc.std_move_for(this) + * if/when DSchematikaParser is moveable + **/ + assert(false); + return nullptr; + } + + void + DSchematikaParser::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + psm_.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end SchematikaParser.cpp */ diff --git a/xo-reader2/src/reader2/DSequenceSsm.cpp b/xo-reader2/src/reader2/DSequenceSsm.cpp new file mode 100644 index 00000000..c3517065 --- /dev/null +++ b/xo-reader2/src/reader2/DSequenceSsm.cpp @@ -0,0 +1,271 @@ +/* @file DSequenceSsm.cpp */ + +#include "DSequenceSsm.hpp" +#include "ssm/ISyntaxStateMachine_DSequenceSsm.hpp" +#include "DExpectExprSsm.hpp" +#include +#include + +#ifdef NOT_YET +#include "expect_expr_xs.hpp" +#include "let1_xs.hpp" +#include "xo/expression/DefineExpr.hpp" +#include "xo/expression/pretty_expression.hpp" +#endif + +namespace xo { +#ifdef NOT_YET + using xo::scm::DDefineExpr; +#endif + using xo::facet::typeseq; + + namespace scm { + void + DSequenceSsm::start(ParserStateMachine * p_psm) + { + 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 + */ + DExpectExprSsm::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + false /*!cxl_on_rightparen*/, + 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} + {} + + syntaxstatetype + DSequenceSsm::ssm_type() const noexcept + { + return syntaxstatetype::sequence; + } + + std::string_view + DSequenceSsm::get_expect_str() const noexcept + { + return "expr|semicolon|rightbrace"; + } + + void + 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_deftype: + 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_quote: + 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_cmple: + case tokentype::tk_cmpge: + 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_nil: + 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())); + + // TODO: switch to printable facet + + log && log(xtag("expr", expr)); + +#ifdef NOT_YET + /* 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); + } +#endif + + 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 + void + sequence_xs::on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) + { + /* sequence continues until right brace */ + this->on_expr(expr, p_psm); + } +#endif + + bool + DSequenceSsm::pretty(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DSequenceSsm", + refrtag("seq_expr.size", seq_expr_->size()), + refrtag("expect", this->get_expect_str())); + } + + void + DSequenceSsm::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_child(reason, &seq_expr_); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DSequenceSsm.cpp */ diff --git a/xo-reader2/src/reader2/DToplevelSeqSsm.cpp b/xo-reader2/src/reader2/DToplevelSeqSsm.cpp new file mode 100644 index 00000000..cab947b1 --- /dev/null +++ b/xo-reader2/src/reader2/DToplevelSeqSsm.cpp @@ -0,0 +1,529 @@ +/** @file DToplevelSeqSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DToplevelSeqSsm.hpp" +#include "ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp" +#include "DDefineSsm.hpp" +#include "DeftypeSsm.hpp" +#include "LambdaSsm.hpp" +#include "ProgressSsm.hpp" +#include "IfElseSsm.hpp" +#include "QuoteSsm.hpp" +#include "ParenSsm.hpp" +#include "ExpectExprSsm.hpp" +#include "VarRef.hpp" + +#include +#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::mm::DArena; + //using xo::facet::with_facet; + 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?"; + } + + DToplevelSeqSsm::DToplevelSeqSsm(exprseqtype ty) : seqtype_{ty} + {} + + namespace { + obj + make_exprseq_ssm(DArena & mm, + exprseqtype seqtype) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DToplevelSeqSsm)); + + DToplevelSeqSsm * ssm = new (mem) DToplevelSeqSsm(seqtype); + + return obj(ssm); + } + } + + void + DToplevelSeqSsm::establish_interactive(DArena & mm, + ParserStateMachine * p_psm) + { + p_psm->establish_toplevel_ssm(make_exprseq_ssm + (mm, + exprseqtype::toplevel_interactive)); + } + + void + DToplevelSeqSsm::establish_batch(DArena & mm, + ParserStateMachine * p_psm) + { + p_psm->establish_toplevel_ssm(make_exprseq_ssm + (mm, + exprseqtype::toplevel_batch)); + } + + // SyntaxStateMachine facet methods + + syntaxstatetype + DToplevelSeqSsm::ssm_type() const noexcept + { + return syntaxstatetype::expect_toplevel_expression_sequence; + } + + std::string_view + DToplevelSeqSsm::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-DToplevelSeqSsm::get_expr_str"; + } + + void + DToplevelSeqSsm::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); + return; + + case tokentype::tk_def: + this->on_def_token(tk, p_psm); + return; + + case tokentype::tk_deftype: + this->on_deftype_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; + + 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_nil: + this->on_nil_token(tk, p_psm); + return; + + case tokentype::tk_leftparen: + this->on_leftparen_token(tk, p_psm); + return; + + case tokentype::tk_quote: + this->on_quote_token(tk, p_psm); + return; + + // all the not-yet handled cases + 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_cmple: + case tokentype::tk_cmpge: + 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: + 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("DToplevelSeqSsm::on_token", + tk, + this->get_expect_str()); + } + + void + DToplevelSeqSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { + auto varref = obj(p_psm->lookup_varref(tk.text())); + + if (varref) { + DProgressSsm::start(p_psm->parser_alloc(), + varref, + p_psm); + return; + } else { + p_psm->error_unbound_variable("DToplevelSeqSsm", + tk.text()); + return; + } + } + break; + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::on_token(tk, p_psm); + } + + void + DToplevelSeqSsm::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DDefineSsm::start(p_psm->parser_alloc(), + p_psm->expr_alloc(), + p_psm); + + /* keyword 'def' introduces a definition: + * def pi : f64 = 3.14159265 + * def sq(x : f64) -> f64 { (x * x) } + */ + } + + void + DToplevelSeqSsm::on_deftype_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DDeftypeSsm::start(p_psm->parser_alloc(), + p_psm); + p_psm->on_token(Token::deftype_token()); + } + + void + DToplevelSeqSsm::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; + } + + Super::on_token(tk, p_psm); + } + + void + DToplevelSeqSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + DIfElseSsm::start(p_psm->parser_alloc(), + p_psm->expr_alloc(), + p_psm); + return; + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::on_token(tk, p_psm); + } + + void + DToplevelSeqSsm::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); + obj expr = DConstant::make(p_psm->expr_alloc(), str); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::on_token(tk, p_psm); + } + + void + DToplevelSeqSsm::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 expr = DConstant::make(p_psm->expr_alloc(), f64o); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::on_token(tk, p_psm); + } + + void + DToplevelSeqSsm::on_i64_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { + 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(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::illegal_token(tk, p_psm); + } + + void + DToplevelSeqSsm::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 expr = DConstant::make(p_psm->expr_alloc(), dvalue); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::illegal_token(tk, p_psm); + } + + void + DToplevelSeqSsm::on_nil_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { + auto dvalue = DList::nil(); + auto expr = DConstant::make(p_psm->expr_alloc(), dvalue); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); + break; + } + + Super::illegal_token(tk, p_psm); + } + + void + DToplevelSeqSsm::on_leftparen_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: { + // 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; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::illegal_token(tk, p_psm); + } + + void + DToplevelSeqSsm::on_quote_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: { + DProgressSsm::start(p_psm->parser_alloc(), + p_psm); + DQuoteSsm::start(p_psm); + p_psm->on_token(Token::quote_token()); + + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + Super::illegal_token(tk, p_psm); + } + + void + DToplevelSeqSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + // toplevel expr sequence accepts an arbitrary number of expressions. + + p_psm->capture_result("DToplevelSeqSsm::on_parsed_expression", expr); + } + + void + 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("DToplevelSeqSsm::on_parsed_expression_with_token", expr); + return; + } + + Super::on_parsed_expression_with_token(expr, tk, p_psm); + } + + bool + DToplevelSeqSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DToplevelSeqSsm", + refrtag("seqtype", seqtype_)); + } + void + DToplevelSeqSsm::visit_gco_children(VisitReason, obj) noexcept + { + // seqtype_: POD, skip + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DToplevelSeqSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectExprSsm.cpp new file mode 100644 index 00000000..7febe575 --- /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: + * [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 */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..262cb91e --- /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: + * [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 */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectQArraySsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectQArraySsm.cpp new file mode 100644 index 00000000..b3f875d9 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExpectQArraySsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectQArraySsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQArraySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQArraySsm.json5] +**/ + +#include "ssm/IPrintable_DExpectQArraySsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectQArraySsm::pretty(const DExpectQArraySsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectQArraySsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectQListSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectQListSsm.cpp new file mode 100644 index 00000000..c8342703 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExpectQListSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectQListSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQListSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQListSsm.json5] +**/ + +#include "ssm/IPrintable_DExpectQListSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectQListSsm::pretty(const DExpectQListSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectQListSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectQLiteralSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectQLiteralSsm.cpp new file mode 100644 index 00000000..24c33902 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DExpectQLiteralSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectQLiteralSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQLiteralSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQLiteralSsm.json5] +**/ + +#include "ssm/IPrintable_DExpectQLiteralSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectQLiteralSsm::pretty(const DExpectQLiteralSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectQLiteralSsm.cpp */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectSymbolSsm.cpp new file mode 100644 index 00000000..f03af120 --- /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: + * [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 */ diff --git a/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/IPrintable_DExpectTypeSsm.cpp new file mode 100644 index 00000000..14c20d53 --- /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: + * [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 */ diff --git a/xo-reader2/src/reader2/IPrintable_DParenSsm.cpp b/xo-reader2/src/reader2/IPrintable_DParenSsm.cpp new file mode 100644 index 00000000..7cda341b --- /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 "paren/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/IPrintable_DProgressSsm.cpp b/xo-reader2/src/reader2/IPrintable_DProgressSsm.cpp new file mode 100644 index 00000000..bd9dd7e8 --- /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: + * [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 */ 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/IPrintable_DToplevelSeqSsm.cpp b/xo-reader2/src/reader2/IPrintable_DToplevelSeqSsm.cpp new file mode 100644 index 00000000..7a958fa8 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DToplevelSeqSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DToplevelSeqSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --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_DToplevelSeqSsm.json5] +**/ + +#include "ssm/IPrintable_DToplevelSeqSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DToplevelSeqSsm::pretty(const DToplevelSeqSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DToplevelSeqSsm.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..e20b42f6 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -0,0 +1,108 @@ +/** @file ISyntaxStateMachine_Any.cpp + * + **/ + +#include "ssm/ISyntaxStateMachine_Any.hpp" +#include +#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_token(Opaque, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + +auto +ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void +{ + _fatal(); +} + +auto +ISyntaxStateMachine_Any::on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) -> void +{ + _fatal(); +} + +auto +ISyntaxStateMachine_Any::on_parsed_type(Opaque, obj, ParserStateMachine *) -> void +{ + _fatal(); +} + +auto +ISyntaxStateMachine_Any::on_parsed_formal(Opaque, const DUniqueString *, TypeDescr, ParserStateMachine *) -> void +{ + _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 +{ + _fatal(); +} + +auto +ISyntaxStateMachine_Any::on_parsed_expression(Opaque, obj, ParserStateMachine *) -> void +{ + _fatal(); +} + +auto +ISyntaxStateMachine_Any::on_parsed_expression_with_token(Opaque, obj, const Token &, ParserStateMachine *) -> void +{ + _fatal(); +} + +auto +ISyntaxStateMachine_Any::on_quoted_literal(Opaque, obj, ParserStateMachine *) -> void +{ + _fatal(); +} + +auto +ISyntaxStateMachine_Any::visit_gco_children(Opaque, VisitReason, obj) -> void +{ + _fatal(); +} + + +} /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_Any.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp new file mode 100644 index 00000000..0d6146e4 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectExprSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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_token(DExpectExprSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_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); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_type(DExpectExprSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression_with_token(DExpectExprSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::on_quoted_literal(DExpectExprSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectExprSsm::visit_gco_children(DExpectExprSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectExprSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..77bf5f55 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectFormalArglistSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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_type(DExpectFormalArglistSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + 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_token(DExpectFormalArglistSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_quoted_literal(DExpectFormalArglistSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::visit_gco_children(DExpectFormalArglistSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectFormalArglistSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQArraySsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQArraySsm.cpp new file mode 100644 index 00000000..2eb6f6b5 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQArraySsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectQArraySsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQArraySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQArraySsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectQArraySsm::ssm_type(const DExpectQArraySsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectQArraySsm::get_expect_str(const DExpectQArraySsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectQArraySsm::on_token(DExpectQArraySsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_symbol(DExpectQArraySsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_typedescr(DExpectQArraySsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_type(DExpectQArraySsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_formal(DExpectQArraySsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_formal_with_token(DExpectQArraySsm & 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_DExpectQArraySsm::on_parsed_formal_arglist(DExpectQArraySsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_expression(DExpectQArraySsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_expression_with_token(DExpectQArraySsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_quoted_literal(DExpectQArraySsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::visit_gco_children(DExpectQArraySsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectQArraySsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQListSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQListSsm.cpp new file mode 100644 index 00000000..b0f89a2d --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQListSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectQListSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQListSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQListSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectQListSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectQListSsm::ssm_type(const DExpectQListSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectQListSsm::get_expect_str(const DExpectQListSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectQListSsm::on_token(DExpectQListSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::on_parsed_symbol(DExpectQListSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::on_parsed_typedescr(DExpectQListSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::on_parsed_type(DExpectQListSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::on_parsed_formal(DExpectQListSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::on_parsed_formal_with_token(DExpectQListSsm & 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_DExpectQListSsm::on_parsed_formal_arglist(DExpectQListSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::on_parsed_expression(DExpectQListSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::on_parsed_expression_with_token(DExpectQListSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::on_quoted_literal(DExpectQListSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectQListSsm::visit_gco_children(DExpectQListSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectQListSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQLiteralSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQLiteralSsm.cpp new file mode 100644 index 00000000..69f17c50 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectQLiteralSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectQLiteralSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQLiteralSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQLiteralSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectQLiteralSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectQLiteralSsm::ssm_type(const DExpectQLiteralSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectQLiteralSsm::get_expect_str(const DExpectQLiteralSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_token(DExpectQLiteralSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_parsed_symbol(DExpectQLiteralSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_parsed_typedescr(DExpectQLiteralSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_parsed_type(DExpectQLiteralSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_parsed_formal(DExpectQLiteralSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_parsed_formal_with_token(DExpectQLiteralSsm & 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_DExpectQLiteralSsm::on_parsed_formal_arglist(DExpectQLiteralSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_parsed_expression(DExpectQLiteralSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_parsed_expression_with_token(DExpectQLiteralSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::on_quoted_literal(DExpectQLiteralSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectQLiteralSsm::visit_gco_children(DExpectQLiteralSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectQLiteralSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp new file mode 100644 index 00000000..ea2b7a0d --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectSymbolSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_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); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_type(DExpectSymbolSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression_with_token(DExpectSymbolSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_quoted_literal(DExpectSymbolSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::visit_gco_children(DExpectSymbolSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectSymbolSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp new file mode 100644 index 00000000..e107f011 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectTypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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_token(DExpectTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_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); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_type(DExpectTypeSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression_with_token(DExpectTypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_quoted_literal(DExpectTypeSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectTypeSsm::visit_gco_children(DExpectTypeSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectTypeSsm.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..f67e77c8 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DParenSsm.cpp @@ -0,0 +1,89 @@ +/** @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 "paren/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_type(DParenSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + 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); + } + auto + ISyntaxStateMachine_DParenSsm::on_quoted_literal(DParenSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DParenSsm::visit_gco_children(DParenSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DParenSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp new file mode 100644 index 00000000..5ad51fe2 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DProgressSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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_token(DProgressSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_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); + } + auto + ISyntaxStateMachine_DProgressSsm::on_parsed_type(DProgressSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + auto + ISyntaxStateMachine_DProgressSsm::on_parsed_expression(DProgressSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_parsed_expression_with_token(DProgressSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::on_quoted_literal(DProgressSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DProgressSsm::visit_gco_children(DProgressSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DProgressSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp new file mode 100644 index 00000000..8dff7fa0 --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DSequenceSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DSequenceSsm.cpp + * + * 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_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DSequenceSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DSequenceSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DSequenceSsm::ssm_type(const DSequenceSsm & self) noexcept -> 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_type(DSequenceSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + 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_token(DSequenceSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DSequenceSsm::on_quoted_literal(DSequenceSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DSequenceSsm::visit_gco_children(DSequenceSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DSequenceSsm.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..ba17482f --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DToplevelSeqSsm.cpp @@ -0,0 +1,89 @@ +/** @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_type(DToplevelSeqSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + 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); + } + auto + ISyntaxStateMachine_DToplevelSeqSsm::on_quoted_literal(DToplevelSeqSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DToplevelSeqSsm::visit_gco_children(DToplevelSeqSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DToplevelSeqSsm.cpp */ diff --git a/xo-reader2/src/reader2/ParserResult.cpp b/xo-reader2/src/reader2/ParserResult.cpp new file mode 100644 index 00000000..bb3d4034 --- /dev/null +++ b/xo-reader2/src/reader2/ParserResult.cpp @@ -0,0 +1,120 @@ +/** @file ParserResult.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ParserResult.hpp" +#include +#include +#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, + const DString * error_description) + : result_type_{type}, + result_expr_{expr}, + error_src_fn_{error_src_fn}, + 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) + { + return ParserResult(parser_result_type::error, + obj(), + 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; + } + + void + ParserResult::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + // {result_type_, error_src_fn_}: pod, ignore + + gc.visit_poly_child(reason, &result_expr_); + gc.visit_child(reason, &error_description_); + } + } /*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..83d21df1 --- /dev/null +++ b/xo-reader2/src/reader2/ParserStack.cpp @@ -0,0 +1,108 @@ +/** @file ParserStack.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ParserStack.hpp" +#include "SyntaxStateMachine.hpp" +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::facet::typeseq; + + namespace scm { + ParserStack::ParserStack(DArena::Checkpoint ckp, + obj ssm, + ParserStack * parent) + : ckp_{ckp}, ssm_{ssm}, parent_{parent} + {} + + ParserStack * + ParserStack::push(ParserStack * stack, + DArena::Checkpoint ckp, + DArena & mm, + obj ssm) + + { + //DArena::Checkpoint ckp = mm.checkpoint(); // wrong, must precede allocation of ssm + + void * mem = mm.alloc(typeseq::id(), + sizeof(ParserStack)); + + return new (mem) ParserStack(ckp, ssm, stack); + } + + ParserStack * + ParserStack::pop(ParserStack * stack, + DArena & mm) + { + assert(stack); + + mm.restore(stack->ckp()); + + return stack->parent(); + } + + void + ParserStack::print(std::ostream & os) const + { + os << ""; + os << xtag("ssm", "*placeholder*"); + os << xtag("parent", "*placeholder*"); + os << ">"; + } + + bool + ParserStack::pretty(const ppindentinfo & ppii) const + { + auto * pps = ppii.pps(); + + /* always use multiple lines */ + + if (ppii.upto()) + return false; + + pps->write(" (frame->top())); + assert(ssm.data()); + + pps->newline_pretty_tag(ppii.ci1(), buf, ssm); + + ++i_frame; + frame = frame->parent_; + } + + pps->write(">"); + + return false; + } + + void + ParserStack::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + + for (ParserStack * target = this; target; target = target->parent_) { + // ParserStack::ckp: skip, POD + + if (target->ssm_) + target->ssm_.visit_gco_children(reason, gc); + } + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ParserStack.cpp */ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp new file mode 100644 index 00000000..71028ebe --- /dev/null +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -0,0 +1,942 @@ +/** @file ParserStateMachine.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "ParserStateMachine.hpp" +#include "ParserStack.hpp" +#include "SyntaxStateMachine.hpp" +#include "ToplevelSeqSsm.hpp" +#include "DefineSsm.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xo { + using xo::mm::ACollector; + using xo::mm::AAllocator; + using xo::mm::AGCObject; + using xo::print::APrintable; + using xo::reflect::TypeDescr; + using xo::facet::FacetRegistry; + using xo::facet::with_facet; + + namespace scm { + namespace { + /** Create global environment and populate with builtin primitives. + * Get memory from @p mm, with symbol names in @p stringtable. + * Stash symbol names in @p global_symtab, which coordinates with + * new global environment. + * @p pm_install_flags controls which primitives to install + **/ + obj + global_env_setup(StringTable & stringtable, + obj mm, + DGlobalSymtab * global_symtab, + InstallFlags pm_install_flags) + { + scope log(XO_DEBUG(false)); + + DGlobalEnv * env = DGlobalEnv::_make(mm, + global_symtab); + + // FUDGING this for now + obj err_mm; + + DSimpleRcx rcx(mm, err_mm, &stringtable); + + InstallSink sink = ([env, rcx, &log] + (std::string_view name, + TypeDescr fn_td, + obj pm, + InstallFlags flags) + { + (void)flags; + + obj pm_gco = pm.to_facet(); + + const DUniqueString * sym + = rcx.stringtable()->intern(name); + + log && log("upsert", xtag("sym", std::string_view(*sym))); + + env->_upsert_value(rcx.allocator(), + sym, + fn_td, + pm_gco); + + return true; + }); + + PrimitiveRegistry::instance() + .install_primitives(with_facet::mkobj(&rcx), + sink, + pm_install_flags); + + return obj(env); + } + } + + ParserStateMachine::ParserStateMachine(const ArenaConfig & config, + const ArenaHashMapConfig & symtab_var_config, + const ArenaHashMapConfig & symtab_type_config, + size_type max_stringtable_capacity, + InstallFlags pm_install_flags, + obj expr_alloc, + obj aux_alloc) + : stringtable_{max_stringtable_capacity}, + parser_alloc_{DArena::map(config)}, + expr_alloc_{expr_alloc}, + aux_alloc_{aux_alloc}, + global_symtab_{DGlobalSymtab::make(expr_alloc, aux_alloc, + symtab_var_config, + symtab_type_config)}, + global_env_{global_env_setup(stringtable_, + expr_alloc_, + global_symtab_.data(), + pm_install_flags)}, + debug_flag_{config.debug_flag_} + { + // see xo-numeric/ {SetupNumeric.cpp, NumericPrimitives.cpp} + // for setup of {_mul, _div, _sub, ...} + // + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_multiply_pm_name); + assert(name); + this->multiply_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_divide_pm_name); + assert(name); + this->divide_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_add_pm_name); + assert(name); + this->add_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_sub_pm_name); + assert(name); + this->subtract_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_cmpeq_pm_name); + assert(name); + this->cmpeq_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_cmpne_pm_name); + assert(name); + this->cmpne_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_cmplt_pm_name); + assert(name); + this->cmplt_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_cmple_pm_name); + assert(name); + this->cmple_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_cmpgt_pm_name); + assert(name); + this->cmpgt_binding_ = global_symtab_->lookup_binding(name); + } + + { + const DUniqueString * name + = stringtable_.lookup(NumericPrimitives::c_cmpge_pm_name); + assert(name); + this->cmpge_binding_ = global_symtab_->lookup_binding(name); + } + } + + ParserStateMachine::~ParserStateMachine() + { + obj gc = expr_alloc_.try_to_facet(); + + if (gc) { + scope log(XO_DEBUG(true), "remove_gc_root not implemented"); + + gc.remove_gc_root(&global_symtab_); + gc.remove_gc_root(&local_symtab_); + gc.remove_gc_root(&global_env_); + } + } + + obj + ParserStateMachine::multiply_pm() const + { + obj retval = global_env_->lookup_value(multiply_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::divide_pm() const + { + obj retval = global_env_->lookup_value(divide_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::add_pm() const + { + obj retval = global_env_->lookup_value(add_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::subtract_pm() const + { + obj retval = global_env_->lookup_value(subtract_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::cmpeq_pm() const + { + obj retval = global_env_->lookup_value(cmpeq_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::cmpne_pm() const + { + obj retval = global_env_->lookup_value(cmpne_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::cmplt_pm() const + { + obj retval = global_env_->lookup_value(cmplt_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::cmple_pm() const + { + obj retval = global_env_->lookup_value(cmple_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::cmpgt_pm() const + { + obj retval = global_env_->lookup_value(cmpgt_binding_); + assert(retval); + + return retval; + } + + obj + ParserStateMachine::cmpge_pm() const + { + obj retval = global_env_->lookup_value(cmpge_binding_); + assert(retval); + + return retval; + } + + bool + ParserStateMachine::is_at_toplevel() const noexcept + { + /* top-level always 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 + + ParserStack * s = stack_; + + if (s) { + auto top = obj::from(s->top()); + + return !top; + } else { + return false; + } + } + + obj + ParserStateMachine::top_ssm() const + { + return this->stack_->top(); + } + + void + ParserStateMachine::visit_pools(const MemorySizeVisitor & visitor) const + { + 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 + } + + void + ParserStateMachine::establish_toplevel_ssm(obj ssm) + { + scope log(XO_DEBUG(debug_flag_)); + + assert(stack_ == nullptr); + + 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(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_, ckp, parser_alloc_, ssm); + } + + void + ParserStateMachine::pop_ssm() + { + scope log(XO_DEBUG(debug_flag_)); + + assert(this->stack_); + + this->stack_ = ParserStack::pop(stack_, parser_alloc_); + } + + const DUniqueString * + ParserStateMachine::intern_string(std::string_view str) + { + return stringtable_.intern(str); + } + + const DUniqueString * + ParserStateMachine::gensym(std::string_view str) + { + return stringtable_.gensym(str); + } + + DVarRef * + ParserStateMachine::lookup_varref(std::string_view symbolname) + { + 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 + // 3. move lookup_varref implementation there. + // + + if (local_symtab_) { + DLocalSymtab * symtab = local_symtab_.data(); + + // 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(); + } + } + + DVariable * vardef = global_symtab_->lookup_variable(ustr); + + if (vardef) { + return DVarRef::make(expr_alloc_, + vardef, + 0 /*link_count -- n/a for globals*/); + + } + + // symbol not found + return nullptr; + } + + void + ParserStateMachine::push_local_symtab(DLocalSymtab * symtab) + { + this->local_symtab_ = obj(symtab); + } + + void + ParserStateMachine::pop_local_symtab() + { + assert(local_symtab_); + + this->local_symtab_ = obj(local_symtab_->parent()); + } + + void + ParserStateMachine::upsert_var(DVariable * var) + { + assert(global_symtab_); + + global_symtab_->upsert_variable(this->expr_alloc(), var); + } + + 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 + 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_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_parsed_type(obj type) + { + scope log(XO_DEBUG(debug_flag_)); + + assert(stack_); + + this->stack_->top().on_parsed_type(type, 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_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) + { + 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) + { + 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_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_with_token(expr, tk, this); + } + + void + ParserStateMachine::on_quoted_literal(obj lit) + { + this->top_ssm().on_quoted_literal(lit, this); + } + + 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!") + )); + } + + stack_->top().on_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) + { + if (result_.is_error()) { + /* in case one error triggers another, remmber just the first one */ + } else { + 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")); + + assert(expr_alloc_); + + auto errmsg = DString::from_view(expr_alloc_, + std::string_view(errmsg_string)); + + 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); + } + + 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); + } + + void + ParserStateMachine::illegal_input_on_type(std::string_view ssm_name, + obj 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 type for parsing state", + xtag("type", type), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_input_on_type")); + + 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(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 formal", + 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_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_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, + 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")); + + assert(expr_alloc_); + + auto errmsg = DString::from_str(expr_alloc_, errmsg_string); + + 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 expr_pr = expr.to_facet(); + //= 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("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_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::illegal_quoted_literal(std::string_view ssm_name, + obj lit, + std::string_view expect_str) + { + obj lit_pr + = FacetRegistry::instance().variant(lit); + + /** 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 quoted literal", + xtag("lit", lit_pr), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_quoted_literal")); + + 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) + { + 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); + } + + // ----- gc support ----- + +#ifdef OBSOLETE + void + ParserStateMachine::shallow_copy(obj gc) noexcept + { + (void)gc; + + assert(false); + } +#endif + + void + ParserStateMachine::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + //scope log(XO_DEBUG(true)); + + assert(!stringtable_.is_gc_eligible()); + assert(!parser_alloc_.is_gc_eligible()); + + //log && log("forward stack_", xtag("addr", stack_)); + if (stack_) { + stack_->visit_gco_children(reason, gc); + } + + // static_assert(!expr_alloc_.is_gc_eligible()); + // static_assert(!aux_alloc_.is_gc_eligible()); + + //log && log("global_symtab_", xtag("addr", global_symtab_.data())); + gc.visit_child(reason, &global_symtab_); + + //log && log("local_symtab_", xtag("addr", local_symtab_.data())); + gc.visit_child(reason, &local_symtab_); + + //log && log("global_env_", xtag("addr", global_env_.data())); + gc.visit_child(reason, &global_env_); + + //log && log("result_"); + result_.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ParserStateMachine.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..168f562a --- /dev/null +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -0,0 +1,224 @@ +/** @file SchematikaReader.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "SchematikaReader.hpp" + +namespace xo { + using xo::mm::MemorySizeInfo; + + namespace scm { + void + ReaderResult::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + gc.visit_poly_child(reason, &expr_); + } + + // ----- SchematikaReader ----- + + SchematikaReader::SchematikaReader(const ReaderConfig & config, + obj expr_alloc, + obj aux_alloc) + : tokenizer_{config.tk_buffer_config_, + config.tk_debug_flag_}, + parser_{ParserConfig(config.parser_arena_config_, + config.symtab_var_config_, + config.symtab_types_config_, + config.max_stringtable_cap_, + config.pm_install_flags_, + config.parser_debug_flag_), + expr_alloc, + aux_alloc}, + debug_flag_{config.reader_debug_flag_} + { + } + + DGlobalSymtab * + SchematikaReader::global_symtab() const noexcept + { + return parser_.global_symtab(); + } + + DGlobalEnv * + SchematikaReader::global_env() const noexcept + { + return parser_.global_env(); + } + + StringTable * + SchematikaReader::stringtable() noexcept + { + return parser_.stringtable(); + } + + void + SchematikaReader::visit_pools(const MemorySizeVisitor & visitor) const + { + tokenizer_.visit_pools(visitor); + parser_.visit_pools(visitor); + } + + bool + SchematikaReader::is_at_toplevel() const noexcept + { + return parser_.is_at_toplevel(); + } + + void + SchematikaReader::begin_interactive_session() + { + parser_.begin_interactive_session(); + } + + void + SchematikaReader::begin_batch_session() + { + parser_.begin_batch_session(); + } + + // TODO: + // Schematika::end_interactive_session() + + const DUniqueString * + SchematikaReader::intern_string(std::string_view str) + { + return parser_.intern_string(str); + } + + 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); + + 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 + { .expr_ = obj(), + .remaining_input_ = rem_input, + .tk_error_ = std::move(error) + }; + + 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_.on_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(), + .remaining_input_ = rem_input, + .tk_error_ = std::move(error) }; + + assert(presult.error_description()); + + // carefully created error description, maybe + 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_; + } + } + + input = rem_input; + } + } + + this->result_ = ReaderResult(); + + return this->result_; + } + + void + SchematikaReader::reset_result() + { + this->parser_.reset_result(); + } + + void + SchematikaReader::reset_to_idle_toplevel() + { + this->tokenizer_.discard_current_line(); + this->parser_.reset_to_idle_toplevel(); + } + + void + SchematikaReader::visit_gco_children(VisitReason reason, + obj gc) noexcept + { + // tokenizer doesn't contain any gc-aware pointers. + + parser_.visit_gco_children(reason, gc); + result_.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end SchematikaReader.cpp */ diff --git a/xo-reader2/src/reader2/SetupReader2.cpp b/xo-reader2/src/reader2/SetupReader2.cpp new file mode 100644 index 00000000..3dca4ac8 --- /dev/null +++ b/xo-reader2/src/reader2/SetupReader2.cpp @@ -0,0 +1,164 @@ +/** @file SetupReader2.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "SetupReader2.hpp" + +#include "SchematikaParser.hpp" +#include "ToplevelSeqSsm.hpp" +#include "DefineSsm.hpp" +#include "DeftypeSsm.hpp" +#include "LambdaSsm.hpp" +#include "IfElseSsm.hpp" +#include "ApplySsm.hpp" +#include "SequenceSsm.hpp" +#include "ParenSsm.hpp" +#include "QuoteSsm.hpp" +#include "ProgressSsm.hpp" +#include "SyntaxStateMachine.hpp" +#include "ExpectFormalArglistSsm.hpp" +#include "ExpectFormalArgSsm.hpp" +#include "ExpectSymbolSsm.hpp" +#include "ExpectTypeSsm.hpp" +#include "ExpectListTypeSsm.hpp" +#include "ExpectExprSsm.hpp" +#include "ExpectQLiteralSsm.hpp" +#include "ExpectQListSsm.hpp" +#include "ExpectQDictSsm.hpp" +#include "ExpectQArraySsm.hpp" + +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::facet::FacetRegistry; + using xo::facet::TypeRegistry; + using xo::facet::typeseq; + using xo::facet::impl_for; + + namespace scm { + bool + SetupReader2::register_facets() + { + scope log(XO_DEBUG(true)); + + // SchematikParser + + FacetRegistry::register_impl(); + + // GlobalEnv + + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + // SyntaxStateMachine + + 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(); + 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(); + + 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(); + + // misc types showing up in parser stack arena + TypeRegistry::register_type(); + + log && log(xtag("DSchematikaParser.tseq", typeseq::id())); + + log && log(xtag("DGlobalEnv.tseq", typeseq::id())); + log && log(xtag("DToplevelSeqSsm.tseq", typeseq::id())); + log && log(xtag("DDefineSsm.tseq", typeseq::id())); + log && log(xtag("DDeftypeSsm.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("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())); + log && log(xtag("DExpectQLiteralSsm.tseq", typeseq::id())); + log && log(xtag("DExpectQListSsm.tseq", typeseq::id())); + log && log(xtag("DExpectQDictSsm.tseq", typeseq::id())); + log && log(xtag("DExpectQArraySsm.tseq", typeseq::id())); + + log && log(xtag("DProgressSsm.tseq", typeseq::id())); + log && log(xtag("DParenSsm.tseq", typeseq::id())); + log && log(xtag("DQuoteSsm.tseq", typeseq::id())); + log && log(xtag("ASyntaxStateMachine.tseq", typeseq::id())); + + return true; + } + + bool + SetupReader2::register_types(obj gc) + { + scope log(XO_DEBUG(true)); + + bool ok = true; + + ok &= gc.install_type(impl_for()); + + return ok; + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end SetupReader2.cpp */ diff --git a/xo-reader2/src/reader2/facet/IGCObject_DGlobalEnv.cpp b/xo-reader2/src/reader2/facet/IGCObject_DGlobalEnv.cpp new file mode 100644 index 00000000..72c9b065 --- /dev/null +++ b/xo-reader2/src/reader2/facet/IGCObject_DGlobalEnv.cpp @@ -0,0 +1,32 @@ +/** @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::gco_shallow_move(DGlobalEnv & self, obj gc) noexcept -> Opaque + { + return self.gco_shallow_move(gc); + } + auto + IGCObject_DGlobalEnv::visit_gco_children(DGlobalEnv & self, VisitReason reason, obj fn) noexcept -> void + { + self.visit_gco_children(reason, fn); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DGlobalEnv.cpp */ diff --git a/xo-reader2/src/reader2/facet/IGCObject_DSchematikaParser.cpp b/xo-reader2/src/reader2/facet/IGCObject_DSchematikaParser.cpp new file mode 100644 index 00000000..7586fc25 --- /dev/null +++ b/xo-reader2/src/reader2/facet/IGCObject_DSchematikaParser.cpp @@ -0,0 +1,32 @@ +/** @file IGCObject_DSchematikaParser.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DSchematikaParser.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DSchematikaParser.json5] +**/ + +#include "parser/IGCObject_DSchematikaParser.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DSchematikaParser::gco_shallow_move(DSchematikaParser & self, obj gc) noexcept -> Opaque + { + return self.gco_shallow_move(gc); + } + auto + IGCObject_DSchematikaParser::visit_gco_children(DSchematikaParser & self, VisitReason reason, obj fn) noexcept -> void + { + self.visit_gco_children(reason, fn); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DSchematikaParser.cpp */ diff --git a/xo-reader2/src/reader2/facet/IPrintable_DApplySsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DApplySsm.cpp new file mode 100644 index 00000000..20e40bfc --- /dev/null +++ b/xo-reader2/src/reader2/facet/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 "apply/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/facet/IPrintable_DDefineSsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DDefineSsm.cpp new file mode 100644 index 00000000..c63eaf7f --- /dev/null +++ b/xo-reader2/src/reader2/facet/IPrintable_DDefineSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DDefineSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 "define/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 */ diff --git a/xo-reader2/src/reader2/facet/IPrintable_DDeftypeSsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DDeftypeSsm.cpp new file mode 100644 index 00000000..eb7351d2 --- /dev/null +++ b/xo-reader2/src/reader2/facet/IPrintable_DDeftypeSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DDeftypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDeftypeSsm.json5] +**/ + +#include "deftype/IPrintable_DDeftypeSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DDeftypeSsm::pretty(const DDeftypeSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DDeftypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/IPrintable_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DExpectFormalArgSsm.cpp new file mode 100644 index 00000000..bdcf6a61 --- /dev/null +++ b/xo-reader2/src/reader2/facet/IPrintable_DExpectFormalArgSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectFormalArgSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 "expect_formal_arg/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 */ diff --git a/xo-reader2/src/reader2/facet/IPrintable_DExpectListTypeSsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DExpectListTypeSsm.cpp new file mode 100644 index 00000000..8f90fad5 --- /dev/null +++ b/xo-reader2/src/reader2/facet/IPrintable_DExpectListTypeSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectListTypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectListTypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectListTypeSsm.json5] +**/ + +#include "expect_listtype/IPrintable_DExpectListTypeSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectListTypeSsm::pretty(const DExpectListTypeSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectListTypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/IPrintable_DExpectQDictSsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DExpectQDictSsm.cpp new file mode 100644 index 00000000..ae6f4423 --- /dev/null +++ b/xo-reader2/src/reader2/facet/IPrintable_DExpectQDictSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectQDictSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQDictSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQDictSsm.json5] +**/ + +#include "expect_qdict/IPrintable_DExpectQDictSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectQDictSsm::pretty(const DExpectQDictSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectQDictSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/IPrintable_DGlobalEnv.cpp b/xo-reader2/src/reader2/facet/IPrintable_DGlobalEnv.cpp new file mode 100644 index 00000000..84fc561c --- /dev/null +++ b/xo-reader2/src/reader2/facet/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-reader2/src/reader2/facet/IPrintable_DIfElseSsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DIfElseSsm.cpp new file mode 100644 index 00000000..50a98996 --- /dev/null +++ b/xo-reader2/src/reader2/facet/IPrintable_DIfElseSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DIfElseSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 "ifelse/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 */ diff --git a/xo-reader2/src/reader2/facet/IPrintable_DLambdaSsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DLambdaSsm.cpp new file mode 100644 index 00000000..bd1437bd --- /dev/null +++ b/xo-reader2/src/reader2/facet/IPrintable_DLambdaSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DLambdaSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 "lambda/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 */ diff --git a/xo-reader2/src/reader2/facet/IPrintable_DQuoteSsm.cpp b/xo-reader2/src/reader2/facet/IPrintable_DQuoteSsm.cpp new file mode 100644 index 00000000..b190ec52 --- /dev/null +++ b/xo-reader2/src/reader2/facet/IPrintable_DQuoteSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DQuoteSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DQuoteSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DQuoteSsm.json5] +**/ + +#include "quote/IPrintable_DQuoteSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DQuoteSsm::pretty(const DQuoteSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DQuoteSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DApplySsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DApplySsm.cpp new file mode 100644 index 00000000..baba1c7f --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DApplySsm.cpp @@ -0,0 +1,89 @@ +/** @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 "apply/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_type(DApplySsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + 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); + } + auto + ISyntaxStateMachine_DApplySsm::on_quoted_literal(DApplySsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::visit_gco_children(DApplySsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DApplySsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DDefineSsm.cpp new file mode 100644 index 00000000..5fe37536 --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DDefineSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DDefineSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 "define/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_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_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); + } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_type(DDefineSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_expression(DDefineSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_expression_with_token(DDefineSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DDefineSsm::on_quoted_literal(DDefineSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DDefineSsm::visit_gco_children(DDefineSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DDefineSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DDeftypeSsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DDeftypeSsm.cpp new file mode 100644 index 00000000..a88b1005 --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DDeftypeSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DDeftypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DDeftypeSsm.json5] +**/ + +#include "deftype/ISyntaxStateMachine_DDeftypeSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DDeftypeSsm::ssm_type(const DDeftypeSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DDeftypeSsm::get_expect_str(const DDeftypeSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DDeftypeSsm::on_token(DDeftypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_symbol(DDeftypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_typedescr(DDeftypeSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_type(DDeftypeSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_formal(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_formal_with_token(DDeftypeSsm & 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_DDeftypeSsm::on_parsed_formal_arglist(DDeftypeSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_expression(DDeftypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_expression_with_token(DDeftypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_quoted_literal(DDeftypeSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::visit_gco_children(DDeftypeSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DDeftypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectFormalArgSsm.cpp new file mode 100644 index 00000000..c0adc804 --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectFormalArgSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectFormalArgSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 "expect_formal_arg/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_type(DExpectFormalArgSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + 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_token(DExpectFormalArgSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArgSsm::on_quoted_literal(DExpectFormalArgSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArgSsm::visit_gco_children(DExpectFormalArgSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectFormalArgSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectListTypeSsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectListTypeSsm.cpp new file mode 100644 index 00000000..1306e061 --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectListTypeSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectListTypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectListTypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectListTypeSsm.json5] +**/ + +#include "expect_listtype/ISyntaxStateMachine_DExpectListTypeSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectListTypeSsm::ssm_type(const DExpectListTypeSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectListTypeSsm::get_expect_str(const DExpectListTypeSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_token(DExpectListTypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_parsed_symbol(DExpectListTypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_parsed_typedescr(DExpectListTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_parsed_type(DExpectListTypeSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_parsed_formal(DExpectListTypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_parsed_formal_with_token(DExpectListTypeSsm & 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_DExpectListTypeSsm::on_parsed_formal_arglist(DExpectListTypeSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_parsed_expression(DExpectListTypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_parsed_expression_with_token(DExpectListTypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::on_quoted_literal(DExpectListTypeSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectListTypeSsm::visit_gco_children(DExpectListTypeSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectListTypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectQDictSsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectQDictSsm.cpp new file mode 100644 index 00000000..5cc75b00 --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DExpectQDictSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DExpectQDictSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQDictSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQDictSsm.json5] +**/ + +#include "expect_qdict/ISyntaxStateMachine_DExpectQDictSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectQDictSsm::ssm_type(const DExpectQDictSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectQDictSsm::get_expect_str(const DExpectQDictSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectQDictSsm::on_token(DExpectQDictSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::on_parsed_symbol(DExpectQDictSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::on_parsed_typedescr(DExpectQDictSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::on_parsed_type(DExpectQDictSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::on_parsed_formal(DExpectQDictSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::on_parsed_formal_with_token(DExpectQDictSsm & 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_DExpectQDictSsm::on_parsed_formal_arglist(DExpectQDictSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::on_parsed_expression(DExpectQDictSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::on_parsed_expression_with_token(DExpectQDictSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::on_quoted_literal(DExpectQDictSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DExpectQDictSsm::visit_gco_children(DExpectQDictSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectQDictSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DIfElseSsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DIfElseSsm.cpp new file mode 100644 index 00000000..37a20363 --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DIfElseSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DIfElseSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 "ifelse/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_type(DIfElseSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + 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_token(DIfElseSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DIfElseSsm::on_quoted_literal(DIfElseSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DIfElseSsm::visit_gco_children(DIfElseSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DIfElseSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DLambdaSsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DLambdaSsm.cpp new file mode 100644 index 00000000..08754857 --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DLambdaSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DLambdaSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [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 "lambda/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_type(DLambdaSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, 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_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); + } + 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_token(DLambdaSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DLambdaSsm::on_quoted_literal(DLambdaSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DLambdaSsm::visit_gco_children(DLambdaSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DLambdaSsm.cpp */ diff --git a/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DQuoteSsm.cpp b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DQuoteSsm.cpp new file mode 100644 index 00000000..b4ee1261 --- /dev/null +++ b/xo-reader2/src/reader2/facet/ISyntaxStateMachine_DQuoteSsm.cpp @@ -0,0 +1,89 @@ +/** @file ISyntaxStateMachine_DQuoteSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DQuoteSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DQuoteSsm.json5] +**/ + +#include "quote/ISyntaxStateMachine_DQuoteSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DQuoteSsm::ssm_type(const DQuoteSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DQuoteSsm::get_expect_str(const DQuoteSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DQuoteSsm::on_token(DQuoteSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::on_parsed_symbol(DQuoteSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::on_parsed_typedescr(DQuoteSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::on_parsed_type(DQuoteSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::on_parsed_formal(DQuoteSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::on_parsed_formal_with_token(DQuoteSsm & 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_DQuoteSsm::on_parsed_formal_arglist(DQuoteSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::on_parsed_expression(DQuoteSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::on_parsed_expression_with_token(DQuoteSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::on_quoted_literal(DQuoteSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + auto + ISyntaxStateMachine_DQuoteSsm::visit_gco_children(DQuoteSsm & self, VisitReason reason, obj gc) -> void + { + self.visit_gco_children(reason, gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DQuoteSsm.cpp */ diff --git a/xo-reader2/src/reader2/init_reader2.cpp b/xo-reader2/src/reader2/init_reader2.cpp new file mode 100644 index 00000000..46b4de00 --- /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 "SetupReader2.hpp" + +#include +#include +#include + +namespace xo { + using xo::scm::SetupReader2; + using xo::mm::CollectorTypeRegistry; + + void + InitSubsys::init() + { + SetupReader2::register_facets(); + + CollectorTypeRegistry::instance().register_types(&SetupReader2::register_types); + } + + InitEvidence + InitSubsys::require() + { + InitEvidence retval; + + /* direct subsystem deps for xo-reader2/ */ + retval ^= InitSubsys::require(); + 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/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp new file mode 100644 index 00000000..8ca07af2 --- /dev/null +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -0,0 +1,66 @@ +/** @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::defexpr: + return "defexpr"; + case syntaxstatetype::deftypeexpr: + return "deftypeexpr"; + case syntaxstatetype::lambdaexpr: + return "lambdaexpr"; + case syntaxstatetype::ifelseexpr: + return "ifelseexpr"; + case syntaxstatetype::sequence: + return "sequence"; + case syntaxstatetype::apply: + return "apply"; + case syntaxstatetype::progress: + return "progress"; + case syntaxstatetype::paren: + return "paren"; + case syntaxstatetype::quote: + return "quote"; + case syntaxstatetype::expect_toplevel_expression_sequence: + 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: + return "expect-type"; + case syntaxstatetype::expect_listtype: + return "expect-listtype"; + case syntaxstatetype::expect_rhs_expression: + return "expect-rhs-expression"; + case syntaxstatetype::expect_qliteral: + return "expect-qliteral"; + case syntaxstatetype::expect_qlist: + return "expect-qlist"; + case syntaxstatetype::expect_qarray: + return "expect-qarray"; + case syntaxstatetype::expect_qdict: + return "expect-qdict"; + case syntaxstatetype::N: + break; + } + + return "syntaxstatetype?"; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end syntaxstatetype.cpp */ 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..d2234b6f --- /dev/null +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -0,0 +1,2075 @@ +/** @file SchematikaParser.test.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xo { + using xo::scm::ParserConfig; + using xo::scm::DSchematikaParser; + + using xo::scm::AExpression; + using xo::scm::DDefineExpr; + using xo::scm::DIfElseExpr; + using xo::scm::DApplyExpr; + using xo::scm::DVarRef; + using xo::scm::DConstant; + + using xo::scm::Token; + using xo::scm::DPrimitive_gco_2_gco_gco; + using xo::scm::DList; + using xo::scm::DString; + using xo::scm::DFloat; + using xo::scm::DInteger; + + using xo::facet::FacetRegistry; + + using xo::mm::ArenaConfig; + using xo::mm::AAllocator; + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::mm::DArena; + using xo::mm::DX1Collector; + using xo::mm::Generation; + using xo::mm::X1CollectorConfig; + using xo::mm::CollectorTypeRegistry; + using xo::mm::MemorySizeInfo; + + static InitEvidence s_init = (InitSubsys::require() + ^ InitSubsys::require()); + + namespace ut { + struct ParserFixture { + ParserFixture(const std::string & testname, + bool gc_flag, + bool debug_flag) + { + this->aux_arena_ + = std::move(DArena(ArenaConfig() + .with_name(testname) + .with_size(64 * 1024) + .with_store_header_flag(true))); + obj aux_mm(&aux_arena_); + + if (gc_flag) { + X1CollectorConfig x1_config + = (X1CollectorConfig() + .with_name("gc") + .with_size(32 * 1024) + .with_debug_flag(debug_flag) + .with_sanitize_flag(true)); + + dp expr_x1_dp + = dp::make(aux_mm, x1_config); + + this->expr_mm_ + = obj(expr_x1_dp.release()); + + obj gc = expr_mm_.to_facet(); + + CollectorTypeRegistry::instance().install_types(gc); + } else { + ArenaConfig arena_config + = (ArenaConfig().with_name("expr") + .with_size(16 * 1024) + .with_store_header_flag(true)); + + dp expr_arena_dp + = dp::make(aux_mm, arena_config); + + this->expr_mm_ + = obj(expr_arena_dp.release()); + + } + + ParserConfig cfg; + { + cfg.parser_arena_config_.size_ = 16 * 1024; + /* editor bait: symbol table */ + cfg.symtab_var_config_.hint_max_capacity_ = 128; + cfg.symtab_types_config_.hint_max_capacity_ = 64; + cfg.max_stringtable_capacity_ = 512; + cfg.debug_flag_ = false; + } + + this->parser_ + = DSchematikaParser::make(aux_mm, cfg, expr_mm_, aux_mm); + this->parser_gco_ = parser_; + + if (gc_flag) { + obj gc = expr_mm_.to_facet(); + + if (gc) { + gc.add_gc_root_poly(&parser_gco_); + } + + // Also add parser itself as a global. + // SchematikaParser is a snowflake GCObject: + // it only supports the AGCObject forward_children() method + // + } + + this->gc_flag_ = gc_flag; + this->debug_flag_ = debug_flag; + } + + ParserFixture(const ParserFixture & other) = delete; + ParserFixture(const ParserFixture && other) = delete; + + ~ParserFixture() { + // destroy allocator + expr_mm_._drop(); + // destroy parser (reminder: was allocated from aux_arena_) + parser_._drop(); + } + + bool log_memory_layout(scope * p_log) { + using xo::facet::TypeRegistry; + using xo::mm::MemorySizeDetail; + + auto visitor = [this, p_log](const MemorySizeInfo & info) { + *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_)); + + if (*p_log && debug_mm_detail_ && 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; + + char buf[40]; + snprintf(buf, sizeof(buf), "[%lu]", i); + + (*p_log)(buf, + 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); + FacetRegistry::instance().visit_pools(visitor); + TypeRegistry::instance().visit_pools(visitor); + expr_mm_.visit_pools(visitor); + parser_->visit_pools(visitor); + + return true; + } + + DArena aux_arena_; + /** allocator for parsed schematika expressions **/ + obj expr_mm_; + obj parser_; + /** parser_ as variant gco, to sastify Collector.add_gc_root_poly() **/ + obj parser_gco_; + bool gc_flag_ = false; + bool debug_flag_ = false; + bool debug_mm_detail_ = false; + }; + + void + utest_tokenizer_loop(ParserFixture * fixture, + std::vector & tk_v, + bool debug_flag) + { + scope log(XO_DEBUG(debug_flag)); + + obj expr_gc + = fixture->expr_mm_.try_to_facet(); + + 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 = fixture->parser_->on_token(tk); + + log && log("after token", + xtag("i_tk", i_tk), xtag("tk", tk)); + log && log(xtag("parser", fixture->parser_.data())); + log && log(xtag("result", result)); + + if (i_tk + 1 < n_tk) { + REQUIRE(fixture->parser_->has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } else { + /* last token in tk_v[] */ + + REQUIRE(fixture->parser_->has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(result.is_expression()); + REQUIRE(result.result_expr()); + } + + ++i_tk; + + // for this test: invoke full collection after each token + if (fixture->gc_flag_) { + REQUIRE(expr_gc); + + expr_gc.request_gc(Generation(2)); + } + } + } + + TEST_CASE("SchematikaParser-ctor", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ParserFixture fixture(testname, false /*!gc*/, c_debug_flag); + auto parser = fixture.parser_; + + 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]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ParserFixture fixture(testname, false /*!gc*/, 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]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ParserFixture fixture(testname, false /*!gc*/, 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); + } + + namespace { + void + test_batch_def(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_batch_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(fixture, tk_v, fixture->debug_flag_); + + const auto & result = parser->result(); + { + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + } + + log && fixture->log_memory_layout(&log); + } + + void + test_driver(const std::string & testname, + std::function test_subject, + std::array debug_flag_v) + { + scope log(XO_DEBUG(debug_flag_v[0] || debug_flag_v[1]), + xtag("test", testname)); + + /* phase=0 arena, no gc + * phase=1 x1 collector + */ + for (int phase = 0; phase < 2; ++phase) + { + log && log(xtag("phase", phase)); + + ParserFixture fixture(testname, phase == 1 /*gc*/, debug_flag_v[phase]); + + test_subject(&fixture); + } + } + } + + TEST_CASE("SchematikaParser-batch-def", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_batch_def, + c_debug_flag_v); + } + + namespace { + void + test_batch_deftype(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_batch_session(); + + /** Walkthrough parsing input equivalent to: + * + * deftype foo :: f64; + **/ + + std::vector tk_v{ + Token::deftype_token(), + Token::symbol_token("foo"), + Token::doublecolon_token(), + Token::symbol_token("f64"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + const auto & result = parser->result(); + { + // placeholder for form's sake. + // deftype doesn't actuallly produce any executable content + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + } + + log && fixture->log_memory_layout(&log); + } + } + + TEST_CASE("SchematikaParser-batch-deftype", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_batch_deftype, + c_debug_flag_v); + } + + namespace { + void + test_batch_deftype2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_batch_session(); + + /** Walkthrough parsing input equivalent to: + * + * deftype foo :: list; + **/ + + std::vector tk_v{ + Token::deftype_token(), + Token::symbol_token("foo"), + Token::doublecolon_token(), + Token::symbol_token("list"), + Token::leftangle_token(), + Token::symbol_token("f64"), + Token::rightangle_token(), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + const auto & result = parser->result(); + { + // placeholder for form's sake. + // deftype doesn't actuallly produce any executable content + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + } + + log && fixture->log_memory_layout(&log); + } + } + + TEST_CASE("SchematikaParser-batch-deftype2", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_batch_deftype2, + c_debug_flag_v); + } + + namespace { + void test_interactive_def2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->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(fixture, tk_v, fixture->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(fixture, tk_v, fixture->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-def2", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_def2, + c_debug_flag_v); + } + + void test_interactive_integer(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + 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()); + + 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()); + //// illegal input on token + //REQUIRE(result.error_description()); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-integer", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_integer, + c_debug_flag_v); + } + + void test_interactive_float(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + 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()); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-float", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_float, + c_debug_flag_v); + } + + void test_interactive_string(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + 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()); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-string", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_string, + c_debug_flag_v); + } + + void test_interactive_nil(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * nil ; + * + **/ + + { + auto & result = parser->on_token(Token::nil_token()); + + log && log("after nil 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_list = obj::from(expr->value()); + + REQUIRE(value_list); + + REQUIRE(value_list->is_empty()); + } + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-nil", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_nil, + c_debug_flag_v); + } + + void test_interactive_arith(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 3.14159265 * 0.5 ; + * + **/ + + std::vector tk_v{ + Token::f64_token("3.14159265"), + Token::star_token(), + Token::f64_token("0.5"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->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() == "_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); + } + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-arith", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_arith, + c_debug_flag_v); + } + + void test_interactive_arith2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 3.14159265 / 10.0 ; + * + **/ + + std::vector tk_v{ + Token::f64_token("3.14159265"), + Token::slash_token(), + Token::f64_token("10.0"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->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() == "_div"); + + 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() == 10.0); + } + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-arith2", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_arith2, + c_debug_flag_v); + } + + void test_interactive_arith3(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 7 * 2 - 3; + * + **/ + + std::vector tk_v{ + Token::i64_token("7"), + Token::star_token(), + Token::i64_token("2"), + Token::minus_token(), + Token::i64_token("3"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->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() == "_sub"); + + auto lhs = obj::from(expr->arg(0)); + REQUIRE(lhs); + + auto lhs_lhs = obj::from(lhs->arg(0)); + REQUIRE(lhs_lhs); + auto lhs_lhs_i64 = obj::from(lhs_lhs->value()); + REQUIRE(lhs_lhs_i64); + REQUIRE(lhs_lhs_i64->value() == 7); + + auto lhs_rhs = obj::from(lhs->arg(1)); + REQUIRE(lhs_rhs); + auto lhs_rhs_i64 = obj::from(lhs_rhs->value()); + REQUIRE(lhs_rhs_i64); + REQUIRE(lhs_rhs_i64->value() == 2); + + auto rhs = obj::from(expr->arg(1)); + REQUIRE(rhs); + + auto rhs_i64 = obj::from(rhs->value()); + REQUIRE(rhs_i64); + REQUIRE(rhs_i64->value() == 3); + } + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-arith3", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_arith3, + c_debug_flag_v); + } + + void test_interactive_arith4(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 7 + 2 / 3; + * + **/ + + std::vector tk_v{ + Token::i64_token("7"), + Token::plus_token(), + Token::i64_token("2"), + Token::slash_token(), + Token::i64_token("3"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->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() == "_add"); + + auto lhs = obj::from(expr->arg(0)); + REQUIRE(lhs); + + auto lhs_i64 = obj::from(lhs->value()); + REQUIRE(lhs_i64->value() == 7); + + auto rhs = obj::from(expr->arg(1)); + REQUIRE(rhs); + + auto rhs_lhs = obj::from(rhs->arg(0)); + REQUIRE(rhs_lhs); + auto rhs_lhs_i64 = obj::from(rhs_lhs->value()); + REQUIRE(rhs_lhs_i64); + REQUIRE(rhs_lhs_i64->value() == 2); + + auto rhs_rhs = obj::from(rhs->arg(1)); + REQUIRE(rhs_rhs); + auto rhs_rhs_i64 = obj::from(rhs_rhs->value()); + REQUIRE(rhs_rhs_i64); + REQUIRE(rhs_rhs_i64->value() == 3); + } + + log && fixture->log_memory_layout(&log); + } /*test_interactive_arith4*/ + + TEST_CASE("SchematikaParser-interactive-arith4", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_arith4, + c_debug_flag_v); + } + +#ifdef OBSOLETE + TEST_CASE("SchematikaParser-interactive-arith3-bad", "[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, false /*!gc*/, c_debug_flag); + auto parser = fixture.parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 7 * 2 - 3 4; + * + **/ + + std::vector tk_v{ + Token::i64_token("7"), + Token::star_token(), + Token::i64_token("2"), + Token::minus_token(), + Token::i64_token("3"), + Token::i64_token("4"), + Token::semicolon_token(), + }; + + INFO(testname); + + 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() == "_sub"); + + auto lhs = obj::from(expr->arg(0)); + REQUIRE(lhs); + + auto lhs_lhs = obj::from(lhs->arg(0)); + REQUIRE(lhs_lhs); + auto lhs_lhs_i64 = obj::from(lhs_lhs->value()); + REQUIRE(lhs_lhs_i64); + REQUIRE(lhs_lhs_i64->value() == 7); + + auto lhs_rhs = obj::from(lhs->arg(1)); + REQUIRE(lhs_rhs); + auto lhs_rhs_i64 = obj::from(lhs_rhs->value()); + REQUIRE(lhs_rhs_i64); + REQUIRE(lhs_rhs_i64->value() == 2); + + auto rhs = obj::from(expr->arg(1)); + REQUIRE(rhs); + + auto rhs_i64 = obj::from(rhs->value()); + REQUIRE(rhs_i64); + REQUIRE(rhs_i64->value() == 3); + } + + log && fixture.log_memory_layout(&log); + } +#endif // OBSOLETE + +#ifdef NOPE + void test_interactive_cmpne(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 312 != 312 ; + * ^ ^ ^ ^ + * 0 1 2 3 + **/ + + std::vector tk_v{ + /* [0] */ Token::i64_token("312"), + /* [1] */ Token::cmpne_token(), + /* [2] */ Token::i64_token("312"), + /* [3] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->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() == "_cmpne"); + + 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); + } + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-cmpne", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_cmpne, + c_debug_flag_v); + } + + void test_interactive_cmpeq(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * 312 == 312 ; + * ^ ^ ^ ^ + * 0 1 2 3 + **/ + + std::vector tk_v{ + /* [0] */ Token::i64_token("312"), + /* [1] */ Token::cmpeq_token(), + /* [2] */ Token::i64_token("312"), + /* [3] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->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() == "_cmpeq"); + + 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); + } + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-cmpeq", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_cmpeq, + c_debug_flag_v); + } + + void test_interactive_if1(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + { + /** Walkthrough parsing input equivalent to: + * + * def n = 4 ; + * ^ ^ ^ ^ ^ + * 0 1 2 3 4 + **/ + + std::vector tk_v{ + /* [0] */ Token::def_token(), + /* [1] */ Token::symbol_token("n"), + /* [2] */ Token::singleassign_token(), + /* [3] */ Token::i64_token("4"), + /* [4] */ Token::semicolon_token() + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + } + + { + const auto & result = parser->result(); + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + } + + { + parser->reset_result(); + + /** Walkthrough parsing input equivalent to: + * + * if (n == 4) then 1 else n * 5 ; + * ^ ^^ ^ ^^ ^ ^ ^ ^ ^ ^ ^ + * 0 1| 3 4| 6 7 8 9 a b c + * 2 5 + **/ + + std::vector tk_v{ + /* [0] */ Token::if_token(), + /* [1] */ Token::leftparen_token(), + /* [2] */ Token::symbol_token("n"), + /* [3] */ Token::cmpeq_token(), + /* [4] */ Token::i64_token("4"), + /* [5] */ Token::rightparen_token(), + /* [6] */ Token::then_token(), + /* [7] */ Token::i64_token("1"), + /* [8] */ Token::else_token(), + /* [9] */ Token::symbol_token("n"), + /* [a] */ Token::star_token(), + /* [b] */ Token::i64_token("5"), + /* [c] */ Token::semicolon_token() + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->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-if1", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + + test_driver(testname, + &test_interactive_if1, + c_debug_flag_v); + } +#endif + + void test_interactive_lambda(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** 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 + **/ + + 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(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_interactive_lambda, + c_debug_flag_v); + } + + void test_interactive_if2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * if true then 777 else "fooey" ; + * ^ ^ ^ ^ ^ ^ ^ + * 0 1 2 3 4 5 6 + **/ + + std::vector tk_v{ + /* [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(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-if2", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_interactive_if2, + c_debug_flag_v); + } + + void test_interactive_lambda2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * lambda (x : i64) -> i64 { x * x } + * ^ ^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + * 0 1| 3 4 5 6 7 8 9 a b c + * 2 + **/ + + std::vector tk_v{ + /* [ 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(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-lambda2", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_interactive_lambda2, + c_debug_flag_v); + } + + void test_interactive_apply(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * (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{ + /* [ 0] */ Token::leftparen_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(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-apply", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_interactive_apply, + c_debug_flag_v); + } + + void test_interactive_apply2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * (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{ + /* [ 0] */ Token::leftparen_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(), + + /* [ b] */ Token::leftbrace_token(), + /* [ c] */ Token::symbol_token("x"), + /* [ d] */ Token::star_token(), + /* [ e] */ Token::symbol_token("y"), + /* [ f] */ Token::rightbrace_token(), + + /* [ g] */ 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(), + + /* [ m] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-interactive-apply2", "[reader2][SchematikaParser]") + { + // top-level apply, with multiple arguments + + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_interactive_apply2, + c_debug_flag_v); + } + + void test_batch_def2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->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(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-batch-def2", "[reader2][SchematikaParser]") + { + // top-level recursive function definition + + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_batch_def2, + c_debug_flag_v); + } + + void test_batch_qliteral1(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * #q{ 4.5 } ; + * ^ ^ ^ ^ ^ + * 0 1 2 3 4 + **/ + + std::vector tk_v{ + /* [ 0] */ Token::quote_token(), + + /* [ 1] */ Token::leftbrace_token(), + /* [ 2] */ Token::f64_token("4.5"), + /* [ 3] */ Token::rightbrace_token(), + /* [ 4] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-batch-qliteral1", "[reader2][SchematikaParser]") + { + // top-level recursive function definition + + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_batch_qliteral1, + c_debug_flag_v); + + } + + void test_batch_qliteral2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * #q{ 4.5 } + #q { 7.2 }; + * ^ ^ ^ ^ ^ ^ ^ ^ ^^ + * 0 1 2 3 4 5 6 7 8| + * 9 + **/ + + std::vector tk_v{ + /* [ 0] */ Token::quote_token(), + /* [ 1] */ Token::leftbrace_token(), + /* [ 2] */ Token::f64_token("4.5"), + /* [ 3] */ Token::rightbrace_token(), + + /* [ 4] */ Token::plus_token(), + + /* [ 5] */ Token::quote_token(), + /* [ 6] */ Token::leftbrace_token(), + /* [ 7] */ Token::f64_token("7.2"), + /* [ 8] */ Token::rightbrace_token(), + + /* [ 9] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-batch-qliteral2", "[reader2][SchematikaParser]") + { + // top-level recursive function definition + + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_batch_qliteral2, + c_debug_flag_v); + + } + + void test_batch_qlist(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * #q{ (4.5 7.2) }; + * ^ ^ ^^ ^ ^ ^^ + * 0 1 2| 4 5 6| + * 3 7 + **/ + + std::vector tk_v{ + /* [ 0] */ Token::quote_token(), + /* [ 1] */ Token::leftbrace_token(), + /* [ 2] */ Token::leftparen_token(), + /* [ 3] */ Token::f64_token("4.5"), + /* [ 4] */ Token::f64_token("7.2"), + /* [ 5] */ Token::rightparen_token(), + /* [ 6] */ Token::rightbrace_token(), + /* [ 7] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-batch-qlist", "[reader2][SchematikaParser]") + { + // top-level recursive function definition + + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_batch_qlist, + c_debug_flag_v); + } + + void test_batch_qlist2(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * #q{ (4 7.2) }; + * ^ ^ ^^ ^ ^ ^^ + * 0 1 2| 4 5 6| + * 3 7 + **/ + + std::vector tk_v{ + /* [ 0] */ Token::quote_token(), + /* [ 1] */ Token::leftbrace_token(), + /* [ 2] */ Token::leftparen_token(), + /* [ 3] */ Token::i64_token("4"), + /* [ 4] */ Token::f64_token("7.2"), + /* [ 5] */ Token::rightparen_token(), + /* [ 6] */ Token::rightbrace_token(), + /* [ 7] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-batch-qlist2", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_batch_qlist2, + c_debug_flag_v); + } + + void test_batch_qarray(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * #q{ [4.5 7.2] }; + * ^ ^ ^^ ^ ^ ^^ + * 0 1 2| 4 5 6| + * 3 7 + **/ + + std::vector tk_v{ + /* [ 0] */ Token::quote_token(), + /* [ 1] */ Token::leftbrace_token(), + /* [ 2] */ Token::leftbracket_token(), + /* [ 3] */ Token::f64_token("4.5"), + /* [ 4] */ Token::f64_token("7.2"), + /* [ 5] */ Token::rightbracket_token(), + /* [ 6] */ Token::rightbrace_token(), + /* [ 7] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-batch-qarray", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_batch_qarray, + c_debug_flag_v); + } + + void test_batch_qdict0(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * #q{ {} }; + * ^ ^ ^^ ^^ + * 0 1 2| 4| + * 3 5 + **/ + + std::vector tk_v{ + /* [ 0] */ Token::quote_token(), + /* [ 1] */ Token::leftbrace_token(), + + /* [ 2] */ Token::leftbrace_token(), + /* [ 3] */ Token::rightbrace_token(), + + /* [ 4] */ Token::rightbrace_token(), + /* [ 5] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-batch-qdict0", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_batch_qdict0, + c_debug_flag_v); + } + + void test_batch_qdict1(ParserFixture * fixture) + { + scope log(XO_DEBUG(fixture->debug_flag_)); + + auto parser = fixture->parser_; + + parser->begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * #q{ {name: "kobold"; alignment: "chaotic evil"; hp: 15} }; + * ^ ^ ^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^^ + * 0 1 2| 4 5 6 7 8 9 a b c d e f| + * 3 g + **/ + + std::vector tk_v{ + /* [ 0] */ Token::quote_token(), + /* [ 1] */ Token::leftbrace_token(), + + /* [ 2] */ Token::leftbrace_token(), + + /* [ 3] */ Token::symbol_token("name"), + /* [ 4] */ Token::colon_token(), + /* [ 5] */ Token::string_token("kobold"), + /* [ 6] */ Token::semicolon_token(), + + /* [ 7] */ Token::symbol_token("alignment"), + /* [ 8] */ Token::colon_token(), + /* [ 9] */ Token::string_token("chaotic evil"), + /* [ a] */ Token::semicolon_token(), + + /* [ b] */ Token::symbol_token("hp"), + /* [ c] */ Token::colon_token(), + /* [ d] */ Token::i64_token("15"), + + /* [ e] */ Token::rightbrace_token(), + /* [ f] */ Token::rightbrace_token(), + /* [ g] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(fixture, tk_v, fixture->debug_flag_); + + log && fixture->log_memory_layout(&log); + } + + TEST_CASE("SchematikaParser-batch-qdict1", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + // [0] arena; [1] gc + constexpr std::array c_debug_flag_v = {{false, false}}; + test_driver(testname, + &test_batch_qdict1, + c_debug_flag_v); + } + + } /*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 */