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);