xo-reader2: refactor: crtp to share code across SSM impls

This commit is contained in:
Roland Conybeare 2026-01-30 13:23:44 -05:00
commit b5b6a51ce4
4 changed files with 116 additions and 40 deletions

View file

@ -2,6 +2,11 @@
cmake_minimum_required(VERSION 3.10)
# relying on
# this auto&&
#
set(CMAKE_CXX_STANDARD 23)
project(xo_reader2 VERSION 1.0)
enable_language(CXX)

View file

@ -5,7 +5,7 @@
#pragma once
#include "SyntaxStateMachine.hpp"
#include "DSyntaxStateMachine.hpp"
#include <xo/expression2/DLambdaExpr.hpp>
#include <xo/expression2/SymbolTable.hpp>
//#include <xo/expression2/DLocalSymtab.hpp>
@ -55,9 +55,9 @@ namespace xo {
/** @class DLambdaSsm
* @brief parsing state-machine for a lambda-expression
**/
class DLambdaSsm {
class DLambdaSsm : public DSyntaxStateMachine<DLambdaSsm> {
public:
//using DSymbolTable = xo::scm::DSymbolTable;
using Super = DSyntaxStateMachine<DLambdaSsm>;
using DLocalSymtab = xo::scm::DLocalSymtab;
using AAllocator = xo::mm::AAllocator;
using DArena = xo::mm::DArena;
@ -80,6 +80,8 @@ namespace xo {
/** @defgroup scm-lambdassm-methods **/
///@{
const char * ssm_classname() const noexcept { return "DLambdaSsm"; }
static void start(ParserStateMachine * p_psm);
/** update ssm on lambda keyword token @p tk,
@ -110,11 +112,13 @@ namespace xo {
void on_token(const Token & tk,
ParserStateMachine * p_psm);
#ifdef OBSOLETE
/** update this ssm when nested parser
* emits @p td.
**/
void on_parsed_symbol(std::string_view sym,
ParserStateMachine * p_psm);
#endif
/** update this ssm when nested parser
* emits @p td.
@ -122,12 +126,14 @@ namespace xo {
void on_parsed_typedescr(TypeDescr td,
ParserStateMachine * p_psm);
#ifdef OBSOLETE
/** update this ssm to consume parsed formal (name,value)
* from nested (and now expired) ssm
**/
void on_parsed_formal(const DUniqueString * sym,
TypeDescr td,
ParserStateMachine * p_psm);
#endif
/** consume formal params @p arglist from completed nested ssm,
* with overall parser state in @p p_psm.

View file

@ -5,16 +5,16 @@
#pragma once
#include "SyntaxStateMachine.hpp"
#include <xo/object2/DArray.hpp>
namespace xo {
namespace scm {
/** @class DSyntaxStateMachine
* @brief static interface for implementing ASyntaxStateMachine
* @brief static helper interface for ASyntaxStateMachine implementations
*
* Using CRTP to collect methods common to ASyntaxStateMachine
* implementations.
* Using CRTP.
*
* Deliberately unusable through base class pointer.
* For runtime polymorphism use something like:
@ -27,11 +27,91 @@ namespace xo {
**/
template<typename Derived>
class DSyntaxStateMachine {
friend Derived;
public:
using TypeDescr = xo::reflect::TypeDescr;
/** arglist is DArray of obj<AGCObejct,DVariable> **/
void on_parsed_formal_arglist(this auto&& self, DArray * arglist, ParserStateMachine * p_psm) {
p_psm->illegal_parsed_formal_arglist(
/** Default implementation for required SyntaxStateMachine facet method
**/
void on_token(this auto&& self,
const Token & tk,
ParserStateMachine * p_psm)
{
p_psm->illegal_input_on_token(self.ssm_classname(),
tk,
self.get_expect_str());
}
void on_parsed_symbol(this auto&& self,
std::string_view sym,
ParserStateMachine * p_psm)
{
p_psm->illegal_input_on_symbol(self.ssm_classname(),
sym,
self.get_expect_str());
}
/** Default implementation for required SyntaxStateMachine facet method
**/
void on_parsed_typedescr(this auto&& self,
TypeDescr td,
ParserStateMachine * p_psm)
{
p_psm->illegal_input_on_typedescr(self.ssm_classname(),
td,
self.get_expect_str());
}
/** Default implementation for required SyntaxStateMachine facet method
**/
void on_parsed_formal(this auto&& self,
const DUniqueString * param_name,
TypeDescr param_type,
ParserStateMachine * p_psm)
{
p_psm->illegal_parsed_formal(self.ssm_classname(),
param_name,
param_type,
self.get_expect_str());
}
/** Default implementation for required SyntaxStateMachine facet method
*
* arglist is DArray of obj<AGCObejct,DVariable>
**/
void on_parsed_formal_arglist(this auto&& self,
DArray * arglist,
ParserStateMachine * p_psm)
{
p_psm->illegal_parsed_formal_arglist(self.ssm_classname(),
arglist,
self.get_expect_str());
}
/** Default implementation for required SyntaxStateMachine facet method
**/
void on_parsed_expression(this auto&& self,
obj<AExpression> expr,
ParserStateMachine * p_psm)
{
p_psm->illegal_parsed_expression(self.ssm_classname(),
expr,
self.get_expect_str());
}
/** Default implementation for required SyntaxStateMachine facet method
**/
void on_parsed_expression_with_semicolon(this auto&& self,
obj<AExpression> expr,
ParserStateMachine * p_psm)
{
// We don't need a separate entry point,
// since the semicolon isn't relevant to problem with syntax
//
p_psm->illegal_parsed_expression(self.ssm_classname(),
expr,
self.get_expect_str());
}
};

View file

@ -177,9 +177,12 @@ namespace xo {
break;
}
Super::on_token(tk, p_psm);
#ifdef OBSOLETE
p_psm->illegal_input_on_token("DLambdaSsm::on_token",
tk,
this->get_expect_str());
#endif
}
void
@ -194,9 +197,12 @@ namespace xo {
return;
}
Super::on_token(tk, p_psm);
#ifdef OBSOLETE
p_psm->illegal_input_on_token("DLambdaSsm::on_lambda_token",
tk,
this->get_expect_str());
#endif
}
void
@ -212,9 +218,12 @@ namespace xo {
return;
}
Super::on_token(tk, p_psm);
#ifdef OBSOLETE
p_psm->illegal_input_on_token("DLambdaSsm::on_yields_token",
tk,
this->get_expect_str());
#endif
}
@ -231,9 +240,7 @@ namespace xo {
return;
}
p_psm->illegal_input_on_typedescr("DLambdaSsm::on_parsed_typedescr",
td,
this->get_expect_str());
Super::on_parsed_typedescr(td, p_psm);
}
#ifdef NOT_YET
@ -264,26 +271,6 @@ namespace xo {
}
#endif
void
DLambdaSsm::on_parsed_symbol(std::string_view sym,
ParserStateMachine * p_psm)
{
p_psm->illegal_input_on_symbol("DLambdaSsm::on_parsed_sybol",
sym,
this->get_expect_str());
}
void
DLambdaSsm::on_parsed_formal(const DUniqueString * param_name,
TypeDescr param_type,
ParserStateMachine * p_psm)
{
p_psm->illegal_parsed_formal("DLambdaSsm::on_parsed_formal",
param_name,
param_type,
this->get_expect_str());
}
void
DLambdaSsm::on_parsed_formal_arglist(DArray * arglist,
ParserStateMachine * p_psm)
@ -337,28 +324,26 @@ namespace xo {
return;
}
Super::on_parsed_formal_arglist(arglist, p_psm);
#ifdef OBSOLETE
p_psm->illegal_parsed_formal_arglist("DLambdaSsm::on_parsed_formal_arglist",
arglist,
this->get_expect_str());
#endif
}
void
DLambdaSsm::on_parsed_expression(obj<AExpression> expr,
ParserStateMachine * p_psm)
{
p_psm->illegal_parsed_expression("DLambdaSsm::on_parsed_expression",
expr,
this->get_expect_str());
Super::on_parsed_expression(expr, p_psm);
}
void
DLambdaSsm::on_parsed_expression_with_semicolon(obj<AExpression> expr,
ParserStateMachine * p_psm)
{
p_psm->illegal_parsed_expression
("DLambdaSsm::on_parsed_expression_with_semicolon",
expr,
this->get_expect_str());
Super::on_parsed_expression_with_semicolon(expr, p_psm);
}
#ifdef NOT_YET