diff --git a/Userland/Shell/PosixParser.cpp b/Userland/Shell/PosixParser.cpp index 3594f59904..951050aa5a 100644 --- a/Userland/Shell/PosixParser.cpp +++ b/Userland/Shell/PosixParser.cpp @@ -769,15 +769,38 @@ ErrorOr> Parser::parse_and_or() ErrorOr> Parser::parse_pipeline() { - return parse_pipe_sequence(); + while (peek().type == Token::Type::Newline) + skip(); + + auto is_negated = false; + if (peek().type == Token::Type::Bang) { + is_negated = true; + skip(); + } + + return parse_pipe_sequence(is_negated); } -ErrorOr> Parser::parse_pipe_sequence() +ErrorOr> Parser::parse_pipe_sequence(bool is_negated) { auto node = TRY(parse_command()); if (!node) return RefPtr {}; + if (is_negated) { + if (is(node.ptr())) { + node = make_ref_counted( + node->position(), + make_ref_counted( + node->position(), + Vector> { + make_ref_counted( + node->position(), + "not"_short_string), + *static_cast(*node).inner() })); + } + } + for (;;) { if (peek().type != Token::Type::Pipe) break; diff --git a/Userland/Shell/PosixParser.h b/Userland/Shell/PosixParser.h index 462e3dc319..3a817e842f 100644 --- a/Userland/Shell/PosixParser.h +++ b/Userland/Shell/PosixParser.h @@ -71,7 +71,7 @@ private: ErrorOr> parse_list(); ErrorOr> parse_and_or(); ErrorOr> parse_pipeline(); - ErrorOr> parse_pipe_sequence(); + ErrorOr> parse_pipe_sequence(bool is_negated); ErrorOr> parse_command(); ErrorOr> parse_compound_command(); ErrorOr> parse_subshell();