diff --git a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp index 4d2af7f7..b5252f49 100644 --- a/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/alloc/RAllocator.hpp @@ -43,8 +43,6 @@ namespace xo { template T * std_copy_for(const T * src) noexcept { - // TODO: fix alloc_copy(), should take const std::byte * - T * copy = (T *)(this->alloc_copy_for(src)); if (copy) { diff --git a/xo-cmake/cmake/xo_macros/xo_cxx.cmake b/xo-cmake/cmake/xo_macros/xo_cxx.cmake index 1550e282..9d94e9b7 100644 --- a/xo-cmake/cmake/xo_macros/xo_cxx.cmake +++ b/xo-cmake/cmake/xo_macros/xo_cxx.cmake @@ -1772,7 +1772,7 @@ function(xo_add_genfacetimpl) ) # Create a target for this generation - add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}) + add_custom_target(${GF_TARGET} DEPENDS ${GF_INPUT}.out) set_property(DIRECTORY APPEND PROPERTY XO_GENFACET_TARGETS ${GF_TARGET}) endfunction() diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 1b84df8d..c9180ad8 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -230,6 +230,17 @@ xo_add_genfacetimpl( OUTPUT_IMPL_SUBDIR detail ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-defineexpr + FACET_PKG xo_gc + FACET GCObject + REPR DefineExpr + INPUT idl/IGCObject_DDefineExpr.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR define +) + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-printable-defineexpr diff --git a/xo-expression2/idl/IGCObject_DDefineExpr.json5 b/xo-expression2/idl/IGCObject_DDefineExpr.json5 new file mode 100644 index 00000000..6b0eba68 --- /dev/null +++ b/xo-expression2/idl/IGCObject_DDefineExpr.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "define", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DDefineExpr", + using_doxygen: true, + repr: "DDefineExpr", + doc: [ "implement AGCObject for DDefineExpr" ], +} diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp index 6b7716e3..6ad8494f 100644 --- a/xo-expression2/include/xo/expression2/DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -1,5 +1,5 @@ /** @file DDefineExpr.hpp -* + * * @author Roland Conybeare, Jan 2026 **/ @@ -23,6 +23,7 @@ namespace xo { class DDefineExpr { public: using ppindentinfo = xo::print::ppindentinfo; + using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using TypeDescr = xo::reflect::TypeDescr; @@ -67,6 +68,14 @@ namespace xo { TypeDescr valuetype() const noexcept { return lhs_var_->typeref().td(); } void assign_valuetype(TypeDescr td) noexcept; + ///@} + /** @defgroup scm-defineexpr-gcobject-facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DDefineExpr * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} /** @defgroup scm-defineexpr-printable-facet **/ ///@{ diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 63a2a91f..5cd03fb2 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -32,6 +32,7 @@ namespace xo { using AAllocator = xo::mm::AAllocator; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; public: /** @defgroup scm-globalsymtab-ctors constructors **/ @@ -55,6 +56,9 @@ namespace xo { /** @defgroup scm-globalsymtab-access-methods access methods **/ ///@{ + size_type size() const noexcept { return map_->size(); } + size_type capacity() const noexcept { return map_->capacity(); } + /** visit symtab-owned memory pools; call visitor(info) for each **/ void visit_pools(const MemorySizeVisitor & visitor) const; diff --git a/xo-expression2/include/xo/expression2/DefineExpr.hpp b/xo-expression2/include/xo/expression2/DefineExpr.hpp index 37a77c03..4a0c42c2 100644 --- a/xo-expression2/include/xo/expression2/DefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DefineExpr.hpp @@ -7,7 +7,7 @@ #include "DDefineExpr.hpp" #include "detail/IExpression_DDefineExpr.hpp" -//#include "detail/IGCObject_DDefineExpr.hpp" +#include "define/IGCObject_DDefineExpr.hpp" #include "detail/IPrintable_DDefineExpr.hpp" /* end DefineExpr.hpp */ diff --git a/xo-expression2/include/xo/expression2/define/IGCObject_DDefineExpr.hpp b/xo-expression2/include/xo/expression2/define/IGCObject_DDefineExpr.hpp new file mode 100644 index 00000000..216dd18b --- /dev/null +++ b/xo-expression2/include/xo/expression2/define/IGCObject_DDefineExpr.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DDefineExpr.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DDefineExpr.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DDefineExpr.hpp" + +namespace xo { namespace scm { class IGCObject_DDefineExpr; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DDefineExpr + **/ + class IGCObject_DDefineExpr { + public: + /** @defgroup scm-gcobject-ddefineexpr-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-ddefineexpr-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DDefineExpr & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DDefineExpr & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DDefineExpr & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/src/expression2/CMakeLists.txt b/xo-expression2/src/expression2/CMakeLists.txt index 8aafa01a..f05cf2f1 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -9,7 +9,6 @@ set(SELF_SRCS DConstant.cpp DVariable.cpp DVarRef.cpp - DDefineExpr.cpp DApplyExpr.cpp TypeRef.cpp @@ -30,7 +29,9 @@ set(SELF_SRCS IGCObject_DVarRef.cpp IPrintable_DVarRef.cpp + DDefineExpr.cpp IExpression_DDefineExpr.cpp + IGCObject_DDefineExpr.cpp IPrintable_DDefineExpr.cpp IExpression_DApplyExpr.cpp diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index 961fbecc..aee6ccf9 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -4,13 +4,16 @@ **/ #include "DDefineExpr.hpp" -#include "detail/IPrintable_DVariable.hpp" +#include "Variable.hpp" +#include +#include #include #include #include #include namespace xo { + using xo::mm::poly_forward_inplace; using xo::print::APrintable; using xo::facet::FacetRegistry; using xo::facet::typeseq; @@ -68,10 +71,35 @@ namespace xo { } void - DDefineExpr::assign_rhs(obj x) { + DDefineExpr::assign_rhs(obj x) + { this->rhs_ = x; } + // ----- GCObject facet ----- + + std::size_t + DDefineExpr::shallow_size() const noexcept + { + return sizeof(*this); + } + + DDefineExpr * + DDefineExpr::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DDefineExpr::forward_children(obj gc) noexcept + { + gc.forward_inplace(&lhs_var_); + //gc.forward_inplace(&rhs_); // complicated - need to access via GCObject facet + poly_forward_inplace(gc, &rhs_); + + return this->shallow_size(); + } + bool DDefineExpr::pretty(const ppindentinfo & ppii) const { diff --git a/xo-expression2/src/expression2/IGCObject_DDefineExpr.cpp b/xo-expression2/src/expression2/IGCObject_DDefineExpr.cpp new file mode 100644 index 00000000..eb43932b --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DDefineExpr.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DDefineExpr.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DDefineExpr.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DDefineExpr.json5] +**/ + +#include "define/IGCObject_DDefineExpr.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DDefineExpr::shallow_size(const DDefineExpr & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DDefineExpr::shallow_copy(const DDefineExpr & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DDefineExpr::forward_children(DDefineExpr & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DDefineExpr.cpp */ diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index c563c9da..82bff638 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -6,17 +6,12 @@ #include "expression2_register_facets.hpp" #include -//#include -//#include - -#include -//#include -#include #include #include #include +#include #include #include #include @@ -74,7 +69,7 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); - //FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); diff --git a/xo-gc/include/xo/gc/PolyForwarderUtil.hpp b/xo-gc/include/xo/gc/PolyForwarderUtil.hpp new file mode 100644 index 00000000..19f99c9b --- /dev/null +++ b/xo-gc/include/xo/gc/PolyForwarderUtil.hpp @@ -0,0 +1,66 @@ +/** @file PolyForwarderUtil.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "Collector.hpp" +#include + +namespace xo { + namespace mm { + + /** Utility class for forwarding support on + * faceted object pointers that have some primary + * facet _other_ than AGCObject. + * + * For fop with AGCObject facet, with collector gc: + * + * obj gc = ..; + * obj ptr = ..; + * + * gc.forward_inplace(&ptr); + * + * for fop with some other facet: + * + * obj ptr = ..; + * PolyForwarderUtil::forward_inplace(gc, &ptr); + * + * or + * poly_forward_inplace(gc, &ptr); + **/ + class PolyForwarderUtil { + public: + template + static void forward_inplace(obj gc, obj * p_ptr) { + using xo::facet::FacetRegistry; + + /** + * p_ptr + * v FacetRegistry + * +--------+---------+ .variant() +-----------+---------+ + * | AFacet | DRepr x | -----------------> | AGCobject | DRepr x | + * +--------+-------|-+ +-----------+-------|-+ + * | | + * | /-------------------------------------------/ + * | | + * v v + * +-------+ + * | DRepr | + * +-------+ + **/ + + auto gco = FacetRegistry::instance().variant(*p_ptr); + gc.forward_inplace(gco.iface(), (void **)&(p_ptr->data_)); + } + }; + + template + void poly_forward_inplace(obj gc, obj * p_ptr) { + PolyForwarderUtil::forward_inplace(gc, p_ptr); + } + } /*namespace mm*/ +} /*namespace xo*/ + +/* end PolyForwarderUtil.hpp */ diff --git a/xo-interpreter2/CMakeLists.txt b/xo-interpreter2/CMakeLists.txt index 7ffbebc3..2d1a6db8 100644 --- a/xo-interpreter2/CMakeLists.txt +++ b/xo-interpreter2/CMakeLists.txt @@ -25,6 +25,26 @@ add_subdirectory(utest) # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-vsmdefcontframe + FACET_PKG xo_gc + FACET GCObject + REPR VsmDefContFrame + INPUT idl/IGCObject_DVsmDefContFrame.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-vsmdefcontframe + FACET_PKG xo_printable2 + FACET Printable + REPR VsmDefContFrame + INPUT idl/IPrintable_DVsmDefContFrame.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-interpreter2-facetimpl-gcobject-vsmapplyframe @@ -155,6 +175,26 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-gcobject-globalenv + FACET_PKG xo_gc + FACET GCObject + REPR GlobalEnv + INPUT idl/IGCObject_DGlobalEnv.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-interpreter2-facetimpl-printable-globalenv + FACET_PKG xo_printable2 + FACET Printable + REPR GlobalEnv + INPUT idl/IPrintable_DGlobalEnv.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-interpreter2-facetimpl-gcobject-localenv diff --git a/xo-interpreter2/idl/IGCObject_DGlobalEnv.json5 b/xo-interpreter2/idl/IGCObject_DGlobalEnv.json5 new file mode 100644 index 00000000..ce0bc090 --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DGlobalEnv.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "env", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for GlobalEnv", + using_doxygen: true, + repr: "DGlobalEnv", + doc: [ "implement AGCObject for DGlobalEnv" ], +} diff --git a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 index 1fbce208..252bfbd7 100644 --- a/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 +++ b/xo-interpreter2/idl/IGCObject_DLocalEnv.json5 @@ -2,7 +2,7 @@ mode: "implementation", output_cpp_dir: "src/interpreter2", output_hpp_dir: "include/xo/interpreter2", - output_impl_subdir: "detail", + output_impl_subdir: "env", includes: [ "", "" diff --git a/xo-interpreter2/idl/IGCObject_DVsmDefContFrame.json5 b/xo-interpreter2/idl/IGCObject_DVsmDefContFrame.json5 new file mode 100644 index 00000000..061fca5d --- /dev/null +++ b/xo-interpreter2/idl/IGCObject_DVsmDefContFrame.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "define", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DVsmDefContFrame", + using_doxygen: true, + repr: "DVsmDefContFrame", + doc: [ "implement AGCObject for DVsmDefContFrame" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DGlobalEnv.json5 b/xo-interpreter2/idl/IPrintable_DGlobalEnv.json5 new file mode 100644 index 00000000..541146ae --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DGlobalEnv.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "env", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DGlobalEnv", + using_doxygen: true, + repr: "DGlobalEnv", + doc: [ "implement APrintable for DGlobalEnv" ], +} diff --git a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 index 79ef4c74..dfc6a644 100644 --- a/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 +++ b/xo-interpreter2/idl/IPrintable_DLocalEnv.json5 @@ -2,7 +2,7 @@ mode: "implementation", output_cpp_dir: "src/interpreter2", output_hpp_dir: "include/xo/interpreter2", - output_impl_subdir: "detail", + output_impl_subdir: "env", includes: [ "", "" ], local_types: [ ], diff --git a/xo-interpreter2/idl/IPrintable_DVsmDefContFrame.json5 b/xo-interpreter2/idl/IPrintable_DVsmDefContFrame.json5 new file mode 100644 index 00000000..58410fd6 --- /dev/null +++ b/xo-interpreter2/idl/IPrintable_DVsmDefContFrame.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/interpreter2", + output_hpp_dir: "include/xo/interpreter2", + output_impl_subdir: "define", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DVsmDefContFrame", + using_doxygen: true, + repr: "DVsmDefContFrame", + doc: [ "implement APrintable for DVsmDefContFrame" ], +} diff --git a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp index 60fbe461..e68ad55d 100644 --- a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp @@ -25,18 +25,55 @@ namespace xo { **/ class DGlobalEnv { public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; using MemorySizeVisitor = xo::mm::MemorySizeVisitor; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; public: - DGlobalEnv() = default; + /** @defgroup scm-globalenv-ctors constructors **/ + ///@{ - /** visit env-owned memory pools; call visitor(info) for each **/ - void visit_pools(const MemorySizeVisitor & visitor) const; + DGlobalEnv(DGlobalSymtab * symtab, DArray * values); - protected: // temporary, to appease compiler + static DGlobalEnv * _make(obj mm, + DGlobalSymtab * symtab); - // absurd O(n) implementation for now - // replace with gc-aware hashtable, when available. + + ///@} + /** @defgroup scm-globalenv-methods methods **/ + ///@{ + + /** symbol-table size. Is the number of distinct global symbols **/ + size_type size() const noexcept { return symtab_->size(); } + + /** lookup current value associated with binding @p ix **/ + obj lookup_value(Binding ix) const noexcept; + + /** assign value associated with binding @p to @p x. + * If need to expand size of this env, use memory from @p mm + **/ + void assign_value(obj mm, Binding ix, obj x); + + ///@} + /** @defgroup scm-globalenv-gcobject-facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DGlobalEnv * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} + /** @defgroup scm-globalenv-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: /** symbol table assigns a unique index for each symbol **/ DGlobalSymtab * symtab_; diff --git a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp index c99aaad1..eaef71c2 100644 --- a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp @@ -37,7 +37,7 @@ namespace xo { DArray * args); ///@} - /** @defgroup scm-local-env-methods methods **/ + /** @defgroup scm-localenv-methods methods **/ ///@{ DLocalEnv * parent() const noexcept { return parent_; } diff --git a/xo-interpreter2/include/xo/interpreter2/DVsmDefContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/DVsmDefContFrame.hpp new file mode 100644 index 00000000..68c2510a --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/DVsmDefContFrame.hpp @@ -0,0 +1,82 @@ +/** @file DVsmDefContFrame.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "VsmInstr.hpp" +#include +#include + +namespace xo { + namespace scm { + /** @brief saved VSM state during evaluation of a SequenceExpr + **/ + class DVsmDefContFrame { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-vsmdefcontframe-ctors constructors **/ + ///@{ + + DVsmDefContFrame(obj parent, + VsmInstr cont, + DDefineExpr * def_expr); + + /** create instance using memory from allocator @p mm **/ + static DVsmDefContFrame * make(obj mm, + obj parent_stack, + VsmInstr cont, + DDefineExpr * def_expr); + + ///@} + /** @defgroup scm-vsmdefcontframe-access-methods access methods **/ + ///@{ + + obj parent() const noexcept { return parent_; } + VsmInstr cont() const noexcept { return cont_; } + DDefineExpr * def_expr() const noexcept { return def_expr_; } + + ///@} + /** @defgroup scm-vsmdefcontframe-general-methods general methods **/ + ///@{ + + ///@} + /** @defgroup scm-vsmdefcontframe-gcobject-facet gcobject facet **/ + ///@{ + + std::size_t shallow_size() const noexcept; + DVsmDefContFrame * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + + ///@} + /** @defgrouop scm-vsmseqcontframe-printable-facet printable facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const noexcept; + + ///@} + + private: + /** @defgroup scm-vsmdefcontframe-members member variables **/ + ///@{ + + /** saved VSM stack; restore when this frame consumed **/ + obj parent_; + /** saved continuation; restore when this frame consumed **/ + VsmInstr cont_; + /** saved expr. evaluate elements of this sequence in order **/ + DDefineExpr * def_expr_ = nullptr; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmDefContFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/GlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/GlobalEnv.hpp new file mode 100644 index 00000000..94bafc42 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/GlobalEnv.hpp @@ -0,0 +1,12 @@ +/** @file GlobalEnv.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DGlobalEnv.hpp" +#include "env/IGCObject_DGlobalEnv.hpp" +#include "env/IPrintable_DGlobalEnv.hpp" + +/* end GlobalEnv.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp index a34310ab..724e1c33 100644 --- a/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -191,6 +191,11 @@ namespace xo { /** call primitive @ref fn_ with arguments @ref args_ **/ void _do_call_primitive_op(); + /** perform assignment after evaluating + * the rhs of a define-expr + **/ + void _do_def_cont_op(); + /** restore registers from stack frame * (specifically: local_env_, stack_, cont_) * after invoking a schematika closure @@ -225,13 +230,13 @@ namespace xo { #ifdef NOT_YET /** allocator (likely DArena) for globals. - * For example DArenaHashMap in global symtab, + * For example DArenaHashMap in global symta. **/ obj aux_mm_; #endif /** allocator (likely DX1Collector or similar) for - * expressions and values + * expressions and values. Schemaatika reader will use this also **/ abox mm_; @@ -267,19 +272,17 @@ namespace xo { /** expression register **/ obj expr_; + /** environment pointer. Maintains bindings + * for global variables. + **/ + DGlobalEnv * global_env_ = nullptr; + /** environment pointer. Provides bindings * for surrounding lexical scope at this point * in execution **/ DLocalEnv * local_env_ = nullptr; - protected: // temporarily, to appease compiler - /** environment pointer. Maintains bindings - * for global variables. - **/ - DGlobalEnv * global_env_ = nullptr; - - private: /** evaluated function to call **/ obj fn_; /** evaluated argument list **/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmDefContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/VsmDefContFrame.hpp new file mode 100644 index 00000000..5ea2bad6 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/VsmDefContFrame.hpp @@ -0,0 +1,12 @@ +/** @file VsmDefContFrame.hpp +* + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DVsmDefContFrame.hpp" +#include "define/IGCObject_DVsmDefContFrame.hpp" +#include "define/IPrintable_DVsmDefContFrame.hpp" + +/* end VsmDefContFrame.hpp */ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp index 1279f8b7..2417757f 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmInstr.hpp @@ -9,15 +9,25 @@ namespace xo { namespace scm { + /** + * Thin instruction wrapper for VSM (virtual schematika machine) instructions. + * For exeuction see VirtualSchematikaMachine.cpp + **/ class VsmInstr { public: explicit VsmInstr(vsm_opcode oc) : opcode_{oc} {} // instructions + static VsmInstr c_sentinel; static VsmInstr c_halt; static VsmInstr c_eval; + /** proceed to assignment after evaluating rhs + * of define-expression + **/ + static VsmInstr c_def_cont; + static VsmInstr c_apply; static VsmInstr c_evalargs; /** restore VSM state for continuation of an apply expression **/ diff --git a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp index e1000cb3..161b352e 100644 --- a/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp +++ b/xo-interpreter2/include/xo/interpreter2/VsmOpcode.hpp @@ -14,6 +14,8 @@ namespace xo { * exeucted by VirtualSchematikaMachine **/ enum class vsm_opcode { + /** Flags bad state (defect in VSM itself) **/ + sentinel, /** Immediately halt virtual schematika machine. **/ halt, /** Evaluate expression in expr register **/ @@ -28,6 +30,11 @@ namespace xo { **/ evalargs, + /** continuation to complete execution of define-expression, + * after evaluting rhs expression + **/ + def_cont, + /** continuation to restore vsm registers (local_env, stack, cont) * after invoking a closure **/ @@ -58,4 +65,3 @@ namespace xo { } /*namespace xo*/ /* end VsmOpcode.hpp */ - diff --git a/xo-interpreter2/include/xo/interpreter2/define/IGCObject_DVsmDefContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/define/IGCObject_DVsmDefContFrame.hpp new file mode 100644 index 00000000..309a6ac7 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/define/IGCObject_DVsmDefContFrame.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DVsmDefContFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmDefContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmDefContFrame.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DVsmDefContFrame.hpp" + +namespace xo { namespace scm { class IGCObject_DVsmDefContFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DVsmDefContFrame + **/ + class IGCObject_DVsmDefContFrame { + public: + /** @defgroup scm-gcobject-dvsmdefcontframe-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dvsmdefcontframe-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DVsmDefContFrame & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DVsmDefContFrame & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DVsmDefContFrame & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/define/IPrintable_DVsmDefContFrame.hpp b/xo-interpreter2/include/xo/interpreter2/define/IPrintable_DVsmDefContFrame.hpp new file mode 100644 index 00000000..46ab4ee7 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/define/IPrintable_DVsmDefContFrame.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DVsmDefContFrame.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmDefContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmDefContFrame.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DVsmDefContFrame.hpp" + +namespace xo { namespace scm { class IPrintable_DVsmDefContFrame; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DVsmDefContFrame + **/ + class IPrintable_DVsmDefContFrame { + public: + /** @defgroup scm-printable-dvsmdefcontframe-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dvsmdefcontframe-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DVsmDefContFrame & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DGlobalEnv.hpp new file mode 100644 index 00000000..1f0f9281 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DGlobalEnv.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DGlobalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DGlobalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DGlobalEnv.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DGlobalEnv.hpp" + +namespace xo { namespace scm { class IGCObject_DGlobalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DGlobalEnv + **/ + class IGCObject_DGlobalEnv { + public: + /** @defgroup scm-gcobject-dglobalenv-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dglobalenv-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DGlobalEnv & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DGlobalEnv & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DGlobalEnv & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DLocalEnv.hpp new file mode 100644 index 00000000..d318bb61 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/env/IGCObject_DLocalEnv.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DLocalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DLocalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DLocalEnv.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DLocalEnv.hpp" + +namespace xo { namespace scm { class IGCObject_DLocalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DLocalEnv + **/ + class IGCObject_DLocalEnv { + public: + /** @defgroup scm-gcobject-dlocalenv-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dlocalenv-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DLocalEnv & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DLocalEnv & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DLocalEnv & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DGlobalEnv.hpp new file mode 100644 index 00000000..6efcd963 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DGlobalEnv.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DGlobalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DGlobalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DGlobalEnv.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DGlobalEnv.hpp" + +namespace xo { namespace scm { class IPrintable_DGlobalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DGlobalEnv + **/ + class IPrintable_DGlobalEnv { + public: + /** @defgroup scm-printable-dglobalenv-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dglobalenv-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DGlobalEnv & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DLocalEnv.hpp new file mode 100644 index 00000000..c0ddb7f8 --- /dev/null +++ b/xo-interpreter2/include/xo/interpreter2/env/IPrintable_DLocalEnv.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DLocalEnv.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DLocalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DLocalEnv.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DLocalEnv.hpp" + +namespace xo { namespace scm { class IPrintable_DLocalEnv; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DLocalEnv + **/ + class IPrintable_DLocalEnv { + public: + /** @defgroup scm-printable-dlocalenv-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dlocalenv-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DLocalEnv & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-interpreter2/src/interpreter2/CMakeLists.txt b/xo-interpreter2/src/interpreter2/CMakeLists.txt index c21821e1..c15ddef6 100644 --- a/xo-interpreter2/src/interpreter2/CMakeLists.txt +++ b/xo-interpreter2/src/interpreter2/CMakeLists.txt @@ -8,6 +8,10 @@ set(SELF_SRCS VirtualSchematikaMachine.cpp + DVsmDefContFrame.cpp + IGCObject_DVsmDefContFrame.cpp + IPrintable_DVsmDefContFrame.cpp + DVsmEvalArgsFrame.cpp IGCObject_DVsmEvalArgsFrame.cpp IPrintable_DVsmEvalArgsFrame.cpp @@ -32,9 +36,13 @@ set(SELF_SRCS IGCObject_DClosure.cpp IPrintable_DClosure.cpp + DGlobalEnv.cpp + IGCObject_DGlobalEnv.cpp + IPrintable_DGlobalEnv.cpp + + DLocalEnv.cpp IGCObject_DLocalEnv.cpp IPrintable_DLocalEnv.cpp - DLocalEnv.cpp DVsmRcx.cpp IRuntimeContext_DVsmRcx.cpp diff --git a/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp b/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp new file mode 100644 index 00000000..a9285b73 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp @@ -0,0 +1,128 @@ +/** @file DGlobalEnv.cpp + * + * @author Roland Conybeare, Feb 2026 +**/ + +#include "GlobalEnv.hpp" +#include +#include + +namespace xo { + using xo::mm::AAllocator; + using xo::mm::AGCObject; + + namespace scm { + + DGlobalEnv::DGlobalEnv(DGlobalSymtab * symtab, DArray * values) + : symtab_{symtab}, values_{values} + {} + + DGlobalEnv * + DGlobalEnv::_make(obj mm, + DGlobalSymtab * symtab) + { + DArray * values = DArray::empty(mm, symtab->capacity()); + + void * mem = mm.alloc_for(); + + return new (mem) DGlobalEnv(symtab, values); + } + + obj + DGlobalEnv::lookup_value(Binding ix) const noexcept + { + if (!ix.is_global()) { + assert(false); + return obj(); + } + + if (ix.j_slot() >= static_cast(values_->size())) { + assert(false); + return obj(); + } + + return (*values_)[ix.j_slot()]; + } + + void + DGlobalEnv::assign_value(obj mm, Binding ix, obj x) + { + scope log(XO_DEBUG(true), + xtag("ix.j_slot", ix.j_slot()), + xtag("values.cap", values_->capacity())); + + assert(ix.is_global()); + + if (ix.j_slot() >= static_cast(values_->size())) { + // Control will come here in interpreter as new definitions are introduced. + // After seeing + // def foo = 1.2345; + // introducing new symbol foo: + // GlobalSymtab extends to include foo without this GlobalEnv + // knowing about it. + + if (ix.j_slot() + 1 > static_cast(values_->capacity())) { + // realloc global array for more size + + size_t cap_2x = 2 * values_->capacity(); + + while (cap_2x < static_cast(ix.j_slot() + 1)) + cap_2x = 2 * cap_2x; + + DArray * values_2x = DArray::copy(mm, values_, cap_2x); + assert(values_2x); + + if (values_2x) { + log && log("STUB: need write barrier for GC (also in GlobalSymtab!)"); + this->values_ = values_2x; + } else { + return; + } + } + + /** expand size sot that j_slot is valid **/ + values_->resize(ix.j_slot() + 1); + } + + log && log("STUB: need write barrier for GC here"); + (*values_)[ix.j_slot()] = x; + } + + // ----- AGCObject facet ----- + + std::size_t + DGlobalEnv::shallow_size() const noexcept + { + return sizeof(*this); + } + + DGlobalEnv * + DGlobalEnv::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DGlobalEnv::forward_children(obj gc) noexcept + { + gc.forward_inplace(&symtab_); + gc.forward_inplace(&values_); + + return this->shallow_size(); + } + + // ----- APrintable facet ----- + + bool + DGlobalEnv::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct + (ppii, + "DGlobalEnv", + refrtag("size", symtab_->size())); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DGlobalEnv.cpp */ diff --git a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp index 6866fda7..8f45b38a 100644 --- a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp @@ -6,6 +6,7 @@ #include "LocalEnv.hpp" #include #include +#include namespace xo { using xo::mm::AGCObject; @@ -64,6 +65,8 @@ namespace xo { void DLocalEnv::assign_value(Binding ix, obj x) { + scope log(XO_DEBUG(true)); + assert(!ix.is_global()); const DLocalEnv * env = this; @@ -76,6 +79,7 @@ namespace xo { auto j = ix.j_slot(); if (j < static_cast(env->size())) { + log && log("STUB: need write barrier for GC here"); (*(env->args_))[j] = x; } else { assert(false); diff --git a/xo-interpreter2/src/interpreter2/DVsmDefContFrame.cpp b/xo-interpreter2/src/interpreter2/DVsmDefContFrame.cpp new file mode 100644 index 00000000..7b3b9e7a --- /dev/null +++ b/xo-interpreter2/src/interpreter2/DVsmDefContFrame.cpp @@ -0,0 +1,68 @@ +/** @file DVsmDefContFrame.cpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#include "DVsmDefContFrame.hpp" +#include +#include + +namespace xo { + namespace scm { + + DVsmDefContFrame::DVsmDefContFrame(obj parent, + VsmInstr cont, + DDefineExpr * def_expr) + : parent_{parent}, + cont_{cont}, + def_expr_{def_expr} + {} + + DVsmDefContFrame * + DVsmDefContFrame::make(obj mm, + obj parent, + VsmInstr cont, + DDefineExpr * def_expr) + { + void * mem = mm.alloc_for(); + + return new (mem) DVsmDefContFrame(parent, cont, def_expr); + } + + // gcobject facet + + std::size_t + DVsmDefContFrame::shallow_size() const noexcept + { + return sizeof(*this); + } + + DVsmDefContFrame * + DVsmDefContFrame::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DVsmDefContFrame::forward_children(obj gc) noexcept + { + gc.forward_inplace(&parent_); + gc.forward_inplace(&def_expr_); + + return this->shallow_size(); + } + + // printable facet + + bool + DVsmDefContFrame::pretty(const ppindentinfo & ppii) const noexcept + { + return ppii.pps()->pretty_struct(ppii, + "DVsmDefContFrame", + refrtag("cont", cont_)); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DVsmDefContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DGlobalEnv.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DGlobalEnv.cpp new file mode 100644 index 00000000..76606d6f --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DGlobalEnv.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DGlobalEnv.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DGlobalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DGlobalEnv.json5] +**/ + +#include "env/IGCObject_DGlobalEnv.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DGlobalEnv::shallow_size(const DGlobalEnv & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DGlobalEnv::shallow_copy(const DGlobalEnv & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DGlobalEnv::forward_children(DGlobalEnv & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DGlobalEnv.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp index 3ee3b7c7..3b6cd5f7 100644 --- a/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/IGCObject_DLocalEnv.cpp @@ -11,7 +11,7 @@ * [idl/IGCObject_DLocalEnv.json5] **/ -#include "detail/IGCObject_DLocalEnv.hpp" +#include "env/IGCObject_DLocalEnv.hpp" namespace xo { namespace scm { diff --git a/xo-interpreter2/src/interpreter2/IGCObject_DVsmDefContFrame.cpp b/xo-interpreter2/src/interpreter2/IGCObject_DVsmDefContFrame.cpp new file mode 100644 index 00000000..26a23611 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IGCObject_DVsmDefContFrame.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DVsmDefContFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DVsmDefContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DVsmDefContFrame.json5] +**/ + +#include "define/IGCObject_DVsmDefContFrame.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DVsmDefContFrame::shallow_size(const DVsmDefContFrame & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DVsmDefContFrame::shallow_copy(const DVsmDefContFrame & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DVsmDefContFrame::forward_children(DVsmDefContFrame & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DVsmDefContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DGlobalEnv.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DGlobalEnv.cpp new file mode 100644 index 00000000..84fc561c --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DGlobalEnv.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DGlobalEnv.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DGlobalEnv.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DGlobalEnv.json5] +**/ + +#include "env/IPrintable_DGlobalEnv.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DGlobalEnv::pretty(const DGlobalEnv & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DGlobalEnv.cpp */ diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp index bf701cb6..6fe745b2 100644 --- a/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/IPrintable_DLocalEnv.cpp @@ -11,7 +11,7 @@ * [idl/IPrintable_DLocalEnv.json5] **/ -#include "detail/IPrintable_DLocalEnv.hpp" +#include "env/IPrintable_DLocalEnv.hpp" namespace xo { namespace scm { diff --git a/xo-interpreter2/src/interpreter2/IPrintable_DVsmDefContFrame.cpp b/xo-interpreter2/src/interpreter2/IPrintable_DVsmDefContFrame.cpp new file mode 100644 index 00000000..f73b7dd6 --- /dev/null +++ b/xo-interpreter2/src/interpreter2/IPrintable_DVsmDefContFrame.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DVsmDefContFrame.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DVsmDefContFrame.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DVsmDefContFrame.json5] +**/ + +#include "define/IPrintable_DVsmDefContFrame.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DVsmDefContFrame::pretty(const DVsmDefContFrame & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DVsmDefContFrame.cpp */ diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 5c2d2c57..aa0861f5 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -4,6 +4,7 @@ **/ #include "VirtualSchematikaMachine.hpp" +#include "VsmDefContFrame.hpp" #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "VsmApplyClosureFrame.hpp" @@ -11,10 +12,12 @@ #include "VsmSeqContFrame.hpp" #include "VsmRcx.hpp" #include "Closure.hpp" +#include #include #include #include #include +#include #include #include //#include @@ -65,10 +68,10 @@ namespace xo { DArena * arena = new DArena(config_.error_config_); assert(arena); - error_mm_.adopt(obj(arena)); + this->error_mm_.adopt(obj(arena)); } - // TODO: allocate global_env + this->global_env_ = DGlobalEnv::_make(mm_.to_op(), reader_.global_symtab()); } obj @@ -166,17 +169,20 @@ namespace xo { VirtualSchematikaMachine::execute_one() { scope log(XO_DEBUG(config_.debug_flag_)); + log && log(xtag("pc", pc_), xtag("cont", cont_)); - obj stack_pr = stack_.to_facet(); -// = (FacetRegistry::instance() -// .try_variant(stack_)); + auto expr_pr = expr_.to_facet(); + if (expr_pr) + log && log(xtag("expr", expr_pr)); + auto stack_pr = stack_.to_facet(); if (stack_pr) log && log(xtag("stack", stack_pr)); switch (pc_.opcode()) { + case vsm_opcode::sentinel: case vsm_opcode::halt: case vsm_opcode::N: return false; @@ -189,6 +195,9 @@ namespace xo { case vsm_opcode::evalargs: _do_evalargs_op(); break; + case vsm_opcode::def_cont: + _do_def_cont_op(); + break; case vsm_opcode::apply_cont: _do_apply_cont_op(); break; @@ -244,14 +253,84 @@ namespace xo { = obj::from(expr_); this->value_ = VsmResult(expr.data()->value()); + this->pc_ = this->cont_; + this->cont_ = VsmInstr::c_sentinel; } void VirtualSchematikaMachine::_do_eval_define_op() { - // not implemented - assert(false); + scope log(XO_DEBUG(true)); + + auto def_expr + = obj::from(expr_); + + if (local_env_ == nullptr) { + // top-level define + + // .stack_ --+ + // | + // v + // +------DVsmDefContFrame------+ + // | .parent x | .cont | .def x | + // +---------|-+-------+------|-+ + // | | + // ParserStack* <-----/ | + // | + // v + // DDefineExpr + + /* stack frame for nested continuation + * (to perform assignment) + */ + auto defcont_frame + = obj + (DVsmDefContFrame::make(mm_.to_op(), + this->stack_ /*saved stack*/, + this->cont_ /*saved cont*/, + def_expr.data() /*saved expr*/)); + + this->stack_ = defcont_frame; + + // setup evaluation of rhs + + this->expr_ = def_expr->rhs(); + this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_def_cont; + } else { + // nested defines implemented by rewriting, + // so this branch should be unreachable + + assert(false); + } + } + + void + VirtualSchematikaMachine::_do_def_cont_op() + { + // see DVsmDefContFrame + + auto frame = obj::from(stack_); + + assert(frame); + assert(value_.is_value()); + + // TODO: verify that value satisfies expected type ? + + DVariable * lhs = frame->def_expr()->lhs(); + obj rhs = *value_.value(); + + assert(lhs->path().is_global()); + + global_env_->assign_value(mm_.to_op(), lhs->path(), rhs); + + // TODO: unfortunate const_cast here, because obj<> doesn't support const DRepr yet + this->value_ = VsmResult(obj(const_cast(lhs->name()))); + + this->stack_ = frame->parent(); + this->pc_ = frame->cont(); + this->cont_ = VsmInstr::c_sentinel; } void @@ -294,7 +373,9 @@ namespace xo { this->value_ = VsmResult(obj(obj(closure))); + this->pc_ = this->cont_; + this->cont_ = VsmInstr::c_sentinel; } void @@ -320,7 +401,9 @@ namespace xo { if (value) { this->value_ = VsmResult(value); + this->pc_ = this->cont_; + this->cont_ = VsmInstr::c_sentinel; return; } @@ -338,6 +421,7 @@ namespace xo { // 3. have every vsm instruction check inputs for errors this->pc_ = VsmInstr::c_halt; + this->cont_ = VsmInstr::c_sentinel; } void @@ -385,9 +469,9 @@ namespace xo { // Setup evaluation of first argument. No new stack for this. - this->cont_ = VsmInstr::c_evalargs; this->expr_ = apply->fn(); this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_evalargs; } void @@ -404,9 +488,9 @@ namespace xo { stack_, cont_, ifelse_expr.data())); this->stack_ = ifelse_frame; - this->cont_ = VsmInstr::c_ifelse_cont; this->expr_ = ifelse_expr->test(); this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_ifelse_cont; } void @@ -445,9 +529,9 @@ namespace xo { // Setup evaluation of first sequence element - this->cont_ = VsmInstr::c_seq_cont; this->expr_ = (*seq_expr.data())[0]; this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_seq_cont; } void @@ -514,6 +598,7 @@ namespace xo { this->local_env_ = local_env; this->expr_ = lambda->body_expr(); this->pc_ = VsmInstr::c_eval; + // cont_ already established } void @@ -523,6 +608,7 @@ namespace xo { this->value_ = VsmResult(fn.apply_nocheck(rcx_.to_op(), args_)); this->pc_ = cont_; + this->cont_ = VsmInstr::c_sentinel; } void @@ -537,6 +623,7 @@ namespace xo { log && log("error in apply -> terminating app"); this->pc_ = VsmInstr::c_halt; + this->cont_ = VsmInstr::c_sentinel; return; } @@ -595,7 +682,7 @@ namespace xo { this->expr_ = apply_expr->arg(i_arg); this->pc_ = VsmInstr::c_eval; - //this->cont_ = VsmInstra::c_evalargs; // redundant, since preserved + this->cont_ = VsmInstr::c_evalargs; return; } else { @@ -633,7 +720,7 @@ namespace xo { } else { this->expr_ = apply_expr->arg(i_arg); this->pc_ = VsmInstr::c_eval; - //this->cont_ = VsmInstra::c_evalargs; // redundant, since preserved + this->cont_ = VsmInstr::c_evalargs; return; } @@ -655,6 +742,7 @@ namespace xo { this->stack_ = frame->parent(); this->local_env_ = frame->local_env(); this->pc_ = frame->cont(); + this->cont_ = VsmInstr::c_sentinel; } void @@ -682,9 +770,9 @@ namespace xo { } this->stack_ = frame->parent(); - this->cont_ = frame->cont(); this->expr_ = next_expr; this->pc_ = VsmInstr::c_eval; + this->cont_ = frame->cont(); } else { auto error = DRuntimeError::make(mm_.to_op(), "_do_ifelse_cont_op", @@ -698,6 +786,7 @@ namespace xo { // 3. have every vsm instruction check inputs for errors this->pc_ = VsmInstr::c_halt; + this->cont_ = VsmInstr::c_sentinel; } } @@ -722,13 +811,16 @@ namespace xo { this->stack_ = frame->parent(); this->pc_ = frame->cont(); + this->cont_ = VsmInstr::c_sentinel; + return; } else { frame->incr_i_seq(); - this->cont_ = VsmInstr::c_seq_cont; this->expr_ = (*seq_expr)[i_seq]; this->pc_ = VsmInstr::c_eval; + this->cont_ = VsmInstr::c_seq_cont; + return; } } diff --git a/xo-interpreter2/src/interpreter2/VsmInstr.cpp b/xo-interpreter2/src/interpreter2/VsmInstr.cpp index b815c079..852b6332 100644 --- a/xo-interpreter2/src/interpreter2/VsmInstr.cpp +++ b/xo-interpreter2/src/interpreter2/VsmInstr.cpp @@ -11,10 +11,12 @@ namespace xo { vsm_opcode_descr(vsm_opcode x) { switch (x) { + case vsm_opcode::sentinel: return "sentinel"; case vsm_opcode::halt: return "halt"; case vsm_opcode::eval: return "eval"; case vsm_opcode::apply: return "apply"; case vsm_opcode::evalargs: return "evalargs"; + case vsm_opcode::def_cont: return "def_cont"; case vsm_opcode::apply_cont: return "apply_cont"; case vsm_opcode::ifelse_cont: return "ifelse_cont"; case vsm_opcode::seq_cont: return "seq_cont"; @@ -25,6 +27,9 @@ namespace xo { return "opcode?"; } + VsmInstr + VsmInstr::c_sentinel = VsmInstr(vsm_opcode::sentinel); + VsmInstr VsmInstr::c_halt = VsmInstr(vsm_opcode::halt); @@ -37,12 +42,15 @@ namespace xo { VsmInstr VsmInstr::c_evalargs = VsmInstr(vsm_opcode::evalargs); + VsmInstr + VsmInstr::c_def_cont = VsmInstr(vsm_opcode::def_cont); + VsmInstr VsmInstr::c_apply_cont = VsmInstr(vsm_opcode::apply_cont); VsmInstr VsmInstr::c_ifelse_cont = VsmInstr(vsm_opcode::ifelse_cont); - + VsmInstr VsmInstr::c_seq_cont = VsmInstr(vsm_opcode::seq_cont); } /*namespace scm*/ diff --git a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp index dc9b31be..22c9bfb9 100644 --- a/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp +++ b/xo-interpreter2/src/interpreter2/interpreter2_register_facets.cpp @@ -6,6 +6,7 @@ #include "interpreter2_register_facets.hpp" #include "DPrimitive_gco_2_gco_gco.hpp" +#include "VsmDefContFrame.hpp" #include "VsmApplyFrame.hpp" #include "VsmEvalArgsFrame.hpp" #include "VsmApplyClosureFrame.hpp" @@ -13,6 +14,7 @@ #include "VsmSeqContFrame.hpp" #include "Primitive_gco_2_gco_gco.hpp" #include "Closure.hpp" +#include "GlobalEnv.hpp" #include "LocalEnv.hpp" #include "VsmRcx.hpp" @@ -39,6 +41,7 @@ namespace xo { // +- VsmApplyFrame // +- VsmEvalArgsFrame // +- VsmApplyClosureFrame + // +- VsmDefContFrame // +- VsmIfElseContFrame // \- VsmSeqContFrame @@ -51,12 +54,20 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl(); + // GlobalEnv + + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // LocalEnv FacetRegistry::register_impl(); @@ -84,8 +95,12 @@ namespace xo { log && log(xtag("DVsmApplyFrame.tseq", typeseq::id())); log && log(xtag("DVsmEvalArgsFrame.tseq", typeseq::id())); log && log(xtag("DVsmApplyClosureFrame.tseq", typeseq::id())); + log && log(xtag("DVsmDefContFrame.tseq", typeseq::id())); + log && log(xtag("DVsmDefContFrame.tseq", typeseq::id())); + log && log(xtag("DVsmIfElseContFrame.tseq", typeseq::id())); log && log(xtag("DVsmSeqContFrame.tseq", typeseq::id())); log && log(xtag("DClosure.tseq", typeseq::id())); + log && log(xtag("DGlobalEnv.tseq", typeseq::id())); log && log(xtag("DLocalEnv.tseq", typeseq::id())); log && log(xtag("DVsmRcx.tseq", typeseq::id())); diff --git a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp index 1a50c555..1af15c86 100644 --- a/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp +++ b/xo-interpreter2/utest/VirtualSchematikaMachine.test.cpp @@ -5,11 +5,13 @@ #include #include +#include #include #include #include #include #include +#include #ifdef NOT_YET #include @@ -32,6 +34,7 @@ namespace xo { using xo::scm::VsmResultExt; using xo::scm::DClosure; using xo::scm::DString; + using xo::scm::DUniqueString; // aks Symbol in lisp using xo::scm::DFloat; using xo::scm::DBoolean; using xo::scm::DInteger; @@ -42,6 +45,7 @@ namespace xo { using xo::mm::DArena; using xo::mm::ArenaConfig; using xo::facet::FacetRegistry; + using xo::facet::TypeRegistry; using span_type = xo::scm::VirtualSchematikaMachine::span_type; using Catch::Matchers::WithinAbs; @@ -81,6 +85,7 @@ namespace xo { aux_mm_.arena_.visit_pools(visitor); FacetRegistry::instance().visit_pools(visitor); + TypeRegistry::instance().visit_pools(visitor); vsm_.visit_pools(visitor); return true; @@ -298,7 +303,7 @@ namespace xo { { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - bool c_debug_flag = true; + bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); VsmFixture vsm_fixture(testname, c_debug_flag); @@ -333,6 +338,96 @@ namespace xo { log && vsm_fixture.log_memory_layout(&log); } + TEST_CASE("VirtualSchematikaMachine-def1", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; + + bool eof_flag = false; + + vsm.begin_interactive_session(); + VsmResultExt res + = vsm.read_eval_print(span_type::from_cstr("def foo = 3.14159;"), + eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq()), + xtag("res.type", TypeRegistry::id2name(res.value()->_typeseq()))); + + // currently get not-implemented error + auto x = obj::from(*res.value()); + + REQUIRE(x); + REQUIRE(strcmp(x->chars(), "foo") == 0); + + //log && log("runtime-error", xtag("ex.src", x->src_function()), xtag("ex.descr", x->error_descr())); + + //REQUIRE(x.data()->value() == 1.570796325); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + + log && vsm_fixture.log_memory_layout(&log); + } + + TEST_CASE("VirtualSchematikaMachine-def2", "[interpreter2][VSM]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + VsmFixture vsm_fixture(testname, c_debug_flag); + auto & vsm = vsm_fixture.vsm_; + + bool eof_flag = false; + + vsm.begin_interactive_session(); + + span_type input = span_type::from_cstr("def foo = 3.14159; foo"); + + for (int i_expr = 0; i_expr < 2; ++i_expr) { + VsmResultExt res + = vsm.read_eval_print(input, eof_flag); + + REQUIRE(res.is_value()); + REQUIRE(res.value()); + + log && log(xtag("res.tseq", res.value()->_typeseq()), + xtag("res.type", TypeRegistry::id2name(res.value()->_typeseq()))); + + if (i_expr == 0) { + auto x = obj::from(*res.value()); + REQUIRE(x); + REQUIRE(strcmp(x->chars(), "foo") == 0); + + REQUIRE(res.remaining_.size() > 1); + + input = res.remaining_; + } else if (i_expr == 1) { + auto x = obj::from(*res.value()); + REQUIRE(x); + REQUIRE(x->value() == 3.14159); + + REQUIRE(res.remaining_.size() == 1); + REQUIRE(*res.remaining_.lo() == '\n'); + input = res.remaining_; + } + + ++i_expr; + } + + log && vsm_fixture.log_memory_layout(&log); + + } + } /*namespace ut*/ } /*namespace xo*/ diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index 7b758860..8d7248e5 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -75,9 +75,6 @@ namespace xo { requires (std::same_as> && ...) static DArray * array(obj mm, Args... args); - const obj & operator[](size_type index) const noexcept { return elts_[index]; } - obj & operator[](size_type index) noexcept { return elts_[index]; } - ///@} /** @defgroup darray-access acecss methods **/ ///@{ @@ -91,6 +88,10 @@ namespace xo { size_type size() const noexcept { return size_; } /** return element @p index of this array (0-based) **/ obj at(size_type index) const; + + const obj & operator[](size_type index) const noexcept { return elts_[index]; } + obj & operator[](size_type index) noexcept { return elts_[index]; } + ///@} /** @defgroup darray-iterators iterators **/ ///@{ @@ -106,6 +107,11 @@ namespace xo { /** @defgroup darray-general general methods **/ ///@{ + /** resize to @p new_size. @p new_size may not be larger than capacity + * Return true if resize was accomplished; false otherwise. + **/ + bool resize(size_type new_size) noexcept; + ///@} /** @defgroup darray-conversion-operators conversion operators **/ ///@{ diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index e1414eec..31ced92e 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -84,6 +84,19 @@ namespace xo { } } + bool + DArray::resize(size_type new_z) noexcept { + if (new_z >= capacity_) { + return false; + } else if (new_z > size_) { + // ensure new size is zeroed (we/re not zeroing if/when we shrink) + ::memset((std::byte *)(&elts_[size_]), 0, (std::byte *)(&elts_[new_z]) - (std::byte *)(&elts_[size_])); + } + + this->size_ = new_z; + return true; + } + // printing support bool diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 2dfba437..f2654e1c 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -71,6 +71,7 @@ namespace xo { bool debug_flag() const noexcept { return debug_flag_; } ParserStack * stack() const noexcept { return stack_; } obj expr_alloc() const noexcept { return expr_alloc_; } + DGlobalSymtab * global_symtab() const noexcept { return global_symtab_.data(); } DLocalSymtab * local_symtab() const noexcept { return local_symtab_; } const ParserResult & result() const noexcept { return result_; } @@ -315,6 +316,17 @@ namespace xo { **/ obj aux_alloc_; + /** global symbol table. + * Toplevel definitions go here. + * + * Uses mmap -> non-trivial destructor. + * + * TODO: may want to move ownership upstairs. + * if so, along with stringtable_. + * maybe new struct ParserState? + **/ + dp global_symtab_; + /** symbol table with local bindings. * non-null during parsing of lambda expressions. * Always allocated from @p expr_alloc_. @@ -323,15 +335,6 @@ namespace xo { **/ DLocalSymtab * local_symtab_ = nullptr; - /** global symbol table. - * Toplevel definitions go here. - * - * Uses mmap -> non-trivial destructor. - * - * TODO: may want to move ownership upstairs - **/ - dp global_symtab_; - /** current output from parser **/ ParserResult result_; diff --git a/xo-reader2/include/xo/reader2/SchematikaParser.hpp b/xo-reader2/include/xo/reader2/SchematikaParser.hpp index 45b45c19..96de8628 100644 --- a/xo-reader2/include/xo/reader2/SchematikaParser.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaParser.hpp @@ -183,6 +183,8 @@ namespace xo { /** scm-schematikaparser-access-methods **/ ///@{ + DGlobalSymtab * global_symtab() const noexcept; + bool debug_flag() const { return debug_flag_; } /** true if parser is at top-level, diff --git a/xo-reader2/include/xo/reader2/SchematikaReader.hpp b/xo-reader2/include/xo/reader2/SchematikaReader.hpp index 5a4243a1..efd031ca 100644 --- a/xo-reader2/include/xo/reader2/SchematikaReader.hpp +++ b/xo-reader2/include/xo/reader2/SchematikaReader.hpp @@ -54,6 +54,9 @@ namespace xo { /** non-trivial dtor because of @p parser **/ ~SchematikaReader() = default; + /** top-level symbol table **/ + DGlobalSymtab * global_symtab() const noexcept; + /** visit reader-owned memory pools; call visitor(info) for each. * Specifically exclude expr_alloc, since we don't consider * that reader-owned diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 1bb188cb..25b3bc7f 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -32,6 +32,12 @@ namespace xo { { } + DGlobalSymtab * + SchematikaParser::global_symtab() const noexcept + { + return psm_.global_symtab(); + } + bool SchematikaParser::is_at_toplevel() const { diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index 98d44112..c3e13254 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -24,6 +24,12 @@ namespace xo { { } + DGlobalSymtab * + SchematikaReader::global_symtab() const noexcept + { + return parser_.global_symtab(); + } + void SchematikaReader::visit_pools(const MemorySizeVisitor & visitor) const { diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index e4a0e1de..6153ecb7 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -117,6 +117,7 @@ namespace xo { aux_arena_.visit_pools(visitor); FacetRegistry::instance().visit_pools(visitor); + TypeRegistry::instance().visit_pools(visitor); expr_arena_->visit_pools(visitor); parser_->visit_pools(visitor);