xo-interpreter2 stack: refactor + bugfix operator expr
This commit is contained in:
parent
2e1ae9bca3
commit
9c17e89bf0
51 changed files with 572 additions and 505 deletions
|
|
@ -103,11 +103,11 @@ add_subdirectory(xo-stringtable2) # experiment w/ facet object model
|
|||
add_subdirectory(xo-gc) # experiment w/ facet object model
|
||||
add_subdirectory(xo-object)
|
||||
add_subdirectory(xo-object2) # experiment w/ facet object model
|
||||
add_subdirectory(xo-type) # experiment w/ fomo
|
||||
add_subdirectory(xo-procedure2) # schematika procedure abstraction + runtime context (fomo)
|
||||
add_subdirectory(xo-numeric) # experiment w/ facet object model
|
||||
add_subdirectory(xo-ordinaltree)
|
||||
#
|
||||
add_subdirectory(xo-type) # experiment w/ (fomo)
|
||||
add_subdirectory(xo-tokenizer2) # schematika tokenizer (fomo)
|
||||
add_subdirectory(xo-expression2) # schematika expressions (fomo)
|
||||
add_subdirectory(xo-reader2) # schematika expression parser (fomo)
|
||||
|
|
|
|||
|
|
@ -58,9 +58,14 @@ namespace xo {
|
|||
* Return false if installation fails (e.g. memory exhausted)
|
||||
**/
|
||||
virtual bool install_type(Opaque d, const AGCObject & iface) = 0;
|
||||
|
||||
/** add gc root with address @p p_root **/
|
||||
virtual void add_gc_root_poly(Opaque d, obj<AGCObject> * p_root) = 0;
|
||||
//virtual void add_gc_root_typed(Opaque d, typeseq tseq, Opaque * root) = 0;
|
||||
|
||||
/** remove gc root with address @p p_root **/
|
||||
virtual void remove_gc_root_poly(Opaque d, obj<AGCObject> * p_root) = 0;
|
||||
|
||||
/** Request immediate collection.
|
||||
* 1. if collection is enabled, immediately collect all generations
|
||||
* up to (but not including) g
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ namespace xo {
|
|||
// non-const methods
|
||||
[[noreturn]] bool install_type(Opaque, const AGCObject &) noexcept override { _fatal(); }
|
||||
[[noreturn]] void add_gc_root_poly(Opaque, obj<AGCObject> *) override { _fatal(); }
|
||||
[[noreturn]] void remove_gc_root_poly(Opaque, obj<AGCObject> *) override { _fatal(); }
|
||||
[[noreturn]] void request_gc(Opaque, generation) override { _fatal(); }
|
||||
[[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override { _fatal(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ namespace xo {
|
|||
void add_gc_root_poly(Opaque d, obj<AGCObject> * p_root) override {
|
||||
I::add_gc_root_poly(_dcast(d), p_root);
|
||||
}
|
||||
void remove_gc_root_poly(Opaque d, obj<AGCObject> * p_root) override {
|
||||
I::remove_gc_root_poly(_dcast(d), p_root);
|
||||
}
|
||||
void request_gc(Opaque d, generation upto) override {
|
||||
I::request_gc(_dcast(d), upto);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ namespace xo {
|
|||
|
||||
RCollector() = default;
|
||||
RCollector(DataPtr data) : Object{std::move(data)} {}
|
||||
RCollector(const ACollector * iface, void * data)
|
||||
requires std::is_same_v<typename Object::DataType, xo::facet::DVariantPlaceholder>
|
||||
: Object(iface, data) {}
|
||||
|
||||
/** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/
|
||||
template <typename DRepr>
|
||||
|
|
@ -33,6 +36,11 @@ namespace xo {
|
|||
template <typename DRepr>
|
||||
void forward_inplace(DRepr ** pp_repr);
|
||||
|
||||
/** convenience template where pointer requires pivot **/
|
||||
template <typename AFacet, typename DRepr>
|
||||
requires (!std::is_same_v<AFacet, AGCObject>)
|
||||
void forward_pivot_inplace(obj<AFacet,DRepr> * p_obj);
|
||||
|
||||
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
||||
size_type allocated(generation g, role r) const noexcept { return O::iface()->allocated(O::data(), g, r); }
|
||||
size_type reserved(generation g, role r) const noexcept { return O::iface()->reserved(O::data(), g, r); }
|
||||
|
|
@ -41,6 +49,7 @@ namespace xo {
|
|||
|
||||
bool install_type(const AGCObject & iface) { return O::iface()->install_type(O::data(), iface); }
|
||||
void add_gc_root_poly(obj<AGCObject> * p_root) { O::iface()->add_gc_root_poly(O::data(), p_root); }
|
||||
void remove_gc_root_poly(obj<AGCObject> * p_root) { O::iface()->remove_gc_root_poly(O::data(), p_root); }
|
||||
void request_gc(generation g) { O::iface()->request_gc(O::data(), g); }
|
||||
void forward_inplace(AGCObject * lhs_iface, void ** lhs_data) { O::iface()->forward_inplace(O::data(), lhs_iface, lhs_data); }
|
||||
|
||||
|
|
@ -50,6 +59,12 @@ namespace xo {
|
|||
O::iface()->add_gc_root_poly(O::data(), (obj<AGCObject> *)p_root);
|
||||
}
|
||||
|
||||
/** remove root @p p_root **/
|
||||
template <typename DRepr>
|
||||
void remove_gc_root(obj<AGCObject, DRepr> * p_root) {
|
||||
O::iface()->remove_gc_root_poly(O::data(), (obj<AGCObject> *)p_root);
|
||||
}
|
||||
|
||||
static bool _valid;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <xo/facet/FacetRegistry.hpp>
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
/** defined here to avoid #include cycle, since
|
||||
|
|
@ -34,6 +36,16 @@ namespace xo {
|
|||
|
||||
this->forward_inplace(&iface, (void **)p_repr);
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
template <typename AFacet, typename DRepr>
|
||||
requires (!std::is_same_v<AFacet, AGCObject>)
|
||||
void
|
||||
RCollector<Object>::forward_pivot_inplace(obj<AFacet, DRepr> * p_objs)
|
||||
{
|
||||
auto e = xo::facet::FacetRegistry::instance().variant<AGCObject,AFacet>(*p_objs);
|
||||
this->forward_inplace(e.iface(), (void **)&(p_objs->data_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
/** @file CollectorTypeRegistry.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Mar 2026
|
||||
**/
|
||||
|
||||
#include "CollectorTypeRegistry.hpp"
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ namespace ut {
|
|||
REQUIRE(ok);
|
||||
|
||||
// wrap primitive as GCObject, then as expression
|
||||
obj<AGCObject> prim_gco = with_facet<AGCObject>::mkobj(&NumericPrimitives::s_mul_gco_gco_pm);
|
||||
obj<AGCObject> prim_gco = with_facet<AGCObject>::mkobj(NumericPrimitives::make_multiply_pm(alloc));
|
||||
obj<AExpression,DConstant> fn_expr = DConstant::make(alloc, prim_gco);
|
||||
REQUIRE(fn_expr.data() != nullptr);
|
||||
|
||||
|
|
@ -131,7 +131,8 @@ namespace ut {
|
|||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> prim_gco = with_facet<AGCObject>::mkobj(&NumericPrimitives::s_mul_gco_gco_pm);
|
||||
obj<AGCObject> prim_gco
|
||||
= with_facet<AGCObject>::mkobj(NumericPrimitives::make_multiply_pm(alloc));
|
||||
obj<AExpression,DConstant> fn_expr = DConstant::make(alloc, prim_gco);
|
||||
|
||||
obj<AGCObject> val1 = DFloat::box<AGCObject>(alloc, 3.0);
|
||||
|
|
@ -166,7 +167,7 @@ namespace ut {
|
|||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> prim_gco = with_facet<AGCObject>::mkobj(&NumericPrimitives::s_mul_gco_gco_pm);
|
||||
obj<AGCObject> prim_gco = with_facet<AGCObject>::mkobj(NumericPrimitives::make_multiply_pm(alloc));
|
||||
obj<AExpression,DConstant> fn_expr = DConstant::make(alloc, prim_gco);
|
||||
|
||||
obj<AGCObject> val1 = DFloat::box<AGCObject>(alloc, 3.0);
|
||||
|
|
@ -201,7 +202,7 @@ namespace ut {
|
|||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> prim_gco = with_facet<AGCObject>::mkobj(&NumericPrimitives::s_mul_gco_gco_pm);
|
||||
obj<AGCObject> prim_gco = with_facet<AGCObject>::mkobj(NumericPrimitives::make_multiply_pm(alloc));
|
||||
obj<AExpression,DConstant> fn_expr = DConstant::make(alloc, prim_gco);
|
||||
|
||||
obj<AGCObject> val1 = DFloat::box<AGCObject>(alloc, 3.0);
|
||||
|
|
@ -283,7 +284,8 @@ namespace ut {
|
|||
bool ok = CollectorTypeRegistry::instance().install_types(coll);
|
||||
REQUIRE(ok);
|
||||
|
||||
obj<AGCObject> prim_gco = with_facet<AGCObject>::mkobj(&NumericPrimitives::s_mul_gco_gco_pm);
|
||||
obj<AGCObject> prim_gco
|
||||
= with_facet<AGCObject>::mkobj(NumericPrimitives::make_multiply_pm(alloc));
|
||||
obj<AExpression,DConstant> fn_expr = DConstant::make(alloc, prim_gco);
|
||||
|
||||
obj<AGCObject> val1 = DFloat::box<AGCObject>(alloc, 3.0);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include "TypeRegistry.hpp"
|
||||
#include "facet_implementation.hpp"
|
||||
//#include "typeseq.hpp"
|
||||
#include "obj.hpp"
|
||||
#include <xo/arena/DArenaHashMap.hpp>
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ namespace xo {
|
|||
*
|
||||
* Deliberately disable this for variants
|
||||
**/
|
||||
DRepr * operator->()
|
||||
DRepr * operator->() const noexcept
|
||||
requires (!std::is_same_v<DataType, DVariantPlaceholder>)
|
||||
{ return data_; }
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ namespace xo {
|
|||
|
||||
static bool install_type(DX1Collector & d, const AGCObject & iface);
|
||||
static void add_gc_root_poly(DX1Collector & d, obj<AGCObject> * p_root);
|
||||
static void remove_gc_root_poly(DX1Collector & d, obj<AGCObject> * p_root);
|
||||
static void request_gc(DX1Collector & d, generation upto);
|
||||
static void forward_inplace(DX1Collector & d, AGCObject * lhs_iface, void ** lhs_data);
|
||||
|
||||
|
|
|
|||
|
|
@ -287,6 +287,14 @@ namespace xo {
|
|||
*(obj<AGCObject> **)mem = p_root;
|
||||
}
|
||||
|
||||
void
|
||||
DX1Collector::remove_gc_root_poly(obj<AGCObject> * p_root) noexcept
|
||||
{
|
||||
// iterate over roots_, find p_root and drop it
|
||||
|
||||
(void)p_root;
|
||||
}
|
||||
|
||||
void
|
||||
DX1Collector::request_gc(generation upto) noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,6 +67,13 @@ namespace xo {
|
|||
d.add_gc_root_poly(p_root);
|
||||
}
|
||||
|
||||
void
|
||||
ICollector_DX1Collector::remove_gc_root_poly(DX1Collector & d,
|
||||
obj<AGCObject> * p_root)
|
||||
{
|
||||
d.remove_gc_root_poly(p_root);
|
||||
}
|
||||
|
||||
void
|
||||
ICollector_DX1Collector::request_gc(DX1Collector & d,
|
||||
generation upto)
|
||||
|
|
|
|||
|
|
@ -161,24 +161,6 @@ xo_add_genfacetimpl(
|
|||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-gcobject-globalenv
|
||||
FACET_PKG xo_alloc2
|
||||
# REPR GlobalEnv
|
||||
INPUT idl/IGCObject_DGlobalEnv.json5
|
||||
)
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-printable-globalenv
|
||||
FACET_PKG xo_printable2
|
||||
# REPR GlobalEnv
|
||||
INPUT idl/IPrintable_DGlobalEnv.json5
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-gcobject-localenv
|
||||
|
|
|
|||
|
|
@ -36,10 +36,6 @@ set(SELF_SRCS
|
|||
IGCObject_DClosure.cpp
|
||||
IPrintable_DClosure.cpp
|
||||
|
||||
DGlobalEnv.cpp
|
||||
IGCObject_DGlobalEnv.cpp
|
||||
IPrintable_DGlobalEnv.cpp
|
||||
|
||||
DLocalEnv.cpp
|
||||
IGCObject_DLocalEnv.cpp
|
||||
IPrintable_DLocalEnv.cpp
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ namespace xo {
|
|||
InitEvidence
|
||||
InitSubsys<S_interpreter2_tag>::require()
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
InitEvidence retval;
|
||||
|
||||
/* direct subsystem deps for xo-interpreter2/ */
|
||||
|
|
|
|||
|
|
@ -63,12 +63,7 @@ namespace xo {
|
|||
FacetRegistry::register_impl<AGCObject, DVsmSeqContFrame>();
|
||||
FacetRegistry::register_impl<APrintable, DVsmSeqContFrame>();
|
||||
|
||||
// GlobalEnv
|
||||
|
||||
FacetRegistry::register_impl<AGCObject, DGlobalEnv>();
|
||||
FacetRegistry::register_impl<APrintable, DGlobalEnv>();
|
||||
|
||||
// LocalEnv
|
||||
// LocalEnv (see xo-reader2/ for GlobalEnv)
|
||||
|
||||
FacetRegistry::register_impl<AGCObject, DLocalEnv>();
|
||||
FacetRegistry::register_impl<APrintable, DLocalEnv>();
|
||||
|
|
|
|||
|
|
@ -110,13 +110,15 @@ namespace xo {
|
|||
//using X1CollectorConfig = xo::mm::X1CollectorConfig;
|
||||
//using DArena = xo::mm::DArena;
|
||||
//using ArenaConfig = xo::mm::ArenaConfig;
|
||||
using VsmConfig = xo::scm::VsmConfig;
|
||||
using Replxx = replxx::Replxx;
|
||||
using span_type = VirtualSchematikaMachine::span_type;
|
||||
|
||||
App(const AppConfig & cfg = AppConfig())
|
||||
: repl_config_{cfg.repl_config_},
|
||||
app_arena_{cfg.app_arena_config_},
|
||||
vsm_{cfg.vsm_config_, obj<AAllocator,DArena>(&app_arena_)}
|
||||
vsm_config_{cfg.vsm_config_}
|
||||
//vsm_{cfg.vsm_config_, obj<AAllocator,DArena>(&app_arena_)}
|
||||
{
|
||||
this->interactive_ = isatty(STDIN_FILENO);
|
||||
|
||||
|
|
@ -148,7 +150,8 @@ namespace xo {
|
|||
/** arena with same lifetime as this application **/
|
||||
DArena app_arena_;
|
||||
/** schematika virtual machine **/
|
||||
VirtualSchematikaMachine vsm_;
|
||||
VsmConfig vsm_config_;
|
||||
std::unique_ptr<VirtualSchematikaMachine> vsm_;
|
||||
};
|
||||
|
||||
void
|
||||
|
|
@ -162,13 +165,16 @@ namespace xo {
|
|||
void
|
||||
App::_init()
|
||||
{
|
||||
// window to contorl size of registries ends as soon as we init other subsystems
|
||||
// window to control size of registries ends as soon as we init other subsystems
|
||||
TypeRegistry::instance(1024);
|
||||
FacetRegistry::instance(1024);
|
||||
|
||||
InitEvidence init_evidence_ = (InitSubsys<S_interpreter2_tag>::require());
|
||||
|
||||
Subsystem::initialize_all();
|
||||
|
||||
vsm_.reset(new VirtualSchematikaMachine(vsm_config_,
|
||||
obj<AAllocator,DArena>(&app_arena_)));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -176,7 +182,7 @@ namespace xo {
|
|||
{
|
||||
welcome(cerr);
|
||||
|
||||
vsm_.begin_interactive_session();
|
||||
vsm_->begin_interactive_session();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -186,7 +192,7 @@ namespace xo {
|
|||
span_type input;
|
||||
|
||||
// outer loop: fetch one line of interactive input
|
||||
while (replxx_getline(interactive_, vsm_.is_at_toplevel(), rx_, &input)) {
|
||||
while (replxx_getline(interactive_, vsm_->is_at_toplevel(), rx_, &input)) {
|
||||
|
||||
// inner loop: consume up to one expression at a time.
|
||||
while (!input.empty() && this->_read_eval_print(&input, false /*eof*/))
|
||||
|
|
@ -218,7 +224,7 @@ namespace xo {
|
|||
if (!p_input || p_input->empty())
|
||||
return true;
|
||||
|
||||
VsmResultExt res = vsm_.read_eval_print(*p_input, eof);
|
||||
VsmResultExt res = vsm_->read_eval_print(*p_input, eof);
|
||||
|
||||
*p_input = res.remaining_;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,21 +14,25 @@ namespace xo {
|
|||
**/
|
||||
class NumericPrimitives {
|
||||
public:
|
||||
/** polymorphic (in both arguments) multiply **/
|
||||
static DPrimitive_gco_2_gco_gco s_mul_gco_gco_pm;
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
|
||||
public:
|
||||
/** polymorphic (in both arguments1) multiply **/
|
||||
static DPrimitive_gco_2_gco_gco * make_multiply_pm(obj<AAllocator> mm);
|
||||
|
||||
/** polymorphic (in both arguments) divide **/
|
||||
static DPrimitive_gco_2_gco_gco s_div_gco_gco_pm;
|
||||
static DPrimitive_gco_2_gco_gco * make_divide_pm(obj<AAllocator> mm);
|
||||
/** polymorphic (in both arguments) add **/
|
||||
static DPrimitive_gco_2_gco_gco s_add_gco_gco_pm;
|
||||
static DPrimitive_gco_2_gco_gco * make_add_pm(obj<AAllocator> mm);
|
||||
/** polymorphic (in both arguments) subtract **/
|
||||
static DPrimitive_gco_2_gco_gco s_sub_gco_gco_pm;
|
||||
static DPrimitive_gco_2_gco_gco * make_subtract_pm(obj<AAllocator> mm);
|
||||
|
||||
/** polymorphic (in both arguments) compare (==) **/
|
||||
static DPrimitive_gco_2_gco_gco s_cmpeq_gco_gco_pm;
|
||||
static DPrimitive_gco_2_gco_gco * make_cmpeq_pm(obj<AAllocator> mm);
|
||||
/** polymorphic (in both arguments) compare (!=) **/
|
||||
static DPrimitive_gco_2_gco_gco s_cmpne_gco_gco_pm;
|
||||
static DPrimitive_gco_2_gco_gco * make_cmpne_pm(obj<AAllocator> mm);
|
||||
/** polymorphic (in both arguments) compare (<) **/
|
||||
static DPrimitive_gco_2_gco_gco s_cmplt_gco_gco_pm;
|
||||
static DPrimitive_gco_2_gco_gco * make_cmplt_pm(obj<AAllocator> mm);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
/** @file numeric_register_primitives.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Mar 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PrimitiveRegistry.hpp"
|
||||
#include <xo/alloc2/Collector.hpp>
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** Register gc-aware (AGCObject,DRepr) combinations with garbage collector @p gc **/
|
||||
bool numeric_register_primitives(obj<xo::mm::AAllocator> gc,
|
||||
InstallSink sink,
|
||||
InstallFlags flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* end numeric_register_primitives.hpp */
|
||||
|
|
@ -4,6 +4,7 @@ set(SELF_LIB xo_numeric)
|
|||
set(SELF_SRCS
|
||||
init_numeric.cpp
|
||||
numeric_register_facets.cpp
|
||||
numeric_register_primitives.cpp
|
||||
NumericPrimitives.cpp
|
||||
NumericDispatch.cpp
|
||||
INumeric_Any.cpp
|
||||
|
|
|
|||
|
|
@ -7,38 +7,59 @@
|
|||
#include "NumericDispatch.hpp"
|
||||
|
||||
namespace xo {
|
||||
using xo::mm::AGCObject;
|
||||
using xo::mm::AAllocator;
|
||||
//using xo::mm::AGCObject;
|
||||
|
||||
namespace scm {
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
NumericPrimitives::s_mul_gco_gco_pm("_mul",
|
||||
&NumericDispatch::multiply);
|
||||
DPrimitive_gco_2_gco_gco *
|
||||
NumericPrimitives::make_multiply_pm(obj<AAllocator> mm)
|
||||
{
|
||||
return DPrimitive_gco_2_gco_gco::_make(mm, "_mul",
|
||||
&NumericDispatch::multiply);
|
||||
}
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
NumericPrimitives::s_div_gco_gco_pm("_div",
|
||||
&NumericDispatch::divide);
|
||||
DPrimitive_gco_2_gco_gco *
|
||||
NumericPrimitives::make_divide_pm(obj<AAllocator> mm)
|
||||
{
|
||||
return DPrimitive_gco_2_gco_gco::_make(mm, "_div",
|
||||
&NumericDispatch::divide);
|
||||
}
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
NumericPrimitives::s_add_gco_gco_pm("_add",
|
||||
&NumericDispatch::add);
|
||||
DPrimitive_gco_2_gco_gco *
|
||||
NumericPrimitives::make_add_pm(obj<AAllocator> mm)
|
||||
{
|
||||
return DPrimitive_gco_2_gco_gco::_make(mm, "_add",
|
||||
&NumericDispatch::add);
|
||||
}
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
NumericPrimitives::s_sub_gco_gco_pm("_sub",
|
||||
&NumericDispatch::subtract);
|
||||
DPrimitive_gco_2_gco_gco *
|
||||
NumericPrimitives::make_subtract_pm(obj<AAllocator> mm)
|
||||
{
|
||||
return DPrimitive_gco_2_gco_gco::_make(mm, "_sub",
|
||||
&NumericDispatch::subtract);
|
||||
}
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
NumericPrimitives::s_cmpeq_gco_gco_pm("_cmpeq",
|
||||
&NumericDispatch::cmp_equal);
|
||||
DPrimitive_gco_2_gco_gco *
|
||||
NumericPrimitives::make_cmpeq_pm(obj<AAllocator> mm)
|
||||
{
|
||||
return DPrimitive_gco_2_gco_gco::_make(mm, "_cmpeq",
|
||||
&NumericDispatch::cmp_equal);
|
||||
}
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
NumericPrimitives::s_cmpne_gco_gco_pm("_cmpne",
|
||||
&NumericDispatch::cmp_notequal);
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
NumericPrimitives::s_cmplt_gco_gco_pm("_cmplt",
|
||||
&NumericDispatch::cmp_less);
|
||||
DPrimitive_gco_2_gco_gco *
|
||||
NumericPrimitives::make_cmpne_pm(obj<AAllocator> mm)
|
||||
{
|
||||
return DPrimitive_gco_2_gco_gco::_make(mm, "_cmpne",
|
||||
&NumericDispatch::cmp_notequal);
|
||||
}
|
||||
|
||||
DPrimitive_gco_2_gco_gco *
|
||||
NumericPrimitives::make_cmplt_pm(obj<AAllocator> mm)
|
||||
{
|
||||
return DPrimitive_gco_2_gco_gco::_make(mm, "_cmplt",
|
||||
&NumericDispatch::cmp_less);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -7,14 +7,20 @@
|
|||
#include <xo/procedure2/init_procedure2.hpp>
|
||||
#include "Subsystem.hpp"
|
||||
#include "numeric_register_facets.hpp"
|
||||
#include "numeric_register_primitives.hpp"
|
||||
|
||||
namespace xo {
|
||||
using xo::scm::numeric_register_facets;
|
||||
using xo::scm::numeric_register_primitives;
|
||||
using xo::scm::PrimitiveRegistry;
|
||||
|
||||
void
|
||||
InitSubsys<S_numeric_tag>::init()
|
||||
{
|
||||
numeric_register_facets();
|
||||
|
||||
PrimitiveRegistry::instance().register_primitives(&numeric_register_primitives);
|
||||
|
||||
}
|
||||
|
||||
InitEvidence
|
||||
|
|
|
|||
81
xo-numeric/src/numeric/numeric_register_primitives.cpp
Normal file
81
xo-numeric/src/numeric/numeric_register_primitives.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/** @file numeric_register_primitives.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Mar 2026
|
||||
**/
|
||||
|
||||
#include "numeric_register_primitives.hpp"
|
||||
#include "NumericPrimitives.hpp"
|
||||
#include "NumericDispatch.hpp"
|
||||
#include <xo/procedure2/Primitive_gco_2_gco_gco.hpp>
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::mm::AAllocator;
|
||||
using xo::scope;
|
||||
|
||||
namespace scm {
|
||||
namespace {
|
||||
bool install_aux(InstallSink sink,
|
||||
DPrimitive_gco_2_gco_gco * pm,
|
||||
InstallFlags flags)
|
||||
{
|
||||
if (flags != InstallFlags::f_none) {
|
||||
return sink(pm->name(),
|
||||
pm->fn_td(),
|
||||
obj<AProcedure,DPrimitive_gco_2_gco_gco>(pm),
|
||||
flags);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool install_aux(InstallSink sink,
|
||||
obj<AAllocator> mm,
|
||||
std::string_view name,
|
||||
obj<AGCObject> (*impl)(obj<ARuntimeContext> rcx,
|
||||
obj<AGCObject> x,
|
||||
obj<AGCObject> y),
|
||||
InstallFlags flags)
|
||||
{
|
||||
if (flags != InstallFlags::f_none) {
|
||||
auto pm
|
||||
= DPrimitive_gco_2_gco_gco::_make(mm, name, impl);
|
||||
|
||||
return install_aux(sink, pm, flags);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
numeric_register_primitives(obj<AAllocator> mm, InstallSink sink, InstallFlags flags)
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok = ok & install_aux(sink,
|
||||
NumericPrimitives::make_multiply_pm(mm),
|
||||
flags & InstallFlags::f_essential);
|
||||
ok = ok & install_aux(sink,
|
||||
NumericPrimitives::make_divide_pm(mm),
|
||||
flags & InstallFlags::f_essential);
|
||||
ok = ok & install_aux(sink, mm, "_add", &NumericDispatch::add,
|
||||
flags & InstallFlags::f_essential);
|
||||
ok = ok & install_aux(sink, mm, "_sub", &NumericDispatch::subtract,
|
||||
flags & InstallFlags::f_essential);
|
||||
|
||||
ok = ok & install_aux(sink, mm, "_cmpeq", &NumericDispatch::cmp_equal,
|
||||
flags & InstallFlags::f_essential);
|
||||
ok = ok & install_aux(sink, mm, "_cmpne", &NumericDispatch::cmp_notequal,
|
||||
flags & InstallFlags::f_essential);
|
||||
ok = ok & install_aux(sink, mm, "_cmplt", &NumericDispatch::cmp_less,
|
||||
flags & InstallFlags::f_essential);
|
||||
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end numeric_register_primitives.cpp */
|
||||
|
|
@ -6,8 +6,8 @@ include(CMakeFindDependencyMacro)
|
|||
# must coordinate with xo_dependency() calls
|
||||
# in CMakeLists.txt
|
||||
#
|
||||
find_dependency(xo_type)
|
||||
find_dependency(xo_object2)
|
||||
#find_dependency(xo_gc)
|
||||
find_dependency(subsys)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
|
|
|
|||
|
|
@ -55,6 +55,18 @@ namespace xo {
|
|||
}
|
||||
|
||||
/** @brief Schematika primitive with fixed number of arguments
|
||||
*
|
||||
* Distinction between type-constructor (@ref type_) and
|
||||
* type-description (@ref fn_td_): type-constructor is narrower;
|
||||
* it may lift into schematika type system some information about function
|
||||
* behavior. For example
|
||||
* @pre
|
||||
* cons :: (T x list<T>) -> list<T>
|
||||
* @endpre
|
||||
* but implementation has signature:
|
||||
* @pre
|
||||
* (obj<AGCobject> x obj<AGCObject,DList>) -> obj<AGCObject,DList>
|
||||
* @endpre
|
||||
**/
|
||||
template <typename Fn>
|
||||
class Primitive {
|
||||
|
|
@ -70,13 +82,28 @@ namespace xo {
|
|||
using ppindentinfo = xo::print::ppindentinfo;
|
||||
|
||||
public:
|
||||
Primitive(std::string_view name, Fn fn) : name_{name},
|
||||
fn_td_{Reflect::require<Fn>()},
|
||||
fn_{fn} {}
|
||||
/** @defgroup scm-primitive-ctors constructors **/
|
||||
///@{
|
||||
|
||||
Primitive(std::string_view name, Fn fn)
|
||||
: name_{name},
|
||||
fn_td_{Reflect::require<Fn>()},
|
||||
fn_{fn} {}
|
||||
|
||||
static Primitive * _make(obj<AAllocator> mm, std::string_view name, Fn fn) {
|
||||
void * mem = mm.alloc_for<Primitive>();
|
||||
|
||||
return new (mem) Primitive(name, fn);
|
||||
}
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-primitive-methods general methods **/
|
||||
///@{
|
||||
|
||||
TypeDescr fn_td() const noexcept { return fn_td_; }
|
||||
|
||||
std::string_view name() const noexcept { return name_; }
|
||||
|
||||
static constexpr std::int32_t n_args() noexcept { return Traits::n_args; }
|
||||
|
||||
bool is_nary() const noexcept { return false; }
|
||||
|
|
@ -86,6 +113,7 @@ namespace xo {
|
|||
std::make_index_sequence<Traits::n_args>{});
|
||||
}
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-primitive-printable-facet **/
|
||||
///@{
|
||||
|
||||
|
|
@ -166,8 +194,12 @@ namespace xo {
|
|||
|
||||
template <typename Fn>
|
||||
std::size_t
|
||||
Primitive<Fn>::forward_children(obj<ACollector>) noexcept {
|
||||
// Primitive holds no GC refs (just string_view + function pointer)
|
||||
Primitive<Fn>::forward_children(obj<ACollector> gc) noexcept {
|
||||
{
|
||||
auto e = type_.to_facet<AGCObject>(); // FacetRegistry dep
|
||||
gc.forward_inplace(e.iface(), (void **)&(type_.data_));
|
||||
}
|
||||
|
||||
return this->shallow_size();
|
||||
}
|
||||
|
||||
|
|
|
|||
89
xo-procedure2/include/xo/procedure2/PrimitiveRegistry.hpp
Normal file
89
xo-procedure2/include/xo/procedure2/PrimitiveRegistry.hpp
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/** @file PrimitiveRegistry.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Mar 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Procedure.hpp"
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include <xo/reflect/TypeDescr.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** partition primitives based on scope.
|
||||
* Each primitive associates with exactly one flag value.
|
||||
* Flags also operate as bitmasks when calling
|
||||
* @ref PrimitiveRegistry::install_primitives()
|
||||
**/
|
||||
enum class InstallFlags {
|
||||
f_none = 0x0,
|
||||
|
||||
/** mandatory primitives, necessary for operator support,
|
||||
* e.g. _add needed to implement infix +
|
||||
**/
|
||||
f_essential = 0x1,
|
||||
f_generalpurpose = 0x2,
|
||||
|
||||
/** all primitives **/
|
||||
f_all = f_essential | f_generalpurpose,
|
||||
};
|
||||
|
||||
inline InstallFlags operator&(InstallFlags x, InstallFlags y) {
|
||||
return InstallFlags(static_cast<uint64_t>(x) & static_cast<uint64_t>(y));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** provided by VSM to receive created primitives.
|
||||
* InstallSink(pm) adopts a primitive
|
||||
**/
|
||||
using InstallSink = std::function<bool (std::string_view name,
|
||||
xo::reflect::TypeDescr fn_td,
|
||||
obj<AProcedure> pm,
|
||||
InstallFlags flags)>;
|
||||
|
||||
/** @class PrimitiveRegistry
|
||||
*
|
||||
* @brief Runtime registry for primitives
|
||||
*
|
||||
* Singleton to remember setup code for known primitives.
|
||||
* Use to gather primitives for installation in global
|
||||
* environment for a virtual schematika machine (VSM)
|
||||
**/
|
||||
class PrimitiveRegistry {
|
||||
public:
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
|
||||
/** provided by a subsystem that provides primitives.
|
||||
* Allocates primitives using memory from mm, delivering them
|
||||
* to InstallSink sink.
|
||||
**/
|
||||
using InstallSource = std::function<bool (obj<AAllocator> mm,
|
||||
InstallSink sink,
|
||||
InstallFlags flags)>;
|
||||
|
||||
public:
|
||||
/** singleton instance **/
|
||||
static PrimitiveRegistry & instance();
|
||||
|
||||
/** remember primitive-factory @p source_fn **/
|
||||
void register_primitives(InstallSource source_fn);
|
||||
|
||||
/** create primitives using memory from @p mm,
|
||||
* delivering each primitive to @p sink.
|
||||
**/
|
||||
bool install_primitives(obj<AAllocator> mm,
|
||||
InstallSink sink,
|
||||
InstallFlags flags);
|
||||
|
||||
private:
|
||||
/** a set of factories that create primitives **/
|
||||
std::vector<InstallSource> init_seq_v_;
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end PrimitiveRegistry.hpp */
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/** @file procedure2_register_primitives.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Mar 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PrimitiveRegistry.hpp"
|
||||
#include <xo/alloc2/Collector.hpp>
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** Register gc-aware (AGCObject,DRepr) combinations with garbage collector @p gc **/
|
||||
bool procedure2_register_primitives(obj<xo::mm::AAllocator> gc, InstallSink sink);
|
||||
}
|
||||
}
|
||||
|
||||
/* end procedure2_register_primitives.hpp */
|
||||
|
|
@ -34,10 +34,9 @@ xo_install_include_tree3(include/xo/procedure2)
|
|||
# NOTE: dependency set here must be kept consistent with
|
||||
# xo-procedure2/cmake/xo_procedure2Config.cmake.in
|
||||
|
||||
xo_dependency(${SELF_LIB} xo_type)
|
||||
xo_dependency(${SELF_LIB} xo_object2)
|
||||
#xo_dependency(${SELF_LIB} xo_gc)
|
||||
xo_dependency(${SELF_LIB} subsys)
|
||||
#xo_dependency(${SELF_LIB} xo_indentlog)
|
||||
|
||||
xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets)
|
||||
|
||||
|
|
|
|||
49
xo-procedure2/src/procedure2/PrimitiveRegistry.cpp
Normal file
49
xo-procedure2/src/procedure2/PrimitiveRegistry.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/** @file PrimitiveRegistry.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Mar 2026
|
||||
**/
|
||||
|
||||
#include "PrimitiveRegistry.hpp"
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
PrimitiveRegistry &
|
||||
PrimitiveRegistry::instance()
|
||||
{
|
||||
static PrimitiveRegistry s_instance;
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void
|
||||
PrimitiveRegistry::register_primitives(InstallSource factory)
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
init_seq_v_.push_back(factory);
|
||||
}
|
||||
|
||||
bool
|
||||
PrimitiveRegistry::install_primitives(obj<AAllocator> mm,
|
||||
InstallSink sink,
|
||||
InstallFlags flags)
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
bool ok = true;
|
||||
|
||||
size_t i = 0;
|
||||
size_t n = init_seq_v_.size();
|
||||
log && log("run n init steps", xtag("n", n));
|
||||
|
||||
for (const auto & fn : init_seq_v_) {
|
||||
log && log("do install fn (", i+1, "/", n, ")");
|
||||
|
||||
ok = ok & fn(mm, sink, flags);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
|
@ -37,187 +37,6 @@ namespace xo {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef OBSOLETE // see xo-numeric/xo/numeric/NumericPrimitives.cpp
|
||||
obj<AGCObject>
|
||||
mul_gco_gco(obj<ARuntimeContext> rcx,
|
||||
obj<AGCObject> x_gco,
|
||||
obj<AGCObject> y_gco)
|
||||
{
|
||||
using xo::reflect::typeseq;
|
||||
|
||||
obj<AAllocator> mm = rcx.allocator();
|
||||
|
||||
// PLACEHOLDER
|
||||
|
||||
// TODO:
|
||||
// 1. move this to xo-numeric2/ when available
|
||||
// 2. at that point will require polymorphic dispatch
|
||||
// on argument representations, analogous to dispatch
|
||||
// in FacetRegistry
|
||||
|
||||
typeseq x_tseq = x_gco._typeseq();
|
||||
typeseq y_tseq = y_gco._typeseq();
|
||||
|
||||
// FOR NOW: just test runtime values
|
||||
//
|
||||
if (x_tseq == typeseq::id<DInteger>()) {
|
||||
// i64 * ..
|
||||
long x = GCObjectConversion<long>::from_gco(mm, x_gco);
|
||||
|
||||
if (y_tseq == typeseq::id<DInteger>()) {
|
||||
// i64 * i64
|
||||
long y = GCObjectConversion<long>::from_gco(mm, y_gco);
|
||||
|
||||
return DInteger::box<AGCObject>(mm, x * y);
|
||||
} else if (y_tseq == typeseq::id<DFloat>()) {
|
||||
// i64 * f64
|
||||
double y = GCObjectConversion<double>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, x * y);
|
||||
}
|
||||
} else if (x_tseq == typeseq::id<DFloat>()) {
|
||||
if (y_tseq == typeseq::id<DInteger>()) {
|
||||
// f64 * i64.
|
||||
double x = GCObjectConversion<double>::from_gco(mm, x_gco);
|
||||
long y = GCObjectConversion<long>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, x * y);
|
||||
} else if (y_tseq == typeseq::id<DFloat>()) {
|
||||
// f64 * f64.
|
||||
double x = GCObjectConversion<double>::from_gco(mm, x_gco);
|
||||
double y = GCObjectConversion<double>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, x * y);
|
||||
}
|
||||
}
|
||||
|
||||
// here: error
|
||||
throw std::runtime_error(tostr("mul_gco_gco: unexpected argument types xt,yt",
|
||||
xtag("x.tseq", x_tseq),
|
||||
xtag("y.tseq", y_tseq)));
|
||||
return obj<AGCObject>();
|
||||
}
|
||||
|
||||
obj<AGCObject>
|
||||
sub_gco_gco(obj<ARuntimeContext> rcx,
|
||||
obj<AGCObject> x_gco,
|
||||
obj<AGCObject> y_gco)
|
||||
{
|
||||
using xo::reflect::typeseq;
|
||||
|
||||
obj<AAllocator> mm = rcx.allocator();
|
||||
|
||||
// PLACEHOLDER
|
||||
|
||||
// TODO:
|
||||
// 1. move this to xo-numeric2/ when available
|
||||
// 2. at that point will require polymorphic dispatch
|
||||
// on argument representations, analogous to dispatch
|
||||
// in FacetRegistry
|
||||
|
||||
typeseq x_tseq = x_gco._typeseq();
|
||||
typeseq y_tseq = y_gco._typeseq();
|
||||
|
||||
// FOR NOW: just test runtime values
|
||||
//
|
||||
if (x_tseq == typeseq::id<DInteger>()) {
|
||||
// i64 * ..
|
||||
long x = GCObjectConversion<long>::from_gco(mm, x_gco);
|
||||
|
||||
if (y_tseq == typeseq::id<DInteger>()) {
|
||||
// i64 * i64
|
||||
long y = GCObjectConversion<long>::from_gco(mm, y_gco);
|
||||
|
||||
return DInteger::box<AGCObject>(mm, x - y);
|
||||
} else if (y_tseq == typeseq::id<DFloat>()) {
|
||||
// i64 * f64
|
||||
double y = GCObjectConversion<double>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, x - y);
|
||||
}
|
||||
} else if (x_tseq == typeseq::id<DFloat>()) {
|
||||
if (y_tseq == typeseq::id<DInteger>()) {
|
||||
// f64 * i64.
|
||||
double x = GCObjectConversion<double>::from_gco(mm, x_gco);
|
||||
long y = GCObjectConversion<long>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, x - y);
|
||||
} else if (y_tseq == typeseq::id<DFloat>()) {
|
||||
// f64 * f64.
|
||||
double x = GCObjectConversion<double>::from_gco(mm, x_gco);
|
||||
double y = GCObjectConversion<double>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, x - y);
|
||||
}
|
||||
}
|
||||
|
||||
// here: error
|
||||
throw std::runtime_error(tostr("sub_gco_gco: unexpected argument types xt,yt",
|
||||
xtag("x.tseq", x_tseq),
|
||||
xtag("y.tseq", y_tseq)));
|
||||
return obj<AGCObject>();
|
||||
}
|
||||
|
||||
obj<AGCObject>
|
||||
equal_gco_gco(obj<ARuntimeContext> rcx,
|
||||
obj<AGCObject> x_gco,
|
||||
obj<AGCObject> y_gco)
|
||||
{
|
||||
using xo::reflect::typeseq;
|
||||
|
||||
obj<AAllocator> mm = rcx.allocator();
|
||||
|
||||
// PLACEHOLDER
|
||||
|
||||
// TODO
|
||||
// 1. move this to xo-numeric2/ when available
|
||||
// 2. at that point will require polymorphic dispatch on argument representations.
|
||||
//
|
||||
|
||||
typeseq x_tseq = x_gco._typeseq();
|
||||
typeseq y_tseq = y_gco._typeseq();
|
||||
|
||||
// FOR NOW: just test runtime values
|
||||
//
|
||||
if (x_tseq == typeseq::id<DInteger>()) {
|
||||
// i64 * ..
|
||||
long x = GCObjectConversion<long>::from_gco(mm, x_gco);
|
||||
|
||||
if (y_tseq == typeseq::id<DInteger>()) {
|
||||
// i64 == i64
|
||||
long y = GCObjectConversion<long>::from_gco(mm, y_gco);
|
||||
|
||||
return DBoolean::box<AGCObject>(mm, x == y);
|
||||
} else if (y_tseq == typeseq::id<DFloat>()) {
|
||||
// i64 == f64
|
||||
double y = GCObjectConversion<double>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, static_cast<double>(x) == y);
|
||||
}
|
||||
} else if (x_tseq == typeseq::id<DFloat>()) {
|
||||
if (y_tseq == typeseq::id<DInteger>()) {
|
||||
// f64 == i64.
|
||||
double x = GCObjectConversion<double>::from_gco(mm, x_gco);
|
||||
long y = GCObjectConversion<long>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, x == static_cast<double>(y));
|
||||
} else if (y_tseq == typeseq::id<DFloat>()) {
|
||||
// f64 * f64.
|
||||
double x = GCObjectConversion<double>::from_gco(mm, x_gco);
|
||||
double y = GCObjectConversion<double>::from_gco(mm, y_gco);
|
||||
|
||||
return DFloat::box<AGCObject>(mm, x == y);
|
||||
}
|
||||
}
|
||||
|
||||
// here: error
|
||||
throw std::runtime_error(tostr("mul_gco_gco: unexpected argument types xt,yt",
|
||||
xtag("x.tseq", x_tseq),
|
||||
xtag("y.tseq", y_tseq)));
|
||||
return obj<AGCObject>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NOT_YET
|
||||
double
|
||||
mul_f64_f64(double x, double y) {
|
||||
|
|
@ -255,17 +74,6 @@ namespace xo {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef OSOLETE
|
||||
DPrimitive_gco_2_gco_gco
|
||||
Primitives::s_mul_gco_gco_pm("_mul", &mul_gco_gco);
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
Primitives::s_sub_gco_gco_pm("_sub", &sub_gco_gco);
|
||||
|
||||
DPrimitive_gco_2_gco_gco
|
||||
Primitives::s_equal_gco_gco_pm("_equal", &equal_gco_gco);
|
||||
#endif
|
||||
|
||||
#ifdef NOT_YET
|
||||
Primitive_f64_1_f64
|
||||
Primitives::s_neg_f64_pm("_neg_d",
|
||||
|
|
|
|||
|
|
@ -337,6 +337,22 @@ xo_add_genfacetimpl(
|
|||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-reader2-facetimpl-gcobject-globalenv
|
||||
FACET_PKG xo_alloc2
|
||||
INPUT idl/IGCObject_DGlobalEnv.json5
|
||||
)
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-reader2-facetimpl-printable-globalenv
|
||||
FACET_PKG xo_printable2
|
||||
INPUT idl/IPrintable_DGlobalEnv.json5
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
xo_add_genfacet_all(xo-reader2-genfacet-all)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
mode: "implementation",
|
||||
output_cpp_dir: "src/interpreter2",
|
||||
output_cpp_dir: "src/reader2/facet",
|
||||
output_hpp_dir: "include/xo/interpreter2",
|
||||
output_impl_subdir: "env",
|
||||
includes: [
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
mode: "implementation",
|
||||
output_cpp_dir: "src/interpreter2",
|
||||
output_cpp_dir: "src/interpreter2/facet",
|
||||
output_hpp_dir: "include/xo/interpreter2",
|
||||
output_impl_subdir: "env",
|
||||
includes: [ "<xo/printable2/Printable.hpp>",
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <xo/procedure2/PrimitiveRegistry.hpp>
|
||||
#include <xo/arena/ArenaHashMapConfig.hpp>
|
||||
#include <xo/arena/ArenaConfig.hpp>
|
||||
|
||||
|
|
@ -55,6 +56,9 @@ namespace xo {
|
|||
/** max capacity for unique string table **/
|
||||
size_t max_stringtable_capacity_ = 4096;
|
||||
|
||||
/** flags controlling which primitives to install **/
|
||||
InstallFlags pm_install_flags_ = InstallFlags::f_all;
|
||||
|
||||
/** control SchematikaParser debug logging **/
|
||||
bool debug_flag_ = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "ParserResult.hpp"
|
||||
#include "GlobalEnv.hpp"
|
||||
#include <xo/expression2/DGlobalSymtab.hpp>
|
||||
#include <xo/expression2/DLocalSymtab.hpp>
|
||||
#include <xo/expression2/DVariable.hpp>
|
||||
#include <xo/expression2/VarRef.hpp>
|
||||
#include <xo/tokenizer2/Token.hpp>
|
||||
#include <xo/procedure2/PrimitiveRegistry.hpp>
|
||||
#include <xo/type/Type.hpp>
|
||||
#include <xo/object2/DArray.hpp>
|
||||
#include <xo/stringtable2/StringTable.hpp>
|
||||
|
|
@ -45,6 +47,9 @@ namespace xo {
|
|||
using size_type = std::size_t;
|
||||
|
||||
public:
|
||||
/** @defgroup scm-parserstatemachine-ctors constructors **/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @p config arena configuration for parser state
|
||||
* @p symtab_var_config configuration for global symtab variables
|
||||
|
|
@ -53,6 +58,8 @@ namespace xo {
|
|||
* (maps to separate dedicated memory)
|
||||
* @p max_stringtable_capacity
|
||||
* hard max size for unique stringtable
|
||||
* @p pm_install_flags
|
||||
* flags controlling primitives to install
|
||||
* @p expr_alloc allocator for schematika expressions.
|
||||
* Probably shared with execution.
|
||||
* @p aux_alloc auxiliary allocator for non-copyable memory
|
||||
|
|
@ -64,12 +71,17 @@ namespace xo {
|
|||
const ArenaHashMapConfig & symtab_var_config,
|
||||
const ArenaHashMapConfig & symtab_type_config,
|
||||
size_type max_stringtable_capacity,
|
||||
InstallFlags pm_install_flags,
|
||||
obj<AAllocator> expr_alloc,
|
||||
obj<AAllocator> aux_alloc);
|
||||
|
||||
/** non-trivial dtor for @ref global_symtab_ **/
|
||||
~ParserStateMachine() = default;
|
||||
/** not copyable (need to put global_env into gc **/
|
||||
ParserStateMachine(const ParserStateMachine & other) = delete;
|
||||
|
||||
/** non-trivial dtor for @ref global_symtab_ **/
|
||||
~ParserStateMachine();
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-parserstatemachine-accessors accessor methods **/
|
||||
///@{
|
||||
|
||||
|
|
@ -80,6 +92,21 @@ namespace xo {
|
|||
DLocalSymtab * local_symtab() const noexcept { return local_symtab_; }
|
||||
const ParserResult & result() const noexcept { return result_; }
|
||||
|
||||
/** polymoprhihc multiply primitive. Use to implement infix op* **/
|
||||
obj<AGCObject> multiply_pm() const;
|
||||
/** polymorphic divide primitive. Use to implement infix op/ **/
|
||||
obj<AGCObject> divide_pm() const;
|
||||
/** polymorphic add primitive. Use to implement infix op+ **/
|
||||
obj<AGCObject> add_pm() const;
|
||||
/** polymorphic subtract primitive. Use to implement infix op- **/
|
||||
obj<AGCObject> subtract_pm() const;
|
||||
/** polymorphic equality comparison. Use to implement infix op== **/
|
||||
obj<AGCObject> cmpeq_pm() const;
|
||||
/** polymorphic inequality comparison. Use to implement infix op!= **/
|
||||
obj<AGCObject> cmpne_pm() const;
|
||||
/** polymorphich less-than comparison. Use to implement infix op< **/
|
||||
obj<AGCObject> cmplt_pm() const;
|
||||
|
||||
/** true iff state machine is currently idle (at top-level) **/
|
||||
bool is_at_toplevel() const noexcept;
|
||||
|
||||
|
|
@ -378,6 +405,20 @@ namespace xo {
|
|||
**/
|
||||
DLocalSymtab * local_symtab_ = nullptr;
|
||||
|
||||
/** global variable bindings (builtin primitives) **/
|
||||
obj<AGCObject,DGlobalEnv> global_env_;
|
||||
|
||||
/** bindings for special builtin primitives
|
||||
* (asociated with hardwired operator syntax)
|
||||
**/
|
||||
Binding multiply_binding_;
|
||||
Binding divide_binding_;
|
||||
Binding add_binding_;
|
||||
Binding subtract_binding_;
|
||||
Binding cmpeq_binding_;
|
||||
Binding cmpne_binding_;
|
||||
Binding cmplt_binding_;
|
||||
|
||||
/** current output from parser **/
|
||||
ParserResult result_;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <xo/procedure2/PrimitiveRegistry.hpp>
|
||||
#include <xo/arena/CircularBufferConfig.hpp>
|
||||
#include <xo/arena/ArenaHashMapConfig.hpp>
|
||||
#include <xo/arena/ArenaConfig.hpp>
|
||||
|
|
@ -71,6 +72,9 @@ namespace xo {
|
|||
/** max size (in bytes) of stringtable **/
|
||||
size_t max_stringtable_cap_ = 64*1024;
|
||||
|
||||
/** flags controlling which primitives to install **/
|
||||
InstallFlags pm_install_flags_ = InstallFlags::f_all;
|
||||
|
||||
/** debug flag for schematika_reader **/
|
||||
bool reader_debug_flag_ = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ set(SELF_SRCS
|
|||
ParserStack.cpp
|
||||
ParserResult.cpp
|
||||
|
||||
DGlobalEnv.cpp
|
||||
facet/IGCObject_DGlobalEnv.cpp
|
||||
facet/IPrintable_DGlobalEnv.cpp
|
||||
|
||||
syntaxstatetype.cpp
|
||||
ISyntaxStateMachine_Any.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -603,173 +603,6 @@ namespace xo {
|
|||
p_psm->on_error(self_name, std::move(errmsg));
|
||||
}
|
||||
|
||||
rp<Expression>
|
||||
progress_xs::assemble_expr(parserstatemachine * p_psm) {
|
||||
/* need to defer building Apply incase expr followed by higher-precedence operator:
|
||||
* consider input like
|
||||
* 3.14 + 2.0 * ...
|
||||
*/
|
||||
|
||||
constexpr const char * c_self_name = "progress_xs::assemble_expr";
|
||||
|
||||
if ((op_type_ != optype::invalid) && (rhs_.get() == nullptr)) {
|
||||
std::string errmsg = tostr("expected expression on rhs of operator op",
|
||||
xtag("lhs", lhs_),
|
||||
xtag("op", op_type_));
|
||||
|
||||
p_psm->on_error(c_self_name, errmsg);
|
||||
}
|
||||
|
||||
/* consecutive expressions not legal, e.g:
|
||||
* 3.14 6.28
|
||||
* but expressions surrounding an infix operators is:
|
||||
* 3.14 / 6.28
|
||||
*/
|
||||
switch (op_type_) {
|
||||
case optype::invalid:
|
||||
return this->lhs_;
|
||||
|
||||
case optype::op_assign:
|
||||
{
|
||||
bp<Variable> lhs = Variable::from(this->lhs_);
|
||||
|
||||
if (!lhs) {
|
||||
throw std::runtime_error
|
||||
(tostr("progress_xs::assemble_expr",
|
||||
" expect variable on lhs of assignment operator :=",
|
||||
xtag("lhs", lhs_),
|
||||
xtag("rhs", rhs_)));
|
||||
}
|
||||
|
||||
return AssignExpr::make(lhs.promote(),
|
||||
this->rhs_);
|
||||
}
|
||||
|
||||
case optype::op_equal:
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_cmp_eq_i64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::op_not_equal:
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_cmp_ne_i64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::op_less:
|
||||
// TODO: floating-point less-than
|
||||
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_cmp_lt_i64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::op_less_equal:
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_cmp_le_i64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::op_great:
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_cmp_gt_i64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::op_great_equal:
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_cmp_ge_i64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
|
||||
case optype::op_add:
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_add2_i64(lhs_, rhs_);
|
||||
} else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) {
|
||||
return Apply::make_add2_f64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case optype::op_subtract:
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_sub2_i64(lhs_, rhs_);
|
||||
} else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) {
|
||||
return Apply::make_sub2_f64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::op_multiply:
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_mul2_i64(lhs_, rhs_);
|
||||
} else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) {
|
||||
return Apply::make_mul2_f64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case optype::op_divide:
|
||||
// TODO: upconvert integer->double
|
||||
if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) {
|
||||
return Apply::make_div2_i64(lhs_, rhs_);
|
||||
} else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) {
|
||||
return Apply::make_div2_f64(lhs_, rhs_);
|
||||
} else {
|
||||
this->apply_type_error(c_self_name,
|
||||
op_type_, lhs_, rhs_, p_psm);
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case optype::n_optype:
|
||||
/* unreachable */
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
progress_xs::on_expr(bp<Expression> expr,
|
||||
parserstatemachine * p_psm)
|
||||
|
|
@ -1216,11 +1049,10 @@ namespace xo {
|
|||
obj<AExpression>
|
||||
assemble_numeric_expr_aux(obj<AAllocator> expr_alloc,
|
||||
const TypeRef::prefix_type & prefix,
|
||||
DPrimitive_gco_2_gco_gco * p_gco_pm,
|
||||
obj<AGCObject> pm_obj,
|
||||
obj<AExpression> lhs,
|
||||
obj<AExpression> rhs)
|
||||
{
|
||||
auto pm_obj = with_facet<AGCObject>::mkobj(p_gco_pm);
|
||||
auto fn_expr = DConstant::make(expr_alloc, pm_obj);
|
||||
|
||||
/* note:
|
||||
|
|
@ -1247,6 +1079,23 @@ namespace xo {
|
|||
tref, fn_expr, lhs, rhs);
|
||||
|
||||
}
|
||||
|
||||
#ifdef OBSOLETE
|
||||
obj<AExpression>
|
||||
assemble_numeric_expr_aux(obj<AAllocator> expr_alloc,
|
||||
const TypeRef::prefix_type & prefix,
|
||||
DPrimitive_gco_2_gco_gco * p_gco_pm,
|
||||
obj<AExpression> lhs,
|
||||
obj<AExpression> rhs)
|
||||
{
|
||||
auto pm_obj = with_facet<AGCObject>::mkobj(p_gco_pm);
|
||||
|
||||
return assemble_numeric_expr_aux(expr_alloc,
|
||||
prefix,
|
||||
pm_obj,
|
||||
lhs, rhs);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
obj<AExpression>
|
||||
|
|
@ -1288,41 +1137,21 @@ namespace xo {
|
|||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_cmpeq_gco"),
|
||||
&NumericPrimitives::s_cmpeq_gco_gco_pm,
|
||||
p_psm->cmpeq_pm(),
|
||||
lhs_, rhs_);
|
||||
|
||||
#ifdef OBSOLETE
|
||||
{
|
||||
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||
(&NumericPrimitives::s_cmpeq_gco_gco_pm));
|
||||
auto fn_expr = (DConstant::make
|
||||
(p_psm->expr_alloc(), pm_obj));
|
||||
|
||||
// see note on op_multiply
|
||||
|
||||
TypeRef tref = TypeRef::dwim
|
||||
(TypeRef::prefix_type::from_chars("_equal_gco"),
|
||||
nullptr);
|
||||
|
||||
return DApplyExpr::make2(p_psm->expr_alloc(),
|
||||
tref,
|
||||
fn_expr, lhs_, rhs_);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case optype::op_not_equal:
|
||||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_cmpne_gco"),
|
||||
&NumericPrimitives::s_cmpne_gco_gco_pm,
|
||||
p_psm->cmpne_pm(),
|
||||
lhs_, rhs_);
|
||||
|
||||
case optype::op_less:
|
||||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_cmplt_gco"),
|
||||
&NumericPrimitives::s_cmplt_gco_gco_pm,
|
||||
p_psm->cmplt_pm(),
|
||||
lhs_, rhs_);
|
||||
|
||||
case optype::op_less_equal:
|
||||
|
|
@ -1335,45 +1164,18 @@ namespace xo {
|
|||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_mul_gco"),
|
||||
&NumericPrimitives::s_mul_gco_gco_pm,
|
||||
p_psm->multiply_pm(), //&NumericPrimitives::s_mul_gco_gco_pm
|
||||
lhs_, rhs_);
|
||||
|
||||
#ifdef OBSOLETE
|
||||
{
|
||||
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||
(&NumericPrimitives::s_mul_gco_gco_pm));
|
||||
auto fn_expr = (DConstant::make
|
||||
(p_psm->expr_alloc(), pm_obj));
|
||||
|
||||
/* note:
|
||||
* 1. don't assume we know lhs_ / rhs_ value types yet.
|
||||
* perhaps have expression like
|
||||
* f(..) * g(..)
|
||||
* where f is the function that contains current ssm.
|
||||
*
|
||||
* 2. consequence: we need representation for
|
||||
* polymorphic multiply on unknown numeric arguments.
|
||||
*
|
||||
* 3. TypeRef::dwim(..) is a placeholder.
|
||||
* Plan to later provide abstract interpreter
|
||||
* (ie compiler pass :) to drive type inference/unification
|
||||
*
|
||||
* 4. Alternatively could supply type-annotation syntax
|
||||
* so human can assist inference; context here is we want
|
||||
* to automate the boring stuff
|
||||
*/
|
||||
|
||||
TypeRef tref = TypeRef::dwim
|
||||
(TypeRef::prefix_type::from_chars("_mul_gco"),
|
||||
nullptr);
|
||||
|
||||
return DApplyExpr::make2(p_psm->expr_alloc(),
|
||||
tref, fn_expr, lhs_, rhs_);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
case optype::op_divide:
|
||||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_div_gco"),
|
||||
p_psm->divide_pm(), // &NumericPrimitives::s_div_gco_gco_pm
|
||||
lhs_, rhs_);
|
||||
|
||||
#ifdef OBSOLETE
|
||||
{
|
||||
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||
(&NumericPrimitives::s_div_gco_gco_pm));
|
||||
|
|
@ -1405,10 +1207,17 @@ namespace xo {
|
|||
return DApplyExpr::make2(p_psm->expr_alloc(),
|
||||
tref, fn_expr, lhs_, rhs_);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case optype::op_add:
|
||||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_add_gco"),
|
||||
p_psm->add_pm(),
|
||||
lhs_, rhs_);
|
||||
#ifdef OBSOLETE
|
||||
{
|
||||
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||
(&NumericPrimitives::s_add_gco_gco_pm));
|
||||
|
|
@ -1440,10 +1249,18 @@ namespace xo {
|
|||
return DApplyExpr::make2(p_psm->expr_alloc(),
|
||||
tref, fn_expr, lhs_, rhs_);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case optype::op_subtract: /* editor bait: op_minus */
|
||||
return assemble_numeric_expr_aux
|
||||
(p_psm->expr_alloc(),
|
||||
TypeRef::prefix_type::from_chars("_sub_gco"),
|
||||
p_psm->subtract_pm(),
|
||||
lhs_, rhs_);
|
||||
|
||||
#ifdef OBSOLETE
|
||||
{
|
||||
auto pm_obj = (with_facet<AGCObject>::mkobj
|
||||
(&NumericPrimitives::s_sub_gco_gco_pm));
|
||||
|
|
@ -1459,6 +1276,7 @@ namespace xo {
|
|||
return DApplyExpr::make2(p_psm->expr_alloc(),
|
||||
tref, fn_expr, lhs_, rhs_);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@
|
|||
#include "SyntaxStateMachine.hpp"
|
||||
#include "ToplevelSeqSsm.hpp"
|
||||
#include "DefineSsm.hpp"
|
||||
#include <xo/procedure2/PrimitiveRegistry.hpp>
|
||||
#include <xo/object2/array/IPrintable_DArray.hpp>
|
||||
#include <xo/printable2/Printable.hpp>
|
||||
#include <xo/alloc2/Collector.hpp>
|
||||
#include <xo/alloc2/arena/IAllocator_DArena.hpp>
|
||||
#include <xo/facet/FacetRegistry.hpp>
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ namespace xo {
|
|||
cfg.symtab_var_config_,
|
||||
cfg.symtab_types_config_,
|
||||
cfg.max_stringtable_capacity_,
|
||||
cfg.pm_install_flags_,
|
||||
expr_alloc,
|
||||
aux_alloc
|
||||
},
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ namespace xo {
|
|||
config.symtab_var_config_,
|
||||
config.symtab_types_config_,
|
||||
config.max_stringtable_cap_,
|
||||
config.pm_install_flags_,
|
||||
config.parser_debug_flag_),
|
||||
expr_alloc,
|
||||
aux_alloc},
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
namespace xo {
|
||||
using xo::print::APrintable;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::facet::FacetRegistry;
|
||||
using xo::facet::TypeRegistry;
|
||||
using xo::facet::typeseq;
|
||||
|
|
@ -43,6 +44,13 @@ namespace xo {
|
|||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
// GlobalEnv
|
||||
|
||||
FacetRegistry::register_impl<AGCObject, DGlobalEnv>();
|
||||
FacetRegistry::register_impl<APrintable, DGlobalEnv>();
|
||||
|
||||
// SyntaxStateMachine
|
||||
|
||||
FacetRegistry::register_impl<ASyntaxStateMachine, DToplevelSeqSsm>();
|
||||
FacetRegistry::register_impl<APrintable, DToplevelSeqSsm>();
|
||||
|
||||
|
|
@ -105,6 +113,7 @@ namespace xo {
|
|||
// misc types showing up in parser stack arena
|
||||
TypeRegistry::register_type<ParserStack>();
|
||||
|
||||
log && log(xtag("DGlobalEnv.tseq", typeseq::id<DGlobalEnv>()));
|
||||
log && log(xtag("DToplevelSeqSsm.tseq", typeseq::id<DToplevelSeqSsm>()));
|
||||
log && log(xtag("DDefineSsm.tseq", typeseq::id<DDefineSsm>()));
|
||||
log && log(xtag("DDeftypeSsm.tseq", typeseq::id<DDeftypeSsm>()));
|
||||
|
|
|
|||
|
|
@ -4,22 +4,25 @@
|
|||
**/
|
||||
|
||||
#include "reader2_register_types.hpp"
|
||||
#include "GlobalEnv.hpp"
|
||||
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::mm::ACollector;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::facet::impl_for;
|
||||
using xo::scope;
|
||||
|
||||
namespace scm {
|
||||
bool
|
||||
reader2_register_types(obj<ACollector> /*gc*/)
|
||||
reader2_register_types(obj<ACollector> gc)
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* no gc-aware types yet; scaffold for future use */
|
||||
ok &= gc.install_type(impl_for<AGCObject, DGlobalEnv>());
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue