From 4657db77b9d262d5984fa82af75b9b7d26ff0d21 Mon Sep 17 00:00:00 2001 From: Nicolai Stawinoga Date: Mon, 13 Jul 2026 21:28:36 +0200 Subject: [PATCH 1/2] core: (attr assembly fmt) add keyword directive --- .../test_attr_declarative_assembly_format.py | 14 +++++++- xdsl/irdl/declarative_assembly_format.py | 36 +++++++++++++++---- .../declarative_assembly_format_parser.py | 9 ++++- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/tests/irdl/test_attr_declarative_assembly_format.py b/tests/irdl/test_attr_declarative_assembly_format.py index c313f467a6..bb21e3bdfa 100644 --- a/tests/irdl/test_attr_declarative_assembly_format.py +++ b/tests/irdl/test_attr_declarative_assembly_format.py @@ -58,12 +58,24 @@ def test_parse_attribute_end_to_end(): assert Parser(ctx, "!test_af.empty").parse_type() == EmptyType() +@pytest.mark.parametrize( + "format_str, printed", + [("`hello`", "hello"), ("`foo``bar`", "foo bar")], +) +def test_keyword_print(format_str: str, printed: str): + assert _print(format_str) == printed + + +def test_keyword_parse(): + assert _parse("`kw`", "kw") == [] + + @pytest.mark.parametrize( "format_str, error", [ ("$foo", "unexpected token"), ("` `", "unexpected whitespace in directive"), - ("`+`", "expected a whitespace directive"), + ("`+`", "punctuation or identifier expected"), ], ) def test_error(format_str: str, error: str): diff --git a/xdsl/irdl/declarative_assembly_format.py b/xdsl/irdl/declarative_assembly_format.py index ee70c481ec..3f897eb146 100644 --- a/xdsl/irdl/declarative_assembly_format.py +++ b/xdsl/irdl/declarative_assembly_format.py @@ -1371,6 +1371,14 @@ def _print_whitespace(printer: Printer, state: PrintingState, whitespace: str) - state.should_emit_space = False +def _print_keyword(printer: Printer, state: PrintingState, keyword: str) -> None: + if state.should_emit_space: + printer.print_string(" ") + state.should_emit_space = True + state.last_was_punctuation = False + printer.print_string(keyword) + + @dataclass(frozen=True) class WhitespaceDirective(FormatDirective): """ @@ -1446,12 +1454,7 @@ def parse(self, parser: Parser, state: ParsingState) -> bool: return parser.parse_optional_keyword(self.keyword) is not None def print(self, printer: Printer, state: PrintingState, op: IRDLOperation) -> None: - if state.should_emit_space: - printer.print_string(" ") - state.should_emit_space = True - state.last_was_punctuation = False - - printer.print_string(self.keyword) + _print_keyword(printer, state, self.keyword) def is_optional_like(self) -> bool: return True @@ -1570,6 +1573,27 @@ def print( _print_whitespace(printer, state, self.whitespace) +@dataclass(frozen=True) +class AttrKeywordDirective(AttrFormatDirective): + """ + A keyword directive for attribute/type assembly format. + + Mirrors the op-side KeywordDirective: expects a specific identifier and + requests a space to be printed after. + """ + + keyword: str + """The identifier that should be printed.""" + + def parse(self, parser: AttrParser, state: AttrParsingState) -> bool: + return parser.parse_optional_keyword(self.keyword) is not None + + def print( + self, printer: Printer, state: PrintingState, attr: ParametrizedAttribute, / + ) -> None: + _print_keyword(printer, state, self.keyword) + + @dataclass(frozen=True) class AttrFormatProgram: """ diff --git a/xdsl/irdl/declarative_assembly_format_parser.py b/xdsl/irdl/declarative_assembly_format_parser.py index ded3eccbb4..aa8570b8bf 100644 --- a/xdsl/irdl/declarative_assembly_format_parser.py +++ b/xdsl/irdl/declarative_assembly_format_parser.py @@ -49,6 +49,7 @@ AttrFormatDirective, AttrFormatProgram, AttributeVariable, + AttrKeywordDirective, AttrWhitespaceDirective, DenseArrayAttributeVariable, Directive, @@ -949,4 +950,10 @@ def parse_keyword_or_punctuation(self) -> AttrFormatDirective: ) return AttrWhitespaceDirective(whitespace) - self.raise_error("expected a whitespace directive") + # Identifier case + ident = self.parse_optional_identifier() + if ident is None or ident == "`": + self.raise_error("punctuation or identifier expected") + + self.parse_characters("`") + return AttrKeywordDirective(ident) From c067d24a7ae012a39673222a489fa3e86367439c Mon Sep 17 00:00:00 2001 From: Nicolai Stawinoga Date: Tue, 14 Jul 2026 11:51:34 +0200 Subject: [PATCH 2/2] Iterating --- .../test_attr_declarative_assembly_format.py | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/tests/irdl/test_attr_declarative_assembly_format.py b/tests/irdl/test_attr_declarative_assembly_format.py index bb21e3bdfa..d752fed0bc 100644 --- a/tests/irdl/test_attr_declarative_assembly_format.py +++ b/tests/irdl/test_attr_declarative_assembly_format.py @@ -44,12 +44,19 @@ def test_empty_format_produces_empty_program(): @pytest.mark.parametrize( - "format_str, printed", - [("", ""), ("` `", " "), ("``", ""), ("`\\n`", "\n")], + "format_str, body, printed", + [ + ("", "", ""), + ("` `", "", " "), + ("``", "", ""), + ("`\\n`", "", "\n"), + ("`hello`", "hello", "hello"), + ("`foo``bar`", "foo bar", "foo bar"), + ], ) -def test_prints_and_parses_nothing(format_str: str, printed: str): +def test_print_and_parse(format_str: str, body: str, printed: str): assert _print(format_str) == printed - assert _parse(format_str, "") == [] + assert _parse(format_str, body) == [] def test_parse_attribute_end_to_end(): @@ -58,18 +65,6 @@ def test_parse_attribute_end_to_end(): assert Parser(ctx, "!test_af.empty").parse_type() == EmptyType() -@pytest.mark.parametrize( - "format_str, printed", - [("`hello`", "hello"), ("`foo``bar`", "foo bar")], -) -def test_keyword_print(format_str: str, printed: str): - assert _print(format_str) == printed - - -def test_keyword_parse(): - assert _parse("`kw`", "kw") == [] - - @pytest.mark.parametrize( "format_str, error", [