aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-14 21:11:03 +0200
committerEugen Wissner <belka@caraus.de>2026-09-14 21:11:03 +0200
commit52c8ca2c06da93c8d14e80a256e8996c1fa1e885 (patch)
tree3579cffe682bb2d2270e5d892f26ae3c197880e6 /include
parent49e6a0518eb6b7b09938b562ef270028337508bf (diff)
downloadelna-52c8ca2c06da93c8d14e80a256e8996c1fa1e885.tar.gz
Implement volatile operations
Diffstat (limited to 'include')
-rw-r--r--include/elna/boot/type_check.h26
-rw-r--r--include/elna/gcc/elna-generic.h4
2 files changed, 27 insertions, 3 deletions
diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h
index 5faec43..582b887 100644
--- a/include/elna/boot/type_check.h
+++ b/include/elna/boot/type_check.h
@@ -181,6 +181,10 @@ namespace elna::boot
{
type actual;
};
+ struct argument_not_scalar
+ {
+ type actual;
+ };
struct constant_argument
{
type actual;
@@ -196,8 +200,8 @@ namespace elna::boot
};
using payload_type = std::variant<not_generic, unused_parameter,
- argument_not_pointer, constant_argument, uninferrable_parameter,
- shape_mismatch>;
+ argument_not_pointer, argument_not_scalar, constant_argument,
+ uninferrable_parameter, shape_mismatch>;
generic_error(const source_position position, const std::string& generic_name,
payload_type payload);
@@ -210,6 +214,21 @@ namespace elna::boot
};
/**
+ * What a generic declaration accepts as a type argument.
+ *
+ * An erased generic takes a pointer, because that is what its single
+ * compiled body knows how to move. A builtin has no body to erase, so it
+ * takes whatever it can load or store, and only a reading one tolerates a
+ * constant.
+ */
+ enum class argument_rule
+ {
+ pointer,
+ scalar,
+ mutable_scalar
+ };
+
+ /**
* Chain of responsibility for type compatibility checks.
*
* Populate \c ctx with pre-resolved types, then call \c run().
@@ -265,7 +284,8 @@ namespace elna::boot
static bool is_equality_compatible(const type& left, const type& right);
void visit_and_validate_condition(expression& condition);
- void check_arguments(const named_expression& reference, const std::vector<type>& arguments);
+ void check_arguments(const named_expression& reference, const std::vector<type>& arguments,
+ const argument_rule rule);
void check_parameters_used(const source_position position, const std::string& name,
const std::vector<type>& parameters, const type& heading);
type infer_call(procedure_call& call, const named_expression& reference,
diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h
index fbd68d8..dde883a 100644
--- a/include/elna/gcc/elna-generic.h
+++ b/include/elna/gcc/elna-generic.h
@@ -61,6 +61,10 @@ namespace elna::gcc
const std::vector<boot::type>& argument_types);
bool build_builtin_procedures(boot::procedure_call *call);
void build_assert_builtin(location_t call_location, const std::vector<boot::expression *>& arguments);
+ tree build_volatile_reference(location_t location, boot::expression& pointer,
+ const boot::type& accessed);
+ void build_volatile_load_builtin(location_t call_location, boot::procedure_call *call);
+ void build_volatile_store_builtin(location_t call_location, boot::procedure_call *call);
void visit_statements(const std::vector<boot::statement *>& statements);
void assert_constant();