Spicy
keyword.h
1 // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <utility>
6 
7 #include <hilti/ast/declaration.h>
8 #include <hilti/ast/declarations/expression.h>
9 #include <hilti/ast/expression.h>
10 #include <hilti/ast/type.h>
11 #include <hilti/ast/types/auto.h>
12 
13 namespace hilti::expression {
14 
15 namespace keyword {
16 // Type of a reserved keyword
17 enum class Kind {
18  Self,
19  DollarDollar,
20  Captures,
21  Scope
22 };
23 
24 namespace detail {
25 constexpr util::enum_::Value<Kind> Kinds[] = {{.value = Kind::Self, .name = "self"},
26  {.value = Kind::DollarDollar, .name = "$$"},
27  {.value = Kind::Captures, .name = "$@"},
28  {.value = Kind::Scope, .name = "$scope"}};
29 } // namespace detail
30 
31 namespace kind {
32 constexpr auto from_string(std::string_view s) { return util::enum_::from_string<Kind>(s, detail::Kinds); }
33 } // namespace kind
34 
35 constexpr auto to_string(Kind m) { return util::enum_::to_string(m, detail::Kinds); }
36 
37 } // namespace keyword
38 
40 class Keyword : public Expression {
41 public:
42  keyword::Kind kind() const { return _kind; }
43  void setType(ASTContext* ctx, QualifiedType* t) { setChild(ctx, 0, t); }
44 
45  QualifiedType* type() const final { return child<QualifiedType>(0); }
46 
47  node::Properties properties() const final {
48  auto p = node::Properties{{{"kind", to_string(_kind)}}};
49  return Expression::properties() + std::move(p);
50  }
51 
52  static auto create(ASTContext* ctx, keyword::Kind kind, QualifiedType* type, Meta meta = {}) {
53  return ctx->make<Keyword>(ctx, {type}, kind, std::move(meta));
54  }
55 
56  static auto create(ASTContext* ctx, keyword::Kind kind, const Meta& meta = {}) {
57  return create(ctx, kind, QualifiedType::createAuto(ctx, meta), meta);
58  }
59 
62  auto* kw = create(ctx, keyword::Kind::DollarDollar, type);
63  return declaration::Expression::create(ctx, ID("__dd"), kw, hilti::declaration::Linkage::Private);
64  }
65 
66 protected:
67  Keyword(ASTContext* ctx, Nodes children, keyword::Kind kind, Meta meta)
68  : Expression(ctx, NodeTags, std::move(children), std::move(meta)), _kind(kind) {}
69 
70  HILTI_NODE_1(expression::Keyword, Expression, final);
71 
72 private:
73  keyword::Kind _kind;
74 };
75 
76 inline std::ostream& operator<<(std::ostream& stream, const Keyword& keyword) {
77  switch ( keyword.kind() ) {
78  case keyword::Kind::Self: return stream << "<self>";
79  case keyword::Kind::DollarDollar: return stream << "<$$>";
80  case keyword::Kind::Captures: return stream << "<captures>";
81  case keyword::Kind::Scope: return stream << "<scope>";
82  }
83 
84  return stream;
85 }
86 
87 } // namespace hilti::expression
Definition: ast-context.h:121
T * make(Args &&... args)
Definition: ast-context.h:366
Definition: expression.h:15
Definition: id.h:15
Definition: meta.h:30
void setChild(ASTContext *ctx, size_t idx, Node *n)
Definition: node.h:602
const auto & children() const
Definition: node.h:364
const auto & meta() const
Definition: node.h:306
virtual node::Properties properties() const
Definition: node.h:891
Definition: forward.h:758
Definition: type.h:362
static QualifiedType * createAuto(ASTContext *ctx, const Meta &m=Meta())
Definition: type.cc:121
Definition: keyword.h:40
QualifiedType * type() const final
Definition: keyword.h:45
static auto createDollarDollarDeclaration(ASTContext *ctx, QualifiedType *type)
Definition: keyword.h:61
node::Properties properties() const final
Definition: keyword.h:47