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 itemRefs() const { return childRefsOfType<type::unit::Item>(); }
38 
40  bool isDefault() const { return expressions().empty() && ! _look_ahead; }
41 
43  bool isLookAhead() const { return _look_ahead; }
44 
46  bool isResolved() const {
47  for ( const auto& i : items() ) {
48  if ( ! i.isResolved() )
49  return false;
50  }
51 
52  return true;
53  }
54 
55  auto properties() const { return node::Properties{{"default", isDefault()}, {"look-ahead", isLookAhead()}}; }
56 
57  bool operator==(const Case& other) const;
58 
59 private:
60  bool _look_ahead = false;
61 };
62 
63 inline Node to_node(Case c) { return Node(std::move(c)); }
64 
65 } // namespace switch_
66 
69 public:
70  Switch(std::optional<Expression> expr, const std::vector<switch_::Case>& cases, Engine e,
71  std::optional<Expression> cond, std::vector<Hook> hooks, std::optional<AttributeSet> attributes,
72  Meta m = Meta())
73  : NodeBase(nodes(std::move(expr), std::move(cond), std::move(attributes), cases, std::move(hooks)),
74  std::move(m)),
75  _engine(e) {}
76 
77  Engine engine() const { return _engine; }
78  auto attributes() const { return childs()[2].tryAs<AttributeSet>(); }
79  auto cases() const { return childsOfType<switch_::Case>(); }
80  auto condition() const { return childs()[1].tryAs<Expression>(); }
81  auto expression() const { return childs()[0].tryAs<Expression>(); }
82  auto hooks() const { return childsOfType<Hook>(); }
83 
84  auto itemRefs() const { return childRefsOfType<type::unit::Item>(); }
85 
87  bool hasNoFields() const;
88 
95 
96  bool operator==(const Switch& other) const {
97  return expression() == other.expression() && engine() == other.engine() && condition() == other.condition() &&
98  cases() == other.cases() && hooks() == other.hooks();
99  }
100 
101  // Unit item interface
102  const Type& itemType() const { return type::void_; }
103 
104  bool isResolved() const {
105  for ( const auto& c : cases() ) {
106  if ( ! c.isResolved() )
107  return false;
108  }
109 
110  return true;
111  }
112 
113  auto isEqual(const Item& other) const { return node::isEqual(this, other); }
114 
115  // Node interface.
116  auto properties() const { return node::Properties{{"engine", to_string(_engine)}}; }
117 
118 private:
119  Engine _engine;
120 };
121 
122 } // namespace spicy::type::unit::item
NodeBase(Meta meta)
Definition: node.h:365
Case(std::vector< type::unit::Item > items, Meta m=Meta())
Definition: switch.h:26
Definition: optional.h:79
bool isResolved() const
Definition: switch.h:46
Definition: field.h:22
Definition: meta.h:18
Definition: attribute.h:145
Definition: type.h:159
Definition: optional-ref.h:22
Definition: switch.h:68
bool isDefault() const
Definition: switch.h:40
Case(type::unit::Item field, Meta m=Meta())
Definition: switch.h:30
Definition: node.h:113
bool isLookAhead() const
Definition: switch.h:43
Definition: unit-item.h:19
const auto & childs() const
Definition: node.h:470
Definition: hook.h:22
Definition: node.h:358