aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-10-09 14:43:11 +0200
committerEugen Wissner <belka@caraus.de>2026-10-09 14:43:11 +0200
commit134d3ac4caff6d87c79b0892e57073594cb0064c (patch)
treee93c73d59ee50f3bdaa073bb5908ae3c74f7a985 /boot
parent244449004fb62adbfd43b81e8dfce7500ca4a7e4 (diff)
downloadelna-134d3ac4caff6d87c79b0892e57073594cb0064c.tar.gz
Remove Pointer and nil support
Diffstat (limited to 'boot')
-rw-r--r--boot/ast.cc9
-rw-r--r--boot/evaluator.cc66
-rw-r--r--boot/lexer.ll3
-rw-r--r--boot/materialization.cc26
-rw-r--r--boot/name_analysis.cc6
-rw-r--r--boot/parser.yy25
-rw-r--r--boot/result.cc7
-rw-r--r--boot/symbol.cc5
-rw-r--r--boot/type_check.cc52
9 files changed, 48 insertions, 151 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index b681695..edc10a7 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -217,11 +217,6 @@ namespace elna::boot
__builtin_unreachable();
}
- void empty_visitor::visit(literal<std::nullptr_t> *)
- {
- __builtin_unreachable();
- }
-
void empty_visitor::visit(literal<std::string> *)
{
__builtin_unreachable();
@@ -500,10 +495,6 @@ namespace elna::boot
{
}
- void walking_visitor::visit(literal<std::nullptr_t> *)
- {
- }
-
void walking_visitor::visit(literal<std::string> *)
{
}
diff --git a/boot/evaluator.cc b/boot/evaluator.cc
index 18633ba..78eb4cd 100644
--- a/boot/evaluator.cc
+++ b/boot/evaluator.cc
@@ -280,10 +280,6 @@ namespace elna::boot
{
return constant_value{ character_subject->value };
}
- else if (auto *pointer_subject = subject.is_a<std::nullptr_t>())
- {
- return constant_value{ pointer_subject->value };
- }
else if (auto *string_subject = subject.is_a<std::string>())
{
return constant_value{ string_subject->value };
@@ -517,25 +513,10 @@ namespace elna::boot
template<typename T>
static std::optional<constant_value> evaluate_operation(binary_operator operation, const T& lhs, const T& rhs)
{
- if constexpr (std::is_same_v<T, std::nullptr_t>)
- {
- switch (operation)
- {
- using enum binary_operator;
- case equals:
- return constant_value{ true };
- case not_equals:
- return constant_value{ false };
- default:
- return std::nullopt;
- }
- }
- else
+ switch (operation)
{
- switch (operation)
- {
- using enum binary_operator;
- case sum:
+ using enum binary_operator;
+ case sum:
if constexpr (std::is_same_v<T, integer_literal>)
{
if (auto result = lhs.add(rhs))
@@ -667,25 +648,29 @@ namespace elna::boot
case not_equals:
return constant_value{ lhs != rhs };
case less:
- if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>
+ || std::is_same_v<T, pointer_literal>)
{
return constant_value{ lhs < rhs };
}
return std::nullopt;
case greater:
- if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>
+ || std::is_same_v<T, pointer_literal>)
{
return constant_value{ lhs > rhs };
}
return std::nullopt;
case less_equal:
- if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>
+ || std::is_same_v<T, pointer_literal>)
{
return constant_value{ lhs <= rhs };
}
return std::nullopt;
case greater_equal:
- if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>
+ || std::is_same_v<T, pointer_literal>)
{
return constant_value{ lhs >= rhs };
}
@@ -693,7 +678,6 @@ namespace elna::boot
default:
return std::nullopt;
}
- }
}
std::optional<constant_value> evaluator::evaluate_binary(binary_expression& subject)
@@ -799,9 +783,9 @@ namespace elna::boot
{
return integer_constant(target_signed, target_size, static_cast<double>(source_value));
}
- else if constexpr (std::is_same_v<T, std::nullptr_t>)
+ else if constexpr (std::is_same_v<T, pointer_literal>)
{
- return integer_constant(target_signed, target_size, 0.0);
+ return constant_value{ source_value.address.cast_to(target_signed, target_size) };
}
else
{
@@ -834,10 +818,6 @@ namespace elna::boot
return constant_value{ widened.cast_to(target_format) };
}
- else if constexpr (std::is_same_v<T, std::nullptr_t>)
- {
- return constant_value{ float_literal::from(0.0).cast_to(target_format) };
- }
else
{
return std::nullopt;
@@ -866,9 +846,9 @@ namespace elna::boot
{
return constant_value{ source_value != 0U };
}
- else if constexpr (std::is_same_v<T, std::nullptr_t>)
+ else if constexpr (std::is_same_v<T, pointer_literal>)
{
- return constant_value{ false };
+ return constant_value{ !(source_value.address == std::size_t{ 0 }) };
}
else
{
@@ -906,10 +886,6 @@ namespace elna::boot
{
return constant_value{ static_cast<std::uint32_t>(source_value) };
}
- else if constexpr (std::is_same_v<T, std::nullptr_t>)
- {
- return constant_value{ std::uint32_t{ 0 } };
- }
else
{
return std::nullopt;
@@ -935,17 +911,15 @@ namespace elna::boot
return value;
}
- std::optional<constant_value> evaluator::cast_to_pointer(const constant_value& source_expression)
+ std::optional<constant_value> evaluator::cast_to_pointer(const constant_value& source_expression) const
{
- if (std::holds_alternative<std::nullptr_t>(source_expression))
+ if (const auto *address = std::get_if<integer_literal>(&source_expression))
{
- return source_expression;
+ return constant_value{ pointer_literal{ address->cast_to(false, this->target.pointer_properties.size) } };
}
- // 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 })
+ else if (std::holds_alternative<pointer_literal>(source_expression))
{
- return constant_value{ nullptr };
+ return source_expression;
}
return std::nullopt;
}
diff --git a/boot/lexer.ll b/boot/lexer.ll
index c6a5498..90753ba 100644
--- a/boot/lexer.ll
+++ b/boot/lexer.ll
@@ -150,9 +150,6 @@ true {
false {
return yy::parser::make_BOOLEAN(false, this->location);
}
-nil {
- return yy::parser::make_NIL(this->location);
-}
\& {
return yy::parser::make_AND(this->location);
}
diff --git a/boot/materialization.cc b/boot/materialization.cc
index 9e9d3ae..c7296f9 100644
--- a/boot/materialization.cc
+++ b/boot/materialization.cc
@@ -37,12 +37,8 @@ namespace elna::boot
return "Local symbols cannot be exported";
case local_extern:
return "Local symbols cannot be extern";
- case field_export:
- return "Record fields cannot be exported";
case variable_generic:
return "Variables cannot have generic parameters";
- case field_generic:
- return "Record fields cannot have generic parameters";
}
__builtin_unreachable();
}
@@ -95,28 +91,6 @@ namespace elna::boot
}
}
- void materialization_visitor::visit(record_type_expression *expression)
- {
- for (const auto& [field_identifiers, field_type] : expression->fields)
- {
- field_type->accept(this);
-
- for (const auto& field_identifier : field_identifiers)
- {
- if (field_identifier.exported())
- {
- add_error<materialization_error>(field_identifier.id().position(),
- materialization_error::kind::field_export);
- }
- if (!field_identifier.parameters.empty())
- {
- add_error<materialization_error>(field_identifier.id().position(),
- materialization_error::kind::field_generic);
- }
- }
- }
- }
-
void materialization_visitor::visit(literal<integer_literal> *literal)
{
switch (literal->wants_signed)
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index 17e15f6..9b3dec4 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -1236,12 +1236,6 @@ namespace elna::boot
this->current_type = type();
}
- void resolving_visitor::visit(literal<std::nullptr_t> *literal)
- {
- literal->type_decoration = lookup_primitive_type("Pointer");
- this->current_type = type();
- }
-
void resolving_visitor::visit(literal<std::string> *literal)
{
literal->type_decoration = type(std::make_shared<slice_type>(
diff --git a/boot/parser.yy b/boot/parser.yy
index 855cc76..9628443 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -95,7 +95,6 @@ along with GCC; see the file COPYING3. If not see
COLON ":" SEMICOLON ";" DOT "." COMMA ","
%token PROGRAM "program" MODULE "module"
CAST "cast"
- NIL "nil"
CONST "const"
VAR "var" THREADVAR "threadvar"
PROCEDURE "proc"
@@ -156,8 +155,8 @@ along with GCC; see the file COPYING3. If not see
%type <std::vector<elna::boot::conditional_statements>> elsif_then_statements elsif_do_statements;;
%type <std::unique_ptr<elna::boot::block>> else_statements block;
%type <std::unique_ptr<elna::boot::identifier>> identifier with_counter;
-%type <std::unique_ptr<elna::boot::identifier_definition>> identifier_definition attributed_identifier;
-%type <std::vector<elna::boot::identifier_definition>> identifier_definitions;
+%type <std::unique_ptr<elna::boot::identifier_definition>> identifier_definition attributed_identifier field_identifier;
+%type <std::vector<elna::boot::identifier_definition>> identifier_definitions field_identifiers;
%type <std::unique_ptr<elna::boot::attribute>> attribute;
%type <std::vector<elna::boot::attribute>> attributes;
%type <std::pair<std::vector<std::string>, bool>> import_declaration;
@@ -406,11 +405,6 @@ literal:
$$ = new boot::literal<std::uint32_t>(boot::make_position(@$),
$1, boot::integer_sign::_unsigned);
}
- | "nil"
- {
- $$ = new boot::literal<std::nullptr_t>(boot::make_position(@$),
- nullptr, boot::integer_sign::_unsigned);
- }
| STRING
{
$$ = new boot::literal<std::string>(boot::make_position(@$),
@@ -631,8 +625,21 @@ statements:
$$.insert($$.cend(), $3);
}
| statement { $$.push_back($1); }
+field_identifier:
+ IDENTIFIER attributes
+ {
+ $$ = std::make_unique<boot::identifier_definition>($1, boot::make_position(@1),
+ false, std::vector<boot::identifier>{}, std::move($2));
+ }
+field_identifiers:
+ field_identifier "," field_identifiers
+ {
+ $$ = $3;
+ $$.emplace($$.cbegin(), std::move(*$1));
+ }
+ | field_identifier { $$.emplace_back(std::move(*$1)); }
field_declaration:
- identifier_definitions ":" type_expression
+ field_identifiers ":" type_expression
{ $$ = std::make_pair($1, std::shared_ptr<boot::type_expression>($3)); }
field_declarations:
field_declaration ";" field_declarations
diff --git a/boot/result.cc b/boot/result.cc
index 71326c0..10fb9fe 100644
--- a/boot/result.cc
+++ b/boot/result.cc
@@ -603,3 +603,10 @@ std::size_t std::hash<elna::boot::float_literal>::operator()(const elna::boot::f
// -0.0 and 0.0 compare equal, so their hashes must agree.
return std::hash<double>{}(key == 0.0 ? 0.0 : key.value());
}
+
+std::size_t std::hash<elna::boot::pointer_literal>::operator()(
+ const elna::boot::pointer_literal& key) const noexcept
+{
+ return std::hash<elna::boot::integer_literal>{}(key.address);
+}
+
diff --git a/boot/symbol.cc b/boot/symbol.cc
index 2805839..ffefea4 100644
--- a/boot/symbol.cc
+++ b/boot/symbol.cc
@@ -411,8 +411,6 @@ namespace elna::boot
result->enter("Char",
std::make_shared<type_info>(type(std::make_shared<primitive_type>("Char", target.char_properties))));
- const type pointer = type(std::make_shared<primitive_type>("Pointer", target.pointer_properties));
- result->enter("Pointer", std::make_shared<type_info>(pointer));
result->enter("Single",
std::make_shared<type_info>(type(std::make_shared<primitive_type>("Single", target.single_properties))));
result->enter("Double",
@@ -831,8 +829,7 @@ namespace elna::boot
bool is_any_pointer_type(const type& checked)
{
- return checked.get<pointer_type>() != nullptr
- || is_primitive_type(checked, "Pointer");
+ return checked.get<pointer_type>() != nullptr;
}
bool is_scalar_type(const type& checked)
diff --git a/boot/type_check.cc b/boot/type_check.cc
index 31e10f1..797282c 100644
--- a/boot/type_check.cc
+++ b/boot/type_check.cc
@@ -406,8 +406,7 @@ namespace elna::boot
/*
* Scaling an offset needs the pointee size, which neither an opaque type
- * nor a type parameter has. Only a pointer_type scales; the generic
- * Pointer advances byte-wise.
+ * nor a type parameter has.
*/
static std::optional<type> find_arithmetic_violation(binary_operator operation,
const type& lhs, const type& rhs)
@@ -505,45 +504,11 @@ namespace elna::boot
}
}
- assign_check::verdict assign_check::guard_const_laundering() const
- {
- if (!is_primitive_type(ctx.aliased_assignee, "Pointer"))
- {
- return verdict::pass;
- }
- if (const auto ptr = ctx.aliased_assignment.get<pointer_type>();
- ptr != nullptr && resolve_aliases(ptr->base).get<constant_type>() != nullptr)
- {
- return verdict::reject;
- }
- if (const auto const_assign = ctx.aliased_assignment.get<constant_type>();
- const_assign != nullptr && is_primitive_type(const_assign->unqualified, "Pointer"))
- {
- return verdict::reject;
- }
- return verdict::pass;
- }
-
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() const
- {
- if (is_primitive_type(ctx.resolved_assignee, "Pointer")
- && is_any_pointer_type(ctx.resolved_assignment))
- {
- return verdict::accept;
- }
- if (is_primitive_type(ctx.resolved_assignment, "Pointer")
- && is_any_pointer_type(ctx.resolved_assignee))
- {
- return verdict::accept;
- }
- return verdict::pass;
- }
-
assign_check::verdict assign_check::check_pointer_conversion() const
{
const std::shared_ptr<pointer_type> assignee_ptr = ctx.resolved_assignee.get<pointer_type>();
@@ -637,11 +602,9 @@ namespace elna::boot
bool assign_check::run()
{
const std::initializer_list assign_handlers = {
- &assign_check::guard_const_laundering,
&assign_check::check_exact_match,
&assign_check::check_slice_conversion,
&assign_check::check_array_conversion,
- &assign_check::check_pointer_hatch,
&assign_check::check_pointer_conversion
};
for (const auto handler : assign_handlers)
@@ -1153,17 +1116,10 @@ namespace elna::boot
}
else if (const auto left_pointer = left.get<pointer_type>())
{
- if (is_primitive_type(right, "Pointer"))
- {
- return true;
- }
- else
- {
- const std::shared_ptr<pointer_type> 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);
- }
+ return right_pointer != nullptr
+ && bind_arguments(parameters, bindings, left_pointer->base, right_pointer->base);
}
else if (const auto left_slice = left.get<slice_type>())
{