aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-24 00:39:51 +0200
committerEugen Wissner <belka@caraus.de>2026-09-24 00:39:51 +0200
commitf7b035a505e86ad916a43ab1dc1a662a6066b011 (patch)
treea54369ae8ad56352d148c4583ab568f7d4869d30
parent74e75e41fe12f19e5365a3152ffafa1a29376240 (diff)
downloadelna-f7b035a505e86ad916a43ab1dc1a662a6066b011.tar.gz
Move module heading to the top
-rw-r--r--.clang-tidy5
-rw-r--r--boot/ast.cc12
-rw-r--r--boot/driver.cc25
-rw-r--r--boot/evaluator.cc58
-rw-r--r--boot/lexer.ll5
-rw-r--r--boot/name_analysis.cc166
-rw-r--r--boot/parser.yy81
-rw-r--r--boot/result.cc10
-rw-r--r--boot/symbol.cc112
-rw-r--r--boot/type_check.cc197
-rw-r--r--boot/validation.cc8
-rw-r--r--gcc/gcc/elna-builtins.cc34
-rw-r--r--gcc/gcc/elna-generic.cc35
-rw-r--r--gcc/gcc/elna-tree.cc5
-rw-r--r--include/elna/boot/ast.h8
-rw-r--r--include/elna/boot/dependency.h5
-rw-r--r--include/elna/boot/driver.h8
-rw-r--r--include/elna/boot/result.h24
-rw-r--r--include/elna/boot/symbol.h4
-rw-r--r--include/elna/boot/type_check.h6
-rw-r--r--source/cctype.elna1
-rw-r--r--source/command_line_interface.elna2
-rw-r--r--source/common.elna2
-rw-r--r--source/cstdio.elna1
-rw-r--r--source/cstdlib.elna1
-rw-r--r--source/cstring.elna1
-rw-r--r--source/lexer.elna2
-rw-r--r--source/main.elna8
-rw-r--r--testsuite/compilable/aliased_type_constant.elna2
-rw-r--r--testsuite/compilable/assign_record_to_base.elna6
-rw-r--r--testsuite/compilable/compile_time_array_length.elna2
-rw-r--r--testsuite/compilable/const_alias.elna2
-rw-r--r--testsuite/compilable/const_element_array.elna2
-rw-r--r--testsuite/compilable/const_extern.elna2
-rw-r--r--testsuite/compilable/const_negation.elna4
-rw-r--r--testsuite/compilable/const_var_chain.elna4
-rw-r--r--testsuite/compilable/double_literals.elna2
-rw-r--r--testsuite/compilable/empty_proc.elna2
-rw-r--r--testsuite/compilable/empty_proc_type_expression.elna2
-rw-r--r--testsuite/compilable/empty_statements_in_a_row.elna2
-rw-r--r--testsuite/compilable/generic_alias.elna4
-rw-r--r--testsuite/compilable/generic_arguments.elna8
-rw-r--r--testsuite/compilable/generic_base_chain.elna4
-rw-r--r--testsuite/compilable/generic_inference.elna4
-rw-r--r--testsuite/compilable/opaque_type.elna4
-rw-r--r--testsuite/compilable/pointer_cast.elna4
-rw-r--r--testsuite/compilable/pointer_const_conversion.elna4
-rw-r--r--testsuite/compilable/pointer_subtraction.elna2
-rw-r--r--testsuite/compilable/procedure_forward_reference.elna2
-rw-r--r--testsuite/compilable/record_const_base.elna2
-rw-r--r--testsuite/compilable/self-referencing-record.elna2
-rw-r--r--testsuite/compilable/semicolon_parameter_separator.elna2
-rw-r--r--testsuite/compilable/single_literals.elna2
-rw-r--r--testsuite/compilable/slice_index.elna2
-rw-r--r--testsuite/compilable/take_const_address.elna4
-rw-r--r--testsuite/compilable/trailing_text.elna2
-rw-r--r--testsuite/compilable/traits_size.elna4
-rw-r--r--testsuite/fail_compilation/access_record_type_field.elna2
-rw-r--r--testsuite/fail_compilation/alias-cycle-behind-const.elna3
-rw-r--r--testsuite/fail_compilation/alias-cycle.elna3
-rw-r--r--testsuite/fail_compilation/alias-field-cycle.elna3
-rw-r--r--testsuite/fail_compilation/aligned_attribute.elna6
-rw-r--r--testsuite/fail_compilation/array-cycle.elna3
-rw-r--r--testsuite/fail_compilation/assign_array_length.elna4
-rw-r--r--testsuite/fail_compilation/assign_const_array_pointer.elna2
-rw-r--r--testsuite/fail_compilation/assign_const_element.elna2
-rw-r--r--testsuite/fail_compilation/assign_const_member.elna2
-rw-r--r--testsuite/fail_compilation/assign_const_primitive.elna2
-rw-r--r--testsuite/fail_compilation/assign_const_record_pointer.elna2
-rw-r--r--testsuite/fail_compilation/assign_const_to_pointer.elna4
-rw-r--r--testsuite/fail_compilation/assign_deep_const_pointer.elna2
-rw-r--r--testsuite/fail_compilation/assign_element_of_const.elna2
-rw-r--r--testsuite/fail_compilation/assign_from_const_pointer.elna4
-rw-r--r--testsuite/fail_compilation/assign_member_of_const.elna2
-rw-r--r--testsuite/fail_compilation/assign_slice_ptr.elna4
-rw-r--r--testsuite/fail_compilation/assign_to_call_result_field.elna4
-rw-r--r--testsuite/fail_compilation/assign_to_slicing.elna4
-rw-r--r--testsuite/fail_compilation/assign_void_call.elna4
-rw-r--r--testsuite/fail_compilation/case_label_overflow.elna4
-rw-r--r--testsuite/fail_compilation/case_non_constant.elna4
-rw-r--r--testsuite/fail_compilation/case_type_mismatch.elna4
-rw-r--r--testsuite/fail_compilation/case_unique_label.elna2
-rw-r--r--testsuite/fail_compilation/circular_import/sut.elna2
-rw-r--r--testsuite/fail_compilation/compare_unrelated_records.elna4
-rw-r--r--testsuite/fail_compilation/compile_time_array_ptr.elna2
-rw-r--r--testsuite/fail_compilation/const_array.elna3
-rw-r--r--testsuite/fail_compilation/const_uninitialized.elna2
-rw-r--r--testsuite/fail_compilation/constant_enum_to_int.elna4
-rw-r--r--testsuite/fail_compilation/double_const.elna3
-rw-r--r--testsuite/fail_compilation/enumeration_member_missing.elna2
-rw-r--r--testsuite/fail_compilation/float_remainder.elna2
-rw-r--r--testsuite/fail_compilation/generic_arity.elna6
-rw-r--r--testsuite/fail_compilation/generic_base_mismatch.elna4
-rw-r--r--testsuite/fail_compilation/generic_parameter_arithmetic.elna6
-rw-r--r--testsuite/fail_compilation/generic_uninferrable.elna8
-rw-r--r--testsuite/fail_compilation/import_import_collision/first.elna2
-rw-r--r--testsuite/fail_compilation/import_import_collision/second.elna2
-rw-r--r--testsuite/fail_compilation/import_import_collision/sut.elna2
-rw-r--r--testsuite/fail_compilation/import_local_collision/helper.elna2
-rw-r--r--testsuite/fail_compilation/import_local_collision/sut.elna5
-rw-r--r--testsuite/fail_compilation/local_var_exported.elna2
-rw-r--r--testsuite/fail_compilation/local_var_extern.elna2
-rw-r--r--testsuite/fail_compilation/negative_integer_literal_overflow.elna2
-rw-r--r--testsuite/fail_compilation/non_constant_array_dimension.elna8
-rw-r--r--testsuite/fail_compilation/offset_not_record.elna4
-rw-r--r--testsuite/fail_compilation/opaque_pointer_arithmetic.elna4
-rw-r--r--testsuite/fail_compilation/opaque_slice_element.elna2
-rw-r--r--testsuite/fail_compilation/pointer-cycle.elna2
-rw-r--r--testsuite/fail_compilation/proc_type_without_parameters.elna4
-rw-r--r--testsuite/fail_compilation/procedure-cycle.elna2
-rw-r--r--testsuite/fail_compilation/program_arguments.elna2
-rw-r--r--testsuite/fail_compilation/record-base-cycle-indirect.elna6
-rw-r--r--testsuite/fail_compilation/record-base-cycle.elna2
-rw-r--r--testsuite/fail_compilation/record_base_constructor_type_mismatch.elna4
-rw-r--r--testsuite/fail_compilation/record_duplicate_field.elna2
-rw-r--r--testsuite/fail_compilation/record_duplicate_field_import_base/helper.elna2
-rw-r--r--testsuite/fail_compilation/record_duplicate_field_import_base/sut.elna2
-rw-r--r--testsuite/fail_compilation/redefined_variable.elna2
-rw-r--r--testsuite/fail_compilation/reference_call_result_field.elna4
-rw-r--r--testsuite/fail_compilation/reference_literal.elna4
-rw-r--r--testsuite/fail_compilation/reference_slicing.elna4
-rw-r--r--testsuite/fail_compilation/slice-cycle.elna2
-rw-r--r--testsuite/fail_compilation/unary_minus_on_record.elna2
-rw-r--r--testsuite/fail_compilation/unary_negation_on_record.elna2
-rw-r--r--testsuite/fail_compilation/unary_plus_on_record.elna2
-rw-r--r--testsuite/fail_compilation/varargs_argument.elna4
-rw-r--r--testsuite/fail_compilation/varargs_attribute.elna3
-rw-r--r--testsuite/fail_compilation/while_condition.elna2
-rw-r--r--testsuite/runnable/aggregate_argument.elna4
-rw-r--r--testsuite/runnable/aggregate_equality.elna4
-rw-r--r--testsuite/runnable/aligned_attribute.elna4
-rw-r--r--testsuite/runnable/array_constructor.elna4
-rw-r--r--testsuite/runnable/binary_literal.elna2
-rw-r--r--testsuite/runnable/block_local_variable.elna3
-rw-r--r--testsuite/runnable/case_constant_label.elna4
-rw-r--r--testsuite/runnable/case_else.elna4
-rw-r--r--testsuite/runnable/case_int.elna4
-rw-r--r--testsuite/runnable/case_multilabel.elna4
-rw-r--r--testsuite/runnable/case_record.elna4
-rw-r--r--testsuite/runnable/compile_time_array_access.elna4
-rw-r--r--testsuite/runnable/const_copy.elna4
-rw-r--r--testsuite/runnable/const_initialization.elna4
-rw-r--r--testsuite/runnable/constant_string_initializer.elna4
-rw-r--r--testsuite/runnable/define_multiple_local_variables.elna4
-rw-r--r--testsuite/runnable/exported_variable/helper.elna2
-rw-r--r--testsuite/runnable/exported_variable/sut.elna4
-rw-r--r--testsuite/runnable/fixed_int_max.elna2
-rw-r--r--testsuite/runnable/fixed_int_min.elna2
-rw-r--r--testsuite/runnable/fixed_word_max.elna2
-rw-r--r--testsuite/runnable/float_arithmetic.elna2
-rw-r--r--testsuite/runnable/float_cast.elna4
-rw-r--r--testsuite/runnable/for_call.elna4
-rw-r--r--testsuite/runnable/for_defer.elna4
-rw-r--r--testsuite/runnable/for_each_array.elna4
-rw-r--r--testsuite/runnable/for_each_slice.elna4
-rw-r--r--testsuite/runnable/for_with.elna3
-rw-r--r--testsuite/runnable/generic_base.elna4
-rw-r--r--testsuite/runnable/generic_constructor.elna4
-rw-r--r--testsuite/runnable/generic_erasure.elna4
-rw-r--r--testsuite/runnable/generic_pointer_arithmetic.elna4
-rw-r--r--testsuite/runnable/generic_record.elna4
-rw-r--r--testsuite/runnable/hexadecimal_literal.elna2
-rw-r--r--testsuite/runnable/multi_module/helper.elna2
-rw-r--r--testsuite/runnable/multi_module/sut.elna4
-rw-r--r--testsuite/runnable/named_block.elna4
-rw-r--r--testsuite/runnable/procedure_cast.elna7
-rw-r--r--testsuite/runnable/record_base_assignment.elna4
-rw-r--r--testsuite/runnable/record_base_constructor.elna4
-rw-r--r--testsuite/runnable/record_construction.elna4
-rw-r--r--testsuite/runnable/record_extension.elna4
-rw-r--r--testsuite/runnable/record_layout.elna4
-rw-r--r--testsuite/runnable/recursive_record.elna4
-rw-r--r--testsuite/runnable/repeat_loop.elna4
-rw-r--r--testsuite/runnable/return_aggregate.elna4
-rw-r--r--testsuite/runnable/slice_array.elna4
-rw-r--r--testsuite/runnable/slice_cast.elna4
-rw-r--r--testsuite/runnable/slice_equality.elna4
-rw-r--r--testsuite/runnable/slice_pointer.elna4
-rw-r--r--testsuite/runnable/slice_slice.elna4
-rw-r--r--testsuite/runnable/two_fields_same_type.elna4
-rw-r--r--testsuite/runnable/two_parameters_same_type.elna5
-rw-r--r--testsuite/runnable/unary_plus.elna5
-rw-r--r--testsuite/runnable/unicode_escape_character.elna2
-rw-r--r--testsuite/runnable/unicode_escape_string.elna2
-rw-r--r--testsuite/runnable/varargs.elna4
185 files changed, 661 insertions, 686 deletions
diff --git a/.clang-tidy b/.clang-tidy
index c5d99db..e447482 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -9,6 +9,7 @@ Checks: |
concurrency-*,
cert-*,
-bugprone-easily-swappable-parameters,
+ -bugprone-unchecked-optional-access,
-misc-include-cleaner,
-misc-multiple-inheritance,
-misc-non-private-member-variables-in-classes,
@@ -18,15 +19,13 @@ Checks: |
-readability-else-after-return,
-readability-function-cognitive-complexity,
-readability-named-parameter,
- -bugprone-unchecked-optional-access,
+ -readability-trailing-comma,
-performance-enum-size,
-modernize-use-trailing-return-type,
-modernize-use-nodiscard,
-modernize-pass-by-value,
-modernize-use-auto,
-modernize-return-braced-init-list,
- # False positives: does not see delete inside loop bodies of destructors.
- -modernize-use-equals-default,
# llvm/llvm-project#213560: fires on every assert() with glibc's variadic macro.
-misc-static-assert,
diff --git a/boot/ast.cc b/boot/ast.cc
index b38e8d1..2d8e90d 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -367,7 +367,10 @@ namespace elna::boot
void walking_visitor::visit_entry_point(unit *unit)
{
- traverse_body(this, unit->entry_point.value());
+ for (statement *body_statement : unit->entry_point.value())
+ {
+ body_statement->accept(this);
+ }
}
void walking_visitor::visit(type_declaration *declaration)
@@ -1121,10 +1124,9 @@ namespace elna::boot
std::vector<declaration *>&& declarations,
std::vector<identifier>&& parameters,
const source_position entry_position,
- std::optional<procedure_body>&& body)
- : node(position),
- imports(std::move(imports)), declarations(std::move(declarations)), entry_point(std::move(body)),
- parameters(std::move(parameters)), entry_position(entry_position)
+ std::vector<statement *>&& body)
+ : node(position), imports(std::move(imports)), declarations(std::move(declarations)),
+ entry_point(std::move(body)), parameters(std::move(parameters)), entry_position(entry_position)
{
}
diff --git a/boot/driver.cc b/boot/driver.cc
index 2bcbcb1..14575f7 100644
--- a/boot/driver.cc
+++ b/boot/driver.cc
@@ -23,9 +23,9 @@ namespace elna::boot
{
source_position make_position(const yy::location& location)
{
- auto start_location = boot::location(static_cast<std::size_t>(location.begin.line),
+ const boot::location start_location = boot::location(static_cast<std::size_t>(location.begin.line),
static_cast<std::size_t>(location.begin.column));
- auto end_location = boot::location(static_cast<std::size_t>(location.end.line),
+ const boot::location end_location = boot::location(static_cast<std::size_t>(location.end.line),
static_cast<std::size_t>(location.end.column));
return source_position(start_location, end_location);
@@ -41,6 +41,11 @@ namespace elna::boot
return message;
}
+ bool driver::has_finished() const
+ {
+ return this->tree != nullptr;
+ }
+
static char unescape_character(char escape)
{
switch (escape)
@@ -79,19 +84,19 @@ namespace elna::boot
constexpr unsigned char utf8_lead_tag_3byte = 0xE0;
constexpr unsigned char utf8_lead_tag_4byte = 0xF0;
- constexpr int utf8_continuation_bits = 6;
- constexpr uint32_t utf8_continuation_mask = 0x3F;
+ constexpr std::uint32_t utf8_continuation_bits = 6;
+ constexpr std::uint32_t utf8_continuation_mask = 0x3F;
constexpr unsigned char utf8_continuation_tag = 0x80;
- constexpr uint32_t utf8_surrogate_range_start = 0xD800;
- constexpr uint32_t utf8_surrogate_range_end = 0xDFFF;
- constexpr uint32_t utf8_max_unicode_codepoint = 0x10FFFF;
+ constexpr std::uint32_t utf8_surrogate_range_start = 0xD800;
+ constexpr std::uint32_t utf8_surrogate_range_end = 0xDFFF;
+ constexpr std::uint32_t utf8_max_unicode_codepoint = 0x10FFFF;
static std::optional<std::string> encode_utf8(uint32_t codepoint)
{
- constexpr uint32_t utf8_1byte_max = 0x80;
- constexpr uint32_t utf8_2byte_max = 0x800;
- constexpr uint32_t utf8_3byte_max = 0x10000;
+ constexpr std::uint32_t utf8_1byte_max = 0x80;
+ constexpr std::uint32_t utf8_2byte_max = 0x800;
+ constexpr std::uint32_t utf8_3byte_max = 0x10000;
std::string result;
diff --git a/boot/evaluator.cc b/boot/evaluator.cc
index 0085c62..6cf287c 100644
--- a/boot/evaluator.cc
+++ b/boot/evaluator.cc
@@ -66,7 +66,7 @@ namespace elna::boot
std::optional<type_properties> get_type_properties(const type& subject, const target_info& target)
{
- auto resolved = resolve_underlying_type(subject);
+ const type resolved = resolve_underlying_type(subject);
if (resolved.get<enumeration_type>() != nullptr)
{
@@ -78,7 +78,7 @@ namespace elna::boot
return erased.empty() ? std::nullopt : get_type_properties(erased, target);
}
- else if (auto resolved_primitive = resolved.get<primitive_type>())
+ else if (const auto resolved_primitive = resolved.get<primitive_type>())
{
return resolved_primitive->properties;
}
@@ -93,7 +93,7 @@ namespace elna::boot
{
return target.pointer_properties;
}
- else if (auto array = resolved.get<array_type>())
+ else if (const auto array = resolved.get<array_type>())
{
if (auto element = get_type_properties(array->base, target))
{
@@ -103,7 +103,7 @@ namespace elna::boot
};
}
}
- else if (auto record = resolved.get<record_type>())
+ else if (const auto record = resolved.get<record_type>())
{
auto record_layout = layout_record(record, target);
if (record_layout.has_value())
@@ -212,7 +212,7 @@ namespace elna::boot
{
return evaluate_traits(*traits);
}
- else if (auto *record_constructor = subject.is_record_constructor())
+ else if (const auto *record_constructor = subject.is_record_constructor())
{
ordered_map<constant_value> aggregate;
@@ -227,7 +227,7 @@ namespace elna::boot
}
return constant_value{ constant_aggregate<ordered_map>{ std::move(aggregate) } };
}
- else if (auto *array_constructor = subject.is_array_constructor())
+ else if (const auto *array_constructor = subject.is_array_constructor())
{
std::vector<constant_value> elements;
for (expression *element : array_constructor->elements)
@@ -275,13 +275,13 @@ namespace elna::boot
std::optional<constant_value> evaluator::evaluate_named(named_expression& subject)
{
- auto symbol = this->bag.lookup(subject.name);
+ const std::shared_ptr<info> symbol = this->bag.lookup(subject.name);
if (symbol == nullptr)
{
return std::nullopt;
}
- auto variable = symbol->is_variable();
+ const std::shared_ptr<variable_info> variable = symbol->is_variable();
if (variable == nullptr
|| resolve_aliases(variable->symbol).get<constant_type>() == nullptr)
@@ -315,17 +315,17 @@ namespace elna::boot
// reading the type decoration set by name analysis.
if (auto *base_designator = subject.base().is_designator())
{
- if (auto *base_name = base_designator->is_named())
+ if (const auto *base_name = base_designator->is_named())
{
- auto symbol = this->bag.lookup(base_name->name);
+ const std::shared_ptr<info> symbol = this->bag.lookup(base_name->name);
if (symbol != nullptr)
{
- if (auto type_symbol = symbol->is_type())
+ if (const auto type_symbol = symbol->is_type())
{
- if (auto enumeration = resolve_underlying_type(type_symbol->symbol).get<enumeration_type>())
+ if (const auto enumeration = resolve_underlying_type(type_symbol->symbol).get<enumeration_type>())
{
- auto member_iterator = std::ranges::find(enumeration->members, subject.field().name());
+ const auto member_iterator = std::ranges::find(enumeration->members, subject.field().name());
if (member_iterator == enumeration->members.end())
{
@@ -344,7 +344,7 @@ namespace elna::boot
{
if (auto *record = std::get_if<constant_aggregate<ordered_map>>(&base.value()))
{
- auto field_iterator = (*record)->find(subject.field().name());
+ const auto field_iterator = (*record)->find(subject.field().name());
return field_iterator != std::cend(**record)
? std::make_optional(field_iterator->second)
@@ -355,7 +355,7 @@ namespace elna::boot
{
return constant_value{ integer_literal::from((*vector)->size()) };
}
- else if (auto *string_value = std::get_if<std::string>(&base.value()); subject.field() == "length")
+ else if (const auto *string_value = std::get_if<std::string>(&base.value()); subject.field() == "length")
{
return constant_value{ integer_literal::from(string_value->size()) };
}
@@ -370,7 +370,7 @@ namespace elna::boot
{
return std::nullopt;
}
- auto& index_literal = std::get<integer_literal>(evaluated_index.value());
+ const integer_literal& index_literal = std::get<integer_literal>(evaluated_index.value());
return index_literal < 0 ? std::nullopt : index_literal.try_to<std::size_t>();
}
@@ -389,8 +389,8 @@ namespace elna::boot
{
return std::nullopt;
}
- auto slice_begin = std::next((*array)->begin(), static_cast<std::ptrdiff_t>(start_index.value() - 1));
- auto slice_end = std::next((*array)->begin(), static_cast<std::ptrdiff_t>(end_index.value()));
+ const auto slice_begin = std::next((*array)->begin(), static_cast<std::ptrdiff_t>(start_index.value() - 1));
+ const auto slice_end = std::next((*array)->begin(), static_cast<std::ptrdiff_t>(end_index.value()));
return constant_value{
constant_aggregate<std::vector>{ std::vector<constant_value>(slice_begin, slice_end) }
@@ -687,7 +687,7 @@ namespace elna::boot
}
return std::visit([&rhs, operation = subject.operation()](auto&& lhs_value) {
using T = std::decay_t<decltype(lhs_value)>;
- auto rhs_value = std::get<T>(rhs.value());
+ const T rhs_value = std::get<T>(rhs.value());
return evaluate_operation<T>(operation, lhs_value, rhs_value);
}, lhs.value());
@@ -921,13 +921,11 @@ namespace elna::boot
{
return source_expression;
}
- if (const auto *address = std::get_if<integer_literal>(&source_expression))
+ // Only the null pointer has a constant representation.
+ else if (const auto *address = std::get_if<integer_literal>(&source_expression);
+ *address == std::ptrdiff_t{ 0 })
{
- // Only the null pointer has a constant representation.
- if (*address == std::ptrdiff_t{ 0 })
- {
- return constant_value{ nullptr };
- }
+ return constant_value{ nullptr };
}
return std::nullopt;
}
@@ -1056,7 +1054,7 @@ namespace elna::boot
{
return constant_value{ float_literal::from(std::numeric_limits<double>::min()) };
}
- if (auto enumeration = resolved.get<enumeration_type>())
+ if (const auto enumeration = resolved.get<enumeration_type>())
{
return constant_value{ integer_literal::from<std::size_t>(1) };
}
@@ -1101,22 +1099,22 @@ namespace elna::boot
{
return constant_value{ float_literal::from(std::numeric_limits<double>::max()) };
}
- if (auto enumeration = resolved.get<enumeration_type>())
+ if (const auto enumeration = resolved.get<enumeration_type>())
{
return constant_value{ integer_literal::from(enumeration->members.size()) };
}
}
else if (subject.name.name() == "offset")
{
- auto *field = subject.arguments.at(1)->is_named();
- auto record = erase_generic(subject.types.front()).get<record_type>();
+ const named_expression *field = subject.arguments.at(1)->is_named();
+ const std::shared_ptr<record_type> record = erase_generic(subject.types.front()).get<record_type>();
if (field == nullptr || record == nullptr)
{
return std::nullopt;
}
if (auto record_layout = layout_record(record, this->target))
{
- auto field_search = record_layout.value().offset_map.find(field->name);
+ const auto field_search = record_layout.value().offset_map.find(field->name);
if (field_search != std::cend(record_layout.value().offset_map))
{
diff --git a/boot/lexer.ll b/boot/lexer.ll
index 3d881e3..6fa1904 100644
--- a/boot/lexer.ll
+++ b/boot/lexer.ll
@@ -55,7 +55,7 @@ EXPONENT [eE][+-]?[[:digit:]]+
%%
%{
- if (driver.finished)
+ if (driver.has_finished())
{
return yy::parser::make_YYEOF(this->location);
}
@@ -197,6 +197,9 @@ to {
program {
return yy::parser::make_PROGRAM(this->location);
}
+module {
+ return yy::parser::make_MODULE(this->location);
+}
{ID1}{ID2}* {
return yy::parser::make_IDENTIFIER(yytext, this->location);
}
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index 18aaca2..5d5bd34 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -195,7 +195,7 @@ namespace elna::boot
if (is_enum || is_record)
{
std::string message = is_enum ? "Enumeration" : "Record";
- if (auto alias = this->composite.get<alias_type>())
+ if (const auto alias = this->composite.get<alias_type>())
{
message += " '" + alias->name + "'";
}
@@ -220,7 +220,7 @@ namespace elna::boot
const std::string kind = is_enum ? "member" : "field";
std::string message = is_enum ? "Enumeration" : "Record";
- if (auto alias = this->composite.get<alias_type>())
+ if (const auto alias = this->composite.get<alias_type>())
{
message += " '" + alias->name + "'";
}
@@ -267,7 +267,7 @@ namespace elna::boot
static void collect_field_names(const type& composite_type,
ordered_map<field_origin>& names)
{
- auto record = erase_generic(composite_type).get<record_type>();
+ const std::shared_ptr<record_type> record = erase_generic(composite_type).get<record_type>();
if (record == nullptr)
{
return;
@@ -276,7 +276,7 @@ namespace elna::boot
{
collect_field_names(record->base, names);
}
- for (auto& field : record->fields)
+ for (const auto& field : record->fields)
{
names.insert(field.first, field_origin{ .position = std::nullopt, .base_type = composite_type });
}
@@ -435,7 +435,7 @@ namespace elna::boot
if (!existing->second.position.has_value()
&& !existing->second.base_type.empty())
{
- if (auto alias = existing->second.base_type.get<alias_type>())
+ if (const auto alias = existing->second.base_type.get<alias_type>())
{
base_name = alias->name;
}
@@ -471,7 +471,7 @@ namespace elna::boot
if (!this->bag.enter(name, variable_symbol))
{
- auto original = this->bag.lookup(name);
+ const std::shared_ptr<info> original = this->bag.lookup(name);
symbol_declaration_error::redefinition original_definition{
.original = original->position,
.file = this->redefinition_file(original)
@@ -490,7 +490,7 @@ namespace elna::boot
}
if (field_name == "ptr")
{
- auto pointer = type(std::make_shared<pointer_type>(element_type));
+ const type pointer = type(std::make_shared<pointer_type>(element_type));
return type(std::make_shared<constant_type>(pointer));
}
return std::nullopt;
@@ -506,9 +506,9 @@ namespace elna::boot
}
const type resolved_type = resolve_underlying_type(composite_type);
- if (auto range_base = get_range_base_type(resolved_type))
+ if (const auto range_base = get_range_base_type(resolved_type))
{
- if (auto field = lookup_pointer_like_field(field_name, range_base))
+ if (const auto field = lookup_pointer_like_field(field_name, range_base))
{
return field.value();
}
@@ -524,18 +524,18 @@ namespace elna::boot
for (const identifier& parameter : parameters)
{
const type parameter_symbol = type(std::make_shared<parameter_type>(parameter.name()));
- auto info = std::make_shared<type_info>(parameter_symbol);
+ const std::shared_ptr<type_info> info_object = std::make_shared<type_info>(parameter_symbol);
- info->position.emplace(parameter.position());
- info->file = this->module_file;
+ info_object->position.emplace(parameter.position());
+ info_object->file = this->module_file;
- if (this->bag.enter(parameter.name(), info))
+ if (this->bag.enter(parameter.name(), info_object))
{
result.push_back(parameter_symbol);
}
else
{
- auto original = this->bag.lookup(parameter.name());
+ const std::shared_ptr<info> original = this->bag.lookup(parameter.name());
add_error<symbol_declaration_error>(parameter.position(), parameter.name(),
symbol_declaration_error::redefinition{
@@ -556,7 +556,7 @@ namespace elna::boot
// to something other than a type is left to report.
if (this->current_type.empty())
{
- if (auto *named = expression.is_named();
+ if (const auto *named = expression.is_named();
named != nullptr && this->bag.lookup(named->name) != nullptr)
{
add_error<symbol_declaration_error>(named->position(),
@@ -639,13 +639,13 @@ namespace elna::boot
{
type base_type;
- if (auto unresolved_alias = this->bag.declared(expression->base.value().name()))
+ if (const auto unresolved_alias = this->bag.declared(expression->base.value().name()))
{
base_type = type(unresolved_alias);
}
- else if (auto base_symbol = this->bag.lookup(expression->base.value().name()))
+ else if (const auto base_symbol = this->bag.lookup(expression->base.value().name()))
{
- if (auto base_type_info = base_symbol->is_type())
+ if (const auto base_type_info = base_symbol->is_type())
{
base_type = base_type_info->symbol;
}
@@ -708,7 +708,7 @@ namespace elna::boot
for (const auto& member : expression->members)
{
- auto existing = seen.find(member.name());
+ const std::map<std::string, source_position>::const_iterator existing = seen.find(member.name());
if (existing != seen.end())
{
add_error<member_error>(member.position(), member.name(), aggregate,
@@ -799,13 +799,13 @@ namespace elna::boot
statement->body.symbols = this->bag.enter();
- auto label_symbol = std::make_shared<label_info>(this->defer_depth);
+ const std::shared_ptr<label_info> label_symbol = std::make_shared<label_info>(this->defer_depth);
label_symbol->position.emplace(statement->name.position());
label_symbol->file = this->module_file;
if (!this->bag.enter(label_name, label_symbol))
{
- auto original = this->bag.lookup(label_name);
+ const std::shared_ptr<info> original = this->bag.lookup(label_name);
symbol_declaration_error::redefinition original_definition{
.original = original->position,
.file = this->redefinition_file(original)
@@ -829,7 +829,7 @@ namespace elna::boot
symbol_declaration_error::kind::undeclared_label);
return;
}
- auto label_symbol = symbol->is_label();
+ const std::shared_ptr<label_info> label_symbol = symbol->is_label();
if (label_symbol == nullptr)
{
@@ -867,7 +867,7 @@ namespace elna::boot
void resolving_visitor::visit(procedure_call *call)
{
call->callable().accept(this);
- if (auto procedure = call->callable().type_decoration.get<procedure_type>())
+ if (const auto procedure = call->callable().type_decoration.get<procedure_type>())
{
call->type_decoration = procedure->return_type.proper_type;
}
@@ -888,9 +888,9 @@ namespace elna::boot
void resolving_visitor::visit(record_constructor_expression *expression)
{
- if (auto type_symbol = this->bag.lookup(expression->type_name.name()))
+ if (const auto type_symbol = this->bag.lookup(expression->type_name.name()))
{
- if (auto type_info = type_symbol->is_type())
+ if (const auto type_info = type_symbol->is_type())
{
expression->type_decoration = expression->arguments.empty()
? type_info->symbol
@@ -918,7 +918,7 @@ namespace elna::boot
void resolving_visitor::visit(array_constructor_expression *expression)
{
- for (auto *element : expression->elements)
+ for (auto *const element : expression->elements)
{
element->accept(this);
}
@@ -931,17 +931,17 @@ namespace elna::boot
void resolving_visitor::visit(slicing_expression *expression)
{
expression->base().accept(this);
- auto resolved_base = resolve_underlying_type(expression->base().type_decoration);
+ const type resolved_base = resolve_underlying_type(expression->base().type_decoration);
- if (auto pointer = resolved_base.get<pointer_type>())
+ if (const auto pointer = resolved_base.get<pointer_type>())
{
expression->type_decoration = type(std::make_shared<slice_type>(pointer->base));
}
- else if (auto array = resolved_base.get<array_type>())
+ else if (const auto array = resolved_base.get<array_type>())
{
expression->type_decoration = type(std::make_shared<slice_type>(array->base));
}
- else if (auto slice = resolved_base.get<slice_type>())
+ else if (const auto slice = resolved_base.get<slice_type>())
{
expression->type_decoration = type(slice);
}
@@ -1027,21 +1027,21 @@ namespace elna::boot
{
this->current_type = type();
- if (auto unresolved_alias = this->bag.declared(expression->name))
+ if (const auto unresolved_alias = this->bag.declared(expression->name))
{
this->current_type = type(unresolved_alias);
}
- else if (auto from_symbol_table = this->bag.lookup(expression->name))
+ else if (const auto from_symbol_table = this->bag.lookup(expression->name))
{
- if (auto type_symbol = from_symbol_table->is_type())
+ if (const auto type_symbol = from_symbol_table->is_type())
{
this->current_type = type_symbol->symbol;
}
- else if (auto variable_symbol = from_symbol_table->is_variable())
+ else if (const auto variable_symbol = from_symbol_table->is_variable())
{
expression->type_decoration = variable_symbol->symbol;
}
- else if (auto procedure_symbol = from_symbol_table->is_procedure())
+ else if (const auto procedure_symbol = from_symbol_table->is_procedure())
{
type procedure = type(std::make_shared<procedure_type>(procedure_symbol->symbol));
@@ -1051,7 +1051,7 @@ namespace elna::boot
procedure = substitute(procedure, procedure_symbol->parameters,
expression->argument_types);
}
- expression->type_decoration = procedure;
+ std::swap(expression->type_decoration, procedure);
return;
}
}
@@ -1092,11 +1092,11 @@ namespace elna::boot
{
expression->base().accept(this);
expression->index().accept(this);
- auto resolved_base = resolve_underlying_type(expression->base().type_decoration);
+ const type resolved_base = resolve_underlying_type(expression->base().type_decoration);
if (auto range_base = get_range_base_type(resolved_base))
{
- expression->type_decoration = range_base;
+ std::swap(expression->type_decoration, range_base);
// Elements of a constant array are constant themselves since a static
// array is a holistic type.
@@ -1113,11 +1113,11 @@ namespace elna::boot
// Handling field access on a type (only valid for enumerations).
if (!this->current_type.empty())
{
- auto resolved_base = resolve_underlying_type(this->current_type);
+ const type resolved_base = resolve_underlying_type(this->current_type);
- if (auto enumeration_base = resolved_base.get<enumeration_type>())
+ if (const auto enumeration_base = resolved_base.get<enumeration_type>())
{
- auto member_iterator = std::ranges::find(enumeration_base->members, expression->field().name());
+ const auto member_iterator = std::ranges::find(enumeration_base->members, expression->field().name());
if (member_iterator == enumeration_base->members.cend())
{
@@ -1158,7 +1158,7 @@ namespace elna::boot
{
expression->base().accept(this);
- if (auto pointer = resolve_underlying_type(expression->base().type_decoration).get<pointer_type>())
+ if (const auto pointer = resolve_underlying_type(expression->base().type_decoration).get<pointer_type>())
{
expression->type_decoration = pointer->base;
}
@@ -1251,7 +1251,7 @@ namespace elna::boot
* cycle is behind a pointer or a slice, so that the record layout
* stays finite. All other cycles are rejected.
*/
- if (auto link = referent.get<alias_type>())
+ if (const auto link = referent.get<alias_type>())
{
if (std::ranges::find(alias_path, link->name) != std::cend(alias_path))
{
@@ -1270,38 +1270,38 @@ namespace elna::boot
}
return acyclic;
}
- else if (auto link = referent.get<constant_type>())
+ else if (const auto link = referent.get<constant_type>())
{
return find_alias_cycle(being_resolved, link->unqualified, alias_path, state);
}
- else if (auto link = referent.get<pointer_type>())
+ else if (const auto link = referent.get<pointer_type>())
{
walk_state guarded_state = state;
guarded_state.guarded = true;
return find_alias_cycle(being_resolved, link->base, alias_path, guarded_state);
}
- else if (auto link = referent.get<slice_type>())
+ else if (const auto link = referent.get<slice_type>())
{
walk_state guarded_state = state;
guarded_state.guarded = true;
return find_alias_cycle(being_resolved, link->base, alias_path, guarded_state);
}
- else if (auto link = referent.get<array_type>())
+ else if (const auto link = referent.get<array_type>())
{
return find_alias_cycle(being_resolved, link->base, alias_path, state);
}
- else if (auto link = referent.get<generic_type>())
+ else if (const auto link = referent.get<generic_type>())
{
return find_alias_cycle(being_resolved, link->referent, alias_path, state);
}
- else if (auto link = referent.get<instantiated_type>())
+ else if (const auto link = referent.get<instantiated_type>())
{
// Erasure is argument blind, so the arguments cannot close a cycle
// the generic does not close on its own. This is what lets
// polymorphic recursion terminate.
return find_alias_cycle(being_resolved, link->generic, alias_path, state);
}
- else if (auto link = referent.get<procedure_type>())
+ else if (const auto link = referent.get<procedure_type>())
{
const std::size_t saved_path = alias_path.size();
@@ -1320,7 +1320,7 @@ namespace elna::boot
}
return true;
}
- else if (auto link = referent.get<record_type>())
+ else if (const auto link = referent.get<record_type>())
{
const std::size_t saved_path = alias_path.size();
walk_state in_record = state;
@@ -1353,7 +1353,7 @@ namespace elna::boot
}
if (unit->entry_point.has_value())
{
- auto word8_primitive = lookup_primitive_type("Word8");
+ const type word8_primitive = lookup_primitive_type("Word8");
const procedure_type::return_t result_return = procedure_type::return_t(word8_primitive);
auto heading = procedure_type(result_return);
std::shared_ptr<procedure_info> info;
@@ -1385,8 +1385,6 @@ namespace elna::boot
info->position = unit->entry_position;
info->file = this->module_file;
- // A unit has at most one entry point and an imported program is
- // rejected before its symbols are merged, so this cannot collide.
this->bag.enter("", info);
}
}
@@ -1411,23 +1409,22 @@ namespace elna::boot
// Reject the cycle and wire an empty referent: the declaration still
// resolves and is entered, so its uses degrade silently.
- if (auto cycle = find_alias_cycle(
- this->bag.declared(declaration->identifier.name()), underlying))
+ if (const auto cycle = find_alias_cycle(this->bag.declared(declaration->identifier.name()), underlying))
{
add_error<cyclic_declaration_error>(declaration->position(), *cycle);
underlying = type();
}
const std::shared_ptr<alias_type> resolved =
this->bag.resolve(declaration->identifier.name(), underlying);
- auto info = std::make_shared<type_info>(type(resolved));
+ const std::shared_ptr<type_info> info_object = std::make_shared<type_info>(type(resolved));
- info->exported = declaration->identifier.exported();
- info->position.emplace(declaration->position());
- info->file = this->module_file;
+ info_object->exported = declaration->identifier.exported();
+ info_object->position.emplace(declaration->position());
+ info_object->file = this->module_file;
- if (!this->bag.enter(declaration->identifier.name(), info))
+ if (!this->bag.enter(declaration->identifier.name(), info_object))
{
- auto original = this->bag.lookup(declaration->identifier.name());
+ const std::shared_ptr<info> original = this->bag.lookup(declaration->identifier.name());
symbol_declaration_error::redefinition original_definition{
.original = original->position,
.file = this->redefinition_file(original)
@@ -1455,7 +1452,7 @@ namespace elna::boot
}
else if (!declaration->is_extern && resolve_aliases(variable_type).get<constant_type>() != nullptr)
{
- auto position_span = source_position(
+ const source_position position_span = source_position(
declaration->identifiers.front().id().position().start(),
declaration->identifiers.back().id().position().end());
add_error<declaration_format_error>(position_span,
@@ -1463,7 +1460,7 @@ namespace elna::boot
}
for (const auto& variable_identifier : declaration->identifiers)
{
- auto variable_symbol = register_variable(variable_identifier.name(),
+ const std::shared_ptr<variable_info> variable_symbol = register_variable(variable_identifier.name(),
variable_type, declaration->position(), declaration->is_extern);
variable_symbol->exported = variable_identifier.exported();
variable_symbol->alignment =
@@ -1482,18 +1479,19 @@ namespace elna::boot
const std::vector<type> type_parameters = enter_parameters(declaration->parameters);
auto [heading, parameter_names] =
build_procedure(declaration->heading(), !declaration->body.has_value());
- std::shared_ptr<procedure_info> info;
+ std::shared_ptr<procedure_info> info_object;
if (declaration->body.has_value())
{
- info = std::make_shared<procedure_info>(heading, std::move(parameter_names), scope);
- auto name_iterator = std::cbegin(info->names);
- auto type_iterator = std::cbegin(info->symbol.parameters);
+ info_object = std::make_shared<procedure_info>(heading, std::move(parameter_names), scope);
+ auto name_iterator = std::cbegin(info_object->names);
+ auto type_iterator = std::cbegin(info_object->symbol.parameters);
- while (name_iterator != std::cend(info->names) && type_iterator != std::cend(info->symbol.parameters))
+ while (name_iterator != std::cend(info_object->names)
+ && type_iterator != std::cend(info_object->symbol.parameters))
{
- auto variable_symbol = register_variable(*name_iterator, *type_iterator,
- declaration->heading().position());
+ const std::shared_ptr<variable_info> variable_symbol =
+ register_variable(*name_iterator, *type_iterator, declaration->heading().position());
++name_iterator;
++type_iterator;
@@ -1501,16 +1499,16 @@ namespace elna::boot
}
else
{
- info = std::make_shared<procedure_info>(heading, std::move(parameter_names));
+ info_object = std::make_shared<procedure_info>(heading, std::move(parameter_names));
}
this->bag.leave();
- info->parameters = type_parameters;
- info->exported = declaration->identifier.exported();
- info->position.emplace(declaration->position());
- info->file = this->module_file;
- if (!this->bag.enter(declaration->identifier.name(), info))
+ info_object->parameters = type_parameters;
+ info_object->exported = declaration->identifier.exported();
+ info_object->position.emplace(declaration->position());
+ info_object->file = this->module_file;
+ if (!this->bag.enter(declaration->identifier.name(), info_object))
{
- auto original = this->bag.lookup(declaration->identifier.name());
+ const std::shared_ptr<info> original = this->bag.lookup(declaration->identifier.name());
symbol_declaration_error::redefinition original_definition{
.original = original->position,
.file = this->redefinition_file(original)
@@ -1541,9 +1539,11 @@ namespace elna::boot
{
const std::shared_ptr<procedure_info> info = this->bag.lookup("")->is_procedure();
- unit->entry_point->symbols = info->scope;
this->bag.enter(info->scope);
- traverse_body(this, unit->entry_point.value());
+ for (statement *body_statement : unit->entry_point.value())
+ {
+ body_statement->accept(this);
+ }
this->bag.leave();
}
}
@@ -1564,7 +1564,7 @@ namespace elna::boot
}
else if (resolve_aliases(variable_type).get<constant_type>() != nullptr)
{
- auto position_span = source_position(
+ const source_position position_span = source_position(
declaration->identifiers.front().id().position().start(),
declaration->identifiers.back().id().position().end());
add_error<declaration_format_error>(position_span,
@@ -1572,7 +1572,7 @@ namespace elna::boot
}
for (const auto& variable_identifier : declaration->identifiers)
{
- auto variable_symbol = register_variable(variable_identifier.name(),
+ const std::shared_ptr<variable_info> variable_symbol = register_variable(variable_identifier.name(),
variable_type, declaration->position(), declaration->is_extern);
variable_symbol->exported = variable_identifier.exported();
variable_symbol->alignment =
@@ -1598,7 +1598,7 @@ namespace elna::boot
void name_analysis_visitor::visit(for_statement *statement)
{
statement->range().accept(this);
- auto resolved_range = resolve_underlying_type(statement->range().type_decoration);
+ const type resolved_range = resolve_underlying_type(statement->range().type_decoration);
const type control_variable_base_type = get_range_base_type(resolved_range);
const type control_variable_pointer_type = type(std::make_shared<pointer_type>(control_variable_base_type));
const type control_variable_const_type = type(std::make_shared<constant_type>(control_variable_pointer_type));
diff --git a/boot/parser.yy b/boot/parser.yy
index 01dfa80..1e732c6 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -95,12 +95,11 @@ along with GCC; see the file COPYING3. If not see
EXCLAMATION "!" ARROW "->"
AT "@" HAT "^"
COLON ":" SEMICOLON ";" DOT "." COMMA ","
-%token PROGRAM "program"
+%token PROGRAM "program" MODULE "module"
CAST "cast"
NIL "nil"
CONST "const"
- VAR "var"
- THREADVAR "threadvar"
+ VAR "var" THREADVAR "threadvar"
PROCEDURE "proc"
TYPE "type"
RECORD "record"
@@ -135,7 +134,7 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::switch_case> switch_case;
%type <std::vector<elna::boot::switch_case>> switch_cases;
%type <elna::boot::variable_declaration *> variable_declaration;
-%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part;
+%type <std::vector<elna::boot::variable_declaration *>> variable_declarations;
%type <elna::boot::type_expression *> type_expression;
%type <std::vector<elna::boot::type_expression *>> type_expressions;
%type <elna::boot::expression *> expression operand simple_expression procedure_return unary_expression;
@@ -144,14 +143,15 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::designator_expression *> designator_expression;
%type <std::unique_ptr<elna::boot::procedure_call>> call_expression;
%type <elna::boot::statement *> statement;
-%type <std::vector<elna::boot::statement *>> statements statement_part;
+%type <std::vector<elna::boot::statement *>> statements statement_part optional_begin_statements;
%type <elna::boot::block> block;
%type <elna::boot::procedure_declaration *> procedure_declaration;
%type <std::unique_ptr<elna::boot::procedure_type_expression>> procedure_heading;
%type <elna::boot::procedure_type_expression::return_t> return_declaration;
%type <std::unique_ptr<elna::boot::type_declaration>> type_declaration;
-%type <std::vector<elna::boot::declaration *>> type_declarations;
-%type <std::vector<elna::boot::declaration *>> module_declaration module_declarations;
+%type <std::vector<elna::boot::declaration *>> type_declarations sections section;
+%type <std::pair<std::vector<elna::boot::import_declaration *>, std::vector<elna::boot::declaration *>>>
+ required_declarations optional_declarations;
%type <std::unique_ptr<elna::boot::procedure_body>> procedure_body;
%type <elna::boot::field_declaration> field_declaration;
%type <std::vector<elna::boot::field_declaration>> field_declarations;
@@ -167,31 +167,38 @@ along with GCC; see the file COPYING3. If not see
%type <std::vector<std::string>> import_declaration;
%type <std::vector<elna::boot::identifier>> required_identifiers optional_identifiers generic_parameters;
%type <elna::boot::named_expression *> name_reference;
-%type <std::vector<elna::boot::import_declaration *>> import_declarations import_part;
+%type <std::vector<elna::boot::import_declaration *>> import_declarations;
%type <std::unique_ptr<elna::boot::array_type_expression>> array_type_expression;
+%type <std::unique_ptr<elna::boot::unit>> unit;
%%
-program:
- import_part module_declarations "end" "."
+program: unit
{
- driver.finished = true;
+ driver.tree = $1;
+ }
+unit:
+ "module" optional_declarations "end" "."
+ {
+ auto [modules, sections] = $2;
- boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2);
- driver.tree.reset(tree);
+ $$ = std::make_unique<boot::unit>(boot::make_position(@$), std::move(modules), std::move(sections));
}
- | import_part module_declarations
- "program" "(" optional_identifiers ")" procedure_body "end" "."
+ | "program" "(" optional_identifiers ")" required_declarations statement_part "end" "."
{
- driver.finished = true;
+ auto [modules, sections] = $5;
- boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2,
- std::move($5), boot::make_position(@3), std::move(*$7));
- driver.tree.reset(tree);
+ $$ = std::make_unique<boot::unit>(boot::make_position(@$), std::move(modules),
+ std::move(sections), $3, boot::make_position(@1), $6);
}
-module_declaration:
+ | "program" "(" optional_identifiers ")" optional_begin_statements "end" "."
+ {
+ $$ = std::make_unique<boot::unit>(boot::make_position(@$), std::vector<boot::import_declaration *>{},
+ std::vector<boot::declaration *>{}, $3, boot::make_position(@1), $5);
+ }
+section:
"type" type_declarations { $$ = $2; }
- | variable_part
+ | "var" variable_declarations
{
- std::vector<boot::variable_declaration *> variables = $1;
+ std::vector<boot::variable_declaration *> variables = $2;
$$.insert($$.end(), variables.begin(), variables.end());
}
@@ -206,33 +213,36 @@ module_declaration:
$$.insert($$.end(), variables.begin(), variables.end());
}
| procedure_declaration { $$.emplace_back($1); }
-module_declarations:
+required_declarations:
+ sections { $$ = { {}, $1 }; }
+ | "import" import_declarations { $$ = { $2, {} }; }
+ | "import" import_declarations sections { $$ = { $2, $3 }; }
+optional_declarations:
%empty {}
- | module_declaration module_declarations
+ | required_declarations { $$ = $1; }
+sections:
+ section sections
{
std::vector<boot::declaration *> appendix = $2;
$$ = $1;
$$.insert($$.end(), appendix.begin(), appendix.end());
}
+ | section { $$ = $1; }
procedure_body:
block procedure_return
{ $$ = std::make_unique<boot::procedure_body>(std::move($1), $2); }
-
-variable_part:
- "var" variable_declarations { $$ = $2; }
-
block:
- variable_part statement_part
- { $$ = boot::block(std::move($1), std::move($2)); }
- | "begin" statements
- { $$ = boot::block(std::vector<boot::variable_declaration *>(), std::move($2)); }
- | statements
+ "var" variable_declarations statement_part
+ { $$ = boot::block(std::move($2), std::move($3)); }
+ | optional_begin_statements
{ $$ = boot::block(std::vector<boot::variable_declaration *>(), std::move($1)); }
-
statement_part:
%empty {}
| "begin" statements { $$ = $2; }
+optional_begin_statements:
+ "begin" statements { $$ = $2; }
+ | statements { $$ = $1; }
identifier:
IDENTIFIER { $$ = std::make_unique<boot::identifier>($1, boot::make_position(@1)); }
identifier_definition:
@@ -739,9 +749,6 @@ import_declarations:
{
$$.emplace_back(new boot::import_declaration(boot::make_position(@$), $1));
}
-import_part:
- %empty {}
- | "import" import_declarations { $$ = $2; }
type_declaration: identifier_definition generic_parameters "=" type_expression
{
$$ = std::make_unique<boot::type_declaration>(boot::make_position(@$), std::move(*$1), $4);
diff --git a/boot/result.cc b/boot/result.cc
index c8ea267..71326c0 100644
--- a/boot/result.cc
+++ b/boot/result.cc
@@ -131,7 +131,7 @@ namespace elna::boot
std::optional<diagnostic_note> identifier_list_note(
const std::vector<identifier>& identifiers)
{
- auto position_span = source_position(identifiers.front().position().start(),
+ const source_position position_span = source_position(identifiers.front().position().start(),
identifiers.back().position().end());
return diagnostic_note{ .message = join(identifiers), .position = position_span, .file = {} };
@@ -501,7 +501,7 @@ namespace elna::boot
constexpr std::size_t shortest_round_trip = 24;
std::array<char, shortest_round_trip + 4> buffer;
- auto float_chars = std::to_chars(buffer.begin(), buffer.end(), this->raw);
+ const std::to_chars_result float_chars = std::to_chars(buffer.begin(), buffer.end(), this->raw);
return std::string(buffer.begin(), float_chars.ptr);
}
@@ -557,7 +557,8 @@ std::size_t std::hash<elna::boot::constant_aggregate<std::vector>>::operator()(
const elna::boot::constant_aggregate<std::vector>& key) const noexcept
{
const elna::boot::constant_value_hash hasher{};
- auto hash = std::accumulate(key->begin(), key->end(), elna::boot::hash_accumulator{},
+ const elna::boot::hash_accumulator hash = std::accumulate(key->begin(), key->end(),
+ elna::boot::hash_accumulator{},
[&hasher](const auto& accumulator, const auto& element) {
return accumulator + hasher(element);
});
@@ -569,7 +570,8 @@ std::size_t std::hash<elna::boot::constant_aggregate<elna::boot::ordered_map>>::
const elna::boot::constant_aggregate<elna::boot::ordered_map>& key) const noexcept
{
const elna::boot::constant_value_hash hasher{};
- auto hash = std::accumulate(key->begin(), key->end(), elna::boot::hash_accumulator{},
+ const elna::boot::hash_accumulator hash = std::accumulate(key->begin(), key->end(),
+ elna::boot::hash_accumulator{},
[&hasher](const auto& accumulator, const auto& element) {
return accumulator + std::hash<std::string>{}(element.first) + hasher(element.second);
});
diff --git a/boot/symbol.cc b/boot/symbol.cc
index 962808a..54cb595 100644
--- a/boot/symbol.cc
+++ b/boot/symbol.cc
@@ -67,77 +67,80 @@ namespace elna::boot
bool type::operator==(const type& other) const
{
- type const resolved_this = resolve_aliases(*this);
- type const resolved_that = resolve_aliases(other);
+ const type resolved_this = resolve_aliases(*this);
+ const type resolved_that = resolve_aliases(other);
- if (auto left_record = resolved_this.get<record_type>())
+ if (const auto left_record = resolved_this.get<record_type>())
{
return left_record == resolved_that.get<record_type>();
}
- if (auto left_primitive = resolved_this.get<primitive_type>())
+ else if (const auto left_primitive = resolved_this.get<primitive_type>())
{
- auto right_primitive = resolved_that.get<primitive_type>();
+ const std::shared_ptr<primitive_type> right_primitive = resolved_that.get<primitive_type>();
return right_primitive != nullptr && left_primitive->identifier == right_primitive->identifier;
}
- if (auto left_enumeration = resolved_this.get<enumeration_type>())
+ else if (const auto left_enumeration = resolved_this.get<enumeration_type>())
{
return left_enumeration == resolved_that.get<enumeration_type>();
}
- if (auto left_extern = resolved_this.get<extern_type>())
+ else if (const auto left_extern = resolved_this.get<extern_type>())
{
return left_extern == resolved_that.get<extern_type>();
}
- if (auto left_pointer = resolved_this.get<pointer_type>())
+ else if (const auto left_pointer = resolved_this.get<pointer_type>())
{
- auto right_pointer = resolved_that.get<pointer_type>();
+ const std::shared_ptr<pointer_type> right_pointer = resolved_that.get<pointer_type>();
return right_pointer != nullptr && left_pointer->base == right_pointer->base;
}
- if (auto left_const = resolved_this.get<constant_type>())
+ else if (const auto left_const = resolved_this.get<constant_type>())
{
- auto right_const = resolved_that.get<constant_type>();
+ const std::shared_ptr<constant_type> right_const = resolved_that.get<constant_type>();
return right_const != nullptr && left_const->unqualified == right_const->unqualified;
}
- if (auto left_array = resolved_this.get<array_type>())
+ else if (const auto left_array = resolved_this.get<array_type>())
{
- auto right_array = resolved_that.get<array_type>();
+ const std::shared_ptr<array_type> right_array = resolved_that.get<array_type>();
return right_array != nullptr && left_array->size == right_array->size
&& left_array->base == right_array->base;
}
- if (auto left_slice = resolved_this.get<slice_type>())
+ else if (const auto left_slice = resolved_this.get<slice_type>())
{
- auto right_slice = resolved_that.get<slice_type>();
+ const std::shared_ptr<slice_type> right_slice = resolved_that.get<slice_type>();
return right_slice != nullptr && left_slice->base == right_slice->base;
}
- if (auto left_procedure = resolved_this.get<procedure_type>())
+ else if (const auto left_procedure = resolved_this.get<procedure_type>())
{
- auto right_procedure = resolved_that.get<procedure_type>();
+ const std::shared_ptr<procedure_type> right_procedure = resolved_that.get<procedure_type>();
return right_procedure != nullptr && left_procedure->return_type == right_procedure->return_type
&& left_procedure->parameters == right_procedure->parameters
&& left_procedure->variadic == right_procedure->variadic;
}
- if (auto left_parameter = resolved_this.get<parameter_type>())
+ else if (const auto left_parameter = resolved_this.get<parameter_type>())
{
return left_parameter == resolved_that.get<parameter_type>();
}
- if (auto left_generic = resolved_this.get<generic_type>())
+ else if (const auto left_generic = resolved_this.get<generic_type>())
{
return left_generic == resolved_that.get<generic_type>();
}
- if (auto left_instance = resolved_this.get<instantiated_type>())
+ else if (const auto left_instance = resolved_this.get<instantiated_type>())
{
- auto right_instance = resolved_that.get<instantiated_type>();
+ const std::shared_ptr<instantiated_type> right_instance = resolved_that.get<instantiated_type>();
return right_instance != nullptr
&& left_instance->generic == right_instance->generic
&& left_instance->arguments == right_instance->arguments;
}
- return resolved_this.empty() && resolved_that.empty();
+ else
+ {
+ return resolved_this.empty() && resolved_that.empty();
+ }
}
type::operator bool() const
@@ -378,14 +381,14 @@ namespace elna::boot
// matching the machine word.
if (bit_size == properties.front().size * CHAR_BIT)
{
- auto alias = std::make_shared<alias_type>(integer_name, variant_type);
+ const std::shared_ptr<alias_type> alias = std::make_shared<alias_type>(integer_name, variant_type);
symbols->enter(integer_name, std::make_shared<type_info>(type(alias)));
}
}
if (!symbols->contains(integer_name))
{
- auto variant_type = type(std::make_shared<primitive_type>(integer_name, properties.front()));
+ const type variant_type = type(std::make_shared<primitive_type>(integer_name, properties.front()));
symbols->enter(integer_name, std::make_shared<type_info>(variant_type));
}
@@ -489,14 +492,14 @@ namespace elna::boot
std::shared_ptr<alias_type> symbol_bag::declared(const std::string& symbol_name)
{
- auto unresolved_alias = this->unresolved.find(symbol_name);
+ const auto unresolved_alias = this->unresolved.find(symbol_name);
return unresolved_alias == this->unresolved.end() ? std::shared_ptr<alias_type>() : unresolved_alias->second;
}
std::shared_ptr<alias_type> symbol_bag::resolve(const std::string& symbol_name, type& resolution)
{
- auto unresolved_node = this->unresolved.extract(symbol_name);
+ const auto unresolved_node = this->unresolved.extract(symbol_name);
assert(!unresolved_node.empty());
auto unresolved_declaration = unresolved_node.mapped();
@@ -563,7 +566,7 @@ namespace elna::boot
{
type resolved_alias = resolve_aliases(alias);
- if (auto qualified = resolved_alias.get<constant_type>())
+ if (const auto qualified = resolved_alias.get<constant_type>())
{
return resolve_underlying_type(qualified->unqualified);
}
@@ -575,7 +578,7 @@ namespace elna::boot
type unwrap_aliases(const type& checked)
{
- if (auto alias = checked.get<alias_type>())
+ if (const auto alias = checked.get<alias_type>())
{
return unwrap_aliases(alias->referent);
}
@@ -590,7 +593,7 @@ namespace elna::boot
type substitute(const type& subject, const std::vector<type>& parameters,
const std::vector<type>& arguments)
{
- if (auto parameter = subject.get<parameter_type>())
+ if (const auto parameter = subject.get<parameter_type>())
{
for (std::size_t i = 0; i < parameters.size() && i < arguments.size(); ++i)
{
@@ -601,27 +604,27 @@ namespace elna::boot
}
return subject;
}
- if (auto pointer = subject.get<pointer_type>())
+ else if (const auto pointer = subject.get<pointer_type>())
{
return type(std::make_shared<pointer_type>(
substitute(pointer->base, parameters, arguments)));
}
- if (auto slice = subject.get<slice_type>())
+ else if (const auto slice = subject.get<slice_type>())
{
return type(std::make_shared<slice_type>(
substitute(slice->base, parameters, arguments)));
}
- if (auto array = subject.get<array_type>())
+ else if (const auto array = subject.get<array_type>())
{
return type(std::make_shared<array_type>(
substitute(array->base, parameters, arguments), array->size));
}
- if (auto qualified = subject.get<constant_type>())
+ else if (const auto qualified = subject.get<constant_type>())
{
return type(std::make_shared<constant_type>(
substitute(qualified->unqualified, parameters, arguments)));
}
- if (auto procedure = subject.get<procedure_type>())
+ else if (const auto procedure = subject.get<procedure_type>())
{
procedure_type::return_t result_return = procedure->return_type;
@@ -630,7 +633,7 @@ namespace elna::boot
result_return = procedure_type::return_t(
substitute(result_return.proper_type, parameters, arguments));
}
- auto result = std::make_shared<procedure_type>(std::move(result_return));
+ const std::shared_ptr<procedure_type> result = std::make_shared<procedure_type>(std::move(result_return));
result->variadic = procedure->variadic;
result->parameters.reserve(procedure->parameters.size());
@@ -640,7 +643,7 @@ namespace elna::boot
}
return type(result);
}
- if (auto instance = subject.get<instantiated_type>())
+ else if (const auto instance = subject.get<instantiated_type>())
{
std::vector<type> substituted;
@@ -667,17 +670,20 @@ namespace elna::boot
{
type resolved = resolve_underlying_type(checked);
- if (auto instance = resolved.get<instantiated_type>())
+ if (const auto instance = resolved.get<instantiated_type>())
{
std::shared_ptr<generic_type> const generic = unwrap_generic(instance->generic);
return generic == nullptr ? type() : resolve_underlying_type(generic->referent);
}
- if (auto generic = resolved.get<generic_type>())
+ else if (const auto generic = resolved.get<generic_type>())
{
return resolve_underlying_type(generic->referent);
}
- return resolved;
+ else
+ {
+ return resolved;
+ }
}
/*
@@ -686,13 +692,13 @@ namespace elna::boot
*/
static type substitute_from(const type& subject, const type& taken)
{
- auto instance = subject.get<instantiated_type>();
+ const std::shared_ptr<instantiated_type> instance = subject.get<instantiated_type>();
if (instance == nullptr)
{
return taken;
}
- std::shared_ptr<generic_type> const generic = unwrap_generic(instance->generic);
+ const std::shared_ptr<generic_type> generic = unwrap_generic(instance->generic);
return generic == nullptr
? type()
@@ -702,7 +708,7 @@ namespace elna::boot
type base_of(const type& derived)
{
const type resolved = resolve_underlying_type(derived);
- auto record = erase_generic(resolved).get<record_type>();
+ const std::shared_ptr<record_type> record = erase_generic(resolved).get<record_type>();
return record == nullptr || record->base.empty()
? type()
@@ -723,13 +729,13 @@ namespace elna::boot
type resolve_aliases(const type& checked)
{
- if (auto alias = checked.get<alias_type>())
+ if (const auto alias = checked.get<alias_type>())
{
return resolve_aliases(alias->referent);
}
- if (auto instance = checked.get<instantiated_type>())
+ else if (const auto instance = checked.get<instantiated_type>())
{
- std::shared_ptr<generic_type> const generic = unwrap_generic(instance->generic);
+ const std::shared_ptr<generic_type> generic = unwrap_generic(instance->generic);
// A record referent makes the instantiation nominal, so resolution
// stops here and Stack#[^File] stays distinct from Stack#[^Socket].
@@ -744,7 +750,7 @@ namespace elna::boot
bool is_primitive_type(const type& checked, const std::string& name)
{
- if (auto primitive_checked = checked.get<primitive_type>())
+ if (const auto primitive_checked = checked.get<primitive_type>())
{
return primitive_checked->identifier == name;
}
@@ -753,7 +759,7 @@ namespace elna::boot
bool is_integer_type(const type& checked)
{
- if (auto primitive_checked = checked.get<primitive_type>())
+ if (const auto primitive_checked = checked.get<primitive_type>())
{
return primitive_checked->identifier.starts_with("Int");
}
@@ -762,7 +768,7 @@ namespace elna::boot
bool is_word_type(const type& checked)
{
- if (auto primitive_checked = checked.get<primitive_type>())
+ if (const auto primitive_checked = checked.get<primitive_type>())
{
return primitive_checked->identifier.starts_with("Word");
}
@@ -811,9 +817,9 @@ namespace elna::boot
bool is_string_type(const type& checked)
{
- if (auto slice = checked.get<slice_type>())
+ if (const auto slice = checked.get<slice_type>())
{
- if (auto base = resolve_aliases(slice->base).get<constant_type>())
+ if (const auto base = resolve_aliases(slice->base).get<constant_type>())
{
return is_primitive_type(resolve_aliases(base->unqualified), "Word8");
}
@@ -823,11 +829,11 @@ namespace elna::boot
type get_range_base_type(const type& range)
{
- if (auto array = range.get<array_type>())
+ if (const auto array = range.get<array_type>())
{
return array->base;
}
- else if (auto slice = range.get<slice_type>())
+ else if (const auto slice = range.get<slice_type>())
{
return slice->base;
}
@@ -838,7 +844,7 @@ namespace elna::boot
{
const type resolved_type = resolve_underlying_type(composite_type);
- if (auto record = erase_generic(resolved_type).get<record_type>())
+ if (const auto record = erase_generic(resolved_type).get<record_type>())
{
for (const auto& [name, field] : record->fields)
{
diff --git a/boot/type_check.cc b/boot/type_check.cc
index 5d5bc59..7be236d 100644
--- a/boot/type_check.cc
+++ b/boot/type_check.cc
@@ -44,7 +44,7 @@ namespace elna::boot
__builtin_unreachable();
}
- static std::string print_binary_operator(const binary_operator operation)
+ static std::string_view print_binary_operator(const binary_operator operation)
{
switch (operation)
{
@@ -215,7 +215,7 @@ namespace elna::boot
{
return "Invalid operands of type '" + this->actual.to_string()
+ "' and '" + payload.right.to_string()
- + "' for operator " + print_binary_operator(payload.operation);
+ + "' for operator " + std::string(print_binary_operator(payload.operation));
}
else if constexpr (std::is_same_v<T, invalid_cast>)
{
@@ -345,13 +345,13 @@ namespace elna::boot
static bool contains_constant_member(const type& checked)
{
- auto referent = resolve_aliases(checked);
+ const type referent = resolve_aliases(checked);
if (referent.get<constant_type>() != nullptr)
{
return true;
}
- else if (auto record = referent.get<record_type>())
+ else if (const auto record = referent.get<record_type>())
{
for (const auto& [field_name, field] : record->fields)
{
@@ -363,7 +363,7 @@ namespace elna::boot
return !record->base.empty()
&& contains_constant_member(resolve_underlying_type(record->base));
}
- else if (auto array = referent.get<array_type>())
+ else if (const auto array = referent.get<array_type>())
{
return contains_constant_member(array->base);
}
@@ -385,30 +385,30 @@ namespace elna::boot
}
const type referent = resolve_aliases(checked);
- if (auto record = referent.get<record_type>())
+ if (const auto record = referent.get<record_type>())
{
for (const auto& [field_name, field] : record->fields)
{
- if (auto opaque = find_opaque_type(field.field_type))
+ if (const auto opaque = find_opaque_type(field.field_type))
{
return opaque;
}
}
return !record->base.empty() ? find_opaque_type(record->base) : std::nullopt;
}
- else if (auto array = referent.get<array_type>())
+ else if (const auto array = referent.get<array_type>())
{
return find_opaque_type(array->base);
}
- else if (auto slice = referent.get<slice_type>())
+ else if (const auto slice = referent.get<slice_type>())
{
return find_opaque_type(slice->base);
}
- else if (auto procedure = referent.get<procedure_type>())
+ else if (const auto procedure = referent.get<procedure_type>())
{
for (const type& parameter : procedure->parameters)
{
- if (auto opaque = find_opaque_type(parameter))
+ if (const auto opaque = find_opaque_type(parameter))
{
return opaque;
}
@@ -446,7 +446,7 @@ namespace elna::boot
{
return std::nullopt;
}
- if (auto pointer = (lhs_integral ? rhs : lhs).get<pointer_type>())
+ if (const auto pointer = (lhs_integral ? rhs : lhs).get<pointer_type>())
{
return find_opaque_type(pointer->base);
}
@@ -456,7 +456,8 @@ namespace elna::boot
// Checks whether the type has zero size.
static bool has_zero_size(const type& checked, const target_info& target)
{
- auto properties = get_type_properties(resolve_underlying_type(checked), target);
+ const std::optional<type_properties> properties =
+ get_type_properties(resolve_underlying_type(checked), target);
return properties.has_value() && properties->size == 0;
}
@@ -469,7 +470,7 @@ namespace elna::boot
{
return checked;
}
- if (auto record = resolve_aliases(checked).get<record_type>())
+ if (const auto record = resolve_aliases(checked).get<record_type>())
{
for (const auto& [field_name, field] : record->fields)
{
@@ -520,23 +521,18 @@ namespace elna::boot
}
}
- /*
- * Checks whether derived has base in its record parent chain.
- *
- * Base record type must not be null. Derived record type may be null.
- */
assign_check::verdict assign_check::guard_const_laundering() const
{
if (!is_primitive_type(ctx.aliased_assignee, "Pointer"))
{
return verdict::pass;
}
- if (auto ptr = ctx.aliased_assignment.get<pointer_type>();
+ if (const auto ptr = ctx.aliased_assignment.get<pointer_type>();
ptr != nullptr && resolve_aliases(ptr->base).get<constant_type>() != nullptr)
{
return verdict::reject;
}
- if (auto const_assign = ctx.aliased_assignment.get<constant_type>();
+ if (const auto const_assign = ctx.aliased_assignment.get<constant_type>();
const_assign != nullptr && is_primitive_type(const_assign->unqualified, "Pointer"))
{
return verdict::reject;
@@ -566,15 +562,16 @@ namespace elna::boot
assign_check::verdict assign_check::check_pointer_conversion() const
{
- auto assignee_ptr = ctx.resolved_assignee.get<pointer_type>();
- auto assignment_ptr = ctx.resolved_assignment.get<pointer_type>();
+ const std::shared_ptr<pointer_type> assignee_ptr = ctx.resolved_assignee.get<pointer_type>();
+ const std::shared_ptr<pointer_type> assignment_ptr = ctx.resolved_assignment.get<pointer_type>();
if (assignee_ptr == nullptr || assignment_ptr == nullptr)
{
return verdict::pass;
}
- auto assignee_pointee_const = resolve_aliases(assignee_ptr->base).get<constant_type>();
- auto assignment_pointee_const = resolve_aliases(assignment_ptr->base).get<constant_type>();
+ const std::shared_ptr<constant_type> assignee_pointee_const =
+ resolve_aliases(assignee_ptr->base).get<constant_type>();
+ const std::shared_ptr<constant_type> assignment_pointee_const = resolve_aliases(assignment_ptr->base).get<constant_type>();
// Constness can be added at the first indirection level, but not removed.
if (assignee_pointee_const != nullptr
@@ -599,15 +596,17 @@ namespace elna::boot
assign_check::verdict assign_check::check_slice_conversion() const
{
- auto assignee_slice = ctx.resolved_assignee.get<slice_type>();
- auto assignment_slice = ctx.resolved_assignment.get<slice_type>();
+ const std::shared_ptr<slice_type> assignee_slice = ctx.resolved_assignee.get<slice_type>();
+ const std::shared_ptr<slice_type> assignment_slice = ctx.resolved_assignment.get<slice_type>();
if (assignee_slice == nullptr || assignment_slice == nullptr)
{
return verdict::pass;
}
- auto assignee_element_const = resolve_aliases(assignee_slice->base).get<constant_type>();
- auto assignment_element_const = resolve_aliases(assignment_slice->base).get<constant_type>();
+ const std::shared_ptr<constant_type> assignee_element_const =
+ resolve_aliases(assignee_slice->base).get<constant_type>();
+ const std::shared_ptr<constant_type> assignment_element_const =
+ resolve_aliases(assignment_slice->base).get<constant_type>();
// Const can be added to the element type, but not removed.
if (assignee_element_const != nullptr
@@ -624,16 +623,18 @@ namespace elna::boot
assign_check::verdict assign_check::check_array_conversion() const
{
- auto assignee_array = ctx.resolved_assignee.get<array_type>();
- auto assignment_array = ctx.resolved_assignment.get<array_type>();
+ const std::shared_ptr<array_type> assignee_array = ctx.resolved_assignee.get<array_type>();
+ const std::shared_ptr<array_type> assignment_array = ctx.resolved_assignment.get<array_type>();
if (assignee_array == nullptr || assignment_array == nullptr
|| assignee_array->size != assignment_array->size)
{
return verdict::pass;
}
- auto assignee_element_const = resolve_aliases(assignee_array->base).get<constant_type>();
- auto assignment_element_const = resolve_aliases(assignment_array->base).get<constant_type>();
+ const std::shared_ptr<constant_type> assignee_element_const =
+ resolve_aliases(assignee_array->base).get<constant_type>();
+ const std::shared_ptr<constant_type> assignment_element_const =
+ resolve_aliases(assignment_array->base).get<constant_type>();
// An array is copied by value, so const can be added to the element type,
// but not removed. Writing to such an array is rejected on the lvalue.
@@ -651,7 +652,7 @@ namespace elna::boot
bool assign_check::run()
{
- auto const assign_handlers = {
+ const std::initializer_list assign_handlers = {
&assign_check::guard_const_laundering,
&assign_check::check_exact_match,
&assign_check::check_slice_conversion,
@@ -659,7 +660,7 @@ namespace elna::boot
&assign_check::check_pointer_hatch,
&assign_check::check_pointer_conversion
};
- for (auto handler : assign_handlers)
+ for (const auto handler : assign_handlers)
{
switch ((this->*handler)())
{
@@ -804,7 +805,6 @@ namespace elna::boot
this->current_procedure = this->bag.lookup("")->is_procedure();
this->bag.enter(this->current_procedure->scope);
walking_visitor::visit_entry_point(unit);
- check_return(unit->entry_point.value(), unit->entry_position.value(), "");
this->bag.leave();
this->current_procedure.reset();
}
@@ -815,14 +815,15 @@ namespace elna::boot
for (const auto& variable_identifier : declaration->identifiers)
{
- auto variable_symbol = this->bag.lookup(variable_identifier.name())->is_variable();
+ const std::shared_ptr<variable_info> variable_symbol =
+ this->bag.lookup(variable_identifier.name())->is_variable();
- if (auto opaque = find_opaque_type(variable_symbol->symbol))
+ if (const auto opaque = find_opaque_type(variable_symbol->symbol))
{
add_error<type_requirement_error>(variable_identifier.id().position(),
opaque.value(), type_requirement_error::kind::opaque_variable);
}
- else if (auto found = find_zero_sized(variable_symbol->symbol, this->target))
+ else if (const auto found = find_zero_sized(variable_symbol->symbol, this->target))
{
add_error<type_requirement_error>(variable_identifier.id().position(),
found.value(), type_requirement_error::kind::zero_sized);
@@ -834,7 +835,9 @@ namespace elna::boot
}
for (const auto& variable_identifier : declaration->identifiers)
{
- auto variable_symbol = this->bag.lookup(variable_identifier.name())->is_variable();
+ const std::shared_ptr<variable_info> variable_symbol =
+ this->bag.lookup(variable_identifier.name())->is_variable();
+
if (!is_assignable_from(variable_symbol->symbol, declaration->initializer->type_decoration))
{
add_error<type_mismatch_error>(declaration->initializer->position(),
@@ -869,7 +872,7 @@ namespace elna::boot
void type_analysis_visitor::visit(for_statement *statement)
{
statement->range().accept(this);
- auto resolved_range = resolve_underlying_type(statement->range().type_decoration);
+ const type resolved_range = resolve_underlying_type(statement->range().type_decoration);
if (!get_range_base_type(resolved_range))
{
@@ -923,9 +926,10 @@ namespace elna::boot
void type_analysis_visitor::visit(type_declaration *declaration)
{
walking_visitor::visit(declaration);
- auto unresolved_type = this->bag.lookup(declaration->identifier.name())->is_type()->symbol.get<alias_type>();
+ const std::shared_ptr<alias_type> unresolved_type =
+ this->bag.lookup(declaration->identifier.name())->is_type()->symbol.get<alias_type>();
- if (auto generic = unresolved_type->referent.get<generic_type>())
+ if (const auto generic = unresolved_type->referent.get<generic_type>())
{
check_parameters_used(declaration->position(), declaration->identifier.name(),
generic->parameters, generic->referent);
@@ -933,11 +937,11 @@ namespace elna::boot
}
const type referent = resolve_aliases(unresolved_type->referent);
- if (auto record = referent.get<record_type>())
+ if (const auto record = referent.get<record_type>())
{
for (const auto& [field_name, field] : record->fields)
{
- if (auto opaque = find_opaque_type(field.field_type))
+ if (const auto opaque = find_opaque_type(field.field_type))
{
add_error<type_requirement_error>(declaration->position(),
opaque.value(), type_requirement_error::kind::opaque_field);
@@ -949,27 +953,27 @@ namespace elna::boot
}
}
}
- else if (auto array = referent.get<array_type>())
+ else if (const auto array = referent.get<array_type>())
{
- if (auto opaque = find_opaque_type(array->base))
+ if (const auto opaque = find_opaque_type(array->base))
{
add_error<type_requirement_error>(declaration->position(),
opaque.value(), type_requirement_error::kind::opaque_element);
}
}
- else if (auto slice = referent.get<slice_type>())
+ else if (const auto slice = referent.get<slice_type>())
{
- if (auto opaque = find_opaque_type(slice->base))
+ if (const auto opaque = find_opaque_type(slice->base))
{
add_error<type_requirement_error>(declaration->position(),
opaque.value(), type_requirement_error::kind::opaque_element);
}
}
- else if (auto procedure = referent.get<procedure_type>())
+ else if (const auto procedure = referent.get<procedure_type>())
{
for (const type& parameter : procedure->parameters)
{
- if (auto opaque = find_opaque_type(parameter))
+ if (const auto opaque = find_opaque_type(parameter))
{
add_error<type_requirement_error>(declaration->position(),
opaque.value(), type_requirement_error::kind::opaque_parameter);
@@ -982,7 +986,7 @@ namespace elna::boot
}
if (!procedure->return_type.proper_type.empty())
{
- if (auto opaque = find_opaque_type(procedure->return_type.proper_type))
+ if (const auto opaque = find_opaque_type(procedure->return_type.proper_type))
{
add_error<type_requirement_error>(declaration->position(),
opaque.value(), type_requirement_error::kind::opaque_return);
@@ -1001,7 +1005,8 @@ namespace elna::boot
{
if (expression->base.has_value())
{
- auto const base_symbol = this->bag.lookup(expression->base.value().name());
+ const std::shared_ptr<info> base_symbol = this->bag.lookup(expression->base.value().name());
+
if (base_symbol == nullptr || base_symbol->is_type() == nullptr)
{
add_error<type_requirement_error>(expression->position(),
@@ -1009,7 +1014,7 @@ namespace elna::boot
}
else
{
- type const base_type = erase_generic(base_symbol->is_type()->symbol);
+ const type base_type = erase_generic(base_symbol->is_type()->symbol);
if (base_type.get<record_type>() == nullptr)
{
add_error<type_requirement_error>(expression->position(),
@@ -1032,23 +1037,23 @@ namespace elna::boot
{
return true;
}
- if (auto pointer = subject.get<pointer_type>())
+ else if (const auto pointer = subject.get<pointer_type>())
{
return occurs_in(parameter, pointer->base);
}
- if (auto slice = subject.get<slice_type>())
+ else if (const auto slice = subject.get<slice_type>())
{
return occurs_in(parameter, slice->base);
}
- if (auto array = subject.get<array_type>())
+ else if (const auto array = subject.get<array_type>())
{
return occurs_in(parameter, array->base);
}
- if (auto qualified = subject.get<constant_type>())
+ else if (const auto qualified = subject.get<constant_type>())
{
return occurs_in(parameter, qualified->unqualified);
}
- if (auto record = subject.get<record_type>())
+ else if (const auto record = subject.get<record_type>())
{
for (const auto& [field_name, field] : record->fields)
{
@@ -1059,7 +1064,7 @@ namespace elna::boot
}
return !record->base.empty() && occurs_in(parameter, record->base);
}
- if (auto procedure = subject.get<procedure_type>())
+ else if (const auto procedure = subject.get<procedure_type>())
{
for (const type& parameter_type : procedure->parameters)
{
@@ -1071,7 +1076,7 @@ namespace elna::boot
return !procedure->return_type.proper_type.empty()
&& occurs_in(parameter, procedure->return_type.proper_type);
}
- if (auto instance = subject.get<instantiated_type>())
+ else if (const auto instance = subject.get<instantiated_type>())
{
for (const type& argument : instance->arguments)
{
@@ -1112,7 +1117,7 @@ namespace elna::boot
const type left = resolve_aliases(declared);
const type right = resolve_aliases(actual);
- if (auto parameter = left.get<parameter_type>())
+ if (const auto parameter = left.get<parameter_type>())
{
for (std::size_t i = 0; i < parameters.size(); ++i)
{
@@ -1125,40 +1130,40 @@ namespace elna::boot
}
return true;
}
- if (auto left_pointer = left.get<pointer_type>())
+ else if (const auto left_pointer = left.get<pointer_type>())
{
- auto right_pointer = right.get<pointer_type>();
+ const std::shared_ptr<pointer_type> right_pointer = right.get<pointer_type>();
return right_pointer != nullptr
&& bind_arguments(parameters, bindings, left_pointer->base, right_pointer->base);
}
- if (auto left_slice = left.get<slice_type>())
+ else if (const auto left_slice = left.get<slice_type>())
{
- auto right_slice = right.get<slice_type>();
+ const std::shared_ptr<slice_type> right_slice = right.get<slice_type>();
return right_slice != nullptr
&& bind_arguments(parameters, bindings, left_slice->base, right_slice->base);
}
- if (auto left_array = left.get<array_type>())
+ else if (const auto left_array = left.get<array_type>())
{
- auto right_array = right.get<array_type>();
+ const std::shared_ptr<array_type> right_array = right.get<array_type>();
return right_array != nullptr
&& bind_arguments(parameters, bindings, left_array->base, right_array->base);
}
- if (auto left_constant = left.get<constant_type>())
+ else if (const auto left_constant = left.get<constant_type>())
{
- auto right_constant = right.get<constant_type>();
+ const std::shared_ptr<constant_type> right_constant = right.get<constant_type>();
return right_constant != nullptr
- && bind_arguments(parameters, bindings,
- left_constant->unqualified, right_constant->unqualified);
+ && bind_arguments(parameters, bindings, left_constant->unqualified, right_constant->unqualified);
}
- if (auto left_instance = left.get<instantiated_type>())
+ else if (const auto left_instance = left.get<instantiated_type>())
{
for (type candidate = right; !candidate.empty(); candidate = base_of(candidate))
{
- auto right_instance = resolve_aliases(candidate).get<instantiated_type>();
+ const std::shared_ptr<instantiated_type> right_instance =
+ resolve_aliases(candidate).get<instantiated_type>();
if (right_instance == nullptr
|| !(left_instance->generic == right_instance->generic)
@@ -1178,9 +1183,9 @@ namespace elna::boot
}
return false;
}
- if (auto left_procedure = left.get<procedure_type>())
+ else if (const auto left_procedure = left.get<procedure_type>())
{
- auto right_procedure = right.get<procedure_type>();
+ const std::shared_ptr<procedure_type> right_procedure = right.get<procedure_type>();
if (right_procedure == nullptr
|| left_procedure->parameters.size() != right_procedure->parameters.size())
@@ -1281,7 +1286,7 @@ namespace elna::boot
}
const type denoted = expression->type_decoration;
- if (auto instance = denoted.get<instantiated_type>())
+ if (const auto instance = denoted.get<instantiated_type>())
{
std::shared_ptr<generic_type> const generic = unwrap_generic(instance->generic);
@@ -1404,7 +1409,7 @@ namespace elna::boot
{
// Inference reads the argument types, so they are decorated
// before the parameter types they will be checked against exist.
- for (expression *argument : call->arguments)
+ for (expression *const argument : call->arguments)
{
argument->accept(this);
}
@@ -1414,13 +1419,13 @@ namespace elna::boot
// Name analysis decorated the call with the declared return
// type, which still mentions the parameters inference has
// just bound.
- if (auto substituted = callable_type.get<procedure_type>())
+ if (const auto substituted = callable_type.get<procedure_type>())
{
call->type_decoration = substituted->return_type.proper_type;
}
}
}
- if (auto procedure = callable_type.get<procedure_type>())
+ if (const auto procedure = callable_type.get<procedure_type>())
{
std::vector<expression *>::const_iterator argument_iterator = std::cbegin(call->arguments);
std::vector<type>::const_iterator type_iterator = std::cbegin(procedure->parameters);
@@ -1455,7 +1460,7 @@ namespace elna::boot
if (call->arguments.size() < procedure->parameters.size()
|| (!procedure->variadic && call->arguments.size() > procedure->parameters.size()))
{
- if (auto *procedure_name = call->callable().is_named())
+ if (const auto *procedure_name = call->callable().is_named())
{
add_error<argument_count_error>(call->position(),
argument_count_error::kind::call, procedure_name->name,
@@ -1480,7 +1485,7 @@ namespace elna::boot
void type_analysis_visitor::visit(record_constructor_expression *expression)
{
- auto record = erase_generic(expression->type_decoration).get<record_type>();
+ const std::shared_ptr<record_type> record = erase_generic(expression->type_decoration).get<record_type>();
if (record == nullptr)
{
@@ -1507,7 +1512,8 @@ namespace elna::boot
void type_analysis_visitor::visit(array_constructor_expression *expression)
{
- auto array = resolve_underlying_type(expression->type_decoration).get<array_type>();
+ const std::shared_ptr<array_type> array =
+ resolve_underlying_type(expression->type_decoration).get<array_type>();
if (array == nullptr)
{
@@ -1518,7 +1524,7 @@ namespace elna::boot
}
// The first element of the array literal determines the array type and
// does not have to be checked.
- for (auto *element : expression->elements | std::views::drop(1))
+ for (const auto *element : expression->elements | std::views::drop(1))
{
if (!is_assignable_from(array->base, element->type_decoration))
{
@@ -1548,7 +1554,7 @@ namespace elna::boot
{
walking_visitor::visit(expression);
- auto resolved_base = resolve_underlying_type(expression->base().type_decoration);
+ const type resolved_base = resolve_underlying_type(expression->base().type_decoration);
if (resolved_base.get<array_type>() == nullptr
&& resolved_base.get<slice_type>() == nullptr)
{
@@ -1566,7 +1572,7 @@ namespace elna::boot
{
walking_visitor::visit(expression);
- auto operation = expression->operation();
+ const unary_operator operation = expression->operation();
type const resolved = resolve_underlying_type(expression->operand().type_decoration);
if (operation == unary_operator::plus || operation == unary_operator::minus)
@@ -1595,14 +1601,11 @@ namespace elna::boot
type_mismatch_error::unary{ .operation = operation });
}
}
- else if (operation == unary_operator::reference)
+ else if (operation == unary_operator::reference && !is_addressable(expression->operand()))
{
- if (!is_addressable(expression->operand()))
- {
- add_error<type_requirement_error>(expression->position(),
- expression->operand().type_decoration,
- type_requirement_error::kind::not_addressable);
- }
+ add_error<type_requirement_error>(expression->position(),
+ expression->operand().type_decoration,
+ type_requirement_error::kind::not_addressable);
}
}
@@ -1634,8 +1637,8 @@ namespace elna::boot
opaque.value(), type_requirement_error::kind::opaque_cast);
return;
}
- auto source = resolve_underlying_type(expression->value().type_decoration);
- auto target = resolve_underlying_type(expression->type_decoration);
+ const type source = resolve_underlying_type(expression->value().type_decoration);
+ const type target = resolve_underlying_type(expression->type_decoration);
if (source != target // const cast.
&& (!is_scalar_type(source) || !is_scalar_type(target))
@@ -1651,7 +1654,7 @@ namespace elna::boot
{
walking_visitor::visit(expression);
- auto operation = expression->operation();
+ const binary_operator operation = expression->operation();
type const lhs_resolved = resolve_underlying_type(expression->lhs().type_decoration);
type const rhs_resolved = resolve_underlying_type(expression->rhs().type_decoration);
bool valid = false;
@@ -1804,7 +1807,7 @@ namespace elna::boot
add_error<trait_error>(trait->name.position(), trait->name.name(),
trait_error::unsupported_type{ trait->types.front() });
}
- else if (auto *field = trait->arguments.at(1)->is_named())
+ else if (const auto *field = trait->arguments.at(1)->is_named())
{
if (erase_generic(trait->types.front()).get<record_type>() == nullptr)
{
diff --git a/boot/validation.cc b/boot/validation.cc
index facef04..dda3af7 100644
--- a/boot/validation.cc
+++ b/boot/validation.cc
@@ -64,10 +64,10 @@ namespace elna::boot
}
if (unit->entry_point.has_value())
{
- auto entry_point = this->bag.lookup("")->is_procedure();
+ const std::shared_ptr<procedure_info> entry_point = this->bag.lookup("")->is_procedure();
this->bag.enter(entry_point->scope);
- visit_statements(unit->entry_point->statements);
+ visit_statements(unit->entry_point.value());
this->bag.leave();
}
}
@@ -84,7 +84,9 @@ namespace elna::boot
{
if (declaration->body.has_value())
{
- auto procedure = this->bag.lookup(declaration->identifier.name())->is_procedure();
+ const std::shared_ptr<procedure_info> procedure =
+ this->bag.lookup(declaration->identifier.name())->is_procedure();
+
this->bag.enter(procedure->scope);
visit_statements(declaration->body.value().statements);
this->bag.leave();
diff --git a/gcc/gcc/elna-builtins.cc b/gcc/gcc/elna-builtins.cc
index 0da991a..ee6856d 100644
--- a/gcc/gcc/elna-builtins.cc
+++ b/gcc/gcc/elna-builtins.cc
@@ -31,6 +31,7 @@ namespace elna::gcc
{
return boot::type_properties{
.size = static_cast<std::size_t>(TYPE_PRECISION(node) / BITS_PER_UNIT),
+ // NOLINTNEXTLINE(bugprone-signed-bitwise)
.alignment = TYPE_ALIGN_UNIT(node)
};
}
@@ -59,6 +60,7 @@ namespace elna::gcc
.bool_properties = {
.size = static_cast<std::size_t>(
(TYPE_PRECISION(elna_bool_type_node) + BITS_PER_UNIT - 1) / BITS_PER_UNIT),
+ // NOLINTNEXTLINE(bugprone-signed-bitwise)
.alignment = TYPE_ALIGN_UNIT(elna_bool_type_node)
},
.c_int_properties = get_host_numeric_properties(integer_type_node)
@@ -190,14 +192,14 @@ namespace elna::gcc
tree get_inner_alias(const boot::type& type, const std::shared_ptr<symbol_table>& symbols,
tree placeholder)
{
- if (auto reference = type.get<boot::primitive_type>())
+ if (const auto reference = type.get<boot::primitive_type>())
{
tree looked_up = symbols->lookup(reference->identifier);
gcc_assert(looked_up != NULL_TREE);
return TREE_TYPE(looked_up);
}
- else if (auto reference = type.get<boot::record_type>())
+ else if (const auto reference = type.get<boot::record_type>())
{
tree composite_type_node = placeholder != NULL_TREE ? placeholder : make_node(RECORD_TYPE);
@@ -220,11 +222,11 @@ namespace elna::gcc
}
return composite_type_node;
}
- else if (auto reference = type.get<boot::enumeration_type>())
+ else if (const auto reference = type.get<boot::enumeration_type>())
{
return build_enumeration_type(reference->members);
}
- else if (auto reference = type.get<boot::extern_type>())
+ else if (const auto reference = type.get<boot::extern_type>())
{
/*
* An incomplete type: a record without fields and without layout,
@@ -233,17 +235,17 @@ namespace elna::gcc
*/
return make_node(RECORD_TYPE);
}
- else if (auto reference = type.get<boot::pointer_type>())
+ else if (const auto reference = type.get<boot::pointer_type>())
{
return build_pointer_type(get_inner_alias(reference->base, symbols, placeholder));
}
- else if (auto reference = type.get<boot::array_type>())
+ else if (const auto reference = type.get<boot::array_type>())
{
tree base = get_inner_alias(reference->base, symbols, placeholder);
return build_static_array_type(base, reference->size);
}
- else if (auto reference = type.get<boot::slice_type>())
+ else if (const auto reference = type.get<boot::slice_type>())
{
tree base_type = get_inner_alias(reference->base, symbols, placeholder);
tree slice_record = make_node(RECORD_TYPE);
@@ -256,18 +258,18 @@ namespace elna::gcc
layout_type(slice_record);
return type_hash_canon(type_hash_canon_hash(slice_record), slice_record);
}
- else if (auto reference = type.get<boot::procedure_type>())
+ else if (const auto reference = type.get<boot::procedure_type>())
{
tree procedure = build_procedure_type(*reference, symbols);
return build_pointer_type(procedure);
}
- else if (auto reference = type.get<boot::constant_type>())
+ else if (const auto reference = type.get<boot::constant_type>())
{
tree unqualified = get_inner_alias(reference->unqualified, symbols, placeholder);
return build_qualified_type(unqualified, TYPE_QUAL_CONST);
}
- else if (auto reference = type.get<boot::alias_type>())
+ else if (const auto reference = type.get<boot::alias_type>())
{
return TREE_TYPE(handle_symbol(reference->name, reference, symbols));
}
@@ -275,13 +277,13 @@ namespace elna::gcc
{
return elna_pointer_type_node;
}
- else if (auto reference = type.get<boot::instantiated_type>())
+ else if (const auto reference = type.get<boot::instantiated_type>())
{
// Erasure is argument blind, so every instantiation of one generic
// shares the tree the generic's own name is bound to.
return get_inner_alias(reference->generic, symbols, placeholder);
}
- else if (auto reference = type.get<boot::generic_type>())
+ else if (const auto reference = type.get<boot::generic_type>())
{
return get_inner_alias(reference->referent, symbols, placeholder);
}
@@ -391,7 +393,7 @@ namespace elna::gcc
const boot::type_info& info, const std::shared_ptr<symbol_table>& symbols)
{
// The top level symbol table has basic (builtin) types in it which are not aliases.
- if (auto alias_type = info.symbol.get<boot::alias_type>())
+ if (const auto alias_type = info.symbol.get<boot::alias_type>())
{
tree type_declaration = handle_symbol(name, alias_type, symbols);
@@ -404,11 +406,11 @@ namespace elna::gcc
{
for (auto& [symbol_name, symbol_info] : *info_table)
{
- if (auto type_info = symbol_info->is_type())
+ if (const auto type_info = symbol_info->is_type())
{
declare_type(symbol_name, *type_info, symbols);
}
- else if (auto variable_info = symbol_info->is_variable())
+ else if (const auto variable_info = symbol_info->is_variable())
{
tree declaration_tree = declare_variable(symbol_name, *variable_info, symbols);
@@ -422,7 +424,7 @@ namespace elna::gcc
set_decl_tls_model(declaration_tree, decl_default_tls_model(declaration_tree));
}
}
- else if (auto procedure_info = symbol_info->is_procedure())
+ else if (const auto procedure_info = symbol_info->is_procedure())
{
declare_procedure(symbol_name, *procedure_info, symbols);
}
diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc
index 46c8edc..034e4ae 100644
--- a/gcc/gcc/elna-generic.cc
+++ b/gcc/gcc/elna-generic.cc
@@ -106,6 +106,7 @@ namespace elna::gcc
pointer.accept(this);
tree pointee = get_inner_alias(accessed, this->symbols);
+ // NOLINTNEXTLINE(bugprone-signed-bitwise)
tree qualified = build_qualified_type(pointee, TYPE_QUALS(pointee) | TYPE_QUAL_VOLATILE);
tree address = fold_convert_loc(location, build_pointer_type(qualified),
prepare_rvalue(this->current_expression));
@@ -200,10 +201,10 @@ namespace elna::gcc
expression->value().accept(this);
this->current_expression = prepare_rvalue(this->current_expression);
const location_t cast_location = get_location(&expression->position());
- auto source_slice = resolve_underlying_type(expression->value().type_decoration)
- .get<boot::slice_type>();
- auto target_slice = resolve_underlying_type(expression->type_decoration)
- .get<boot::slice_type>();
+ const std::shared_ptr<boot::slice_type> source_slice =
+ resolve_underlying_type(expression->value().type_decoration).get<boot::slice_type>();
+ const std::shared_ptr<boot::slice_type> target_slice =
+ resolve_underlying_type(expression->type_decoration).get<boot::slice_type>();
if (source_slice != nullptr && target_slice != nullptr)
{
@@ -398,19 +399,13 @@ namespace elna::gcc
declare_local_variable(unit->parameters.front(), argument_info, slice);
}
- for (boot::variable_declaration *const variable : unit->entry_point->variables)
- {
- variable->accept(this);
- }
- visit_statements(unit->entry_point->statements);
+ visit_statements(unit->entry_point.value());
- unit->entry_point->return_expression->accept(this);
- tree return_value = fold_convert(integer_type_node, this->current_expression);
- tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(fndecl), return_value);
+ tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(fndecl), integer_zero_node);
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
append_statement(return_stmt);
- this->current_expression = NULL_TREE;
+ this->current_expression = NULL_TREE;
this->bag.leave();
finish_function(fndecl);
}
@@ -428,7 +423,8 @@ namespace elna::gcc
const std::string& variable_name = variable_identifier.name();
tree declaration_tree = this->symbols->lookup(variable_name);
- auto variable_symbol = this->bag.lookup(variable_name)->is_variable();
+ const std::shared_ptr<boot::variable_info> variable_symbol =
+ this->bag.lookup(variable_name)->is_variable();
if (declaration_tree == NULL_TREE)
{
@@ -1080,9 +1076,11 @@ namespace elna::gcc
tree end_pointer = do_pointer_arithmetic(boot::binary_operator::sum, start_pointer, length, location);
enter_scope();
- // Declare control variable with the unqualified type. The constant_type wrapper
- // is for semantic checking only, because GENERIC needs to modify the control variable.
- auto control_variable_info = statement->body.symbols->lookup(statement->control_variable.name());
+ // Declare control variable with the unqualified type. The constant_type
+ // wrapper is for semantic checking only, because GENERIC needs to modify
+ // the control variable.
+ const boot::symbol_table::symbol_ptr control_variable_info =
+ statement->body.symbols->lookup(statement->control_variable.name());
const boot::variable_info unqualified_info(
boot::resolve_underlying_type(control_variable_info->is_variable()->symbol),
control_variable_info->is_variable()->is_extern);
@@ -1092,7 +1090,8 @@ namespace elna::gcc
tree counter_declaration{ NULL_TREE };
if (statement->counter != nullptr)
{
- auto counter_info = statement->body.symbols->lookup(statement->counter->name());
+ const boot::symbol_table::symbol_ptr counter_info =
+ statement->body.symbols->lookup(statement->counter->name());
counter_declaration = declare_local_variable(*statement->counter,
*counter_info->is_variable(), elna_word_one_node);
}
diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc
index 690cf41..e762b8e 100644
--- a/gcc/gcc/elna-tree.cc
+++ b/gcc/gcc/elna-tree.cc
@@ -226,6 +226,7 @@ namespace elna::gcc
}
TYPE_MIN_VALUE(composite_type_node) = DECL_INITIAL(TREE_VALUE(TYPE_VALUES(composite_type_node)));
TYPE_UNSIGNED(composite_type_node) = TYPE_UNSIGNED(base_type);
+ // NOLINTNEXTLINE(bugprone-signed-bitwise)
SET_TYPE_ALIGN(composite_type_node, TYPE_ALIGN(base_type));
TYPE_SIZE(composite_type_node) = NULL_TREE;
TYPE_PRECISION(composite_type_node) = TYPE_PRECISION(base_type);
@@ -261,7 +262,7 @@ namespace elna::gcc
if (std::holds_alternative<boot::integer_literal>(constant_value))
{
- auto literal_value = std::get<boot::integer_literal>(constant_value);
+ const boot::integer_literal literal_value = std::get<boot::integer_literal>(constant_value);
if (literal_value.is_signed())
{
@@ -282,7 +283,7 @@ namespace elna::gcc
}
else if (std::holds_alternative<boot::float_literal>(constant_value))
{
- auto literal = std::get<boot::float_literal>(constant_value);
+ const boot::float_literal literal = std::get<boot::float_literal>(constant_value);
mpfr_t number;
mpfr_init2(number, SIGNIFICAND_BITS);
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h
index 52461e6..4a0cdb0 100644
--- a/include/elna/boot/ast.h
+++ b/include/elna/boot/ast.h
@@ -687,7 +687,7 @@ namespace elna::boot
{
expression *return_expression{ nullptr };
- procedure_body(block&& body, expression *return_expression = nullptr);
+ explicit procedure_body(block&& body, expression *return_expression = nullptr);
procedure_body(procedure_body&& that) noexcept = default;
virtual ~procedure_body() = default;
@@ -1076,7 +1076,7 @@ namespace elna::boot
public:
const std::vector<import_declaration *> imports;
const std::vector<declaration *> declarations;
- std::optional<procedure_body> entry_point;
+ std::optional<std::vector<statement *>> entry_point;
const std::vector<identifier> parameters;
const std::optional<source_position> entry_position;
@@ -1088,7 +1088,7 @@ namespace elna::boot
std::vector<declaration *>&& declarations,
std::vector<identifier>&& parameters,
const source_position entry_position,
- std::optional<procedure_body>&& body);
+ std::vector<statement *>&& body);
void accept(parser_visitor *visitor) override;
@@ -1157,7 +1157,7 @@ namespace elna::boot
class empty_statement : public statement
{
public:
- empty_statement(const source_position);
+ explicit empty_statement(const source_position);
void accept(parser_visitor *visitor) override;
};
diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h
index a87503e..7bd3de9 100644
--- a/include/elna/boot/dependency.h
+++ b/include/elna/boot/dependency.h
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include <concepts>
#include <filesystem>
-#include <fstream>
+#include <istream>
#include <unordered_set>
#include <variant>
#include <vector>
@@ -250,7 +250,8 @@ namespace elna::boot
dependency compile(const std::filesystem::path& key, Loader& loader,
const target_info& target, const bool imported = false)
{
- auto cached = this->cache.find(key);
+ const auto cached = this->cache.find(key);
+
if (cached != this->cache.cend())
{
return {};
diff --git a/include/elna/boot/driver.h b/include/elna/boot/driver.h
index e918954..6bcfa9e 100644
--- a/include/elna/boot/driver.h
+++ b/include/elna/boot/driver.h
@@ -38,10 +38,14 @@ namespace elna::boot
class driver final : public diagnostic_container
{
public:
- std::unique_ptr<unit> tree;
/// Set once the module terminator has been parsed. The lexer stops
/// scanning then, so whatever follows is not program text.
- bool finished{ false };
+ std::unique_ptr<unit> tree;
+
+ /**
+ * \return Whenever module terminator has been parsed.
+ */
+ bool has_finished() const;
driver() = default;
};
diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h
index a8ad73b..d0a550a 100644
--- a/include/elna/boot/result.h
+++ b/include/elna/boot/result.h
@@ -100,7 +100,7 @@ namespace elna::boot
class diagnostic
{
protected:
- diagnostic(const source_position position);
+ explicit diagnostic(const source_position position);
public:
virtual ~diagnostic() = default;
@@ -716,7 +716,8 @@ namespace elna::boot
*/
iterator find(const key_type& key)
{
- auto search_result = this->index_map.find(key);
+ const auto search_result = this->index_map.find(key);
+
if (search_result == this->index_map.cend())
{
return this->payload.end();
@@ -730,7 +731,8 @@ namespace elna::boot
/// \overload
const_iterator find(const key_type& key) const
{
- auto search_result = this->index_map.find(key);
+ const auto search_result = this->index_map.find(key);
+
if (search_result == this->index_map.cend())
{
return this->payload.cend();
@@ -752,23 +754,23 @@ namespace elna::boot
*/
std::pair<iterator, bool> insert(const key_type& key, const mapped_type& value)
{
- auto insert_result = this->index_map.emplace(key, this->payload.size());
- if (insert_result.second)
+ const auto [at_position, inserted] = this->index_map.emplace(key, this->payload.size());
+ if (inserted)
{
this->payload.emplace_back(key, value);
}
- return { this->payload.begin() + insert_result.first->second, insert_result.second };
+ return { this->payload.begin() + at_position->second, inserted };
}
/// \overload
std::pair<iterator, bool> insert(const key_type& key, mapped_type&& value)
{
- auto insert_result = this->index_map.emplace(key, this->payload.size());
- if (insert_result.second)
+ const auto [at_position, inserted] = this->index_map.emplace(key, this->payload.size());
+ if (inserted)
{
this->payload.emplace_back(key, std::move(value));
}
- return { this->payload.begin() + insert_result.first->second, insert_result.second };
+ return { this->payload.begin() + at_position->second, inserted };
}
/**
@@ -992,8 +994,8 @@ namespace elna::boot
private:
static constexpr std::size_t golden_ratio = 0x9e3779b9;
- static constexpr int mix_shift_left = 6;
- static constexpr int mix_shift_right = 2;
+ static constexpr unsigned int mix_shift_left = 6;
+ static constexpr unsigned int mix_shift_right = 2;
std::size_t m_seed{ 0 };
};
diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h
index a5f7ca8..38aee08 100644
--- a/include/elna/boot/symbol.h
+++ b/include/elna/boot/symbol.h
@@ -182,7 +182,7 @@ namespace elna::boot
/// type's own alignment.
std::optional<std::size_t> alignment;
- field_info(type field_type = type(), std::optional<std::size_t> alignment = std::nullopt);
+ explicit field_info(type field_type = type(), std::optional<std::size_t> alignment = std::nullopt);
};
struct record_type
@@ -370,7 +370,7 @@ namespace elna::boot
*/
symbol_ptr lookup(const std::string& name)
{
- auto entry = entries.find(name);
+ const iterator entry = entries.find(name);
if (entry != entries.cend())
{
diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h
index 94f8961..620af74 100644
--- a/include/elna/boot/type_check.h
+++ b/include/elna/boot/type_check.h
@@ -253,7 +253,13 @@ namespace elna::boot
};
context ctx;
+ /**
+ * Checks whether derived has base in its record parent chain.
+ *
+ * Base record type must not be null. Derived record type may be null.
+ */
verdict guard_const_laundering() const;
+
verdict check_exact_match() const;
verdict check_pointer_hatch() const;
verdict check_pointer_conversion() const;
diff --git a/source/cctype.elna b/source/cctype.elna
index 13dc50a..19c3491 100644
--- a/source/cctype.elna
+++ b/source/cctype.elna
@@ -1,6 +1,7 @@
(* This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. *)
+module
proc isdigit*(c: Int ) -> Int
extern
diff --git a/source/command_line_interface.elna b/source/command_line_interface.elna
index 0feb53b..511d6a0 100644
--- a/source/command_line_interface.elna
+++ b/source/command_line_interface.elna
@@ -1,10 +1,10 @@
(* This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. *)
-
(*
Command line handling.
*)
+module
import cstdlib, cstring, common
type
diff --git a/source/common.elna b/source/common.elna
index 0a50fe1..e31def8 100644
--- a/source/common.elna
+++ b/source/common.elna
@@ -1,7 +1,7 @@
(* This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. *)
-
+module
import cstring, cstdio, cstdlib
type
diff --git a/source/cstdio.elna b/source/cstdio.elna
index bf74234..e69d81a 100644
--- a/source/cstdio.elna
+++ b/source/cstdio.elna
@@ -1,6 +1,7 @@
(* This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. *)
+module
type
FILE* = extern
diff --git a/source/cstdlib.elna b/source/cstdlib.elna
index 09b1ddf..9b858e7 100644
--- a/source/cstdlib.elna
+++ b/source/cstdlib.elna
@@ -1,6 +1,7 @@
(* This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. *)
+module
proc malloc*(size: Word) -> Pointer
extern
diff --git a/source/cstring.elna b/source/cstring.elna
index 70c468c..dcf9e6f 100644
--- a/source/cstring.elna
+++ b/source/cstring.elna
@@ -1,6 +1,7 @@
(* This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. *)
+module
proc memset*(ptr: Pointer; c: Int; n: Word) -> ^Word8
extern
diff --git a/source/lexer.elna b/source/lexer.elna
index 1cfe097..bf1c449 100644
--- a/source/lexer.elna
+++ b/source/lexer.elna
@@ -1,7 +1,7 @@
(* This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. *)
-
+module
import cstdio, common, cstdlib
type
diff --git a/source/main.elna b/source/main.elna
index 955f313..adac5ac 100644
--- a/source/main.elna
+++ b/source/main.elna
@@ -2,7 +2,9 @@
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. *)
-import cstdio, cstdlib, cstring, cctype, common, command_line_interface, lexer
+program(parameters)
+import
+ cstdio, cstdlib, cstring, cctype, common, command_line_interface, lexer
type
SourceFile* = record
@@ -825,10 +827,8 @@ begin
stderr := fdopen(2, "w\0".ptr)
return
-program(parameters)
begin
initialize_global_state();
-return cast(process(cast(parameters.length: Int), parameters.ptr): Word8)
-
+ exit(process(cast(parameters.length: Int), parameters.ptr))
end.
diff --git a/testsuite/compilable/aliased_type_constant.elna b/testsuite/compilable/aliased_type_constant.elna
index 16a52c2..e4054c7 100644
--- a/testsuite/compilable/aliased_type_constant.elna
+++ b/testsuite/compilable/aliased_type_constant.elna
@@ -1,3 +1,5 @@
+module
+
type
Handle = Int
diff --git a/testsuite/compilable/assign_record_to_base.elna b/testsuite/compilable/assign_record_to_base.elna
index 303bde0..14bc3f5 100644
--- a/testsuite/compilable/assign_record_to_base.elna
+++ b/testsuite/compilable/assign_record_to_base.elna
@@ -1,3 +1,4 @@
+program()
type
B = record
x: Int
@@ -10,9 +11,6 @@ var
x: ^B := nil
y: ^R := nil
-program()
begin
- x := y;
-return 0u8
-
+ x := y
end.
diff --git a/testsuite/compilable/compile_time_array_length.elna b/testsuite/compilable/compile_time_array_length.elna
index e38919e..9e2c896 100644
--- a/testsuite/compilable/compile_time_array_length.elna
+++ b/testsuite/compilable/compile_time_array_length.elna
@@ -1,3 +1,5 @@
+module
+
var
source: const [3]Int := [1, 2, 3]
target: Word := source.length
diff --git a/testsuite/compilable/const_alias.elna b/testsuite/compilable/const_alias.elna
index 3a6b365..e4b6434 100644
--- a/testsuite/compilable/const_alias.elna
+++ b/testsuite/compilable/const_alias.elna
@@ -1,3 +1,5 @@
+module
+
type
CI = const Int
CCI = const CI
diff --git a/testsuite/compilable/const_element_array.elna b/testsuite/compilable/const_element_array.elna
index 2d68ff5..d6419fa 100644
--- a/testsuite/compilable/const_element_array.elna
+++ b/testsuite/compilable/const_element_array.elna
@@ -1,3 +1,5 @@
+module
+
type
CI = const Int
diff --git a/testsuite/compilable/const_extern.elna b/testsuite/compilable/const_extern.elna
index 9e8fbb0..6f4b058 100644
--- a/testsuite/compilable/const_extern.elna
+++ b/testsuite/compilable/const_extern.elna
@@ -1,3 +1,5 @@
+module
+
var
errno_like: const Int := extern
diff --git a/testsuite/compilable/const_negation.elna b/testsuite/compilable/const_negation.elna
index 82a4cb6..1dd45f4 100644
--- a/testsuite/compilable/const_negation.elna
+++ b/testsuite/compilable/const_negation.elna
@@ -1,11 +1,9 @@
+program()
var
x: const Int := -5
y: const Int := -x
-program()
begin
assert(x = -5);
assert(y = 5);
-return 0u8
-
end.
diff --git a/testsuite/compilable/const_var_chain.elna b/testsuite/compilable/const_var_chain.elna
index ad85f48..438b79a 100644
--- a/testsuite/compilable/const_var_chain.elna
+++ b/testsuite/compilable/const_var_chain.elna
@@ -1,10 +1,8 @@
+program()
var
x: const Int := 42
y: Int := x
-program()
begin
assert(y = 42)
-return 0u8
-
end.
diff --git a/testsuite/compilable/double_literals.elna b/testsuite/compilable/double_literals.elna
index 9e8a73d..2f2bcdd 100644
--- a/testsuite/compilable/double_literals.elna
+++ b/testsuite/compilable/double_literals.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
var
x: const Double := 3.14
diff --git a/testsuite/compilable/empty_proc.elna b/testsuite/compilable/empty_proc.elna
index bf3bd84..d08593b 100644
--- a/testsuite/compilable/empty_proc.elna
+++ b/testsuite/compilable/empty_proc.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
return
diff --git a/testsuite/compilable/empty_proc_type_expression.elna b/testsuite/compilable/empty_proc_type_expression.elna
index 7738cae..f9c0819 100644
--- a/testsuite/compilable/empty_proc_type_expression.elna
+++ b/testsuite/compilable/empty_proc_type_expression.elna
@@ -1,3 +1,5 @@
+module
+
type
P = proc()
diff --git a/testsuite/compilable/empty_statements_in_a_row.elna b/testsuite/compilable/empty_statements_in_a_row.elna
index 7cf723c..465ab19 100644
--- a/testsuite/compilable/empty_statements_in_a_row.elna
+++ b/testsuite/compilable/empty_statements_in_a_row.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
begin
;
diff --git a/testsuite/compilable/generic_alias.elna b/testsuite/compilable/generic_alias.elna
index 3b431be..47ac638 100644
--- a/testsuite/compilable/generic_alias.elna
+++ b/testsuite/compilable/generic_alias.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -20,12 +21,9 @@ var
raw: ^^File
boxed: Boxed#[^File]
-program()
begin
chain.next := nil;
aliased := raw;
raw := aliased;
boxed.inner := @chain
-return 0u8
-
end.
diff --git a/testsuite/compilable/generic_arguments.elna b/testsuite/compilable/generic_arguments.elna
index 6bc5242..4d33db5 100644
--- a/testsuite/compilable/generic_arguments.elna
+++ b/testsuite/compilable/generic_arguments.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -11,18 +12,15 @@ type
var
entry: Pair#[^File, ^Word8]
-proc allocate#[T](size: Word) -> T extern
+proc allocate#[T](size: Word) -> T
+extern
proc first#[K, V](entry_ptr: ^Pair#[K, V]) -> K
-begin
return entry_ptr^.key
-program()
begin
entry.key := allocate#[^File](#size(File));
assert(#size(Pair#[^File, ^Word8]) = #size(Pointer) * 2u);
assert(#offset(Pair#[^File, ^Word8], value) = #size(Pointer));
assert(first#[^File, ^Word8](@entry) = entry.key)
-return 0u8
-
end.
diff --git a/testsuite/compilable/generic_base_chain.elna b/testsuite/compilable/generic_base_chain.elna
index 736042b..c303e6d 100644
--- a/testsuite/compilable/generic_base_chain.elna
+++ b/testsuite/compilable/generic_base_chain.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -22,10 +23,7 @@ begin
target^.key := key
return
-program()
begin
upcast := @store;
put(@store, byte_key)
-return 0u8
-
end.
diff --git a/testsuite/compilable/generic_inference.elna b/testsuite/compilable/generic_inference.elna
index 25faca4..ab1ff3a 100644
--- a/testsuite/compilable/generic_inference.elna
+++ b/testsuite/compilable/generic_inference.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -23,11 +24,8 @@ begin
store(target, value)
return
-program()
begin
store(@files, @f);
relay(@bytes, @b);
store(@files, nil)
-return 0u8
-
end.
diff --git a/testsuite/compilable/opaque_type.elna b/testsuite/compilable/opaque_type.elna
index c570e0d..6474337 100644
--- a/testsuite/compilable/opaque_type.elna
+++ b/testsuite/compilable/opaque_type.elna
@@ -1,3 +1,4 @@
+program()
type
Handle = extern
Alias = Handle
@@ -9,9 +10,6 @@ var
proc take(h: ^Handle) -> ^Handle
return h
-program()
begin
alias := take(handle)
-return 0u8
-
end.
diff --git a/testsuite/compilable/pointer_cast.elna b/testsuite/compilable/pointer_cast.elna
index ad15432..2b986c0 100644
--- a/testsuite/compilable/pointer_cast.elna
+++ b/testsuite/compilable/pointer_cast.elna
@@ -1,11 +1,9 @@
+program()
var
c: ^Char := nil
p: Pointer := nil
-program()
begin
p := c;
c := p
-return 0u8
-
end.
diff --git a/testsuite/compilable/pointer_const_conversion.elna b/testsuite/compilable/pointer_const_conversion.elna
index a5bd297..c08862b 100644
--- a/testsuite/compilable/pointer_const_conversion.elna
+++ b/testsuite/compilable/pointer_const_conversion.elna
@@ -1,10 +1,8 @@
+program()
var
x: Int
p: ^const Int
-program()
begin
p := @x
-return 0u8
-
end.
diff --git a/testsuite/compilable/pointer_subtraction.elna b/testsuite/compilable/pointer_subtraction.elna
index 8dd1ff6..738845d 100644
--- a/testsuite/compilable/pointer_subtraction.elna
+++ b/testsuite/compilable/pointer_subtraction.elna
@@ -1,3 +1,5 @@
+module
+
proc test(a, b: ^Char) -> Int
return a - b
diff --git a/testsuite/compilable/procedure_forward_reference.elna b/testsuite/compilable/procedure_forward_reference.elna
index cdf3008..0e6f93c 100644
--- a/testsuite/compilable/procedure_forward_reference.elna
+++ b/testsuite/compilable/procedure_forward_reference.elna
@@ -1,3 +1,5 @@
+module
+
proc first() -> Int
return second() + 1
diff --git a/testsuite/compilable/record_const_base.elna b/testsuite/compilable/record_const_base.elna
index f24d27b..a4c6b7b 100644
--- a/testsuite/compilable/record_const_base.elna
+++ b/testsuite/compilable/record_const_base.elna
@@ -1,3 +1,5 @@
+module
+
type
B = record
x: Int
diff --git a/testsuite/compilable/self-referencing-record.elna b/testsuite/compilable/self-referencing-record.elna
index 311f148..d340492 100644
--- a/testsuite/compilable/self-referencing-record.elna
+++ b/testsuite/compilable/self-referencing-record.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record
field: ^R
diff --git a/testsuite/compilable/semicolon_parameter_separator.elna b/testsuite/compilable/semicolon_parameter_separator.elna
index 229fde0..c998606 100644
--- a/testsuite/compilable/semicolon_parameter_separator.elna
+++ b/testsuite/compilable/semicolon_parameter_separator.elna
@@ -1,3 +1,5 @@
+module
+
proc f(a: Int; b: Word)
return
diff --git a/testsuite/compilable/single_literals.elna b/testsuite/compilable/single_literals.elna
index ac03623..a18d2ca 100644
--- a/testsuite/compilable/single_literals.elna
+++ b/testsuite/compilable/single_literals.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
var
x: const Single := 3.14f
diff --git a/testsuite/compilable/slice_index.elna b/testsuite/compilable/slice_index.elna
index 70d26ae..13121eb 100644
--- a/testsuite/compilable/slice_index.elna
+++ b/testsuite/compilable/slice_index.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
var
a: []Int
diff --git a/testsuite/compilable/take_const_address.elna b/testsuite/compilable/take_const_address.elna
index 4f82b2a..a60b1c2 100644
--- a/testsuite/compilable/take_const_address.elna
+++ b/testsuite/compilable/take_const_address.elna
@@ -1,10 +1,8 @@
+program()
var
x: ^const Int
y: const Int := 1
-program()
begin
x := @y
-return 0u8
-
end.
diff --git a/testsuite/compilable/trailing_text.elna b/testsuite/compilable/trailing_text.elna
index 1eb3595..0a95516 100644
--- a/testsuite/compilable/trailing_text.elna
+++ b/testsuite/compilable/trailing_text.elna
@@ -1,3 +1,5 @@
+module
+
end.
Everything after the module terminator is ignored and is never scanned, so it
diff --git a/testsuite/compilable/traits_size.elna b/testsuite/compilable/traits_size.elna
index f245637..ad49b61 100644
--- a/testsuite/compilable/traits_size.elna
+++ b/testsuite/compilable/traits_size.elna
@@ -1,3 +1,4 @@
+program()
var
i: Int := 1
s: Int := cast(#size(Int): Int)
@@ -5,11 +6,8 @@ var
as: Int := cast(#size([10]Int): Int)
p: Int := cast(#size(Pointer): Int)
-program()
begin
assert(s > 0);
assert(as = 10 * cast(#size(Int): Int));
assert(p > 0)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/access_record_type_field.elna b/testsuite/fail_compilation/access_record_type_field.elna
index 4378404..4dcdceb 100644
--- a/testsuite/fail_compilation/access_record_type_field.elna
+++ b/testsuite/fail_compilation/access_record_type_field.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record
field1, field2: Int
diff --git a/testsuite/fail_compilation/alias-cycle-behind-const.elna b/testsuite/fail_compilation/alias-cycle-behind-const.elna
index 0c3b626..a05240b 100644
--- a/testsuite/fail_compilation/alias-cycle-behind-const.elna
+++ b/testsuite/fail_compilation/alias-cycle-behind-const.elna
@@ -1,4 +1,7 @@
+module
+
type
A = B
B = const A (* @Error Type declaration forms a cycle: A -> B -> A *)
+
end.
diff --git a/testsuite/fail_compilation/alias-cycle.elna b/testsuite/fail_compilation/alias-cycle.elna
index e6c822b..ba05947 100644
--- a/testsuite/fail_compilation/alias-cycle.elna
+++ b/testsuite/fail_compilation/alias-cycle.elna
@@ -1,4 +1,7 @@
+module
+
type
A = B
B = A (* @Error Type declaration forms a cycle: A -> B -> A *)
+
end.
diff --git a/testsuite/fail_compilation/alias-field-cycle.elna b/testsuite/fail_compilation/alias-field-cycle.elna
index f4a554a..8296c69 100644
--- a/testsuite/fail_compilation/alias-field-cycle.elna
+++ b/testsuite/fail_compilation/alias-field-cycle.elna
@@ -1,5 +1,8 @@
+module
+
type
A = record (* @Error Type declaration forms a cycle: A -> A *)
field: A
end
+
end.
diff --git a/testsuite/fail_compilation/aligned_attribute.elna b/testsuite/fail_compilation/aligned_attribute.elna
index aab5513..46a9b94 100644
--- a/testsuite/fail_compilation/aligned_attribute.elna
+++ b/testsuite/fail_compilation/aligned_attribute.elna
@@ -1,3 +1,4 @@
+module
type
Uneven = record
x #{aligned 3}: Word8 (* @Error Alignment must be a power of two *)
@@ -10,11 +11,6 @@ type
end
proc takes(p #{aligned 8}: Int) (* @Error Attribute 'aligned' is not supported in this position *)
-begin
return
-program()
-begin
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/array-cycle.elna b/testsuite/fail_compilation/array-cycle.elna
index 617e23d..a5b79c2 100644
--- a/testsuite/fail_compilation/array-cycle.elna
+++ b/testsuite/fail_compilation/array-cycle.elna
@@ -1,3 +1,6 @@
+module
+
type
A = [2]A (* @Error Type declaration forms a cycle: A -> A *)
+
end.
diff --git a/testsuite/fail_compilation/assign_array_length.elna b/testsuite/fail_compilation/assign_array_length.elna
index 92d6769..c794b11 100644
--- a/testsuite/fail_compilation/assign_array_length.elna
+++ b/testsuite/fail_compilation/assign_array_length.elna
@@ -1,10 +1,8 @@
+program()
var
slice: []Int
array: [2]Int
-program()
begin
array.length := slice.length (* @Error Cannot assign to a value of type 'const Word', because it is constant or contains constant members *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/assign_const_array_pointer.elna b/testsuite/fail_compilation/assign_const_array_pointer.elna
index 32dc66d..d8ecb72 100644
--- a/testsuite/fail_compilation/assign_const_array_pointer.elna
+++ b/testsuite/fail_compilation/assign_const_array_pointer.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
var
p: ^[2]Int
diff --git a/testsuite/fail_compilation/assign_const_element.elna b/testsuite/fail_compilation/assign_const_element.elna
index 9b9c341..721d337 100644
--- a/testsuite/fail_compilation/assign_const_element.elna
+++ b/testsuite/fail_compilation/assign_const_element.elna
@@ -1,3 +1,5 @@
+module
+
type
CI = const Int
diff --git a/testsuite/fail_compilation/assign_const_member.elna b/testsuite/fail_compilation/assign_const_member.elna
index 8aecb01..a603729 100644
--- a/testsuite/fail_compilation/assign_const_member.elna
+++ b/testsuite/fail_compilation/assign_const_member.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record
x: const Int
diff --git a/testsuite/fail_compilation/assign_const_primitive.elna b/testsuite/fail_compilation/assign_const_primitive.elna
index 22fef25..2db9c85 100644
--- a/testsuite/fail_compilation/assign_const_primitive.elna
+++ b/testsuite/fail_compilation/assign_const_primitive.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
var
x: const Int := 4
diff --git a/testsuite/fail_compilation/assign_const_record_pointer.elna b/testsuite/fail_compilation/assign_const_record_pointer.elna
index 5e6f3df..adf3d91 100644
--- a/testsuite/fail_compilation/assign_const_record_pointer.elna
+++ b/testsuite/fail_compilation/assign_const_record_pointer.elna
@@ -1,3 +1,5 @@
+module
+
type
B = record
x: Int
diff --git a/testsuite/fail_compilation/assign_const_to_pointer.elna b/testsuite/fail_compilation/assign_const_to_pointer.elna
index 50e4a44..796b60c 100644
--- a/testsuite/fail_compilation/assign_const_to_pointer.elna
+++ b/testsuite/fail_compilation/assign_const_to_pointer.elna
@@ -1,10 +1,8 @@
+program()
var
c: const Int := 2
p: Pointer
-program()
begin
p := @c (* @Error Expected type 'Pointer', but got '\^const Int' *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/assign_deep_const_pointer.elna b/testsuite/fail_compilation/assign_deep_const_pointer.elna
index 7ed3840..7c977d4 100644
--- a/testsuite/fail_compilation/assign_deep_const_pointer.elna
+++ b/testsuite/fail_compilation/assign_deep_const_pointer.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
var
p: ^^const Int
diff --git a/testsuite/fail_compilation/assign_element_of_const.elna b/testsuite/fail_compilation/assign_element_of_const.elna
index 8235448..a51822b 100644
--- a/testsuite/fail_compilation/assign_element_of_const.elna
+++ b/testsuite/fail_compilation/assign_element_of_const.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
var
a: const [2]Int := [1, 3]
diff --git a/testsuite/fail_compilation/assign_from_const_pointer.elna b/testsuite/fail_compilation/assign_from_const_pointer.elna
index 4c383cc..64f7f5d 100644
--- a/testsuite/fail_compilation/assign_from_const_pointer.elna
+++ b/testsuite/fail_compilation/assign_from_const_pointer.elna
@@ -1,10 +1,8 @@
+program()
var
cv: const Pointer := nil
p: Pointer
-program()
begin
p := cv (* @Error Expected type 'Pointer', but got 'const Pointer' *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/assign_member_of_const.elna b/testsuite/fail_compilation/assign_member_of_const.elna
index fc945bb..efdf67b 100644
--- a/testsuite/fail_compilation/assign_member_of_const.elna
+++ b/testsuite/fail_compilation/assign_member_of_const.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record
x: Int
diff --git a/testsuite/fail_compilation/assign_slice_ptr.elna b/testsuite/fail_compilation/assign_slice_ptr.elna
index fa3dd22..b4e72f1 100644
--- a/testsuite/fail_compilation/assign_slice_ptr.elna
+++ b/testsuite/fail_compilation/assign_slice_ptr.elna
@@ -1,10 +1,8 @@
+program()
var
slice: []Int
array: [2]Int
-program()
begin
slice.ptr := array.ptr (* @Error Cannot assign to a value of type 'const \^Int', because it is constant or contains constant members *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/assign_to_call_result_field.elna b/testsuite/fail_compilation/assign_to_call_result_field.elna
index 50cd135..e4995e5 100644
--- a/testsuite/fail_compilation/assign_to_call_result_field.elna
+++ b/testsuite/fail_compilation/assign_to_call_result_field.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
x: Int
@@ -10,9 +11,6 @@ begin
result.x := 1
return result
-program()
begin
make().x := 5 (* @Error Expression of type 'Int' is not addressable *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/assign_to_slicing.elna b/testsuite/fail_compilation/assign_to_slicing.elna
index 92d0dae..da369b3 100644
--- a/testsuite/fail_compilation/assign_to_slicing.elna
+++ b/testsuite/fail_compilation/assign_to_slicing.elna
@@ -1,10 +1,8 @@
+program()
var
s: [3]Int
t: [2]Int
-program()
begin
s[1 to 2] := t[1 to 2] (* @Error Expression of type '\[\]Int' is not addressable *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/assign_void_call.elna b/testsuite/fail_compilation/assign_void_call.elna
index 75f7c6b..ecdba8d 100644
--- a/testsuite/fail_compilation/assign_void_call.elna
+++ b/testsuite/fail_compilation/assign_void_call.elna
@@ -1,12 +1,10 @@
+program()
var
x: Int
proc v()
return
-program()
begin
x := v() (* @Error Expected type 'Int', but the expression has no value *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/case_label_overflow.elna b/testsuite/fail_compilation/case_label_overflow.elna
index def83e9..cfed88a 100644
--- a/testsuite/fail_compilation/case_label_overflow.elna
+++ b/testsuite/fail_compilation/case_label_overflow.elna
@@ -1,7 +1,7 @@
+program()
var
x: Int8 := 100i8
-program()
begin
case x of
100i8: assert(true)
@@ -9,6 +9,4 @@ begin
else
assert(false)
end
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/case_non_constant.elna b/testsuite/fail_compilation/case_non_constant.elna
index 0345653..9f7ba9a 100644
--- a/testsuite/fail_compilation/case_non_constant.elna
+++ b/testsuite/fail_compilation/case_non_constant.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
a: Int;
@@ -8,12 +9,9 @@ var
r: R
x: R
-program()
begin
x := r;
case x of
r: (* @Error Case label must be a constant expression *)
end
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/case_type_mismatch.elna b/testsuite/fail_compilation/case_type_mismatch.elna
index 56be244..f2db7e7 100644
--- a/testsuite/fail_compilation/case_type_mismatch.elna
+++ b/testsuite/fail_compilation/case_type_mismatch.elna
@@ -1,12 +1,10 @@
+program()
var
x: Int
-program()
begin
case x of
1: (* ok *)
| true: (* @Error Invalid operands of type 'Int' and 'Bool' for operator = *)
end
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/case_unique_label.elna b/testsuite/fail_compilation/case_unique_label.elna
index 95d5f53..7ee8391 100644
--- a/testsuite/fail_compilation/case_unique_label.elna
+++ b/testsuite/fail_compilation/case_unique_label.elna
@@ -5,6 +5,4 @@ begin
| 3:
| 1 + 2: (* @Error Duplicate case label *)
end
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/circular_import/sut.elna b/testsuite/fail_compilation/circular_import/sut.elna
index f6452fb..7641a73 100644
--- a/testsuite/fail_compilation/circular_import/sut.elna
+++ b/testsuite/fail_compilation/circular_import/sut.elna
@@ -1,3 +1,5 @@
+module
+
import sut (* @Error Circular import of module 'sut' *)
end.
diff --git a/testsuite/fail_compilation/compare_unrelated_records.elna b/testsuite/fail_compilation/compare_unrelated_records.elna
index 4b04aa7..a113809 100644
--- a/testsuite/fail_compilation/compare_unrelated_records.elna
+++ b/testsuite/fail_compilation/compare_unrelated_records.elna
@@ -1,3 +1,4 @@
+program()
type
A = record
x: Int
@@ -12,9 +13,6 @@ var
b: B
ok: Bool
-program()
begin
ok := b = a (* @Error Invalid operands of type 'B' and 'A' for operator = *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/compile_time_array_ptr.elna b/testsuite/fail_compilation/compile_time_array_ptr.elna
index bd630ac..f11f2f2 100644
--- a/testsuite/fail_compilation/compile_time_array_ptr.elna
+++ b/testsuite/fail_compilation/compile_time_array_ptr.elna
@@ -1,3 +1,5 @@
+module
+
var
source: [3]Int := [1, 2, 3]
target: ^Int := source.ptr (* @Error Variable initializers must be constant expressions *)
diff --git a/testsuite/fail_compilation/const_array.elna b/testsuite/fail_compilation/const_array.elna
index 7a1a6f5..d42f0b4 100644
--- a/testsuite/fail_compilation/const_array.elna
+++ b/testsuite/fail_compilation/const_array.elna
@@ -1,7 +1,8 @@
+module
+
proc f()
var
a: [10]const Int (* @Error const must be written before the array size, not after *)
-begin
return
end.
diff --git a/testsuite/fail_compilation/const_uninitialized.elna b/testsuite/fail_compilation/const_uninitialized.elna
index 06db3d7..a3be5d3 100644
--- a/testsuite/fail_compilation/const_uninitialized.elna
+++ b/testsuite/fail_compilation/const_uninitialized.elna
@@ -1,3 +1,5 @@
+module
+
var
x: const Int (* @Error All constants should be initialized *)
diff --git a/testsuite/fail_compilation/constant_enum_to_int.elna b/testsuite/fail_compilation/constant_enum_to_int.elna
index 85f6d4c..194109b 100644
--- a/testsuite/fail_compilation/constant_enum_to_int.elna
+++ b/testsuite/fail_compilation/constant_enum_to_int.elna
@@ -1,3 +1,4 @@
+program()
type
Enumeration = (one, two, three)
@@ -5,9 +6,6 @@ var
x: [3]Int := [1, 2, 3]
y: []Int
-program()
begin
y := x[Enumeration.one to Enumeration.two] (* @Error Array index must be an integral type, but got 'Enumeration' *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/double_const.elna b/testsuite/fail_compilation/double_const.elna
index 204a7f7..fe1b134 100644
--- a/testsuite/fail_compilation/double_const.elna
+++ b/testsuite/fail_compilation/double_const.elna
@@ -1,7 +1,8 @@
+module
+
proc f()
var
x: const const Int (* @Error Duplicate 'const' qualifier is not allowed *)
-begin
return
end.
diff --git a/testsuite/fail_compilation/enumeration_member_missing.elna b/testsuite/fail_compilation/enumeration_member_missing.elna
index 6f82131..69f1eed 100644
--- a/testsuite/fail_compilation/enumeration_member_missing.elna
+++ b/testsuite/fail_compilation/enumeration_member_missing.elna
@@ -1,3 +1,5 @@
+module
+
type
Enumeration = (one, two, three)
diff --git a/testsuite/fail_compilation/float_remainder.elna b/testsuite/fail_compilation/float_remainder.elna
index ec6c9e2..f2eba60 100644
--- a/testsuite/fail_compilation/float_remainder.elna
+++ b/testsuite/fail_compilation/float_remainder.elna
@@ -1,3 +1,5 @@
+module
+
proc f()
var
x: Double
diff --git a/testsuite/fail_compilation/generic_arity.elna b/testsuite/fail_compilation/generic_arity.elna
index bb234af..645aded 100644
--- a/testsuite/fail_compilation/generic_arity.elna
+++ b/testsuite/fail_compilation/generic_arity.elna
@@ -1,3 +1,5 @@
+module
+
type
Stack#[T] = record
items: T
@@ -6,8 +8,4 @@ type
var
broken: Stack (* @Error Too few type arguments for generic 'Stack', expected 1, got 0 *)
-program()
-begin
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/generic_base_mismatch.elna b/testsuite/fail_compilation/generic_base_mismatch.elna
index 64e0c40..e361052 100644
--- a/testsuite/fail_compilation/generic_base_mismatch.elna
+++ b/testsuite/fail_compilation/generic_base_mismatch.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -18,9 +19,6 @@ var
jobs: Queue#[^File]
wrong: ^List#[^Socket]
-program()
begin
wrong := @jobs (* @Error Expected type '\^List#\[\^Socket\]', but got '\^Queue#\[\^File\]' *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/generic_parameter_arithmetic.elna b/testsuite/fail_compilation/generic_parameter_arithmetic.elna
index 969c5c7..e05b1ee 100644
--- a/testsuite/fail_compilation/generic_parameter_arithmetic.elna
+++ b/testsuite/fail_compilation/generic_parameter_arithmetic.elna
@@ -1,11 +1,9 @@
+module
+
proc walk#[T](value: T; step: ^T)
begin
step := step + 1;
value := value + 1 (* @Error Type parameter 'T' cannot be used in pointer arithmetic *)
return
-program()
-begin
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/generic_uninferrable.elna b/testsuite/fail_compilation/generic_uninferrable.elna
index 20d3d25..b3556d6 100644
--- a/testsuite/fail_compilation/generic_uninferrable.elna
+++ b/testsuite/fail_compilation/generic_uninferrable.elna
@@ -1,10 +1,10 @@
-proc allocate#[R](size: Word) -> R extern
-
program()
var
got: ^Word8
+
+proc allocate#[R](size: Word) -> R
+extern
+
begin
got := allocate(8u) (* @Error Type parameter 'R' of 'allocate' cannot be inferred *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/import_import_collision/first.elna b/testsuite/fail_compilation/import_import_collision/first.elna
index e60ca8e..251eaee 100644
--- a/testsuite/fail_compilation/import_import_collision/first.elna
+++ b/testsuite/fail_compilation/import_import_collision/first.elna
@@ -1,3 +1,5 @@
+module
+
var
X*: Int := 1
diff --git a/testsuite/fail_compilation/import_import_collision/second.elna b/testsuite/fail_compilation/import_import_collision/second.elna
index 0a3d8e0..65f1ed3 100644
--- a/testsuite/fail_compilation/import_import_collision/second.elna
+++ b/testsuite/fail_compilation/import_import_collision/second.elna
@@ -1,3 +1,5 @@
+module
+
var
X*: Int := 2
diff --git a/testsuite/fail_compilation/import_import_collision/sut.elna b/testsuite/fail_compilation/import_import_collision/sut.elna
index 208aa21..657113d 100644
--- a/testsuite/fail_compilation/import_import_collision/sut.elna
+++ b/testsuite/fail_compilation/import_import_collision/sut.elna
@@ -1,3 +1,5 @@
+module
+
import first, second (* @Error Symbol 'X' has been already defined *)
end.
diff --git a/testsuite/fail_compilation/import_local_collision/helper.elna b/testsuite/fail_compilation/import_local_collision/helper.elna
index e60ca8e..251eaee 100644
--- a/testsuite/fail_compilation/import_local_collision/helper.elna
+++ b/testsuite/fail_compilation/import_local_collision/helper.elna
@@ -1,3 +1,5 @@
+module
+
var
X*: Int := 1
diff --git a/testsuite/fail_compilation/import_local_collision/sut.elna b/testsuite/fail_compilation/import_local_collision/sut.elna
index ecac1ca..c628941 100644
--- a/testsuite/fail_compilation/import_local_collision/sut.elna
+++ b/testsuite/fail_compilation/import_local_collision/sut.elna
@@ -1,9 +1,8 @@
+program()
+
import helper
var
X: Int (* @Error Symbol 'X' has been already defined *)
-program()
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/local_var_exported.elna b/testsuite/fail_compilation/local_var_exported.elna
index 307d34f..be0183d 100644
--- a/testsuite/fail_compilation/local_var_exported.elna
+++ b/testsuite/fail_compilation/local_var_exported.elna
@@ -1,3 +1,5 @@
+module
+
proc test_local_export()
var
v* : Int (* @Error Local symbols cannot be exported *)
diff --git a/testsuite/fail_compilation/local_var_extern.elna b/testsuite/fail_compilation/local_var_extern.elna
index d0eb22f..948689c 100644
--- a/testsuite/fail_compilation/local_var_extern.elna
+++ b/testsuite/fail_compilation/local_var_extern.elna
@@ -1,3 +1,5 @@
+module
+
proc test_local_extern()
var
v : Int := extern (* @Error Local symbols cannot be extern *)
diff --git a/testsuite/fail_compilation/negative_integer_literal_overflow.elna b/testsuite/fail_compilation/negative_integer_literal_overflow.elna
index 7db4888..fa90009 100644
--- a/testsuite/fail_compilation/negative_integer_literal_overflow.elna
+++ b/testsuite/fail_compilation/negative_integer_literal_overflow.elna
@@ -1,3 +1,5 @@
+module
+
var
a: Int8 := -200i8 (* @Error Integer literal overflows *)
diff --git a/testsuite/fail_compilation/non_constant_array_dimension.elna b/testsuite/fail_compilation/non_constant_array_dimension.elna
index 8efb9e9..3c69b7e 100644
--- a/testsuite/fail_compilation/non_constant_array_dimension.elna
+++ b/testsuite/fail_compilation/non_constant_array_dimension.elna
@@ -1,12 +1,10 @@
+program()
+
proc f(len: Int)
var
array: [len]Int (* @Error Array dimensions for type 'Int' should be constant *)
-begin
- return
+return
-program()
begin
f(5)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/offset_not_record.elna b/testsuite/fail_compilation/offset_not_record.elna
index d19e608..93459e4 100644
--- a/testsuite/fail_compilation/offset_not_record.elna
+++ b/testsuite/fail_compilation/offset_not_record.elna
@@ -1,9 +1,7 @@
+program()
var
n: Word
-program()
begin
n := #offset(Int, top) (* @Error Type 'Int' does not support trait '#offset' *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/opaque_pointer_arithmetic.elna b/testsuite/fail_compilation/opaque_pointer_arithmetic.elna
index cb3a20e..117994a 100644
--- a/testsuite/fail_compilation/opaque_pointer_arithmetic.elna
+++ b/testsuite/fail_compilation/opaque_pointer_arithmetic.elna
@@ -1,12 +1,10 @@
+program()
type
Handle = extern
var
p: ^Handle
-program()
begin
p := p + 1 (* @Error Opaque type 'Handle' cannot be used as an element type in pointer arithmetic *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/opaque_slice_element.elna b/testsuite/fail_compilation/opaque_slice_element.elna
index f50be8a..1dc341d 100644
--- a/testsuite/fail_compilation/opaque_slice_element.elna
+++ b/testsuite/fail_compilation/opaque_slice_element.elna
@@ -1,3 +1,5 @@
+module
+
type
Handle = extern
diff --git a/testsuite/fail_compilation/pointer-cycle.elna b/testsuite/fail_compilation/pointer-cycle.elna
index fe0258a..f2ed05c 100644
--- a/testsuite/fail_compilation/pointer-cycle.elna
+++ b/testsuite/fail_compilation/pointer-cycle.elna
@@ -1,3 +1,5 @@
+module
+
type
A = ^A (* @Error Type declaration forms a cycle: A -> A *)
diff --git a/testsuite/fail_compilation/proc_type_without_parameters.elna b/testsuite/fail_compilation/proc_type_without_parameters.elna
index f7cdffe..d15b7f5 100644
--- a/testsuite/fail_compilation/proc_type_without_parameters.elna
+++ b/testsuite/fail_compilation/proc_type_without_parameters.elna
@@ -1,12 +1,10 @@
+program()
var
x: Int
proc f()
return
-program()
begin
x := f (* @Error Expected type 'Int', but got 'proc\(\)' *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/procedure-cycle.elna b/testsuite/fail_compilation/procedure-cycle.elna
index 2284605..f9a128d 100644
--- a/testsuite/fail_compilation/procedure-cycle.elna
+++ b/testsuite/fail_compilation/procedure-cycle.elna
@@ -1,3 +1,5 @@
+module
+
type
A = proc() -> A (* @Error Type declaration forms a cycle: A -> A *)
diff --git a/testsuite/fail_compilation/program_arguments.elna b/testsuite/fail_compilation/program_arguments.elna
index e614368..73c38df 100644
--- a/testsuite/fail_compilation/program_arguments.elna
+++ b/testsuite/fail_compilation/program_arguments.elna
@@ -1,4 +1,2 @@
program(first, second) (* @Error Program entry point should have no or one argument *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/record-base-cycle-indirect.elna b/testsuite/fail_compilation/record-base-cycle-indirect.elna
index f60b1aa..75c9805 100644
--- a/testsuite/fail_compilation/record-base-cycle-indirect.elna
+++ b/testsuite/fail_compilation/record-base-cycle-indirect.elna
@@ -1,3 +1,5 @@
+module
+
type
A = record(B)
x: Int
@@ -9,8 +11,4 @@ type
var
v: A
-program()
-begin
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/record-base-cycle.elna b/testsuite/fail_compilation/record-base-cycle.elna
index 8af254d..ea3d888 100644
--- a/testsuite/fail_compilation/record-base-cycle.elna
+++ b/testsuite/fail_compilation/record-base-cycle.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record(R) (* @Error Type declaration forms a cycle: R -> R *)
end
diff --git a/testsuite/fail_compilation/record_base_constructor_type_mismatch.elna b/testsuite/fail_compilation/record_base_constructor_type_mismatch.elna
index 621a06c..d7a8419 100644
--- a/testsuite/fail_compilation/record_base_constructor_type_mismatch.elna
+++ b/testsuite/fail_compilation/record_base_constructor_type_mismatch.elna
@@ -1,3 +1,4 @@
+program()
type
Base = record
a: Int
@@ -9,9 +10,6 @@ type
var
c: Child
-program()
begin
c := Child{a: "wrong", b: 9} (* @Error Expected type 'Int', but got '\[\]const Word8' *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/record_duplicate_field.elna b/testsuite/fail_compilation/record_duplicate_field.elna
index 5cf69a9..0cdfbaa 100644
--- a/testsuite/fail_compilation/record_duplicate_field.elna
+++ b/testsuite/fail_compilation/record_duplicate_field.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record
x: Int;
diff --git a/testsuite/fail_compilation/record_duplicate_field_import_base/helper.elna b/testsuite/fail_compilation/record_duplicate_field_import_base/helper.elna
index 0edb965..7865a3f 100644
--- a/testsuite/fail_compilation/record_duplicate_field_import_base/helper.elna
+++ b/testsuite/fail_compilation/record_duplicate_field_import_base/helper.elna
@@ -1,3 +1,5 @@
+module
+
type
Parent* = record
x: Int;
diff --git a/testsuite/fail_compilation/record_duplicate_field_import_base/sut.elna b/testsuite/fail_compilation/record_duplicate_field_import_base/sut.elna
index 58f2f3d..97d9a2f 100644
--- a/testsuite/fail_compilation/record_duplicate_field_import_base/sut.elna
+++ b/testsuite/fail_compilation/record_duplicate_field_import_base/sut.elna
@@ -1,3 +1,5 @@
+module
+
import helper
type
diff --git a/testsuite/fail_compilation/redefined_variable.elna b/testsuite/fail_compilation/redefined_variable.elna
index 905f6ed..1856807 100644
--- a/testsuite/fail_compilation/redefined_variable.elna
+++ b/testsuite/fail_compilation/redefined_variable.elna
@@ -1,3 +1,5 @@
+module
+
var
x: Int
x: Int (* @Error Symbol 'x' has been already defined *)
diff --git a/testsuite/fail_compilation/reference_call_result_field.elna b/testsuite/fail_compilation/reference_call_result_field.elna
index d339ed9..b10d324 100644
--- a/testsuite/fail_compilation/reference_call_result_field.elna
+++ b/testsuite/fail_compilation/reference_call_result_field.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
x: Int
@@ -13,9 +14,6 @@ begin
result.x := 1
return result
-program()
begin
p := @make().x (* @Error Expression of type 'Int' is not addressable *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/reference_literal.elna b/testsuite/fail_compilation/reference_literal.elna
index 26d5a22..72eb986 100644
--- a/testsuite/fail_compilation/reference_literal.elna
+++ b/testsuite/fail_compilation/reference_literal.elna
@@ -1,9 +1,7 @@
+program()
var
p: ^Int
-program()
begin
p := @5 (* @Error Expression of type 'Int' is not addressable *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/reference_slicing.elna b/testsuite/fail_compilation/reference_slicing.elna
index 3875a5d..838e101 100644
--- a/testsuite/fail_compilation/reference_slicing.elna
+++ b/testsuite/fail_compilation/reference_slicing.elna
@@ -1,10 +1,8 @@
+program()
var
s: [3]Int
p: ^Int
-program()
begin
p := @s[1 to 2] (* @Error Expression of type '\[\]Int' is not addressable *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/slice-cycle.elna b/testsuite/fail_compilation/slice-cycle.elna
index fe0a3e1..0ee44a9 100644
--- a/testsuite/fail_compilation/slice-cycle.elna
+++ b/testsuite/fail_compilation/slice-cycle.elna
@@ -1,3 +1,5 @@
+module
+
type
A = []A (* @Error Type declaration forms a cycle: A -> A *)
diff --git a/testsuite/fail_compilation/unary_minus_on_record.elna b/testsuite/fail_compilation/unary_minus_on_record.elna
index d86995b..30da92c 100644
--- a/testsuite/fail_compilation/unary_minus_on_record.elna
+++ b/testsuite/fail_compilation/unary_minus_on_record.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record
x: Int
diff --git a/testsuite/fail_compilation/unary_negation_on_record.elna b/testsuite/fail_compilation/unary_negation_on_record.elna
index d08d2e3..750f828 100644
--- a/testsuite/fail_compilation/unary_negation_on_record.elna
+++ b/testsuite/fail_compilation/unary_negation_on_record.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record
x: Int
diff --git a/testsuite/fail_compilation/unary_plus_on_record.elna b/testsuite/fail_compilation/unary_plus_on_record.elna
index e1f6f4c..59485e3 100644
--- a/testsuite/fail_compilation/unary_plus_on_record.elna
+++ b/testsuite/fail_compilation/unary_plus_on_record.elna
@@ -1,3 +1,5 @@
+module
+
type
R = record
x: Int
diff --git a/testsuite/fail_compilation/varargs_argument.elna b/testsuite/fail_compilation/varargs_argument.elna
index 1325c29..b3b3459 100644
--- a/testsuite/fail_compilation/varargs_argument.elna
+++ b/testsuite/fail_compilation/varargs_argument.elna
@@ -1,12 +1,10 @@
+program()
var
written: Int32
proc printf(format: ^const Word8) #{varargs} -> Int32
extern
-program()
begin
written := printf("%s".ptr, "text") (* @Error Type '\[\]const Word8' cannot be passed as a variadic argument *)
-return 0u8
-
end.
diff --git a/testsuite/fail_compilation/varargs_attribute.elna b/testsuite/fail_compilation/varargs_attribute.elna
index 1c6d3e0..ec42710 100644
--- a/testsuite/fail_compilation/varargs_attribute.elna
+++ b/testsuite/fail_compilation/varargs_attribute.elna
@@ -1,5 +1,6 @@
+module
+
proc with_body(x: Int) #{varargs} (* @Error Attribute 'varargs' is not supported in this position *)
-begin
return
proc no_parameters() #{varargs} -> Int32 (* @Error Attribute 'varargs' requires at least one parameter *)
diff --git a/testsuite/fail_compilation/while_condition.elna b/testsuite/fail_compilation/while_condition.elna
index 0e4aa3c..bd54796 100644
--- a/testsuite/fail_compilation/while_condition.elna
+++ b/testsuite/fail_compilation/while_condition.elna
@@ -2,6 +2,4 @@ program()
begin
while 1 do (* @Error Condition must be a boolean expression, but got 'Int' *)
end
-return 0u8
-
end.
diff --git a/testsuite/runnable/aggregate_argument.elna b/testsuite/runnable/aggregate_argument.elna
index b36ccc3..7ae4947 100644
--- a/testsuite/runnable/aggregate_argument.elna
+++ b/testsuite/runnable/aggregate_argument.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
a: Int;
@@ -7,9 +8,6 @@ type
proc f(r: R) -> Bool
return r.a = 1 & r.b = 2
-program()
begin
assert(f(R{a: 1, b: 2}))
-return 0u8
-
end.
diff --git a/testsuite/runnable/aggregate_equality.elna b/testsuite/runnable/aggregate_equality.elna
index be7b4f1..c9601f9 100644
--- a/testsuite/runnable/aggregate_equality.elna
+++ b/testsuite/runnable/aggregate_equality.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
a: Int;
@@ -7,9 +8,6 @@ type
proc f() -> Bool
return R{a: 1, b: 2} = R{a: 1, b: 2}
-program()
begin
assert(f())
-return 0u8
-
end.
diff --git a/testsuite/runnable/aligned_attribute.elna b/testsuite/runnable/aligned_attribute.elna
index 45c0c37..e339faf 100644
--- a/testsuite/runnable/aligned_attribute.elna
+++ b/testsuite/runnable/aligned_attribute.elna
@@ -1,3 +1,4 @@
+program()
type
Plain = record
a: Word8;
@@ -23,7 +24,6 @@ var
first: ^Word8
second: ^Word8
-program()
begin
assert(#size(Plain) = 2u);
assert(#size(Spread) = 16u);
@@ -36,6 +36,4 @@ begin
first := @spread.a;
second := @spread.b;
assert(cast(second: Word) - cast(first: Word) = 8u)
-return 0u8
-
end.
diff --git a/testsuite/runnable/array_constructor.elna b/testsuite/runnable/array_constructor.elna
index 50d243a..fd22235 100644
--- a/testsuite/runnable/array_constructor.elna
+++ b/testsuite/runnable/array_constructor.elna
@@ -1,14 +1,12 @@
+program()
var
a: [3]Int := [1, 2, 3]
b: [2]Int := [4, 0]
-program()
begin
assert(a[1] = 1 & a[2] = 2 & a[3] = 3);
assert(b[1] = 4 & b[2] = 0);
a := [5, 6, 7];
assert(a[1] = 5 & a[2] = 6 & a[3] = 7)
-return 0u8
-
end.
diff --git a/testsuite/runnable/binary_literal.elna b/testsuite/runnable/binary_literal.elna
index 4f0fc97..6380f24 100644
--- a/testsuite/runnable/binary_literal.elna
+++ b/testsuite/runnable/binary_literal.elna
@@ -2,6 +2,4 @@ program()
begin
assert(0b11 = 3u);
assert(0B011 = 3u)
-return 0u8
-
end.
diff --git a/testsuite/runnable/block_local_variable.elna b/testsuite/runnable/block_local_variable.elna
index 6287eec..8d52b1c 100644
--- a/testsuite/runnable/block_local_variable.elna
+++ b/testsuite/runnable/block_local_variable.elna
@@ -1,6 +1,7 @@
program()
var
total: Int := 0
+
begin
if total = 0 then
var
@@ -9,6 +10,4 @@ begin
total := total + inner
end;
assert(total = 7)
-return 0u8
-
end.
diff --git a/testsuite/runnable/case_constant_label.elna b/testsuite/runnable/case_constant_label.elna
index 49fa2c2..1b01736 100644
--- a/testsuite/runnable/case_constant_label.elna
+++ b/testsuite/runnable/case_constant_label.elna
@@ -1,16 +1,14 @@
+program()
var
base: const Int := 2
limit: const Int := base
x: Int := 2
matched: Bool := false
-program()
begin
case x of
1: assert(false)
| limit: matched := true
end;
assert(matched)
-return 0u8
-
end.
diff --git a/testsuite/runnable/case_else.elna b/testsuite/runnable/case_else.elna
index 68330da..bc84069 100644
--- a/testsuite/runnable/case_else.elna
+++ b/testsuite/runnable/case_else.elna
@@ -1,8 +1,8 @@
+program()
var
x: Int := 5
matched: Bool := false
-program()
begin
case x of
1: assert(false)
@@ -12,6 +12,4 @@ begin
matched := true
end;
assert(matched)
-return 0u8
-
end.
diff --git a/testsuite/runnable/case_int.elna b/testsuite/runnable/case_int.elna
index 3a446d6..018018c 100644
--- a/testsuite/runnable/case_int.elna
+++ b/testsuite/runnable/case_int.elna
@@ -1,7 +1,7 @@
+program()
var
x: Int := 2
-program()
begin
case x of
1: assert(false)
@@ -10,6 +10,4 @@ begin
else
assert(false)
end
-return 0u8
-
end.
diff --git a/testsuite/runnable/case_multilabel.elna b/testsuite/runnable/case_multilabel.elna
index 3a042d2..44bb150 100644
--- a/testsuite/runnable/case_multilabel.elna
+++ b/testsuite/runnable/case_multilabel.elna
@@ -1,7 +1,7 @@
+program()
var
x: Int := 3
-program()
begin
case x of
1, 2, 3: assert(true)
@@ -9,6 +9,4 @@ begin
else
assert(false)
end
-return 0u8
-
end.
diff --git a/testsuite/runnable/case_record.elna b/testsuite/runnable/case_record.elna
index 25b3eb4..db8a6ff 100644
--- a/testsuite/runnable/case_record.elna
+++ b/testsuite/runnable/case_record.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
a: Int;
@@ -7,7 +8,6 @@ type
var
r: R := R{a: 1, b: 2}
-program()
begin
case r of
R{a: 0, b: 0}: assert(false)
@@ -15,6 +15,4 @@ begin
else
assert(false)
end
-return 0u8
-
end.
diff --git a/testsuite/runnable/compile_time_array_access.elna b/testsuite/runnable/compile_time_array_access.elna
index 825e8d5..5ce10a0 100644
--- a/testsuite/runnable/compile_time_array_access.elna
+++ b/testsuite/runnable/compile_time_array_access.elna
@@ -1,10 +1,8 @@
+program()
var
array: const [3]Int := [1, 2, 3]
i: const Int := array[2]
-program()
begin
assert(i = 2)
-return 0u8
-
end.
diff --git a/testsuite/runnable/const_copy.elna b/testsuite/runnable/const_copy.elna
index fde423b..3b7cd1b 100644
--- a/testsuite/runnable/const_copy.elna
+++ b/testsuite/runnable/const_copy.elna
@@ -1,3 +1,4 @@
+program()
proc f()
var
x: const Int := 5
@@ -7,9 +8,6 @@ begin
assert(y = 5)
return
-program()
begin
f()
-return 0u8
-
end.
diff --git a/testsuite/runnable/const_initialization.elna b/testsuite/runnable/const_initialization.elna
index b388845..b4272f4 100644
--- a/testsuite/runnable/const_initialization.elna
+++ b/testsuite/runnable/const_initialization.elna
@@ -1,3 +1,4 @@
+program()
proc f()
var
x: const Int := 5
@@ -5,9 +6,6 @@ begin
assert(x = 5)
return
-program()
begin
f()
-return 0u8
-
end.
diff --git a/testsuite/runnable/constant_string_initializer.elna b/testsuite/runnable/constant_string_initializer.elna
index 0982373..b33b255 100644
--- a/testsuite/runnable/constant_string_initializer.elna
+++ b/testsuite/runnable/constant_string_initializer.elna
@@ -1,9 +1,7 @@
+program()
var
s: []const Word8 := "String value"
-program()
begin
assert(s = "String value")
-return 0u8
-
end.
diff --git a/testsuite/runnable/define_multiple_local_variables.elna b/testsuite/runnable/define_multiple_local_variables.elna
index bd4ba68..13bb357 100644
--- a/testsuite/runnable/define_multiple_local_variables.elna
+++ b/testsuite/runnable/define_multiple_local_variables.elna
@@ -1,11 +1,9 @@
+program()
proc f() -> Bool
var
a, b: Int := 5
return a = 5 & b = 5
-program()
begin
assert(f())
-return 0u8
-
end.
diff --git a/testsuite/runnable/exported_variable/helper.elna b/testsuite/runnable/exported_variable/helper.elna
index 23924be..4b2c9ba 100644
--- a/testsuite/runnable/exported_variable/helper.elna
+++ b/testsuite/runnable/exported_variable/helper.elna
@@ -1,3 +1,5 @@
+module
+
var
Shared*: Int := 42
diff --git a/testsuite/runnable/exported_variable/sut.elna b/testsuite/runnable/exported_variable/sut.elna
index 753293d..1d0449e 100644
--- a/testsuite/runnable/exported_variable/sut.elna
+++ b/testsuite/runnable/exported_variable/sut.elna
@@ -1,8 +1,6 @@
+program()
import helper
-program()
begin
assert(Shared = 42)
-return 0u8
-
end.
diff --git a/testsuite/runnable/fixed_int_max.elna b/testsuite/runnable/fixed_int_max.elna
index 7ccf2fb..f00fd60 100644
--- a/testsuite/runnable/fixed_int_max.elna
+++ b/testsuite/runnable/fixed_int_max.elna
@@ -4,6 +4,4 @@ begin
assert(#max(Int16) = 32767i16);
assert(#max(Int32) = 2147483647i32);
assert(#max(Int64) = 9223372036854775807i64)
-return 0u8
-
end.
diff --git a/testsuite/runnable/fixed_int_min.elna b/testsuite/runnable/fixed_int_min.elna
index f9522fd..fd6b110 100644
--- a/testsuite/runnable/fixed_int_min.elna
+++ b/testsuite/runnable/fixed_int_min.elna
@@ -4,6 +4,4 @@ begin
assert(#min(Int16) = -32768i16);
assert(#min(Int32) = -2147483648i32);
assert(#min(Int64) = -9223372036854775808i64)
-return 0u8
-
end.
diff --git a/testsuite/runnable/fixed_word_max.elna b/testsuite/runnable/fixed_word_max.elna
index 8fb8d27..c657614 100644
--- a/testsuite/runnable/fixed_word_max.elna
+++ b/testsuite/runnable/fixed_word_max.elna
@@ -4,6 +4,4 @@ begin
assert(#max(Word16) = 65535u16);
assert(#max(Word32) = 4294967295u32);
assert(#max(Word64) = 18446744073709551615u64)
-return 0u8
-
end.
diff --git a/testsuite/runnable/float_arithmetic.elna b/testsuite/runnable/float_arithmetic.elna
index e98a26d..f792b04 100644
--- a/testsuite/runnable/float_arithmetic.elna
+++ b/testsuite/runnable/float_arithmetic.elna
@@ -11,6 +11,4 @@ begin
assert(3.0f * 0.5f = 1.5f);
assert(1.0f / 4.0f = 0.25f);
assert(-3.14f < 0.0f)
-return 0u8
-
end.
diff --git a/testsuite/runnable/float_cast.elna b/testsuite/runnable/float_cast.elna
index 08d14c5..26cb0d2 100644
--- a/testsuite/runnable/float_cast.elna
+++ b/testsuite/runnable/float_cast.elna
@@ -1,12 +1,10 @@
+program()
var
folded: Int := cast(2.9: Int)
measure: Double := -2.9
-program()
begin
assert(folded = 2);
assert(cast(measure: Int) = -2);
assert(cast(folded: Double) = 2.0)
-return 0u8
-
end.
diff --git a/testsuite/runnable/for_call.elna b/testsuite/runnable/for_call.elna
index a2fcd06..6c72b38 100644
--- a/testsuite/runnable/for_call.elna
+++ b/testsuite/runnable/for_call.elna
@@ -1,3 +1,4 @@
+program()
var
actual: [2]Int := [0, 0]
@@ -6,12 +7,9 @@ begin
element^ := 1
return
-program()
begin
for x of actual do
set_element(x)
end;
assert(actual = [1, 1])
-return 0u8
-
end.
diff --git a/testsuite/runnable/for_defer.elna b/testsuite/runnable/for_defer.elna
index 04f0404..7a350a0 100644
--- a/testsuite/runnable/for_defer.elna
+++ b/testsuite/runnable/for_defer.elna
@@ -1,7 +1,7 @@
+program()
var
array: [2]Int := [0, 0]
-program()
begin
for x of array do
defer
@@ -9,6 +9,4 @@ begin
end
end;
assert(array = [1, 1])
-return 0u8
-
end.
diff --git a/testsuite/runnable/for_each_array.elna b/testsuite/runnable/for_each_array.elna
index 6eae577..5a754da 100644
--- a/testsuite/runnable/for_each_array.elna
+++ b/testsuite/runnable/for_each_array.elna
@@ -1,15 +1,13 @@
+program()
var
actual: [4]Word := [0u, 0u, 0u, 0u]
input: [4]Word := [2u, 4u, 6u, 8u]
i: Word := 1u
-program()
begin
for element of input do
actual[i] := element^ * 2u;
i := i + 1u
end;
assert(actual = [4u, 8u, 12u, 16u])
-return 0u8
-
end.
diff --git a/testsuite/runnable/for_each_slice.elna b/testsuite/runnable/for_each_slice.elna
index bfc8b44..31bc65a 100644
--- a/testsuite/runnable/for_each_slice.elna
+++ b/testsuite/runnable/for_each_slice.elna
@@ -1,10 +1,10 @@
+program()
var
actual: [4]Word := [0u, 0u, 0u, 0u]
input: [4]Word := [2u, 4u, 6u, 8u]
slice: []Word
i: Word := 1u
-program()
begin
slice := input[1u to input.length];
@@ -13,6 +13,4 @@ begin
i := i + 1u
end;
assert(actual = [4u, 8u, 12u, 16u])
-return 0u8
-
end.
diff --git a/testsuite/runnable/for_with.elna b/testsuite/runnable/for_with.elna
index 0859ed0..b3727f6 100644
--- a/testsuite/runnable/for_with.elna
+++ b/testsuite/runnable/for_with.elna
@@ -1,11 +1,10 @@
program()
var
actual: [3]Word := [0u, 0u, 0u]
+
begin
for element of [1u, 2u, 3u] with i do
actual[i] := i * element^
end;
assert(actual = [1u, 4u, 9u])
-return 0u8
-
end.
diff --git a/testsuite/runnable/generic_base.elna b/testsuite/runnable/generic_base.elna
index c36eccf..63737e0 100644
--- a/testsuite/runnable/generic_base.elna
+++ b/testsuite/runnable/generic_base.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -29,7 +30,6 @@ begin
target^.tail := value
return
-program()
begin
seen := @jobs;
enqueue(@jobs, @f);
@@ -37,6 +37,4 @@ begin
assert(jobs.head = @f);
assert(jobs.tail = @f);
assert(#size(Queue#[^File]) = #size(Pointer) * 3u)
-return 0u8
-
end.
diff --git a/testsuite/runnable/generic_constructor.elna b/testsuite/runnable/generic_constructor.elna
index 201e1b1..d0a3f78 100644
--- a/testsuite/runnable/generic_constructor.elna
+++ b/testsuite/runnable/generic_constructor.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -12,11 +13,8 @@ var
s: Stack#[^File]
f: File
-program()
begin
s := Stack#[^File]{ top: 1u, items: @f };
assert(s.top = 1u);
assert(s.items = @f)
-return 0u8
-
end.
diff --git a/testsuite/runnable/generic_erasure.elna b/testsuite/runnable/generic_erasure.elna
index eccc1d2..20862fa 100644
--- a/testsuite/runnable/generic_erasure.elna
+++ b/testsuite/runnable/generic_erasure.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -18,7 +19,6 @@ begin
target^.held := value
return
-program()
begin
f.fd := 7;
b := 3u8;
@@ -26,6 +26,4 @@ begin
store#[^Word8](@bytes, @b);
assert(files.held^.fd = 7);
assert(bytes.held^ = 3u8)
-return 0u8
-
end.
diff --git a/testsuite/runnable/generic_pointer_arithmetic.elna b/testsuite/runnable/generic_pointer_arithmetic.elna
index fe1e197..209287d 100644
--- a/testsuite/runnable/generic_pointer_arithmetic.elna
+++ b/testsuite/runnable/generic_pointer_arithmetic.elna
@@ -1,16 +1,14 @@
+program()
var
base: [4]Int
element: ^Int
first: Pointer
second: Pointer
-program()
begin
element := base.ptr;
first := element;
second := first + 1;
assert(cast(second : Word) - cast(first : Word) = 1u);
assert(second - 1 = first)
-return 0u8
-
end.
diff --git a/testsuite/runnable/generic_record.elna b/testsuite/runnable/generic_record.elna
index 8a334ce..4164c3d 100644
--- a/testsuite/runnable/generic_record.elna
+++ b/testsuite/runnable/generic_record.elna
@@ -1,3 +1,4 @@
+program()
type
File = record
fd: Int
@@ -18,12 +19,9 @@ begin
target^.top := target^.top + 1u
return
-program()
begin
s.top := 0u;
push#[^File](@s, @f);
assert(s.top = 1u);
assert(s.items = @f)
-return 0u8
-
end.
diff --git a/testsuite/runnable/hexadecimal_literal.elna b/testsuite/runnable/hexadecimal_literal.elna
index 02bc4c5..a168bd2 100644
--- a/testsuite/runnable/hexadecimal_literal.elna
+++ b/testsuite/runnable/hexadecimal_literal.elna
@@ -2,6 +2,4 @@ program()
begin
assert(0xff = 255u);
assert(0X0f = 15u)
-return 0u8
-
end.
diff --git a/testsuite/runnable/multi_module/helper.elna b/testsuite/runnable/multi_module/helper.elna
index 5fd68af..c3c0bfd 100644
--- a/testsuite/runnable/multi_module/helper.elna
+++ b/testsuite/runnable/multi_module/helper.elna
@@ -1,3 +1,5 @@
+module
+
proc multiply*(x, y: Int) -> Int
return x * y
diff --git a/testsuite/runnable/multi_module/sut.elna b/testsuite/runnable/multi_module/sut.elna
index 5ad6860..4b6e176 100644
--- a/testsuite/runnable/multi_module/sut.elna
+++ b/testsuite/runnable/multi_module/sut.elna
@@ -1,8 +1,6 @@
+program()
import helper
-program()
begin
assert(multiply(3, 4) = 12)
-return 0u8
-
end.
diff --git a/testsuite/runnable/named_block.elna b/testsuite/runnable/named_block.elna
index a9c44ed..0ba7eff 100644
--- a/testsuite/runnable/named_block.elna
+++ b/testsuite/runnable/named_block.elna
@@ -1,7 +1,7 @@
+program()
var
counter: Int := 0
-program()
begin
block outer
while true do
@@ -13,6 +13,4 @@ begin
end
end;
assert(counter = 11)
-return 0u8
-
end.
diff --git a/testsuite/runnable/procedure_cast.elna b/testsuite/runnable/procedure_cast.elna
index 724fadf..191afbf 100644
--- a/testsuite/runnable/procedure_cast.elna
+++ b/testsuite/runnable/procedure_cast.elna
@@ -1,12 +1,11 @@
-var cb: proc(x: ^Char) -> Int
+program()
+var
+ cb: proc(x: ^Char) -> Int
proc probe_int(x: ^Int) -> Int
return 42
-program()
begin
cb := cast(probe_int: proc(x: ^Char) -> Int);
assert(cb(nil) = 42)
-return 0u8
-
end.
diff --git a/testsuite/runnable/record_base_assignment.elna b/testsuite/runnable/record_base_assignment.elna
index 5f84f20..7ad17e0 100644
--- a/testsuite/runnable/record_base_assignment.elna
+++ b/testsuite/runnable/record_base_assignment.elna
@@ -1,3 +1,4 @@
+program()
type
B = record
x: Word
@@ -16,9 +17,6 @@ begin
assert(r.x = 3u & r.y = 2u)
return
-program()
begin
f()
-return 0u8
-
end.
diff --git a/testsuite/runnable/record_base_constructor.elna b/testsuite/runnable/record_base_constructor.elna
index 52936e9..80b6802 100644
--- a/testsuite/runnable/record_base_constructor.elna
+++ b/testsuite/runnable/record_base_constructor.elna
@@ -1,3 +1,4 @@
+program()
type
Base = record
a: Int
@@ -12,11 +13,8 @@ type
var
g: Grandchild := Grandchild{a: 3, b: 5, c: 7}
-program()
begin
assert(g.a = 3);
assert(g.b = 5);
assert(g.c = 7)
-return 0u8
-
end.
diff --git a/testsuite/runnable/record_construction.elna b/testsuite/runnable/record_construction.elna
index ca99859..5a3a254 100644
--- a/testsuite/runnable/record_construction.elna
+++ b/testsuite/runnable/record_construction.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
x, y: Int
@@ -6,9 +7,6 @@ type
var
r: R := R{x: 1, y: 2}
-program()
begin
assert(r.x = 1 & r.y = 2)
-return 0u8
-
end.
diff --git a/testsuite/runnable/record_extension.elna b/testsuite/runnable/record_extension.elna
index 5f61d60..95165f4 100644
--- a/testsuite/runnable/record_extension.elna
+++ b/testsuite/runnable/record_extension.elna
@@ -1,3 +1,4 @@
+program()
type
ElnaLexerToken = record
kind: Word
@@ -10,12 +11,9 @@ var
token_memory: ElnaLexerStringToken
current_token: ^ElnaLexerToken
-program()
begin
current_token := @token_memory;
cast(current_token: ^ElnaLexerStringToken)^.value := "Some string";
assert(token_memory.value = "Some string")
-return 0u8
-
end.
diff --git a/testsuite/runnable/record_layout.elna b/testsuite/runnable/record_layout.elna
index 6150a32..a3e64c4 100644
--- a/testsuite/runnable/record_layout.elna
+++ b/testsuite/runnable/record_layout.elna
@@ -1,3 +1,4 @@
+program()
type
IntChar = record
x: Int;
@@ -50,9 +51,6 @@ begin
assert(array_record_c_offset = 3u * int_size)
return
-program()
begin
f()
-return 0u8
-
end.
diff --git a/testsuite/runnable/recursive_record.elna b/testsuite/runnable/recursive_record.elna
index 5c59e64..48fb873 100644
--- a/testsuite/runnable/recursive_record.elna
+++ b/testsuite/runnable/recursive_record.elna
@@ -1,3 +1,4 @@
+program()
type
Node = record
value: Int;
@@ -27,7 +28,6 @@ begin
end;
return result
-program()
begin
first := malloc(#size(Node));
second := malloc(#size(Node));
@@ -46,6 +46,4 @@ begin
free(first);
free(second);
free(third)
-return 0u8
-
end.
diff --git a/testsuite/runnable/repeat_loop.elna b/testsuite/runnable/repeat_loop.elna
index 084b801..ff09735 100644
--- a/testsuite/runnable/repeat_loop.elna
+++ b/testsuite/runnable/repeat_loop.elna
@@ -1,14 +1,12 @@
+program()
var
actual: [4]Word := [0u, 0u, 0u, 0u]
i: Word := 0u
-program()
begin
repeat
i := i + 1u;
actual[i] := i
until i = 4u;
assert(actual = [1u, 2u, 3u, 4u])
-return 0u8
-
end.
diff --git a/testsuite/runnable/return_aggregate.elna b/testsuite/runnable/return_aggregate.elna
index 4377d94..6959b60 100644
--- a/testsuite/runnable/return_aggregate.elna
+++ b/testsuite/runnable/return_aggregate.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
a: Int;
@@ -7,9 +8,6 @@ type
proc f() -> R
return R{ a: 1, b: 2 }
-program()
begin
assert(f() = R{ a: 1, b: 2 })
-return 0u8
-
end.
diff --git a/testsuite/runnable/slice_array.elna b/testsuite/runnable/slice_array.elna
index 7a889a3..4d7ad7e 100644
--- a/testsuite/runnable/slice_array.elna
+++ b/testsuite/runnable/slice_array.elna
@@ -1,14 +1,12 @@
+program()
var
array: [3]Int := [2, 4, 6]
slice: []Int
-program()
begin
slice := array[1 to 3];
assert(slice.length = 3u);
assert(slice[1] = 2);
assert(slice[3] = 6)
-return 0u8
-
end.
diff --git a/testsuite/runnable/slice_cast.elna b/testsuite/runnable/slice_cast.elna
index 0d4a861..d3309f9 100644
--- a/testsuite/runnable/slice_cast.elna
+++ b/testsuite/runnable/slice_cast.elna
@@ -1,9 +1,7 @@
+program()
var
ints: [4]Int32 := [1i32, 2i32, 3i32, 4i32]
-program()
begin
assert(cast(ints[1u to 4u]: []Int8).length = #size(Int32) * ints.length)
-return 0u8
-
end.
diff --git a/testsuite/runnable/slice_equality.elna b/testsuite/runnable/slice_equality.elna
index 1510f40..534afec 100644
--- a/testsuite/runnable/slice_equality.elna
+++ b/testsuite/runnable/slice_equality.elna
@@ -1,13 +1,11 @@
+program()
var
lhs_payload, rhs_payload: [3]Int := [2, 4, 6]
lhs, rhs: []Int
-program()
begin
lhs := lhs_payload[1 to 3];
rhs := rhs_payload[1 to 3];
assert(lhs = rhs)
-return 0u8
-
end.
diff --git a/testsuite/runnable/slice_pointer.elna b/testsuite/runnable/slice_pointer.elna
index c19e64a..150bda8 100644
--- a/testsuite/runnable/slice_pointer.elna
+++ b/testsuite/runnable/slice_pointer.elna
@@ -1,14 +1,12 @@
+program()
var
array: [3]Int := [2, 4, 6]
slice: []Int
-program()
begin
slice := array.ptr[1 to 3];
assert(slice.length = 3u);
assert(slice[1] = 2);
assert(slice[3] = 6)
-return 0u8
-
end.
diff --git a/testsuite/runnable/slice_slice.elna b/testsuite/runnable/slice_slice.elna
index fcfea8b..6395cea 100644
--- a/testsuite/runnable/slice_slice.elna
+++ b/testsuite/runnable/slice_slice.elna
@@ -1,8 +1,8 @@
+program()
var
array: [5]Int := [2, 4, 6, 8, 10]
slice1, slice2: []Int
-program()
begin
slice1 := array[1 to array.length];
slice2 := slice1[2 to 4];
@@ -11,6 +11,4 @@ begin
assert(slice2[1] = 4);
assert(slice2[2] = 6);
assert(slice2[3] = 8)
-return 0u8
-
end.
diff --git a/testsuite/runnable/two_fields_same_type.elna b/testsuite/runnable/two_fields_same_type.elna
index af591e4..2b905b6 100644
--- a/testsuite/runnable/two_fields_same_type.elna
+++ b/testsuite/runnable/two_fields_same_type.elna
@@ -1,3 +1,4 @@
+program()
type
R = record
x, y: Int
@@ -8,9 +9,6 @@ var
r: R := R{x: 3, y: 2}
return r.x + r.y
-program()
begin
assert(f() = 5)
-return 0u8
-
end.
diff --git a/testsuite/runnable/two_parameters_same_type.elna b/testsuite/runnable/two_parameters_same_type.elna
index 08a1b5a..18e3d63 100644
--- a/testsuite/runnable/two_parameters_same_type.elna
+++ b/testsuite/runnable/two_parameters_same_type.elna
@@ -1,9 +1,8 @@
+program()
+
proc f(x, y: Int) -> Int
return x + y
-program()
begin
assert(f(2, 3) = 5)
-return 0u8
-
end.
diff --git a/testsuite/runnable/unary_plus.elna b/testsuite/runnable/unary_plus.elna
index 7f331d4..4df6922 100644
--- a/testsuite/runnable/unary_plus.elna
+++ b/testsuite/runnable/unary_plus.elna
@@ -1,11 +1,10 @@
+program()
+
proc f(x: Int) -> Int
return +x
-program()
begin
assert(+3 = 3);
assert(f(5) = 5);
assert(f(-7) = -7)
-return 0u8
-
end.
diff --git a/testsuite/runnable/unicode_escape_character.elna b/testsuite/runnable/unicode_escape_character.elna
index f5a4b3f..0cfd3e2 100644
--- a/testsuite/runnable/unicode_escape_character.elna
+++ b/testsuite/runnable/unicode_escape_character.elna
@@ -2,6 +2,4 @@ program()
begin
assert(`\{U+E9}` = `é`);
assert(`\{U+1F600}` = `😀`)
-return 0u8
-
end.
diff --git a/testsuite/runnable/unicode_escape_string.elna b/testsuite/runnable/unicode_escape_string.elna
index 20be668..bec794a 100644
--- a/testsuite/runnable/unicode_escape_string.elna
+++ b/testsuite/runnable/unicode_escape_string.elna
@@ -2,6 +2,4 @@ program()
begin
assert("caf\{U+E9}" = "café");
assert("Hi \{U+1F600}!" = "Hi 😀!")
-return 0u8
-
end.
diff --git a/testsuite/runnable/varargs.elna b/testsuite/runnable/varargs.elna
index feeb94b..1bf16e9 100644
--- a/testsuite/runnable/varargs.elna
+++ b/testsuite/runnable/varargs.elna
@@ -1,3 +1,4 @@
+program()
var
buffer: [8]Word8
written: Int32
@@ -5,12 +6,9 @@ var
proc snprintf(buffer: ^Word8; size: Word; format: ^const Word8) #{varargs} -> Int32
extern
-program()
begin
written := snprintf(@buffer[1], 8u, "%d %.1f".ptr, 200u8, 1.5f);
assert(written = 7i32);
assert(buffer[1] = '2');
assert(buffer[7] = '5')
-return 0u8
-
end.