diff --git a/DSequenceExpr.hpp b/DSequenceExpr.hpp new file mode 100644 index 00000000..12caf649 --- /dev/null +++ b/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/include/xo/expression2/exprtype.hpp b/include/xo/expression2/exprtype.hpp index 861d62bd..3bcda3c4 100644 --- a/include/xo/expression2/exprtype.hpp +++ b/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/src/expression2/DSequenceExpr.cpp b/src/expression2/DSequenceExpr.cpp new file mode 100644 index 00000000..c5abf27b --- /dev/null +++ b/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 */