diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-10-25 10:42:03 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-10-29 11:53:01 +0100 |
commit | 1a4ac3531f2cf23a5e74cc6d1b8fa24004b70e8d (patch) | |
tree | 847e12ba16d19049ab9e2bf9c36afa11d4d99ff0 /Shell/Parser.cpp | |
parent | 0801b1fada4d1eacdde3dc4aff04b9ee9eb73bf8 (diff) | |
download | serenity-1a4ac3531f2cf23a5e74cc6d1b8fa24004b70e8d.zip |
Shell: Allow parts of globs to be named in match expressions
This patchset allows a match expression to have a list of names for its
glob parts, which are assigned to the matched values in the body of the
match.
For example,
```sh
stuff=foobarblahblah/target_{1..30}
for $stuff {
match $it {
*/* as (dir sub) {
echo "doing things with $sub in $dir"
make -C $dir $sub # or whatever...
}
}
}
```
With this, match expressions are now significantly more powerful!
Diffstat (limited to 'Shell/Parser.cpp')
-rw-r--r-- | Shell/Parser.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/Shell/Parser.cpp b/Shell/Parser.cpp index 464f5ff465..a6a59f5412 100644 --- a/Shell/Parser.cpp +++ b/Shell/Parser.cpp @@ -752,10 +752,12 @@ AST::MatchEntry Parser::parse_match_entry() NonnullRefPtrVector<AST::Node> patterns; Vector<AST::Position> pipe_positions; + Optional<Vector<String>> match_names; + Optional<AST::Position> match_as_position; auto pattern = parse_match_pattern(); if (!pattern) - return { {}, {}, create<AST::SyntaxError>("Expected a pattern in 'match' body") }; + return { {}, {}, {}, {}, create<AST::SyntaxError>("Expected a pattern in 'match' body") }; patterns.append(pattern.release_nonnull()); @@ -782,6 +784,32 @@ AST::MatchEntry Parser::parse_match_entry() consume_while(is_any_of(" \t\n")); + auto as_start_position = m_offset; + auto as_start_line = line(); + if (expect("as")) { + match_as_position = AST::Position { as_start_position, m_offset, as_start_line, line() }; + consume_while(is_any_of(" \t\n")); + if (!expect('(')) { + if (!error) + error = create<AST::SyntaxError>("Expected an explicit list of identifiers after a pattern 'as'"); + } else { + match_names = Vector<String>(); + for (;;) { + consume_while(is_whitespace); + auto name = consume_while(is_word_character); + if (name.is_empty()) + break; + match_names.value().append(move(name)); + } + + if (!expect(')')) { + if (!error) + error = create<AST::SyntaxError>("Expected a close paren ')' to end the identifier list of pattern 'as'"); + } + } + consume_while(is_any_of(" \t\n")); + } + if (!expect('{')) { if (!error) error = create<AST::SyntaxError>("Expected an open brace '{' to start a match entry body"); @@ -799,7 +827,7 @@ AST::MatchEntry Parser::parse_match_entry() else if (error) body = error; - return { move(patterns), move(pipe_positions), move(body) }; + return { move(patterns), move(match_names), move(match_as_position), move(pipe_positions), move(body) }; } RefPtr<AST::Node> Parser::parse_match_pattern() |