diff options
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/ast.cc | 9 | ||||
| -rw-r--r-- | boot/evaluator.cc | 66 | ||||
| -rw-r--r-- | boot/lexer.ll | 3 | ||||
| -rw-r--r-- | boot/materialization.cc | 26 | ||||
| -rw-r--r-- | boot/name_analysis.cc | 6 | ||||
| -rw-r--r-- | boot/parser.yy | 25 | ||||
| -rw-r--r-- | boot/result.cc | 7 | ||||
| -rw-r--r-- | boot/symbol.cc | 5 | ||||
| -rw-r--r-- | boot/type_check.cc | 52 |
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>()) { |
