From da0d7369461986df09c51944bb74b17d1ce339fc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 19 Jan 2026 21:25:30 -0500 Subject: [PATCH] xo-reader2 xo-expresion2: work on define-expressions [WIP] --- CMakeLists.txt | 16 ++++ idl/IExpression_DDefineExpr.json5 | 12 +++ include/xo/expression2/Binding.hpp | 2 + include/xo/expression2/DDefineExpr.hpp | 75 +++++++++++++++++++ include/xo/expression2/DGlobalSymtab.hpp | 39 ++++++++++ include/xo/expression2/DVariable.hpp | 26 ++++++- .../detail/IExpression_DDefineExpr.hpp | 66 ++++++++++++++++ include/xo/expression2/exprtype.hpp | 4 + src/expression2/CMakeLists.txt | 5 ++ src/expression2/DDefineExpr.cpp | 71 ++++++++++++++++++ src/expression2/DGlobalSymtab.cpp | 27 +++++++ src/expression2/DLocalSymtab.cpp | 25 +++++++ src/expression2/DVariable.cpp | 22 ++++++ src/expression2/IExpression_DDefineExpr.cpp | 45 +++++++++++ 14 files changed, 431 insertions(+), 4 deletions(-) create mode 100644 idl/IExpression_DDefineExpr.json5 create mode 100644 include/xo/expression2/DDefineExpr.hpp create mode 100644 include/xo/expression2/DGlobalSymtab.hpp create mode 100644 include/xo/expression2/detail/IExpression_DDefineExpr.hpp create mode 100644 src/expression2/DDefineExpr.cpp create mode 100644 src/expression2/DGlobalSymtab.cpp create mode 100644 src/expression2/DLocalSymtab.cpp create mode 100644 src/expression2/IExpression_DDefineExpr.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fe5cd540..678e5eca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,8 @@ xo_add_genfacet( OUTPUT_CPP_DIR src/expression2 ) +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacet( TARGET xo-expression2-facet-expression @@ -66,6 +68,20 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/expression2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-expression-defineexpr + FACET_PKG xo_expression2 + FACET Expression + REPR DefineExpr + INPUT idl/IExpression_DDefineExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/expression2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-uniquestring diff --git a/idl/IExpression_DDefineExpr.json5 b/idl/IExpression_DDefineExpr.json5 new file mode 100644 index 00000000..ff35d6d6 --- /dev/null +++ b/idl/IExpression_DDefineExpr.json5 @@ -0,0 +1,12 @@ +{ + mode: "implementation", + includes: [ "\"Expression.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Expression.json5", + brief: "provide AExpression interface for DDefineExpr state", + using_doxygen: true, + repr: "DDefineExpr", + doc: ["doc for IExpression+DDefineExpr" ], +} diff --git a/include/xo/expression2/Binding.hpp b/include/xo/expression2/Binding.hpp index 455c1538..5f0f7e27 100644 --- a/include/xo/expression2/Binding.hpp +++ b/include/xo/expression2/Binding.hpp @@ -15,6 +15,7 @@ namespace xo { static constexpr int32_t s_link_global = -1; public: + Binding() : i_link_{-2}, j_slot_{-1} {} Binding(int32_t i_link, int32_t j_slot) : i_link_{i_link}, j_slot_{j_slot} {} @@ -32,6 +33,7 @@ namespace xo { * >= 0: number of parent links to traverse * to a fixed-size frame * -1: resolve globally + * -2: sentinel (binding info not computed) **/ int32_t i_link_ = s_link_sentinel; /** if @ref i_link_ >= 0, frame offset diff --git a/include/xo/expression2/DDefineExpr.hpp b/include/xo/expression2/DDefineExpr.hpp new file mode 100644 index 00000000..94a37197 --- /dev/null +++ b/include/xo/expression2/DDefineExpr.hpp @@ -0,0 +1,75 @@ +/** @file DDefineExpr.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Expression.hpp" +#include "DVariable.hpp" +#include + +namespace xo { + namespace scm { + class DUniqueString; // see DUniqueString.hpp + + /** @class DDefineExpr + * @brief an expression that introduces a variable. + * + * Variable may optionally be declared with a type, + * and may come with an expression specifying an initial value + **/ + class DDefineExpr { + public: + using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; + + public: + /** create instance: define-expr using memory from @p mm + * with lhs name @p lhs_name and rhs expression @p rhs_expr + **/ + static DDefineExpr * make(obj mm, + const DUniqueString * lhs_name, + obj rhs_expr); + /** create empty skeleton. Rely on this for parsing + **/ + static DDefineExpr * make_empty(obj mm); + + DVariable * lhs() const { return lhs_var_; } + obj rhs() const noexcept { return rhs_; } + + const DUniqueString * name() const noexcept; + + void assign_lhs_name(const DUniqueString * name); + /** CONCESSION. will use DUniqueString* once we have StringTable **/ + void assign_lhs_name(std::string_view name); + + /** @defgroup scm-defineexpr-expression-facet **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::define; } + TypeRef typeref() const noexcept { return lhs_var_->typeref(); } + TypeDescr valuetype() const noexcept { return lhs_var_->typeref().td(); } + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + + private: + DDefineExpr(DVariable * lhs_var, + obj rhs); + + private: + /** variable being defined by this expression. + **/ + DVariable * lhs_var_ = nullptr; + + /** expression for initial value of this expression + **/ + obj rhs_; + + // std::set free_var_set_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineExpr.hpp */ diff --git a/include/xo/expression2/DGlobalSymtab.hpp b/include/xo/expression2/DGlobalSymtab.hpp new file mode 100644 index 00000000..bb668ff3 --- /dev/null +++ b/include/xo/expression2/DGlobalSymtab.hpp @@ -0,0 +1,39 @@ +/** @file DGlobalSymtab.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "Binding.hpp" + +namespace xo { + namespace scm { + class DUniqueString; + + /** @class DGlobalSymtab + * @brief symbol table for toplevel environment + **/ + struct DGlobalSymtab { + public: + + + public: + /** @defgroup xo-expression2-symboltable-facet symboltable facet**/ + ///@{ + + /** true for global symbol table **/ + bool is_global_symtab() const noexcept { return true; } + + /** lookup binding for variable @p sym **/ + Binding lookup_binding(const DUniqueString * sym) const noexcept; + + ///@} + + private: + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalSymtab.hpp */ diff --git a/include/xo/expression2/DVariable.hpp b/include/xo/expression2/DVariable.hpp index 036d88ce..2208852e 100644 --- a/include/xo/expression2/DVariable.hpp +++ b/include/xo/expression2/DVariable.hpp @@ -19,15 +19,33 @@ namespace xo { **/ class DVariable { public: + using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; public: - DVariable(const DUniqueString & name, const TypeRef & typeref, Binding path) - : name_{name}, typeref_{typeref}, path_{path} {} + /** create instance + * @p mm memory allocator + * @p name variable name + * @p typeref type information for legal values + * (possibly just placeholder when relying on inference) + * @p path binding path to runtime value. + * This may be computed after parsing; + * mnust be resolved before execution. + **/ + static DVariable * make(obj mm, + const DUniqueString * name, + const TypeRef & typeref, + Binding path = Binding()); - const DUniqueString & name() const { return name_; } + DVariable(const DUniqueString * name, + const TypeRef & typeref, + Binding path); + + const DUniqueString * name() const { return name_; } Binding path() const { return path_; } + void assign_name(const DUniqueString * name) { this->name_ = name; } + /** @defgroup scm-variable-expression-facet**/ ///@{ @@ -40,7 +58,7 @@ namespace xo { private: /** symbol name **/ - const DUniqueString & name_; + const DUniqueString * name_; /** variable value always has type consistent * with this description **/ diff --git a/include/xo/expression2/detail/IExpression_DDefineExpr.hpp b/include/xo/expression2/detail/IExpression_DDefineExpr.hpp new file mode 100644 index 00000000..3ac7fd49 --- /dev/null +++ b/include/xo/expression2/detail/IExpression_DDefineExpr.hpp @@ -0,0 +1,66 @@ +/** @file IExpression_DDefineExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DDefineExpr.json5] + **/ + +#pragma once + +#include "Expression.hpp" +#include "Expression.hpp" +#include "DDefineExpr.hpp" + +namespace xo { namespace scm { class IExpression_DDefineExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IExpression_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IExpression_DDefineExpr + **/ + class IExpression_DDefineExpr { + public: + /** @defgroup scm-expression-ddefineexpr-type-traits **/ + ///@{ + using TypeDescr = xo::scm::AExpression::TypeDescr; + using Copaque = xo::scm::AExpression::Copaque; + using Opaque = xo::scm::AExpression::Opaque; + ///@} + /** @defgroup scm-expression-ddefineexpr-methods **/ + ///@{ + // const methods + /** expression type (constant | apply | ..) **/ + static exprtype extype(const DDefineExpr & self) noexcept; + /** placeholder for type giving possible values for this expression **/ + static TypeRef typeref(const DDefineExpr & self) noexcept; + /** type giving possible values for this expression. Maybe null before typecheck **/ + static TypeDescr valuetype(const DDefineExpr & self) noexcept; + + // non-const methods + /** assing to valuetype member. Useful when scaffolding expressions **/ + static void assign_valuetype(DDefineExpr & self, TypeDescr td) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/include/xo/expression2/exprtype.hpp b/include/xo/expression2/exprtype.hpp index 0d5e8299..d64a1191 100644 --- a/include/xo/expression2/exprtype.hpp +++ b/include/xo/expression2/exprtype.hpp @@ -23,8 +23,10 @@ namespace xo { #ifdef NOT_YET /** a literal constant that refers to a linkable named function **/ primitive, +#endif /** variable/function definition **/ define, +#ifdef NOT_YET /** variable assignment **/ assign, /** function call **/ @@ -55,7 +57,9 @@ namespace xo { case exprtype::constant: return "constant"; #ifdef NOT_YET case exprtype::primitive: return "primitive"; +#endif case exprtype::define: return "define"; +#ifdef NOT_YET case exprtype::assign: return "assign"; case exprtype::apply: return "apply"; case exprtype::lambda: return "lambda"; diff --git a/src/expression2/CMakeLists.txt b/src/expression2/CMakeLists.txt index 9194bfa5..0fcd6541 100644 --- a/src/expression2/CMakeLists.txt +++ b/src/expression2/CMakeLists.txt @@ -6,12 +6,17 @@ set(SELF_SRCS DConstant.cpp DVariable.cpp + DDefineExpr.cpp TypeRef.cpp IExpression_Any.cpp IExpression_DConstant.cpp IExpression_DVariable.cpp + IExpression_DDefineExpr.cpp + + DLocalSymtab.cpp + DGlobalSymtab.cpp ISymbolTable_Any.cpp diff --git a/src/expression2/DDefineExpr.cpp b/src/expression2/DDefineExpr.cpp new file mode 100644 index 00000000..14d1c52e --- /dev/null +++ b/src/expression2/DDefineExpr.cpp @@ -0,0 +1,71 @@ +/** @file DDefineExpr.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DDefineExpr.hpp" +#include + +namespace xo { + using xo::facet::typeseq; + + namespace scm { + + DDefineExpr::DDefineExpr(DVariable * lhs_var, + obj rhs) + : lhs_var_{lhs_var}, rhs_{rhs} + {} + + DDefineExpr * + DDefineExpr::make(obj mm, + const DUniqueString * lhs_name, + obj rhs_expr) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DDefineExpr)); + + auto lhs_var = DVariable::make(mm, + lhs_name, + rhs_expr.typeref()); + + return new (mem) DDefineExpr(lhs_var, rhs_expr); + } + + DDefineExpr * + DDefineExpr::make_empty(obj mm) + { + return make(mm, + nullptr /*lhs_name*/, + obj() /*rhs_expr*/); + } + + const DUniqueString * + DDefineExpr::name() const noexcept + { + return lhs_var_->name(); + } + + void + DDefineExpr::assign_lhs_name(const DUniqueString * name) + { + lhs_var_->assign_name(name); + } + + void + DDefineExpr::assign_lhs_name(std::string_view name) + { + scope log(XO_DEBUG(true), "bogus impl - will require unique string"); + log && log(xtag("name", name)); + + //lhs_var_->assign_name(name); + } + + void + DDefineExpr::assign_valuetype(TypeDescr td) noexcept + { + lhs_var_->assign_valuetype(td); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineExpr.cpp */ diff --git a/src/expression2/DGlobalSymtab.cpp b/src/expression2/DGlobalSymtab.cpp new file mode 100644 index 00000000..c11761d9 --- /dev/null +++ b/src/expression2/DGlobalSymtab.cpp @@ -0,0 +1,27 @@ +/** @file DGlobalSymtab.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DGlobalSymtab.hpp" +#include "DUniqueString.hpp" +#include + +namespace xo { + namespace scm { + + Binding + DGlobalSymtab::lookup_binding(const DUniqueString * sym) const noexcept + { + (void)sym; + + scope log(XO_DEBUG(true), "stub"); + log && log(xtag("sym", std::string_view(*sym))); + + return Binding(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalSymtab.cpp */ diff --git a/src/expression2/DLocalSymtab.cpp b/src/expression2/DLocalSymtab.cpp new file mode 100644 index 00000000..febd1463 --- /dev/null +++ b/src/expression2/DLocalSymtab.cpp @@ -0,0 +1,25 @@ +/** @file DLocalSymtab.cpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DLocalSymtab.hpp" +#include "DUniqueString.hpp" +#include + +namespace xo { + namespace scm { + + Binding + DLocalSymtab::lookup_binding(const DUniqueString * sym) const noexcept + { + scope log(XO_DEBUG(true), "stub impl"); + log && log(xtag("sym", std::string_view(*sym))); + + return Binding(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DLocalSymtab.cpp */ diff --git a/src/expression2/DVariable.cpp b/src/expression2/DVariable.cpp index f589da7b..d27c71ef 100644 --- a/src/expression2/DVariable.cpp +++ b/src/expression2/DVariable.cpp @@ -7,12 +7,34 @@ #include "exprtype.hpp" namespace xo { + using xo::facet::typeseq; + namespace scm { + + DVariable * + DVariable::make(obj mm, + const DUniqueString * name, + const TypeRef & typeref, + Binding path) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DVariable)); + + return new (mem) DVariable(name, typeref, path); + } + + DVariable::DVariable(const DUniqueString * name, + const TypeRef & typeref, + Binding path) + : name_{name}, typeref_{typeref}, path_{path} + {} + void DVariable::assign_valuetype(TypeDescr td) noexcept { typeref_.resolve(td); } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/expression2/IExpression_DDefineExpr.cpp b/src/expression2/IExpression_DDefineExpr.cpp new file mode 100644 index 00000000..3222eabd --- /dev/null +++ b/src/expression2/IExpression_DDefineExpr.cpp @@ -0,0 +1,45 @@ +/** @file IExpression_DDefineExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IExpression_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IExpression_DDefineExpr.json5] +**/ + +#include "detail/IExpression_DDefineExpr.hpp" + +namespace xo { + namespace scm { + auto + IExpression_DDefineExpr::extype(const DDefineExpr & self) noexcept -> exprtype + { + return self.extype(); + } + + auto + IExpression_DDefineExpr::typeref(const DDefineExpr & self) noexcept -> TypeRef + { + return self.typeref(); + } + + auto + IExpression_DDefineExpr::valuetype(const DDefineExpr & self) noexcept -> TypeDescr + { + return self.valuetype(); + } + + auto + IExpression_DDefineExpr::assign_valuetype(DDefineExpr & self, TypeDescr td) noexcept -> void + { + self.assign_valuetype(td); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IExpression_DDefineExpr.cpp */ \ No newline at end of file