aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/ast.cc137
-rw-r--r--boot/dependency.cc6
-rw-r--r--boot/driver.cc4
-rw-r--r--boot/evaluator.cc85
-rw-r--r--boot/name_analysis.cc57
-rw-r--r--boot/result.cc36
-rw-r--r--boot/symbol.cc109
-rw-r--r--boot/type_check.cc94
8 files changed, 273 insertions, 255 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index 0931a2c..9b3fbe4 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -17,6 +17,8 @@ along with GCC; see the file COPYING3. If not see
#include "elna/boot/ast.h"
+#include <utility>
+
namespace elna::boot
{
void empty_visitor::visit(array_type_expression *)
@@ -210,11 +212,11 @@ namespace elna::boot
}
if (declaration->body.has_value())
{
- for (variable_declaration *const variable : declaration->body.value().variables)
+ for (variable_declaration *variable : declaration->body.value().variables)
{
variable->accept(this);
}
- for (statement *const statement : declaration->body.value().entry_point)
+ for (auto *statement : declaration->body.value().entry_point)
{
statement->accept(this);
}
@@ -234,22 +236,22 @@ namespace elna::boot
void walking_visitor::visit(if_statement *statement)
{
statement->branch().prerequisite().accept(this);
- for (struct statement *const branch_statement : statement->branch().statements)
+ for (auto *branch_statement : statement->branch().statements)
{
branch_statement->accept(this);
}
- for (conditional_statements *const branch : statement->branches)
+ for (conditional_statements *branch : statement->branches)
{
branch->prerequisite().accept(this);
- for (struct statement *const branch_statement : branch->statements)
+ for (auto *branch_statement : branch->statements)
{
branch_statement->accept(this);
}
}
if (statement->alternative != nullptr)
{
- for (struct statement *const branch_statement : *statement->alternative)
+ for (auto *branch_statement : *statement->alternative)
{
branch_statement->accept(this);
}
@@ -259,15 +261,15 @@ namespace elna::boot
void walking_visitor::visit(while_statement *statement)
{
statement->branch().prerequisite().accept(this);
- for (struct statement *const branch_statement : statement->branch().statements)
+ for (auto *branch_statement : statement->branch().statements)
{
branch_statement->accept(this);
}
- for (conditional_statements *const branch : statement->branches)
+ for (conditional_statements *branch : statement->branches)
{
branch->prerequisite().accept(this);
- for (struct statement *const branch_statement : branch->statements)
+ for (auto *branch_statement : branch->statements)
{
branch_statement->accept(this);
}
@@ -276,7 +278,7 @@ namespace elna::boot
void walking_visitor::visit(defer_statement *statement)
{
- for (struct statement *const block_statement : statement->statements)
+ for (auto *block_statement : statement->statements)
{
block_statement->accept(this);
}
@@ -291,18 +293,18 @@ namespace elna::boot
statement->condition().accept(this);
for (const switch_case& case_block : statement->cases)
{
- for (expression *const case_label : case_block.labels)
+ for (expression *case_label : case_block.labels)
{
case_label->accept(this);
}
- for (struct statement *const block_statement : case_block.statements)
+ for (auto *block_statement : case_block.statements)
{
block_statement->accept(this);
}
}
if (statement->alternative != nullptr)
{
- for (struct statement *const block_statement : *statement->alternative)
+ for (auto *block_statement : *statement->alternative)
{
block_statement->accept(this);
}
@@ -312,7 +314,7 @@ namespace elna::boot
void walking_visitor::visit(procedure_call *call)
{
call->callable().accept(this);
- for (expression *const argument : call->arguments)
+ for (expression *argument : call->arguments)
{
argument->accept(this);
}
@@ -320,23 +322,23 @@ namespace elna::boot
void walking_visitor::visit(unit *unit)
{
- for (import_declaration *const _import : unit->imports)
+ for (import_declaration *_import : unit->imports)
{
_import->accept(this);
}
- for (type_declaration *const type : unit->types)
+ for (type_declaration *type : unit->types)
{
type->accept(this);
}
- for (variable_declaration *const variable : unit->variables)
+ for (variable_declaration *variable : unit->variables)
{
variable->accept(this);
}
- for (procedure_declaration *const procedure : unit->procedures)
+ for (procedure_declaration *procedure : unit->procedures)
{
procedure->accept(this);
}
- for (statement *const entry_statement : unit->entry_point)
+ for (auto *entry_statement : unit->entry_point)
{
entry_statement->accept(this);
}
@@ -412,7 +414,7 @@ namespace elna::boot
void walking_visitor::visit(array_constructor_expression *expression)
{
expression->m_element_type->accept(this);
- for (auto element : expression->elements)
+ for (auto *element : expression->elements)
{
element->accept(this);
}
@@ -490,9 +492,7 @@ namespace elna::boot
{
}
- node::~node()
- {
- }
+ node::~node() = default;
const source_position& node::position() const
{
@@ -756,7 +756,7 @@ namespace elna::boot
array_constructor_expression::~array_constructor_expression()
{
delete m_element_type;
- for (expression *const element : elements)
+ for (const expression *element : elements)
{
delete element;
}
@@ -765,14 +765,14 @@ namespace elna::boot
variable_declaration::variable_declaration(const source_position position,
std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type,
expression *initializer)
- : node(position), m_variable_type(variable_type), identifiers(std::move(identifier)), initializer(initializer)
+ : node(position), m_variable_type(std::move(variable_type)), identifiers(std::move(identifier)), initializer(initializer)
{
}
variable_declaration::variable_declaration(const source_position position,
std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type,
std::monostate)
- : node(position), m_variable_type(variable_type), identifiers(std::move(identifier)), is_extern(true)
+ : node(position), m_variable_type(std::move(variable_type)), identifiers(std::move(identifier)), is_extern(true)
{
}
@@ -792,7 +792,7 @@ namespace elna::boot
}
declaration::declaration(const source_position position, identifier_definition identifier)
- : node(position), identifier(identifier)
+ : node(position), identifier(std::move(identifier))
{
}
@@ -804,10 +804,7 @@ namespace elna::boot
procedure_type_expression::~procedure_type_expression()
{
- if (return_type.proper_type != nullptr)
- {
- delete return_type.proper_type;
- }
+ delete return_type.proper_type;
}
void procedure_type_expression::accept(parser_visitor *visitor)
@@ -838,14 +835,14 @@ namespace elna::boot
procedure_declaration::procedure_declaration(const source_position position, identifier_definition identifier,
procedure_type_expression *heading, procedure_body&& body)
- : declaration(position, identifier), m_heading(heading),
+ : declaration(position, std::move(identifier)), m_heading(heading),
body(std::make_optional<procedure_body>(std::move(body)))
{
}
procedure_declaration::procedure_declaration(const source_position position, identifier_definition identifier,
procedure_type_expression *heading)
- : declaration(position, identifier), m_heading(heading)
+ : declaration(position, std::move(identifier)), m_heading(heading)
{
}
@@ -866,7 +863,7 @@ namespace elna::boot
type_declaration::type_declaration(const source_position position, identifier_definition identifier,
type_expression *underlying_type)
- : declaration(position, identifier), m_underlying_type(underlying_type)
+ : declaration(position, std::move(identifier)), m_underlying_type(underlying_type)
{
}
@@ -901,11 +898,11 @@ namespace elna::boot
procedure_body::~procedure_body()
{
- for (statement *body_statement : this->entry_point)
+ for (const statement *body_statement : this->entry_point)
{
delete body_statement;
}
- for (variable_declaration *variable : this->variables)
+ for (const variable_declaration *variable : this->variables)
{
delete variable;
}
@@ -941,15 +938,15 @@ namespace elna::boot
unit::~unit()
{
- for (procedure_declaration *procedure : this->procedures)
+ for (const procedure_declaration *procedure : this->procedures)
{
delete procedure;
}
- for (type_declaration *type : this->types)
+ for (const type_declaration *type : this->types)
{
delete type;
}
- for (import_declaration *declaration : this->imports)
+ for (const import_declaration *declaration : this->imports)
{
delete declaration;
}
@@ -972,7 +969,7 @@ namespace elna::boot
defer_statement::~defer_statement()
{
- for (statement *body_statement : statements)
+ for (const statement *body_statement : statements)
{
delete body_statement;
}
@@ -988,9 +985,7 @@ namespace elna::boot
{
}
- designator_expression::~designator_expression()
- {
- }
+ designator_expression::~designator_expression() = default;
designator_expression *designator_expression::is_designator()
{
@@ -1001,21 +996,24 @@ namespace elna::boot
{
if (named_expression *node = is_named())
{
- return visitor->visit(node);
+ visitor->visit(node);
}
else if (array_access_expression *node = is_array_access())
{
- return visitor->visit(node);
+ visitor->visit(node);
}
else if (field_access_expression *node = is_field_access())
{
- return visitor->visit(node);
+ visitor->visit(node);
}
else if (dereference_expression *node = is_dereference())
{
- return visitor->visit(node);
+ visitor->visit(node);
+ }
+ else
+ {
+ __builtin_unreachable();
}
- __builtin_unreachable();
}
named_expression::named_expression(const source_position position, const std::string& name)
@@ -1161,7 +1159,7 @@ namespace elna::boot
unary_expression::unary_expression(const source_position position, expression *operand,
const unary_operator operation)
- : node(position), m_operand(std::move(operand)), m_operator(operation)
+ : node(position), m_operand(operand), m_operator(operation)
{
}
@@ -1213,7 +1211,7 @@ namespace elna::boot
procedure_call::~procedure_call()
{
- for (expression *const argument : arguments)
+ for (const expression *argument : arguments)
{
delete argument;
}
@@ -1288,7 +1286,7 @@ namespace elna::boot
conditional_statements::~conditional_statements()
{
delete m_prerequisite;
- for (auto statement : statements)
+ for (auto *statement : statements)
{
delete statement;
}
@@ -1376,7 +1374,7 @@ namespace elna::boot
if_statement::~if_statement()
{
delete m_branch;
- for (conditional_statements *const branch : branches)
+ for (const conditional_statements *branch : branches)
{
delete branch;
}
@@ -1412,7 +1410,7 @@ namespace elna::boot
while_statement::~while_statement()
{
delete m_branch;
- for (conditional_statements *const branch : branches)
+ for (const conditional_statements *branch : branches)
{
delete branch;
}
@@ -1422,37 +1420,38 @@ namespace elna::boot
{
switch (operation)
{
- case binary_operator::sum:
+ using enum binary_operator;
+ case sum:
return "+";
- case binary_operator::subtraction:
+ case subtraction:
return "-";
- case binary_operator::multiplication:
+ case multiplication:
return "*";
- case binary_operator::division:
+ case division:
return "/";
- case binary_operator::remainder:
+ case remainder:
return "%";
- case binary_operator::equals:
+ case equals:
return "=";
- case binary_operator::not_equals:
+ case not_equals:
return "<>";
- case binary_operator::less:
+ case less:
return "<";
- case binary_operator::less_equal:
+ case less_equal:
return "<=";
- case binary_operator::greater:
+ case greater:
return ">";
- case binary_operator::greater_equal:
+ case greater_equal:
return ">=";
- case binary_operator::conjunction:
+ case conjunction:
return "and";
- case binary_operator::disjunction:
+ case disjunction:
return "or";
- case binary_operator::exclusive_disjunction:
+ case exclusive_disjunction:
return "xor";
- case binary_operator::shift_left:
+ case shift_left:
return "<<";
- case binary_operator::shift_right:
+ case shift_right:
return ">>";
}
__builtin_unreachable();
diff --git a/boot/dependency.cc b/boot/dependency.cc
index 7bd86fb..dc827fa 100644
--- a/boot/dependency.cc
+++ b/boot/dependency.cc
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see
#include <fstream>
#include <sstream>
-#include <string.h>
+#include <cstring>
#include "elna/boot/driver.h"
#include "elna/boot/name_analysis.h"
@@ -35,7 +35,7 @@ namespace elna::boot
yy::parser parser(tokenizer, parse_driver);
dependency outcome;
- if (parser())
+ if (parser() != 0)
{
std::swap(outcome.errors(), parse_driver.errors());
return outcome;
@@ -56,7 +56,7 @@ namespace elna::boot
return outcome;
}
- error_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag bag,
+ error_list analyze_semantics(std::unique_ptr<unit>& tree, const symbol_bag& bag,
const target_info& target)
{
name_analysis_visitor name_analyser(bag);
diff --git a/boot/driver.cc b/boot/driver.cc
index 8dc95f8..374bcc9 100644
--- a/boot/driver.cc
+++ b/boot/driver.cc
@@ -78,7 +78,7 @@ namespace elna::boot
current_position += 2;
std::size_t processed;
- char character = static_cast<char>(std::stoi(current_position, &processed, 16));
+ char const character = static_cast<char>(std::stoi(current_position, &processed, 16));
if (processed == 0)
{
return std::nullopt;
@@ -93,7 +93,7 @@ namespace elna::boot
{
++current_position;
- char escape = escape_char(*current_position);
+ char const escape = escape_char(*current_position);
if (escape == escape_invalid_char)
{
return std::nullopt;
diff --git a/boot/evaluator.cc b/boot/evaluator.cc
index 1acadd3..b7edd3a 100644
--- a/boot/evaluator.cc
+++ b/boot/evaluator.cc
@@ -86,7 +86,7 @@ namespace elna::boot
std::optional<constant_value> evaluator::evaluate_literal(literal_expression& subject)
{
- type decoration = subject.type_decoration;
+ type const decoration = subject.type_decoration;
if (is_primitive_type(decoration, "Int"))
{
@@ -171,16 +171,16 @@ namespace elna::boot
}
if (subject.operation() == unary_operator::negation)
{
- return std::visit([](auto v) -> std::optional<constant_value> {
- using T = std::decay_t<decltype(v)>;
+ return std::visit([](auto value) -> std::optional<constant_value> {
+ using T = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<T, bool>)
{
- return constant_value{ !v };
+ return constant_value{ !value };
}
else if constexpr (std::is_integral_v<T>)
{
- return constant_value{ ~v };
+ return constant_value{ ~value };
}
return std::nullopt;
}, operand.value());
@@ -232,16 +232,17 @@ namespace elna::boot
}
template<typename T>
- static std::optional<constant_value> evaluate_operation(binary_operator op, T lhs, T rhs)
+ static std::optional<constant_value> evaluate_operation(binary_operator operation, T lhs, T rhs)
{
if constexpr (std::is_same_v<T, std::nullptr_t>
|| std::is_same_v<T, compound_constant>)
{
- switch (op)
+ switch (operation)
{
- case binary_operator::equals:
+ using enum binary_operator;
+ case equals:
return constant_value{ true };
- case binary_operator::not_equals:
+ case not_equals:
return constant_value{ false };
default:
return std::nullopt;
@@ -249,36 +250,37 @@ namespace elna::boot
}
else
{
- switch (op)
+ switch (operation)
{
- case binary_operator::sum:
+ using enum binary_operator;
+ case sum:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
- if (auto r = add_overflow(lhs, rhs))
+ if (auto result = add_overflow(lhs, rhs))
{
- return constant_value{ *r };
+ return constant_value{ *result };
}
}
return std::nullopt;
- case binary_operator::subtraction:
+ case subtraction:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
- if (auto r = sub_overflow(lhs, rhs))
+ if (auto result = sub_overflow(lhs, rhs))
{
- return constant_value{ *r };
+ return constant_value{ *result };
}
}
return std::nullopt;
- case binary_operator::multiplication:
+ case multiplication:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
- if (auto r = mul_overflow(lhs, rhs))
+ if (auto result = mul_overflow(lhs, rhs))
{
- return constant_value{ *r };
+ return constant_value{ *result };
}
}
return std::nullopt;
- case binary_operator::division:
+ case division:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
if (rhs != static_cast<T>(0))
@@ -287,7 +289,7 @@ namespace elna::boot
}
}
return std::nullopt;
- case binary_operator::remainder:
+ case remainder:
if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>)
{
if (rhs != static_cast<T>(0))
@@ -296,25 +298,25 @@ namespace elna::boot
}
}
return std::nullopt;
- case binary_operator::disjunction:
+ case disjunction:
if constexpr (std::is_integral_v<T>)
{
return constant_value{ lhs | rhs };
}
return std::nullopt;
- case binary_operator::conjunction:
+ case conjunction:
if constexpr (std::is_integral_v<T>)
{
return constant_value{ lhs & rhs };
}
return std::nullopt;
- case binary_operator::exclusive_disjunction:
+ case exclusive_disjunction:
if constexpr (std::is_integral_v<T>)
{
return constant_value{ lhs ^ rhs };
}
return std::nullopt;
- case binary_operator::shift_left:
+ case shift_left:
if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>)
{
if (rhs < 0 || static_cast<std::make_unsigned_t<T>>(rhs) >= std::numeric_limits<T>::digits)
@@ -324,35 +326,35 @@ namespace elna::boot
return constant_value{ lhs << rhs };
}
return std::nullopt;
- case binary_operator::shift_right:
+ case shift_right:
if constexpr (std::is_integral_v<T>)
{
return constant_value{ lhs >> rhs };
}
return std::nullopt;
- case binary_operator::equals:
+ case equals:
return constant_value{ lhs == rhs };
- case binary_operator::not_equals:
+ case not_equals:
return constant_value{ lhs != rhs };
- case binary_operator::less:
+ case less:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
return constant_value{ lhs < rhs };
}
return std::nullopt;
- case binary_operator::greater:
+ case greater:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
return constant_value{ lhs > rhs };
}
return std::nullopt;
- case binary_operator::less_equal:
+ case less_equal:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
return constant_value{ lhs <= rhs };
}
return std::nullopt;
- case binary_operator::greater_equal:
+ case greater_equal:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
return constant_value{ lhs >= rhs };
@@ -373,7 +375,7 @@ namespace elna::boot
{
return std::nullopt;
}
- return std::visit([this, &rhs, operation = subject.operation()](auto&& lhs_value) {
+ 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());
@@ -395,7 +397,7 @@ namespace elna::boot
std::optional<std::size_t> evaluator::evaluate_traits_size(const type& subject)
{
- type resolved = resolve_underlying_type(subject);
+ type const resolved = resolve_underlying_type(subject);
if (is_primitive_type(resolved, "Int"))
{
@@ -413,11 +415,8 @@ namespace elna::boot
{
return target.float_size;
}
- else if (is_primitive_type(resolved, "Pointer"))
- {
- return target.pointer_size;
- }
- else if (resolved.get<pointer_type>() != nullptr)
+ else if (is_primitive_type(resolved, "Pointer")
+ || resolved.get<pointer_type>() != nullptr)
{
return target.pointer_size;
}
@@ -433,7 +432,7 @@ namespace elna::boot
std::optional<std::size_t> evaluator::evaluate_traits_alignment(const type& subject)
{
- type resolved = resolve_underlying_type(subject);
+ type const resolved = resolve_underlying_type(subject);
if (is_primitive_type(resolved, "Int"))
{
@@ -521,7 +520,7 @@ namespace elna::boot
}
else if (subject.name.name() == "min")
{
- type resolved = resolve_underlying_type(subject.types.front());
+ type const resolved = resolve_underlying_type(subject.types.front());
if (is_primitive_type(resolved, "Int"))
{
@@ -542,7 +541,7 @@ namespace elna::boot
}
else if (subject.name.name() == "max")
{
- type resolved = resolve_underlying_type(subject.types.front());
+ type const resolved = resolve_underlying_type(subject.types.front());
if (is_primitive_type(resolved, "Int"))
{
@@ -554,7 +553,7 @@ namespace elna::boot
}
if (is_primitive_type(resolved, "Char"))
{
- return constant_value{ static_cast<unsigned char>(255) };
+ return constant_value{ std::numeric_limits<unsigned char>::max() };
}
if (auto enumeration = resolved.get<enumeration_type>())
{
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index b13c043..22b7814 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see
#include "elna/boot/name_analysis.h"
#include <algorithm>
+#include <utility>
namespace elna::boot
{
@@ -95,7 +96,7 @@ namespace elna::boot
}
name_analysis_visitor::name_analysis_visitor(symbol_bag bag)
- : error_container(), bag(bag)
+ : bag(std::move(bag))
{
}
@@ -120,10 +121,10 @@ namespace elna::boot
std::pair<procedure_type, std::vector<std::string>> result_type{
procedure_type(result_return), std::vector<std::string>()
};
- for (auto& [parameter_names, parameters_type] : expression.parameters)
+ for (const auto& [parameter_names, parameters_type] : expression.parameters)
{
parameters_type->accept(this);
- for (auto& parameter_name : parameter_names)
+ for (const auto& parameter_name : parameter_names)
{
result_type.first.parameters.push_back(this->current_type);
result_type.second.push_back(parameter_name.name());
@@ -139,7 +140,7 @@ namespace elna::boot
type name_analysis_visitor::lookup_field(const type& composite_type, const std::string& field_name)
{
- type resolved_type = resolve_underlying_type(composite_type);
+ type const resolved_type = resolve_underlying_type(composite_type);
if (auto record = resolved_type.get<record_type>())
{
@@ -225,21 +226,21 @@ namespace elna::boot
}
for (auto& field : record->fields)
{
- names.insert({ field.first, field_origin{ std::nullopt, composite_type } });
+ names.insert({ field.first, field_origin{ .declaration = std::nullopt, .base_type = composite_type } });
}
}
std::vector<type_field> name_analysis_visitor::build_composite_type(
const std::vector<field_declaration>& fields,
std::map<std::string, field_origin>& field_names,
- type aggregate)
+ const type& aggregate)
{
std::vector<type_field> result;
- for (auto& field : fields)
+ for (const auto& field : fields)
{
field.second->accept(this);
- for (auto& field_name : field.first)
+ for (const auto& field_name : field.first)
{
auto existing = field_names.find(field_name.name());
if (existing != field_names.end())
@@ -260,8 +261,8 @@ namespace elna::boot
else
{
field_names.insert({ field_name.name(),
- field_origin{ field.second->position(), type() } });
- result.push_back(std::make_pair(field_name.name(), this->current_type));
+ field_origin{ .declaration = field.second->position(), .base_type = type() } });
+ result.emplace_back(field_name.name(), this->current_type);
}
}
}
@@ -350,7 +351,7 @@ namespace elna::boot
{
expression->m_element_type->accept(this);
auto element_type = this->current_type;
- for (auto element : expression->elements)
+ for (auto *element : expression->elements)
{
element->accept(this);
}
@@ -359,7 +360,7 @@ namespace elna::boot
void name_analysis_visitor::visit(procedure_type_expression *expression)
{
- std::shared_ptr<procedure_type> result_type =
+ std::shared_ptr<procedure_type> const result_type =
std::make_shared<procedure_type>(std::move(build_procedure(*expression).first));
this->current_type = type(result_type);
@@ -368,16 +369,17 @@ namespace elna::boot
void name_analysis_visitor::visit(enumeration_type_expression *expression)
{
std::vector<std::string> member_names;
- for (auto& member : expression->members)
+ member_names.reserve(expression->members.size());
+for (const auto& member : expression->members)
{
member_names.emplace_back(member.name());
}
- std::shared_ptr<enumeration_type> result_type = std::make_shared<enumeration_type>(
+ std::shared_ptr<enumeration_type> const result_type = std::make_shared<enumeration_type>(
member_names);
std::map<std::string, source_position> seen;
- type aggregate(result_type);
+ type const aggregate(result_type);
- for (auto& member : expression->members)
+ for (const auto& member : expression->members)
{
auto existing = seen.find(member.name());
if (existing != seen.end())
@@ -536,8 +538,8 @@ namespace elna::boot
if (!trait->type_decoration.empty())
{
- type resolved = resolve_underlying_type(trait->type_decoration);
- bool is_enum = resolved.get<enumeration_type>() != nullptr;
+ type const resolved = resolve_underlying_type(trait->type_decoration);
+ bool const is_enum = resolved.get<enumeration_type>() != nullptr;
if (!is_enum && !is_discrete_type(resolved))
{
@@ -560,15 +562,16 @@ namespace elna::boot
switch (expression->operation())
{
- case binary_operator::equals:
- case binary_operator::not_equals:
- case binary_operator::less:
- case binary_operator::greater:
- case binary_operator::less_equal:
- case binary_operator::greater_equal:
+ using enum binary_operator;
+ case equals:
+ case not_equals:
+ case less:
+ case greater:
+ case less_equal:
+ case greater_equal:
expression->type_decoration = lookup_primitive_type("Bool");
break;
- case binary_operator::subtraction:
+ case subtraction:
if (expression->lhs().type_decoration.get<pointer_type>()
&& expression->rhs().type_decoration.get<pointer_type>())
{
@@ -626,7 +629,7 @@ namespace elna::boot
{
walking_visitor::visit(expression);
expression->type_decoration = lookup_field(expression->base().type_decoration, expression->field().name());
- auto is_designator = expression->base().is_designator();
+ auto *is_designator = expression->base().is_designator();
if (expression->type_decoration.empty() && is_designator != nullptr && is_designator->is_named() != nullptr)
{
@@ -725,7 +728,7 @@ namespace elna::boot
}
declaration_visitor::declaration_visitor()
- : error_container()
+
{
}
diff --git a/boot/result.cc b/boot/result.cc
index 5f3c516..86b0e7a 100644
--- a/boot/result.cc
+++ b/boot/result.cc
@@ -39,16 +39,6 @@ namespace elna::boot
return this->m_line != 0 || this->m_column != 0;
}
- bool location::operator==(const location& that) const
- {
- return this->m_line == that.m_line && this->m_column == that.m_column;
- }
-
- bool location::operator!=(const location& that) const
- {
- return !(*this == that);
- }
-
source_position::source_position(location start, location end)
: m_start(start), m_end(end)
{
@@ -99,22 +89,30 @@ namespace elna::boot
return this->m_position;
}
- bool identifier::operator==(const identifier& that) const
+ std::strong_ordering identifier::operator<=>(const identifier& that) const
{
- return this->m_name == that.m_name;
- }
+ auto comparison = this->m_name.compare(that.name());
- bool identifier::operator!=(const identifier& that) const
- {
- return !(*this == that);
+ if (comparison < 0)
+ {
+ return std::strong_ordering::less;
+ }
+ else if (comparison > 0)
+ {
+ return std::strong_ordering::greater;
+ }
+ else
+ {
+ return std::strong_ordering::equal;
+ }
}
- bool identifier::operator==(const std::string& that) const
+ bool identifier::operator==(std::string_view that) const
{
return this->m_name == that;
}
- bool identifier::operator!=(const std::string& that) const
+ bool identifier::operator!=(std::string_view that) const
{
return !(*this == that);
}
@@ -142,7 +140,7 @@ namespace elna::boot
}
std::size_t std::hash<elna::boot::identifier>::operator()(
- const elna::boot::identifier& key) const
+ const elna::boot::identifier& key) const noexcept
{
return std::hash<std::string>{}(key.name());
}
diff --git a/boot/symbol.cc b/boot/symbol.cc
index 7b45612..d7a1cae 100644
--- a/boot/symbol.cc
+++ b/boot/symbol.cc
@@ -17,6 +17,8 @@ along with GCC; see the file COPYING3. If not see
#include "elna/boot/symbol.h"
+#include <utility>
+
namespace elna::boot
{
type::type(std::shared_ptr<alias_type> alias)
@@ -64,14 +66,16 @@ namespace elna::boot
{
if constexpr (std::is_same_v<T, alias_type>)
{
- if (auto *wp = std::get_if<std::weak_ptr<alias_type>>(&payload))
- return wp->lock();
+ if (const auto *weak_pointer = std::get_if<std::weak_ptr<alias_type>>(&payload)) {
+ return weak_pointer->lock();
+}
return nullptr;
}
else
{
- if (auto *sp = std::get_if<std::shared_ptr<T>>(&payload))
- return *sp;
+ if (auto *shared_pointer = std::get_if<std::shared_ptr<T>>(&payload)) {
+ return *shared_pointer;
+}
return nullptr;
}
}
@@ -93,8 +97,8 @@ namespace elna::boot
bool type::operator==(const type& other) const
{
- type resolved_this = resolve_aliases(*this);
- type resolved_that = resolve_aliases(other);
+ type const resolved_this = resolve_aliases(*this);
+ type const resolved_that = resolve_aliases(other);
if (auto left_record = resolved_this.get<record_type>())
{
@@ -146,64 +150,79 @@ namespace elna::boot
std::string type::to_string() const
{
- return std::visit([](const auto& p) -> std::string {
- using T = std::decay_t<decltype(p)>;
+ return std::visit([](const auto& payload) -> std::string {
+ using T = std::decay_t<decltype(payload)>;
if constexpr (std::is_same_v<T, std::monostate>)
+ {
return "<empty>";
+ }
else if constexpr (std::is_same_v<T, std::weak_ptr<alias_type>>)
- return p.lock()->name;
+ {
+ return payload.lock()->name;
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<primitive_type>>)
- return p->identifier;
+ {
+ return payload->identifier;
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<pointer_type>>)
- return "^" + p->base.to_string();
+ {
+ return "^" + payload->base.to_string();
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<constant_type>>)
- return "const " + p->unqualified.to_string();
+ {
+ return "const " + payload->unqualified.to_string();
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<array_type>>)
- return "[" + std::to_string(p->size) + "]" + p->base.to_string();
+ {
+ return "[" + std::to_string(payload->size) + "]" + payload->base.to_string();
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<record_type>>)
{
- if (p->base.empty())
- return "record ... end";
- else
- return "record(" + p->base.to_string() + ") ... end";
+ return payload->base.empty()
+ ? "record ... end"
+ : "record(" + payload->base.to_string() + ") ... end";
}
else if constexpr (std::is_same_v<T, std::shared_ptr<procedure_type>>)
{
std::string result = "proc(";
- for (std::size_t i = 0; i < p->parameters.size(); ++i)
+ for (std::size_t i = 0; i < payload->parameters.size(); ++i)
{
- if (i > 0) result += ", ";
- result += p->parameters[i].to_string();
+ if (i > 0) { result += ", ";
+}
+ result += payload->parameters[i].to_string();
}
result += ")";
- if (p->return_type.no_return)
+ if (payload->return_type.no_return) {
result += ": !";
- else if (!p->return_type.proper_type.empty())
- result += ": " + p->return_type.proper_type.to_string();
+ } else if (!payload->return_type.proper_type.empty()) {
+ result += ": " + payload->return_type.proper_type.to_string();
+}
return result;
}
else if constexpr (std::is_same_v<T, std::shared_ptr<enumeration_type>>)
+ {
return "(enumeration)";
+ }
}, payload);
}
alias_type::alias_type(const std::string& name)
- : name(name), referent()
+ : name(name)
{
}
pointer_type::pointer_type(type base)
- : base(base)
+ : base(std::move(base))
{
}
constant_type::constant_type(type unqualified)
- : unqualified(unqualified)
+ : unqualified(std::move(unqualified))
{
}
array_type::array_type(type base, std::uint64_t size)
- : base(base), size(size)
+ : base(std::move(base)), size(size)
{
}
@@ -213,12 +232,12 @@ namespace elna::boot
}
record_type::record_type(type base)
- : base(base)
+ : base(std::move(base))
{
}
procedure_type::procedure_type(return_t return_type)
- : return_type(return_type)
+ : return_type(std::move(return_type))
{
}
@@ -227,9 +246,7 @@ namespace elna::boot
{
}
- info::~info()
- {
- }
+ info::~info() = default;
std::shared_ptr<type_info> info::is_type()
{
@@ -246,7 +263,7 @@ namespace elna::boot
return nullptr;
}
- type_info::type_info(const type symbol)
+ type_info::type_info(const type& symbol)
: symbol(symbol)
{
}
@@ -256,9 +273,9 @@ namespace elna::boot
return std::static_pointer_cast<type_info>(shared_from_this());
}
- procedure_info::procedure_info(const procedure_type symbol, const std::vector<std::string> names,
+ procedure_info::procedure_info(const procedure_type& symbol, const std::vector<std::string>& names,
std::shared_ptr<symbol_table> scope)
- : symbol(symbol), names(names), scope(scope)
+ : symbol(symbol), names(names), scope(std::move(scope))
{
}
@@ -272,7 +289,7 @@ namespace elna::boot
return this->scope == nullptr;
}
- variable_info::variable_info(const type symbol, bool is_extern)
+ variable_info::variable_info(const type& symbol, bool is_extern)
: symbol(symbol), is_extern(is_extern)
{
}
@@ -293,19 +310,19 @@ namespace elna::boot
result->enter("Float", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Float"))));
result->enter("String", std::make_shared<type_info>(type(std::make_shared<primitive_type>("String"))));
- type boolean = type(std::make_shared<primitive_type>("Bool"));
+ type const boolean = type(std::make_shared<primitive_type>("Bool"));
result->enter("Bool", std::make_shared<type_info>(boolean));
procedure_type assert_symbol{ procedure_type::return_t() };
assert_symbol.parameters.push_back(boolean);
- std::shared_ptr<procedure_info> assert_info = std::make_shared<procedure_info>(assert_symbol,
+ std::shared_ptr<procedure_info> const assert_info = std::make_shared<procedure_info>(assert_symbol,
std::vector<std::string>{ "condition" });
result->enter("assert", assert_info);
return result;
}
- symbol_bag::symbol_bag(forward_table&& unresolved, std::shared_ptr<symbol_table> global_table)
+ symbol_bag::symbol_bag(forward_table&& unresolved, const std::shared_ptr<symbol_table>& global_table)
: unresolved(unresolved)
{
this->symbols = std::make_shared<symbol_table>(global_table);
@@ -313,7 +330,7 @@ namespace elna::boot
std::shared_ptr<info> symbol_bag::lookup(const std::string& name)
{
- for (auto import_bag : this->imports)
+ for (const auto& import_bag : this->imports)
{
if (auto result = import_bag->lookup(name))
{
@@ -323,7 +340,7 @@ namespace elna::boot
return this->symbols->lookup(name);
}
- bool symbol_bag::enter(const std::string& name, std::shared_ptr<info> entry)
+ bool symbol_bag::enter(const std::string& name, const std::shared_ptr<info>& entry)
{
return this->symbols->enter(name, entry);
}
@@ -336,7 +353,7 @@ namespace elna::boot
void symbol_bag::enter(std::shared_ptr<symbol_table> child)
{
- this->symbols = child;
+ this->symbols = std::move(child);
}
std::shared_ptr<symbol_table> symbol_bag::leave()
@@ -383,7 +400,7 @@ namespace elna::boot
return m_exported;
}
- type resolve_underlying_type(std::shared_ptr<alias_type> alias)
+ type resolve_underlying_type(const std::shared_ptr<alias_type>& alias)
{
return resolve_underlying_type(alias->referent);
}
@@ -422,7 +439,7 @@ namespace elna::boot
bool is_numeric_type(const type& checked)
{
- type resolved = resolve_underlying_type(checked);
+ type const resolved = resolve_underlying_type(checked);
return is_primitive_type(resolved, "Int")
|| is_primitive_type(resolved, "Word")
@@ -431,7 +448,7 @@ namespace elna::boot
bool is_integral_type(const type& checked)
{
- type resolved = resolve_underlying_type(checked);
+ type const resolved = resolve_underlying_type(checked);
return is_primitive_type(resolved, "Int")
|| is_primitive_type(resolved, "Word");
@@ -439,7 +456,7 @@ namespace elna::boot
bool is_discrete_type(const type& checked)
{
- type resolved = resolve_underlying_type(checked);
+ type const resolved = resolve_underlying_type(checked);
return is_primitive_type(resolved, "Int")
|| is_primitive_type(resolved, "Word")
diff --git a/boot/type_check.cc b/boot/type_check.cc
index d9f3071..c5fb062 100644
--- a/boot/type_check.cc
+++ b/boot/type_check.cc
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see
#include "elna/boot/type_check.h"
#include <algorithm>
+#include <utility>
namespace elna::boot
{
@@ -33,7 +34,7 @@ namespace elna::boot
type_mismatch_error::type_mismatch_error(const source_position position,
type expected, type actual)
- : error(position), expected(expected), actual(actual)
+ : error(position), expected(std::move(expected)), actual(std::move(actual))
{
}
@@ -45,7 +46,7 @@ namespace elna::boot
constant_assignment_error::constant_assignment_error(const source_position position,
type assignee)
- : error(position), assignee(assignee)
+ : error(position), assignee(std::move(assignee))
{
}
@@ -57,15 +58,15 @@ namespace elna::boot
field_not_found_error::field_not_found_error(const identifier& field_name,
type composite_type)
- : error(field_name.position()), field_name(field_name.name()), composite_type(composite_type)
+ : error(field_name.position()), field_name(field_name.name()), composite_type(std::move(composite_type))
{
}
std::string field_not_found_error::what() const
{
- type resolved = resolve_underlying_type(composite_type);
- bool is_enum = resolved.get<enumeration_type>() != nullptr;
- bool is_record = resolved.get<record_type>() != nullptr;
+ type const resolved = resolve_underlying_type(composite_type);
+ bool const is_enum = resolved.get<enumeration_type>() != nullptr;
+ bool const is_record = resolved.get<record_type>() != nullptr;
if (is_enum || is_record)
{
@@ -87,16 +88,16 @@ namespace elna::boot
duplicate_member_error::duplicate_member_error(const boot::identifier& member_name,
type aggregate, std::optional<source_position> original,
std::optional<std::string> base_name)
- : error(member_name.position()), member_name(member_name.name()), aggregate(aggregate),
- original(original), base_name(base_name)
+ : error(member_name.position()), member_name(member_name.name()), aggregate(std::move(aggregate)),
+ original(original), base_name(std::move(base_name))
{
}
std::string duplicate_member_error::what() const
{
- type resolved = resolve_underlying_type(aggregate);
- bool is_enum = resolved.get<enumeration_type>() != nullptr;
- std::string kind = is_enum ? "member" : "field";
+ type const resolved = resolve_underlying_type(aggregate);
+ bool const is_enum = resolved.get<enumeration_type>() != nullptr;
+ std::string const kind = is_enum ? "member" : "field";
std::string message = is_enum ? "Enumeration" : "Record";
if (auto alias = aggregate.get<alias_type>())
@@ -142,7 +143,7 @@ namespace elna::boot
return_error::return_error(const std::string& identifier, const source_position position,
type return_type)
- : error(position), identifier(identifier), return_type(return_type)
+ : error(position), identifier(identifier), return_type(std::move(return_type))
{
}
@@ -159,7 +160,7 @@ namespace elna::boot
}
base_type_error::base_type_error(type actual, const source_position position)
- : error(position), actual(actual)
+ : error(position), actual(std::move(actual))
{
}
@@ -190,7 +191,7 @@ namespace elna::boot
unsupported_trait_type_error::unsupported_trait_type_error(const identifier& trait,
type actual)
- : error(trait.position()), actual(actual), trait_name(trait.name())
+ : error(trait.position()), actual(std::move(actual)), trait_name(trait.name())
{
}
@@ -201,22 +202,23 @@ namespace elna::boot
}
unary_operation_error::unary_operation_error(const source_position position,
- type actual, unary_operator op)
- : error(position), actual(actual), op(op)
+ type actual, unary_operator operation)
+ : error(position), actual(std::move(actual)), op(operation)
{
}
- char unary_operation_error::unary_operator_symbol(unary_operator op)
+ char unary_operation_error::unary_operator_symbol(unary_operator operation)
{
- switch (op)
+ switch (operation)
{
- case unary_operator::reference:
+ using enum unary_operator;
+ case reference:
return '@';
- case unary_operator::negation:
+ case negation:
return '~';
- case unary_operator::minus:
+ case minus:
return '-';
- case unary_operator::plus:
+ case plus:
return '+';
}
__builtin_unreachable();
@@ -261,10 +263,10 @@ namespace elna::boot
return false;
}
- bool type_analysis_visitor::check_unresolved_symbol(std::shared_ptr<alias_type> alias,
+ bool type_analysis_visitor::check_unresolved_symbol(const std::shared_ptr<alias_type>& alias,
std::vector<std::string>& alias_path)
{
- if (std::find(std::cbegin(alias_path), std::cend(alias_path), alias->name) != std::cend(alias_path))
+ if (std::ranges::find(alias_path, alias->name) != std::cend(alias_path))
{
return false;
}
@@ -295,7 +297,7 @@ namespace elna::boot
return false;
}
- assign_check::verdict assign_check::guard_const_laundering()
+ assign_check::verdict assign_check::guard_const_laundering() const
{
if (!is_primitive_type(ctx.aliased_assignee, "Pointer"))
{
@@ -314,12 +316,12 @@ namespace elna::boot
return verdict::pass;
}
- assign_check::verdict assign_check::check_exact_match()
+ assign_check::verdict assign_check::check_exact_match() const
{
return ctx.resolved_assignee == ctx.resolved_assignment ? verdict::accept : verdict::pass;
}
- assign_check::verdict assign_check::check_pointer_hatch()
+ assign_check::verdict assign_check::check_pointer_hatch() const
{
if (is_primitive_type(ctx.resolved_assignee, "Pointer")
&& is_any_pointer_type(ctx.resolved_assignment))
@@ -334,7 +336,7 @@ namespace elna::boot
return verdict::pass;
}
- assign_check::verdict assign_check::check_pointer_conversion()
+ 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>();
@@ -394,7 +396,7 @@ namespace elna::boot
}
type_analysis_visitor::type_analysis_visitor(symbol_bag bag, const target_info& target)
- : error_container(), bag(bag), target(target)
+ : bag(std::move(bag)), target(target)
{
}
@@ -412,8 +414,8 @@ namespace elna::boot
{
if (declaration->body.value().return_expression != nullptr)
{
- expression *return_expr = declaration->body.value().return_expression;
- type return_type = this->current_procedure->symbol.return_type.proper_type;
+ const expression *return_expr = declaration->body.value().return_expression;
+ type const return_type = this->current_procedure->symbol.return_type.proper_type;
if (!return_type.empty())
{
@@ -475,12 +477,12 @@ namespace elna::boot
}
// Record const variable initializers so later declarations
// can chain through them.
- for (const auto& id : declaration->identifiers)
+ for (const auto& identifier : declaration->identifiers)
{
- if (auto var = this->bag.lookup(id.name())->is_variable();
+ if (auto var = this->bag.lookup(identifier.name())->is_variable();
resolve_aliases(var->symbol).get<constant_type>() != nullptr)
{
- this->evaluated_initializers[id.name()] = declaration->initializer;
+ this->evaluated_initializers[identifier.name()] = declaration->initializer;
}
}
for (const identifier_definition& variable_identifier : declaration->identifiers)
@@ -498,11 +500,11 @@ namespace elna::boot
void type_analysis_visitor::visit(case_statement *statement)
{
walking_visitor::visit(statement);
- type condition_type = resolve_underlying_type(statement->condition().type_decoration);
+ type const condition_type = resolve_underlying_type(statement->condition().type_decoration);
for (const switch_case& case_block : statement->cases)
{
- for (expression *const case_label : case_block.labels)
+ for (const expression *case_label : case_block.labels)
{
if (!is_assignable_from(condition_type, case_label->type_decoration))
{
@@ -532,7 +534,7 @@ namespace elna::boot
{
if (expression->base.has_value())
{
- type base_type = resolve_underlying_type(this->bag.lookup(expression->base.value().name())->is_type()->symbol);
+ type const base_type = resolve_underlying_type(this->bag.lookup(expression->base.value().name())->is_type()->symbol);
if (base_type.get<record_type>() == nullptr)
{
add_error<base_type_error>(base_type, expression->position());
@@ -617,7 +619,7 @@ namespace elna::boot
expression->position());
return;
}
- for (auto element : expression->elements)
+ for (auto *element : expression->elements)
{
if (!is_assignable_from(array->base, element->type_decoration))
{
@@ -631,33 +633,33 @@ namespace elna::boot
{
walking_visitor::visit(expression);
- auto op = expression->operation();
- type resolved = resolve_underlying_type(expression->operand().type_decoration);
+ auto operation = expression->operation();
+ type const resolved = resolve_underlying_type(expression->operand().type_decoration);
- if (op == unary_operator::plus)
+ if (operation == unary_operator::plus)
{
if (!is_numeric_type(resolved))
{
add_error<unary_operation_error>(expression->position(),
- expression->operand().type_decoration, op);
+ expression->operand().type_decoration, operation);
}
}
- else if (op == unary_operator::minus)
+ else if (operation == unary_operator::minus)
{
if (!is_primitive_type(resolved, "Int")
&& !is_primitive_type(resolved, "Float"))
{
add_error<unary_operation_error>(expression->position(),
- expression->operand().type_decoration, op);
+ expression->operand().type_decoration, operation);
}
}
- else if (op == unary_operator::negation)
+ else if (operation == unary_operator::negation)
{
if (!is_primitive_type(resolved, "Bool")
&& !is_integral_type(resolved))
{
add_error<unary_operation_error>(expression->position(),
- expression->operand().type_decoration, op);
+ expression->operand().type_decoration, operation);
}
}
}