Skip to content

Commit 43ce9af

Browse files
committed
WIP: Improve constexpr-if string formatting
Signed-off-by: Robert Winkler <[email protected]>
1 parent 5b671e4 commit 43ce9af

File tree

6 files changed

+75
-16
lines changed

6 files changed

+75
-16
lines changed

xls/dslx/fmt/ast_fmt.cc

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,14 +1597,19 @@ DocRef Fmt(const String& n, Comments& comments, DocArena& arena) {
15971597
// if <break1> $test_expr <break1> {
15981598
DocRef MakeConditionalTest(const Conditional& n, Comments& comments,
15991599
DocArena& arena) {
1600-
return ConcatN(
1601-
arena, {
1602-
arena.Make(Keyword::kIf),
1603-
arena.space(),
1604-
FmtExpr(*n.test(), comments, arena, /*suppress_parens=*/true),
1605-
arena.space(),
1606-
arena.ocurl(),
1607-
});
1600+
std::vector<DocRef> pieces;
1601+
if (n.IsConst() && !n.IsPartOfLadder()) {
1602+
pieces.push_back(arena.Make(Keyword::kConst));
1603+
pieces.push_back(arena.space());
1604+
}
1605+
pieces.push_back(arena.Make(Keyword::kIf));
1606+
pieces.push_back(arena.space());
1607+
pieces.push_back(
1608+
FmtExpr(*n.test(), comments, arena, /*suppress_parens=*/true));
1609+
pieces.push_back(arena.space());
1610+
pieces.push_back(arena.ocurl());
1611+
1612+
return ConcatNGroup(arena, pieces);
16081613
}
16091614

16101615
// When there's an else-if, or multiple statements inside of the blocks, we

xls/dslx/fmt/ast_fmt_test.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,33 @@ TEST_F(FunctionFmtTest, ConditionalWithUnnecessaryParens) {
558558
EXPECT_EQ(got, want);
559559
}
560560

561+
TEST_F(FunctionFmtTest, ConstexprConditionalInTernaryStyle) {
562+
const std::string_view original =
563+
"fn f<TEST:bool>(y:u32,z:u32)->u32{const if TEST{y}else{z}}";
564+
XLS_ASSERT_OK_AND_ASSIGN(std::string got, DoFmt(original));
565+
const std::string_view want =
566+
R"(fn f<TEST: bool>(y: u32, z: u32) -> u32 { const if TEST { y } else { z } })";
567+
EXPECT_EQ(got, want);
568+
}
569+
570+
TEST_F(FunctionFmtTest, ConstexprConditionalWithElseIf) {
571+
const std::string_view original =
572+
"fn f<TEST: bool[2]>(x:u32[3])->u32{const if TEST[0]{x[0]}else if "
573+
"TEST[1]{x[1]}else{x[2]}}";
574+
XLS_ASSERT_OK_AND_ASSIGN(std::string got, DoFmt(original));
575+
const std::string_view want =
576+
R"(fn f<TEST: bool[2]>(x: u32[3]) -> u32 {
577+
const if TEST[0] {
578+
x[0]
579+
} else if TEST[1] {
580+
x[1]
581+
} else {
582+
x[2]
583+
}
584+
})";
585+
EXPECT_EQ(got, want);
586+
}
587+
561588
TEST_F(FunctionFmtTest, SimpleForOneStatementNoTypeAnnotation) {
562589
const std::string_view original =
563590
"fn f(x:u32)->u32{for(i,accum)in u32:0..u32:4{accum+i}(x)}";

xls/dslx/frontend/ast.cc

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -719,23 +719,21 @@ std::vector<StatementBlock*> Conditional::GatherBlocks() {
719719
}
720720

721721
std::string Conditional::ToStringInternal() const {
722-
const absl::string_view const_prefix = is_const_ ? "const " : "";
722+
const absl::string_view const_prefix = (is_const_ && IsPartOfLadder()) ? "const " : "";
723723

724724
auto make_string = [&](std::string (AstNode::*to_str_fn)()
725725
const) -> std::string {
726726
std::string test_str = (test_->*to_str_fn)();
727727
std::string then_str = (consequent_->*to_str_fn)();
728-
729-
std::string else_part = " ";
728+
std::string else_str = "";
730729
if (has_else_) {
731-
std::string else_str = (ToAstNode(alternate_)->*to_str_fn)();
732-
absl::string_view view = else_str;
733-
absl::ConsumePrefix(&view, const_prefix);
734-
else_part = absl::StrFormat(" else %s", view);
730+
else_str = absl::StrFormat(" else %s",
731+
(ToAstNode(alternate_)->*to_str_fn)()
732+
);
735733
}
736734

737735
return absl::StrFormat("%sif %s %s%s", const_prefix, test_str, then_str,
738-
else_part);
736+
else_str);
739737
};
740738

741739
std::string inline_str = make_string(&AstNode::ToInlineString);

xls/dslx/frontend/ast.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,6 +2349,19 @@ class Conditional : public Expr {
23492349
// blocks of this if/else-if.../else ladder.
23502350
std::vector<StatementBlock*> GatherBlocks();
23512351

2352+
bool IsPartOfLadder() const {
2353+
if (parent() == nullptr) {
2354+
return false;
2355+
}
2356+
2357+
if (parent()->kind() == AstNodeKind::kConditional) {
2358+
AstNode *parent_node = parent();
2359+
Conditional *parent = down_cast<Conditional*>(parent_node);
2360+
return ToAstNode(parent->alternate()) == this;
2361+
}
2362+
return false;
2363+
}
2364+
23522365
private:
23532366
std::string ToStringInternal() const final;
23542367

xls/dslx/frontend/parser.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,7 @@ absl::StatusOr<Conditional*> Parser::ParseConditionalNode(
11721172
for (StatementBlock* block : outer_conditional->GatherBlocks()) {
11731173
block->SetEnclosing(outer_conditional);
11741174
}
1175+
outer_conditional->SetParentage();
11751176
return outer_conditional;
11761177
}
11771178

xls/dslx/frontend/parser_test.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2940,6 +2940,21 @@ TEST_F(ParserTest, TernaryConditional) {
29402940
{"really_long_identifier_so_that_this_is_too_many_chars"});
29412941
}
29422942

2943+
TEST_F(ParserTest, ConstexprTernaryConditional) {
2944+
Expr* e = RoundTripExpr("const if true { u32:42 } else { u32:24 }", {});
2945+
2946+
EXPECT_TRUE(down_cast<Conditional*>(e)->IsConst());
2947+
EXPECT_FALSE(down_cast<Conditional*>(e)->HasElseIf());
2948+
EXPECT_FALSE(down_cast<Conditional*>(e)->HasMultiStatementBlocks());
2949+
2950+
RoundTripExpr(R"(const if really_long_identifier_so_that_this_is_too_many_chars {
2951+
u32:42
2952+
} else {
2953+
u32:24
2954+
})",
2955+
{"really_long_identifier_so_that_this_is_too_many_chars"});
2956+
}
2957+
29432958
TEST_F(ParserTest, ConditionalInBinopChain) {
29442959
RoundTrip("const X = if true { u32:42 } else { u32:24 } + u32:1;");
29452960
RoundTrip("const X = u32:1 + if true { u32:42 } else { u32:24 };");

0 commit comments

Comments
 (0)