diff --git a/xo-expression/include/xo/expression/Apply.hpp b/xo-expression/include/xo/expression/Apply.hpp index 69e830c4..f01fe2a5 100644 --- a/xo-expression/include/xo/expression/Apply.hpp +++ b/xo-expression/include/xo/expression/Apply.hpp @@ -37,6 +37,9 @@ namespace xo { /** 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 less-than-or-equal comparison of two 64-bit integers **/ + static rp make_cmp_le_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); diff --git a/xo-expression/include/xo/expression/Primitive.hpp b/xo-expression/include/xo/expression/Primitive.hpp index e2283f33..619d943e 100644 --- a/xo-expression/include/xo/expression/Primitive.hpp +++ b/xo-expression/include/xo/expression/Primitive.hpp @@ -206,6 +206,8 @@ namespace xo { static rp make_cmp_ne2_i64(); /** lt2_i64: compare two 64-bit integers for lessthan **/ static rp make_cmp_lt2_i64(); + /** lt2_i64: compare two 64-bit integers for lessthanorequal **/ + static rp make_cmp_le2_i64(); /** gt2_i64: compare two 64-bit integers for greaterthan **/ static rp make_cmp_gt2_i64(); }; diff --git a/xo-expression/src/expression/Apply.cpp b/xo-expression/src/expression/Apply.cpp index 3dfc5a6c..70f4bf95 100644 --- a/xo-expression/src/expression/Apply.cpp +++ b/xo-expression/src/expression/Apply.cpp @@ -56,6 +56,14 @@ namespace xo { {lhs, rhs}); } + rp + Apply::make_cmp_le_i64(const rp & lhs, + const rp & rhs) + { + return Apply::make(Primitive_cmp_i64::make_cmp_le2_i64(), + {lhs, rhs}); + } + rp Apply::make_cmp_gt_i64(const rp & lhs, const rp & rhs) diff --git a/xo-expression/src/expression/Primitive.cpp b/xo-expression/src/expression/Primitive.cpp index cafaffb1..234edd88 100644 --- a/xo-expression/src/expression/Primitive.cpp +++ b/xo-expression/src/expression/Primitive.cpp @@ -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 + { + static rp 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 { diff --git a/xo-reader/src/reader/exprstate.cpp b/xo-reader/src/reader/exprstate.cpp index 00fb7b78..f7d25dcc 100644 --- a/xo-reader/src/reader/exprstate.cpp +++ b/xo-reader/src/reader/exprstate.cpp @@ -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; diff --git a/xo-reader/src/reader/progress_xs.cpp b/xo-reader/src/reader/progress_xs.cpp index b3c7490a..8e90b8e5 100644 --- a/xo-reader/src/reader/progress_xs.cpp +++ b/xo-reader/src/reader/progress_xs.cpp @@ -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; diff --git a/xo-tokenizer/include/xo/tokenizer/tokenizer.hpp b/xo-tokenizer/include/xo/tokenizer/tokenizer.hpp index ab4a9d6d..7984126c 100644 --- a/xo-tokenizer/include/xo/tokenizer/tokenizer.hpp +++ b/xo-tokenizer/include/xo/tokenizer/tokenizer.hpp @@ -186,13 +186,6 @@ namespace xo { bool tokenizer::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))); } diff --git a/xo-tokenizer/include/xo/tokenizer/tokentype.hpp b/xo-tokenizer/include/xo/tokenizer/tokentype.hpp index 92d9bf60..eeeb7dd0 100644 --- a/xo-tokenizer/include/xo/tokenizer/tokentype.hpp +++ b/xo-tokenizer/include/xo/tokenizer/tokentype.hpp @@ -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, diff --git a/xo-tokenizer/src/tokenizer/tokentype.cpp b/xo-tokenizer/src/tokenizer/tokentype.cpp index 745651a7..33d683de 100644 --- a/xo-tokenizer/src/tokenizer/tokentype.cpp +++ b/xo-tokenizer/src/tokenizer/tokentype.cpp @@ -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);