aboutsummaryrefslogtreecommitdiff
path: root/boot/result.cc
diff options
context:
space:
mode:
Diffstat (limited to 'boot/result.cc')
-rw-r--r--boot/result.cc270
1 files changed, 232 insertions, 38 deletions
diff --git a/boot/result.cc b/boot/result.cc
index 0eb5c12..f9f57db 100644
--- a/boot/result.cc
+++ b/boot/result.cc
@@ -91,22 +91,9 @@ namespace elna::boot
return this->m_position;
}
- std::strong_ordering identifier::operator<=>(const identifier& that) const
+ bool identifier::operator==(const identifier& that) const
{
- auto comparison = this->m_name.compare(that.name());
-
- if (comparison < 0)
- {
- return std::strong_ordering::less;
- }
- else if (comparison > 0)
- {
- return std::strong_ordering::greater;
- }
- else
- {
- return std::strong_ordering::equal;
- }
+ return this->m_name == that;
}
bool identifier::operator==(std::string_view that) const
@@ -114,11 +101,6 @@ namespace elna::boot
return this->m_name == that;
}
- bool identifier::operator!=(std::string_view that) const
- {
- return !(*this == that);
- }
-
identifier_definition::identifier_definition(const std::string& name,
const source_position& position, const bool exported)
: m_identifier(name, position), m_exported(exported)
@@ -140,6 +122,231 @@ namespace elna::boot
return this->m_exported;
}
+ integer_literal::integer_literal(bool is_signed, std::size_t size)
+ : m_signed(is_signed), m_size(size)
+ {
+ mpz_init(this->raw);
+ }
+
+ integer_literal::integer_literal(integer_literal&& that) noexcept
+ {
+ mpz_init(this->raw);
+ mpz_swap(this->raw, that.raw);
+ }
+
+ integer_literal::integer_literal(const integer_literal& that)
+ {
+ mpz_init(this->raw);
+ mpz_set(this->raw, that.raw);
+ }
+
+ integer_literal::~integer_literal()
+ {
+ mpz_clear(this->raw);
+ }
+
+ std::optional<integer_literal> integer_literal::add(const integer_literal& that) const
+ {
+ integer_literal result = *this;
+
+ mpz_add(result.raw, this->raw, that.raw);
+
+ return std::move(result).check();
+ }
+
+ std::optional<integer_literal> integer_literal::sub(const integer_literal& that) const
+ {
+ integer_literal result = *this;
+
+ mpz_sub(result.raw, this->raw, that.raw);
+
+ return std::move(result).check();
+ }
+
+ std::optional<integer_literal> integer_literal::mul(const integer_literal& that) const
+ {
+ integer_literal result = *this;
+
+ mpz_mul(result.raw, this->raw, that.raw);
+
+ return std::move(result).check();
+ }
+
+ std::optional<integer_literal> integer_literal::div(const integer_literal& that) const
+ {
+ if (mpz_cmp_ui(that.raw, 0U) == 0)
+ {
+ return std::nullopt;
+ }
+ else
+ {
+ integer_literal result = *this;
+
+ mpz_div(result.raw, this->raw, that.raw);
+
+ return std::make_optional(std::move(result));
+ }
+ }
+
+ std::optional<integer_literal> integer_literal::mod(const integer_literal& that) const
+ {
+ if (mpz_cmp_ui(that.raw, 0U) == 0)
+ {
+ return std::nullopt;
+ }
+ else
+ {
+ integer_literal result = *this;
+
+ mpz_mod(result.raw, this->raw, that.raw);
+
+ return std::make_optional(std::move(result));
+ }
+ }
+
+ std::optional<integer_literal> integer_literal::neg() const
+ {
+ if (!is_signed() || is_negative_minimum())
+ {
+ return std::nullopt;
+ }
+ integer_literal result = *this;
+
+ mpz_neg(result.raw, this->raw);
+
+ return result;
+ }
+
+ std::optional<integer_literal> integer_literal::shl(const integer_literal& that) const
+ {
+ if (that >= bits())
+ {
+ return std::nullopt;
+ }
+ integer_literal result = *this;
+
+ mpz_mul_2exp(result.raw, this->raw, static_cast<mp_bitcnt_t>(mpz_get_ui(that.raw)));
+
+ return std::move(result).check();
+ }
+
+ std::optional<integer_literal> integer_literal::shr(const integer_literal& that) const
+ {
+ integer_literal result = *this;
+
+ if (that >= bits())
+ {
+ mpz_set_si(result.raw, *this > 0 ? 0 : -1);
+ }
+ else
+ {
+ mpz_fdiv_q_2exp(result.raw, this->raw, static_cast<mp_bitcnt_t>(mpz_get_ui(that.raw)));
+ }
+ return std::make_optional(std::move(result));
+ }
+
+ integer_literal integer_literal::operator|(const integer_literal& that) const
+ {
+ integer_literal result = *this;
+
+ mpz_ior(result.raw, this->raw, that.raw);
+
+ return result;
+ }
+
+ integer_literal integer_literal::operator&(const integer_literal& that) const
+ {
+ integer_literal result = *this;
+
+ mpz_and(result.raw, this->raw, that.raw);
+
+ return result;
+ }
+
+ integer_literal integer_literal::operator^(const integer_literal& that) const
+ {
+ integer_literal result = *this;
+
+ mpz_xor(result.raw, this->raw, that.raw);
+
+ return result;
+ }
+
+ integer_literal integer_literal::operator~() const
+ {
+ integer_literal result = *this;
+
+ mpz_com(result.raw, this->raw);
+
+ return result;
+ }
+
+ bool integer_literal::operator==(const integer_literal& that) const
+ {
+ return mpz_cmp(this->raw, that.raw) == 0;
+ }
+
+ std::weak_ordering integer_literal::operator<=>(const integer_literal& that) const
+ {
+ return mpz_cmp(this->raw, that.raw) <=> 0;
+ }
+
+ integer_literal& integer_literal::operator=(integer_literal&& that) noexcept
+ {
+ if (this != &that)
+ {
+ mpz_swap(this->raw, that.raw);
+ }
+ return *this;
+ }
+
+ integer_literal& integer_literal::operator=(const integer_literal& that)
+ {
+ if (this != &that)
+ {
+ mpz_set(this->raw, that.raw);
+ }
+ return *this;
+ }
+
+ bool integer_literal::is_signed() const
+ {
+ return this->m_signed;
+ }
+
+ std::size_t integer_literal::size() const
+ {
+ return this->m_size;
+ }
+
+ std::optional<integer_literal> integer_literal::check() &&
+ {
+ std::size_t required_bits = mpz_sizeinbase(this->raw, 2);
+
+ if (!is_negative_minimum())
+ {
+ ++required_bits; // Add one bit for the sign.
+ }
+ if (required_bits > bits() || (mpz_sgn(this->raw) < 0 && !is_signed()))
+ {
+ return std::nullopt;
+ }
+ else
+ {
+ return std::move(*this);
+ }
+ }
+
+ bool integer_literal::is_negative_minimum() const
+ {
+ return mpz_sgn(this->raw) < 0 && mpz_scan1(this->raw, 0) == bits() - 1;
+ }
+
+ std::size_t integer_literal::bits() const
+ {
+ return size() * CHAR_BIT;
+ }
+
std::size_t constant_value_hash::operator()(const elna::boot::constant_value& value) const noexcept
{
return std::visit([](auto&& alternative) -> std::size_t {
@@ -149,24 +356,6 @@ namespace elna::boot
}, value);
}
- bool constant_value_hash::operator()(const elna::boot::constant_value& lhs,
- const elna::boot::constant_value& rhs) const noexcept
- {
- return std::visit([](auto&& first, auto&& second) -> bool {
- using T = std::decay_t<decltype(first)>;
- using U = std::decay_t<decltype(second)>;
-
- if constexpr (std::is_same_v<T, U>)
- {
- return first == second;
- }
- else
- {
- return false;
- }
- }, lhs, rhs);
- }
-
hash_accumulator hash_accumulator::operator+(const std::size_t& that) const
{
hash_accumulator result{};
@@ -219,3 +408,8 @@ std::size_t std::hash<elna::boot::constant_aggregate<elna::boot::ordered_map>>::
return hash.seed();
}
+
+std::size_t std::hash<elna::boot::integer_literal>::operator()(const elna::boot::integer_literal& key) const noexcept
+{
+ return std::hash<std::uint32_t>{}(key.to<std::uint32_t>());
+}