diff --git a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp index 40ccb834..c258cdd6 100644 --- a/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/VirtualSchematikaMachine.cpp @@ -132,7 +132,9 @@ namespace xo { VsmResult evalresult = this->start_eval(expr); - if (evalresult.is_eval_error() || evalresult.is_tk_error()) { + if (evalresult.is_tk_error()) { + // TODO: print error here + return VsmResultExt(evalresult, remaining); } diff --git a/xo-numeric/include/xo/numeric/FloatIntegerOps.hpp b/xo-numeric/include/xo/numeric/FloatIntegerOps.hpp index 5cf301ad..0ee99710 100644 --- a/xo-numeric/include/xo/numeric/FloatIntegerOps.hpp +++ b/xo-numeric/include/xo/numeric/FloatIntegerOps.hpp @@ -30,6 +30,8 @@ namespace xo { static obj cmp_equal(obj rcx, DFloat * x, DInteger * y); + static obj cmp_notequal(obj rcx, + DFloat * x, DInteger * y); }; class IntegerFloatOps { @@ -48,6 +50,8 @@ namespace xo { static obj cmp_equal(obj rcx, DInteger * x, DFloat * y); + static obj cmp_notequal(obj rcx, + DInteger * x, DFloat * y); }; } diff --git a/xo-numeric/include/xo/numeric/FloatOps.hpp b/xo-numeric/include/xo/numeric/FloatOps.hpp index 5f7d06be..88b56442 100644 --- a/xo-numeric/include/xo/numeric/FloatOps.hpp +++ b/xo-numeric/include/xo/numeric/FloatOps.hpp @@ -29,6 +29,8 @@ namespace xo { static obj cmp_equal(obj rcx, DFloat * x, DFloat * y); + static obj cmp_notequal(obj rcx, + DFloat * x, DFloat * y); }; } diff --git a/xo-numeric/include/xo/numeric/IntegerOps.hpp b/xo-numeric/include/xo/numeric/IntegerOps.hpp index 001a915f..09306522 100644 --- a/xo-numeric/include/xo/numeric/IntegerOps.hpp +++ b/xo-numeric/include/xo/numeric/IntegerOps.hpp @@ -31,6 +31,8 @@ namespace xo { static obj cmp_equal(obj rcx, DInteger * x, DInteger * y); + static obj cmp_notequal(obj rcx, + DInteger * x, DInteger * y); }; diff --git a/xo-numeric/include/xo/numeric/NumericDispatch.hpp b/xo-numeric/include/xo/numeric/NumericDispatch.hpp index 58d06565..c40f8155 100644 --- a/xo-numeric/include/xo/numeric/NumericDispatch.hpp +++ b/xo-numeric/include/xo/numeric/NumericDispatch.hpp @@ -25,6 +25,7 @@ namespace xo { using typeseq = xo::reflect::typeseq; using KeyType = std::pair; using MappedType = AnonymizedNumericOps; + using BinaryOp = AnonymizedNumericOps::BinaryOp; /** hash function for key_type **/ struct KeyHash { @@ -58,6 +59,16 @@ namespace xo { return s_instance; } + /** multi-dispatch driver. + * Invoke @p member_ptr in AnonymizedNumericOps + **/ + static obj dispatch(obj rcx, + const char * caller, + const char * error_headline, + BinaryOp AnonymizedNumericOps::* member_ptr, + obj x, + obj y); + /** multiply w/ runtime polymorphism (double-dispatch) **/ static obj multiply(obj rcx, @@ -87,6 +98,11 @@ namespace xo { obj x, obj y); + /** compare two numeric values for inequality **/ + static obj cmp_notequal(obj rcx, + obj x, + obj y); + /** report memory use for owned arenas to @p visitor **/ void visit_pools(const MemorySizeVisitor & visitor); @@ -100,7 +116,8 @@ namespace xo { typename NumericOps::BinaryOp_Impl div_fn, typename NumericOps::BinaryOp_Impl add_fn, typename NumericOps::BinaryOp_Impl sub_fn, - typename NumericOps::BinaryOp_Impl cmpeq_fn) { + typename NumericOps::BinaryOp_Impl cmpeq_fn, + typename NumericOps::BinaryOp_Impl cmpne_fn) { KeyType key(typeseq::id().seqno(), typeseq::id().seqno()); @@ -111,7 +128,8 @@ namespace xo { div_fn, add_fn, sub_fn, - cmpeq_fn); + cmpeq_fn, + cmpne_fn); } private: diff --git a/xo-numeric/include/xo/numeric/NumericOps.hpp b/xo-numeric/include/xo/numeric/NumericOps.hpp index f85b20f4..6d888434 100644 --- a/xo-numeric/include/xo/numeric/NumericOps.hpp +++ b/xo-numeric/include/xo/numeric/NumericOps.hpp @@ -26,9 +26,10 @@ namespace xo { BinaryOp divide, BinaryOp add, BinaryOp subtract, - BinaryOp cmpeq) + BinaryOp cmpeq, + BinaryOp cmpne) : multiply_{multiply}, divide_{divide}, add_{add}, subtract_{subtract}, - cmpeq_{cmpeq} {} + cmpeq_{cmpeq}, cmpne_{cmpne} {} BinaryOp multiply_ = nullptr; BinaryOp divide_ = nullptr; @@ -37,6 +38,8 @@ namespace xo { /** compare numerics for equality **/ BinaryOp cmpeq_ = nullptr; + /** compare numerics for inequality **/ + BinaryOp cmpne_ = nullptr; }; template @@ -52,12 +55,14 @@ namespace xo { BinaryOp_Impl divide, BinaryOp_Impl add, BinaryOp_Impl subtract, - BinaryOp_Impl cmpeq) { + BinaryOp_Impl cmpeq, + BinaryOp_Impl cmpne) { return AnonymizedNumericOps(reinterpret_cast(multiply), reinterpret_cast(divide), reinterpret_cast(add), reinterpret_cast(subtract), - reinterpret_cast(cmpeq)); + reinterpret_cast(cmpeq), + reinterpret_cast(cmpne)); } }; diff --git a/xo-numeric/include/xo/numeric/NumericPrimitives.hpp b/xo-numeric/include/xo/numeric/NumericPrimitives.hpp index 8f9c40db..a2cc3cdb 100644 --- a/xo-numeric/include/xo/numeric/NumericPrimitives.hpp +++ b/xo-numeric/include/xo/numeric/NumericPrimitives.hpp @@ -25,6 +25,8 @@ namespace xo { /** polymorphic (in both arguments) compare (==) **/ static DPrimitive_gco_2_gco_gco s_cmpeq_gco_gco_pm; + /** polymorphic (in both arguments) compare (!=) **/ + static DPrimitive_gco_2_gco_gco s_cmpne_gco_gco_pm; }; } } diff --git a/xo-numeric/src/numeric/FloatIntegerOps.cpp b/xo-numeric/src/numeric/FloatIntegerOps.cpp index 476a6745..f82e10dc 100644 --- a/xo-numeric/src/numeric/FloatIntegerOps.cpp +++ b/xo-numeric/src/numeric/FloatIntegerOps.cpp @@ -50,6 +50,14 @@ namespace xo { x->value() == DFloat::value_type(y->value())); } + obj + FloatIntegerOps::cmp_notequal(obj rcx, + DFloat * x, DInteger * y) + { + return DBoolean::box(rcx.allocator(), + x->value() != DFloat::value_type(y->value())); + } + // ----- Integer op Float ----- obj @@ -84,8 +92,16 @@ namespace xo { IntegerFloatOps::cmp_equal(obj rcx, DInteger * x, DFloat * y) { - return DFloat::box(rcx.allocator(), - DFloat::value_type(x->value() == y->value())); + return DBoolean::box(rcx.allocator(), + DFloat::value_type(x->value()) == y->value()); + } + + obj + IntegerFloatOps::cmp_notequal(obj rcx, + DInteger * x, DFloat * y) + { + return DBoolean::box(rcx.allocator(), + DFloat::value_type(x->value()) != y->value()); } } diff --git a/xo-numeric/src/numeric/FloatOps.cpp b/xo-numeric/src/numeric/FloatOps.cpp index d0aa57aa..6f984728 100644 --- a/xo-numeric/src/numeric/FloatOps.cpp +++ b/xo-numeric/src/numeric/FloatOps.cpp @@ -47,6 +47,13 @@ namespace xo { return DBoolean::box(rcx.allocator(), x->value() == y->value()); } + obj + FloatOps::cmp_notequal(obj rcx, + DFloat * x, DFloat * y) + { + return DBoolean::box(rcx.allocator(), x->value() != y->value()); + } + } } diff --git a/xo-numeric/src/numeric/IntegerOps.cpp b/xo-numeric/src/numeric/IntegerOps.cpp index 062cbeef..31f9110d 100644 --- a/xo-numeric/src/numeric/IntegerOps.cpp +++ b/xo-numeric/src/numeric/IntegerOps.cpp @@ -48,6 +48,13 @@ namespace xo { return DBoolean::box(rcx.allocator(), x->value() == y->value()); } + obj + IntegerOps::cmp_notequal(obj rcx, + DInteger * x, DInteger * y) + { + return DBoolean::box(rcx.allocator(), x->value() != y->value()); + } + } } diff --git a/xo-numeric/src/numeric/NumericDispatch.cpp b/xo-numeric/src/numeric/NumericDispatch.cpp index 935d92eb..a40c0efc 100644 --- a/xo-numeric/src/numeric/NumericDispatch.cpp +++ b/xo-numeric/src/numeric/NumericDispatch.cpp @@ -4,10 +4,13 @@ **/ #include "NumericDispatch.hpp" +#include +#include #include namespace xo { using xo::mm::AGCObject; + using xo::facet::TypeRegistry; namespace scm { @@ -17,6 +20,35 @@ namespace xo { dispatch_.visit_pools(visitor); } + obj + NumericDispatch::dispatch(obj rcx, + const char * caller, + const char * error_headline, + BinaryOp AnonymizedNumericOps::* member_ptr, + obj x, + obj y) + { + KeyType key(x._typeseq(), y._typeseq()); + + auto target_fn + = NumericDispatch::instance().dispatch_[key].*member_ptr; + + if (!target_fn) { + // FIXME: use {fmt} here + std::stringstream ss; + tosn(ss, + error_headline, + xtag("x.type", TypeRegistry::id2name(x._typeseq())), + xtag("y.type", TypeRegistry::id2name(y._typeseq()))); + + return DRuntimeError::make(rcx.allocator(), + caller, + ss.str().c_str()); + } + + return (*target_fn)(rcx, x.data(), y.data()); + } + obj NumericDispatch::multiply(obj rcx, obj x, @@ -91,12 +123,56 @@ namespace xo { auto target_fn = NumericDispatch::instance().dispatch_[key].cmpeq_; - if (!target_fn) - assert(false); + if (!target_fn) { + // FIXME: use {fmt} here + std::stringstream ss; + tosn(ss, + "incomparable types in x==y", + xtag("x.type", TypeRegistry::id2name(x._typeseq())), + xtag("y.type", TypeRegistry::id2name(y._typeseq()))); + + return DRuntimeError::make(rcx.allocator(), + "NumericDispatch::cmp_equal", + ss.str().c_str()); + } return (*target_fn)(rcx, x.data(), y.data()); } + obj + NumericDispatch::cmp_notequal(obj rcx, + obj x, + obj y) + { + return dispatch(rcx, + "NumericDispatch::cmp_notequal", + "incomparable types in x!=y", + &AnonymizedNumericOps::cmpne_, + x, y); + +#ifdef OBSOLETE + KeyType key(x._typeseq(), y._typeseq()); + + auto target_fn + = NumericDispatch::instance().dispatch_[key].cmpne_; + + if (!target_fn) { + // FIXME: use {fmt} here + std::stringstream ss; + tosn(ss, + "incomparable types in x==y", + xtag("x.type", TypeRegistry::id2name(x._typeseq())), + xtag("y.type", TypeRegistry::id2name(y._typeseq()))); + + return DRuntimeError::make(rcx.allocator(), + "NumericDispatch::cmp_notequal", + ss.str().c_str()); + } + + return (*target_fn)(rcx, x.data(), y.data()); +#endif + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-numeric/src/numeric/NumericPrimitives.cpp b/xo-numeric/src/numeric/NumericPrimitives.cpp index 28031fac..eb8ebf83 100644 --- a/xo-numeric/src/numeric/NumericPrimitives.cpp +++ b/xo-numeric/src/numeric/NumericPrimitives.cpp @@ -31,6 +31,10 @@ namespace xo { NumericPrimitives::s_cmpeq_gco_gco_pm("_cmpeq", &NumericDispatch::cmp_equal); + DPrimitive_gco_2_gco_gco + NumericPrimitives::s_cmpne_gco_gco_pm("_cmpne", + &NumericDispatch::cmp_notequal); + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-numeric/src/numeric/numeric_register_facets.cpp b/xo-numeric/src/numeric/numeric_register_facets.cpp index 9cc6e1f9..2bb29401 100644 --- a/xo-numeric/src/numeric/numeric_register_facets.cpp +++ b/xo-numeric/src/numeric/numeric_register_facets.cpp @@ -39,28 +39,32 @@ namespace xo { &FloatOps::divide, &FloatOps::add, &FloatOps::subtract, - &FloatOps::cmp_equal); + &FloatOps::cmp_equal, + &FloatOps::cmp_notequal); NumericDispatch::instance().register_impl (&FloatIntegerOps::multiply, &FloatIntegerOps::divide, &FloatIntegerOps::add, &FloatIntegerOps::subtract, - &FloatIntegerOps::cmp_equal); + &FloatIntegerOps::cmp_equal, + &FloatIntegerOps::cmp_notequal); NumericDispatch::instance().register_impl (&IntegerFloatOps::multiply, &IntegerFloatOps::divide, &IntegerFloatOps::add, &IntegerFloatOps::subtract, - &IntegerFloatOps::cmp_equal); + &IntegerFloatOps::cmp_equal, + &IntegerFloatOps::cmp_notequal); NumericDispatch::instance().register_impl (&IntegerOps::multiply, &IntegerOps::divide, &IntegerOps::add, &IntegerOps::subtract, - &IntegerOps::cmp_equal); + &IntegerOps::cmp_equal, + &IntegerOps::cmp_notequal); log && log(xtag("ANumeric.tseq", typeseq::id())); diff --git a/xo-object2/include/xo/object2/DRuntimeError.hpp b/xo-object2/include/xo/object2/DRuntimeError.hpp index c59de59d..8a0ae33b 100644 --- a/xo-object2/include/xo/object2/DRuntimeError.hpp +++ b/xo-object2/include/xo/object2/DRuntimeError.hpp @@ -42,7 +42,7 @@ namespace xo { /** @defgroup scm-runtimeerror-printable-facet printable facet **/ ///@{ - + bool pretty(const ppindentinfo & ppii) const; ///@} diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index 46321b0a..9907869d 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -303,10 +303,10 @@ namespace xo { case tokentype::tk_plus: case tokentype::tk_minus: case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: this->on_operator_token(tk, p_psm); return; - case tokentype::tk_cmpne: case tokentype::tk_type: case tokentype::tk_lambda: break; @@ -1290,6 +1290,12 @@ namespace xo { #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, + lhs_, rhs_); + case optype::op_less: case optype::op_less_equal: case optype::op_great: