xo-expression: less-than-or-equal

This commit is contained in:
Roland Conybeare 2025-07-27 18:19:54 -04:00
commit 813407310c
9 changed files with 93 additions and 14 deletions

View file

@ -37,6 +37,9 @@ namespace xo {
/** create apply-expression for less-than comparison of two 64-bit integers **/
static rp<Apply> make_cmp_lt_i64(const rp<Expression> & lhs,
const rp<Expression> & rhs);
/** create apply-expression for less-than-or-equal comparison of two 64-bit integers **/
static rp<Apply> make_cmp_le_i64(const rp<Expression> & lhs,
const rp<Expression> & rhs);
/** create apply-expression for greater-than comparison of two 64-bit integers **/
static rp<Apply> make_cmp_gt_i64(const rp<Expression> & lhs,
const rp<Expression> & rhs);

View file

@ -206,6 +206,8 @@ namespace xo {
static rp<PrimitiveType> make_cmp_ne2_i64();
/** lt2_i64: compare two 64-bit integers for lessthan **/
static rp<PrimitiveType> make_cmp_lt2_i64();
/** lt2_i64: compare two 64-bit integers for lessthanorequal **/
static rp<PrimitiveType> make_cmp_le2_i64();
/** gt2_i64: compare two 64-bit integers for greaterthan **/
static rp<PrimitiveType> make_cmp_gt2_i64();
};

View file

@ -56,6 +56,14 @@ namespace xo {
{lhs, rhs});
}
rp<Apply>
Apply::make_cmp_le_i64(const rp<Expression> & lhs,
const rp<Expression> & rhs)
{
return Apply::make(Primitive_cmp_i64::make_cmp_le2_i64(),
{lhs, rhs});
}
rp<Apply>
Apply::make_cmp_gt_i64(const rp<Expression> & lhs,
const rp<Expression> & rhs)

View file

@ -27,6 +27,11 @@ extern "C" {
return x < y;
}
bool
cmp_le2_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;
@ -117,6 +122,20 @@ namespace xo {
return s_retval;
}
auto
Primitive_cmp_i64::make_cmp_le2_i64() -> rp<PrimitiveType>
{
static rp<PrimitiveType> s_retval;
if (!s_retval)
s_retval = Primitive::make("cmp_le2_i64",
&cmp_le2_i64,
true /*explicit_symbol_def*/,
llvmintrinsic::i_sle);
return s_retval;
}
auto
Primitive_cmp_i64::make_cmp_gt2_i64() -> rp<PrimitiveType>
{

View file

@ -418,6 +418,8 @@ namespace xo {
case tokentype::tk_leftangle:
case tokentype::tk_rightangle:
case tokentype::tk_lessequal:
case tokentype::tk_greatequal:
this->on_operator_token(tk, p_psm);
return;

View file

@ -218,6 +218,15 @@ namespace xo {
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:
@ -563,8 +572,12 @@ namespace xo {
return optype::op_not_equal;
case tokentype::tk_leftangle:
return optype::op_less;
case tokentype::tk_lessequal:
return optype::op_less_equal;
case tokentype::tk_rightangle:
return optype::op_great;
case tokentype::tk_greatequal:
return optype::op_great_equal;
default:
assert(false);
return optype::invalid;

View file

@ -186,13 +186,6 @@ namespace xo {
bool
tokenizer<CharT>::is_1char_punctuation(CharT ch) const {
switch(ch) {
case '<':
return true;
case '>':
/* can't be punctuation
* - appears in tk_yields token: ->
*/
return false;
case '(':
return true;
case ')':
@ -205,6 +198,14 @@ namespace xo {
return true;
case '}':
return true;
case '<':
/* can't be 1char punctuation -- can begin lessequal token */
return false;
case '>':
/* can't be 1char punctuation -- can begin greatequal token,
* and appears in tk_yields token
*/
return false;
case ',':
return true;
case ';':
@ -249,6 +250,12 @@ namespace xo {
*/
switch(ch) {
case '<':
/* can begin <= */
return true;
case '>':
/* can begin >= */
return true;
case ':':
/* can begin := */
return true;
@ -621,13 +628,33 @@ namespace xo {
break;
}
case '<':
tk_type = tokentype::tk_leftangle;
++ix;
{
log && log("leftangle or lessequal token");
if (*(ix + 1) == '=') {
tk_type = tokentype::tk_lessequal;
++ix;
++ix;
} else {
tk_type = tokentype::tk_leftangle;
++ix;
}
break;
}
case '>':
tk_type = tokentype::tk_rightangle;
++ix;
{
log && log("rightangle or greatequal token");
if (*(ix + 1) == '=') {
tk_type = tokentype::tk_greatequal;
++ix;
++ix;
} else {
tk_type = tokentype::tk_rightangle;
++ix;
}
break;
}
case '(':
tk_type = tokentype::tk_leftparen;
++ix;
@ -683,9 +710,6 @@ namespace xo {
(error_type(__FUNCTION__ /*src_function*/,
"illegal input character",
input_state_,
//current_line_,
//current_pos_,
//initial_whitespace,
(ix - tk_start)));
}

View file

@ -88,6 +88,12 @@ namespace xo {
/** right-hand angle bracket @c '>' **/
tk_rightangle,
/** less-equal @c '<=' **/
tk_lessequal,
/** great-equal @c '>=' **/
tk_greatequal,
/** dot @c '.' **/
tk_dot,

View file

@ -28,6 +28,8 @@ namespace xo {
CASE(tk_leftangle);
CASE(tk_rightangle);
CASE(tk_lessequal);
CASE(tk_greatequal);
CASE(tk_dot);
CASE(tk_comma);
CASE(tk_colon);