New operator: modulo operator '%'

This commit is contained in:
Robert Bendun 2022-08-29 20:37:11 +02:00
parent b8feb4043e
commit 2b29522293
4 changed files with 26 additions and 3 deletions

View File

@ -436,7 +436,7 @@ struct Token
}; };
static constexpr usize Keywords_Count = 6; static constexpr usize Keywords_Count = 6;
static constexpr usize Operators_Count = 14; static constexpr usize Operators_Count = 15;
std::string_view type_name(Token::Type type); std::string_view type_name(Token::Type type);
@ -685,6 +685,8 @@ struct Number
Number& operator*=(Number const& rhs); Number& operator*=(Number const& rhs);
Number operator/(Number const& rhs) const; Number operator/(Number const& rhs) const;
Number& operator/=(Number const& rhs); Number& operator/=(Number const& rhs);
Number operator%(Number const& rhs) const;
Number& operator%=(Number const& rhs);
Number floor() const; ///< Return number rounded down to nearest integer Number floor() const; ///< Return number rounded down to nearest integer
Number ceil() const; ///< Return number rounded up to nearest integer Number ceil() const; ///< Return number rounded up to nearest integer

View File

@ -172,6 +172,7 @@ static constexpr auto Operators = std::array {
Operator_Entry { "-", plus_minus_operator<std::minus<>> }, Operator_Entry { "-", plus_minus_operator<std::minus<>> },
Operator_Entry { "*", multiplication_operator }, Operator_Entry { "*", multiplication_operator },
Operator_Entry { "/", binary_operator<std::divides<>, '/'> }, Operator_Entry { "/", binary_operator<std::divides<>, '/'> },
Operator_Entry { "%", binary_operator<std::modulus<>, '%'> },
Operator_Entry { "<", comparison_operator<std::less<>> }, Operator_Entry { "<", comparison_operator<std::less<>> },
Operator_Entry { ">", comparison_operator<std::greater<>> }, Operator_Entry { ">", comparison_operator<std::greater<>> },

View File

@ -119,6 +119,26 @@ Number& Number::operator/=(Number const& rhs)
return *this; return *this;
} }
Number Number::operator%(Number const& rhs) const
{
return Number(*this) %= rhs;
}
Number& Number::operator%=(Number const& rhs)
{
simplify_inplace();
auto [rnum, rden] = rhs.simplify();
if (den == 1 && rden == 1) {
num %= rnum;
} else {
assert(false, "Modulo for fractions is not supported");
}
return *this;
}
std::ostream& operator<<(std::ostream& os, Number const& n) std::ostream& operator<<(std::ostream& os, Number const& n)
{ {
return n.den == 1 return n.den == 1

View File

@ -506,13 +506,13 @@ static usize precedense(std::string_view op)
// '.' since it have own precedense rules and is not binary expression but its own kind of expression // '.' since it have own precedense rules and is not binary expression but its own kind of expression
// //
// Exclusion of them is marked by subtracting total number of excluded operators. // Exclusion of them is marked by subtracting total number of excluded operators.
static_assert(Operators_Count - 1 == 13, "Ensure that all operators have defined precedense below"); static_assert(Operators_Count - 1 == 14, "Ensure that all operators have defined precedense below");
if (one_of(op, "or")) return 100; if (one_of(op, "or")) return 100;
if (one_of(op, "and")) return 150; if (one_of(op, "and")) return 150;
if (one_of(op, "<", ">", "<=", ">=", "==", "!=")) return 200; if (one_of(op, "<", ">", "<=", ">=", "==", "!=")) return 200;
if (one_of(op, "+", "-")) return 300; if (one_of(op, "+", "-")) return 300;
if (one_of(op, "*", "/", "&")) return 400; if (one_of(op, "*", "/", "%", "&")) return 400;
unreachable(); unreachable();
} }