xo-reader2 stack: expand symbol table to store typedefs

+ typedef utest
+ misc qol policy choices
This commit is contained in:
Roland Conybeare 2026-03-11 07:49:14 -05:00
commit fc25a17262
109 changed files with 2139 additions and 345 deletions

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,18 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "typename",
includes: [
// "<xo/alloc2/GCObject.hpp>",
// "<xo/alloc2/Allocator.hpp>"
],
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" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/expression2",
output_hpp_dir: "include/xo/expression2",
output_impl_subdir: "typename",
includes: [ "<xo/printable2/Printable.hpp>",
"<xo/printable2/detail/IPrintable_Xfer.hpp>" ],
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" ],
}

View file

@ -7,6 +7,7 @@
#include "Binding.hpp"
#include "DVariable.hpp"
#include "DTypename.hpp"
#include <xo/object2/DArray.hpp>
#include <xo/alloc2/dp.hpp>
#include <xo/arena/DArenaHashMap.hpp>
@ -38,16 +39,18 @@ namespace xo {
/** @defgroup scm-globalsymtab-ctors constructors **/
///@{
DGlobalSymtab(dp<repr_type> map, DArray * vars);
DGlobalSymtab(dp<repr_type> var_map, DArray * vars,
dp<repr_type> 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<DGlobalSymtab> make(obj<AAllocator> mm,
obj<AAllocator> 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<AAllocator> 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<AAllocator> 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<repr_type> map_;
dp<repr_type> 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<repr_type> 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*/

View file

@ -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<AExpression> body_expr() const noexcept { return body_expr_; }
// get_free_variables()

View file

@ -8,9 +8,7 @@
#include "Binding.hpp"
#include "DVariable.hpp"
#include "DUniqueString.hpp"
//#include "exprtype.hpp"
//#include <xo/reflect/TaggedPtr.hpp>
//#include <xo/gc/GCObject.hpp>
#include <xo/object2/DArray.hpp>
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<AAllocator> 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<int32_t>(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<AAllocator> mm,
const DUniqueString * name,
obj<AType> 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<AGCObject>
**/
DArray * vars_ = nullptr;
/** types owned by (defined in) this symbol table
* types_[i] is convertible to obj<AType>
**/
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*/

View file

@ -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<AExpression,DSequenceExpr> make_empty(obj<AAllocator> mm);

View file

@ -0,0 +1,77 @@
/** @file DTypename.hpp
*
* @author Roland Conybeare, Mar 2026
**/
#pragma once
#include "DUniqueString.hpp"
#include <xo/type/Type.hpp>
#include <xo/printable2/Printable.hpp>
#include <xo/indentlog/print/pretty.hpp>
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<AType> type);
/** create instance
* @p mm memory allocator
* @p name type name
* @p type type definition
**/
static DTypename * _make(obj<AAllocator> mm,
const DUniqueString * name,
obj<AType> type);
/** create fop for new instance **/
static obj<AGCObject,DTypename> make(obj<AAllocator> mm,
const DUniqueString * name,
obj<AType> type);
const DUniqueString * name() const noexcept { return name_; }
obj<AType> 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<AAllocator> mm) const noexcept;
size_t forward_children(obj<ACollector> 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<AType> type_;
};
} /*namespace scm*/
} /*namespace xo*/
/* end DTypename.hpp */

View file

@ -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
**/

View file

@ -5,7 +5,9 @@
#pragma once
#include <xo/type/Type.hpp>
#include <xo/reflect/TypeDescr.hpp>
#include <xo/alloc2/Collector.hpp>
#include <xo/flatstring/flatstring.hpp>
#include <xo/indentlog/print/pretty.hpp>
@ -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<AType> 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<AType> 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<AType> 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<ACollector> 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<AType> type_;
/** Description for concrete type, once resolved.
* May be null when this TypeRef created,
* but expected to be immutable once established.

View file

@ -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 */

View file

@ -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<xo::mm::AGCObject,
xo::scm::DTypename>
{
using ImplType = xo::mm::IGCObject_Xfer
<xo::scm::DTypename,
xo::scm::IGCObject_DTypename>;
};
}
}
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<AAllocator> mm) noexcept;
// non-const methods
/** during GC: forward immdiate children **/
static size_type forward_children(DTypename & self, obj<ACollector> gc) noexcept;
///@}
};
} /*namespace scm*/
} /*namespace xo*/
/* end */

View file

@ -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 <xo/printable2/Printable.hpp>
#include <xo/printable2/detail/IPrintable_Xfer.hpp>
#include "DTypename.hpp"
namespace xo { namespace scm { class IPrintable_DTypename; } }
namespace xo {
namespace facet {
template <>
struct FacetImplementation<xo::print::APrintable,
xo::scm::DTypename>
{
using ImplType = xo::print::IPrintable_Xfer
<xo::scm::DTypename,
xo::scm::IPrintable_DTypename>;
};
}
}
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 */

View file

@ -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)

View file

@ -129,6 +129,13 @@ namespace xo {
std::size_t
DApplyExpr::forward_children(obj<ACollector> gc) noexcept
{
typeref_.forward_children(gc);
{
obj<AGCObject> fn_gco = fn_.to_facet<AGCObject>();
gc.forward_inplace(fn_gco.iface(), (void **)&fn_.data_);
}
for (size_type i = 0; i < n_args_; ++i) {
obj<AExpression> & arg = args_[i];

View file

@ -91,7 +91,10 @@ namespace xo {
std::size_t
DConstant::forward_children(obj<ACollector> 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();
}

View file

@ -4,6 +4,8 @@
**/
#include "DGlobalSymtab.hpp"
#include "Typename.hpp"
#include "Binding.hpp"
#include "DUniqueString.hpp"
#include <xo/expression2/Expression.hpp>
#include <xo/expression2/Variable.hpp>
@ -18,25 +20,40 @@ namespace xo {
namespace scm {
DGlobalSymtab::DGlobalSymtab(dp<repr_type> map,
DArray * vars)
: map_{std::move(map)}, vars_{vars}
DGlobalSymtab::DGlobalSymtab(dp<repr_type> var_map,
DArray * vars,
dp<repr_type> type_map,
DArray * types)
: var_map_{std::move(var_map)}, vars_{vars},
type_map_{std::move(type_map)}, types_{types}
{
}
dp<DGlobalSymtab>
DGlobalSymtab::make(obj<AAllocator> mm,
obj<AAllocator> aux_mm,
const ArenaHashMapConfig & cfg)
const ArenaHashMapConfig & var_cfg,
const ArenaHashMapConfig & type_cfg)
{
auto map = dp<repr_type>::make(aux_mm, cfg);
assert(map);
/* note: using aux_mm for DArenaHashMap superstructure.
* {variable, type} storage allocated from mm.
*/
auto var_map = dp<repr_type>::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<DGlobalSymtab>::make(mm, std::move(map), vars);
auto type_map = dp<repr_type>::make(aux_mm, type_cfg);
assert(type_map);
DArray * types = DArray::empty(mm, type_map->capacity());
auto symtab = dp<DGlobalSymtab>::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<AGCObject,DVariable>::from((*vars_)[existing.j_slot()]);
auto var = var_gco.to_facet<AExpression>();
assert(var.data());
//auto var = var_gco.to_facet<AExpression>();
//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<AGCObject,DVariable>(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<AGCObject,DVariable>(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<AGCObject,DTypename>::from((*types_)[i_slot]);
return tname_gco.data();
}
void
DGlobalSymtab::upsert_typename(obj<AAllocator> 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<AGCObject,DTypename>(tname));
} else {
Binding::slot_type i_slot = ix->second;
log && log("STUB: need write barrier");
(*types_)[i_slot] = obj<AGCObject,DTypename>(tname);
}
}
#ifdef NOT_USING // don't know if we need this path
DVariable *
DGlobalSymtab::establish_variable(obj<AAllocator> 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<DGlobalSymtab*>(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*/

View file

@ -102,17 +102,19 @@ namespace xo {
std::size_t
DIfElseExpr::forward_children(obj<ACollector> gc) noexcept
{
typeref_.forward_children(gc);
// GC needs to locate AGCObject iface for each member.
{
auto gco = FacetRegistry::instance().variant<AGCObject,AExpression>(test_);
auto gco = test_.to_facet<AGCObject>();
gc.forward_inplace(gco.iface(), (void **)&(test_.data_));
}
{
auto gco = FacetRegistry::instance().variant<AGCObject,AExpression>(when_true_);
auto gco = when_true_.to_facet<AGCObject>();
gc.forward_inplace(gco.iface(), (void **)&(when_true_.data_));
}
{
auto gco = FacetRegistry::instance().variant<AGCObject,AExpression>(when_false_);
auto gco = when_false_.to_facet<AGCObject>();
gc.forward_inplace(gco.iface(), (void **)&(when_false_.data_));
}

View file

@ -95,7 +95,7 @@ namespace xo {
std::vector<TypeDescr> 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<ACollector> gc) noexcept {
typeref_.forward_children(gc);
{
//gc.forward_inplace(&name_); // doesn't compile for const ptr
auto iface = xo::facet::impl_for<AGCObject,DUniqueString>();
gc.forward_inplace(&iface, (void **)(&name_));
}
@ -160,8 +163,9 @@ namespace xo {
// type_name_str_
{
auto iface = xo::facet::impl_for<AGCObject,DLocalSymtab>();
gc.forward_inplace(&iface, (void **)(&local_symtab_));
gc.forward_inplace(&local_symtab_);
//auto iface = xo::facet::impl_for<AGCObject,DLocalSymtab>();
//gc.forward_inplace(&iface, (void **)(&local_symtab_));
}
{

View file

@ -5,38 +5,52 @@
#include "LocalSymtab.hpp"
#include "Variable.hpp"
#include "Typename.hpp"
#include "DUniqueString.hpp"
#include <xo/object2/Array.hpp>
#include <xo/printable2/Printable.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <xo/indentlog/scope.hpp>
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<AAllocator> mm,
DLocalSymtab * p,
size_type n)
size_type nv,
size_type nt)
{
void * mem = mm.alloc(typeseq::id<DLocalSymtab>(),
sizeof(DLocalSymtab) + (n * sizeof(Slot)));
void * mem = mm.alloc_for<DLocalSymtab>();
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<int32_t>(vars_->size()));
auto var = obj<AGCObject,DVariable>::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<AGCObject,DVariable>(var));
return binding;
}
}
void
DLocalSymtab::append_type(obj<AAllocator> mm,
const DUniqueString * name,
obj<AType> type)
{
assert(name);
if (types_->size() >= types_->capacity() || !name) {
assert(false);
} else {
obj<AGCObject> 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<AGCObject,DVariable>::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<AAllocator> 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<ACollector> gc) noexcept
{
{
auto iface
= xo::facet::impl_for<AGCObject,DLocalSymtab>();
gc.forward_inplace(&iface, (void **)(&parent_));
}
auto iface
= xo::facet::impl_for<AGCObject,DVariable>();
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("<LocalSymtab"))
return false;
if (!pps->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 <n; ++i) {
char buf[32];
snprintf(buf, sizeof(buf), "[%u]", i);
assert(slots_[i].var_);
obj<APrintable,DVariable> arg_pr(const_cast<DVariable*>(slots_[i].var_));
obj<APrintable> arg_pr = (*vars_)[i].to_facet<APrintable>();
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<APrintable> type_pr = (*types_)[i].to_facet<APrintable>();
if (!pps->print_upto(xrefrtag(buf, type_pr)))
return false;
}
pps->write(">");
return true;
} else {
/* with line breaks */
pps->write("<LocalSymtab");
pps->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<APrintable,DVariable> arg_pr(const_cast<DVariable *>(slots_[i].var_));
obj<APrintable> arg_pr = (*vars_)[i].to_facet<APrintable>();
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<APrintable> type_pr = (*types_)[i].to_facet<APrintable>();
pps->newline_pretty_tag(ppii.ci1(), buf, type_pr);
}
pps->write(">");
return false;
}
}

View file

@ -22,6 +22,12 @@ namespace xo {
namespace scm {
DSequenceExpr::DSequenceExpr() = default;
DSequenceExpr::DSequenceExpr(DArray * xv)
: expr_v_{xv}
{}
obj<AExpression,DSequenceExpr>
DSequenceExpr::make_empty(obj<AAllocator> mm)
{
@ -127,13 +133,13 @@ namespace xo {
std::size_t
DSequenceExpr::forward_children(obj<ACollector> gc) noexcept
{
// WARNING.
// if this proves problematic,
// may resort to obj<AGCObject,DArray> for expr_v_ member
typeref_.forward_children(gc);
auto iface = facet::impl_for<AGCObject,DArray>();
gc.forward_inplace(&iface, (void**)&expr_v_);
{
//auto iface = facet::impl_for<AGCObject,DArray>();
//gc.forward_inplace(&iface, (void**)&expr_v_);
gc.forward_inplace(&expr_v_);
}
return this->shallow_size();
}

View file

@ -0,0 +1,89 @@
/** @file DTypename.cpp
*
* @author Roland Conybeare, Jan 2026
**/
#include "Typename.hpp"
#include <xo/stringtable2/UniqueString.hpp>
#include <xo/alloc2/GCObject.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <xo/indentlog/print/quoted.hpp>
#include <cstddef>
namespace xo {
using xo::mm::ACollector;
using xo::mm::AGCObject;
using xo::print::APrintable;
namespace scm {
DTypename *
DTypename::_make(obj<AAllocator> mm,
const DUniqueString * name,
obj<AType> type)
{
void * mem = mm.alloc_for<DTypename>();
return new (mem) DTypename(name, type);
}
obj<AGCObject,DTypename>
DTypename::make(obj<AAllocator> mm,
const DUniqueString * name,
obj<AType> type)
{
return obj<AGCObject,DTypename>(_make(mm, name, type));
}
DTypename::DTypename(const DUniqueString * name,
obj<AType> type)
: name_{name}, type_{type}
{}
size_t
DTypename::shallow_size() const noexcept
{
return sizeof(DTypename);
}
DTypename *
DTypename::shallow_copy(obj<AAllocator> mm) const noexcept
{
return mm.std_copy_for(this);
}
size_t
DTypename::forward_children(obj<ACollector> gc) noexcept
{
gc.forward_inplace(const_cast<DUniqueString**>(&name_));
{
auto e = type_.to_facet<AGCObject>();
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<APrintable>();
return ppii.pps()->pretty_struct
(ppii,
"DTypename"
, refrtag("name", quot(name))
, refrtag("type", type_pr)
);
}
} /*namespace scm*/
} /*namespace xo*/
/* end DTypename.cpp */

View file

@ -57,12 +57,9 @@ namespace xo {
}
size_t
DVariable::forward_children(obj<ACollector>) noexcept
DVariable::forward_children(obj<ACollector> 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();
}

View file

@ -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<AAllocator> mm) noexcept -> Opaque
{
return self.shallow_copy(mm);
}
auto
IGCObject_DTypename::forward_children(DTypename & self, obj<ACollector> gc) noexcept -> size_type
{
return self.forward_children(gc);
}
} /*namespace scm*/
} /*namespace xo*/
/* end IGCObject_DTypename.cpp */

View file

@ -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 */

View file

@ -4,16 +4,34 @@
**/
#include "TypeRef.hpp"
#include <xo/alloc2/GCObject.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <xo/indentlog/print/cond.hpp>
#include <xo/indentlog/print/pretty.hpp>
#include <xo/indentlog/print/quoted.hpp>
namespace xo {
using xo::mm::AGCObject;
using xo::facet::FacetRegistry;
namespace scm {
TypeRef::TypeRef(const type_var & id, obj<AType> type)
: id_{id}, type_{type}
{}
TypeRef::TypeRef(const type_var & id, TypeDescr td)
: id_{id}, td_{td}
{}
TypeRef
TypeRef::resolved(obj<AType> 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<AType> 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<ACollector> gc) noexcept
{
{
auto e = FacetRegistry::instance().variant<AGCObject,AType>(type_);
gc.forward_inplace(e.iface(), (void **)&(type_.data_));
}
}
bool
TypeRef::pretty(const ppindentinfo & ppii) const
{

View file

@ -5,11 +5,13 @@
#include "expression2_register_facets.hpp"
#include <xo/expression2/detail/IExpression_DVariable.hpp>
#include <xo/expression2/detail/IGCObject_DVariable.hpp>
#include <xo/expression2/detail/IPrintable_DVariable.hpp>
//#include <xo/expression2/detail/IExpression_DVariable.hpp>
//#include <xo/expression2/detail/IGCObject_DVariable.hpp>
//#include <xo/expression2/detail/IPrintable_DVariable.hpp>
#include <xo/expression2/DefineExpr.hpp>
#include <xo/expression2/Variable.hpp>
#include <xo/expression2/Typename.hpp>
#include <xo/expression2/VarRef.hpp>
#include <xo/expression2/Constant.hpp>
#include <xo/expression2/ApplyExpr.hpp>
@ -83,6 +85,11 @@ namespace xo {
FacetRegistry::register_impl<AGCObject, DSequenceExpr>();
FacetRegistry::register_impl<APrintable, DSequenceExpr>();
// Typename
FacetRegistry::register_impl<AGCObject, DTypename>();
FacetRegistry::register_impl<APrintable, DTypename>();
// SymbolTable
// +- LocalSymtab
// \- GlobalSymtab
@ -103,6 +110,7 @@ namespace xo {
log && log(xtag("DUniqueString.tseq", typeseq::id<DUniqueString>()));
log && log(xtag("DDefineExpr.tseq", typeseq::id<DDefineExpr>()));
log && log(xtag("DVariable.tseq", typeseq::id<DVariable>()));
log && log(xtag("DTypename.tseq", typeseq::id<DTypename>()));
log && log(xtag("DVarRef.tseq", typeseq::id<DVarRef>()));
log && log(xtag("DConstant.tseq", typeseq::id<DConstant>()));
log && log(xtag("DApplyExpr.tseq", typeseq::id<DApplyExpr>()));

View file

@ -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<AGCObject, DConstant>());
ok &= gc.install_type(impl_for<AGCObject, DVariable>());
//ok &= gc.install_type(impl_for<AGCObject, DDefineExpr>()); // when avail
ok &= gc.install_type(impl_for<AGCObject, DTypename>());
ok &= gc.install_type(impl_for<AGCObject, DDefineExpr>());
//ok &= gc.install_type(impl_for<AGCObject, DApplyExpr>()); // when avail
//ok &= gc.install_type(impl_for<AGCObject, DLambdaExpr>()); // when avail
ok &= gc.install_type(impl_for<AGCObject, DLambdaExpr>());
ok &= gc.install_type(impl_for<AGCObject, DIfElseExpr>());
ok &= gc.install_type(impl_for<AGCObject, DSequenceExpr>());
//ok &= gc.install_type(impl_for<AGCObject, DLocalSymtab>()); // when avail
ok &= gc.install_type(impl_for<AGCObject, DLocalSymtab>());
ok &= gc.install_type(impl_for<AGCObject, DGlobalSymtab>());
return ok;
}