diff --git a/xls/dslx/fmt/ast_fmt.cc b/xls/dslx/fmt/ast_fmt.cc index 07f8d6bafd..2cdf6eaa27 100644 --- a/xls/dslx/fmt/ast_fmt.cc +++ b/xls/dslx/fmt/ast_fmt.cc @@ -3125,6 +3125,11 @@ absl::StatusOr Formatter::Format(const Module& n) { pieces.push_back(arena_.MakeText("#![feature(channel_attributes)]")); pieces.push_back(arena_.hard_line()); break; + case ModuleAttribute::kExplicitStateAccess: + pieces.push_back( + arena_.MakeText("#![feature(explicit_state_access)]")); + pieces.push_back(arena_.hard_line()); + break; case ModuleAttribute::kGenerics: pieces.push_back(arena_.MakeText("#![feature(generics)]")); pieces.push_back(arena_.hard_line()); diff --git a/xls/dslx/frontend/module.cc b/xls/dslx/frontend/module.cc index b6fdefa5c0..d9a620ad72 100644 --- a/xls/dslx/frontend/module.cc +++ b/xls/dslx/frontend/module.cc @@ -94,6 +94,9 @@ std::string Module::ToString() const { case ModuleAttribute::kChannelAttributes: absl::StrAppend(out, "#![feature(channel_attributes)]"); break; + case ModuleAttribute::kExplicitStateAccess: + absl::StrAppend(out, "#![feature(explicit_state_access)]"); + break; case ModuleAttribute::kGenerics: absl::StrAppend(out, "#![feature(generics)]"); break; diff --git a/xls/dslx/frontend/module.h b/xls/dslx/frontend/module.h index 185a769899..818ccf4af8 100644 --- a/xls/dslx/frontend/module.h +++ b/xls/dslx/frontend/module.h @@ -82,6 +82,10 @@ enum class ModuleAttribute : uint8_t { // Enable #channel() attributes for this module. kChannelAttributes, + // Enable read and write with optional labels for state access for this + // module. + kExplicitStateAccess, + kGenerics, // Enable `trait` declarations. diff --git a/xls/dslx/frontend/parser.cc b/xls/dslx/frontend/parser.cc index fc2a59968b..2182353895 100644 --- a/xls/dslx/frontend/parser.cc +++ b/xls/dslx/frontend/parser.cc @@ -311,6 +311,9 @@ absl::Status Parser::ParseModuleAttribute() { } else if (feature == "channel_attributes") { module_->AddAttribute(ModuleAttribute::kChannelAttributes, attribute_span); + } else if (feature == "explicit_state_access") { + module_->AddAttribute(ModuleAttribute::kExplicitStateAccess, + attribute_span); } else if (feature == "generics") { module_->AddAttribute(ModuleAttribute::kGenerics, attribute_span); } else if (feature == "traits") { diff --git a/xls/dslx/frontend/parser_test.cc b/xls/dslx/frontend/parser_test.cc index 7c17c2e425..bfc6dfd619 100644 --- a/xls/dslx/frontend/parser_test.cc +++ b/xls/dslx/frontend/parser_test.cc @@ -3451,6 +3451,14 @@ TEST_F(ParserTest, ParseTypeInferenceV1AndV2Attributes) { "and `type_inference_v2` attributes"))); } +TEST_F(ParserTest, ParseExplicitStateAccessAttribute) { + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr module, Parse(R"( +#![feature(explicit_state_access)] +)")); + EXPECT_THAT(module->attributes(), + testing::ElementsAre(ModuleAttribute::kExplicitStateAccess)); +} + // Verifies that we can walk backwards through a tree. In this case, from the // terminal node to the defining expr. TEST(ParserBackrefTest, CanFindDefiner) {