From 7960e05b84c64d5ac53043cc8fd31f0d828de8bc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 30 Jan 2026 20:08:41 -0500 Subject: [PATCH] xo-expression2 xo-reader2 DSequenceExpr, DSequenceSsm [WIP] --- xo-expression2/DSequenceExpr.hpp | 77 ++++++++++ .../include/xo/expression2/exprtype.hpp | 4 +- .../src/expression2/DSequenceExpr.cpp | 88 +++++++++++ xo-object2/include/xo/object2/DArray.hpp | 2 + xo-reader2/include/xo/reader2/DDefineSsm.hpp | 15 -- .../include/xo/reader2/DSequenceSsm.hpp | 57 ++++++++ xo-reader2/src/reader2/DExpectExprSsm.cpp | 4 +- xo-reader2/src/reader2/DSequenceSsm.cpp | 137 ++++++++++++++++++ 8 files changed, 364 insertions(+), 20 deletions(-) create mode 100644 xo-expression2/DSequenceExpr.hpp create mode 100644 xo-expression2/src/expression2/DSequenceExpr.cpp create mode 100644 xo-reader2/include/xo/reader2/DSequenceSsm.hpp create mode 100644 xo-reader2/src/reader2/DSequenceSsm.cpp diff --git a/xo-expression2/DSequenceExpr.hpp b/xo-expression2/DSequenceExpr.hpp new file mode 100644 index 00000000..12caf649 --- /dev/null +++ b/xo-expression2/DSequenceExpr.hpp @@ -0,0 +1,77 @@ +/** @file DSequenceExpr.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "TypeRef.hpp" +#include + +namespace xo { + namespace scm { + + /** syntax for a sequence of expressions + * { + * expr(1); + * expr(2); + * ... + * expr(n); + * } + **/ + class DSequenceExpr { + public: + using size_type = DArray::size_type; + using ppindentinfo = xo::print::ppindentinfo; + + public: + DSequenceExpr() = default; + DSequenceExpr(DArray * xv) : expr_v_{xv} {} + + /** create empty sequence using memory from @p mm **/ + static obj make_empty(obj mm); + + /** create empty sequence expression using mmeory from @p mm **/ + static DSequenceExpr * _make_empty(obj mm); + + size_type size() const noexcept; + obj operator[](std::size_t i) const; + + /** append @p expr to the end of this sequence **/ + void push_back(obj expr); + + // get_free_variables(); + // visit_preorder(); + // visit_layer(); + // xform_layer() + // attach_envs() + + /** @defgroup scm-ifelseexpr-expression-facets **/ + ///@{ + + exprtype extype() const noexcept { return exprtype::sequence; } + TypeRef typeref() const noexcept { return typeref_; } + TypeDescr valuetype() const noexcept { return typeref_.td(); } + void assign_valuetype(TypeDescr td) noexcept; + + ///@} + /** @defgroup scm-sequenceexpr-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printing driver; combine layout+printing **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** expression value always has type consistent with this description + **/ + TypeRef typeref_; + /** array of expressions **/ + DArray * expr_v_ = nullptr; + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DSequenceExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/exprtype.hpp b/xo-expression2/include/xo/expression2/exprtype.hpp index 861d62bd..3bcda3c4 100644 --- a/xo-expression2/include/xo/expression2/exprtype.hpp +++ b/xo-expression2/include/xo/expression2/exprtype.hpp @@ -40,10 +40,10 @@ namespace xo { variable, /** if-then-else **/ ifexpr, -#ifdef NOT_YET /** sequence **/ sequence, - /** type conversion **/ +#ifdef NOT_YET + ) /** type conversion **/ convert, #endif diff --git a/xo-expression2/src/expression2/DSequenceExpr.cpp b/xo-expression2/src/expression2/DSequenceExpr.cpp new file mode 100644 index 00000000..c5abf27b --- /dev/null +++ b/xo-expression2/src/expression2/DSequenceExpr.cpp @@ -0,0 +1,88 @@ +/** @file DSequenceExpr.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "DSequenceExpr.hpp" + +namespace xo { + namespace scm { + + obj + DSequenceExpr::make_empty(obj mm) + { + return obj(_make_empty(mm)); + } + + DSequenceExpr * + DSequenceExpr::_make_empty(obj mm) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DSequenceExpr)); + + DSequenceExpr * expr = new (mem) DSequenceExpr(); + + constexpr size_type c_hint_capacity = 8; + + /** allocate 2nd, so it comes after DSequenceExpr in + * memory. This may later allow realloc + **/ + DArray * expr_v = DArray::empty(mm, + c_hint_capacity); + + expr->expr_v_ = expr_v; + + return expr; + } + + size_type + DSequenceExpr::size() const noexcept + { + return expr_v_->size(); + } + + obj + DSequenceExpr::operator[](std::size_t i) const + { + return (*expr_v_)[i]; + } + + void + DSequenceExpr::push_back(obj mm, + obj expr) + { + if (expr_v_->size() == expr_v_->capacity()) { + /* reallocate+expand */ + + DArray * expr_2x_v + = DArray::empty(mm, 2 * expr_v_->capacity()); + + for (size_type i = 0, z = expr_v_->size(); i < z; ++i) { + expr_2x_v->push_back((*expr_2x_v)[i]); + } + + this->expr_v_ = expr_2x_v; + } + + this->expr_v_->push_back(expr); + } + + void + DSequenceExpr::assign_valuetype(TypeDescr td) noexcept + { + typeref_.resolve(td); + } + + void + DSequenceExpr::pretty(const ppindentinfo & ppii) const + { + using xo::print::ppstate; + + ppstate * pps = ppii.pps(); + + xxx; + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DSequenceExpr.cpp */ diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index f50936e3..e95f67f6 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -68,6 +68,8 @@ namespace xo { requires (std::same_as> && ...) static DArray * array(obj mm, Args... args); + obj operator[](size_type index) const noexcept { return elts_[index]; } + ///@} /** @defgroup darray-access acecss methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 939d5479..34918dc9 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -169,21 +169,6 @@ namespace xo { void on_parsed_typedescr(TypeDescr td, ParserStateMachine * p_psm); -#ifdef OBSOLETE - /** update state for this ssm to consume param (name,value) - * emitted by nested @p_psm - **/ - void on_parsed_formal(const DUniqueString * param_name, - TypeDescr param_type, - ParserStateMachine * p_psm); - - /** consume formal params @p arglist from completed nested ssm, - * with overall parser state in @p p_psm. - **/ - void on_parsed_formal_arglist(DArray * arglist, - ParserStateMachine * p_psm); -#endif - /** update state for this syntax after parsing an expression @p expr, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DSequenceSsm.hpp b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp new file mode 100644 index 00000000..8d936254 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DSequenceSsm.hpp @@ -0,0 +1,57 @@ +/** @file DSequenceSsm.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +//#include "exprstate.hpp" + +namespace xo { + namespace scm { class Sequence; } + namespace scm { class Lambda; } + + namespace scm { + class DSequenceSsm : public DSyntaxStateMachine { + public: + using Sequence = xo::scm::Sequence; + using Lambda = xo::scm::Lambda; + + public: + const char * ssm_classname() const noexcept { return "DSequenceSsm"; } + +#ifdef NOT_YET + /** start parsing a sequence-expr. + * input begins with first expression in the sequence. + **/ + static void start(parserstatemachine * p_psm); + + /** named ctor idiom **/ + static std::unique_ptr make(); + + virtual void on_expr(bp expr, + parserstatemachine * p_psm) override; + virtual void on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) override; + + virtual void on_rightbrace_token(const token_type & tk, + parserstatemachine * p_psm) override; + + virtual void print(std::ostream & os) const override; + virtual bool pretty_print(const xo::print::ppindentinfo & ppii) const override; +#endif + + private: + DSequenceSsm(); + + private: + /** will build SequenceExpr from in-order contents of this array **/ + DArray * expr_v_; + //std::vector> expr_v_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DSequenceSsm.hpp */ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 899731a3..3b4b2c36 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -183,9 +183,7 @@ namespace xo { DExpectExprSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) { - p_psm->illegal_input_on_token("DExpectExprSsm", - tk, - this->get_expect_str()); + Super::on_token(tk, p_psm); } #ifdef NOT_YET diff --git a/xo-reader2/src/reader2/DSequenceSsm.cpp b/xo-reader2/src/reader2/DSequenceSsm.cpp new file mode 100644 index 00000000..285960bd --- /dev/null +++ b/xo-reader2/src/reader2/DSequenceSsm.cpp @@ -0,0 +1,137 @@ +/* @file DSequenceSsm.cpp */ + +#include "DSequenceSsm.hpp" + +#ifdef NOT_YET +#include "expect_expr_xs.hpp" +#include "let1_xs.hpp" +#include "xo/expression/DefineExpr.hpp" +#include "xo/expression/Sequence.hpp" +#include "xo/expression/pretty_expression.hpp" +#endif + +namespace xo { + using xo::scm::DefineExpr; + + namespace scm { +#ifdef NOT_YET + std::unique_ptr + sequence_xs::make() { + return std::make_unique(sequence_xs()); + } +#endif + + void + sequence_xs::start(parserstatemachine * p_psm) { + p_psm->push_exprstate(sequence_xs::make()); + /* want to accept anything that starts an expression, + * except that } ends it + */ + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } + + sequence_xs::sequence_xs() + : exprstate(exprstatetype::sequenceexpr) + {} + + void + sequence_xs::on_expr(bp expr, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + log && log(xtag("expr", expr.promote())); + + /* TODO: if expr is a DefineExpr, + * then need to rewrite... + * + * ...prefix + * DefineExpr(lhs_name, rhs) + * rest... + * + * becomes: + * + * /-- .outer_seq_expr_ + * v + * Sequence( + * ...prefix, + * + * /-- .inner_lm_expr_ + * v + * Apply(Lambda(gen999, + * [Variable(lhs_name, type(rhs))], + * /-- .expr_v_ + * v + * sequencify(rest...)), + * rhs)) + * + * so amongst other things, + * helpful to have nested seequence_xs that propagates '}' + * instead of swallowing it. + */ + bp def_expr = DefineExpr::from(expr); + + if (def_expr) { + /** nested_start: control returns via + * .on_expr(x) + * with x something like: + * Apply(Lambda(gensym(), + * [Variable(def_expr->lhs_name(), + * def_expr->valuetype())], + * body...)) + * followed immediately by + * .on_rightbrace_token() + **/ + let1_xs::start(def_expr->lhs_name(), + def_expr->rhs(), + p_psm); + } else { + this->expr_v_.push_back(expr.promote()); + + expect_expr_xs::start(true /*allow_defs*/, + true /*cxl_on_rightbrace*/, + p_psm); + } + } + + void + sequence_xs::on_expr_with_semicolon(bp expr, + parserstatemachine * p_psm) + { + /* sequence continues until right brace */ + this->on_expr(expr, p_psm); + } + + void + sequence_xs::on_rightbrace_token(const token_type & /*tk*/, + parserstatemachine * p_psm) + { + auto self = p_psm->pop_exprstate(); + + /* make sequence from expressions seen at this level, + * and report it to parent + */ + auto expr = Sequence::make(this->expr_v_); + + p_psm->top_exprstate().on_expr(expr, p_psm); + } + + void + sequence_xs::print(std::ostream & os) const { + os << ""; + } + + bool + sequence_xs::pretty_print(const xo::print::ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, "sequence_xs", + xrefrtag("expr_v.size", expr_v_.size())); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DSequenceSsm.cpp */