From 37b0ea3c3e656498b8b51636e2930c560fcb365d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 17 Jan 2026 01:09:02 -0500 Subject: [PATCH] xo-expression2: + SymbolTable facet --- idl/SymbolTable.json5 | 59 +++++++++++++ include/xo/expression2/SymbolTable.hpp | 22 +++++ .../xo/expression2/symtab/ASymbolTable.hpp | 75 ++++++++++++++++ .../expression2/symtab/ISymbolTable_Any.hpp | 86 +++++++++++++++++++ .../expression2/symtab/ISymbolTable_Xfer.hpp | 84 ++++++++++++++++++ .../xo/expression2/symtab/RSymbolTable.hpp | 82 ++++++++++++++++++ src/expression2/CMakeLists.txt | 8 ++ src/expression2/ISymbolTable_Any.cpp | 41 +++++++++ 8 files changed, 457 insertions(+) create mode 100644 idl/SymbolTable.json5 create mode 100644 include/xo/expression2/SymbolTable.hpp create mode 100644 include/xo/expression2/symtab/ASymbolTable.hpp create mode 100644 include/xo/expression2/symtab/ISymbolTable_Any.hpp create mode 100644 include/xo/expression2/symtab/ISymbolTable_Xfer.hpp create mode 100644 include/xo/expression2/symtab/RSymbolTable.hpp create mode 100644 src/expression2/ISymbolTable_Any.cpp diff --git a/idl/SymbolTable.json5 b/idl/SymbolTable.json5 new file mode 100644 index 00000000..3d91a3d7 --- /dev/null +++ b/idl/SymbolTable.json5 @@ -0,0 +1,59 @@ +{ + mode: "facet", + includes: [ + "\"Binding.hpp\"", + "\"DUniqueString.hpp\"" + ], + // extra includes in SymbolTable.hpp, if any + user_hpp_includes: [], + namespace1: "xo", + namespace2: "scm", + // text after includes, before ASymbolTable + pretext: [ "// {pretext} here" ], + facet: "SymbolTable", + detail_subdir: "symtab", + brief: "symbol table derived from a set of schematika expressions", + using_doxygen: true, + doc: [ + "Map symbols to schematika expressions. Output of schematika parser" + ], + types: [ + // { name: string, doc: [ string ], definition: string }, + ], + const_methods: [ + + { + // bool is_global_symtab() const noexcept; + name: "is_global_symtab", + doc: ["true iff this is toplevel (global) symbol table."], + return_type: "bool", + args: [], + const: true, + noexcept: true, + attributes: [], + }, + + { + // Binding lookup_binding(const DUniqueString * sym) const noexcept; + name: "lookup_binding", + doc: ["report ingredients needed to address variable at runtime."], + return_type: "Binding", + args: [ + {type: "const DUniqueString *", name: "sym"}, + ], + const: true, + noexcept: true, + attributes: [], + }, + + // // + // obj lookup_var(const DUniqueString * sym) const noexcept; + + // // + // obj lookup_local(const DUniqueString * sym) const noexcept; + ], + nonconst_methods: [ + // // Variable gives both {name, type} + // void upsert_local(DVariable * target) = 0; + ], +} diff --git a/include/xo/expression2/SymbolTable.hpp b/include/xo/expression2/SymbolTable.hpp new file mode 100644 index 00000000..09fc04a8 --- /dev/null +++ b/include/xo/expression2/SymbolTable.hpp @@ -0,0 +1,22 @@ +/** @file SymbolTable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SymbolTable.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/SymbolTable.json5] + **/ + +#pragma once + +#include "symtab/ASymbolTable.hpp" +#include "symtab/ISymbolTable_Any.hpp" +#include "symtab/ISymbolTable_Xfer.hpp" +#include "symtab/RSymbolTable.hpp" + + +/* end SymbolTable.hpp */ \ No newline at end of file diff --git a/include/xo/expression2/symtab/ASymbolTable.hpp b/include/xo/expression2/symtab/ASymbolTable.hpp new file mode 100644 index 00000000..36d4c812 --- /dev/null +++ b/include/xo/expression2/symtab/ASymbolTable.hpp @@ -0,0 +1,75 @@ +/** @file ASymbolTable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SymbolTable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/SymbolTable.json5] + **/ + +#pragma once + +// includes (via {facet_includes}) +#include "Binding.hpp" +#include "DUniqueString.hpp" +#include +#include +#include + +// {pretext} here + +namespace xo { +namespace scm { + +using Copaque = const void *; +using Opaque = void *; + +/** +Map symbols to schematika expressions. Output of schematika parser +**/ +class ASymbolTable { +public: + /** @defgroup scm-symboltable-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; + ///@} + + /** @defgroup scm-symboltable-methods **/ + ///@{ + // const methods + /** RTTI: unique id# for actual runtime data representation **/ + virtual typeseq _typeseq() const noexcept = 0; + /** true iff this is toplevel (global) symbol table. **/ + virtual bool is_global_symtab(Copaque data) const noexcept = 0; + /** report ingredients needed to address variable at runtime. **/ + virtual Binding lookup_binding(Copaque data, const DUniqueString * sym) const noexcept = 0; + + // nonconst methods + ///@} +}; /*ASymbolTable*/ + +/** Implementation ISymbolTable_DRepr of ASymbolTable for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = ISymbolTable_DRepr; + * }; + * + * then ISymbolTable_ImplType --> ISymbolTable_DRepr + **/ +template +using ISymbolTable_ImplType = xo::facet::FacetImplType; + +} /*namespace scm*/ +} /*namespace xo*/ + +/* ASymbolTable.hpp */ \ No newline at end of file diff --git a/include/xo/expression2/symtab/ISymbolTable_Any.hpp b/include/xo/expression2/symtab/ISymbolTable_Any.hpp new file mode 100644 index 00000000..6a119832 --- /dev/null +++ b/include/xo/expression2/symtab/ISymbolTable_Any.hpp @@ -0,0 +1,86 @@ +/** @file ISymbolTable_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SymbolTable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/SymbolTable.json5] + **/ + +#pragma once + +#include "ASymbolTable.hpp" +#include + +namespace xo { namespace scm { class ISymbolTable_Any; } } + +namespace xo { +namespace facet { + +template <> +struct FacetImplementation +{ + using ImplType = xo::scm::ISymbolTable_Any; +}; + +} +} + +namespace xo { +namespace scm { + + /** @class ISymbolTable_Any + * @brief ASymbolTable implementation for empty variant instance + **/ + class ISymbolTable_Any : public ASymbolTable { + public: + /** @defgroup scm-symboltable-any-type-traits **/ + ///@{ + + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + + ///@} + /** @defgroup scm-symboltable-any-methods **/ + ///@{ + + const ASymbolTable * iface() const { return std::launder(this); } + + // from ASymbolTable + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] bool is_global_symtab(Copaque) const noexcept override { _fatal(); } + [[noreturn]] Binding lookup_binding(Copaque, const DUniqueString *) const noexcept override { _fatal(); } + + // nonconst methods + + ///@} + + private: + /** @defgraoup scm-symboltable-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup scm-symboltable-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace scm */ +} /*namespace xo */ + +/* ISymbolTable_Any.hpp */ \ No newline at end of file diff --git a/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp b/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp new file mode 100644 index 00000000..2333bb05 --- /dev/null +++ b/include/xo/expression2/symtab/ISymbolTable_Xfer.hpp @@ -0,0 +1,84 @@ +/** @file ISymbolTable_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SymbolTable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/SymbolTable.json5] + **/ + +#pragma once + +#include "Binding.hpp" +#include "DUniqueString.hpp" + +namespace xo { +namespace scm { + /** @class ISymbolTable_Xfer + **/ + template + class ISymbolTable_Xfer : public ASymbolTable { + public: + /** @defgroup scm-symboltable-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = ISymbolTable_DRepr; + /** integer identifying a type **/ + using typeseq = ASymbolTable::typeseq; + ///@} + + /** @defgroup scm-symboltable-xfer-methods **/ + ///@{ + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + + // from ASymbolTable + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + bool is_global_symtab(Copaque data) const noexcept override { + return I::is_global_symtab(_dcast(data)); + } + Binding lookup_binding(Copaque data, const DUniqueString * sym) const noexcept override { + return I::lookup_binding(_dcast(data), sym); + } + + // non-const methods + + ///@} + + private: + using I = Impl; + + public: + /** @defgroup scm-symboltable-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + xo::facet::typeseq + ISymbolTable_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + ISymbolTable_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace scm */ +} /*namespace xo*/ + +/* end ISymbolTable_Xfer.hpp */ \ No newline at end of file diff --git a/include/xo/expression2/symtab/RSymbolTable.hpp b/include/xo/expression2/symtab/RSymbolTable.hpp new file mode 100644 index 00000000..c72503cc --- /dev/null +++ b/include/xo/expression2/symtab/RSymbolTable.hpp @@ -0,0 +1,82 @@ +/** @file RSymbolTable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/SymbolTable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/SymbolTable.json5] + **/ + +#pragma once + +#include "ASymbolTable.hpp" + +namespace xo { +namespace scm { + +/** @class RSymbolTable + **/ +template +class RSymbolTable : public Object { +private: + using O = Object; + +public: + /** @defgroup scm-symboltable-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + using typeseq = xo::reflect::typeseq; + ///@} + + /** @defgroup scm-symboltable-router-ctors **/ + ///@{ + RSymbolTable() {} + RSymbolTable(Object::DataPtr data) : Object{std::move(data)} {} + RSymbolTable(const ASymbolTable * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} + + ///@} + /** @defgroup scm-symboltable-router-methods **/ + ///@{ + + // const methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + bool is_global_symtab() const noexcept { + return O::iface()->is_global_symtab(O::data()); + } + Binding lookup_binding(const DUniqueString * sym) const noexcept { + return O::iface()->lookup_binding(O::data(), sym); + } + + // non-const methods (still const in router!) + + ///@} + /** @defgroup scm-symboltable-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RSymbolTable::_valid = xo::facet::valid_object_router(); + +} /*namespace scm*/ +} /*namespace xo*/ + +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::scm::RSymbolTable; + }; +} } + +/* end RSymbolTable.hpp */ \ No newline at end of file diff --git a/src/expression2/CMakeLists.txt b/src/expression2/CMakeLists.txt index 6b897535..e7de9253 100644 --- a/src/expression2/CMakeLists.txt +++ b/src/expression2/CMakeLists.txt @@ -3,15 +3,23 @@ set(SELF_LIB xo_expression2) set(SELF_SRCS init_expression2.cpp + DConstant.cpp DVariable.cpp + TypeRef.cpp + IExpression_Any.cpp IExpression_DConstant.cpp + + ISymbolTable_Any.cpp + StringTable.cpp + DUniqueString.cpp IGCObject_DUniqueString.cpp IPrintable_DUniqueString.cpp + expression2_register_facets.cpp expression2_register_types.cpp ) diff --git a/src/expression2/ISymbolTable_Any.cpp b/src/expression2/ISymbolTable_Any.cpp new file mode 100644 index 00000000..7c811253 --- /dev/null +++ b/src/expression2/ISymbolTable_Any.cpp @@ -0,0 +1,41 @@ +/** @file ISymbolTable_Any.cpp + * + **/ + +#include "symtab/ISymbolTable_Any.hpp" +#include + +namespace xo { +namespace scm { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +ISymbolTable_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " ISymbolTable_Any method" + << std::endl; + std::terminate(); +} + +typeseq +ISymbolTable_Any::s_typeseq = typeseq::id(); + +bool +ISymbolTable_Any::_valid + = valid_facet_implementation(); + +// nonconst methods + + +} /*namespace scm*/ +} /*namespace xo*/ + +/* end ISymbolTable_Any.cpp */ \ No newline at end of file