xo-procedure2 xo-object2: + polymorphic primitive support

This commit is contained in:
Roland Conybeare 2026-01-26 12:38:17 -05:00
commit 43a6235439
26 changed files with 268 additions and 45 deletions

View file

@ -7,6 +7,8 @@
#include <xo/gc/GCObject.hpp> #include <xo/gc/GCObject.hpp>
#include <xo/alloc2/Allocator.hpp> #include <xo/alloc2/Allocator.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <xo/facet/obj.hpp>
namespace xo { namespace xo {
namespace scm { namespace scm {
@ -20,10 +22,70 @@ namespace xo {
using AGCObject = xo::mm::AGCObject; using AGCObject = xo::mm::AGCObject;
using AAllocator = xo::mm::AAllocator; using AAllocator = xo::mm::AAllocator;
/** find gc-aware representation for @p x.
* If necessary allocate from @p mm, but may
* refer to @p x in-place
**/
static obj<AGCObject> to_gco(obj<AAllocator> mm, const T & x); static obj<AGCObject> to_gco(obj<AAllocator> mm, const T & x);
/** convert to native representation @tparam T from gc-aware
* @p gco. If necessary allocate from @p mm, but
* may instead refer to @p x in-place
**/
static T from_gco(obj<AAllocator> mm, obj<AGCObject> gco); static T from_gco(obj<AAllocator> mm, obj<AGCObject> gco);
}; };
/** Motivating use-case for GCObjectConversion is to transform
* primitive function arguments and results to/from gc-aware
* representation.
*
* However: Schematika also supports runtime polymorphism
* which leads to primitives that expect obj<AFacet> arguments.
*
* Also, Schematika expression parser needs representation for
* expressions, before type unification.
*
* Consider a function like:
* def fact = lambda (n : i64) { if (n <= 0) then 1 else (n * fact(n - 1)); }
* During expression parsing the rhs argument to multiply has unknown type.
* To construct an expression for input to unification will use polymorphic
* binding for multiply primitive, relying on specialization here for
* its implementation.
**/
template <typename AFacet, typename DRepr>
struct GCObjectConversion<obj<AFacet,DRepr>> {
using AGCObject = xo::mm::AGCObject;
using AAllocator = xo::mm::AAllocator;
using FacetRegistry = xo::facet::FacetRegistry;
using DVariantPlaceholder = xo::facet::DVariantPlaceholder;
static obj<AGCObject> to_gco(obj<AAllocator>,
obj<AFacet,DRepr> gco) {
if constexpr (std::is_same_v<AFacet, AGCObject>) {
// trivial conversion!
return gco;
} else if constexpr (std::is_same_v<DRepr, DVariantPlaceholder>) {
// runtime polymorphism
return FacetRegistry::instance().variant<AGCObject,AFacet>(gco);
} else /* DRepr != DVariantPlaceholder */ {
// known content w/ fat object pointer
return obj<AGCObject,DRepr>(gco.data());
}
}
static obj<AFacet,DRepr> from_gco(obj<AAllocator>,
obj<AGCObject> gco) {
if constexpr (std::is_same_v<AFacet, AGCObject>) {
// trivial conversion
return gco;
} else {
// both runtime and comptime polymorphism
// use same path here, since representation of @p gco
// is type-erased here
return FacetRegistry::instance().variant<AFacet,AGCObject>(gco);
}
}
};
} /*namespace scm */ } /*namespace scm */
} /*namespace xo*/ } /*namespace xo*/

View file

@ -23,7 +23,7 @@ namespace xo {
* fixed at construction time, but not part of type. * fixed at construction time, but not part of type.
* Can reallocate to change * Can reallocate to change
**/ **/
struct DArray { class DArray {
public: public:
/** @defgroup darray-types type traits **/ /** @defgroup darray-types type traits **/
///@{ ///@{

View file

@ -19,7 +19,7 @@ namespace xo {
using AGCObject = xo::mm::AGCObject; using AGCObject = xo::mm::AGCObject;
using AAllocator = xo::mm::AAllocator; using AAllocator = xo::mm::AAllocator;
static obj<AGCObject> to_gco(obj<AAllocator> mm, const double & x); static obj<AGCObject> to_gco(obj<AAllocator> mm, double x);
static double from_gco(obj<AAllocator> mm, obj<AGCObject> gco); static double from_gco(obj<AAllocator> mm, obj<AGCObject> gco);
}; };

View file

@ -0,0 +1,29 @@
/** @file GCObjectConversion_DInteger.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include "DInteger.hpp"
#include "number/IGCObject_DInteger.hpp"
#include <xo/gc/GCObjectConversion.hpp>
namespace xo {
namespace scm {
template <>
struct GCObjectConversion<long> {
static_assert(std::is_same_v<long, DInteger::value_type>);
using AGCObject = xo::mm::AGCObject;
using AAllocator = xo::mm::AAllocator;
static obj<AGCObject> to_gco(obj<AAllocator> mm, long x);
static long from_gco(obj<AAllocator> mm, obj<AGCObject> gco);
};
}
} /*namespace xo*/
/* end GCObjectConversion_DInteger.hpp */

View file

@ -6,6 +6,7 @@ set(SELF_SRCS
object2_register_types.cpp object2_register_types.cpp
object2_register_facets.cpp object2_register_facets.cpp
GCObjectConversion_DFloat.cpp GCObjectConversion_DFloat.cpp
GCObjectConversion_DInteger.cpp
IGCObject_DArray.cpp IGCObject_DArray.cpp
IGCObject_DFloat.cpp IGCObject_DFloat.cpp
IGCObject_DBoolean.cpp IGCObject_DBoolean.cpp

View file

@ -13,7 +13,7 @@ namespace xo {
obj<AGCObject> obj<AGCObject>
GCObjectConversion<double>::to_gco(obj<AAllocator> mm, GCObjectConversion<double>::to_gco(obj<AAllocator> mm,
const double & x) double x)
{ {
return DFloat::box<AGCObject>(mm, x); return DFloat::box<AGCObject>(mm, x);
} }

View file

@ -0,0 +1,41 @@
/** @file GCObjectConversion_DInteger.cpp
*
* @author Roland Conybeare, Jan 2026
**/
#include "number/GCObjectConversion_DInteger.hpp"
#include <xo/indentlog/print/tag.hpp>
namespace xo {
using xo::mm::AGCObject;
namespace scm {
obj<AGCObject>
GCObjectConversion<long>::to_gco(obj<AAllocator> mm,
long x)
{
return DInteger::box<AGCObject>(mm, x);
}
long
GCObjectConversion<long>::from_gco(obj<AAllocator> mm,
obj<AGCObject> gco)
{
(void)mm;
auto int_obj = obj<AGCObject,DInteger>::from(gco);
if (!int_obj) {
throw std::runtime_error
(tostr("Object obj found where Integer expected",
xtag("obj", gco)));
}
return int_obj.data()->value();
}
} /*namespace scm*/
} /*namespace xo*/
/* end GCObjectConversion_DFloat.cpp */

View file

@ -0,0 +1,25 @@
.. _implementation:
.. toctree::
:maxdepth: 2
Components
==========
Library dependency tower for *xo-procedure2*
.. ditaa::
+--------------------------------+
| xo_gc |
+--------------------------------+
| xo_alloc2 |
+--------------------------------+
| xo_facet |
+----------------+---------------+
| xo_reflectutil | xo_indentlog |
+----------------+---------------+
| xo_cmake |
+--------------------------------+
Expect to have xo_facet depending on xo_arena instead of using std::unordered_map

View file

@ -56,7 +56,6 @@
doc: ["invoke procedure; assume arguments satisfy type system" ], doc: ["invoke procedure; assume arguments satisfy type system" ],
return_type: "obj<AGCObject>", return_type: "obj<AGCObject>",
args: [ args: [
{type: "obj<ARuntimeContext>", name: "rcx"},
{type: "const DArray *", name: "args"}, {type: "const DArray *", name: "args"},
] ]
} }

View file

@ -10,6 +10,7 @@
#include <xo/gc/GCObjectConversion.hpp> #include <xo/gc/GCObjectConversion.hpp>
#include <xo/gc/GCObject.hpp> #include <xo/gc/GCObject.hpp>
#include <xo/alloc2/Allocator.hpp> #include <xo/alloc2/Allocator.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
@ -62,24 +63,29 @@ namespace xo {
bool is_nary() const noexcept { return false; } bool is_nary() const noexcept { return false; }
static constexpr std::int32_t n_args() noexcept { return Traits::n_args; } static constexpr std::int32_t n_args() noexcept { return Traits::n_args; }
obj<AGCObject> apply_nocheck(obj<ARuntimeContext> rcx, const DArray * args) { obj<AGCObject> apply_nocheck(const DArray * args) {
return _apply_nocheck(rcx, args, return _apply_nocheck(args,
std::make_index_sequence<Traits::n_args>{}); std::make_index_sequence<Traits::n_args>{});
} }
private: private:
template <std::size_t... Is> template <std::size_t... Is>
obj<AGCObject> _apply_nocheck(obj<ARuntimeContext> rcx, obj<AGCObject> _apply_nocheck(const DArray * args,
const DArray * args,
std::index_sequence<Is...>) std::index_sequence<Is...>)
{ {
using xo::facet::FacetRegistry;
using R = typename Traits::return_type; using R = typename Traits::return_type;
assert(args);
assert(args->size() > 0);
obj<ARuntimeContext> rcx
= FacetRegistry::instance().variant<ARuntimeContext>(args->at(0));
obj<AAllocator> mm = rcx.allocator(); obj<AAllocator> mm = rcx.allocator();
R result R result
= fn_(rcx, = fn_(GCObjectConversion<typename Traits::template arg_type<Is>>::from_gco(mm, args->at(Is))... );
GCObjectConversion<typename Traits::template arg_type<Is>>::from_gco(mm, args->at(Is))... );
return GCObjectConversion<R>::to_gco(mm, result); return GCObjectConversion<R>::to_gco(mm, result);
} }

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/Procedure.json5] * --input [idl/Procedure.json5]
* 2. jinja2 template for facet .hpp file: * 2. jinja2 template for facet .hpp file:

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/RuntimeContext.json5] * --input [idl/RuntimeContext.json5]
* 2. jinja2 template for facet .hpp file: * 2. jinja2 template for facet .hpp file:

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/Procedure.json5] * --input [idl/Procedure.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:
@ -56,7 +56,7 @@ public:
// nonconst methods // nonconst methods
/** invoke procedure; assume arguments satisfy type system **/ /** invoke procedure; assume arguments satisfy type system **/
virtual obj<AGCObject> apply_nocheck(Opaque data, obj<ARuntimeContext> rcx, const DArray * args) = 0; virtual obj<AGCObject> apply_nocheck(Opaque data, const DArray * args) = 0;
///@} ///@}
}; /*AProcedure*/ }; /*AProcedure*/

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/RuntimeContext.json5] * --input [idl/RuntimeContext.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/Procedure.json5] * --input [idl/Procedure.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:
@ -60,7 +60,7 @@ namespace scm {
[[noreturn]] std::int32_t n_args(Copaque) const noexcept override { _fatal(); } [[noreturn]] std::int32_t n_args(Copaque) const noexcept override { _fatal(); }
// nonconst methods // nonconst methods
[[noreturn]] obj<AGCObject> apply_nocheck(Opaque, obj<ARuntimeContext>, const DArray *) override; [[noreturn]] obj<AGCObject> apply_nocheck(Opaque, const DArray *) override;
///@} ///@}

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:
@ -57,7 +57,7 @@ namespace xo {
// non-const methods // non-const methods
/** invoke procedure; assume arguments satisfy type system **/ /** invoke procedure; assume arguments satisfy type system **/
static obj<AGCObject> apply_nocheck(DPrimitive_gco_2_gco_gco & self, obj<ARuntimeContext> rcx, const DArray * args); static obj<AGCObject> apply_nocheck(DPrimitive_gco_2_gco_gco & self, const DArray * args);
///@} ///@}
}; };

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/Procedure.json5] * --input [idl/Procedure.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:
@ -50,8 +50,8 @@ namespace scm {
} }
// non-const methods // non-const methods
obj<AGCObject> apply_nocheck(Opaque data, obj<ARuntimeContext> rcx, const DArray * args) override { obj<AGCObject> apply_nocheck(Opaque data, const DArray * args) override {
return I::apply_nocheck(_dcast(data), rcx, args); return I::apply_nocheck(_dcast(data), args);
} }
///@} ///@}

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/RuntimeContext.json5] * --input [idl/RuntimeContext.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/RuntimeContext.json5] * --input [idl/RuntimeContext.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/Procedure.json5] * --input [idl/Procedure.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:
@ -56,8 +56,8 @@ public:
} }
// non-const methods (still const in router!) // non-const methods (still const in router!)
obj<AGCObject> apply_nocheck(obj<ARuntimeContext> rcx, const DArray * args) { obj<AGCObject> apply_nocheck(const DArray * args) {
return O::iface()->apply_nocheck(O::data(), rcx, args); return O::iface()->apply_nocheck(O::data(), args);
} }
///@} ///@}

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/RuntimeContext.json5] * --input [idl/RuntimeContext.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:

View file

@ -3,13 +3,19 @@
#pragma once #pragma once
#include "DPrimitive.hpp" #include "DPrimitive.hpp"
#include "DPrimitive_gco_2_gco_gco.hpp"
namespace xo { namespace xo {
namespace scm { namespace scm {
#ifdef NOT_YET
using Primitive_f64_1_f64 = Primitive<double (*)(double)>; using Primitive_f64_1_f64 = Primitive<double (*)(double)>;
using Primitive_f64_2_f64_f64 = Primitive<double (*)(double, double)>; using Primitive_f64_2_f64_f64 = Primitive<double (*)(double, double)>;
#endif
struct Primitives { struct Primitives {
static DPrimitive_gco_2_gco_gco s_mul_gco_gco_pm;
#ifdef NOT_YET
static Primitive_f64_1_f64 s_neg_f64_pm; static Primitive_f64_1_f64 s_neg_f64_pm;
static Primitive_f64_2_f64_f64 s_add_f64_f64_pm; static Primitive_f64_2_f64_f64 s_add_f64_f64_pm;
@ -22,6 +28,7 @@ namespace xo {
static Primitive_f64_1_f64 s_sin_f64_pm; static Primitive_f64_1_f64 s_sin_f64_pm;
static Primitive_f64_1_f64 s_cos_f64_pm; static Primitive_f64_1_f64 s_cos_f64_pm;
static Primitive_f64_1_f64 s_tan_f64_pm; static Primitive_f64_1_f64 s_tan_f64_pm;
#endif
}; };
} }
} }

View file

@ -35,7 +35,7 @@ IProcedure_Any::_valid
// nonconst methods // nonconst methods
auto auto
IProcedure_Any::apply_nocheck(Opaque, obj<ARuntimeContext>, const DArray *) -> obj<AGCObject> IProcedure_Any::apply_nocheck(Opaque, const DArray *) -> obj<AGCObject>
{ {
_fatal(); _fatal();
} }

View file

@ -2,7 +2,7 @@
* *
* Generated automagically from ingredients: * Generated automagically from ingredients:
* 1. code generator: * 1. code generator:
* [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
* arguments: * arguments:
* --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5] * --input [idl/IProcedure_DPrimitive_gco_2_gco_gco.json5]
* 2. jinja2 template for abstract facet .hpp file: * 2. jinja2 template for abstract facet .hpp file:
@ -28,9 +28,9 @@ namespace xo {
} }
auto auto
IProcedure_DPrimitive_gco_2_gco_gco::apply_nocheck(DPrimitive_gco_2_gco_gco & self, obj<ARuntimeContext> rcx, const DArray * args) -> obj<AGCObject> IProcedure_DPrimitive_gco_2_gco_gco::apply_nocheck(DPrimitive_gco_2_gco_gco & self, const DArray * args) -> obj<AGCObject>
{ {
return self.apply_nocheck(rcx, args); return self.apply_nocheck(args);
} }
} /*namespace scm*/ } /*namespace scm*/

View file

@ -5,10 +5,23 @@
#include "init_primitives.hpp" #include "init_primitives.hpp"
#include "DPrimitive.hpp" #include "DPrimitive.hpp"
#include <xo/object2/DFloat.hpp>
#include <xo/object2/number/IGCObject_DFloat.hpp>
#include <xo/object2/DInteger.hpp>
#include <xo/object2/number/IGCObject_DInteger.hpp>
#include <xo/gc/GCObjectConversion.hpp>
#include <xo/object2/number/GCObjectConversion_DFloat.hpp>
#include <xo/object2/number/GCObjectConversion_DInteger.hpp>
#include <xo/facet/facet.hpp>
#include <cmath> #include <cmath>
namespace xo { namespace xo {
using xo::mm::AAllocator;
using xo::scm::DFloat;
using xo::facet::with_facet;
namespace scm { namespace scm {
#ifdef NOT_YET
double double
neg_f64(double x) { neg_f64(double x) {
return -x; return -x;
@ -23,11 +36,17 @@ namespace xo {
sub_f64_f64(double x, double y) { sub_f64_f64(double x, double y) {
return x - y; return x - y;
} }
#endif
#ifdef NOT_YET
obj<AGCObject> obj<AGCObject>
mul_any_any(obj<AGCObject> x_gco, obj<AGCObject> y_gco) mul_gco_gco(obj<ARuntimeContext> rcx,
obj<AGCObject> x_gco,
obj<AGCObject> y_gco)
{ {
using xo::reflect::typeseq;
obj<AAllocator> mm = rcx.allocator();
// PLACEHOLDER // PLACEHOLDER
// TODO: // TODO:
@ -44,20 +63,45 @@ namespace xo {
// FOR NOW: just test runtime values // FOR NOW: just test runtime values
// //
if (x_tseq == typeseq::id<DFloat>()) { if (x_tseq == typeseq::id<DInteger>()) {
if (y_tseq == typeseq::id<DFloat>()) { // i64 * ..
// unusable placeholder allocator; long x = GCObjectConversion<long>::from_gco(mm, x_gco);
obj<AAllocator> placeholder_mm;
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. // f64 * f64.
double x = GCObjectConversion<double>::from_gco(placeholder_mm, x_gco); double x = GCObjectConversion<double>::from_gco(mm, x_gco);
double y = GCObjectConversion<double>::from_gco(placeholder_mm, y_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 double
mul_f64_f64(double x, double y) { mul_f64_f64(double x, double y) {
return x * y; return x * y;
@ -92,7 +136,12 @@ namespace xo {
tan_f64(double x) { tan_f64(double x) {
return ::tan(x); return ::tan(x);
} }
#endif
DPrimitive_gco_2_gco_gco
Primitives::s_mul_gco_gco_pm("_mul", &mul_gco_gco);
#ifdef NOT_YET
Primitive_f64_1_f64 Primitive_f64_1_f64
Primitives::s_neg_f64_pm("_neg_d", Primitives::s_neg_f64_pm("_neg_d",
&neg_f64); &neg_f64);
@ -123,6 +172,7 @@ namespace xo {
Primitive_f64_1_f64 Primitive_f64_1_f64
Primitives::s_tan_f64_pm("_tan_d", &tan_f64); Primitives::s_tan_f64_pm("_tan_d", &tan_f64);
#endif
} /*namespace scm*/ } /*namespace scm*/
} /*namespace xo*/ } /*namespace xo*/

View file

@ -226,8 +226,11 @@ namespace xo {
case tokentype::tk_minus: case tokentype::tk_minus:
break; break;
case tokentype::tk_star: case tokentype::tk_star:
#ifdef NOT_YET
this->on_operator_token(tk, p_psm); this->on_operator_token(tk, p_psm);
return; return;
#endif
break;
case tokentype::tk_slash: case tokentype::tk_slash:
case tokentype::tk_cmpeq: case tokentype::tk_cmpeq:
case tokentype::tk_cmpne: case tokentype::tk_cmpne: