From 1c2fb173ea3b674207badc721556ad72962b266e Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 2 Aug 2026 17:05:34 +0200 Subject: Check array property accessbility at compile time --- boot/evaluator.cc | 4 ++-- boot/name_analysis.cc | 14 ++++++++------ boot/result.cc | 6 +++--- boot/type_check.cc | 50 +++++++++++++++++++++++++++++--------------------- 4 files changed, 42 insertions(+), 32 deletions(-) (limited to 'boot') diff --git a/boot/evaluator.cc b/boot/evaluator.cc index 097b6a5..8f414fa 100644 --- a/boot/evaluator.cc +++ b/boot/evaluator.cc @@ -459,7 +459,7 @@ namespace elna::boot { switch (operation) { - using enum binary_operator; + using enum binary_operator; case equals: return constant_value{ true }; case not_equals: @@ -472,7 +472,7 @@ namespace elna::boot { switch (operation) { - using enum binary_operator; + using enum binary_operator; case sum: if constexpr (std::is_same_v) { diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index e4f1920..3667dff 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -41,13 +41,14 @@ namespace elna::boot { switch (payload) { - case kind::undeclared_type: + using enum kind; + case undeclared_type: return "Type '" + this->name + "' not declared"; - case kind::undeclared_trait: + case undeclared_trait: return "Trait '#" + this->name + "' not declared"; - case kind::undeclared_symbol: + case undeclared_symbol: return "Symbol '" + this->name + "' not declared"; - case kind::local_export: + case local_export: return "Local symbol '" + this->name + "' cannot be exported"; default: __builtin_unreachable(); @@ -77,9 +78,10 @@ namespace elna::boot { switch (error_kind) { - case kind::array_position: + using enum kind; + case array_position: return "const must be written before the array size, not after"; - case kind::duplicate: + case duplicate: return "Duplicate 'const' qualifier is not allowed"; default: __builtin_unreachable(); diff --git a/boot/result.cc b/boot/result.cc index b56046b..c47be95 100644 --- a/boot/result.cc +++ b/boot/result.cc @@ -424,9 +424,9 @@ namespace elna::boot { hash_accumulator result{}; - result.m_seed ^= that + hash_accumulator::golden_ratio - // NOLINTNEXTLINE(readability-magic-numbers) - + (this->m_seed << 6) + (this->m_seed >> 2); + result.m_seed ^= that + golden_ratio + + (this->m_seed << mix_shift_left) + + (this->m_seed >> mix_shift_right); return result; } diff --git a/boot/type_check.cc b/boot/type_check.cc index 529f66a..78e975a 100644 --- a/boot/type_check.cc +++ b/boot/type_check.cc @@ -174,25 +174,26 @@ namespace elna::boot { switch (payload) { - case kind::record_base: + using enum kind; + case record_base: return "Expected a record type, but got '" + this->actual.to_string() + "'"; - case kind::for_range: + case for_range: return "Expected an array or slice type, but got '" + this->actual.to_string() + "'"; - case kind::condition: + case condition: return "Condition must be a boolean expression, but got '" + this->actual.to_string() + "'"; - case kind::constant_assignment: + case constant_assignment: return "Cannot assign to a value of type '" + this->actual.to_string() + "', because it is constant or contains constant members"; - case kind::array_index: + case array_index: return "Array index must be an integral type, but got '" + this->actual.to_string() + "'"; - case kind::non_indexable: + case non_indexable: return "Indexing is not allowed on type '" + this->actual.to_string() + "'"; - case kind::dereference_of_non_pointer: + case dereference_of_non_pointer: return "Type '" + this->actual.to_string() + "' cannot be dereferenced, it is not a pointer"; default: @@ -422,17 +423,24 @@ namespace elna::boot bool assign_check::run() { - for (auto handler : {&assign_check::guard_const_laundering, - &assign_check::check_exact_match, - &assign_check::check_slice_conversion, - &assign_check::check_pointer_hatch, - &assign_check::check_pointer_conversion}) + auto const assign_handlers = { + &assign_check::guard_const_laundering, + &assign_check::check_exact_match, + &assign_check::check_slice_conversion, + &assign_check::check_pointer_hatch, + &assign_check::check_pointer_conversion + }; + for (auto handler : assign_handlers) { switch ((this->*handler)()) { - case verdict::accept: return true; - case verdict::reject: return false; - case verdict::pass:; + using enum verdict; + case accept: + return true; + case reject: + return false; + case pass: + break; } } return false; @@ -441,11 +449,11 @@ namespace elna::boot bool type_analysis_visitor::is_assignable_from(const type& assignee, const type& assignment) { return assign_check{ - resolve_aliases(assignee), - resolve_aliases(assignment), - resolve_underlying_type(assignee), - resolve_underlying_type(assignment) - }.run(); + resolve_aliases(assignee), + resolve_aliases(assignment), + resolve_underlying_type(assignee), + resolve_underlying_type(assignment) + }.run(); } type_analysis_visitor::type_analysis_visitor(symbol_bag bag, const target_info& target) @@ -893,7 +901,7 @@ namespace elna::boot switch (operation) { - using enum binary_operator; + using enum binary_operator; case sum: valid = (is_any_pointer_type(lhs_resolved) && is_integral_type(rhs_resolved)) || (is_integral_type(lhs_resolved) && is_any_pointer_type(rhs_resolved)) -- cgit v1.2.3