Spicy
operator.h
1 // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <string>
6 #include <utility>
7 
8 #include <hilti/ast/forward.h>
9 #include <hilti/ast/node.h>
10 #include <hilti/ast/types/operand-list.h>
11 #include <hilti/base/logger.h>
12 
13 namespace hilti {
14 
15 namespace expression {
16 class ResolvedOperator;
17 }
18 
19 namespace operator_ {
20 class Registry;
21 
23 enum class Kind {
24  Add,
25  Begin,
26  BitAnd,
27  BitOr,
28  BitXor,
29  Call,
30  Cast,
31  CustomAssign,
32  DecrPostfix,
33  DecrPrefix,
34  Delete,
35  Deref,
36  Difference,
37  DifferenceAssign,
38  Division,
39  DivisionAssign,
40  Equal,
41  End,
42  Greater,
43  GreaterEqual,
44  HasMember,
45  In,
46  IncrPostfix,
47  IncrPrefix,
48  Index,
49  IndexAssign,
50  Lower,
51  LowerEqual,
52  Member,
53  MemberCall,
54  Modulo,
55  Multiple,
56  MultipleAssign,
57  Negate,
58  New,
59  Pack,
60  Power,
61  ShiftLeft,
62  ShiftRight,
63  SignNeg,
64  SignPos,
65  Size,
66  Sum,
67  SumAssign,
68  TryMember,
69  Unequal,
70  Unknown,
71  Unpack,
72  Unset
73 };
74 
76 inline auto isCommutative(Kind k) {
77  switch ( k ) {
78  case Kind::BitAnd:
79  case Kind::BitOr:
80  case Kind::BitXor:
81  case Kind::Equal:
82  case Kind::Unequal:
83  case Kind::Multiple:
84  case Kind::Sum: return true;
85 
86  case Kind::Add:
87  case Kind::Begin:
88  case Kind::Call:
89  case Kind::Cast:
90  case Kind::CustomAssign:
91  case Kind::DecrPostfix:
92  case Kind::DecrPrefix:
93  case Kind::Delete:
94  case Kind::Deref:
95  case Kind::Difference:
96  case Kind::DifferenceAssign:
97  case Kind::Division:
98  case Kind::DivisionAssign:
99  case Kind::End:
100  case Kind::Greater:
101  case Kind::GreaterEqual:
102  case Kind::HasMember:
103  case Kind::In:
104  case Kind::IncrPostfix:
105  case Kind::IncrPrefix:
106  case Kind::Index:
107  case Kind::IndexAssign:
108  case Kind::Lower:
109  case Kind::LowerEqual:
110  case Kind::Member:
111  case Kind::MemberCall:
112  case Kind::Modulo:
113  case Kind::MultipleAssign:
114  case Kind::Negate:
115  case Kind::New:
116  case Kind::Pack:
117  case Kind::Power:
118  case Kind::ShiftLeft:
119  case Kind::ShiftRight:
120  case Kind::SignNeg:
121  case Kind::SignPos:
122  case Kind::Size:
123  case Kind::SumAssign:
124  case Kind::TryMember:
125  case Kind::Unknown:
126  case Kind::Unpack:
127  case Kind::Unset: return false;
128  };
129 
130  util::cannotBeReached();
131 }
132 
133 namespace detail {
134 constexpr util::enum_::Value<Kind> Kinds[] =
135  {{.value = Kind::Add, .name = "add"}, {.value = Kind::Begin, .name = "begin"},
136  {.value = Kind::BitAnd, .name = "&"}, {.value = Kind::BitOr, .name = "|"},
137  {.value = Kind::BitXor, .name = "^"}, {.value = Kind::Call, .name = "call"},
138  {.value = Kind::Cast, .name = "cast"}, {.value = Kind::CustomAssign, .name = "="},
139  {.value = Kind::DecrPostfix, .name = "--"}, {.value = Kind::DecrPrefix, .name = "--"},
140  {.value = Kind::Delete, .name = "delete"}, {.value = Kind::Deref, .name = "*"},
141  {.value = Kind::Division, .name = "/"}, {.value = Kind::DivisionAssign, .name = "/="},
142  {.value = Kind::Equal, .name = "=="}, {.value = Kind::End, .name = "end"},
143  {.value = Kind::Greater, .name = ">"}, {.value = Kind::GreaterEqual, .name = ">="},
144  {.value = Kind::HasMember, .name = "?."}, {.value = Kind::In, .name = "in"},
145  {.value = Kind::IncrPostfix, .name = "++"}, {.value = Kind::IncrPrefix, .name = "++"},
146  {.value = Kind::Index, .name = "index"}, {.value = Kind::IndexAssign, .name = "index_assign"},
147  {.value = Kind::Lower, .name = "<"}, {.value = Kind::LowerEqual, .name = "<="},
148  {.value = Kind::Member, .name = "."}, {.value = Kind::MemberCall, .name = "method call"},
149  {.value = Kind::Negate, .name = "~"}, {.value = Kind::New, .name = "new"},
150  {.value = Kind::Difference, .name = "-"}, {.value = Kind::DifferenceAssign, .name = "-="},
151  {.value = Kind::Modulo, .name = "%"}, {.value = Kind::Multiple, .name = "*"},
152  {.value = Kind::MultipleAssign, .name = "*="}, {.value = Kind::Sum, .name = "+"},
153  {.value = Kind::Pack, .name = "pack"}, {.value = Kind::Unset, .name = "unset"},
154  {.value = Kind::SumAssign, .name = "+="}, {.value = Kind::Power, .name = "**"},
155  {.value = Kind::ShiftLeft, .name = "<<"}, {.value = Kind::ShiftRight, .name = ">>"},
156  {.value = Kind::SignNeg, .name = "-"}, {.value = Kind::SignPos, .name = "+"},
157  {.value = Kind::Size, .name = "size"}, {.value = Kind::TryMember, .name = ".?"},
158  {.value = Kind::Unequal, .name = "!="}, {.value = Kind::Unknown, .name = "<unknown>"},
159  {.value = Kind::Unpack, .name = "unpack"}, {.value = Kind::Unset, .name = "unset"}};
160 
162 extern std::string print(Kind kind, const Expressions& operands);
163 
165 extern std::string printSignature(Kind kind, const Expressions& operands, const Meta& meta);
166 
167 } // namespace detail
168 
174 constexpr auto to_string(Kind m) { return util::enum_::to_string(m, detail::Kinds); }
175 
177 enum class Priority { Low, Normal };
178 
179 using Operand = type::operand_list::Operand;
180 using Operands = type::operand_list::Operands;
181 
183 struct Signature {
185  struct QType {
186  parameter::Kind kind = parameter::Kind::Unknown;
187  UnqualifiedType* type = nullptr;
188  std::string doc;
191  UnqualifiedType* getType() const {
192  if ( external_type )
193  return external_type;
194  else
195  return type;
196  }
197 
198  operator bool() const { return kind != parameter::Kind::Unknown && getType(); }
199  };
200 
201  struct QResult {
202  Constness constness = Constness::Const;
203  UnqualifiedType* type = nullptr;
204  std::string doc;
206  operator bool() const { return type != nullptr; }
207  };
208 
210  struct QParam {
211  std::string name;
213  Expression* default_ = nullptr;
214  bool optional = false;
216  operator bool() const { return type; }
217  };
218 
219  operator_::Kind kind;
220  operator_::Priority priority = operator_::Priority::Normal;
221 
222  QType self;
223  QType op0;
224  QType op1;
225  QType op2;
226 
227  std::optional<std::string> member;
228  QParam param0;
229  QParam param1;
230  QParam param2;
231  QParam param3;
232  QParam param4;
233 
235  std::string result_doc;
237  std::string ns;
238  std::string doc;
239  bool skip_doc = false;
240 };
241 
242 namespace detail {
243 
246  operator_::Kind kind = operator_::Kind::Unknown;
250  operator_::Priority priority;
251  std::string doc;
252  std::string result_doc;
253  std::string namespace_;
254  bool skip_doc;
255 };
256 } // namespace detail
257 
258 } // namespace operator_
259 
268 class Operator {
269 public:
270  template<typename T>
271  using Result = ::hilti::Result<T>;
272 
280  Operator(Meta meta = Meta(), bool builtin = true) : _meta(std::move(meta)), _builtin(builtin) {}
281 
283  virtual ~Operator() {}
284 
285  Operator(const Operator& other) = delete;
286  Operator(Operator&& other) = delete;
287 
288  Operator& operator=(const Operator& other) = delete;
289  Operator& operator=(Operator&& other) = delete;
290 
292  auto isInitialized() const { return _signature.has_value(); }
293 
299  auto hasOperands() const { return _signature->operands; }
300 
302  const auto& signature() const {
303  assert(_signature);
304  return *_signature;
305  }
306 
308  auto kind() const { return signature().kind; }
309 
314  auto isBuiltIn() const { return _builtin; }
315 
317  auto operands() const { return signature().operands->operands(); }
318 
320  auto op0() const { return operands()[0]; }
321 
323  auto op1() const { return operands()[1]; }
324 
326  auto op2() const { return operands()[2]; }
327 
329  const auto& meta() const { return _meta; }
330 
332  const auto& doc() const { return signature().doc; }
333 
338  auto typename_() const { return _typename(); }
339 
345  virtual QualifiedType* result(Builder* builder, const Expressions& operands, const Meta& meta) const;
346 
352  virtual std::optional<operator_::Operands> filter(Builder* /*builder*/, const Expressions& /*operands*/) const {
353  return {};
354  }
355 
360  virtual void validate(expression::ResolvedOperator* n) const {};
361 
364  Expressions operands,
365  Meta meta) const = 0;
366 
371  virtual std::string name() const = 0;
372 
374  virtual std::string print() const;
375 
377  virtual std::string dump() const;
378 
379 protected:
380  friend class operator_::Registry;
381 
383  bool init(Builder* builder, Node* scope_root = nullptr);
384 
389  virtual operator_::Signature signature(Builder* builder) const = 0;
390 
392  virtual std::string _typename() const { return util::typename_(*this); }
393 
400  static operator_::Operand* operandForType(Builder* builder,
401  parameter::Kind kind,
402  UnqualifiedType* t,
403  std::string doc = "");
404 
412  parameter::Kind kind,
413  const Expressions& e,
414  size_t i) {
415  return operandForType(builder, kind, e[i]->type()->type(), "");
416  }
417 
418 private:
419  Meta _meta;
420  bool _builtin;
421  std::optional<operator_::detail::ProcessedSignature> _signature;
422 };
423 
428 class BuiltInMemberCall : public Operator {
429 public:
430  ~BuiltInMemberCall() override {}
431 
433  std::string print() const final;
434 };
435 
436 } // namespace hilti
Definition: builder.h:36
Definition: operator.h:428
std::string print() const final
Definition: operator.cc:360
Definition: expression.h:15
Definition: meta.h:30
Definition: node.h:243
Definition: operator.h:268
static operator_::Operand * operandForType(Builder *builder, parameter::Kind kind, UnqualifiedType *t, std::string doc="")
Definition: operator.cc:347
virtual QualifiedType * result(Builder *builder, const Expressions &operands, const Meta &meta) const
Definition: operator.cc:324
bool init(Builder *builder, Node *scope_root=nullptr)
Definition: operator.cc:217
Operator(Meta meta=Meta(), bool builtin=true)
Definition: operator.h:280
auto hasOperands() const
Definition: operator.h:299
static operator_::Operand * operandForExpression(Builder *builder, parameter::Kind kind, const Expressions &e, size_t i)
Definition: operator.h:411
auto isBuiltIn() const
Definition: operator.h:314
auto operands() const
Definition: operator.h:317
virtual std::optional< operator_::Operands > filter(Builder *, const Expressions &) const
Definition: operator.h:352
virtual std::string dump() const
Definition: operator.cc:339
virtual operator_::Signature signature(Builder *builder) const =0
auto op2() const
Definition: operator.h:326
auto kind() const
Definition: operator.h:308
const auto & signature() const
Definition: operator.h:302
auto op1() const
Definition: operator.h:323
virtual ~Operator()
Definition: operator.h:283
virtual std::string _typename() const
Definition: operator.h:392
auto isInitialized() const
Definition: operator.h:292
virtual std::string name() const =0
auto typename_() const
Definition: operator.h:338
const auto & doc() const
Definition: operator.h:332
virtual std::string print() const
Definition: operator.cc:332
const auto & meta() const
Definition: operator.h:329
virtual Result< expression::ResolvedOperator * > instantiate(Builder *builder, Expressions operands, Meta meta) const =0
virtual void validate(expression::ResolvedOperator *n) const
Definition: operator.h:360
auto op0() const
Definition: operator.h:320
Definition: type.h:365
Definition: type.h:147
Definition: resolved-operator.h:23
Definition: node.h:179
Definition: operator-registry.h:35
Definition: result.h:73
Definition: operand-list.h:18
void print(const T &t, const hilti::rt::TypeInfo *, bool newline=true)
Definition: hilti.h:23
Definition: operator.h:210
Expression * default_
Definition: operator.h:213
QType type
Definition: operator.h:212
std::string name
Definition: operator.h:211
bool optional
Definition: operator.h:214
Definition: operator.h:201
Constness constness
Definition: operator.h:202
std::string doc
Definition: operator.h:204
UnqualifiedType * type
Definition: operator.h:203
Definition: operator.h:185
parameter::Kind kind
Definition: operator.h:186
std::string doc
Definition: operator.h:188
UnqualifiedType * type
Definition: operator.h:187
UnqualifiedType * external_type
Definition: operator.h:189
Definition: operator.h:183
QResult result
Definition: operator.h:234
std::string result_doc
Definition: operator.h:235
std::string ns
Definition: operator.h:237
bool skip_doc
Definition: operator.h:239
std::string doc
Definition: operator.h:238
std::string result_doc
Definition: operator.h:252
std::string namespace_
Definition: operator.h:253
std::string doc
Definition: operator.h:251
node::RetainedPtr< QualifiedType > result
Definition: operator.h:248
node::RetainedPtr< type::OperandList > operands
Definition: operator.h:249
bool skip_doc
Definition: operator.h:254