aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-02 17:05:34 +0200
committerEugen Wissner <belka@caraus.de>2026-08-02 17:05:34 +0200
commit1c2fb173ea3b674207badc721556ad72962b266e (patch)
tree950b1d58b719f3302045e114eee35a426af8b0dd /boot
parentc07c43bf911f62ad6363c024b3f81ceb4f95b16c (diff)
downloadelna-1c2fb173ea3b674207badc721556ad72962b266e.tar.gz
Check array property accessbility at compile time
Diffstat (limited to 'boot')
-rw-r--r--boot/evaluator.cc4
-rw-r--r--boot/name_analysis.cc14
-rw-r--r--boot/result.cc6
-rw-r--r--boot/type_check.cc50
4 files changed, 42 insertions, 32 deletions
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<T, integer_literal>)
{
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))