From b811e340901ec1c672d44e8e4e43aafba232767f Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 27 Jul 2025 14:32:31 -0400 Subject: [PATCH] xo-expression xo-reader: integer comparisons !=, <, > --- xo-expression/include/xo/expression/Apply.hpp | 6 +++ .../include/xo/expression/Primitive.hpp | 4 ++ xo-expression/src/expression/Apply.cpp | 16 ++++++++ xo-expression/src/expression/Primitive.cpp | 38 +++++++++++++++++++ xo-reader/src/reader/exprstate.cpp | 3 ++ xo-reader/src/reader/progress_xs.cpp | 35 ++++++++++++++++- 6 files changed, 101 insertions(+), 1 deletion(-) diff --git a/xo-expression/include/xo/expression/Apply.hpp b/xo-expression/include/xo/expression/Apply.hpp index aae28585..69e830c4 100644 --- a/xo-expression/include/xo/expression/Apply.hpp +++ b/xo-expression/include/xo/expression/Apply.hpp @@ -34,6 +34,12 @@ namespace xo { /** create apply-expression to compare two 64-bit integers **/ static rp make_cmp_ne_i64(const rp & lhs, const rp & rhs); + /** create apply-expression for less-than comparison of two 64-bit integers **/ + static rp make_cmp_lt_i64(const rp & lhs, + const rp & rhs); + /** create apply-expression for greater-than comparison of two 64-bit integers **/ + static rp make_cmp_gt_i64(const rp & lhs, + const rp & rhs); /** create apply-expression to add two 64-bit integers **/ static rp make_add2_i64(const rp & lhs, diff --git a/xo-expression/include/xo/expression/Primitive.hpp b/xo-expression/include/xo/expression/Primitive.hpp index cb940092..e2283f33 100644 --- a/xo-expression/include/xo/expression/Primitive.hpp +++ b/xo-expression/include/xo/expression/Primitive.hpp @@ -204,6 +204,10 @@ namespace xo { static rp make_cmp_eq2_i64(); /** ne2_i64: compare two 64-bit integers for inequality **/ static rp make_cmp_ne2_i64(); + /** lt2_i64: compare two 64-bit integers for lessthan **/ + static rp make_cmp_lt2_i64(); + /** gt2_i64: compare two 64-bit integers for greaterthan **/ + static rp make_cmp_gt2_i64(); }; /** builtin primitives :: i64 x i64 -> i64 **/ diff --git a/xo-expression/src/expression/Apply.cpp b/xo-expression/src/expression/Apply.cpp index d3403784..3dfc5a6c 100644 --- a/xo-expression/src/expression/Apply.cpp +++ b/xo-expression/src/expression/Apply.cpp @@ -48,6 +48,22 @@ namespace xo { {lhs, rhs}); } + rp + Apply::make_cmp_lt_i64(const rp & lhs, + const rp & rhs) + { + return Apply::make(Primitive_cmp_i64::make_cmp_lt2_i64(), + {lhs, rhs}); + } + + rp + Apply::make_cmp_gt_i64(const rp & lhs, + const rp & rhs) + { + return Apply::make(Primitive_cmp_i64::make_cmp_gt2_i64(), + {lhs, rhs}); + } + // ----- integer arithmetic ----- rp diff --git a/xo-expression/src/expression/Primitive.cpp b/xo-expression/src/expression/Primitive.cpp index db44d820..cafaffb1 100644 --- a/xo-expression/src/expression/Primitive.cpp +++ b/xo-expression/src/expression/Primitive.cpp @@ -22,6 +22,16 @@ extern "C" { return x != y; } + bool + cmp_lt2_i64(std::int64_t x, std::int64_t y) { + return x < y; + } + + bool + cmp_gt2_i64(std::int64_t x, std::int64_t y) { + return x > y; + } + std::int64_t add2_i64(std::int64_t x, std::int64_t y) { return x + y; @@ -93,6 +103,34 @@ namespace xo { return s_retval; } + auto + Primitive_cmp_i64::make_cmp_lt2_i64() -> rp + { + static rp s_retval; + + if (!s_retval) + s_retval = Primitive::make("cmp_lt2_i64", + &cmp_lt2_i64, + true /*explicit_symbol_def*/, + llvmintrinsic::i_slt); + + return s_retval; + } + + auto + Primitive_cmp_i64::make_cmp_gt2_i64() -> rp + { + static rp s_retval; + + if (!s_retval) + s_retval = Primitive::make("cmp_gt2_i64", + &cmp_gt2_i64, + true /*explicit_symbol_def*/, + llvmintrinsic::i_sgt); + + return s_retval; + } + /* TODO: remaining integer arithmetic */ auto diff --git a/xo-reader/src/reader/exprstate.cpp b/xo-reader/src/reader/exprstate.cpp index a9642063..00fb7b78 100644 --- a/xo-reader/src/reader/exprstate.cpp +++ b/xo-reader/src/reader/exprstate.cpp @@ -418,6 +418,9 @@ namespace xo { case tokentype::tk_leftangle: case tokentype::tk_rightangle: + this->on_operator_token(tk, p_psm); + return; + case tokentype::tk_dot: assert(false); return; diff --git a/xo-reader/src/reader/progress_xs.cpp b/xo-reader/src/reader/progress_xs.cpp index 150e092e..b3c7490a 100644 --- a/xo-reader/src/reader/progress_xs.cpp +++ b/xo-reader/src/reader/progress_xs.cpp @@ -182,12 +182,41 @@ namespace xo { } case optype::op_equal: - return Apply::make_cmp_eq_i64(lhs_, rhs_); + 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_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: case optype::op_not_equal: + assert(false); + 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: assert(false); @@ -532,6 +561,10 @@ namespace xo { return optype::op_equal; case tokentype::tk_cmpne: return optype::op_not_equal; + case tokentype::tk_leftangle: + return optype::op_less; + case tokentype::tk_rightangle: + return optype::op_great; default: assert(false); return optype::invalid;