From 1a6ab248be97b6ba6e5a09b034875c6ec68e981b Mon Sep 17 00:00:00 2001
From: 7FM <41307817+7FM@users.noreply.github.com>
Date: Wed, 22 Jul 2026 14:59:18 +0200
Subject: [PATCH] Allow [[...]] attributes on loop statements
Add an attributes slot to the while, for and do-while loop rules so that
[[name]] / [[name=expr]] / [[name(a, b)]] attributes can be attached to
loops, matching the existing attachment points (functions, instructions,
always-blocks and declarators). Since all three loop rules declare the
same feature, it is hoisted onto the common LoopStatement supertype.
The analyzer validates them uniformly across all three loop forms via a
new `loop` AttributeUsage: attribute parameters are analyzed, unknown
names produce the usual warning, and attributes registered only for
other usages are rejected when placed on a loop.
---
com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext | 6 +++---
.../com/minres/coredsl/analysis/AttributeRegistry.xtend | 3 ++-
.../src/com/minres/coredsl/analysis/CoreDslAnalyzer.xtend | 8 ++++++++
3 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext b/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext
index 847938f3..8bfe2ec3 100644
--- a/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext
+++ b/com.minres.coredsl/src/com/minres/coredsl/CoreDsl.xtext
@@ -91,17 +91,17 @@ ReturnStatement: {ReturnStatement} t_return='return' value=ConditionalExpression
LoopStatement: WhileLoop | ForLoop | DoLoop;
WhileLoop:
- 'while' '(' condition=Expression ')' body=Statement;
+ 'while' '(' condition=Expression ')' attributes+=Attribute* body=Statement;
ForLoop:
'for' '('
(startDeclaration=MultiInitDeclaration | startExpression=AssignmentExpression?) ';'
(condition=Expression?) ';'
(loopExpressions+=AssignmentExpression (',' loopExpressions+=AssignmentExpression)*)?
- ')' body=Statement;
+ ')' attributes+=Attribute* body=Statement;
DoLoop:
- 'do' body=Statement 'while' '(' condition=Expression ')' ';';
+ 'do' body=Statement 'while' '(' condition=Expression ')' attributes+=Attribute* ';';
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////// Declarations ////////////////////////////////
diff --git a/com.minres.coredsl/src/com/minres/coredsl/analysis/AttributeRegistry.xtend b/com.minres.coredsl/src/com/minres/coredsl/analysis/AttributeRegistry.xtend
index b73b9cdd..e66d7bba 100644
--- a/com.minres.coredsl/src/com/minres/coredsl/analysis/AttributeRegistry.xtend
+++ b/com.minres.coredsl/src/com/minres/coredsl/analysis/AttributeRegistry.xtend
@@ -35,7 +35,8 @@ class AttributeRegistry {
instruction,
function,
declarator,
- alwaysBlock
+ alwaysBlock,
+ loop
}
static final class AttributeInfo {
diff --git a/com.minres.coredsl/src/com/minres/coredsl/analysis/CoreDslAnalyzer.xtend b/com.minres.coredsl/src/com/minres/coredsl/analysis/CoreDslAnalyzer.xtend
index a231a2d6..33fcf914 100644
--- a/com.minres.coredsl/src/com/minres/coredsl/analysis/CoreDslAnalyzer.xtend
+++ b/com.minres.coredsl/src/com/minres/coredsl/analysis/CoreDslAnalyzer.xtend
@@ -581,6 +581,9 @@ class CoreDslAnalyzer {
* 2. [Warning] The condition should not be an assignment. (LikelyAccidentalAssignment)
*/
def static dispatch void analyzeStatement(AnalysisContext ctx, WhileLoop statement) {
+
+ analyzeAttributes(ctx, statement.attributes, AttributeRegistry.AttributeUsage.loop);
+
val conditionType = analyzeExpression(ctx, statement.condition);
checkAccidentalAssignment(ctx, statement.condition);
@@ -601,6 +604,8 @@ class CoreDslAnalyzer {
*/
def static dispatch void analyzeStatement(AnalysisContext ctx, ForLoop statement) {
+ analyzeAttributes(ctx, statement.attributes, AttributeRegistry.AttributeUsage.loop);
+
if (statement.startDeclaration !== null) {
analyzeDeclaration(ctx, statement.startDeclaration, false);
}
@@ -641,6 +646,9 @@ class CoreDslAnalyzer {
* 2. [Warning] The condition should not be an assignment. (LikelyAccidentalAssignment)
*/
def static dispatch void analyzeStatement(AnalysisContext ctx, DoLoop statement) {
+
+ analyzeAttributes(ctx, statement.attributes, AttributeRegistry.AttributeUsage.loop);
+
val conditionType = analyzeExpression(ctx, statement.condition);
checkAccidentalAssignment(ctx, statement.condition);