Spicy
switch.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <utility>
6 #include <vector>
7 
8 #include <hilti/ast/types/vector.h>
9 
10 #include <spicy/ast/aliases.h>
11 #include <spicy/ast/engine.h>
12 #include <spicy/ast/types/unit-items/field.h>
13 #include <spicy/ast/types/unit.h>
14 
15 namespace spicy::type::unit::item {
16 
17 namespace switch_ {
18 
20 class Case : public hilti::NodeBase {
21 public:
22  Case(std::vector<Expression> exprs, std::vector<type::unit::Item> items, Meta m = Meta())
23  : NodeBase(hilti::nodes(std::move(items), std::move(exprs)), std::move(m)) {}
24 
26  Case(std::vector<type::unit::Item> items, Meta m = Meta())
27  : NodeBase(hilti::nodes(std::move(items)), std::move(m)) {}
28 
30  Case(type::unit::Item field, Meta m = Meta())
31  : NodeBase(hilti::nodes(std::move(field)), std::move(m)), _look_ahead(true) {}
32 
33  Case() = default;
34 
35  auto expressions() const { return childsOfType<Expression>(); }
36  auto items() const { return childsOfType<type::unit::Item>(); }
37  auto itemNodes() { return nodesOfType<type::unit::Item>(); }
38 
40  bool isDefault() const { return expressions().empty() && ! _look_ahead; }
41 
43  bool isLookAhead() const { return _look_ahead; }
44 
45  auto properties() const { return node::Properties{{"default", isDefault()}, {"look-ahead", isLookAhead()}}; }
46 
47  bool operator==(const Case& other) const {
48  return expressions() == other.expressions() && items() == other.items();
49  }
50 
51 private:
52  bool _look_ahead = false;
53 };
54 
55 inline Node to_node(Case c) { return Node(std::move(c)); }
56 
57 } // namespace switch_
58 
61 public:
62  Switch(std::optional<Expression> expr, const std::vector<switch_::Case>& cases, Engine e,
63  std::optional<Expression> cond, std::vector<Hook> hooks, std::optional<AttributeSet> attributes,
64  Meta m = Meta())
65  : NodeBase(nodes(std::move(expr), std::move(cond), std::move(attributes), cases, std::move(hooks)),
66  std::move(m)),
67  _engine(e),
68  _cases_start(3),
69  _cases_end(_cases_start + static_cast<int>(cases.size())),
70  _hooks_start(_cases_end),
71  _hooks_end(-1) {}
72 
73  auto expression() const { return childs()[0].tryReferenceAs<Expression>(); }
74  Engine engine() const { return _engine; }
75  auto condition() const { return childs()[1].tryReferenceAs<Expression>(); }
76  auto cases() const { return childs<switch_::Case>(_cases_start, _cases_end); }
77  auto casesNodes() { return nodesOfType<switch_::Case>(); }
78  auto attributes() const { return childs()[2].tryReferenceAs<AttributeSet>(); }
79 
80  auto hooks() const { return childs<Hook>(_hooks_start, _hooks_end); }
81 
83  bool hasNoFields() const;
84 
90  std::optional<switch_::Case> case_(const type::unit::item::Field& x);
91 
92  bool operator==(const Switch& other) const {
93  return expression() == other.expression() && engine() == other.engine() && condition() == other.condition() &&
94  cases() == other.cases() && hooks() == other.hooks();
95  }
96 
97  // Unit item interface
98  Type itemType() const { return type::Void(); }
99  auto isEqual(const Item& other) const { return node::isEqual(this, other); }
100 
101  // Node interface.
102  auto properties() const { return node::Properties{{"engine", to_string(_engine)}}; }
103 
104 private:
105  Engine _engine;
106  const int _cases_start;
107  const int _cases_end;
108  const int _hooks_start;
109  const int _hooks_end;
110 };
111 
112 } // namespace spicy::type::unit::item
Definition: void.h:13
NodeBase(Meta meta)
Definition: node.h:325
auto & childs() const
Definition: node.h:445
Case(std::vector< type::unit::Item > items, Meta m=Meta())
Definition: switch.h:26
Definition: optional.h:79
Definition: field.h:19
Definition: meta.h:18
Definition: attribute.h:159
Definition: switch.h:60
bool isDefault() const
Definition: switch.h:40
Case(type::unit::Item field, Meta m=Meta())
Definition: switch.h:30
Definition: node.h:97
bool isLookAhead() const
Definition: switch.h:43
Definition: unit-item.h:19
Definition: unit-item.h:39
Definition: node.h:318