From 6814b6778433b52f825db1588cf2778eea5b3cd4 Mon Sep 17 00:00:00 2001 From: Yingchi Long Date: Fri, 29 Mar 2024 20:17:15 +0800 Subject: [PATCH 1/3] libnixf/Basic: add `Fn` to as child of ExprCall --- libnixf/include/nixf/Basic/Nodes/Expr.h | 3 ++- libnixf/test/Basic/Nodes.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libnixf/include/nixf/Basic/Nodes/Expr.h b/libnixf/include/nixf/Basic/Nodes/Expr.h index 344491864..e7d16bca5 100644 --- a/libnixf/include/nixf/Basic/Nodes/Expr.h +++ b/libnixf/include/nixf/Basic/Nodes/Expr.h @@ -55,7 +55,8 @@ class ExprCall : public Expr { [[nodiscard]] ChildVector children() const override { ChildVector Children; - Children.reserve(Args.size()); + Children.reserve(Args.size() + 1); + Children.emplace_back(Fn.get()); for (const auto &Member : Args) { Children.emplace_back(Member.get()); } diff --git a/libnixf/test/Basic/Nodes.cpp b/libnixf/test/Basic/Nodes.cpp index 0ed3c9e0f..adf5cd50c 100644 --- a/libnixf/test/Basic/Nodes.cpp +++ b/libnixf/test/Basic/Nodes.cpp @@ -36,4 +36,12 @@ TEST(Node, InterpolateLiteralFalse) { ASSERT_FALSE(Parts.isLiteral()); } +TEST(Node, ExprCall_Children) { + auto Src = "foo bar baz"sv; + std::vector Diag; + auto Root = parse(Src, Diag); + + ASSERT_EQ(Root->children().size(), 3); +} + } // namespace From 8278f39389e73c209630421fb2593e59a0c7021e Mon Sep 17 00:00:00 2001 From: Yingchi Long Date: Fri, 29 Mar 2024 20:19:59 +0800 Subject: [PATCH 2/3] libnixf/Basic: add interpolated expression to string's children --- libnixf/include/nixf/Basic/Nodes/Simple.h | 11 +++++++++-- libnixf/test/Basic/Nodes.cpp | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libnixf/include/nixf/Basic/Nodes/Simple.h b/libnixf/include/nixf/Basic/Nodes/Simple.h index a2f99ab30..0dce92190 100644 --- a/libnixf/include/nixf/Basic/Nodes/Simple.h +++ b/libnixf/include/nixf/Basic/Nodes/Simple.h @@ -103,7 +103,14 @@ class InterpolatedParts : public Node { return Fragments[0].escaped(); } - [[nodiscard]] ChildVector children() const override { return {}; } + [[nodiscard]] ChildVector children() const override { + ChildVector Children; + for (const auto &Frag : Fragments) { + if (Frag.kind() == InterpolablePart::SPK_Interpolation) + Children.emplace_back(&Frag.interpolation()); + } + return Children; + } }; class ExprString : public Expr { @@ -130,7 +137,7 @@ class ExprString : public Expr { return Parts->literal(); } - [[nodiscard]] ChildVector children() const override { return {}; } + [[nodiscard]] ChildVector children() const override { return {Parts.get()}; } }; class ExprPath : public Expr { diff --git a/libnixf/test/Basic/Nodes.cpp b/libnixf/test/Basic/Nodes.cpp index adf5cd50c..385db1247 100644 --- a/libnixf/test/Basic/Nodes.cpp +++ b/libnixf/test/Basic/Nodes.cpp @@ -44,4 +44,13 @@ TEST(Node, ExprCall_Children) { ASSERT_EQ(Root->children().size(), 3); } +TEST(Node, ExprString_Children) { + auto Src = R"("foo${baz}")"sv; + std::vector Diag; + auto Root = parse(Src, Diag); + + ASSERT_EQ(Root->children().size(), 1); + ASSERT_EQ(Root->children()[0]->children().size(), 1); +} + } // namespace From 2f762266431be2edcab1e48f1f2b6de7103991fb Mon Sep 17 00:00:00 2001 From: Yingchi Long Date: Fri, 29 Mar 2024 20:20:59 +0800 Subject: [PATCH 3/3] libnixf/{Basic,Parse}: add Misc nodes for with expression --- libnixf/include/nixf/Basic/Nodes/Expr.h | 12 +++++++++--- libnixf/src/Parse/ParseExpr.cpp | 5 +++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libnixf/include/nixf/Basic/Nodes/Expr.h b/libnixf/include/nixf/Basic/Nodes/Expr.h index e7d16bca5..b22c60b10 100644 --- a/libnixf/include/nixf/Basic/Nodes/Expr.h +++ b/libnixf/include/nixf/Basic/Nodes/Expr.h @@ -158,19 +158,25 @@ class ExprLet : public Expr { }; class ExprWith : public Expr { + std::shared_ptr KwWith; + std::shared_ptr TokSemi; std::shared_ptr With; std::shared_ptr E; public: - ExprWith(LexerCursorRange Range, std::shared_ptr With, + ExprWith(LexerCursorRange Range, std::shared_ptr KwWith, + std::shared_ptr TokSemi, std::shared_ptr With, std::shared_ptr E) - : Expr(NK_ExprWith, Range), With(std::move(With)), E(std::move(E)) {} + : Expr(NK_ExprWith, Range), KwWith(std::move(KwWith)), + TokSemi(std::move(TokSemi)), With(std::move(With)), E(std::move(E)) {} + [[nodiscard]] const Misc &kwWith() const { return *KwWith; } + [[nodiscard]] const Misc *tokSemi() const { return TokSemi.get(); } [[nodiscard]] Expr *with() const { return With.get(); } [[nodiscard]] Expr *expr() const { return E.get(); } [[nodiscard]] ChildVector children() const override { - return {With.get(), E.get()}; + return {KwWith.get(), TokSemi.get(), With.get(), E.get()}; } }; diff --git a/libnixf/src/Parse/ParseExpr.cpp b/libnixf/src/Parse/ParseExpr.cpp index 1d7a5c0ab..654528661 100644 --- a/libnixf/src/Parse/ParseExpr.cpp +++ b/libnixf/src/Parse/ParseExpr.cpp @@ -280,6 +280,8 @@ std::shared_ptr Parser::parseExprWith() { assert(TokWith.kind() == tok_kw_with && "token should be tok_kw_with"); consume(); // with + + auto KwWith = std::make_shared(TokWith.range()); assert(LastToken && "LastToken should be set after consume()"); auto SyncSemi = withSync(tok_semi_colon); @@ -294,9 +296,11 @@ std::shared_ptr Parser::parseExprWith() { ExpSemi.diag().note(Note::NK_ToMachThis, TokWith.range()) << std::string(tok::spelling(tok_kw_with)); return std::make_shared(LexerCursorRange{LCur, LastToken->rCur()}, + std::move(KwWith), /*TokSemi*/ nullptr, std::move(With), /*E=*/nullptr); } + auto TokSemi = std::make_shared(ExpSemi.tok().range()); consume(); // ; auto E = parseExpr(); @@ -305,6 +309,7 @@ std::shared_ptr Parser::parseExprWith() { diagNullExpr(Diags, LastToken->rCur(), "with body"); return std::make_shared(LexerCursorRange{LCur, LastToken->rCur()}, + std::move(KwWith), std::move(TokSemi), std::move(With), std::move(E)); }