diff --git a/verilog/CST/verilog_nonterminals.h b/verilog/CST/verilog_nonterminals.h index 365a98abd..51b11f526 100644 --- a/verilog/CST/verilog_nonterminals.h +++ b/verilog/CST/verilog_nonterminals.h @@ -175,7 +175,8 @@ enum class NodeEnum { kIfBody, kElseBody, kDisableStatement, - kEventTriggerStatement, + kBlockingEventTriggerStatement, + kNonblockingEventTriggerStatement, kForLoopStatement, kLoopHeader, kJumpStatement, diff --git a/verilog/formatting/token_annotator_test.cc b/verilog/formatting/token_annotator_test.cc index 6d0b4f883..a4b327ac3 100644 --- a/verilog/formatting/token_annotator_test.cc +++ b/verilog/formatting/token_annotator_test.cc @@ -2375,6 +2375,52 @@ TEST(TokenAnnotatorTest, AnnotateFormattingWithContextTest) { {0, SpacingOptions::MustAppend}, }, + // Handle '->' as a unary prefix expression. + { + DefaultStyle, + {TK_TRIGGER, "->"}, + {verilog_tokentype::SymbolIdentifier, "a"}, + {/* any context */}, // context + {0, SpacingOptions::Undecided}, // could be MustAppend though + }, + { + DefaultStyle, + {TK_NONBLOCKING_TRIGGER, "->>"}, + {verilog_tokentype::SymbolIdentifier, "a"}, + {/* any context */}, // context + {0, SpacingOptions::Undecided}, // could be MustAppend though + }, + + // Handle '->' as a binary operator + { + DefaultStyle, + {TK_LOGICAL_IMPLIES, "->"}, + {verilog_tokentype::SymbolIdentifier, "right"}, + {/* any context */}, // context + {1, SpacingOptions::Undecided}, + }, + { + DefaultStyle, + {verilog_tokentype::SymbolIdentifier, "left"}, + {TK_LOGICAL_IMPLIES, "->"}, + {/* any context */}, // context + {1, SpacingOptions::Undecided}, + }, + { + DefaultStyle, + {TK_CONSTRAINT_IMPLIES, "->"}, + {verilog_tokentype::SymbolIdentifier, "right"}, + {/* any context */}, // context + {1, SpacingOptions::Undecided}, + }, + { + DefaultStyle, + {verilog_tokentype::SymbolIdentifier, "left"}, + {TK_CONSTRAINT_IMPLIES, "->"}, + {/* any context */}, // context + {1, SpacingOptions::Undecided}, + }, + // Inside dimension ranges, force space preservation if not around ':' { DefaultStyle, diff --git a/verilog/formatting/verilog_token.cc b/verilog/formatting/verilog_token.cc index 616ff2e13..2b957e8bb 100644 --- a/verilog/formatting/verilog_token.cc +++ b/verilog/formatting/verilog_token.cc @@ -491,7 +491,6 @@ static const auto* FormatTokenTypeMap = {verilog_tokentype::TK_TAND, FTT::binary_operator}, {verilog_tokentype::TK_NXOR, FTT::binary_operator}, {verilog_tokentype::TK_LOGEQUIV, FTT::binary_operator}, - {verilog_tokentype::TK_TRIGGER, FTT::binary_operator}, {verilog_tokentype::TK_LOGICAL_IMPLIES, FTT::binary_operator}, {verilog_tokentype::TK_CONSTRAINT_IMPLIES, FTT::binary_operator}, {verilog_tokentype::TK_COLON_EQ, FTT::binary_operator}, @@ -536,6 +535,8 @@ static const auto* FormatTokenTypeMap = {verilog_tokentype::TK_DECR, FTT::unary_operator}, {verilog_tokentype::TK_NAND, FTT::unary_operator}, {verilog_tokentype::TK_NOR, FTT::unary_operator}, + {verilog_tokentype::TK_TRIGGER, FTT::unary_operator}, + {verilog_tokentype::TK_NONBLOCKING_TRIGGER, FTT::unary_operator}, // hierarchy {verilog_tokentype::TK_SCOPE_RES, FTT::hierarchy}, diff --git a/verilog/parser/verilog.lex b/verilog/parser/verilog.lex index be7a21e85..2e0b866fe 100644 --- a/verilog/parser/verilog.lex +++ b/verilog/parser/verilog.lex @@ -795,6 +795,7 @@ zi_zp { UpdateLocation(); return TK_zi_zp; } "~^" { UpdateLocation(); return TK_NXOR; } "^~" { UpdateLocation(); return TK_NXOR; } "~&" { UpdateLocation(); return TK_NAND; } +"->>" { UpdateLocation(); return TK_NONBLOCKING_TRIGGER; } "->" { UpdateLocation(); return _TK_RARROW; } "<->" { UpdateLocation(); return TK_LOGEQUIV; } "+:" { UpdateLocation(); return TK_PO_POS; } diff --git a/verilog/parser/verilog.y b/verilog/parser/verilog.y index b6554eade..88916e723 100644 --- a/verilog/parser/verilog.y +++ b/verilog/parser/verilog.y @@ -659,6 +659,7 @@ is not locally defined, so the grammar here uses only generic identifiers. // or "^~" %token TK_LOGEQUIV "<->" +%token TK_NONBLOCKING_TRIGGER "->>" %token _TK_RARROW "->" // _TK_RARROW is disambiguated into one of the following symbols // (see verilog_lexical_context.cc): @@ -6614,8 +6615,10 @@ conditional_statement event_trigger : TK_TRIGGER reference ';' - { $$ = MakeTaggedNode(N::kEventTriggerStatement, $1, $2, $3); } - /* TODO(fangism): ->> operator */ + { $$ = MakeTaggedNode(N::kBlockingEventTriggerStatement, $1, $2, $3); } + | TK_NONBLOCKING_TRIGGER delay_or_event_control_opt reference ';' + { $$ = MakeTaggedNode(N::kNonblockingEventTriggerStatement, + $1, $2, $3, $4); } ; repeat_control diff --git a/verilog/parser/verilog_lexer_unittest.cc b/verilog/parser/verilog_lexer_unittest.cc index 676d3cdc5..1346ffc98 100644 --- a/verilog/parser/verilog_lexer_unittest.cc +++ b/verilog/parser/verilog_lexer_unittest.cc @@ -1223,6 +1223,7 @@ static std::initializer_list kKeywordTests = { {{TK_NAND, "~&"}}, {{TK_NOR, "~|"}}, {{TK_NXOR, "~^"}}, + {{TK_NONBLOCKING_TRIGGER, "->>"}}, {{_TK_RARROW, "->"}}, // This can disambiguate to different enums, // depending on context. {{TK_LOGEQUIV, "<->"}}, diff --git a/verilog/parser/verilog_parser_unittest.cc b/verilog/parser/verilog_parser_unittest.cc index d77523bc5..143fd8491 100644 --- a/verilog/parser/verilog_parser_unittest.cc +++ b/verilog/parser/verilog_parser_unittest.cc @@ -1931,6 +1931,26 @@ static const char* kModuleTests[] = { " x = 0;\n" " end\n" "endmodule\n", + "module triggerer;\n" + " always @* begin\n" + " ->>c;\n" // nonblocking event trigger + " end\n" + "endmodule\n", + "module triggerer;\n" + " always @* begin\n" + " ->> #5 c;\n" // nonblocking event trigger, delayed + " end\n" + "endmodule\n", + "module triggerer;\n" + " always @* begin\n" + " ->> @(posedge y) c;\n" // nonblocking event trigger, edge + " end\n" + "endmodule\n", + "module triggerer;\n" + " always @* begin\n" + " ->> repeat(2) @foo c;\n" // nonblocking event trigger, repeat + " end\n" + "endmodule\n", // streaming concatenations with macros "module streaming_cats;\n" "assign s1 = {>>`BAR};\n"