aboutsummaryrefslogtreecommitdiff
path: root/boot/name_analysis.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-13 22:55:06 +0200
committerEugen Wissner <belka@caraus.de>2026-08-13 22:55:06 +0200
commitbf7416a3ef9f0b787dcaebf816f3f3e6e385ff42 (patch)
tree26359c705133dbd8e98f06483008a720d0dae9d7 /boot/name_analysis.cc
parentae29de96c94e5c582f4424804464cdd29bf2a013 (diff)
downloadelna-bf7416a3ef9f0b787dcaebf816f3f3e6e385ff42.tar.gz
Implement fixed-size integers
Diffstat (limited to 'boot/name_analysis.cc')
-rw-r--r--boot/name_analysis.cc117
1 files changed, 67 insertions, 50 deletions
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index 56ea399..ae6810d 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -69,23 +69,53 @@ namespace elna::boot
return std::nullopt;
}
- const_qualifier_error::const_qualifier_error(const source_position position, kind error_kind)
- : error(position), error_kind(error_kind)
+ name_analysis_error::name_analysis_error(const source_position position, payload_type payload)
+ : error(position), payload(std::move(payload))
{
}
- std::string const_qualifier_error::what() const
+ std::string name_analysis_error::what() const
{
- switch (error_kind)
- {
- using enum kind;
- case array_position:
- return "const must be written before the array size, not after";
- case duplicate:
- return "Duplicate 'const' qualifier is not allowed";
- default:
- __builtin_unreachable();
- }
+ return std::visit([](const auto& payload) -> std::string {
+ using T = std::decay_t<decltype(payload)>;
+
+ if constexpr (std::is_same_v<T, not_initialized>)
+ {
+ return "All constants should be initialized";
+ }
+ else if constexpr (std::is_same_v<T, kind>)
+ {
+ switch (payload)
+ {
+ using enum kind;
+ case array_position:
+ return "const must be written before the array size, not after";
+ case duplicate:
+ return "Duplicate 'const' qualifier is not allowed";
+ default:
+ __builtin_unreachable();
+ }
+ }
+ }, this->payload);
+ }
+
+ std::optional<std::pair<std::string, source_position>> name_analysis_error::note() const
+ {
+ return std::visit([](const auto& payload) -> std::optional<std::pair<std::string, source_position>> {
+ using T = std::decay_t<decltype(payload)>;
+
+ if constexpr (std::is_same_v<T, not_initialized>)
+ {
+ auto position_span = source_position(payload.identifiers.front().position().start(),
+ payload.identifiers.back().position().end());
+
+ return std::make_optional(std::make_pair(join(payload.identifiers), position_span));
+ }
+ else
+ {
+ return std::nullopt;
+ }
+ }, this->payload);
}
member_error::member_error(const source_position position, const std::string& name,
@@ -164,23 +194,6 @@ namespace elna::boot
return std::nullopt;
}
- not_initialized_error::not_initialized_error(const source_position position, std::vector<identifier> identifiers)
- : error(position), identifiers(std::move(identifiers))
- {
- }
-
- std::string not_initialized_error::what() const
- {
- return "All constants should be initialized";
- }
-
- std::optional<std::pair<std::string, source_position>> not_initialized_error::note() const
- {
- auto position_span = source_position(this->identifiers.front().position().start(),
- this->identifiers.back().position().end());
- return std::make_pair(join(this->identifiers), position_span);
- }
-
// Members of a constant aggregate are constant themselves.
static type qualify_member_type(const type& element, const type& aggregate)
{
@@ -304,8 +317,8 @@ namespace elna::boot
if (this->current_type.get<constant_type>() != nullptr)
{
- add_error<const_qualifier_error>(expression->position(),
- const_qualifier_error::kind::duplicate);
+ add_error<name_analysis_error>(expression->position(),
+ name_analysis_error::kind::duplicate);
}
this->current_type = type(std::make_shared<constant_type>(this->current_type));
}
@@ -317,8 +330,8 @@ namespace elna::boot
if (array_base.get<constant_type>() != nullptr)
{
- add_error<const_qualifier_error>(expression->position(),
- const_qualifier_error::kind::array_position);
+ add_error<name_analysis_error>(expression->position(),
+ name_analysis_error::kind::array_position);
}
expression->dimensions().accept(this);
const auto size_constant = this->constant_evaluator.evaluate_index(expression->dimensions());
@@ -567,8 +580,8 @@ namespace elna::boot
{
auto position_span = source_position(declaration->identifiers.front().id().position().start(),
declaration->identifiers.back().id().position().end());
- add_error<not_initialized_error>(position_span,
- extract_identifiers(declaration->identifiers));
+ add_error<name_analysis_error>(position_span,
+ name_analysis_error::not_initialized{ extract_identifiers(declaration->identifiers) });
}
for (const identifier_definition& variable_identifier : declaration->identifiers)
{
@@ -881,11 +894,27 @@ namespace elna::boot
{
if (literal->value.is_signed())
{
- literal->type_decoration = lookup_primitive_type("Int");
+ if (literal->has_explicit_size)
+ {
+ literal->type_decoration = lookup_primitive_type(
+ "Int" + std::to_string(literal->value.size() * CHAR_BIT));
+ }
+ else
+ {
+ literal->type_decoration = lookup_primitive_type("Int");
+ }
}
else
{
- literal->type_decoration = lookup_primitive_type("Word");
+ if (literal->has_explicit_size)
+ {
+ literal->type_decoration = lookup_primitive_type(
+ "Word" + std::to_string(literal->value.size() * CHAR_BIT));
+ }
+ else
+ {
+ literal->type_decoration = lookup_primitive_type("Word");
+ }
}
this->current_type = type();
}
@@ -921,20 +950,8 @@ namespace elna::boot
this->current_type = type();
}
- declaration_visitor::declaration_visitor()
- {
- }
-
- void declaration_visitor::visit(import_declaration *)
- {
- }
-
void declaration_visitor::visit(unit *unit)
{
- for (import_declaration *const _import : unit->imports)
- {
- _import->accept(this);
- }
for (type_declaration *const type : unit->types)
{
type->accept(this);