1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 10:27:36 +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

@ -757,6 +757,31 @@ private:
RefPtr<Node> m_right;
};
struct MatchEntry {
NonnullRefPtrVector<Node> options;
Vector<Position> pipe_positions;
RefPtr<Node> body;
};
class MatchExpr final : public Node {
public:
MatchExpr(Position, RefPtr<Node> expr, String name, Optional<Position> as_position, Vector<MatchEntry> entries);
virtual ~MatchExpr();
private:
virtual void dump(int level) const override;
virtual RefPtr<Value> run(RefPtr<Shell>) override;
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
virtual HitTestResult hit_test_position(size_t) override;
virtual String class_name() const override { return "MatchExpr"; }
virtual bool would_execute() const override { return true; }
RefPtr<Node> m_matched_expr;
String m_expr_name;
Optional<Position> m_as_position;
Vector<MatchEntry> m_entries;
};
class Or final : public Node {
public:
Or(Position, RefPtr<Node>, RefPtr<Node>);