aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/name_analysis.cc20
-rw-r--r--include/elna/boot/name_analysis.h22
-rw-r--r--testsuite/fail_compilation/const_array.elna7
3 files changed, 39 insertions, 10 deletions
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index cfc4e35..48251cd 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -51,8 +51,7 @@ namespace elna::boot
return "Symbol '" + identifier + "' has been already defined";
}
- std::optional<std::pair<std::string, source_position>>
- redefinition_error::note() const
+ std::optional<std::pair<std::string, source_position>> redefinition_error::note() const
{
if (original.has_value() && original->start().available())
{
@@ -61,6 +60,16 @@ namespace elna::boot
return std::nullopt;
}
+ const_array_error::const_array_error(const source_position position)
+ : error(position)
+ {
+ }
+
+ std::string const_array_error::what() const
+ {
+ return "const must be written before the array size, not after";
+ }
+
// Members of a constant aggregate are constant themselves.
static type qualify_member_type(const type& element, const type& aggregate)
{
@@ -176,9 +185,12 @@ namespace elna::boot
void name_analysis_visitor::visit(array_type_expression *expression)
{
walking_visitor::visit(expression);
- auto result_type = std::make_shared<array_type>(this->current_type, expression->size);
- this->current_type = type(result_type);
+ if (this->current_type.get<constant_type>() != nullptr)
+ {
+ add_error<const_array_error>(expression->position());
+ }
+ this->current_type = type(std::make_shared<array_type>(this->current_type, expression->size));
}
/**
diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h
index 4498d0c..feef3bf 100644
--- a/include/elna/boot/name_analysis.h
+++ b/include/elna/boot/name_analysis.h
@@ -40,16 +40,14 @@ namespace elna::boot
local_export
};
- private:
- std::string identifier;
- kind error_kind;
-
- public:
-
declaration_error(const kind error_kind,
const boot::identifier& identifier);
std::string what() const override;
+
+ private:
+ std::string identifier;
+ kind error_kind;
};
/**
@@ -71,6 +69,18 @@ namespace elna::boot
};
/**
+ * Array size before \c const is not valid — only \c const [n]T is
+ * accepted, not \c [n]const T.
+ */
+ class const_array_error : public error
+ {
+ public:
+ explicit const_array_error(const source_position position);
+
+ std::string what() const override;
+ };
+
+ /**
* Origin of a field in a composite type.
*/
struct field_origin
diff --git a/testsuite/fail_compilation/const_array.elna b/testsuite/fail_compilation/const_array.elna
new file mode 100644
index 0000000..7a1a6f5
--- /dev/null
+++ b/testsuite/fail_compilation/const_array.elna
@@ -0,0 +1,7 @@
+proc f()
+var
+ a: [10]const Int (* @Error const must be written before the array size, not after *)
+begin
+return
+
+end.