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 
164 
166 extern std::string printSignature(Kind kind, const Expressions& operands, const Meta& meta);
167 
168 } // namespace detail
169 
175 constexpr auto to_string(Kind m) { return util::enum_::to_string(m, detail::Kinds); }
176 
178 enum class Priority { Low, Normal };
179 
180 using Operand = type::operand_list::Operand;
181 using Operands = type::operand_list::Operands;
182 
184 struct Signature {
186  struct QType {
187  parameter::Kind kind = parameter::Kind::Unknown;
188  UnqualifiedType* type = nullptr;
189  std::string doc;
192  UnqualifiedType* getType() const {
193  if ( external_type )
194  return external_type;
195  else
196  return type;
197  }
198 
199  operator bool() const { return kind != parameter::Kind::Unknown && getType(); }
200  };
201 
202  struct QResult {
203  Constness constness = Constness::Const;
204  UnqualifiedType* type = nullptr;
205  std::string doc;
207  operator bool() const { return type != nullptr; }
208  };
209 
211  struct QParam {
212  std::string name;
214  Expression* default_ = nullptr;
215  bool optional = false;
217  operator bool() const { return type; }
218  };
219 
220  operator_::Kind kind;
221  operator_::Priority priority = operator_::Priority::Normal;
222 
223  QType self;
224  QType op0;
225  QType op1;
226  QType op2;
227 
228  std::optional<std::string> member;
229  QParam param0;
230  QParam param1;
231  QParam param2;
232  QParam param3;
233  QParam param4;
234 
236  std::string result_doc;
238  std::string ns;
239  std::string doc;
240  bool skip_doc = false;
241 };
242 
243 namespace detail {
244 
247  operator_::Kind kind = operator_::Kind::Unknown;
251  operator_::Priority priority;
252  std::string doc;
253  std::string result_doc;
254  std::string namespace_;
255  bool skip_doc;
256 };
257 } // namespace detail
258 
259 } // namespace operator_
260 
269 class Operator {
270 public:
271  template<typename T>
272  using Result = ::hilti::Result<T>;
273 
281  Operator(Meta meta = Meta(), bool builtin = true) : _meta(std::move(meta)), _builtin(builtin) {}
282 
284  virtual ~Operator() {}
285 
286  Operator(const Operator& other) = delete;
287  Operator(Operator&& other) = delete;
288 
289  Operator& operator=(const Operator& other) = delete;
290  Operator& operator=(Operator&& other) = delete;
291 
293  auto isInitialized() const { return _signature.has_value(); }
294 
300  auto hasOperands() const { return _signature->operands; }
301 
303  const auto& signature() const {
304  assert(_signature);
305  return *_signature;
306  }
307 
309  auto kind() const { return signature().kind; }
310 
315  auto isBuiltIn() const { return _builtin; }
316 
318  auto operands() const { return signature().operands->operands(); }
319 
321  auto op0() const { return operands()[0]; }
322 
324  auto op1() const { return operands()[1]; }
325 
327  auto op2() const { return operands()[2]; }
328 
330  const auto& meta() const { return _meta; }
331 
333  const auto& doc() const { return signature().doc; }
334 
339  auto typename_() const { return _typename(); }
340 
346  virtual QualifiedType* result(Builder* builder, const Expressions& operands, const Meta& meta) const;
347 
353  virtual std::optional<operator_::Operands> filter(Builder* builder, const Expressions& operands) const {
354  return {};
355  }
356 
361  virtual void validate(expression::ResolvedOperator* n) const {};
362 
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, parameter::Kind kind, UnqualifiedType* t,
401  std::string doc = "");
402 
409  static operator_::Operand* operandForExpression(Builder* builder, parameter::Kind kind, const Expressions& e,
410  size_t i) {
411  return operandForType(builder, kind, e[i]->type()->type(), "");
412  }
413 
414 private:
415  Meta _meta;
416  bool _builtin;
417  std::optional<operator_::detail::ProcessedSignature> _signature;
418 };
419 
424 class BuiltInMemberCall : public Operator {
425 public:
426  ~BuiltInMemberCall() override {}
427 
429  std::string print() const final;
430 };
431 
432 } // namespace hilti
Definition: builder.h:36
Definition: operator.h:424
std::string print() const final
Definition: operator.cc:343
Definition: expression.h:15
Definition: meta.h:30
Definition: node.h:240
Definition: operator.h:269
static operator_::Operand * operandForType(Builder *builder, parameter::Kind kind, UnqualifiedType *t, std::string doc="")
Definition: operator.cc:334
virtual QualifiedType * result(Builder *builder, const Expressions &operands, const Meta &meta) const
Definition: operator.cc:310
bool init(Builder *builder, Node *scope_root=nullptr)
Definition: operator.cc:209
Operator(Meta meta=Meta(), bool builtin=true)
Definition: operator.h:281
auto hasOperands() const
Definition: operator.h:300
static operator_::Operand * operandForExpression(Builder *builder, parameter::Kind kind, const Expressions &e, size_t i)
Definition: operator.h:409
auto isBuiltIn() const
Definition: operator.h:315
virtual std::optional< operator_::Operands > filter(Builder *builder, const Expressions &operands) const
Definition: operator.h:353
auto operands() const
Definition: operator.h:318
virtual std::string dump() const
Definition: operator.cc:326
virtual operator_::Signature signature(Builder *builder) const =0
auto op2() const
Definition: operator.h:327
auto kind() const
Definition: operator.h:309
const auto & signature() const
Definition: operator.h:303
auto op1() const
Definition: operator.h:324
virtual ~Operator()
Definition: operator.h:284
virtual std::string _typename() const
Definition: operator.h:392
auto isInitialized() const
Definition: operator.h:293
virtual std::string name() const =0
auto typename_() const
Definition: operator.h:339
const auto & doc() const
Definition: operator.h:333
virtual std::string print() const
Definition: operator.cc:319
const auto & meta() const
Definition: operator.h:330
virtual Result< expression::ResolvedOperator * > instantiate(Builder *builder, Expressions operands, Meta meta) const =0
virtual void validate(expression::ResolvedOperator *n) const
Definition: operator.h:361
auto op0() const
Definition: operator.h:321
Definition: type.h:362
Definition: type.h:148
Definition: resolved-operator.h:19
Definition: node.h:176
Definition: operator-registry.h:32
Definition: result.h:71
Definition: operand-list.h:18
void print(const T &t, const hilti::rt::TypeInfo *, bool newline=true)
Definition: hilti.h:23
Definition: operator.h:211
Expression * default_
Definition: operator.h:214
QType type
Definition: operator.h:213
std::string name
Definition: operator.h:212
bool optional
Definition: operator.h:215
Definition: operator.h:202
Constness constness
Definition: operator.h:203
std::string doc
Definition: operator.h:205
UnqualifiedType * type
Definition: operator.h:204
Definition: operator.h:186
parameter::Kind kind
Definition: operator.h:187
std::string doc
Definition: operator.h:189
UnqualifiedType * type
Definition: operator.h:188
UnqualifiedType * external_type
Definition: operator.h:190
Definition: operator.h:184
QResult result
Definition: operator.h:235
std::string result_doc
Definition: operator.h:236
std::string ns
Definition: operator.h:238
bool skip_doc
Definition: operator.h:240
std::string doc
Definition: operator.h:239
std::string result_doc
Definition: operator.h:253
std::string namespace_
Definition: operator.h:254
std::string doc
Definition: operator.h:252
node::RetainedPtr< QualifiedType > result
Definition: operator.h:249
node::RetainedPtr< type::OperandList > operands
Definition: operator.h:250
bool skip_doc
Definition: operator.h:255