1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 16:27:35 +00:00

Shell: Add 'match' expressions

This commit adds an equivalent to the sh 'case' construct, except it's
much more pleasing to look at and write:
```sh
match "$something" {
    p1 { echo "p1!" }
    p2 { echo "p2!" }
    *  { echo "string catch-all!" }
}
```
is the equivalent of:
```sh
case $something in
    p1)
        echo "p1!"
        ;;
    p2)
        echo "p2!"
        ;;
    *)
        echo "catch-all!"
        ;;
esac
```

Since our shell does not treat lists as strings, matching lists is also
possible:

```sh
match (1foo 2foo foo3) {
    (?foo 2* *) { echo wowzers! }
    (* * *) { echo 3-element list catch-all }
}
```
This commit is contained in:
AnotherTest 2020-09-14 19:32:21 +04:30 committed by Andreas Kling
parent 53b85bcdd0
commit 4c6f7846b4
4 changed files with 317 additions and 0 deletions

View file

@ -55,6 +55,9 @@ private:
RefPtr<AST::Node> parse_for_loop();
RefPtr<AST::Node> parse_if_expr();
RefPtr<AST::Node> parse_subshell();
RefPtr<AST::Node> parse_match_expr();
AST::MatchEntry parse_match_entry();
RefPtr<AST::Node> parse_match_pattern();
RefPtr<AST::Node> parse_redirection();
RefPtr<AST::Node> parse_list_expression();
RefPtr<AST::Node> parse_expression();
@ -135,6 +138,7 @@ pipe_sequence :: command '|' pipe_sequence
control_structure :: for_expr
| if_expr
| subshell
| match_expr
for_expr :: 'for' ws+ (identifier ' '+ 'in' ws*)? expression ws+ '{' toplevel '}'
@ -145,6 +149,12 @@ else_clause :: else '{' toplevel '}'
subshell :: '{' toplevel '}'
match_expr :: 'match' ws+ expression ws* ('as' ws+ identifier)? '{' match_entry* '}'
match_entry :: match_pattern ws* '{' toplevel '}'
match_pattern :: expression (ws* '|' ws* expression)*
command :: redirection command
| list_expression command?