diff --git a/xo-expression2/CMakeLists.txt b/xo-expression2/CMakeLists.txt index 92652b90..1af09c58 100644 --- a/xo-expression2/CMakeLists.txt +++ b/xo-expression2/CMakeLists.txt @@ -47,7 +47,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-localsymtab - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR LocalSymtab INPUT idl/IGCObject_DLocalSymtab.json5 @@ -82,7 +82,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-globalsymtab - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR GlobalSymtab INPUT idl/IGCObject_DGlobalSymtab.json5 @@ -128,7 +128,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-constant - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR Constant INPUT idl/IGCObject_DConstant.json5 @@ -163,7 +163,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-variable - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR Variable INPUT idl/IGCObject_DVariable.json5 @@ -184,6 +184,30 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-gcobject-typename + FACET_PKG xo_alloc2 + FACET GCObject + REPR Typename + INPUT idl/IGCObject_DTypename.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR typename +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-expression2-facetimpl-printable-typename + FACET_PKG xo_printable2 + FACET Printable + REPR Typename + INPUT idl/IPrintable_DTypename.json5 + OUTPUT_HPP_DIR include/xo/expression2 + OUTPUT_IMPL_SUBDIR typename +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-expression-varref @@ -198,7 +222,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-varref - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR VarRef INPUT idl/IGCObject_DVarRef.json5 @@ -233,7 +257,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-defineexpr - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR DefineExpr INPUT idl/IGCObject_DDefineExpr.json5 @@ -268,7 +292,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-applyexpr - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR ApplyExpr INPUT idl/IGCObject_DApplyExpr.json5 @@ -303,7 +327,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-lambdaexpr - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR LambdaExpr INPUT idl/IGCObject_DLambdaExpr.json5 @@ -338,7 +362,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-ifelseexpr - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR IfElseExpr INPUT idl/IGCObject_DIfElseExpr.json5 @@ -373,7 +397,7 @@ xo_add_genfacetimpl( # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-expression2-facetimpl-gcobject-sequenceexpr - FACET_PKG xo_gc + FACET_PKG xo_alloc2 FACET GCObject REPR SequenceExpr INPUT idl/IGCObject_DSequenceExpr.json5 diff --git a/xo-expression2/cmake/xo_expression2Config.cmake.in b/xo-expression2/cmake/xo_expression2Config.cmake.in index ca2e2ccb..c237d261 100644 --- a/xo-expression2/cmake/xo_expression2Config.cmake.in +++ b/xo-expression2/cmake/xo_expression2Config.cmake.in @@ -6,6 +6,7 @@ include(CMakeFindDependencyMacro) # must coordinate with xo_dependency() calls # in CMakeLists.txt # +find_dependency(xo_type) find_dependency(xo_gc) find_dependency(reflect) find_dependency(xo_procedure2) diff --git a/xo-expression2/idl/IGCObject_DTypename.json5 b/xo-expression2/idl/IGCObject_DTypename.json5 new file mode 100644 index 00000000..ae99ef9a --- /dev/null +++ b/xo-expression2/idl/IGCObject_DTypename.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "typename", + includes: [ +// "", +// "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DTypename", + using_doxygen: true, + repr: "DTypename", + doc: [ "implement AGCObject for DTypename" ], +} diff --git a/xo-expression2/idl/IPrintable_DTypename.json5 b/xo-expression2/idl/IPrintable_DTypename.json5 new file mode 100644 index 00000000..d11d8993 --- /dev/null +++ b/xo-expression2/idl/IPrintable_DTypename.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/expression2", + output_hpp_dir: "include/xo/expression2", + output_impl_subdir: "typename", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DTypename", + using_doxygen: true, + repr: "DTypename", + doc: [ "implement APrintable for DTypename" ], +} diff --git a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp index 5cd03fb2..5fe1edb3 100644 --- a/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DGlobalSymtab.hpp @@ -7,6 +7,7 @@ #include "Binding.hpp" #include "DVariable.hpp" +#include "DTypename.hpp" #include #include #include @@ -38,16 +39,18 @@ namespace xo { /** @defgroup scm-globalsymtab-ctors constructors **/ ///@{ - DGlobalSymtab(dp map, DArray * vars); + DGlobalSymtab(dp var_map, DArray * vars, + dp type_map, DArray * types); /** create instance. * Use memory from @p fixed_mm for @ref map_. * Use memory from @p mm for DGlobalSymtab instance. - * Hashmap configured per @p cfg. + * Hashmap for variables per @p var_cfg; for types per @p type_cfg. **/ static dp make(obj mm, obj fixed_mm, - const ArenaHashMapConfig & cfg); + const ArenaHashMapConfig & var_cfg, + const ArenaHashMapConfig & type_cfg); /** non-trivial destructor for @ref map_ **/ ~DGlobalSymtab() = default; @@ -56,8 +59,8 @@ 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(); } + size_type n_vars() const noexcept { return var_map_->size(); } + size_type var_capacity() const noexcept { return var_map_->capacity(); } /** visit symtab-owned memory pools; call visitor(info) for each **/ void visit_pools(const MemorySizeVisitor & visitor) const; @@ -65,6 +68,9 @@ namespace xo { /** lookup global symbol with name @p sym **/ DVariable * lookup_variable(const DUniqueString * sym) const noexcept; + /** lookup global typename with name @p sym **/ + DTypename * lookup_typename(const DUniqueString * sym) const noexcept; + ///@} /** @defgroup scm-globalsymtab-general-methods general methods **/ ///@{ @@ -76,6 +82,13 @@ namespace xo { void upsert_variable(obj mm, DVariable * var); + /** update this symtab to associate typename @p type with @c type->name(). + * If there was a previous type with the same name, replace it with + * @p type. + **/ + void upsert_typename(obj mm, + DTypename * type); + ///@} /** @defgroup scm-globalsymtab-symboltable-facet symboltable facet **/ ///@{ @@ -104,20 +117,31 @@ namespace xo { ///@} private: - /** map symbols -> bindings. - * Minor point: storing offsets instead of Variables allows us to omit - * iterating over map elements during GC. Possible savings if map_ slots - * sparsely populated. + /** map variable symbol -> index into @ref vars_. + * Minor point: storing offsets instead of Variables allows us to: + * omit hash-map iteration during GC. + * Savings when map_ slots sparsely populated. **/ - dp map_; + dp var_map_; /** array of variables. * When S is a unique-string for a global symbol, then: - * 1. map_[S] is unique global index i(S) for S. + * 1. var_map_[S] is unique global index i(S) for S. * 2. vars_[i(S)] is variable-expr var(S) for S * 3. var(S)->name == S **/ DArray * vars_ = nullptr; + + /** map type name -> index values into @ref types_ **/ + dp type_map_; + + /** array of types. + * When T is a unique-string for a globally-defined type, then: + * 1. type_map_[T] is unique global index i(T) for T. + * 2. types_[i(T)] is type type(T) for T + * 3. type(T)->name == T + **/ + DArray * types_ = nullptr; }; } /*namespace scm*/ diff --git a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp index 30ed2b74..a7de8044 100644 --- a/xo-expression2/include/xo/expression2/DLambdaExpr.hpp +++ b/xo-expression2/include/xo/expression2/DLambdaExpr.hpp @@ -62,7 +62,7 @@ namespace xo { ///@{ DLocalSymtab * local_symtab() const noexcept { return local_symtab_; } - size_type n_args() const noexcept { return local_symtab_->size(); } + size_type n_args() const noexcept { return local_symtab_->n_vars(); } obj body_expr() const noexcept { return body_expr_; } // get_free_variables() diff --git a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp index f4073226..6e459035 100644 --- a/xo-expression2/include/xo/expression2/DLocalSymtab.hpp +++ b/xo-expression2/include/xo/expression2/DLocalSymtab.hpp @@ -8,9 +8,7 @@ #include "Binding.hpp" #include "DVariable.hpp" #include "DUniqueString.hpp" -//#include "exprtype.hpp" -//#include -//#include +#include namespace xo { namespace scm { @@ -19,14 +17,11 @@ namespace xo { **/ struct DLocalSymtab { public: -// using TaggedPtr = xo::reflect::TaggedPtr; -// using TypeDescr = xo::reflect::TypeDescr; -// using AGCObject = xo::mm::AGCObject; -// using typeseq = xo::reflect::typeseq; - + using DArray = xo::scm::DArray; using ppindentinfo = xo::print::ppindentinfo; using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; /* note: uint16_t would be fine too */ using size_type = std::uint32_t; @@ -46,32 +41,31 @@ namespace xo { /** @defgroup scm-lambdaexpr-constructors **/ ///@{ - /** empty instance with parent @p p and capacity for @p n slots. - * Caller must ensure that slots_[0..n) are actually addressable + /** empty instance with parent @p p, using arrays @p vars for variables + * and @p types for type definitions. **/ - DLocalSymtab(DLocalSymtab * p, size_type n); + DLocalSymtab(DLocalSymtab * p, DArray * nv, DArray * nt); /** scaffold empty symtab instance, - * with capacity for @p n slots, using memory from allocator @p mm + * capacity for @p nv vars and @p nt types, + * using memory from allocator @p mm. + * Symtab chains to parent @p p. **/ static DLocalSymtab * _make_empty(obj mm, DLocalSymtab * p, - size_type n); + size_type nv, + size_type nt); ///@} /** @defgroup scm-lambdaexpr-methods **/ ///@{ DLocalSymtab * parent() const noexcept { return parent_; } - size_type capacity() const noexcept { return capacity_; } - size_type size() const noexcept { return size_; } + //size_type capacity() const noexcept { return capacity_; } + size_type n_vars() const noexcept { return vars_->size(); } + size_type n_types() const noexcept { return types_->size(); } - DVariable * lookup_var(Binding ix) noexcept { - assert(ix.i_link() == 0); - assert(ix.j_slot() < static_cast(size_)); - - return slots_[ix.j_slot()].var_; - } + DVariable * lookup_var(Binding ix) noexcept; /** increase slot size (provided below capacity) to append * binding for one local variable. Local variable will be allocated @@ -81,6 +75,14 @@ namespace xo { const DUniqueString * name, TypeRef typeref); + /** increase slot size (provided below capacity) to append + * binding for one local type. Local type will be allocated + * from @p mm, named @p name, with type described by @p type. + **/ + void append_type(obj mm, + const DUniqueString * name, + obj type); + ///@} /** @defgroup xo-localsymtab-symboltable-facet symboltable facet**/ ///@{ @@ -110,12 +112,23 @@ namespace xo { private: /** parent symbol table from scoping surrounding this one **/ DLocalSymtab * parent_ = nullptr; + /** variables owned by (declared in) this symbol table + * vars_[i] is convertible to obj + **/ + DArray * vars_ = nullptr; + /** types owned by (defined in) this symbol table + * types_[i] is convertible to obj + **/ + DArray * types_ = nullptr; + +#ifdef OBSOLETE /** actual range of slots_[] array. Can use indices in [0,..,n) **/ size_type capacity_ = 0; /** number of slots in use **/ size_type size_ = 0; /** memory for names and bindings **/ Slot slots_[]; +#endif }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-expression2/include/xo/expression2/DSequenceExpr.hpp b/xo-expression2/include/xo/expression2/DSequenceExpr.hpp index c5bb6f16..39fa79d0 100644 --- a/xo-expression2/include/xo/expression2/DSequenceExpr.hpp +++ b/xo-expression2/include/xo/expression2/DSequenceExpr.hpp @@ -29,8 +29,8 @@ namespace xo { using ppindentinfo = xo::print::ppindentinfo; public: - DSequenceExpr() = default; - DSequenceExpr(DArray * xv) : expr_v_{xv} {} + DSequenceExpr() ; + DSequenceExpr(DArray * xv); /** create empty sequence using memory from @p mm **/ static obj make_empty(obj mm); diff --git a/xo-expression2/include/xo/expression2/DTypename.hpp b/xo-expression2/include/xo/expression2/DTypename.hpp new file mode 100644 index 00000000..1d9d0629 --- /dev/null +++ b/xo-expression2/include/xo/expression2/DTypename.hpp @@ -0,0 +1,77 @@ +/** @file DTypename.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DUniqueString.hpp" +#include +#include +#include + +namespace xo { + namespace scm { + + /** @class DTypename + * @brief Container for a named type + * + * Represents the result of syntax like + * 1. deftype Foo :: i64; + * 2. deftype FooAlias :: Foo; + **/ + class DTypename { + public: + using ppindentinfo = xo::print::ppindentinfo; + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + using AGCObject = xo::mm::AGCObject; + + public: + DTypename(const DUniqueString * name, + obj type); + + /** create instance + * @p mm memory allocator + * @p name type name + * @p type type definition + **/ + static DTypename * _make(obj mm, + const DUniqueString * name, + obj type); + /** create fop for new instance **/ + static obj make(obj mm, + const DUniqueString * name, + obj type); + + const DUniqueString * name() const noexcept { return name_; } + obj type() const noexcept { return type_; } + + void assign_name(const DUniqueString * name) { this->name_ = name; } + + + /** @defgroup scm-typename-gcobject-facet **/ + ///@{ + + size_t shallow_size() const noexcept; + DTypename * shallow_copy(obj mm) const noexcept; + size_t forward_children(obj gc) noexcept; + + ///@} + /** @defgroup scm-typename-printable-facet **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** symbol name **/ + const DUniqueString * name_ = nullptr; + /** type defintion. Everything but the name **/ + obj type_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DTypename.hpp */ diff --git a/xo-expression2/include/xo/expression2/DVariable.hpp b/xo-expression2/include/xo/expression2/DVariable.hpp index 29253097..329cf088 100644 --- a/xo-expression2/include/xo/expression2/DVariable.hpp +++ b/xo-expression2/include/xo/expression2/DVariable.hpp @@ -76,7 +76,7 @@ namespace xo { private: /** symbol name **/ - const DUniqueString * name_; + const DUniqueString * name_ = nullptr; /** variable value always has type consistent * with this description **/ diff --git a/xo-expression2/include/xo/expression2/TypeRef.hpp b/xo-expression2/include/xo/expression2/TypeRef.hpp index eecb438d..1342b4df 100644 --- a/xo-expression2/include/xo/expression2/TypeRef.hpp +++ b/xo-expression2/include/xo/expression2/TypeRef.hpp @@ -5,7 +5,9 @@ #pragma once +#include #include +#include #include #include @@ -23,17 +25,28 @@ namespace xo { using TypeDescr = xo::reflect::TypeDescr; using type_var = flatstring<20>; using prefix_type = flatstring<8>; + using ACollector = xo::mm::ACollector; using ppindentinfo = xo::print::ppindentinfo; public: TypeRef() = default; - TypeRef(const type_var & id, TypeDescr td); + TypeRef(const type_var & id, obj type); /** trivial typeref, where already resolved. * Require: @p td non-null **/ static TypeRef resolved(TypeDescr td); + /** trivial typeref, where already resolved **/ + static TypeRef resolved(obj type); + + /** if @p type is non-null + * -> type already resolved + * else + * -> generate unique typevar name, starting with @p prefix + **/ + static TypeRef dwim(prefix_type prefix, obj type); + /** if @p td is non-null * -> type is already resolved * @@ -59,9 +72,19 @@ namespace xo { /** pretty-printer support **/ bool pretty(const ppindentinfo & ppii) const; + /** gc support **/ + void forward_children(obj gc) noexcept; + + private: + TypeRef(const type_var & id, TypeDescr td); + private: /** unique (probably generated) name for type at this location **/ type_var id_; + + /** Type, when resolved **/ + obj type_; + /** Description for concrete type, once resolved. * May be null when this TypeRef created, * but expected to be immutable once established. diff --git a/xo-expression2/include/xo/expression2/Typename.hpp b/xo-expression2/include/xo/expression2/Typename.hpp new file mode 100644 index 00000000..69c90bab --- /dev/null +++ b/xo-expression2/include/xo/expression2/Typename.hpp @@ -0,0 +1,12 @@ +/** @file Typename.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DTypename.hpp" +#include "typename/IGCObject_DTypename.hpp" +#include "typename/IPrintable_DTypename.hpp" + +/* end Typename.hpp */ diff --git a/xo-expression2/include/xo/expression2/typename/IGCObject_DTypename.hpp b/xo-expression2/include/xo/expression2/typename/IGCObject_DTypename.hpp new file mode 100644 index 00000000..f01740d4 --- /dev/null +++ b/xo-expression2/include/xo/expression2/typename/IGCObject_DTypename.hpp @@ -0,0 +1,65 @@ +/** @file IGCObject_DTypename.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DTypename.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DTypename.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include "DTypename.hpp" + +namespace xo { namespace scm { class IGCObject_DTypename; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DTypename + **/ + class IGCObject_DTypename { + public: + /** @defgroup scm-gcobject-dtypename-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-dtypename-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DTypename & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DTypename & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DTypename & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-expression2/include/xo/expression2/typename/IPrintable_DTypename.hpp b/xo-expression2/include/xo/expression2/typename/IPrintable_DTypename.hpp new file mode 100644 index 00000000..88504191 --- /dev/null +++ b/xo-expression2/include/xo/expression2/typename/IPrintable_DTypename.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DTypename.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DTypename.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DTypename.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DTypename.hpp" + +namespace xo { namespace scm { class IPrintable_DTypename; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DTypename + **/ + class IPrintable_DTypename { + public: + /** @defgroup scm-printable-dtypename-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dtypename-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DTypename & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*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 d5bf81f4..42b491fc 100644 --- a/xo-expression2/src/expression2/CMakeLists.txt +++ b/xo-expression2/src/expression2/CMakeLists.txt @@ -63,11 +63,16 @@ set(SELF_SRCS IGCObject_DGlobalSymtab.cpp IPrintable_DGlobalSymtab.cpp + DTypename.cpp + IGCObject_DTypename.cpp + IPrintable_DTypename.cpp + ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) # note: deps here must also appear in cmake/xo_expression2Config.cmake.in xo_dependency(${SELF_LIB} xo_gc) +xo_dependency(${SELF_LIB} xo_type) xo_dependency(${SELF_LIB} reflect) xo_dependency(${SELF_LIB} xo_procedure2) xo_dependency(${SELF_LIB} xo_printable2) diff --git a/xo-expression2/src/expression2/DApplyExpr.cpp b/xo-expression2/src/expression2/DApplyExpr.cpp index d4e1fa55..784e4473 100644 --- a/xo-expression2/src/expression2/DApplyExpr.cpp +++ b/xo-expression2/src/expression2/DApplyExpr.cpp @@ -129,6 +129,13 @@ namespace xo { std::size_t DApplyExpr::forward_children(obj gc) noexcept { + typeref_.forward_children(gc); + + { + obj fn_gco = fn_.to_facet(); + gc.forward_inplace(fn_gco.iface(), (void **)&fn_.data_); + } + for (size_type i = 0; i < n_args_; ++i) { obj & arg = args_[i]; diff --git a/xo-expression2/src/expression2/DConstant.cpp b/xo-expression2/src/expression2/DConstant.cpp index f1f560be..53ab045e 100644 --- a/xo-expression2/src/expression2/DConstant.cpp +++ b/xo-expression2/src/expression2/DConstant.cpp @@ -91,7 +91,10 @@ namespace xo { std::size_t DConstant::forward_children(obj gc) noexcept { - gc.forward_inplace(value_.iface(), (void **)&(value_.data_)); + typeref_.forward_children(gc); + + gc.forward_inplace(&value_); + //gc.forward_inplace(value_.iface(), (void **)&(value_.data_)); return shallow_size(); } diff --git a/xo-expression2/src/expression2/DGlobalSymtab.cpp b/xo-expression2/src/expression2/DGlobalSymtab.cpp index 95db6b26..d7f52228 100644 --- a/xo-expression2/src/expression2/DGlobalSymtab.cpp +++ b/xo-expression2/src/expression2/DGlobalSymtab.cpp @@ -4,6 +4,8 @@ **/ #include "DGlobalSymtab.hpp" +#include "Typename.hpp" +#include "Binding.hpp" #include "DUniqueString.hpp" #include #include @@ -18,25 +20,40 @@ namespace xo { namespace scm { - DGlobalSymtab::DGlobalSymtab(dp map, - DArray * vars) - : map_{std::move(map)}, vars_{vars} + DGlobalSymtab::DGlobalSymtab(dp var_map, + DArray * vars, + dp type_map, + DArray * types) + : var_map_{std::move(var_map)}, vars_{vars}, + type_map_{std::move(type_map)}, types_{types} { } dp DGlobalSymtab::make(obj mm, obj aux_mm, - const ArenaHashMapConfig & cfg) + const ArenaHashMapConfig & var_cfg, + const ArenaHashMapConfig & type_cfg) { - auto map = dp::make(aux_mm, cfg); - assert(map); + /* note: using aux_mm for DArenaHashMap superstructure. + * {variable, type} storage allocated from mm. + */ + + auto var_map = dp::make(aux_mm, var_cfg); + assert(var_map); /* choosing same capacity for hash, vars */ - DArray * vars = DArray::empty(mm, map->capacity()); + DArray * vars = DArray::empty(mm, var_map->capacity()); assert(vars); - auto symtab = dp::make(mm, std::move(map), vars); + auto type_map = dp::make(aux_mm, type_cfg); + assert(type_map); + + DArray * types = DArray::empty(mm, type_map->capacity()); + + auto symtab = dp::make(mm, + std::move(var_map), vars, + std::move(type_map), types); assert(symtab); return symtab; @@ -45,8 +62,10 @@ namespace xo { void DGlobalSymtab::visit_pools(const MemorySizeVisitor & visitor) const { - if (map_) - map_->visit_pools(visitor); + if (var_map_) + var_map_->visit_pools(visitor); + if (type_map_) + type_map_->visit_pools(visitor); } DVariable * @@ -58,11 +77,11 @@ namespace xo { return nullptr; auto var_gco = obj::from((*vars_)[existing.j_slot()]); - auto var = var_gco.to_facet(); - assert(var.data()); + //auto var = var_gco.to_facet(); + //assert(var.data()); - return var.data(); + return var_gco.data(); } void @@ -93,6 +112,7 @@ namespace xo { // stash new definition (possibly has different type), // replacing previous one // + log && log("STUB: need write barrier"); (*vars_)[existing->path().j_slot()] = obj(var); } else { log && log("variable is new"); @@ -123,12 +143,70 @@ namespace xo { var->assign_path(binding); // need slot# in .map_ for this unique symbol - (*map_)[var->name()] = binding.j_slot(); + (*var_map_)[var->name()] = binding.j_slot(); vars_->push_back(obj(var)); } } + DTypename * + DGlobalSymtab::lookup_typename(const DUniqueString * sym) const noexcept + { + auto ix = type_map_->find(sym); + + if (ix == type_map_->end()) + return nullptr; + + Binding::slot_type i_slot = ix->second; + + auto tname_gco = obj::from((*types_)[i_slot]); + + return tname_gco.data(); + } + + void + DGlobalSymtab::upsert_typename(obj mm, + DTypename * tname) + { + scope log(XO_DEBUG(true), + std::string_view(*tname->name())); + + auto ix = type_map_->find(tname->name()); + + if (ix == type_map_->end()) { + log && log("typename is new"); + + DArray::size_type n = types_->size(); + + /** make sure types_ has room **/ + if (n == types_->capacity()) { + // DArray is out of room. + // Reallocate with more capacity + DArray * types_2x = DArray::copy(mm, types_, types_->capacity() * 2); + + if (!types_2x) { + assert(false); + + // in any case, we can't make progress + return; + } + + log && log("STUB: need write barrier"); + this->types_ = types_2x; + } + + (*type_map_)[tname->name()] = n; + + log && log("STUB: need write barrier"); + types_->push_back(obj(tname)); + } else { + Binding::slot_type i_slot = ix->second; + + log && log("STUB: need write barrier"); + (*types_)[i_slot] = obj(tname); + } + } + #ifdef NOT_USING // don't know if we need this path DVariable * DGlobalSymtab::establish_variable(obj mm, @@ -154,9 +232,9 @@ namespace xo { scope log(XO_DEBUG(true), std::string_view(*sym)); - auto ix = map_->find(sym); + auto ix = var_map_->find(sym); - if (ix == map_->end()) + if (ix == var_map_->end()) return Binding::null(); return Binding::global(ix->second); @@ -185,7 +263,8 @@ namespace xo { if (copy_mem) { DGlobalSymtab * self = const_cast(this); - return new (copy_mem) DGlobalSymtab(std::move(self->map_), vars_); + return new (copy_mem) DGlobalSymtab(std::move(self->var_map_), vars_, + std::move(self->type_map_), types_); } return nullptr; @@ -197,6 +276,7 @@ namespace xo { // map_ doesn't contain any gc-owned data, can skip gc.forward_inplace(&vars_); + gc.forward_inplace(&types_); return this->shallow_size(); } @@ -209,8 +289,10 @@ namespace xo { return ppii.pps()->pretty_struct (ppii, "DGlobalSymtab", - refrtag("nsym", vars_->size()), - refrtag("capacity", vars_->capacity())); + refrtag("nvar", vars_->size()), + refrtag("var_capacity", vars_->capacity()), + refrtag("ntype", types_->size()), + refrtag("type_capacity", types_->capacity())); } } /*namespace scm*/ diff --git a/xo-expression2/src/expression2/DIfElseExpr.cpp b/xo-expression2/src/expression2/DIfElseExpr.cpp index 649a2482..0db04f7e 100644 --- a/xo-expression2/src/expression2/DIfElseExpr.cpp +++ b/xo-expression2/src/expression2/DIfElseExpr.cpp @@ -102,17 +102,19 @@ namespace xo { std::size_t DIfElseExpr::forward_children(obj gc) noexcept { + typeref_.forward_children(gc); + // GC needs to locate AGCObject iface for each member. { - auto gco = FacetRegistry::instance().variant(test_); + auto gco = test_.to_facet(); gc.forward_inplace(gco.iface(), (void **)&(test_.data_)); } { - auto gco = FacetRegistry::instance().variant(when_true_); + auto gco = when_true_.to_facet(); gc.forward_inplace(gco.iface(), (void **)&(when_true_.data_)); } { - auto gco = FacetRegistry::instance().variant(when_false_); + auto gco = when_false_.to_facet(); gc.forward_inplace(gco.iface(), (void **)&(when_false_.data_)); } diff --git a/xo-expression2/src/expression2/DLambdaExpr.cpp b/xo-expression2/src/expression2/DLambdaExpr.cpp index 56d55c03..a45c1e32 100644 --- a/xo-expression2/src/expression2/DLambdaExpr.cpp +++ b/xo-expression2/src/expression2/DLambdaExpr.cpp @@ -95,7 +95,7 @@ namespace xo { std::vector arg_td_v; { - DLocalSymtab::size_type z = symtab->size(); + DLocalSymtab::size_type z = symtab->n_vars(); arg_td_v.reserve(z); @@ -152,7 +152,10 @@ namespace xo { std::size_t DLambdaExpr::forward_children(obj gc) noexcept { + typeref_.forward_children(gc); + { + //gc.forward_inplace(&name_); // doesn't compile for const ptr auto iface = xo::facet::impl_for(); gc.forward_inplace(&iface, (void **)(&name_)); } @@ -160,8 +163,9 @@ namespace xo { // type_name_str_ { - auto iface = xo::facet::impl_for(); - gc.forward_inplace(&iface, (void **)(&local_symtab_)); + gc.forward_inplace(&local_symtab_); + //auto iface = xo::facet::impl_for(); + //gc.forward_inplace(&iface, (void **)(&local_symtab_)); } { diff --git a/xo-expression2/src/expression2/DLocalSymtab.cpp b/xo-expression2/src/expression2/DLocalSymtab.cpp index cf9c8459..539d5d78 100644 --- a/xo-expression2/src/expression2/DLocalSymtab.cpp +++ b/xo-expression2/src/expression2/DLocalSymtab.cpp @@ -5,38 +5,52 @@ #include "LocalSymtab.hpp" #include "Variable.hpp" +#include "Typename.hpp" #include "DUniqueString.hpp" +#include #include +#include #include namespace xo { using xo::mm::AGCObject; using xo::print::APrintable; - using xo::facet::typeseq; + //using xo::facet::typeseq; using xo::print::ppstate; namespace scm { DLocalSymtab::DLocalSymtab(DLocalSymtab * p, - size_type n) : parent_{p}, - capacity_{n}, - size_{0} + DArray * vars, DArray * types) + : parent_{p}, vars_{vars}, types_{types} { - for (size_type i = 0; i < n; ++i) { - void * mem = &slots_[i]; - new (mem) Slot(); - } } DLocalSymtab * DLocalSymtab::_make_empty(obj mm, DLocalSymtab * p, - size_type n) + size_type nv, + size_type nt) { - void * mem = mm.alloc(typeseq::id(), - sizeof(DLocalSymtab) + (n * sizeof(Slot))); + void * mem = mm.alloc_for(); - return new (mem) DLocalSymtab(p, n); + DArray * vars = DArray::empty(mm, nv); + DArray * types = DArray::empty(mm, nt); + + return new (mem) DLocalSymtab(p, vars, types); + } + + DVariable * + DLocalSymtab::lookup_var(Binding ix) noexcept + { + assert(ix.i_link() == 0); + assert(ix.j_slot() < static_cast(vars_->size())); + + auto var = obj::from((*vars_)[ix.j_slot()]); + + assert(var); + + return var.data(); } Binding @@ -46,32 +60,50 @@ namespace xo { { assert(name); - if (size_ >= capacity_ || !name) { + if (vars_->size() >= vars_->capacity() || !name) { assert(false); return Binding::null(); } else { - size_type i_slot = (this->size_)++; - Binding binding = Binding::local(i_slot); - DVariable * var = DVariable::make(mm, name, typeref, binding); + //size_type i_slot = (this->size_)++; + Binding binding = Binding::local(vars_->size()); - this->slots_[i_slot] = Slot(var); + DVariable * var = DVariable::make(mm, name, typeref, binding); + vars_->push_back(obj(var)); return binding; } } + void + DLocalSymtab::append_type(obj mm, + const DUniqueString * name, + obj type) + { + assert(name); + + if (types_->size() >= types_->capacity() || !name) { + assert(false); + } else { + obj tname = DTypename::make(mm, name, type); + + types_->push_back(tname); + } + } + Binding DLocalSymtab::lookup_binding(const DUniqueString * sym) const noexcept { assert(sym); if (sym) { - for (size_type i = 0; i < size_; ++i) { - const Slot & slot = slots_[i]; + for (size_type i = 0, n = vars_->size(); i < n; ++i) { + auto var_i = obj::from((*vars_)[i]); - if (*sym == *(slot.var_->name())) - return slot.var_->path(); + assert(var_i); + + if (*sym == *(var_i->name())) + return var_i->path(); } } @@ -83,39 +115,21 @@ namespace xo { std::size_t DLocalSymtab::shallow_size() const noexcept { - return (sizeof(DLocalSymtab) + (capacity_ * sizeof(Slot))); + return sizeof(DLocalSymtab); } DLocalSymtab * DLocalSymtab::shallow_copy(obj mm) const noexcept { - DLocalSymtab * copy = (DLocalSymtab *)mm.alloc_copy((std::byte *)this); - - if (copy) { - *copy = *this; - - ::memcpy((void*)&(copy->slots_[0]), - (void*)&(slots_[0]), - capacity_ * sizeof(Slot)); - } - - return copy; + return mm.std_copy_for(this); } std::size_t DLocalSymtab::forward_children(obj gc) noexcept { - { - auto iface - = xo::facet::impl_for(); - gc.forward_inplace(&iface, (void **)(&parent_)); - } - - auto iface - = xo::facet::impl_for(); - for (size_type i = 0; i < size_; ++i) { - gc.forward_inplace(&iface, (void **)(&(slots_[i].var_))); - } + gc.forward_inplace(&parent_); + gc.forward_inplace(&vars_); + gc.forward_inplace(&types_); return shallow_size(); } @@ -127,45 +141,69 @@ namespace xo { { ppstate * pps = ppii.pps(); + (void)pps; + if (ppii.upto()) { /* perhaps print on one line */ if (!pps->print_upto("print_upto(xrefrtag("size", size_))) + + if (!pps->print_upto(xrefrtag("nvars", vars_->size()))) return false; - for (size_type i = 0; i < size_; ++i) { + for (size_type i = 0, n = vars_->size(); i arg_pr(const_cast(slots_[i].var_)); + obj arg_pr = (*vars_)[i].to_facet(); if (!pps->print_upto(xrefrtag(buf, arg_pr))) return false; } + if (!pps->print_upto(xrefrtag("ntypes", types_->size()))) + return false; + + for (size_type i = 0, n = types_->size(); i < n; ++i) { + char buf[32]; + snprintf(buf, sizeof(buf), "[%u]", i); + + obj type_pr = (*types_)[i].to_facet(); + + if (!pps->print_upto(xrefrtag(buf, type_pr))) + return false; + } + pps->write(">"); return true; } else { /* with line breaks */ pps->write("newline_pretty_tag(ppii.ci1(), "size", size_); + pps->newline_pretty_tag(ppii.ci1(), "nvars", vars_->size()); - for (size_type i = 0; i < size_; ++i) { + for (size_type i = 0, n = vars_->size(); i < n; ++i) { char buf[32]; snprintf(buf, sizeof(buf), "[%u]", i); - assert(slots_[i].var_); - - obj arg_pr(const_cast(slots_[i].var_)); + obj arg_pr = (*vars_)[i].to_facet(); pps->newline_pretty_tag(ppii.ci1(), buf, arg_pr); } + pps->newline_pretty_tag(ppii.ci1(), "ntypes", types_->size()); + + for (size_type i = 0, n = types_->size(); i < n; ++i) { + char buf[32]; + snprintf(buf, sizeof(buf), "[%u]", i); + + obj type_pr = (*types_)[i].to_facet(); + + pps->newline_pretty_tag(ppii.ci1(), buf, type_pr); + } + pps->write(">"); + return false; } } diff --git a/xo-expression2/src/expression2/DSequenceExpr.cpp b/xo-expression2/src/expression2/DSequenceExpr.cpp index fdc73b8e..141d4946 100644 --- a/xo-expression2/src/expression2/DSequenceExpr.cpp +++ b/xo-expression2/src/expression2/DSequenceExpr.cpp @@ -22,6 +22,12 @@ namespace xo { namespace scm { + DSequenceExpr::DSequenceExpr() = default; + + DSequenceExpr::DSequenceExpr(DArray * xv) + : expr_v_{xv} + {} + obj DSequenceExpr::make_empty(obj mm) { @@ -127,13 +133,13 @@ namespace xo { std::size_t DSequenceExpr::forward_children(obj gc) noexcept { - // WARNING. - // if this proves problematic, - // may resort to obj for expr_v_ member + typeref_.forward_children(gc); - auto iface = facet::impl_for(); - - gc.forward_inplace(&iface, (void**)&expr_v_); + { + //auto iface = facet::impl_for(); + //gc.forward_inplace(&iface, (void**)&expr_v_); + gc.forward_inplace(&expr_v_); + } return this->shallow_size(); } diff --git a/xo-expression2/src/expression2/DTypename.cpp b/xo-expression2/src/expression2/DTypename.cpp new file mode 100644 index 00000000..fd62336b --- /dev/null +++ b/xo-expression2/src/expression2/DTypename.cpp @@ -0,0 +1,89 @@ +/** @file DTypename.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "Typename.hpp" +#include +#include +#include +#include +#include + +namespace xo { + using xo::mm::ACollector; + using xo::mm::AGCObject; + using xo::print::APrintable; + + namespace scm { + + DTypename * + DTypename::_make(obj mm, + const DUniqueString * name, + obj type) + { + void * mem = mm.alloc_for(); + + return new (mem) DTypename(name, type); + } + + obj + DTypename::make(obj mm, + const DUniqueString * name, + obj type) + { + return obj(_make(mm, name, type)); + } + + DTypename::DTypename(const DUniqueString * name, + obj type) + : name_{name}, type_{type} + {} + + size_t + DTypename::shallow_size() const noexcept + { + return sizeof(DTypename); + } + + DTypename * + DTypename::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + size_t + DTypename::forward_children(obj gc) noexcept + { + gc.forward_inplace(const_cast(&name_)); + { + auto e = type_.to_facet(); + gc.forward_inplace(e.iface(), (void **)&(type_.data_)); + } + + return shallow_size(); + } + + bool + DTypename::pretty(const ppindentinfo & ppii) const + { + using xo::print::quot; + + auto name = (name_ + ? std::string_view(*name_) + : std::string_view("")); + + auto type_pr = type_.to_facet(); + + return ppii.pps()->pretty_struct + (ppii, + "DTypename" + , refrtag("name", quot(name)) + , refrtag("type", type_pr) + ); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DTypename.cpp */ diff --git a/xo-expression2/src/expression2/DVariable.cpp b/xo-expression2/src/expression2/DVariable.cpp index 8fc201a5..092eb715 100644 --- a/xo-expression2/src/expression2/DVariable.cpp +++ b/xo-expression2/src/expression2/DVariable.cpp @@ -57,12 +57,9 @@ namespace xo { } size_t - DVariable::forward_children(obj) noexcept + DVariable::forward_children(obj gc) noexcept { - // nothing to collect. - // - DUniqueString never in GC space - // - TypeDescr not in GC space - // - path only integers + typeref_.forward_children(gc); return shallow_size(); } diff --git a/xo-expression2/src/expression2/IGCObject_DTypename.cpp b/xo-expression2/src/expression2/IGCObject_DTypename.cpp new file mode 100644 index 00000000..2b898fbf --- /dev/null +++ b/xo-expression2/src/expression2/IGCObject_DTypename.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DTypename.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DTypename.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DTypename.json5] +**/ + +#include "typename/IGCObject_DTypename.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DTypename::shallow_size(const DTypename & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DTypename::shallow_copy(const DTypename & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DTypename::forward_children(DTypename & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DTypename.cpp */ diff --git a/xo-expression2/src/expression2/IPrintable_DTypename.cpp b/xo-expression2/src/expression2/IPrintable_DTypename.cpp new file mode 100644 index 00000000..8d753b0e --- /dev/null +++ b/xo-expression2/src/expression2/IPrintable_DTypename.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DTypename.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DTypename.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DTypename.json5] +**/ + +#include "typename/IPrintable_DTypename.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DTypename::pretty(const DTypename & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DTypename.cpp */ diff --git a/xo-expression2/src/expression2/TypeRef.cpp b/xo-expression2/src/expression2/TypeRef.cpp index 5ff1d258..4040cf13 100644 --- a/xo-expression2/src/expression2/TypeRef.cpp +++ b/xo-expression2/src/expression2/TypeRef.cpp @@ -4,16 +4,34 @@ **/ #include "TypeRef.hpp" +#include +#include #include #include #include namespace xo { + using xo::mm::AGCObject; + using xo::facet::FacetRegistry; + namespace scm { + TypeRef::TypeRef(const type_var & id, obj type) + : id_{id}, type_{type} + {} + TypeRef::TypeRef(const type_var & id, TypeDescr td) : id_{id}, td_{td} {} + TypeRef + TypeRef::resolved(obj type) + { + assert(type); + + type_var null; + return TypeRef(null, type); + } + TypeRef TypeRef::resolved(TypeDescr td) { @@ -23,6 +41,23 @@ namespace xo { return TypeRef(null, td); } + TypeRef + TypeRef::dwim(prefix_type prefix, obj type) + { + if (type) { + /* type already resolved + * -> we don't need a type variable name + */ + return TypeRef::resolved(type); + } else { + /* type is not resolved yet. + * -> give it a unique name, + * to seed unification + */ + return TypeRef(generate_unique(prefix), type); + } + } + TypeRef TypeRef::dwim(prefix_type prefix, TypeDescr td) { @@ -65,6 +100,15 @@ namespace xo { return (td_ != nullptr); } + void + TypeRef::forward_children(obj gc) noexcept + { + { + auto e = FacetRegistry::instance().variant(type_); + gc.forward_inplace(e.iface(), (void **)&(type_.data_)); + } + } + bool TypeRef::pretty(const ppindentinfo & ppii) const { diff --git a/xo-expression2/src/expression2/expression2_register_facets.cpp b/xo-expression2/src/expression2/expression2_register_facets.cpp index 3cd9413d..1e68c771 100644 --- a/xo-expression2/src/expression2/expression2_register_facets.cpp +++ b/xo-expression2/src/expression2/expression2_register_facets.cpp @@ -5,11 +5,13 @@ #include "expression2_register_facets.hpp" -#include -#include -#include +//#include +//#include +//#include #include +#include +#include #include #include #include @@ -83,6 +85,11 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + // Typename + + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // SymbolTable // +- LocalSymtab // \- GlobalSymtab @@ -103,6 +110,7 @@ namespace xo { log && log(xtag("DUniqueString.tseq", typeseq::id())); log && log(xtag("DDefineExpr.tseq", typeseq::id())); log && log(xtag("DVariable.tseq", typeseq::id())); + log && log(xtag("DTypename.tseq", typeseq::id())); log && log(xtag("DVarRef.tseq", typeseq::id())); log && log(xtag("DConstant.tseq", typeseq::id())); log && log(xtag("DApplyExpr.tseq", typeseq::id())); diff --git a/xo-expression2/src/expression2/expression2_register_types.cpp b/xo-expression2/src/expression2/expression2_register_types.cpp index 7a64eb1f..c62ea264 100644 --- a/xo-expression2/src/expression2/expression2_register_types.cpp +++ b/xo-expression2/src/expression2/expression2_register_types.cpp @@ -5,14 +5,17 @@ #include "expression2_register_types.hpp" +#include "DefineExpr.hpp" #include "Constant.hpp" -//#include "detail/IGCObject_DConstant.hpp" -#include "detail/IGCObject_DVariable.hpp" +#include "Variable.hpp" +#include "Typename.hpp" //#include "detail/IGCObject_DDefineExpr.hpp" // when avail //#include "detail/IGCObject_DApplyExpr.hpp" // when avail -//#include "detail/IGCObject_DLambdaExpr.hpp" // when avail -#include "detail/IGCObject_DIfElseExpr.hpp" -#include "detail/IGCObject_DSequenceExpr.hpp" +#include "LambdaExpr.hpp" +#include "IfElseExpr.hpp" +#include "SequenceExpr.hpp" +#include "LocalSymtab.hpp" +#include "GlobalSymtab.hpp" //#include "detail/IGCObject_DLocalSymtab.hpp" // when avail //#include "detail/IGCObject_DUniqueString.hpp" @@ -24,7 +27,6 @@ namespace xo { using xo::mm::ACollector; using xo::mm::AGCObject; using xo::facet::impl_for; - using xo::facet::typeseq; using xo::scope; namespace scm { @@ -37,13 +39,15 @@ namespace xo { ok &= gc.install_type(impl_for()); ok &= gc.install_type(impl_for()); - //ok &= gc.install_type(impl_for()); // when avail + ok &= gc.install_type(impl_for()); + ok &= gc.install_type(impl_for()); //ok &= gc.install_type(impl_for()); // when avail - //ok &= gc.install_type(impl_for()); // when avail + ok &= gc.install_type(impl_for()); ok &= gc.install_type(impl_for()); ok &= gc.install_type(impl_for()); - //ok &= gc.install_type(impl_for()); // when avail + ok &= gc.install_type(impl_for()); + ok &= gc.install_type(impl_for()); return ok; } diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index eda22f5d..69bfbee8 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -249,7 +249,7 @@ namespace xo { template template obj - obj::to_facet() + obj::to_facet() const { if (this->data()) { if constexpr (std::is_same_v) { @@ -270,7 +270,7 @@ namespace xo { template template obj - obj::try_to_facet() noexcept + obj::try_to_facet() const noexcept { if (this->data()) { if constexpr (std::is_same_v) { diff --git a/xo-facet/include/xo/facet/obj.hpp b/xo-facet/include/xo/facet/obj.hpp index d16c776c..d5834310 100644 --- a/xo-facet/include/xo/facet/obj.hpp +++ b/xo-facet/include/xo/facet/obj.hpp @@ -135,13 +135,13 @@ namespace xo { * Definition in FacetRegistry.hpp, to avoid #include dependency **/ template - obj to_facet(); + obj to_facet() const; /** like to_facet(), * but on failure return empty obj instead of throwing exception **/ template - obj try_to_facet() noexcept; + obj try_to_facet() const noexcept; /** enabled when RRouter provides _preincrement. * Note we don't need this trick for comparison operators, diff --git a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp index e2df166b..da7f8536 100644 --- a/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DGlobalEnv.hpp @@ -47,8 +47,8 @@ namespace xo { /** @defgroup scm-globalenv-methods methods **/ ///@{ - /** symbol-table size. Is the number of distinct global symbols **/ - size_type size() const noexcept { return symtab_->size(); } + /** symbol-table size. Is the number of distinct global variables **/ + size_type n_vars() const noexcept { return symtab_->n_vars(); } /** lookup current value associated with binding @p ix **/ obj lookup_value(Binding ix) const noexcept; diff --git a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp index eaef71c2..ab407063 100644 --- a/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp +++ b/xo-interpreter2/include/xo/interpreter2/DLocalEnv.hpp @@ -41,7 +41,8 @@ namespace xo { ///@{ DLocalEnv * parent() const noexcept { return parent_; } - size_type size() const noexcept { return symtab_->size(); } + size_type n_vars() const noexcept { return symtab_->n_vars(); } + size_type n_types() const noexcept { return symtab_->n_types(); } /** lookup current value associated with binding @p ix **/ obj lookup_value(Binding ix) const noexcept; diff --git a/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp b/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp index 2ad6c1ba..fcc92efa 100644 --- a/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/DGlobalEnv.cpp @@ -21,7 +21,7 @@ namespace xo { DGlobalEnv::_make(obj mm, DGlobalSymtab * symtab) { - DArray * values = DArray::empty(mm, symtab->capacity()); + DArray * values = DArray::empty(mm, symtab->var_capacity()); void * mem = mm.alloc_for(); @@ -136,7 +136,7 @@ namespace xo { return ppii.pps()->pretty_struct (ppii, "DGlobalEnv", - refrtag("size", symtab_->size())); + refrtag("n_vars", symtab_->n_vars())); } } /*namespace scm*/ diff --git a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp index 8f45b38a..3831b647 100644 --- a/xo-interpreter2/src/interpreter2/DLocalEnv.cpp +++ b/xo-interpreter2/src/interpreter2/DLocalEnv.cpp @@ -49,7 +49,7 @@ namespace xo { if (env) { auto j = ix.j_slot(); - if (j < static_cast(env->size())) { + if (j < static_cast(env->n_vars())) { return (*(env->args_))[j]; } else { assert(false); @@ -78,7 +78,7 @@ namespace xo { if (env) { auto j = ix.j_slot(); - if (j < static_cast(env->size())) { + if (j < static_cast(env->n_vars())) { log && log("STUB: need write barrier for GC here"); (*(env->args_))[j] = x; } else { diff --git a/xo-reader2/CMakeLists.txt b/xo-reader2/CMakeLists.txt index 54441a8c..8e0f1e95 100644 --- a/xo-reader2/CMakeLists.txt +++ b/xo-reader2/CMakeLists.txt @@ -73,6 +73,26 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-deftypessm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR DeftypeSsm + INPUT idl/ISyntaxStateMachine_DDeftypeSsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-deftypessm + FACET_PKG xo_printable2 + FACET Printable + REPR DeftypeSsm + INPUT idl/IPrintable_DDeftypeSsm.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-lambdassm diff --git a/xo-reader2/idl/IPrintable_DDeftypeSsm.json5 b/xo-reader2/idl/IPrintable_DDeftypeSsm.json5 new file mode 100644 index 00000000..e61f5881 --- /dev/null +++ b/xo-reader2/idl/IPrintable_DDeftypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DDeftypeSsm", + using_doxygen: true, + repr: "DDeftypeSsm", + doc: [ "implement APrintable for DDeftypeSsm" ], +} diff --git a/xo-reader2/idl/ISyntaxStateMachine_DDeftypeSsm.json5 b/xo-reader2/idl/ISyntaxStateMachine_DDeftypeSsm.json5 new file mode 100644 index 00000000..d3e3b174 --- /dev/null +++ b/xo-reader2/idl/ISyntaxStateMachine_DDeftypeSsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DDeftypeSsm", + using_doxygen: true, + repr: "DDeftypeSsm", + doc: [ "implement ASyntaxStateMachine for DDeftypeSsm" ], +} diff --git a/xo-reader2/include/xo/reader2/DDeftypeSsm.hpp b/xo-reader2/include/xo/reader2/DDeftypeSsm.hpp new file mode 100644 index 00000000..29a1d691 --- /dev/null +++ b/xo-reader2/include/xo/reader2/DDeftypeSsm.hpp @@ -0,0 +1,186 @@ +/** @file DDeftypeSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +#include + +namespace xo { + namespace scm { + /** + * @pre + * + * deftype foo :: f64 ; + * ^ ^ ^ ^ ^ ^ + * | | | | | (done) + * | | | | def_4 + * | | | def_3 + * | | def_2 + * | def_1 + * def_0 + * + * def_0 --on_deftype_token()--> def_1 [expect symbol] + * def_1 --on_symbol_token()--> def_2 [expect ::] + * def_2 --on_doublecolon_token()--> def_3 [start ExpectTypeSsm] + * def_3 --on_parsed_type()--> def_4 [++ symbol table] + * def_4 --on_semicolon_token()--> (done) [pop] + * + * @endpre + **/ + class DeftypeXst { + public: + enum class code { + invalid = -1, + + def_0, + def_1, + def_2, + def_3, + def_4, + + N, + }; + + explicit DeftypeXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + std::ostream & + operator<<(std::ostream & os, DeftypeXst x); + + /** @class DDeftypeSsm + * @brief state machine for parsing a deftype expression + **/ + class DDeftypeSsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using TypeDescr = xo::reflect::TypeDescr; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using ppindentinfo = xo::print::ppindentinfo; + + public: + /** @defgroup scm-deftypessm-ctors constructors **/ + ///@{ + + /** constructor; using @p def_expr for initial expression scaffold **/ + explicit DDeftypeSsm(); + + /** Create instance using memory from @p parser_mm **/ + static DDeftypeSsm * _make(DArena & parser_mm); + + /** create fop referring to new DDeftypeSsm **/ + static obj make(DArena & parser_mm); + + /** start nested parser for a define-expression, + * on top of parser state machine @p p_psm + * Use @p parser_mm to allocate syntax state machines, + * and @p expr_mm to allocate expressions + **/ + static void start(DArena & parser_mm, + //obj expr_mm, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-definessm-access-methods **/ + ///@{ + + /** identify this nested state machine **/ + static const char * ssm_classname() { return "DDeftypeSsm"; } + + /** internal state **/ + DeftypeXst deftypestate() const noexcept { return deftype_xst_; } + + ///@} + /** @defgroup scm-definessm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error messages + **/ + std::string_view get_expect_str() const noexcept; + + /** operate state machine for this syntax on incoming token @p tk + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming @c deftype token @p tk, + * overall parser state in @p p_psm + **/ + void on_deftype_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming double-colon token @p tk, + * overall parser state in @p p_psm + **/ + void on_doublecolon_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a symbol @p sym; + * overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + /** update state for this syntax after type @p type emitted by nested + * state machine, with overall parser state in @p p_psm + **/ + void on_parsed_type(obj type, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + /** update state for this syntax after parsing a type-description @p td, + * overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); +#endif + + /** update state for this syntax after parsing semicolon token @p tk, + * overall parser state in @p p_psm. + * if state def_4 completes deftype statement. + **/ + void on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-define-printable-facet printable facet methods **/ + ///@{ + + /** pretty-printer support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** @defgroup scm-deftypessm-member-vars **/ + ///@{ + + /** identify deftype ssm state **/ + DeftypeXst deftype_xst_; + + /** lhs symbol for type definition **/ + const DUniqueString * lhs_symbol_ = nullptr; + + ///@} + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDefineSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 8d67b448..aba12f8d 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -30,14 +30,14 @@ namespace xo { using ppindentinfo = xo::print::ppindentinfo; public: - DExpectTypeSsm(); + explicit DExpectTypeSsm(bool corrected); - static DExpectTypeSsm * _make(DArena & parser_mm); + static DExpectTypeSsm * _make(DArena & parser_mm, bool corrected); /** create fop referring to new DExpectTypeSsm **/ - static obj make(DArena & parser_mm); + static obj make(DArena & parser_mm, bool corrected); - static void start(ParserStateMachine * p_psm); + static void start(bool corrected, ParserStateMachine * p_psm); static const char * ssm_classname() { return "DExpectTypeSsm"; } @@ -72,6 +72,12 @@ namespace xo { ///@} + private: + /** temporary shim. + * if true, construct obj + * if false, construct TypeDescr + **/ + bool corrected_ = false; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/include/xo/reader2/DQuoteSsm.hpp b/xo-reader2/include/xo/reader2/DQuoteSsm.hpp index 6cbfac79..26079e8e 100644 --- a/xo-reader2/include/xo/reader2/DQuoteSsm.hpp +++ b/xo-reader2/include/xo/reader2/DQuoteSsm.hpp @@ -32,7 +32,6 @@ namespace xo { * * @endpre **/ - class QuoteXst { public: enum class code { diff --git a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp index 10aeccfa..66852170 100644 --- a/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/DSyntaxStateMachine.hpp @@ -48,6 +48,7 @@ namespace xo { void illegal_type(obj type, ParserStateMachine * p_psm) { + // starting with c++23 can use "this auto&& self" instead Derived & self = static_cast(*this); p_psm->illegal_input_on_type(Derived::ssm_classname(), @@ -55,6 +56,18 @@ namespace xo { self.get_expect_str()); } + /** Explicit error path **/ + void illegal_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + // starting with c++23 can use "this auto&& self" instead + Derived & self = static_cast(*this); + + p_psm->illegal_input_on_symbol(Derived::ssm_classname(), + sym, + self.get_expect_str()); + } + /** Explicit error path **/ void illegal_quoted_literal(obj lit, ParserStateMachine * p_psm) @@ -78,12 +91,7 @@ namespace xo { void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { - // starting with c++23 can use "this auto&& self" instead - Derived & self = reinterpret_cast(*this); - - p_psm->illegal_input_on_symbol(Derived::ssm_classname(), - sym, - self.get_expect_str()); + this->illegal_parsed_symbol(sym, p_psm); } /** Default implementation for required SyntaxStateMachine facet method diff --git a/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp b/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp index d20e751a..9bb9b076 100644 --- a/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp +++ b/xo-reader2/include/xo/reader2/DToplevelSeqSsm.hpp @@ -84,6 +84,11 @@ namespace xo { **/ void on_def_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming @c deftype token @p tk, + * with overall parser state in @p p_psm + **/ + void on_deftype_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming lamdba token @p tk, * overall parser state in @p p_psm **/ diff --git a/xo-reader2/include/xo/reader2/DeftypeSsm.hpp b/xo-reader2/include/xo/reader2/DeftypeSsm.hpp new file mode 100644 index 00000000..22ec3eec --- /dev/null +++ b/xo-reader2/include/xo/reader2/DeftypeSsm.hpp @@ -0,0 +1,12 @@ +/** @file DeftypeSsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DDeftypeSsm.hpp" +#include "ssm/ISyntaxStateMachine_DDeftypeSsm.hpp" +#include "ssm/IPrintable_DDeftypeSsm.hpp" + +/* end DeftypeSsm.hpp */ diff --git a/xo-reader2/include/xo/reader2/ParserConfig.hpp b/xo-reader2/include/xo/reader2/ParserConfig.hpp index 080238c7..07dcb37b 100644 --- a/xo-reader2/include/xo/reader2/ParserConfig.hpp +++ b/xo-reader2/include/xo/reader2/ParserConfig.hpp @@ -24,7 +24,7 @@ namespace xo { .header_{}, .debug_flag_ = false }; - /** configuration for hash map for global symbol table + /** configuration for hash map for global symbol table (variables) * * reminder: ownership chain * SchematikaReader @@ -32,9 +32,25 @@ namespace xo { * ->ParserStateMachine * ->DGlobalSymtab **/ - ArenaHashMapConfig symtab_config_ { .name_ = "global-symtab", - .hint_max_capacity_ = 64*1024, - .debug_flag_ = false }; + ArenaHashMapConfig symtab_var_config_ { + .name_ = "global-vars", + .hint_max_capacity_ = 64*1024, + .debug_flag_ = false + }; + + /** configuration for hash map for global symbol table (types) + * + * reminder: ownership chain + * SchematikaReader + * ->SchematikaParser + * ->ParserStateMachine + * ->DGlobalSymtab + **/ + ArenaHashMapConfig symtab_types_config_ { + .name_ = "global-types", + .hint_max_capacity_ = 32*1024, + .debug_flag_ = false + }; /** max capacity for unique string table **/ size_t max_stringtable_capacity_ = 4096; diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index 2553acbf..f24c6bed 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -47,8 +47,10 @@ namespace xo { public: /** * @p config arena configuration for parser state - * @p symtab_config configuration for global symtab + * @p symtab_var_config configuration for global symtab variables * (maps separate dedicated memory) + * @p symtab_type_config configuration for global symtab types + * (maps to separate dedicated memory) * @p max_stringtable_capacity * hard max size for unique stringtable * @p expr_alloc allocator for schematika expressions. @@ -59,7 +61,8 @@ namespace xo { * same as @p expr_alloc. **/ ParserStateMachine(const ArenaConfig & config, - const ArenaHashMapConfig & symtab_config, + const ArenaHashMapConfig & symtab_var_config, + const ArenaHashMapConfig & symtab_type_config, size_type max_stringtable_capacity, obj expr_alloc, obj aux_alloc); @@ -151,6 +154,9 @@ namespace xo { **/ void on_parsed_typedescr(TypeDescr td); + /** respond to type emitted by nested ssm **/ + void on_parsed_type(obj type); + /** update state to consume param (name, type) emitted by * nested (expired) parsing state **/ diff --git a/xo-reader2/include/xo/reader2/ReaderConfig.hpp b/xo-reader2/include/xo/reader2/ReaderConfig.hpp index e139e9eb..513f515e 100644 --- a/xo-reader2/include/xo/reader2/ReaderConfig.hpp +++ b/xo-reader2/include/xo/reader2/ReaderConfig.hpp @@ -37,7 +37,7 @@ namespace xo { .header_{}, .debug_flag_ = false }; - /** configuration for hash map for global symbol table + /** configuration for hash map for global symbol table (variables) * * reminder: ownership chain * SchematikaReader @@ -45,9 +45,25 @@ namespace xo { * ->ParserStateMachine * ->DGlobalSymtab **/ - ArenaHashMapConfig symtab_config_ { .name_ = "global-symtab", - .hint_max_capacity_ = 64*1024, - .debug_flag_ = false }; + ArenaHashMapConfig symtab_var_config_ { + .name_ = "global-vars", + .hint_max_capacity_ = 64*1024, + .debug_flag_ = false, + }; + + /** configuration for hash map for global symbol table (types) + * + * reminder: ownership chain + * SchematikaReader + * ->SchematikaParser + * ->ParserStateMachine + * ->DGlobalSymtab + **/ + ArenaHashMapConfig symtab_types_config_ { + .name_ = "global-types", + .hint_max_capacity_ = 32*1024, + .debug_flag_ = false, + }; /** debug flag for schematika parser **/ bool parser_debug_flag_ = false; diff --git a/xo-reader2/include/xo/reader2/ssm/IPrintable_DDeftypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/IPrintable_DDeftypeSsm.hpp new file mode 100644 index 00000000..df8820c0 --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/IPrintable_DDeftypeSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DDeftypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDeftypeSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DDeftypeSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DDeftypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DDeftypeSsm + **/ + class IPrintable_DDeftypeSsm { + public: + /** @defgroup scm-printable-ddeftypessm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-ddeftypessm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DDeftypeSsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDeftypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDeftypeSsm.hpp new file mode 100644 index 00000000..114f2dab --- /dev/null +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDeftypeSsm.hpp @@ -0,0 +1,84 @@ +/** @file ISyntaxStateMachine_DDeftypeSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DDeftypeSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DDeftypeSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DDeftypeSsm + **/ + class ISyntaxStateMachine_DDeftypeSsm { + public: + /** @defgroup scm-syntaxstatemachine-ddeftypessm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-ddeftypessm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DDeftypeSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DDeftypeSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DDeftypeSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DDeftypeSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DDeftypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for type emitted by nested ssm **/ + static void on_parsed_type(DDeftypeSsm & self, obj type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DDeftypeSsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DDeftypeSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DDeftypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DDeftypeSsm & self, obj lit, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp index 4d857d53..a01dcb62 100644 --- a/xo-reader2/include/xo/reader2/syntaxstatetype.hpp +++ b/xo-reader2/include/xo/reader2/syntaxstatetype.hpp @@ -21,6 +21,9 @@ namespace xo { /** handle define-expression. See @ref DDefineSsm **/ defexpr, + /** handle deftype-expression. See @ref DDeftypeSsm **/ + deftypeexpr, + /** handle lambda-expression. See @ref DLambdaSsm **/ lambdaexpr, diff --git a/xo-reader2/src/reader2/CMakeLists.txt b/xo-reader2/src/reader2/CMakeLists.txt index 8633f75a..53c69bc6 100644 --- a/xo-reader2/src/reader2/CMakeLists.txt +++ b/xo-reader2/src/reader2/CMakeLists.txt @@ -25,6 +25,10 @@ set(SELF_SRCS ISyntaxStateMachine_DDefineSsm.cpp IPrintable_DDefineSsm.cpp + DDeftypeSsm.cpp + ISyntaxStateMachine_DDeftypeSsm.cpp + IPrintable_DDeftypeSsm.cpp + DIfElseSsm.cpp ISyntaxStateMachine_DIfElseSsm.cpp IPrintable_DIfElseSsm.cpp diff --git a/xo-reader2/src/reader2/DApplySsm.cpp b/xo-reader2/src/reader2/DApplySsm.cpp index b0653a52..ad9a4e50 100644 --- a/xo-reader2/src/reader2/DApplySsm.cpp +++ b/xo-reader2/src/reader2/DApplySsm.cpp @@ -139,6 +139,7 @@ namespace xo { return; case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_then: case tokentype::tk_else: diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 8266046f..344e1fc1 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -13,14 +13,6 @@ #include #include -#ifdef NOT_YET -#include "parserstatemachine.hpp" -#include "expect_symbol_xs.hpp" -#include "expect_expr_xs.hpp" -#include "expect_type_xs.hpp" -#include "pretty_expression.hpp" -#endif - namespace xo { using xo::print::APrintable; using xo::facet::FacetRegistry; @@ -526,6 +518,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_deftype: case tokentype::tk_string: case tokentype::tk_f64: case tokentype::tk_i64: @@ -600,7 +593,7 @@ namespace xo { if (defstate_ == defexprstatetype::def_2) { this->defstate_ = defexprstatetype::def_3; - DExpectTypeSsm::start(p_psm); + DExpectTypeSsm::start(false /*!corrected*/, p_psm); return; } @@ -688,7 +681,6 @@ namespace xo { = FacetRegistry::instance().variant(def_expr_); assert(expr.data()); - (void)expr; return ppii.pps()->pretty_struct(ppii, "DDefineSsm", diff --git a/xo-reader2/src/reader2/DDeftypeSsm.cpp b/xo-reader2/src/reader2/DDeftypeSsm.cpp new file mode 100644 index 00000000..ec36391a --- /dev/null +++ b/xo-reader2/src/reader2/DDeftypeSsm.cpp @@ -0,0 +1,275 @@ +/** @file DDeftypeSsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "DeftypeSsm.hpp" +#include "syntaxstatetype.hpp" +#include "ExpectSymbolSsm.hpp" +#include "ExpectTypeSsm.hpp" +#include "Constant.hpp" +#include +#include + +namespace xo { + namespace scm { + + extern const char * + DeftypeXst::_descr(enum DeftypeXst::code x) + { + switch (x) { + case code::invalid: return "invalid"; + case code::def_0: return "def_0"; + case code::def_1: return "def_1"; + case code::def_2: return "def_2"; + case code::def_3: return "def_3"; + case code::def_4: return "def_4"; + case code::N: break; + } + + return "?DeftypeXst"; + } + + std::ostream & + operator<<(std::ostream & os, DeftypeXst x) + { + os << DeftypeXst::_descr(x.code()); + return os; + } + + DDeftypeSsm::DDeftypeSsm() + : deftype_xst_{DeftypeXst::code::def_0} + {} + + DDeftypeSsm * + DDeftypeSsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc_for(); + + return new (mem) DDeftypeSsm(); + } + + obj + DDeftypeSsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + void + DDeftypeSsm::start(DArena & mm, + ParserStateMachine * p_psm) + { + assert(p_psm->stack()); + + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + auto deftype_ssm = DDeftypeSsm::make(mm); + + p_psm->push_ssm(ckp, deftype_ssm); + } + + syntaxstatetype + DDeftypeSsm::ssm_type() const noexcept + { + return syntaxstatetype::deftypeexpr; + } + + std::string_view + DDeftypeSsm::get_expect_str() const noexcept + { + switch (this->deftype_xst_.code()) { + case DeftypeXst::code::invalid: + break; + case DeftypeXst::code::def_0: + return "deftype"; + case DeftypeXst::code::def_1: + return "symbol"; + case DeftypeXst::code::def_2: + return "doublecolon"; + case DeftypeXst::code::def_3: + return "type"; + case DeftypeXst::code::def_4: + return "semicolon"; + case DeftypeXst::code::N: + break; + + } + + return "?expect"; + } + + void + DDeftypeSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag()), xtag("tk", tk)); + + switch (tk.tk_type()) { + + case tokentype::tk_deftype: + this->on_deftype_token(tk, p_psm); + return; + + case tokentype::tk_doublecolon: + this->on_doublecolon_token(tk, p_psm); + return; + + case tokentype::tk_semicolon: + this->on_semicolon_token(tk, p_psm); + return; + + // all the not-yet handled cases + case tokentype::tk_symbol: + case tokentype::tk_def: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_invalid: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_if: + case tokentype::tk_quote: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_comma: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_lambda: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + + Super::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_deftype_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_0) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_1); + + DExpectSymbolSsm::start(p_psm); + + /* continue in .on_parsed_symbol() */ + + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_parsed_symbol(std::string_view sym_name, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_1) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_2); + this->lhs_symbol_ = p_psm->intern_string(sym_name); + + return; + } + + Super::illegal_parsed_symbol(sym_name, p_psm); + } + + void + DDeftypeSsm::on_doublecolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_2) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_3); + + DExpectTypeSsm::start(true /*corrected*/, p_psm); + + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DDeftypeSsm::on_parsed_type(obj type, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_3) { + this->deftype_xst_ = DeftypeXst(DeftypeXst::code::def_4); + + DLocalSymtab * local = p_psm->local_symtab(); + + if (local) { + local->append_type(p_psm->expr_alloc(), + lhs_symbol_, + type); + } else { + DGlobalSymtab * global = p_psm->global_symtab(); + + DTypename * tname = DTypename::_make(p_psm->expr_alloc(), + lhs_symbol_, + type); + + global->upsert_typename(p_psm->expr_alloc(), tname); + } + + return; + } + + Super::illegal_type(type, p_psm); + } + + void + DDeftypeSsm::on_semicolon_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (deftype_xst_.code() == DeftypeXst::code::def_4) { + p_psm->pop_ssm(); + + // Reporting a placeholder expression to preserve policy + // that 'every toplevel statement produces an expression' + // + auto result_expr + = DConstant::make(p_psm->expr_alloc(), + DBoolean::box(p_psm->expr_alloc(), + true)); + p_psm->on_parsed_expression(result_expr); + + return; + } + + Super::illegal_token(tk, p_psm); + } + + bool + DDeftypeSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DDeftypeSsm", + refrtag("deftypestate", deftype_xst_), + refrtag("expect", this->get_expect_str())); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDeftypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 40ed2476..c2d46140 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -165,6 +165,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: + case tokentype::tk_deftype: case tokentype::tk_singleassign: case tokentype::tk_colon: case tokentype::tk_semicolon: diff --git a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp index 7986a6de..db287abf 100644 --- a/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArgSsm.cpp @@ -105,6 +105,7 @@ namespace xo { case tokentype::tk_leftparen: case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_singleassign: @@ -154,7 +155,7 @@ namespace xo { if (fstate_ == formalstatetype::formal_1) { this->fstate_ = formalstatetype::formal_2; - DExpectTypeSsm::start(p_psm); + DExpectTypeSsm::start(false /*!corrected*/, p_psm); /* control reenters via DExpectFormalArgSsm::on_parsed_typedescr() */ return; diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index 1de4533b..67f327e1 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -135,6 +135,7 @@ namespace xo { // all the not-yet-handled cases case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: diff --git a/xo-reader2/src/reader2/DExpectQArraySsm.cpp b/xo-reader2/src/reader2/DExpectQArraySsm.cpp index b4a9ac29..33ccd7c8 100644 --- a/xo-reader2/src/reader2/DExpectQArraySsm.cpp +++ b/xo-reader2/src/reader2/DExpectQArraySsm.cpp @@ -92,6 +92,7 @@ namespace xo { case tokentype::tk_comma: case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: diff --git a/xo-reader2/src/reader2/DExpectQListSsm.cpp b/xo-reader2/src/reader2/DExpectQListSsm.cpp index 2227a398..9584bfea 100644 --- a/xo-reader2/src/reader2/DExpectQListSsm.cpp +++ b/xo-reader2/src/reader2/DExpectQListSsm.cpp @@ -92,6 +92,7 @@ namespace xo { case tokentype::tk_comma: case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: diff --git a/xo-reader2/src/reader2/DExpectQLiteralSsm.cpp b/xo-reader2/src/reader2/DExpectQLiteralSsm.cpp index e03e7a39..7dc30124 100644 --- a/xo-reader2/src/reader2/DExpectQLiteralSsm.cpp +++ b/xo-reader2/src/reader2/DExpectQLiteralSsm.cpp @@ -110,6 +110,7 @@ namespace xo { case tokentype::tk_comma: case tokentype::tk_lambda: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index 0a5d7abb..79ae0622 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -74,6 +74,7 @@ namespace xo { case tokentype::tk_i64: case tokentype::tk_bool: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_singleassign: case tokentype::tk_colon: diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index e4078936..edd71d66 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -3,14 +3,15 @@ * @author Roland Conybeare, Aug 2024 **/ -#include "DExpectTypeSsm.hpp" -#include "ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp" +#include "ExpectTypeSsm.hpp" +//#include "ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp" #include "SyntaxStateMachine.hpp" -#include +#include #include #include #include #include +#include namespace xo { using xo::facet::with_facet; @@ -19,30 +20,32 @@ namespace xo { using xo::reflect::typeseq; namespace scm { - DExpectTypeSsm::DExpectTypeSsm() + DExpectTypeSsm::DExpectTypeSsm(bool corrected) + : corrected_{corrected} {} DExpectTypeSsm * - DExpectTypeSsm::_make(DArena & mm) + DExpectTypeSsm::_make(DArena & mm, bool corrected) { void * mem = mm.alloc(typeseq::id(), sizeof(DArena)); - return new (mem) DExpectTypeSsm(); + return new (mem) DExpectTypeSsm(corrected); } obj - DExpectTypeSsm::make(DArena & mm) + DExpectTypeSsm::make(DArena & mm, bool corrected) { - return obj(_make(mm)); + return obj(_make(mm, corrected)); } void - DExpectTypeSsm::start(ParserStateMachine * p_psm) + DExpectTypeSsm::start(bool corrected, + ParserStateMachine * p_psm) { DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); - auto ssm = DExpectTypeSsm::make(p_psm->parser_alloc()); + auto ssm = DExpectTypeSsm::make(p_psm->parser_alloc(), corrected); p_psm->push_ssm(ckp, ssm); } @@ -73,6 +76,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_f64: case tokentype::tk_i64: @@ -124,32 +128,57 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); - TypeDescr td = nullptr; + if (corrected_) { + obj type; + obj mm = p_psm->expr_alloc(); - /* TODO: replace with typetable lookup */ + if (tk.text() == "unit") + type = DAtomicType::make(mm, Metatype::t_unit()); + if (tk.text() == "bool") + type = DAtomicType::make(mm, Metatype::t_bool()); + else if (tk.text() == "str") + type = DAtomicType::make(mm, Metatype::t_str()); + else if (tk.text() == "f64") + type = DAtomicType::make(mm, Metatype::t_f64()); + else if(tk.text() == "f32") + type = DAtomicType::make(mm, Metatype::t_f32()); + else if(tk.text() == "i16") + type = DAtomicType::make(mm, Metatype::t_i16()); + else if(tk.text() == "i32") + type = DAtomicType::make(mm, Metatype::t_i32()); + else if(tk.text() == "i64") + type = DAtomicType::make(mm, Metatype::t_i64()); - if (tk.text() == "bool") - td = Reflect::require(); - else if (tk.text() == "str") - td = Reflect::require(); - else if (tk.text() == "f64") - td = Reflect::require(); - else if(tk.text() == "f32") - td = Reflect::require(); - else if(tk.text() == "i16") - td = Reflect::require(); - else if(tk.text() == "i32") - td = Reflect::require(); - else if(tk.text() == "i64") - td = Reflect::require(); + p_psm->pop_ssm(); + p_psm->on_parsed_type(type); + } else { + TypeDescr td = nullptr; - if (!td) { - Super::on_token(tk, p_psm); - return; + /* TODO: replace with typetable lookup */ + + if (tk.text() == "bool") + td = Reflect::require(); + else if (tk.text() == "str") + td = Reflect::require(); + else if (tk.text() == "f64") + td = Reflect::require(); + else if(tk.text() == "f32") + td = Reflect::require(); + else if(tk.text() == "i16") + td = Reflect::require(); + else if(tk.text() == "i32") + td = Reflect::require(); + else if(tk.text() == "i64") + td = Reflect::require(); + + if (!td) { + Super::on_token(tk, p_psm); + return; + } + + p_psm->pop_ssm(); + p_psm->on_parsed_typedescr(td); } - - p_psm->pop_ssm(); - p_psm->on_parsed_typedescr(td); } bool diff --git a/xo-reader2/src/reader2/DIfElseSsm.cpp b/xo-reader2/src/reader2/DIfElseSsm.cpp index 5a17054d..00a41750 100644 --- a/xo-reader2/src/reader2/DIfElseSsm.cpp +++ b/xo-reader2/src/reader2/DIfElseSsm.cpp @@ -147,6 +147,7 @@ namespace xo { switch (tk.tk_type()) { case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: break; case tokentype::tk_if: this->on_if_token(tk, p_psm); diff --git a/xo-reader2/src/reader2/DLambdaSsm.cpp b/xo-reader2/src/reader2/DLambdaSsm.cpp index c0eb92cf..9364476a 100644 --- a/xo-reader2/src/reader2/DLambdaSsm.cpp +++ b/xo-reader2/src/reader2/DLambdaSsm.cpp @@ -3,34 +3,22 @@ * @author Roland Conybeare, Jan 2026 **/ -#include "DLambdaSsm.hpp" -#include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" -#include "DExpectFormalArglistSsm.hpp" -#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" +#include "LambdaSsm.hpp" +//#include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" +#include "ExpectFormalArglistSsm.hpp" +//#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" #include "DExpectTypeSsm.hpp" #include "DExpectExprSsm.hpp" #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" #include -#include -#include +#include +//#include //#include #include #include #include -#ifdef NOT_YET -#include "define_xs.hpp" -#include "parserstatemachine.hpp" -#include "exprstatestack.hpp" -#include "expect_formal_arglist_xs.hpp" -#include "expect_expr_xs.hpp" -#include "expect_type_xs.hpp" -#include "pretty_expression.hpp" -#include "pretty_variable.hpp" -#include "xo/expression/Lambda.hpp" -#endif - namespace xo { using xo::print::APrintable; using xo::mm::AAllocator; @@ -144,6 +132,7 @@ namespace xo { // all the not-yet-handled cases case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_symbol: case tokentype::tk_colon: @@ -209,7 +198,7 @@ namespace xo { if (lmstate_ == lambdastatetype::lm_2) { this->lmstate_ = lambdastatetype::lm_3; - DExpectTypeSsm::start(p_psm); + DExpectTypeSsm::start(false /*!corrected*/, p_psm); /* control reenters via .on_parsed_typedescr() */ return; @@ -300,7 +289,8 @@ namespace xo { DLocalSymtab * symtab = DLocalSymtab::_make_empty(p_psm->expr_alloc(), p_psm->local_symtab(), - arglist->size()); + arglist->size(), + 0 /*ntypes*/); assert(symtab); for (DArray::size_type i = 0, n = arglist->size(); i < n; ++i) { diff --git a/xo-reader2/src/reader2/DParenSsm.cpp b/xo-reader2/src/reader2/DParenSsm.cpp index 53dc3063..d3fb5cfa 100644 --- a/xo-reader2/src/reader2/DParenSsm.cpp +++ b/xo-reader2/src/reader2/DParenSsm.cpp @@ -102,6 +102,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_colon: case tokentype::tk_singleassign: case tokentype::tk_semicolon: diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 02d09e8a..edb55001 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -284,6 +284,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_invalid: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_quote: case tokentype::tk_leftbracket: diff --git a/xo-reader2/src/reader2/DQuoteSsm.cpp b/xo-reader2/src/reader2/DQuoteSsm.cpp index 1ca8a8a2..7f6dd00d 100644 --- a/xo-reader2/src/reader2/DQuoteSsm.cpp +++ b/xo-reader2/src/reader2/DQuoteSsm.cpp @@ -18,7 +18,7 @@ namespace xo { extern const char * QuoteXst::_descr(enum QuoteXst::code x) { - switch(x) { + switch (x) { case code::invalid: return "invalid"; case code::quote_0: return "quote_0"; case code::quote_1: return "quote_1"; @@ -104,6 +104,7 @@ namespace xo { // all the not-yet handled cases case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_colon: case tokentype::tk_singleassign: case tokentype::tk_semicolon: diff --git a/xo-reader2/src/reader2/DSequenceSsm.cpp b/xo-reader2/src/reader2/DSequenceSsm.cpp index 12d47a9d..8bb2f779 100644 --- a/xo-reader2/src/reader2/DSequenceSsm.cpp +++ b/xo-reader2/src/reader2/DSequenceSsm.cpp @@ -81,6 +81,7 @@ namespace xo { return; case tokentype::tk_symbol: case tokentype::tk_def: + case tokentype::tk_deftype: case tokentype::tk_if: case tokentype::tk_then: case tokentype::tk_else: diff --git a/xo-reader2/src/reader2/DToplevelSeqSsm.cpp b/xo-reader2/src/reader2/DToplevelSeqSsm.cpp index d7444e43..45a91a90 100644 --- a/xo-reader2/src/reader2/DToplevelSeqSsm.cpp +++ b/xo-reader2/src/reader2/DToplevelSeqSsm.cpp @@ -6,6 +6,7 @@ #include "DToplevelSeqSsm.hpp" #include "ssm/ISyntaxStateMachine_DToplevelSeqSsm.hpp" #include "DDefineSsm.hpp" +#include "DDeftypeSsm.hpp" #include "DLambdaSsm.hpp" #include "ProgressSsm.hpp" #include "DIfElseSsm.hpp" @@ -15,20 +16,10 @@ #include "VarRef.hpp" #include -//#include - #include -//#include - #include -//#include - #include -//#include - #include -//#include - #include namespace xo { @@ -133,6 +124,10 @@ namespace xo { this->on_def_token(tk, p_psm); return; + case tokentype::tk_deftype: + this->on_deftype_token(tk, p_psm); + return; + case tokentype::tk_lambda: this->on_lambda_token(tk, p_psm); return; @@ -255,6 +250,17 @@ namespace xo { */ } + void + DToplevelSeqSsm::on_deftype_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + DDeftypeSsm::start(p_psm->parser_alloc(), + p_psm); + p_psm->on_token(Token::deftype_token()); + } + void DToplevelSeqSsm::on_lambda_token(const Token & tk, ParserStateMachine * p_psm) @@ -462,8 +468,8 @@ namespace xo { void DToplevelSeqSsm::on_parsed_expression_with_token(obj expr, - const Token & tk, - ParserStateMachine * p_psm) + const Token & tk, + ParserStateMachine * p_psm) { if (tk.tk_type() == tokentype::tk_semicolon) { p_psm->capture_result("DToplevelSeqSsm::on_parsed_expression_with_token", expr); diff --git a/xo-reader2/src/reader2/IPrintable_DDeftypeSsm.cpp b/xo-reader2/src/reader2/IPrintable_DDeftypeSsm.cpp new file mode 100644 index 00000000..8f36fd09 --- /dev/null +++ b/xo-reader2/src/reader2/IPrintable_DDeftypeSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DDeftypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDeftypeSsm.json5] +**/ + +#include "ssm/IPrintable_DDeftypeSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DDeftypeSsm::pretty(const DDeftypeSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DDeftypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDeftypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDeftypeSsm.cpp new file mode 100644 index 00000000..9fcc835f --- /dev/null +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDeftypeSsm.cpp @@ -0,0 +1,84 @@ +/** @file ISyntaxStateMachine_DDeftypeSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DDeftypeSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DDeftypeSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DDeftypeSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DDeftypeSsm::ssm_type(const DDeftypeSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DDeftypeSsm::get_expect_str(const DDeftypeSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DDeftypeSsm::on_token(DDeftypeSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_symbol(DDeftypeSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_typedescr(DDeftypeSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_type(DDeftypeSsm & self, obj type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_type(type, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_formal(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_formal_with_token(DDeftypeSsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_formal_arglist(DDeftypeSsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_expression(DDeftypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_parsed_expression_with_token(DDeftypeSsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DDeftypeSsm::on_quoted_literal(DDeftypeSsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DDeftypeSsm.cpp */ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 3c640332..360ae43e 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -25,7 +25,8 @@ namespace xo { namespace scm { ParserStateMachine::ParserStateMachine(const ArenaConfig & config, - const ArenaHashMapConfig & symtab_config, + const ArenaHashMapConfig & symtab_var_config, + const ArenaHashMapConfig & symtab_type_config, size_type max_stringtable_capacity, obj expr_alloc, obj aux_alloc) @@ -33,7 +34,9 @@ namespace xo { parser_alloc_{DArena::map(config)}, expr_alloc_{expr_alloc}, aux_alloc_{aux_alloc}, - global_symtab_{DGlobalSymtab::make(expr_alloc, aux_alloc, symtab_config)}, + global_symtab_{DGlobalSymtab::make(expr_alloc, aux_alloc, + symtab_var_config, + symtab_type_config)}, debug_flag_{config.debug_flag_} { } @@ -275,6 +278,16 @@ namespace xo { this->stack_->top().on_parsed_typedescr(td, this); } + void + ParserStateMachine::on_parsed_type(obj type) + { + scope log(XO_DEBUG(debug_flag_)); + + assert(stack_); + + this->stack_->top().on_parsed_type(type, this); + } + void ParserStateMachine::on_parsed_formal(const DUniqueString * sym, TypeDescr td) diff --git a/xo-reader2/src/reader2/SchematikaParser.cpp b/xo-reader2/src/reader2/SchematikaParser.cpp index 74e17576..d6ab1a0a 100644 --- a/xo-reader2/src/reader2/SchematikaParser.cpp +++ b/xo-reader2/src/reader2/SchematikaParser.cpp @@ -23,11 +23,14 @@ namespace xo { SchematikaParser::SchematikaParser(const ParserConfig & cfg, obj expr_alloc, obj aux_alloc) - : psm_{cfg.parser_arena_config_, - cfg.symtab_config_, - cfg.max_stringtable_capacity_, - expr_alloc, - aux_alloc}, + : psm_{ + cfg.parser_arena_config_, + cfg.symtab_var_config_, + cfg.symtab_types_config_, + cfg.max_stringtable_capacity_, + expr_alloc, + aux_alloc + }, debug_flag_{cfg.debug_flag_} { } diff --git a/xo-reader2/src/reader2/SchematikaReader.cpp b/xo-reader2/src/reader2/SchematikaReader.cpp index f9cad55a..0725a18c 100644 --- a/xo-reader2/src/reader2/SchematikaReader.cpp +++ b/xo-reader2/src/reader2/SchematikaReader.cpp @@ -15,7 +15,8 @@ namespace xo { : tokenizer_{config.tk_buffer_config_, config.tk_debug_flag_}, parser_{ParserConfig(config.parser_arena_config_, - config.symtab_config_, + config.symtab_var_config_, + config.symtab_types_config_, config.max_stringtable_cap_, config.parser_debug_flag_), expr_alloc, diff --git a/xo-reader2/src/reader2/reader2_register_facets.cpp b/xo-reader2/src/reader2/reader2_register_facets.cpp index 909c1bc2..5262c1e9 100644 --- a/xo-reader2/src/reader2/reader2_register_facets.cpp +++ b/xo-reader2/src/reader2/reader2_register_facets.cpp @@ -8,6 +8,7 @@ #include "SchematikaParser.hpp" #include "ToplevelSeqSsm.hpp" #include "DefineSsm.hpp" +#include "DeftypeSsm.hpp" #include "LambdaSsm.hpp" #include "IfElseSsm.hpp" #include "ApplySsm.hpp" @@ -47,6 +48,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -98,6 +102,7 @@ namespace xo { log && log(xtag("DToplevelSeqSsm.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); + log && log(xtag("DDeftypeSsm.tseq", typeseq::id())); log && log(xtag("DLambdaSsm.tseq", typeseq::id())); log && log(xtag("DIfElseSsm.tseq", typeseq::id())); log && log(xtag("DExpectFormalArglistSsm.tseq", typeseq::id())); diff --git a/xo-reader2/src/reader2/syntaxstatetype.cpp b/xo-reader2/src/reader2/syntaxstatetype.cpp index 9b6c0928..4aa21b0c 100644 --- a/xo-reader2/src/reader2/syntaxstatetype.cpp +++ b/xo-reader2/src/reader2/syntaxstatetype.cpp @@ -15,6 +15,8 @@ namespace xo { break; case syntaxstatetype::defexpr: return "defexpr"; + case syntaxstatetype::deftypeexpr: + return "deftypeexpr"; case syntaxstatetype::lambdaexpr: return "lambdaexpr"; case syntaxstatetype::ifelseexpr: diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index c299306f..c2591815 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -77,7 +77,8 @@ namespace xo { ParserConfig cfg; cfg.parser_arena_config_.size_ = 16 * 1024; /* editor bait: symbol table */ - cfg.symtab_config_.hint_max_capacity_ = 128; + cfg.symtab_var_config_.hint_max_capacity_ = 128; + cfg.symtab_types_config_.hint_max_capacity_ = 64; cfg.max_stringtable_capacity_ = 512; cfg.debug_flag_ = false; @@ -272,6 +273,45 @@ namespace xo { log && fixture.log_memory_layout(&log); } + TEST_CASE("SchematikaParser-batch-deftype", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); + + parser.begin_batch_session(); + + /** Walkthrough parsing input equivalent to: + * + * deftype foo :: f64; + **/ + + std::vector tk_v{ + Token::deftype_token(), + Token::symbol_token("foo"), + Token::doublecolon_token(), + Token::symbol_token("f64"), + Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + const auto & result = parser.result(); + { + // placeholder for form's sake. + // deftype doesn't actuallly produce any executable content + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + } + + log && fixture.log_memory_layout(&log); + } + TEST_CASE("SchematikaParser-interactive-def2", "[reader2][SchematikaParser]") { const auto & testname = Catch::getResultCapture().getCurrentTestName(); @@ -1325,7 +1365,7 @@ namespace xo { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index 5f8be733..c7c43287 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -111,8 +111,8 @@ namespace xo { static Token comma_token() { return Token(tokentype::tk_comma); } /** token representing colon @c ":" **/ static Token colon_token() { return Token(tokentype::tk_colon); } - /** token representing double-colo @c "::" **/ - static Token doublecolon() { return Token(tokentype::tk_doublecolon); } + /** token representing double-colon @c "::" **/ + static Token doublecolon_token() { return Token(tokentype::tk_doublecolon); } /** token representing semicolon @c ";" **/ static Token semicolon_token() { return Token(tokentype::tk_semicolon); } /** token representing single-assignment @c "=" (editor bait: equal_token) **/ @@ -138,6 +138,8 @@ namespace xo { static Token type() { return Token(tokentype::tk_type); } /** token representing keyword @c def **/ static Token def_token() { return Token(tokentype::tk_def); } + /** token representing keyword @c deftype **/ + static Token deftype_token() { return Token(tokentype::tk_deftype); } /** token representing keyword @c lambda **/ static Token lambda_token() { return Token(tokentype::tk_lambda); } /** token representing keyword @c if **/ diff --git a/xo-tokenizer2/include/xo/tokenizer2/tokentype.hpp b/xo-tokenizer2/include/xo/tokenizer2/tokentype.hpp index 3f259f8d..d0290b05 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/tokentype.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/tokentype.hpp @@ -146,6 +146,9 @@ namespace xo { /** keyword @c 'def' **/ tk_def, + /** keyword @c 'deftype' **/ + tk_deftype, + /** keyword @c 'lambda' **/ tk_lambda, diff --git a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp index 323c2d8d..f6ac7c2f 100644 --- a/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp +++ b/xo-tokenizer2/src/tokenizer2/Tokenizer.cpp @@ -591,6 +591,8 @@ namespace xo { tk_type = tokentype::tk_type; } else if (tk_text == "def") { tk_type = tokentype::tk_def; + } else if (tk_text == "deftype") { + tk_type = tokentype::tk_deftype; } else if (tk_text == "lambda") { tk_type = tokentype::tk_lambda; } else if (tk_text == "if") { diff --git a/xo-tokenizer2/src/tokenizer2/tokentype.cpp b/xo-tokenizer2/src/tokenizer2/tokentype.cpp index 0831940f..7df59eec 100644 --- a/xo-tokenizer2/src/tokenizer2/tokentype.cpp +++ b/xo-tokenizer2/src/tokenizer2/tokentype.cpp @@ -51,6 +51,7 @@ namespace xo { CASE(tk_type); CASE(tk_def); + CASE(tk_deftype); CASE(tk_lambda); CASE(tk_if); CASE(tk_then); diff --git a/xo-type/cmake/xo_typeConfig.cmake.in b/xo-type/cmake/xo_typeConfig.cmake.in index e1618c2b..2d7841a5 100644 --- a/xo-type/cmake/xo_typeConfig.cmake.in +++ b/xo-type/cmake/xo_typeConfig.cmake.in @@ -2,6 +2,7 @@ include(CMakeFindDependencyMacro) find_dependency(xo_object2) +find_dependnecy(reflect) find_dependency(xo_alloc2) find_dependency(xo_facet) find_dependency(subsys) diff --git a/xo-type/idl/Type.json5 b/xo-type/idl/Type.json5 index 1ddac826..06fa2dce 100644 --- a/xo-type/idl/Type.json5 +++ b/xo-type/idl/Type.json5 @@ -4,7 +4,8 @@ output_hpp_dir: "include/xo/type", output_impl_subdir: "type", includes: [ - "" + "", + "", ], user_hpp_includes: [ ], @@ -26,6 +27,11 @@ name: "obj_AType", doc: [], definition: "xo::facet::obj", + }, + { + name: "TypeDescr", + doc: [], + definition: "xo::reflect::TypeDescr", } ], const_methods: [ @@ -37,13 +43,22 @@ const: true, noexcept: true, }, + { + name: "repr_td", + doc: ["reflected representation for instances of this type"], + return_type: "TypeDescr", + args: [], + const: true, + noexcept: true, + }, { name: "is_equal_to", doc: ["true iff this type is equal to y"], return_type: "bool", args: [ {type: "const obj_AType &", name: "y"}, - ] + ], + const: true, }, { name: "is_subtype_of", @@ -51,18 +66,9 @@ return_type: "bool", args: [ {type: "const obj_AType &", name: "y"}, - ] + ], + const: true, }, - - // TODO: define methods, e.g.: - // { - // name: "my_method", - // doc: ["description"], - // return_type: "bool", - // args: [], - // const: true, - // noexcept: true, - // }, ], nonconst_methods: [], router_facet_explicit_content: [ diff --git a/xo-type/include/xo/type/DArrayType.hpp b/xo-type/include/xo/type/DArrayType.hpp index 945f7f0a..a8efe329 100644 --- a/xo-type/include/xo/type/DArrayType.hpp +++ b/xo-type/include/xo/type/DArrayType.hpp @@ -20,6 +20,7 @@ namespace xo { public: using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; public: /** @defgroup xo-scm-arraytype-ctors **/ @@ -33,7 +34,8 @@ namespace xo { ///@} /** @defgroup xo-scm-arraytype-type-facet **/ ///@{ - Metatype metatype() const noexcept { return Metatype::array(); } + Metatype metatype() const noexcept { return Metatype::t_array(); } + TypeDescr repr_td() const noexcept; bool is_equal_to(const obj & y) const noexcept; bool is_subtype_of(const obj & y) const noexcept; ///@} diff --git a/xo-type/include/xo/type/DAtomicType.hpp b/xo-type/include/xo/type/DAtomicType.hpp index 074e0c64..6cd11ba5 100644 --- a/xo-type/include/xo/type/DAtomicType.hpp +++ b/xo-type/include/xo/type/DAtomicType.hpp @@ -23,16 +23,20 @@ namespace xo { public: using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; + using TypeDescr = xo::reflect::TypeDescr; public: explicit DAtomicType(Metatype m) : metatype_{m} {} /** create instance using memory from @p mm with metatype @p mtype **/ static DAtomicType * _make(obj mm, Metatype mtype); + /** create instance **/ + static obj make(obj mm, Metatype mtype); /** @defgroup xo-scm-atomictype-type-facet **/ ///@{ Metatype metatype() const noexcept { return metatype_; } + TypeDescr repr_td() const noexcept; bool is_equal_to(const obj & y) const noexcept; bool is_subtype_of(const obj & y) const noexcept; ///@} diff --git a/xo-type/include/xo/type/DFunctionType.hpp b/xo-type/include/xo/type/DFunctionType.hpp index 3ceafb71..7090a60b 100644 --- a/xo-type/include/xo/type/DFunctionType.hpp +++ b/xo-type/include/xo/type/DFunctionType.hpp @@ -22,6 +22,7 @@ namespace xo { using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; + using TypeDescr = xo::reflect::TypeDescr; public: /** @defgroup xo-scm-arraytype-ctors **/ @@ -45,7 +46,8 @@ namespace xo { ///@} /** @defgroup xo-scm-arraytype-type-facet **/ ///@{ - Metatype metatype() const noexcept { return Metatype::array(); } + Metatype metatype() const noexcept { return Metatype::t_array(); } + TypeDescr repr_td() const noexcept; bool is_equal_to(obj y) const noexcept; bool is_subtype_of(const obj & y) const noexcept; ///@} diff --git a/xo-type/include/xo/type/DListType.hpp b/xo-type/include/xo/type/DListType.hpp index 41808ce6..51db9414 100644 --- a/xo-type/include/xo/type/DListType.hpp +++ b/xo-type/include/xo/type/DListType.hpp @@ -7,6 +7,7 @@ #include "Type.hpp" #include "Metatype.hpp" +#include #include #include @@ -21,6 +22,7 @@ namespace xo { **/ class DListType { public: + using TypeDescr = xo::reflect::TypeDescr; using ACollector = xo::mm::ACollector; using AAllocator = xo::mm::AAllocator; @@ -31,12 +33,14 @@ namespace xo { explicit DListType(obj elt); /** create instance using memory from @p mm with metatype @p mtype **/ - static DListType * _make(obj mm, obj elt_type); + static DListType * _make(obj mm, + obj elt_type); ///@} /** @defgroup xo-scm-listtype-type-facet **/ ///@{ - Metatype metatype() const noexcept { return Metatype::list(); } + Metatype metatype() const noexcept { return Metatype::t_list(); } + TypeDescr repr_td() const noexcept; bool is_equal_to(const obj & y) const noexcept; bool is_subtype_of(const obj & y) const noexcept; ///@} diff --git a/xo-type/include/xo/type/Metatype.hpp b/xo-type/include/xo/type/Metatype.hpp index b8a509e6..6fc193ae 100644 --- a/xo-type/include/xo/type/Metatype.hpp +++ b/xo-type/include/xo/type/Metatype.hpp @@ -14,12 +14,21 @@ namespace xo { enum class code { /* void */ t_unit, - t_bool, - t_i64, - t_f64, t_str, + /* int16_t */ + t_i16, + /* int32_t */ + t_i32, + /* int64_t */ + t_i64, + + /* float */ + t_f32, + /* double */ + t_f64, + /* discriminated union */ t_sum, /* list */ @@ -38,16 +47,24 @@ namespace xo { public: explicit Metatype(code x) : code_{x} {} - static Metatype unit() { return Metatype(code::t_unit); } - static Metatype t_bool() { return Metatype(code::t_bool); } - static Metatype i64() { return Metatype(code::t_i64); } - static Metatype f64() { return Metatype(code::t_f64); } - static Metatype str() { return Metatype(code::t_str); } - static Metatype any() { return Metatype(code::t_any); } + static Metatype t_unit() { return Metatype(code::t_unit); } + static Metatype t_bool() { return Metatype(code::t_bool); } + static Metatype t_str() { return Metatype(code::t_str); } - static Metatype list() { return Metatype(code::t_list); } - static Metatype array() { return Metatype(code::t_array); } - static Metatype function() { return Metatype(code::t_function); } + static Metatype t_i16() { return Metatype(code::t_i16); } + static Metatype t_i32() { return Metatype(code::t_i32); } + static Metatype t_i64() { return Metatype(code::t_i64); } + + static Metatype t_f32() { return Metatype(code::t_f32); } + static Metatype t_f64() { return Metatype(code::t_f64); } + + static Metatype t_sum() { return Metatype(code::t_sum); } + static Metatype t_list() { return Metatype(code::t_list); } + static Metatype t_array() { return Metatype(code::t_array); } + static Metatype t_function() { return Metatype(code::t_function); } + static Metatype t_struct() { return Metatype(code::t_struct); } + + static Metatype t_any() { return Metatype(code::t_any); } /** description string for this type category **/ const char * _descr() const noexcept; diff --git a/xo-type/include/xo/type/array/IType_DArrayType.hpp b/xo-type/include/xo/type/array/IType_DArrayType.hpp index e323931b..afeb63f7 100644 --- a/xo-type/include/xo/type/array/IType_DArrayType.hpp +++ b/xo-type/include/xo/type/array/IType_DArrayType.hpp @@ -40,6 +40,7 @@ namespace xo { /** @defgroup scm-type-darraytype-type-traits **/ ///@{ using obj_AType = xo::scm::AType::obj_AType; + using TypeDescr = xo::scm::AType::TypeDescr; using Copaque = xo::scm::AType::Copaque; using Opaque = xo::scm::AType::Opaque; ///@} @@ -48,6 +49,8 @@ namespace xo { // const methods /** category for this type **/ static Metatype metatype(const DArrayType & self) noexcept; + /** reflected representation for instances of this type **/ + static TypeDescr repr_td(const DArrayType & self) noexcept; /** true iff this type is equal to y **/ static bool is_equal_to(const DArrayType & self, const obj_AType & y); /** true iff this is a subtype of y **/ diff --git a/xo-type/include/xo/type/atomic/IType_DAtomicType.hpp b/xo-type/include/xo/type/atomic/IType_DAtomicType.hpp index fc73539f..54210946 100644 --- a/xo-type/include/xo/type/atomic/IType_DAtomicType.hpp +++ b/xo-type/include/xo/type/atomic/IType_DAtomicType.hpp @@ -40,6 +40,7 @@ namespace xo { /** @defgroup scm-type-datomictype-type-traits **/ ///@{ using obj_AType = xo::scm::AType::obj_AType; + using TypeDescr = xo::scm::AType::TypeDescr; using Copaque = xo::scm::AType::Copaque; using Opaque = xo::scm::AType::Opaque; ///@} @@ -48,6 +49,8 @@ namespace xo { // const methods /** category for this type **/ static Metatype metatype(const DAtomicType & self) noexcept; + /** reflected representation for instances of this type **/ + static TypeDescr repr_td(const DAtomicType & self) noexcept; /** true iff this type is equal to y **/ static bool is_equal_to(const DAtomicType & self, const obj_AType & y); /** true iff this is a subtype of y **/ diff --git a/xo-type/include/xo/type/function/IType_DFunctionType.hpp b/xo-type/include/xo/type/function/IType_DFunctionType.hpp index b28050ab..3dba4572 100644 --- a/xo-type/include/xo/type/function/IType_DFunctionType.hpp +++ b/xo-type/include/xo/type/function/IType_DFunctionType.hpp @@ -40,6 +40,7 @@ namespace xo { /** @defgroup scm-type-dfunctiontype-type-traits **/ ///@{ using obj_AType = xo::scm::AType::obj_AType; + using TypeDescr = xo::scm::AType::TypeDescr; using Copaque = xo::scm::AType::Copaque; using Opaque = xo::scm::AType::Opaque; ///@} @@ -48,6 +49,8 @@ namespace xo { // const methods /** category for this type **/ static Metatype metatype(const DFunctionType & self) noexcept; + /** reflected representation for instances of this type **/ + static TypeDescr repr_td(const DFunctionType & self) noexcept; /** true iff this type is equal to y **/ static bool is_equal_to(const DFunctionType & self, const obj_AType & y); /** true iff this is a subtype of y **/ diff --git a/xo-type/include/xo/type/list/IType_DListType.hpp b/xo-type/include/xo/type/list/IType_DListType.hpp index 546b9cbe..658348fe 100644 --- a/xo-type/include/xo/type/list/IType_DListType.hpp +++ b/xo-type/include/xo/type/list/IType_DListType.hpp @@ -40,6 +40,7 @@ namespace xo { /** @defgroup scm-type-dlisttype-type-traits **/ ///@{ using obj_AType = xo::scm::AType::obj_AType; + using TypeDescr = xo::scm::AType::TypeDescr; using Copaque = xo::scm::AType::Copaque; using Opaque = xo::scm::AType::Opaque; ///@} @@ -48,6 +49,8 @@ namespace xo { // const methods /** category for this type **/ static Metatype metatype(const DListType & self) noexcept; + /** reflected representation for instances of this type **/ + static TypeDescr repr_td(const DListType & self) noexcept; /** true iff this type is equal to y **/ static bool is_equal_to(const DListType & self, const obj_AType & y); /** true iff this is a subtype of y **/ diff --git a/xo-type/include/xo/type/type/AType.hpp b/xo-type/include/xo/type/type/AType.hpp index dde14805..d0e8361f 100644 --- a/xo-type/include/xo/type/type/AType.hpp +++ b/xo-type/include/xo/type/type/AType.hpp @@ -15,6 +15,7 @@ // includes (via {facet_includes}) #include +#include #include #include #include @@ -42,6 +43,8 @@ public: using Opaque = void *; /** **/ using obj_AType = xo::facet::obj; + /** **/ + using TypeDescr = xo::reflect::TypeDescr; ///@} /** @defgroup scm-type-methods **/ @@ -53,10 +56,12 @@ public: virtual void _drop(Opaque d) const noexcept = 0; /** category for this type **/ virtual Metatype metatype(Copaque data) const noexcept = 0; + /** reflected representation for instances of this type **/ + virtual TypeDescr repr_td(Copaque data) const noexcept = 0; /** true iff this type is equal to y **/ - virtual bool is_equal_to(Copaque data, const obj_AType & y) = 0; + virtual bool is_equal_to(Copaque data, const obj_AType & y) const = 0; /** true iff this is a subtype of y **/ - virtual bool is_subtype_of(Copaque data, const obj_AType & y) = 0; + virtual bool is_subtype_of(Copaque data, const obj_AType & y) const = 0; // nonconst methods ///@} diff --git a/xo-type/include/xo/type/type/IType_Any.hpp b/xo-type/include/xo/type/type/IType_Any.hpp index b8bdb58c..624db20a 100644 --- a/xo-type/include/xo/type/type/IType_Any.hpp +++ b/xo-type/include/xo/type/type/IType_Any.hpp @@ -45,6 +45,7 @@ namespace scm { /** integer identifying a type **/ using typeseq = xo::facet::typeseq; using obj_AType = AType::obj_AType; + using TypeDescr = AType::TypeDescr; ///@} /** @defgroup scm-type-any-methods **/ @@ -60,8 +61,9 @@ namespace scm { // const methods [[noreturn]] Metatype metatype(Copaque) const noexcept override { _fatal(); } - [[noreturn]] bool is_equal_to(Copaque, const obj_AType &) override { _fatal(); } - [[noreturn]] bool is_subtype_of(Copaque, const obj_AType &) override { _fatal(); } + [[noreturn]] TypeDescr repr_td(Copaque) const noexcept override { _fatal(); } + [[noreturn]] bool is_equal_to(Copaque, const obj_AType &) const override { _fatal(); } + [[noreturn]] bool is_subtype_of(Copaque, const obj_AType &) const override { _fatal(); } // nonconst methods diff --git a/xo-type/include/xo/type/type/IType_Xfer.hpp b/xo-type/include/xo/type/type/IType_Xfer.hpp index 98b138c7..dbc82bc1 100644 --- a/xo-type/include/xo/type/type/IType_Xfer.hpp +++ b/xo-type/include/xo/type/type/IType_Xfer.hpp @@ -14,6 +14,7 @@ #pragma once #include +#include namespace xo { namespace scm { @@ -29,6 +30,7 @@ namespace scm { /** integer identifying a type **/ using typeseq = AType::typeseq; using obj_AType = AType::obj_AType; + using TypeDescr = AType::TypeDescr; ///@} /** @defgroup scm-type-xfer-methods **/ @@ -47,10 +49,13 @@ namespace scm { Metatype metatype(Copaque data) const noexcept override { return I::metatype(_dcast(data)); } - bool is_equal_to(Copaque data, const obj_AType & y) override { + TypeDescr repr_td(Copaque data) const noexcept override { + return I::repr_td(_dcast(data)); + } + bool is_equal_to(Copaque data, const obj_AType & y) const override { return I::is_equal_to(_dcast(data), y); } - bool is_subtype_of(Copaque data, const obj_AType & y) override { + bool is_subtype_of(Copaque data, const obj_AType & y) const override { return I::is_subtype_of(_dcast(data), y); } diff --git a/xo-type/include/xo/type/type/RType.hpp b/xo-type/include/xo/type/type/RType.hpp index 853745ed..648749bf 100644 --- a/xo-type/include/xo/type/type/RType.hpp +++ b/xo-type/include/xo/type/type/RType.hpp @@ -32,6 +32,7 @@ public: using DataPtr = Object::DataPtr; using typeseq = xo::reflect::typeseq; using obj_AType = AType::obj_AType; + using TypeDescr = AType::TypeDescr; ///@} /** @defgroup scm-type-router-ctors **/ @@ -56,10 +57,13 @@ public: Metatype metatype() const noexcept { return O::iface()->metatype(O::data()); } - bool is_equal_to(const obj_AType & y) { + TypeDescr repr_td() const noexcept { + return O::iface()->repr_td(O::data()); + } + bool is_equal_to(const obj_AType & y) const { return O::iface()->is_equal_to(O::data(), y); } - bool is_subtype_of(const obj_AType & y) { + bool is_subtype_of(const obj_AType & y) const { return O::iface()->is_subtype_of(O::data(), y); } diff --git a/xo-type/src/type/CMakeLists.txt b/xo-type/src/type/CMakeLists.txt index 3bc7b2eb..6d6cdcc1 100644 --- a/xo-type/src/type/CMakeLists.txt +++ b/xo-type/src/type/CMakeLists.txt @@ -31,6 +31,7 @@ xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 $ # xo-type/cmake/xo_typeConfig.cmake.in xo_dependency(${SELF_LIB} xo_object2) +xo_dependency(${SELF_LIB} reflect) xo_dependency(${SELF_LIB} xo_alloc2) xo_dependency(${SELF_LIB} xo_facet) xo_dependency(${SELF_LIB} subsys) diff --git a/xo-type/src/type/DArrayType.cpp b/xo-type/src/type/DArrayType.cpp index de5320e2..652186ab 100644 --- a/xo-type/src/type/DArrayType.cpp +++ b/xo-type/src/type/DArrayType.cpp @@ -5,18 +5,24 @@ #include "Type.hpp" #include "ArrayType.hpp" +#include "TypeDescr.hpp" +#include #include #include #include namespace xo { + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; using xo::mm::AGCObject; using xo::mm::AAllocator; using xo::facet::FacetRegistry; namespace scm { - DArrayType::DArrayType(obj elt) : elt_type_{elt} {} + DArrayType::DArrayType(obj elt) + : elt_type_{elt} + {} DArrayType * DArrayType::_make(obj mm, @@ -29,12 +35,18 @@ namespace xo { // ----- type facet ----- + TypeDescr + DArrayType::repr_td() const noexcept + { + return Reflect::require(); + } + bool DArrayType::is_equal_to(const obj & y_arg) const noexcept { Metatype y_mtype = y_arg.metatype(); - if (y_mtype != Metatype::array()) + if (y_mtype != Metatype::t_array()) return false; auto y = obj::from(y_arg); @@ -49,10 +61,10 @@ namespace xo { { Metatype y_mtype = y_arg.metatype(); - if (y_mtype == Metatype::any()) + if (y_mtype == Metatype::t_any()) return true; - if (y_mtype != Metatype::array()) + if (y_mtype != Metatype::t_array()) return false; auto y = obj::from(y_arg); @@ -81,7 +93,7 @@ namespace xo { { { auto e = FacetRegistry::instance().variant(elt_type_); - gc.forward_inplace(e.iface(), (void **)&(e.data_)); + gc.forward_inplace(e.iface(), (void **)&(elt_type_.data_)); } return this->shallow_size(); diff --git a/xo-type/src/type/DAtomicType.cpp b/xo-type/src/type/DAtomicType.cpp index 18c64c81..bc2fe558 100644 --- a/xo-type/src/type/DAtomicType.cpp +++ b/xo-type/src/type/DAtomicType.cpp @@ -4,8 +4,12 @@ **/ #include "AtomicType.hpp" +#include namespace xo { + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; + namespace scm { DAtomicType * @@ -16,8 +20,20 @@ namespace xo { return new (mem) DAtomicType(mtype); } + obj + DAtomicType::make(obj mm, Metatype mtype) + { + return obj(_make(mm, mtype)); + } + // ----- Type facet ----- + TypeDescr + DAtomicType::repr_td() const noexcept + { + return Reflect::require(); + } + bool DAtomicType::is_equal_to(const obj & y) const noexcept { diff --git a/xo-type/src/type/DFunctionType.cpp b/xo-type/src/type/DFunctionType.cpp index 5fdbbdf3..88de628b 100644 --- a/xo-type/src/type/DFunctionType.cpp +++ b/xo-type/src/type/DFunctionType.cpp @@ -4,21 +4,30 @@ **/ #include "FunctionType.hpp" +#include #include namespace xo { + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; using xo::facet::FacetRegistry; namespace scm { // ----- type facet ----- + TypeDescr + DFunctionType::repr_td() const noexcept + { + return Reflect::require(); + } + bool DFunctionType::is_equal_to(obj y_arg) const noexcept { Metatype y_mtype = y_arg.metatype(); - if (y_mtype != Metatype::function()) + if (y_mtype != Metatype::t_function()) return false; auto y = obj::from(y_arg); @@ -48,10 +57,10 @@ namespace xo { { Metatype y_mtype = y_arg.metatype(); - if (y_mtype == Metatype::any()) + if (y_mtype == Metatype::t_any()) return true; - if (y_mtype != Metatype::function()) + if (y_mtype != Metatype::t_function()) return false; auto y = obj::from(y_arg); @@ -95,7 +104,7 @@ namespace xo { { { auto e = FacetRegistry::instance().variant(return_type_); - gc.forward_inplace(e.iface(), (void **)&(e.data_)); + gc.forward_inplace(e.iface(), (void **)&(return_type_.data_)); } gc.forward_inplace(&arg_types_); diff --git a/xo-type/src/type/DListType.cpp b/xo-type/src/type/DListType.cpp index 4be59a36..35b29235 100644 --- a/xo-type/src/type/DListType.cpp +++ b/xo-type/src/type/DListType.cpp @@ -5,11 +5,15 @@ #include "Type.hpp" #include "ListType.hpp" +#include "TypeDescr.hpp" +#include #include #include #include namespace xo { + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; using xo::mm::AGCObject; using xo::mm::AAllocator; using xo::facet::FacetRegistry; @@ -29,12 +33,18 @@ namespace xo { // ----- type facet ----- + TypeDescr + DListType::repr_td() const noexcept + { + return Reflect::require(); + } + bool DListType::is_equal_to(const obj & y_arg) const noexcept { Metatype y_mtype = y_arg.metatype(); - if (y_mtype != Metatype::list()) + if (y_mtype != Metatype::t_list()) return false; auto y = obj::from(y_arg); @@ -49,10 +59,10 @@ namespace xo { { Metatype y_mtype = y_arg.metatype(); - if (y_mtype == Metatype::any()) + if (y_mtype == Metatype::t_any()) return true; - if (y_mtype != Metatype::list()) + if (y_mtype != Metatype::t_list()) return false; auto y = obj::from(y_arg); @@ -81,7 +91,7 @@ namespace xo { { { auto e = FacetRegistry::instance().variant(elt_type_); - gc.forward_inplace(e.iface(), (void **)&(e.data_)); + gc.forward_inplace(e.iface(), (void **)&(elt_type_.data_)); } return this->shallow_size(); diff --git a/xo-type/src/type/IType_DArrayType.cpp b/xo-type/src/type/IType_DArrayType.cpp index 2ed60101..363e79c1 100644 --- a/xo-type/src/type/IType_DArrayType.cpp +++ b/xo-type/src/type/IType_DArrayType.cpp @@ -21,6 +21,12 @@ namespace xo { return self.metatype(); } + auto + IType_DArrayType::repr_td(const DArrayType & self) noexcept -> TypeDescr + { + return self.repr_td(); + } + auto IType_DArrayType::is_equal_to(const DArrayType & self, const obj_AType & y) -> bool { diff --git a/xo-type/src/type/IType_DAtomicType.cpp b/xo-type/src/type/IType_DAtomicType.cpp index 65fcb023..fd137cbb 100644 --- a/xo-type/src/type/IType_DAtomicType.cpp +++ b/xo-type/src/type/IType_DAtomicType.cpp @@ -21,6 +21,12 @@ namespace xo { return self.metatype(); } + auto + IType_DAtomicType::repr_td(const DAtomicType & self) noexcept -> TypeDescr + { + return self.repr_td(); + } + auto IType_DAtomicType::is_equal_to(const DAtomicType & self, const obj_AType & y) -> bool { diff --git a/xo-type/src/type/IType_DFunctionType.cpp b/xo-type/src/type/IType_DFunctionType.cpp index 230cf67d..6e77a152 100644 --- a/xo-type/src/type/IType_DFunctionType.cpp +++ b/xo-type/src/type/IType_DFunctionType.cpp @@ -21,6 +21,12 @@ namespace xo { return self.metatype(); } + auto + IType_DFunctionType::repr_td(const DFunctionType & self) noexcept -> TypeDescr + { + return self.repr_td(); + } + auto IType_DFunctionType::is_equal_to(const DFunctionType & self, const obj_AType & y) -> bool { diff --git a/xo-type/src/type/IType_DListType.cpp b/xo-type/src/type/IType_DListType.cpp index a29e3d74..9632f403 100644 --- a/xo-type/src/type/IType_DListType.cpp +++ b/xo-type/src/type/IType_DListType.cpp @@ -21,6 +21,12 @@ namespace xo { return self.metatype(); } + auto + IType_DListType::repr_td(const DListType & self) noexcept -> TypeDescr + { + return self.repr_td(); + } + auto IType_DListType::is_equal_to(const DListType & self, const obj_AType & y) -> bool { diff --git a/xo-type/src/type/Metatype.cpp b/xo-type/src/type/Metatype.cpp index aa97fdcc..ca61d9c9 100644 --- a/xo-type/src/type/Metatype.cpp +++ b/xo-type/src/type/Metatype.cpp @@ -12,17 +12,24 @@ namespace xo { Metatype::_descr() const noexcept { switch (code_) { - case code::t_any: return "any"; + case code::t_unit: return "unit"; case code::t_bool: return "bool"; - case code::t_i64: return "i64"; - case code::t_f64: return "f64"; case code::t_str: return "str"; + + case code::t_i16: return "i16"; + case code::t_i32: return "i32"; + case code::t_i64: return "i64"; + + case code::t_f32: return "f32"; + case code::t_f64: return "f64"; + case code::t_sum: return "sum"; case code::t_list: return "list"; case code::t_array: return "array"; case code::t_function: return "function"; case code::t_struct: return "struct"; - case code::t_unit: return "unit"; + + case code::t_any: return "any"; } } @@ -30,16 +37,26 @@ namespace xo { Metatype::is_atomic() const noexcept { switch (code_) { - case code::t_any: - return true; + case code::t_unit: + return false; + case code::t_bool: return true; - case code::t_i64: - return true; - case code::t_f64: - return true; case code::t_str: return true; + + case code::t_i16: + return true; + case code::t_i32: + return true; + case code::t_i64: + return true; + + case code::t_f32: + return true; + case code::t_f64: + return true; + case code::t_sum: return false; case code::t_list: @@ -50,8 +67,9 @@ namespace xo { return false; case code::t_struct: return false; - case code::t_unit: - return false; + + case code::t_any: + return true; } } diff --git a/xo-type/utest/DArrayType.test.cpp b/xo-type/utest/DArrayType.test.cpp index fc4ed8cb..5947eb3a 100644 --- a/xo-type/utest/DArrayType.test.cpp +++ b/xo-type/utest/DArrayType.test.cpp @@ -31,7 +31,7 @@ namespace xo { DArena arena = DArena::map(cfg); auto alloc = obj(&arena); - auto i64_type = TypeOps::atomic_type(alloc, Metatype::i64()); + auto i64_type = TypeOps::atomic_type(alloc, Metatype::t_i64()); auto array_i64_type = TypeOps::array_type(alloc, i64_type); REQUIRE(array_i64_type); @@ -43,7 +43,7 @@ namespace xo { REQUIRE(array_bool_type); REQUIRE(array_bool_type.is_equal_to(array_bool_type)); - auto any_type = TypeOps::atomic_type(alloc, Metatype::any()); + auto any_type = TypeOps::atomic_type(alloc, Metatype::t_any()); auto array_any_type = TypeOps::array_type(alloc, any_type); REQUIRE(array_any_type); diff --git a/xo-type/utest/DAtomicType.test.cpp b/xo-type/utest/DAtomicType.test.cpp index 9bab45d0..54557010 100644 --- a/xo-type/utest/DAtomicType.test.cpp +++ b/xo-type/utest/DAtomicType.test.cpp @@ -28,14 +28,14 @@ namespace xo { DArena arena = DArena::map(cfg); auto alloc = obj(&arena); - auto unit_type = obj(DAtomicType::_make(alloc, Metatype::unit())); - auto i64_type = obj(DAtomicType::_make(alloc, Metatype::i64())); - auto f64_type = obj(DAtomicType::_make(alloc, Metatype::f64())); - auto str_type = obj(DAtomicType::_make(alloc, Metatype::str())); - auto any_type = obj(DAtomicType::_make(alloc, Metatype::any())); + auto unit_type = obj(DAtomicType::_make(alloc, Metatype::t_unit())); + auto i64_type = obj(DAtomicType::_make(alloc, Metatype::t_i64())); + auto f64_type = obj(DAtomicType::_make(alloc, Metatype::t_f64())); + auto str_type = obj(DAtomicType::_make(alloc, Metatype::t_str())); + auto any_type = obj(DAtomicType::_make(alloc, Metatype::t_any())); { REQUIRE(unit_type); - REQUIRE(unit_type.metatype().code() == Metatype::unit().code()); + REQUIRE(unit_type.metatype().code() == Metatype::t_unit().code()); REQUIRE(unit_type.is_equal_to(unit_type)); REQUIRE(unit_type.is_subtype_of(unit_type)); @@ -43,7 +43,7 @@ namespace xo { { REQUIRE(i64_type); - REQUIRE(i64_type.metatype().code() == Metatype::i64().code()); + REQUIRE(i64_type.metatype().code() == Metatype::t_i64().code()); REQUIRE(i64_type.is_equal_to(i64_type)); REQUIRE(i64_type.is_subtype_of(i64_type)); @@ -54,7 +54,7 @@ namespace xo { { REQUIRE(f64_type); - REQUIRE(f64_type.metatype().code() == Metatype::f64().code()); + REQUIRE(f64_type.metatype().code() == Metatype::t_f64().code()); REQUIRE(f64_type.is_equal_to(f64_type)); REQUIRE(f64_type.is_subtype_of(f64_type)); @@ -67,7 +67,7 @@ namespace xo { { REQUIRE(str_type); - REQUIRE(str_type.metatype().code() == Metatype::str().code()); + REQUIRE(str_type.metatype().code() == Metatype::t_str().code()); REQUIRE(str_type.is_equal_to(str_type)); REQUIRE(str_type.is_subtype_of(str_type)); @@ -83,7 +83,7 @@ namespace xo { { REQUIRE(any_type); - REQUIRE(any_type.metatype().code() == Metatype::any().code()); + REQUIRE(any_type.metatype().code() == Metatype::t_any().code()); REQUIRE(any_type.is_equal_to(any_type)); REQUIRE(any_type.is_subtype_of(any_type)); diff --git a/xo-type/utest/DListType.test.cpp b/xo-type/utest/DListType.test.cpp index fed5d916..1eace386 100644 --- a/xo-type/utest/DListType.test.cpp +++ b/xo-type/utest/DListType.test.cpp @@ -32,7 +32,7 @@ namespace xo { DArena arena = DArena::map(cfg); auto alloc = obj(&arena); - auto i64_type = TypeOps::atomic_type(alloc, Metatype::i64()); + auto i64_type = TypeOps::atomic_type(alloc, Metatype::t_i64()); auto list_i64_type = TypeOps::list_type(alloc, i64_type); REQUIRE(list_i64_type); @@ -44,7 +44,7 @@ namespace xo { REQUIRE(list_bool_type); REQUIRE(list_bool_type.is_equal_to(list_bool_type)); - auto any_type = TypeOps::atomic_type(alloc, Metatype::any()); + auto any_type = TypeOps::atomic_type(alloc, Metatype::t_any()); auto list_any_type = TypeOps::list_type(alloc, any_type); REQUIRE(list_any_type);