From 76af3ff3b5b2c0e64dc0bb4cadf1425e036fdfc0 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 11 Mar 2026 07:49:14 -0500 Subject: [PATCH] xo-reader2 stack: expand symbol table to store typedefs + typedef utest + misc qol policy choices --- CMakeLists.txt | 20 ++ idl/IPrintable_DDeftypeSsm.json5 | 16 + idl/ISyntaxStateMachine_DDeftypeSsm.json5 | 16 + include/xo/reader2/DDeftypeSsm.hpp | 186 ++++++++++++ include/xo/reader2/DExpectTypeSsm.hpp | 14 +- include/xo/reader2/DQuoteSsm.hpp | 1 - include/xo/reader2/DSyntaxStateMachine.hpp | 20 +- include/xo/reader2/DToplevelSeqSsm.hpp | 5 + include/xo/reader2/DeftypeSsm.hpp | 12 + include/xo/reader2/ParserConfig.hpp | 24 +- include/xo/reader2/ParserStateMachine.hpp | 10 +- include/xo/reader2/ReaderConfig.hpp | 24 +- .../xo/reader2/ssm/IPrintable_DDeftypeSsm.hpp | 62 ++++ .../ssm/ISyntaxStateMachine_DDeftypeSsm.hpp | 84 ++++++ include/xo/reader2/syntaxstatetype.hpp | 3 + src/reader2/CMakeLists.txt | 4 + src/reader2/DApplySsm.cpp | 1 + src/reader2/DDefineSsm.cpp | 12 +- src/reader2/DDeftypeSsm.cpp | 275 ++++++++++++++++++ src/reader2/DExpectExprSsm.cpp | 1 + src/reader2/DExpectFormalArgSsm.cpp | 3 +- src/reader2/DExpectFormalArglistSsm.cpp | 1 + src/reader2/DExpectQArraySsm.cpp | 1 + src/reader2/DExpectQListSsm.cpp | 1 + src/reader2/DExpectQLiteralSsm.cpp | 1 + src/reader2/DExpectSymbolSsm.cpp | 1 + src/reader2/DExpectTypeSsm.cpp | 93 ++++-- src/reader2/DIfElseSsm.cpp | 1 + src/reader2/DLambdaSsm.cpp | 30 +- src/reader2/DParenSsm.cpp | 1 + src/reader2/DProgressSsm.cpp | 1 + src/reader2/DQuoteSsm.cpp | 3 +- src/reader2/DSequenceSsm.cpp | 1 + src/reader2/DToplevelSeqSsm.cpp | 30 +- src/reader2/IPrintable_DDeftypeSsm.cpp | 28 ++ .../ISyntaxStateMachine_DDeftypeSsm.cpp | 84 ++++++ src/reader2/ParserStateMachine.cpp | 17 +- src/reader2/SchematikaParser.cpp | 13 +- src/reader2/SchematikaReader.cpp | 3 +- src/reader2/reader2_register_facets.cpp | 5 + src/reader2/syntaxstatetype.cpp | 2 + utest/SchematikaParser.test.cpp | 44 ++- 42 files changed, 1047 insertions(+), 107 deletions(-) create mode 100644 idl/IPrintable_DDeftypeSsm.json5 create mode 100644 idl/ISyntaxStateMachine_DDeftypeSsm.json5 create mode 100644 include/xo/reader2/DDeftypeSsm.hpp create mode 100644 include/xo/reader2/DeftypeSsm.hpp create mode 100644 include/xo/reader2/ssm/IPrintable_DDeftypeSsm.hpp create mode 100644 include/xo/reader2/ssm/ISyntaxStateMachine_DDeftypeSsm.hpp create mode 100644 src/reader2/DDeftypeSsm.cpp create mode 100644 src/reader2/IPrintable_DDeftypeSsm.cpp create mode 100644 src/reader2/ISyntaxStateMachine_DDeftypeSsm.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 54441a8c..8e0f1e95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,26 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-deftypessm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR DeftypeSsm + 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 + FACET Printable + REPR DeftypeSsm + INPUT idl/IPrintable_DDeftypeSsm.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-lambdassm diff --git a/idl/IPrintable_DDeftypeSsm.json5 b/idl/IPrintable_DDeftypeSsm.json5 new file mode 100644 index 00000000..e61f5881 --- /dev/null +++ b/idl/IPrintable_DDeftypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DDeftypeSsm", + using_doxygen: true, + repr: "DDeftypeSsm", + doc: [ "implement APrintable for DDeftypeSsm" ], +} diff --git a/idl/ISyntaxStateMachine_DDeftypeSsm.json5 b/idl/ISyntaxStateMachine_DDeftypeSsm.json5 new file mode 100644 index 00000000..d3e3b174 --- /dev/null +++ b/idl/ISyntaxStateMachine_DDeftypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DDeftypeSsm", + using_doxygen: true, + repr: "DDeftypeSsm", + doc: [ "implement ASyntaxStateMachine for DDeftypeSsm" ], +} diff --git a/include/xo/reader2/DDeftypeSsm.hpp b/include/xo/reader2/DDeftypeSsm.hpp new file mode 100644 index 00000000..29a1d691 --- /dev/null +++ b/include/xo/reader2/DDeftypeSsm.hpp @@ -0,0 +1,186 @@ +/** @file DDeftypeSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include + +namespace xo { + namespace scm { + /** + * @pre + * + * deftype foo :: f64 ; + * ^ ^ ^ ^ ^ ^ + * | | | | | (done) + * | | | | def_4 + * | | | def_3 + * | | def_2 + * | def_1 + * def_0 + * + * def_0 --on_deftype_token()--> def_1 [expect symbol] + * def_1 --on_symbol_token()--> def_2 [expect ::] + * def_2 --on_doublecolon_token()--> def_3 [start ExpectTypeSsm] + * def_3 --on_parsed_type()--> def_4 [++ symbol table] + * def_4 --on_semicolon_token()--> (done) [pop] + * + * @endpre + **/ + class DeftypeXst { + public: + enum class code { + invalid = -1, + + def_0, + def_1, + def_2, + def_3, + def_4, + + N, + }; + + explicit DeftypeXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + std::ostream & + operator<<(std::ostream & os, DeftypeXst x); + + /** @class DDeftypeSsm + * @brief state machine for parsing a deftype expression + **/ + class DDeftypeSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-deftypessm-ctors constructors **/ + ///@{ + + /** constructor; using @p def_expr for initial expression scaffold **/ + explicit DDeftypeSsm(); + + /** Create instance using memory from @p parser_mm **/ + static DDeftypeSsm * _make(DArena & parser_mm); + + /** create fop referring to new DDeftypeSsm **/ + static obj make(DArena & parser_mm); + + /** start nested parser for a define-expression, + * on top of parser state machine @p p_psm + * Use @p parser_mm to allocate syntax state machines, + * and @p expr_mm to allocate expressions + **/ + static void start(DArena & parser_mm, + //obj expr_mm, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-definessm-access-methods **/ + ///@{ + + /** identify this nested state machine **/ + static const char * ssm_classname() { return "DDeftypeSsm"; } + + /** internal state **/ + DeftypeXst deftypestate() const noexcept { return deftype_xst_; } + + ///@} + /** @defgroup scm-definessm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error messages + **/ + std::string_view get_expect_str() const noexcept; + + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming @c deftype token @p tk, + * overall parser state in @p p_psm + **/ + void on_deftype_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming double-colon token @p tk, + * overall parser state in @p p_psm + **/ + void on_doublecolon_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a symbol @p sym; + * overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + /** update state for this syntax after type @p type emitted by nested + * state machine, with overall parser state in @p p_psm + **/ + void on_parsed_type(obj type, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + /** update state for this syntax after parsing a type-description @p td, + * overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); +#endif + + /** update state for this syntax after parsing semicolon token @p tk, + * overall parser state in @p p_psm. + * if state def_4 completes deftype statement. + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-define-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** @defgroup scm-deftypessm-member-vars **/ + ///@{ + + /** identify deftype ssm state **/ + DeftypeXst deftype_xst_; + + /** lhs symbol for type definition **/ + const DUniqueString * lhs_symbol_ = nullptr; + + ///@} + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineSsm.hpp */ diff --git a/include/xo/reader2/DExpectTypeSsm.hpp b/include/xo/reader2/DExpectTypeSsm.hpp index 8d67b448..aba12f8d 100644 --- a/include/xo/reader2/DExpectTypeSsm.hpp +++ b/include/xo/reader2/DExpectTypeSsm.hpp @@ -30,14 +30,14 @@ namespace xo { using ppindentinfo = xo::print::ppindentinfo; public: - DExpectTypeSsm(); + explicit DExpectTypeSsm(bool corrected); - static DExpectTypeSsm * _make(DArena & parser_mm); + static DExpectTypeSsm * _make(DArena & parser_mm, bool corrected); /** create fop referring to new DExpectTypeSsm **/ - static obj make(DArena & parser_mm); + static obj make(DArena & parser_mm, bool corrected); - static void start(ParserStateMachine * p_psm); + static void start(bool corrected, ParserStateMachine * p_psm); static const char * ssm_classname() { return "DExpectTypeSsm"; } @@ -72,6 +72,12 @@ namespace xo { ///@} + private: + /** temporary shim. + * if true, construct obj + * if false, construct TypeDescr + **/ + bool corrected_ = false; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader2/DQuoteSsm.hpp b/include/xo/reader2/DQuoteSsm.hpp index 6cbfac79..26079e8e 100644 --- a/include/xo/reader2/DQuoteSsm.hpp +++ b/include/xo/reader2/DQuoteSsm.hpp @@ -32,7 +32,6 @@ namespace xo { * * @endpre **/ - class QuoteXst { public: enum class code { diff --git a/include/xo/reader2/DSyntaxStateMachine.hpp b/include/xo/reader2/DSyntaxStateMachine.hpp index 10aeccfa..66852170 100644 --- a/include/xo/reader2/DSyntaxStateMachine.hpp +++ b/include/xo/reader2/DSyntaxStateMachine.hpp @@ -48,6 +48,7 @@ namespace xo { void illegal_type(obj type, ParserStateMachine * p_psm) { + // starting with c++23 can use "this auto&& self" instead Derived & self = static_cast(*this); p_psm->illegal_input_on_type(Derived::ssm_classname(), @@ -55,6 +56,18 @@ namespace xo { self.get_expect_str()); } + /** Explicit error path **/ + void illegal_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + // starting with c++23 can use "this auto&& self" instead + Derived & self = static_cast(*this); + + p_psm->illegal_input_on_symbol(Derived::ssm_classname(), + sym, + self.get_expect_str()); + } + /** Explicit error path **/ void illegal_quoted_literal(obj lit, ParserStateMachine * p_psm) @@ -78,12 +91,7 @@ namespace xo { void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { - // starting with c++23 can use "this auto&& self" instead - Derived & self = reinterpret_cast(*this); - - p_psm->illegal_input_on_symbol(Derived::ssm_classname(), - sym, - self.get_expect_str()); + this->illegal_parsed_symbol(sym, p_psm); } /** Default implementation for required SyntaxStateMachine facet method diff --git a/include/xo/reader2/DToplevelSeqSsm.hpp b/include/xo/reader2/DToplevelSeqSsm.hpp index d20e751a..9bb9b076 100644 --- a/include/xo/reader2/DToplevelSeqSsm.hpp +++ b/include/xo/reader2/DToplevelSeqSsm.hpp @@ -84,6 +84,11 @@ namespace xo { **/ 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 **/ diff --git a/include/xo/reader2/DeftypeSsm.hpp b/include/xo/reader2/DeftypeSsm.hpp new file mode 100644 index 00000000..22ec3eec --- /dev/null +++ b/include/xo/reader2/DeftypeSsm.hpp @@ -0,0 +1,12 @@ +/** @file DeftypeSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DDeftypeSsm.hpp" +#include "ssm/ISyntaxStateMachine_DDeftypeSsm.hpp" +#include "ssm/IPrintable_DDeftypeSsm.hpp" + +/* end DeftypeSsm.hpp */ diff --git a/include/xo/reader2/ParserConfig.hpp b/include/xo/reader2/ParserConfig.hpp index 080238c7..07dcb37b 100644 --- a/include/xo/reader2/ParserConfig.hpp +++ b/include/xo/reader2/ParserConfig.hpp @@ -24,7 +24,7 @@ namespace xo { .header_{}, .debug_flag_ = false }; - /** configuration for hash map for global symbol table + /** configuration for hash map for global symbol table (variables) * * reminder: ownership chain * SchematikaReader @@ -32,9 +32,25 @@ namespace xo { * ->ParserStateMachine * ->DGlobalSymtab **/ - ArenaHashMapConfig symtab_config_ { .name_ = "global-symtab", - .hint_max_capacity_ = 64*1024, - .debug_flag_ = false }; + 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; diff --git a/include/xo/reader2/ParserStateMachine.hpp b/include/xo/reader2/ParserStateMachine.hpp index 2553acbf..f24c6bed 100644 --- a/include/xo/reader2/ParserStateMachine.hpp +++ b/include/xo/reader2/ParserStateMachine.hpp @@ -47,8 +47,10 @@ namespace xo { public: /** * @p config arena configuration for parser state - * @p symtab_config configuration for global symtab + * @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 expr_alloc allocator for schematika expressions. @@ -59,7 +61,8 @@ namespace xo { * same as @p expr_alloc. **/ ParserStateMachine(const ArenaConfig & config, - const ArenaHashMapConfig & symtab_config, + const ArenaHashMapConfig & symtab_var_config, + const ArenaHashMapConfig & symtab_type_config, size_type max_stringtable_capacity, obj expr_alloc, obj aux_alloc); @@ -151,6 +154,9 @@ namespace xo { **/ void on_parsed_typedescr(TypeDescr td); + /** respond to type emitted by nested ssm **/ + void on_parsed_type(obj type); + /** update state to consume param (name, type) emitted by * nested (expired) parsing state **/ diff --git a/include/xo/reader2/ReaderConfig.hpp b/include/xo/reader2/ReaderConfig.hpp index e139e9eb..513f515e 100644 --- a/include/xo/reader2/ReaderConfig.hpp +++ b/include/xo/reader2/ReaderConfig.hpp @@ -37,7 +37,7 @@ namespace xo { .header_{}, .debug_flag_ = false }; - /** configuration for hash map for global symbol table + /** configuration for hash map for global symbol table (variables) * * reminder: ownership chain * SchematikaReader @@ -45,9 +45,25 @@ namespace xo { * ->ParserStateMachine * ->DGlobalSymtab **/ - ArenaHashMapConfig symtab_config_ { .name_ = "global-symtab", - .hint_max_capacity_ = 64*1024, - .debug_flag_ = false }; + 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; diff --git a/include/xo/reader2/ssm/IPrintable_DDeftypeSsm.hpp b/include/xo/reader2/ssm/IPrintable_DDeftypeSsm.hpp new file mode 100644 index 00000000..df8820c0 --- /dev/null +++ b/include/xo/reader2/ssm/IPrintable_DDeftypeSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DDeftypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDeftypeSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DDeftypeSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DDeftypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DDeftypeSsm + **/ + class IPrintable_DDeftypeSsm { + public: + /** @defgroup scm-printable-ddeftypessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-ddeftypessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DDeftypeSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/include/xo/reader2/ssm/ISyntaxStateMachine_DDeftypeSsm.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DDeftypeSsm.hpp new file mode 100644 index 00000000..114f2dab --- /dev/null +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_DDeftypeSsm.hpp @@ -0,0 +1,84 @@ +/** @file ISyntaxStateMachine_DDeftypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DDeftypeSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DDeftypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DDeftypeSsm + **/ + class ISyntaxStateMachine_DDeftypeSsm { + public: + /** @defgroup scm-syntaxstatemachine-ddeftypessm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-ddeftypessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DDeftypeSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DDeftypeSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DDeftypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DDeftypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DDeftypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DDeftypeSsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DDeftypeSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DDeftypeSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DDeftypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DDeftypeSsm & self, obj lit, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/include/xo/reader2/syntaxstatetype.hpp b/include/xo/reader2/syntaxstatetype.hpp index 4d857d53..a01dcb62 100644 --- a/include/xo/reader2/syntaxstatetype.hpp +++ b/include/xo/reader2/syntaxstatetype.hpp @@ -21,6 +21,9 @@ namespace xo { /** handle define-expression. See @ref DDefineSsm **/ defexpr, + /** handle deftype-expression. See @ref DDeftypeSsm **/ + deftypeexpr, + /** handle lambda-expression. See @ref DLambdaSsm **/ lambdaexpr, diff --git a/src/reader2/CMakeLists.txt b/src/reader2/CMakeLists.txt index 8633f75a..53c69bc6 100644 --- a/src/reader2/CMakeLists.txt +++ b/src/reader2/CMakeLists.txt @@ -25,6 +25,10 @@ set(SELF_SRCS ISyntaxStateMachine_DDefineSsm.cpp IPrintable_DDefineSsm.cpp + DDeftypeSsm.cpp + ISyntaxStateMachine_DDeftypeSsm.cpp + IPrintable_DDeftypeSsm.cpp + DIfElseSsm.cpp ISyntaxStateMachine_DIfElseSsm.cpp IPrintable_DIfElseSsm.cpp diff --git a/src/reader2/DApplySsm.cpp b/src/reader2/DApplySsm.cpp index b0653a52..ad9a4e50 100644 --- a/src/reader2/DApplySsm.cpp +++ b/src/reader2/DApplySsm.cpp @@ -139,6 +139,7 @@ namespace xo { return; case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_then: case tokentype::tk_else: diff --git a/src/reader2/DDefineSsm.cpp b/src/reader2/DDefineSsm.cpp index 8266046f..344e1fc1 100644 --- a/src/reader2/DDefineSsm.cpp +++ b/src/reader2/DDefineSsm.cpp @@ -13,14 +13,6 @@ #include #include -#ifdef NOT_YET -#include "parserstatemachine.hpp" -#include "expect_symbol_xs.hpp" -#include "expect_expr_xs.hpp" -#include "expect_type_xs.hpp" -#include "pretty_expression.hpp" -#endif - namespace xo { using xo::print::APrintable; using xo::facet::FacetRegistry; @@ -526,6 +518,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_deftype: case tokentype::tk_string: case tokentype::tk_f64: case tokentype::tk_i64: @@ -600,7 +593,7 @@ namespace xo { if (defstate_ == defexprstatetype::def_2) { this->defstate_ = defexprstatetype::def_3; - DExpectTypeSsm::start(p_psm); + DExpectTypeSsm::start(false /*!corrected*/, p_psm); return; } @@ -688,7 +681,6 @@ namespace xo { = FacetRegistry::instance().variant(def_expr_); assert(expr.data()); - (void)expr; return ppii.pps()->pretty_struct(ppii, "DDefineSsm", diff --git a/src/reader2/DDeftypeSsm.cpp b/src/reader2/DDeftypeSsm.cpp new file mode 100644 index 00000000..ec36391a --- /dev/null +++ b/src/reader2/DDeftypeSsm.cpp @@ -0,0 +1,275 @@ +/** @file DDeftypeSsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "DeftypeSsm.hpp" +#include "syntaxstatetype.hpp" +#include "ExpectSymbolSsm.hpp" +#include "ExpectTypeSsm.hpp" +#include "Constant.hpp" +#include +#include + +namespace xo { + namespace scm { + + extern const char * + DeftypeXst::_descr(enum DeftypeXst::code x) + { + switch (x) { + case code::invalid: return "invalid"; + case code::def_0: return "def_0"; + case code::def_1: return "def_1"; + case code::def_2: return "def_2"; + case code::def_3: return "def_3"; + case code::def_4: return "def_4"; + case code::N: break; + } + + return "?DeftypeXst"; + } + + std::ostream & + operator<<(std::ostream & os, DeftypeXst x) + { + os << DeftypeXst::_descr(x.code()); + return os; + } + + DDeftypeSsm::DDeftypeSsm() + : deftype_xst_{DeftypeXst::code::def_0} + {} + + DDeftypeSsm * + DDeftypeSsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc_for(); + + return new (mem) DDeftypeSsm(); + } + + obj + DDeftypeSsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + void + DDeftypeSsm::start(DArena & mm, + ParserStateMachine * p_psm) + { + assert(p_psm->stack()); + + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + auto deftype_ssm = DDeftypeSsm::make(mm); + + p_psm->push_ssm(ckp, deftype_ssm); + } + + syntaxstatetype + DDeftypeSsm::ssm_type() const noexcept + { + return syntaxstatetype::deftypeexpr; + } + + std::string_view + DDeftypeSsm::get_expect_str() const noexcept + { + switch (this->deftype_xst_.code()) { + case DeftypeXst::code::invalid: + break; + case DeftypeXst::code::def_0: + return "deftype"; + case DeftypeXst::code::def_1: + return "symbol"; + case DeftypeXst::code::def_2: + return "doublecolon"; + case DeftypeXst::code::def_3: + return "type"; + case DeftypeXst::code::def_4: + return "semicolon"; + case DeftypeXst::code::N: + break; + + } + + return "?expect"; + } + + void + DDeftypeSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + + case tokentype::tk_deftype: + this->on_deftype_token(tk, p_psm); + return; + + case tokentype::tk_doublecolon: + this->on_doublecolon_token(tk, p_psm); + return; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + return; + + // all the not-yet handled cases + case tokentype::tk_symbol: + case tokentype::tk_def: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_invalid: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_if: + case tokentype::tk_quote: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + Super::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_deftype_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_0) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_1); + + DExpectSymbolSsm::start(p_psm); + + /* continue in .on_parsed_symbol() */ + + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_parsed_symbol(std::string_view sym_name, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_1) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_2); + this->lhs_symbol_ = p_psm->intern_string(sym_name); + + return; + } + + Super::illegal_parsed_symbol(sym_name, p_psm); + } + + void + DDeftypeSsm::on_doublecolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_2) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_3); + + DExpectTypeSsm::start(true /*corrected*/, p_psm); + + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_parsed_type(obj type, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_3) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_4); + + DLocalSymtab * local = p_psm->local_symtab(); + + if (local) { + local->append_type(p_psm->expr_alloc(), + lhs_symbol_, + type); + } else { + DGlobalSymtab * global = p_psm->global_symtab(); + + DTypename * tname = DTypename::_make(p_psm->expr_alloc(), + lhs_symbol_, + type); + + global->upsert_typename(p_psm->expr_alloc(), tname); + } + + return; + } + + Super::illegal_type(type, p_psm); + } + + void + DDeftypeSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_4) { + p_psm->pop_ssm(); + + // Reporting a placeholder expression to preserve policy + // that 'every toplevel statement produces an expression' + // + auto result_expr + = DConstant::make(p_psm->expr_alloc(), + DBoolean::box(p_psm->expr_alloc(), + true)); + p_psm->on_parsed_expression(result_expr); + + return; + } + + Super::illegal_token(tk, p_psm); + } + + bool + DDeftypeSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DDeftypeSsm", + refrtag("deftypestate", deftype_xst_), + refrtag("expect", this->get_expect_str())); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDeftypeSsm.cpp */ diff --git a/src/reader2/DExpectExprSsm.cpp b/src/reader2/DExpectExprSsm.cpp index 40ed2476..c2d46140 100644 --- a/src/reader2/DExpectExprSsm.cpp +++ b/src/reader2/DExpectExprSsm.cpp @@ -165,6 +165,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_deftype: case tokentype::tk_singleassign: case tokentype::tk_colon: case tokentype::tk_semicolon: diff --git a/src/reader2/DExpectFormalArgSsm.cpp b/src/reader2/DExpectFormalArgSsm.cpp index 7986a6de..db287abf 100644 --- a/src/reader2/DExpectFormalArgSsm.cpp +++ b/src/reader2/DExpectFormalArgSsm.cpp @@ -105,6 +105,7 @@ namespace xo { case tokentype::tk_leftparen: case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_singleassign: @@ -154,7 +155,7 @@ namespace xo { if (fstate_ == formalstatetype::formal_1) { this->fstate_ = formalstatetype::formal_2; - DExpectTypeSsm::start(p_psm); + DExpectTypeSsm::start(false /*!corrected*/, p_psm); /* control reenters via DExpectFormalArgSsm::on_parsed_typedescr() */ return; diff --git a/src/reader2/DExpectFormalArglistSsm.cpp b/src/reader2/DExpectFormalArglistSsm.cpp index 1de4533b..67f327e1 100644 --- a/src/reader2/DExpectFormalArglistSsm.cpp +++ b/src/reader2/DExpectFormalArglistSsm.cpp @@ -135,6 +135,7 @@ namespace xo { // all the not-yet-handled cases case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: diff --git a/src/reader2/DExpectQArraySsm.cpp b/src/reader2/DExpectQArraySsm.cpp index b4a9ac29..33ccd7c8 100644 --- a/src/reader2/DExpectQArraySsm.cpp +++ b/src/reader2/DExpectQArraySsm.cpp @@ -92,6 +92,7 @@ namespace xo { case tokentype::tk_comma: case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: diff --git a/src/reader2/DExpectQListSsm.cpp b/src/reader2/DExpectQListSsm.cpp index 2227a398..9584bfea 100644 --- a/src/reader2/DExpectQListSsm.cpp +++ b/src/reader2/DExpectQListSsm.cpp @@ -92,6 +92,7 @@ namespace xo { case tokentype::tk_comma: case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: diff --git a/src/reader2/DExpectQLiteralSsm.cpp b/src/reader2/DExpectQLiteralSsm.cpp index e03e7a39..7dc30124 100644 --- a/src/reader2/DExpectQLiteralSsm.cpp +++ b/src/reader2/DExpectQLiteralSsm.cpp @@ -110,6 +110,7 @@ namespace xo { case tokentype::tk_comma: case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: diff --git a/src/reader2/DExpectSymbolSsm.cpp b/src/reader2/DExpectSymbolSsm.cpp index 0a5d7abb..79ae0622 100644 --- a/src/reader2/DExpectSymbolSsm.cpp +++ b/src/reader2/DExpectSymbolSsm.cpp @@ -74,6 +74,7 @@ namespace xo { case tokentype::tk_i64: case tokentype::tk_bool: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_singleassign: case tokentype::tk_colon: diff --git a/src/reader2/DExpectTypeSsm.cpp b/src/reader2/DExpectTypeSsm.cpp index e4078936..edd71d66 100644 --- a/src/reader2/DExpectTypeSsm.cpp +++ b/src/reader2/DExpectTypeSsm.cpp @@ -3,14 +3,15 @@ * @author Roland Conybeare, Aug 2024 **/ -#include "DExpectTypeSsm.hpp" -#include "ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp" +#include "ExpectTypeSsm.hpp" +//#include "ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp" #include "SyntaxStateMachine.hpp" -#include +#include #include #include #include #include +#include namespace xo { using xo::facet::with_facet; @@ -19,30 +20,32 @@ namespace xo { using xo::reflect::typeseq; namespace scm { - DExpectTypeSsm::DExpectTypeSsm() + DExpectTypeSsm::DExpectTypeSsm(bool corrected) + : corrected_{corrected} {} DExpectTypeSsm * - DExpectTypeSsm::_make(DArena & mm) + DExpectTypeSsm::_make(DArena & mm, bool corrected) { void * mem = mm.alloc(typeseq::id(), sizeof(DArena)); - return new (mem) DExpectTypeSsm(); + return new (mem) DExpectTypeSsm(corrected); } obj - DExpectTypeSsm::make(DArena & mm) + DExpectTypeSsm::make(DArena & mm, bool corrected) { - return obj(_make(mm)); + return obj(_make(mm, corrected)); } void - DExpectTypeSsm::start(ParserStateMachine * p_psm) + DExpectTypeSsm::start(bool corrected, + ParserStateMachine * p_psm) { DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); - auto ssm = DExpectTypeSsm::make(p_psm->parser_alloc()); + auto ssm = DExpectTypeSsm::make(p_psm->parser_alloc(), corrected); p_psm->push_ssm(ckp, ssm); } @@ -73,6 +76,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_f64: case tokentype::tk_i64: @@ -124,32 +128,57 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); - TypeDescr td = nullptr; + if (corrected_) { + obj type; + obj mm = p_psm->expr_alloc(); - /* TODO: replace with typetable lookup */ + if (tk.text() == "unit") + type = DAtomicType::make(mm, Metatype::t_unit()); + if (tk.text() == "bool") + type = DAtomicType::make(mm, Metatype::t_bool()); + else if (tk.text() == "str") + type = DAtomicType::make(mm, Metatype::t_str()); + else if (tk.text() == "f64") + type = DAtomicType::make(mm, Metatype::t_f64()); + else if(tk.text() == "f32") + type = DAtomicType::make(mm, Metatype::t_f32()); + else if(tk.text() == "i16") + type = DAtomicType::make(mm, Metatype::t_i16()); + else if(tk.text() == "i32") + type = DAtomicType::make(mm, Metatype::t_i32()); + else if(tk.text() == "i64") + type = DAtomicType::make(mm, Metatype::t_i64()); - if (tk.text() == "bool") - td = Reflect::require(); - else if (tk.text() == "str") - td = Reflect::require(); - else if (tk.text() == "f64") - td = Reflect::require(); - else if(tk.text() == "f32") - td = Reflect::require(); - else if(tk.text() == "i16") - td = Reflect::require(); - else if(tk.text() == "i32") - td = Reflect::require(); - else if(tk.text() == "i64") - td = Reflect::require(); + p_psm->pop_ssm(); + p_psm->on_parsed_type(type); + } else { + TypeDescr td = nullptr; - if (!td) { - Super::on_token(tk, p_psm); - return; + /* TODO: replace with typetable lookup */ + + if (tk.text() == "bool") + td = Reflect::require(); + else if (tk.text() == "str") + td = Reflect::require(); + else if (tk.text() == "f64") + td = Reflect::require(); + else if(tk.text() == "f32") + td = Reflect::require(); + else if(tk.text() == "i16") + td = Reflect::require(); + else if(tk.text() == "i32") + td = Reflect::require(); + else if(tk.text() == "i64") + td = Reflect::require(); + + if (!td) { + Super::on_token(tk, p_psm); + return; + } + + p_psm->pop_ssm(); + p_psm->on_parsed_typedescr(td); } - - p_psm->pop_ssm(); - p_psm->on_parsed_typedescr(td); } bool diff --git a/src/reader2/DIfElseSsm.cpp b/src/reader2/DIfElseSsm.cpp index 5a17054d..00a41750 100644 --- a/src/reader2/DIfElseSsm.cpp +++ b/src/reader2/DIfElseSsm.cpp @@ -147,6 +147,7 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: break; case tokentype::tk_if: this->on_if_token(tk, p_psm); diff --git a/src/reader2/DLambdaSsm.cpp b/src/reader2/DLambdaSsm.cpp index c0eb92cf..9364476a 100644 --- a/src/reader2/DLambdaSsm.cpp +++ b/src/reader2/DLambdaSsm.cpp @@ -3,34 +3,22 @@ * @author Roland Conybeare, Jan 2026 **/ -#include "DLambdaSsm.hpp" -#include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" -#include "DExpectFormalArglistSsm.hpp" -#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" +#include "LambdaSsm.hpp" +//#include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" +#include "ExpectFormalArglistSsm.hpp" +//#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" #include "DExpectTypeSsm.hpp" #include "DExpectExprSsm.hpp" #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" #include -#include -#include +#include +//#include //#include #include #include #include -#ifdef NOT_YET -#include "define_xs.hpp" -#include "parserstatemachine.hpp" -#include "exprstatestack.hpp" -#include "expect_formal_arglist_xs.hpp" -#include "expect_expr_xs.hpp" -#include "expect_type_xs.hpp" -#include "pretty_expression.hpp" -#include "pretty_variable.hpp" -#include "xo/expression/Lambda.hpp" -#endif - namespace xo { using xo::print::APrintable; using xo::mm::AAllocator; @@ -144,6 +132,7 @@ namespace xo { // all the not-yet-handled cases case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: @@ -209,7 +198,7 @@ namespace xo { if (lmstate_ == lambdastatetype::lm_2) { this->lmstate_ = lambdastatetype::lm_3; - DExpectTypeSsm::start(p_psm); + DExpectTypeSsm::start(false /*!corrected*/, p_psm); /* control reenters via .on_parsed_typedescr() */ return; @@ -300,7 +289,8 @@ namespace xo { DLocalSymtab * symtab = DLocalSymtab::_make_empty(p_psm->expr_alloc(), p_psm->local_symtab(), - arglist->size()); + arglist->size(), + 0 /*ntypes*/); assert(symtab); for (DArray::size_type i = 0, n = arglist->size(); i < n; ++i) { diff --git a/src/reader2/DParenSsm.cpp b/src/reader2/DParenSsm.cpp index 53dc3063..d3fb5cfa 100644 --- a/src/reader2/DParenSsm.cpp +++ b/src/reader2/DParenSsm.cpp @@ -102,6 +102,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_colon: case tokentype::tk_singleassign: case tokentype::tk_semicolon: diff --git a/src/reader2/DProgressSsm.cpp b/src/reader2/DProgressSsm.cpp index 02d09e8a..edb55001 100644 --- a/src/reader2/DProgressSsm.cpp +++ b/src/reader2/DProgressSsm.cpp @@ -284,6 +284,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_quote: case tokentype::tk_leftbracket: diff --git a/src/reader2/DQuoteSsm.cpp b/src/reader2/DQuoteSsm.cpp index 1ca8a8a2..7f6dd00d 100644 --- a/src/reader2/DQuoteSsm.cpp +++ b/src/reader2/DQuoteSsm.cpp @@ -18,7 +18,7 @@ namespace xo { extern const char * QuoteXst::_descr(enum QuoteXst::code x) { - switch(x) { + switch (x) { case code::invalid: return "invalid"; case code::quote_0: return "quote_0"; case code::quote_1: return "quote_1"; @@ -104,6 +104,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_colon: case tokentype::tk_singleassign: case tokentype::tk_semicolon: diff --git a/src/reader2/DSequenceSsm.cpp b/src/reader2/DSequenceSsm.cpp index 12d47a9d..8bb2f779 100644 --- a/src/reader2/DSequenceSsm.cpp +++ b/src/reader2/DSequenceSsm.cpp @@ -81,6 +81,7 @@ namespace xo { return; case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_then: case tokentype::tk_else: diff --git a/src/reader2/DToplevelSeqSsm.cpp b/src/reader2/DToplevelSeqSsm.cpp index d7444e43..45a91a90 100644 --- a/src/reader2/DToplevelSeqSsm.cpp +++ b/src/reader2/DToplevelSeqSsm.cpp @@ -6,6 +6,7 @@ #include "DToplevelSeqSsm.hpp" #include "ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp" #include "DDefineSsm.hpp" +#include "DDeftypeSsm.hpp" #include "DLambdaSsm.hpp" #include "ProgressSsm.hpp" #include "DIfElseSsm.hpp" @@ -15,20 +16,10 @@ #include "VarRef.hpp" #include -//#include - #include -//#include - #include -//#include - #include -//#include - #include -//#include - #include namespace xo { @@ -133,6 +124,10 @@ namespace xo { this->on_def_token(tk, p_psm); return; + case tokentype::tk_deftype: + this->on_deftype_token(tk, p_psm); + return; + case tokentype::tk_lambda: this->on_lambda_token(tk, p_psm); return; @@ -255,6 +250,17 @@ namespace xo { */ } + void + DToplevelSeqSsm::on_deftype_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DDeftypeSsm::start(p_psm->parser_alloc(), + p_psm); + p_psm->on_token(Token::deftype_token()); + } + void DToplevelSeqSsm::on_lambda_token(const Token & tk, ParserStateMachine * p_psm) @@ -462,8 +468,8 @@ namespace xo { void DToplevelSeqSsm::on_parsed_expression_with_token(obj expr, - const Token & tk, - ParserStateMachine * p_psm) + const Token & tk, + ParserStateMachine * p_psm) { if (tk.tk_type() == tokentype::tk_semicolon) { p_psm->capture_result("DToplevelSeqSsm::on_parsed_expression_with_token", expr); diff --git a/src/reader2/IPrintable_DDeftypeSsm.cpp b/src/reader2/IPrintable_DDeftypeSsm.cpp new file mode 100644 index 00000000..8f36fd09 --- /dev/null +++ b/src/reader2/IPrintable_DDeftypeSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DDeftypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDeftypeSsm.json5] +**/ + +#include "ssm/IPrintable_DDeftypeSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DDeftypeSsm::pretty(const DDeftypeSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DDeftypeSsm.cpp */ diff --git a/src/reader2/ISyntaxStateMachine_DDeftypeSsm.cpp b/src/reader2/ISyntaxStateMachine_DDeftypeSsm.cpp new file mode 100644 index 00000000..9fcc835f --- /dev/null +++ b/src/reader2/ISyntaxStateMachine_DDeftypeSsm.cpp @@ -0,0 +1,84 @@ +/** @file ISyntaxStateMachine_DDeftypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DDeftypeSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DDeftypeSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DDeftypeSsm::ssm_type(const DDeftypeSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DDeftypeSsm::get_expect_str(const DDeftypeSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DDeftypeSsm::on_token(DDeftypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_symbol(DDeftypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_typedescr(DDeftypeSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_type(DDeftypeSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_formal(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_formal_with_token(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_formal_arglist(DDeftypeSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_expression(DDeftypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_expression_with_token(DDeftypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_quoted_literal(DDeftypeSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DDeftypeSsm.cpp */ diff --git a/src/reader2/ParserStateMachine.cpp b/src/reader2/ParserStateMachine.cpp index 3c640332..360ae43e 100644 --- a/src/reader2/ParserStateMachine.cpp +++ b/src/reader2/ParserStateMachine.cpp @@ -25,7 +25,8 @@ namespace xo { namespace scm { ParserStateMachine::ParserStateMachine(const ArenaConfig & config, - const ArenaHashMapConfig & symtab_config, + const ArenaHashMapConfig & symtab_var_config, + const ArenaHashMapConfig & symtab_type_config, size_type max_stringtable_capacity, obj expr_alloc, obj aux_alloc) @@ -33,7 +34,9 @@ namespace xo { parser_alloc_{DArena::map(config)}, expr_alloc_{expr_alloc}, aux_alloc_{aux_alloc}, - global_symtab_{DGlobalSymtab::make(expr_alloc, aux_alloc, symtab_config)}, + global_symtab_{DGlobalSymtab::make(expr_alloc, aux_alloc, + symtab_var_config, + symtab_type_config)}, debug_flag_{config.debug_flag_} { } @@ -275,6 +278,16 @@ namespace xo { this->stack_->top().on_parsed_typedescr(td, this); } + void + ParserStateMachine::on_parsed_type(obj type) + { + scope log(XO_DEBUG(debug_flag_)); + + assert(stack_); + + this->stack_->top().on_parsed_type(type, this); + } + void ParserStateMachine::on_parsed_formal(const DUniqueString * sym, TypeDescr td) diff --git a/src/reader2/SchematikaParser.cpp b/src/reader2/SchematikaParser.cpp index 74e17576..d6ab1a0a 100644 --- a/src/reader2/SchematikaParser.cpp +++ b/src/reader2/SchematikaParser.cpp @@ -23,11 +23,14 @@ namespace xo { SchematikaParser::SchematikaParser(const ParserConfig & cfg, obj expr_alloc, obj aux_alloc) - : psm_{cfg.parser_arena_config_, - cfg.symtab_config_, - cfg.max_stringtable_capacity_, - expr_alloc, - aux_alloc}, + : psm_{ + cfg.parser_arena_config_, + cfg.symtab_var_config_, + cfg.symtab_types_config_, + cfg.max_stringtable_capacity_, + expr_alloc, + aux_alloc + }, debug_flag_{cfg.debug_flag_} { } diff --git a/src/reader2/SchematikaReader.cpp b/src/reader2/SchematikaReader.cpp index f9cad55a..0725a18c 100644 --- a/src/reader2/SchematikaReader.cpp +++ b/src/reader2/SchematikaReader.cpp @@ -15,7 +15,8 @@ namespace xo { : tokenizer_{config.tk_buffer_config_, config.tk_debug_flag_}, parser_{ParserConfig(config.parser_arena_config_, - config.symtab_config_, + config.symtab_var_config_, + config.symtab_types_config_, config.max_stringtable_cap_, config.parser_debug_flag_), expr_alloc, diff --git a/src/reader2/reader2_register_facets.cpp b/src/reader2/reader2_register_facets.cpp index 909c1bc2..5262c1e9 100644 --- a/src/reader2/reader2_register_facets.cpp +++ b/src/reader2/reader2_register_facets.cpp @@ -8,6 +8,7 @@ #include "SchematikaParser.hpp" #include "ToplevelSeqSsm.hpp" #include "DefineSsm.hpp" +#include "DeftypeSsm.hpp" #include "LambdaSsm.hpp" #include "IfElseSsm.hpp" #include "ApplySsm.hpp" @@ -47,6 +48,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -98,6 +102,7 @@ namespace xo { log && log(xtag("DToplevelSeqSsm.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); + log && log(xtag("DDeftypeSsm.tseq", typeseq::id())); log && log(xtag("DLambdaSsm.tseq", typeseq::id())); log && log(xtag("DIfElseSsm.tseq", typeseq::id())); log && log(xtag("DExpectFormalArglistSsm.tseq", typeseq::id())); diff --git a/src/reader2/syntaxstatetype.cpp b/src/reader2/syntaxstatetype.cpp index 9b6c0928..4aa21b0c 100644 --- a/src/reader2/syntaxstatetype.cpp +++ b/src/reader2/syntaxstatetype.cpp @@ -15,6 +15,8 @@ namespace xo { break; case syntaxstatetype::defexpr: return "defexpr"; + case syntaxstatetype::deftypeexpr: + return "deftypeexpr"; case syntaxstatetype::lambdaexpr: return "lambdaexpr"; case syntaxstatetype::ifelseexpr: diff --git a/utest/SchematikaParser.test.cpp b/utest/SchematikaParser.test.cpp index c299306f..c2591815 100644 --- a/utest/SchematikaParser.test.cpp +++ b/utest/SchematikaParser.test.cpp @@ -77,7 +77,8 @@ namespace xo { ParserConfig cfg; cfg.parser_arena_config_.size_ = 16 * 1024; /* editor bait: symbol table */ - cfg.symtab_config_.hint_max_capacity_ = 128; + cfg.symtab_var_config_.hint_max_capacity_ = 128; + cfg.symtab_types_config_.hint_max_capacity_ = 64; cfg.max_stringtable_capacity_ = 512; cfg.debug_flag_ = false; @@ -272,6 +273,45 @@ namespace xo { log && fixture.log_memory_layout(&log); } + TEST_CASE("SchematikaParser-batch-deftype", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); + + parser.begin_batch_session(); + + /** Walkthrough parsing input equivalent to: + * + * deftype foo :: f64; + **/ + + std::vector tk_v{ + Token::deftype_token(), + Token::symbol_token("foo"), + Token::doublecolon_token(), + Token::symbol_token("f64"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + const auto & result = parser.result(); + { + // placeholder for form's sake. + // deftype doesn't actuallly produce any executable content + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + } + + log && fixture.log_memory_layout(&log); + } + TEST_CASE("SchematikaParser-interactive-def2", "[reader2][SchematikaParser]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); @@ -1325,7 +1365,7 @@ namespace xo { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag);