git subrepo clone (merge) git@github.com:Rconybea/xo-reader2.git xo-reader2

subrepo:
  subdir:   "xo-reader2"
  merged:   "70943b8e"
upstream:
  origin:   "git@github.com:Rconybea/xo-reader2.git"
  branch:   "main"
  commit:   "70943b8e"
git-subrepo:
  version:  "0.4.9"
  origin:   "???"
  commit:   "???"
This commit is contained in:
Roland Conybeare 2026-06-06 22:24:57 -04:00
commit dbf8bb38a2
237 changed files with 25870 additions and 0 deletions

12
xo-reader2/.gitrepo Normal file
View file

@ -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

400
xo-reader2/CMakeLists.txt Normal file
View file

@ -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

21
xo-reader2/DESIGN.md Normal file
View file

@ -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

View file

@ -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()

View file

@ -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@")

6
xo-reader2/doc/README.md Normal file
View file

@ -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

View file

@ -0,0 +1,3 @@
ssm = syntax state machine
psm = parser state machine
ckp = checkpoint

View file

@ -0,0 +1 @@
add_subdirectory(readerreplxx)

View file

@ -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()

View file

@ -0,0 +1,248 @@
/** @file readerreplxx.cpp **/
#include <xo/reader2/init_reader2.hpp>
#include <xo/reader2/SchematikaReader.hpp>
#include <xo/gc/X1Collector.hpp>
#include <xo/gc/detail/IAllocator_DX1Collector.hpp>
#include <xo/alloc2/Arena.hpp>
#include <xo/alloc2/Allocator.hpp>
#include <xo/printable2/Printable.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <xo/facet/obj.hpp>
#include <xo/subsys/Subsystem.hpp>
#include <replxx.hxx>
#include <iostream>
#include <unistd.h> // 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-<bs> backward delete word" << endl;
os << " <up>|meta-p previous command from history" << endl;
os << " <down>|meta-n next command from history" << endl;
os << " <pgup>/<pgdown> 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<APrintable> expr_pr;
if (expr) {
expr_pr = FacetRegistry::instance().variant<APrintable,AExpression>(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<AAllocator,DArena>(&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<S_reader2_tag>::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 */

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "env",
includes: [
"<xo/alloc2/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
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" ],
}

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "parser",
includes: [
"<xo/alloc2/GCObject.hpp>",
"<xo/alloc2/Allocator.hpp>"
],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "apply",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "define",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "deftype",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -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: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "expect_listtype",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "expect_qdict",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "env",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ifelse",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "lambda",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "paren",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2/facet",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "quote",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/reader2",
output_hpp_dir: "include/xo/reader2",
output_impl_subdir: "ssm",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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" ],
}

View file

@ -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\"",
"<xo/type/Type.hpp>",
"<xo/tokenizer2/Token.hpp>",
"<xo/reflect/TypeDescr.hpp>",
"<xo/alloc2/GCObjectVisitor.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<AType>", 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<AExpression>", 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<AExpression>", 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<AGCObject>", 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<AGCObjectVisitor>", name: "gc"},
],
}
],
router_facet_explicit_content: [ ],
}

View file

@ -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 */

View file

@ -0,0 +1,226 @@
/** @file DDefineSsm.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include "syntaxstatetype.hpp"
#include <xo/expression2/detail/IExpression_DDefineExpr.hpp>
#include <xo/expression2/DDefineExpr.hpp>
#include <xo/facet/obj.hpp>
#include <string_view>
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<DDefineSsm> {
public:
using Super = DSyntaxStateMachine<DDefineSsm>;
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<ASyntaxStateMachine,DDefineSsm> make(DArena & parser_mm,
DDefineExpr * def_expr);
/** start nested parser for a define-expression,
* on top of parser state machine @p p_psm
* Use @p parser_mm to allocate syntax state machines,
* and @p expr_mm to allocate expressions
**/
static void start(DArena & parser_mm,
obj<AAllocator> 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<AExpression> 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<AExpression> 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<AGCObjectVisitor> 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<AExpression,DDefineExpr> def_expr_;
///@}
};
} /*namespace scm*/
} /*namespace xo*/
/* end DDefineSsm.hpp */

View file

@ -0,0 +1,221 @@
/** @file DExpectExprSsm.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include "syntaxstatetype.hpp"
#include <xo/facet/obj.hpp>
#include <xo/indentlog/print/ppindentinfo.hpp>
namespace xo {
namespace scm {
class DExpectExprSsm : public DSyntaxStateMachine<DExpectExprSsm> {
public:
using Super = DSyntaxStateMachine<DExpectExprSsm>;
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<ASyntaxStateMachine,DExpectExprSsm> 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<AExpression> 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<AExpression> 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<AGCObject> 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<AGCObjectVisitor> 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 */

View file

@ -0,0 +1,167 @@
/** @file DExpectFormalArglistSsm.hpp
*
* @author Roland Conybeare, Aug 2024
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include <xo/object2/DArray.hpp>
#include <xo/arena/DArena.hpp>
#ifdef NOT_YET
#include "exprstate.hpp"
#include "formal_arg.hpp"
#include <vector>
#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<DExpectFormalArglistSsm> {
public:
using Super = DSyntaxStateMachine<DExpectFormalArglistSsm>;
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<ASyntaxStateMachine,DExpectFormalArglistSsm> 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<AGCObjectVisitor> 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<AAllocator> 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 */

View file

@ -0,0 +1,147 @@
/** @file DExpectQArraySsm.hpp
*
* @author Roland Conybeare, Mar 2026
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include <xo/object2/ListOps.hpp>
#include <xo/facet/obj.hpp>
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<DExpectQArraySsm> {
public:
using Super = DSyntaxStateMachine<DExpectQArraySsm>;
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<ASyntaxStateMachine,DExpectQArraySsm> 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<AGCObject> 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<AGCObjectVisitor> 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 */

View file

@ -0,0 +1,149 @@
/** @file DExpectQListSsm.hpp
*
* @author Roland Conybeare, Mar 2026
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include <xo/object2/ListOps.hpp>
#include <xo/facet/obj.hpp>
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<DExpectQListSsm> {
public:
using Super = DSyntaxStateMachine<DExpectQListSsm>;
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<ASyntaxStateMachine,DExpectQListSsm> 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<AGCObject> 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<AGCObjectVisitor> 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 */

View file

@ -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<DExpectQLiteralSsm> {
public:
using Super = DSyntaxStateMachine<DExpectQLiteralSsm>;
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<ASyntaxStateMachine,DExpectQLiteralSsm> 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<AGCObjectVisitor> 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<AAllocator> 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 */

View file

@ -0,0 +1,91 @@
/* file DExpectSymbolSsm.hpp
*
* author: Roland Conybeare, Aug 2024
*/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include "syntaxstatetype.hpp"
#include <xo/indentlog/print/ppindentinfo.hpp>
#include <xo/facet/obj.hpp>
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<DExpectSymbolSsm> {
public:
using Super = DSyntaxStateMachine<DExpectSymbolSsm>;
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<ASyntaxStateMachine,DExpectSymbolSsm> make(DArena & parser_mm);
/** start nested parser expecting a symbol,
* on top of parser state machine @p p_psm.
* On success will deliver symbol by invoking
* .on_symbol(sym, p_psm)
* to the state machine on top of the stack
* as of when this start() method invoked
**/
static void start(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<AGCObjectVisitor> gc) noexcept;
///@}
};
} /*namespace scm*/
} /*namespace xo*/
/* end DExpectSymbolSsm.hpp */

View file

@ -0,0 +1,107 @@
/** @file expect_type_xs.hpp
*
* @author Roland Conybeare, Aug 2024
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include <xo/facet/obj.hpp>
#include <xo/indentlog/print/ppindentinfo.hpp>
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<T> parameterized list (polymorphic if T is any)
* array<T> parameterized array (polymorphic if T is any)
* function<T (U,..)> function (U x ...) -> T
* @endpre
**/
class DExpectTypeSsm : public DSyntaxStateMachine<DExpectTypeSsm> {
public:
using Super = DSyntaxStateMachine<DExpectTypeSsm>;
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<ASyntaxStateMachine,DExpectTypeSsm> 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<AGCObjectVisitor> gc) noexcept;
///@}
private:
/** temporary shim.
* if true, construct obj<AType>
* if false, construct TypeDescr
**/
bool corrected_ = false;
};
} /*namespace scm*/
} /*namespace xo*/
/* end DExpectTypeSsm.hpp */

View file

@ -0,0 +1,95 @@
/** @file DGlobalEnv.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include <xo/expression2/DGlobalSymtab.hpp>
#include <xo/object2/DArray.hpp>
#include <xo/alloc2/GCObjectVisitor.hpp>
namespace xo {
namespace scm {
/** @brief runtime bindings for global variabels
*
* Implementation here uses a DArenaHashMap to hold <key,value> 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<AAllocator> 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<AGCObject> 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<AAllocator> mm, Binding ix, obj<AGCObject> x);
/** create/establish global for symbol @p sym with resolved type @p td
* and associate with @p value.
**/
DVariable * _upsert_value(obj<AAllocator> mm,
const DUniqueString * sym,
TypeDescr td,
obj<AGCObject> value);
///@}
/** @defgroup scm-globalenv-gcobject-facet **/
///@{
DGlobalEnv * gco_shallow_move(obj<AGCObjectVisitor> gc) noexcept;
void visit_gco_children(VisitReason reason, obj<AGCObjectVisitor> 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;
};
}
}

View file

@ -0,0 +1,253 @@
/** @file DProgressSsm.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include "syntaxstatetype.hpp"
#include <xo/facet/obj.hpp>
#ifdef NOT_YET
#include "exprstate.hpp"
#include "xo/reflect/TypeDescr.hpp"
#include <iostream>
//#include <cstdint>
#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<DProgressSsm> {
public:
using Super = DSyntaxStateMachine<DProgressSsm>;
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<AExpression> lhs, optype op);
static DProgressSsm * _make(DArena & parser_mm,
obj<AExpression> lhs,
optype op);
/** create fop referring to new DProgressSsm **/
static obj<ASyntaxStateMachine,DProgressSsm> make(DArena & parser_mm,
obj<AExpression> lhs,
optype op);
static void start(DArena & parser_mm,
ParserStateMachine * p_psm);
static void start(DArena & parser_mm,
obj<AExpression> lhs,
ParserStateMachine * p_psm);
static void start(DArena & parsermm,
obj<AExpression> 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<Expression> expr1,
bp<Expression> 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<AExpression> 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<AExpression> expr,
ParserStateMachine * p_psm);
void on_parsed_expression_with_token(obj<AExpression> 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<AGCObjectVisitor> gc) noexcept;
///@}
private:
/** populate an expression here, may be followed by an operator **/
obj<AExpression> 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<AExpression> rhs_;
};
} /*namespace scm*/
#ifndef ppdetail_atomic
namespace print {
PPDETAIL_ATOMIC(xo::scm::optype);
}
#endif
} /*namespace xo*/
/* end DProgressSsm.hpp */

View file

@ -0,0 +1,172 @@
/** @file DQuoteSsm.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include "syntaxstatetype.hpp"
#include <xo/facet/obj.hpp>
#include <string_view>
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<DQuoteSsm> {
public:
using Super = DSyntaxStateMachine<DQuoteSsm>;
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<ASyntaxStateMachine,DQuoteSsm> 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<AGCObject> 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<AGCObjectVisitor> gc) noexcept;
///@}
private:
/** @defgroup scm-parenssm-member-vars **/
///@{
/** identify quote-expression state **/
QuoteXst quote_xst_;
/** scaffold expression (representing parenthesized value) here **/
obj<AExpression> expr_;
///@}
};
} /*namespace scm*/
} /*namespace xo*/
/* end DQuoteSsm.hpp */

View file

@ -0,0 +1,119 @@
/** @file DSequenceSsm.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include <xo/expression2/DSequenceExpr.hpp>
#include "syntaxstatetype.hpp"
#include <xo/expression2/detail/IExpression_DSequenceExpr.hpp>
#include <xo/expression2/DSequenceExpr.hpp>
#include <xo/facet/obj.hpp>
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<DSequenceSsm> {
public:
using Super = DSyntaxStateMachine<DSequenceSsm>;
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<ASyntaxStateMachine,DSequenceSsm> make(DArena & parser_mm,
obj<AAllocator> expr_mm);
/** create instance using memory from @p parser_mm **/
static DSequenceSsm * _make(DArena & parser_mm,
obj<AAllocator> expr_mm);
#ifdef NOT_YET
virtual void on_expr_with_semicolon(bp<Expression> 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<AExpression> 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<AExpression> 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<AGCObjectVisitor> 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 */

View file

@ -0,0 +1,210 @@
/** @file DSyntaxStateMachine.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "SyntaxStateMachine.hpp"
#include "ParserStateMachine.hpp"
#include <xo/object2/DArray.hpp>
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<ASyntaxStateMachine>::mkobj(d);
* // or
* obj<ASyntaxStateMachine,Derived>(d)
* @endcode
**/
template<typename Derived>
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<Derived&>(*this);
p_psm->illegal_input_on_token(Derived::ssm_classname(),
tk,
self.get_expect_str());
}
/** Explicit error path **/
void illegal_type(obj<AType> type,
ParserStateMachine * p_psm)
{
// starting with c++23 can use "this auto&& self" instead
Derived & self = static_cast<Derived &>(*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<Derived &>(*this);
p_psm->illegal_input_on_symbol(Derived::ssm_classname(),
sym,
self.get_expect_str());
}
/** Explicit error path **/
void illegal_quoted_literal(obj<AGCObject> lit,
ParserStateMachine * p_psm)
{
// starting with c++23 can use "this auto&& self" instead
Derived & self = static_cast<Derived&>(*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<Derived&>(*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<AType> 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<Derived&>(*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<Derived&>(*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<AGCObejct,DVariable>
**/
void on_parsed_formal_arglist(DArray * arglist,
ParserStateMachine * p_psm)
{
// starting with c++23 can use "this auto&& self" instead
Derived & self = static_cast<Derived&>(*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<AExpression> expr,
ParserStateMachine * p_psm)
{
// starting with c++23 can use "this auto&& self" instead
Derived & self = static_cast<Derived&>(*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<AExpression> expr,
const Token & tk,
ParserStateMachine * p_psm)
{
// starting with c++23 can use "this auto&& self" instead
Derived & self = static_cast<Derived&>(*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<AGCObject> lit,
ParserStateMachine * p_psm)
{
this->illegal_quoted_literal(lit, p_psm);
}
};
} /*namespace scm*/
} /*namespace xo*/
/* end DSyntaxStateMachine.hpp */

View file

@ -0,0 +1,179 @@
/** @file DToplevelSeqSsm.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "DSyntaxStateMachine.hpp"
#include "syntaxstatetype.hpp"
#include <xo/facet/obj.hpp>
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<DToplevelSeqSsm> {
public:
using Super = DSyntaxStateMachine<DToplevelSeqSsm>;
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<AExpression> 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<AExpression> 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<AGCObjectVisitor> 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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -0,0 +1,80 @@
/** @file ExpressionParser.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#include "ExprState.hpp"
#include <xo/alloc2/Allocator.hpp>
#include <xo/alloc2/arena/IAllocator_DArena.hpp>
#include <xo/facet/obj.hpp>
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<AExprState> 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<AAllocator> expr_alloc_;
};
} /*namespace scm*/
} /*namespace xo*/
/* end ExpressionParser.hpp */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -0,0 +1,69 @@
/** @file SchematikaParserConfig.hpp
*
* @author Roland Conybeare, Feb 2026
**/
#pragma once
#include <xo/procedure2/PrimitiveRegistry.hpp>
#include <xo/arena/ArenaHashMapConfig.hpp>
#include <xo/arena/ArenaConfig.hpp>
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 */

View file

@ -0,0 +1,119 @@
/** @file ParserResult.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include <xo/expression2/Expression.hpp>
#include <xo/stringtable2/DString.hpp>
#include <xo/indentlog/print/pretty.hpp>
#include <string_view>
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<AExpression> 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<AExpression> 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<AExpression> 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<AGCObjectVisitor> 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<AExpression> 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 <xo/indentlog/print/pretty.hpp> relies on this specialization
* to handle ParserResult instances
**/
template <>
struct ppdetail<xo::scm::ParserResult> {
static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::ParserResult & x) {
return x.pretty(ppii);
}
};
}
} /*namespace xo*/
/* end ParserResult.hpp */

View file

@ -0,0 +1,100 @@
/** @file ParserStack.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "SyntaxStateMachine.hpp"
#include <xo/alloc2/GCObjectVisitor.hpp>
#include <xo/arena/DArena.hpp>
#include <xo/facet/obj.hpp>
#include <xo/indentlog/print/pretty.hpp>
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<ASyntaxStateMachine> 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<ASyntaxStateMachine> 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<ASyntaxStateMachine> 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<AGCObjectVisitor> gc) noexcept;
private:
/** stack pointer: top of stack just before this instance created **/
DArena::Checkpoint ckp_;
/** top of parsing stack: always non-null **/
obj<ASyntaxStateMachine> 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 <xo/indentlog/print/pretty.hpp> relies on this specialization
* to handle ParserResult instances
**/
template <>
struct ppdetail<xo::scm::ParserStack*> {
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 */

View file

@ -0,0 +1,478 @@
/** @file ParserStateMachine.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "ParserResult.hpp"
#include "GlobalEnv.hpp"
#include <xo/expression2/GlobalSymtab.hpp>
#include <xo/expression2/LocalSymtab.hpp>
#include <xo/expression2/DVariable.hpp>
#include <xo/expression2/VarRef.hpp>
#include <xo/tokenizer2/Token.hpp>
#include <xo/procedure2/PrimitiveRegistry.hpp>
#include <xo/type/Type.hpp>
#include <xo/object2/DArray.hpp>
#include <xo/stringtable2/StringTable.hpp>
#include <xo/alloc2/Allocator.hpp>
#include <xo/alloc2/GCObjectVisitor.hpp>
#include <xo/arena/ArenaHashMapConfig.hpp>
#include <xo/arena/DArena.hpp>
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<SyntaxStateMachine> 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<AAllocator> expr_alloc,
obj<AAllocator> 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<AAllocator> 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<AGCObject> multiply_pm() const;
/** polymorphic divide primitive. Use to implement infix op/ **/
obj<AGCObject> divide_pm() const;
/** polymorphic add primitive. Use to implement infix op+ **/
obj<AGCObject> add_pm() const;
/** polymorphic subtract primitive. Use to implement infix op- **/
obj<AGCObject> subtract_pm() const;
/** polymorphic equality comparison. Use to implement infix op== **/
obj<AGCObject> cmpeq_pm() const;
/** polymorphic inequality comparison. Use to implement infix op!= **/
obj<AGCObject> cmpne_pm() const;
/** polymorphic less-than comparison. Use to implement infix op< **/
obj<AGCObject> cmplt_pm() const;
/** polymorphic less-or-equal comparison. Use to implement infix op<= **/
obj<AGCObject> cmple_pm() const;
/** polymorphic greater comparison. Use to implement infix op> **/
obj<AGCObject> cmpgt_pm() const;
/** polymorphic greater-or-equal comparison. Use to implement infix op>= **/
obj<AGCObject> 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<ASyntaxStateMachine> 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<ASyntaxStateMachine> ssm);
/** push syntax @p ssm onto @ref stack_, restore parser stack to @p ckp
* when popped
**/
void push_ssm(DArena::Checkpoint ckp, obj<ASyntaxStateMachine> 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<AType> 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<AExpression> 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<AExpression> expr,
const Token & tk);
/** update state to consume quoted literal @p lit **/
void on_quoted_literal(obj<AGCObject> 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<AExpression> 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<AType> 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<AGCObject,DVariable> 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<AExpression>,
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<AExpression> 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<AGCObject> 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<AGCObjectVisitor> 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<AAllocator> 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<AAllocator> 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<AGCObject,DGlobalSymtab> 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<AGCObject,DLocalSymtab> local_symtab_;
/** global variable bindings (builtin primitives) **/
obj<AGCObject,DGlobalEnv> 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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -0,0 +1,25 @@
/** @file Reader.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#include <xo/tokenizer2/Tokenizer.hpp>
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 */

View file

@ -0,0 +1,85 @@
/** @file ReaderConfig.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include <xo/procedure2/PrimitiveRegistry.hpp>
#include <xo/arena/CircularBufferConfig.hpp>
#include <xo/arena/ArenaHashMapConfig.hpp>
#include <xo/arena/ArenaConfig.hpp>
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 */

View file

@ -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 */

View file

@ -0,0 +1,139 @@
/** @file SchematikaReader.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "ReaderConfig.hpp"
#include "SchematikaParser.hpp"
#include <xo/tokenizer2/Tokenizer.hpp>
#include <xo/alloc2/GCObjectVisitor.hpp>
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<const char>;
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<AGCObjectVisitor> gc) noexcept;
/** schematika expression parsed from input **/
obj<AExpression> 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<const char>;
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<AAllocator> expr_alloc,
obj<AAllocator> 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<AGCObjectVisitor> 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 */

View file

@ -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 */

View file

@ -0,0 +1,25 @@
/** @file SetupReader2.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include <xo/alloc2/Collector.hpp>
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<ACollector> gc);
};
}
}
/* end SetupReader2.hpp */

View file

@ -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 */

View file

@ -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 */

Some files were not shown because too many files have changed in this diff Show more