nixd
Loading...
Searching...
No Matches
Attrs.h
Go to the documentation of this file.
1#pragma once
2
3#include "Basic.h"
4#include "Simple.h"
5
6#include <map>
7
8namespace nixf {
9
10class AttrName : public Node {
11public:
13
14private:
15 const AttrNameKind Kind;
16 const std::shared_ptr<Identifier> ID;
17 const std::shared_ptr<ExprString> String;
18 const std::shared_ptr<Interpolation> Interp;
19
20public:
21 [[nodiscard]] AttrNameKind kind() const { return Kind; }
22
23 AttrName(std::shared_ptr<Identifier> ID, LexerCursorRange Range)
24 : Node(NK_AttrName, Range), Kind(ANK_ID), ID(std::move(ID)) {
25 assert(this->ID && "ID must not be null");
26 }
27
28 AttrName(std::shared_ptr<ExprString> String)
29 : Node(NK_AttrName, String->range()), Kind(ANK_String),
30 String(std::move(String)) {
31 assert(this->String && "String must not be null");
32 }
33
34 AttrName(std::shared_ptr<Interpolation> Interp)
35 : Node(NK_AttrName, Interp->range()), Kind(ANK_Interpolation),
36 Interp(std::move(Interp)) {
37 assert(this->Interp && "Interpolation must not be null");
38 }
39
40 [[nodiscard]] bool isStatic() const {
41 if (Kind == ANK_ID)
42 return true;
43 if (Kind == ANK_Interpolation)
44 return false;
45
46 assert(Kind == ANK_String);
47 return string().isLiteral();
48 }
49
50 [[nodiscard]] const std::string &staticName() const {
51 assert(isStatic() && "must be static");
52 if (Kind == ANK_ID)
53 return id()->name();
54 assert(Kind == ANK_String);
55 return string().literal();
56 }
57
58 [[nodiscard]] const Interpolation &interpolation() const {
59 assert(Kind == ANK_Interpolation);
60 assert(Interp && "Interpolation must not be null");
61 return *Interp;
62 }
63
64 [[nodiscard]] const std::shared_ptr<Identifier> &id() const {
65 assert(Kind == ANK_ID);
66 return ID;
67 }
68
69 [[nodiscard]] const ExprString &string() const {
70 assert(Kind == ANK_String);
71 assert(String && "String must not be null");
72 return *String;
73 }
74
75 [[nodiscard]] ChildVector children() const override {
76 switch (Kind) {
77 case ANK_ID:
78 return {ID.get()};
79 case ANK_String:
80 return {String.get()};
82 return {Interp.get()};
83 default:
84 assert(false && "invalid AttrNameKind");
85 }
86 __builtin_unreachable();
87 }
88};
89
90class AttrPath : public Node {
91 const std::vector<std::shared_ptr<AttrName>> Names;
92 const std::vector<std::shared_ptr<Dot>> Dots;
93
94public:
95 AttrPath(LexerCursorRange Range, std::vector<std::shared_ptr<AttrName>> Names,
96 std::vector<std::shared_ptr<Dot>> Dots)
97 : Node(NK_AttrPath, Range), Names(std::move(Names)),
98 Dots(std::move(Dots)) {}
99
100 [[nodiscard]] const std::vector<std::shared_ptr<AttrName>> &names() const {
101 return Names;
102 }
103
104 [[nodiscard]] ChildVector children() const override {
105 ChildVector Children;
106 Children.reserve(Names.size() + Dots.size());
107 for (const auto &Name : Names)
108 Children.push_back(Name.get());
109 for (const auto &Dot : Dots)
110 Children.emplace_back(Dot.get());
111 return Children;
112 }
113};
114
115class Binding : public Node {
116 const std::shared_ptr<AttrPath> Path;
117 const std::shared_ptr<Expr> Value;
118 // Represents the '=' token in the syntax tree
119 // preserving its position and presence.
120 const std::shared_ptr<Misc> Eq;
121
122public:
123 Binding(LexerCursorRange Range, std::shared_ptr<AttrPath> Path,
124 std::shared_ptr<Expr> Value, std::shared_ptr<Misc> Eq)
125 : Node(NK_Binding, Range), Path(std::move(Path)), Value(std::move(Value)),
126 Eq(std::move(Eq)) {
127 assert(this->Path && "Path must not be null");
128 // Value can be null, if missing in the syntax.
129 }
130
131 [[nodiscard]] const AttrPath &path() const {
132 assert(Path && "Path must not be null");
133 return *Path;
134 }
135
136 [[nodiscard]] const std::shared_ptr<Expr> &value() const { return Value; }
137
138 [[nodiscard]] const std::shared_ptr<Misc> &eq() const { return Eq; }
139
140 [[nodiscard]] ChildVector children() const override {
141 return {Path.get(), Eq.get(), Value.get()};
142 }
143};
144
145class Inherit : public Node {
146 const std::vector<std::shared_ptr<AttrName>> Names;
147 const std::shared_ptr<Expr> E;
148
149public:
150 Inherit(LexerCursorRange Range, std::vector<std::shared_ptr<AttrName>> Names,
151 std::shared_ptr<Expr> E)
152 : Node(NK_Inherit, Range), Names(std::move(Names)), E(std::move(E)) {}
153
154 [[nodiscard]] const std::vector<std::shared_ptr<AttrName>> &names() const {
155 return Names;
156 }
157
158 [[nodiscard]] bool hasExpr() { return E != nullptr; }
159
160 [[nodiscard]] const std::shared_ptr<Expr> &expr() const { return E; }
161
162 [[nodiscard]] ChildVector children() const override {
163 ChildVector Children;
164 Children.reserve(Names.size() + 1);
165 for (const auto &Name : Names) {
166 Children.push_back(Name.get());
167 }
168 Children.push_back(E.get());
169 return Children;
170 }
171};
172
173class Binds : public Node {
174 const std::vector<std::shared_ptr<Node>> Bindings;
175
176public:
177 Binds(LexerCursorRange Range, std::vector<std::shared_ptr<Node>> Bindings)
178 : Node(NK_Binds, Range), Bindings(std::move(Bindings)) {}
179
180 [[nodiscard]] const std::vector<std::shared_ptr<Node>> &bindings() const {
181 return Bindings;
182 }
183
184 [[nodiscard]] ChildVector children() const override {
185 ChildVector Children;
186 Children.reserve(Bindings.size());
187 for (const auto &Binding : Bindings) {
188 Children.push_back(Binding.get());
189 }
190 return Children;
191 }
192};
193
195public:
196 enum class AttributeKind {
197 /// a = b;
199 /// inherit a b c;
201 /// inherit (expr) a b c
203 };
204
205private:
206 const std::shared_ptr<Node> Key;
207 const std::shared_ptr<Expr> Value;
208 AttributeKind Kind;
209
210public:
211 Attribute(std::shared_ptr<Node> Key, std::shared_ptr<Expr> Value,
212 AttributeKind Kind)
213 : Key(std::move(Key)), Value(std::move(Value)), Kind(Kind) {
214 assert(this->Key && "Key must not be null");
215 }
216
217 [[nodiscard]] Node &key() const { return *Key; }
218
219 [[nodiscard]] Expr *value() const { return Value.get(); }
220
221 [[nodiscard]] AttributeKind kind() const { return Kind; }
222
223 [[nodiscard]] bool fromInherit() const {
224 return Kind == AttributeKind::InheritFrom || Kind == AttributeKind::Inherit;
225 }
226};
227
228/// \brief Attribute set after deduplication.
229///
230/// Represeting the attribute set suitable for variable lookups, evaluation.
231///
232/// The attrset cannot have duplicate keys, and keys will be desugared to strict
233/// K-V form.
234///
235/// e.g. `{ a.b.c = 1 }` -> `{ a = { b = { c = 1; }; }; }`
237private:
238 // These fields are in-complete during semantic analysis.
239 // So they explicitly marked as mutable
240 /*mutable*/ std::map<std::string, Attribute> Static;
241 /*mutable*/ std::vector<Attribute> Dynamic;
242
243 const Misc *Recursive;
244
245 friend class Sema;
246
247public:
248 SemaAttrs(Misc *Recursive) : Recursive(Recursive) {}
249 SemaAttrs(std::map<std::string, Attribute> Static,
250 std::vector<Attribute> Dynamic, Misc *Recursive)
251 : Static(std::move(Static)), Dynamic(std::move(Dynamic)),
252 Recursive(Recursive) {}
253
254 /// \brief Static attributes, do not require evaluation to get the key.
255 ///
256 /// e.g. `{ a = 1; b = 2; }`
257 [[nodiscard]] const std::map<std::string, Attribute> &staticAttrs() const {
258 return Static;
259 }
260
261 /// \brief Dynamic attributes, require evaluation to get the key.
262 ///
263 /// e.g. `{ "${asdasda}" = "asdasd"; }`
264 [[nodiscard]] const std::vector<Attribute> &dynamicAttrs() const {
265 return Dynamic;
266 }
267
268 /// \brief If the attribute set is `rec`.
269 [[nodiscard]] bool isRecursive() const { return Recursive; }
270};
271
272class ExprAttrs : public Expr {
273 const std::shared_ptr<Binds> Body;
274 const std::shared_ptr<Misc> Rec;
275 SemaAttrs SA; // Let this mutable for "Sema" class only.
276 friend class Sema;
277
278public:
279 ExprAttrs(LexerCursorRange Range, std::shared_ptr<Binds> Body,
280 std::shared_ptr<Misc> Rec, SemaAttrs SA)
281 : Expr(NK_ExprAttrs, Range), Body(std::move(Body)), Rec(std::move(Rec)),
282 SA(std::move(SA)) {}
283
284 [[nodiscard]] const Binds *binds() const { return Body.get(); }
285 [[nodiscard]] const Misc *rec() const { return Rec.get(); }
286
287 [[nodiscard]] bool isRecursive() const { return Rec != nullptr; }
288
289 [[nodiscard]] const SemaAttrs &sema() const { return SA; }
290
291 [[nodiscard]] ChildVector children() const override {
292 return {Body.get(), Rec.get()};
293 }
294};
295
296} // namespace nixf
const std::string & staticName() const
Definition Attrs.h:50
AttrName(std::shared_ptr< Interpolation > Interp)
Definition Attrs.h:34
const std::shared_ptr< Identifier > & id() const
Definition Attrs.h:64
AttrName(std::shared_ptr< ExprString > String)
Definition Attrs.h:28
AttrNameKind kind() const
Definition Attrs.h:21
const ExprString & string() const
Definition Attrs.h:69
bool isStatic() const
Definition Attrs.h:40
const Interpolation & interpolation() const
Definition Attrs.h:58
ChildVector children() const override
Definition Attrs.h:75
@ ANK_Interpolation
Definition Attrs.h:12
AttrName(std::shared_ptr< Identifier > ID, LexerCursorRange Range)
Definition Attrs.h:23
AttrPath(LexerCursorRange Range, std::vector< std::shared_ptr< AttrName > > Names, std::vector< std::shared_ptr< Dot > > Dots)
Definition Attrs.h:95
ChildVector children() const override
Definition Attrs.h:104
const std::vector< std::shared_ptr< AttrName > > & names() const
Definition Attrs.h:100
Node & key() const
Definition Attrs.h:217
Expr * value() const
Definition Attrs.h:219
AttributeKind kind() const
Definition Attrs.h:221
bool fromInherit() const
Definition Attrs.h:223
@ InheritFrom
inherit (expr) a b c
Definition Attrs.h:202
@ Inherit
inherit a b c;
Definition Attrs.h:200
Attribute(std::shared_ptr< Node > Key, std::shared_ptr< Expr > Value, AttributeKind Kind)
Definition Attrs.h:211
Binding(LexerCursorRange Range, std::shared_ptr< AttrPath > Path, std::shared_ptr< Expr > Value, std::shared_ptr< Misc > Eq)
Definition Attrs.h:123
const AttrPath & path() const
Definition Attrs.h:131
ChildVector children() const override
Definition Attrs.h:140
const std::shared_ptr< Misc > & eq() const
Definition Attrs.h:138
const std::shared_ptr< Expr > & value() const
Definition Attrs.h:136
ChildVector children() const override
Definition Attrs.h:184
Binds(LexerCursorRange Range, std::vector< std::shared_ptr< Node > > Bindings)
Definition Attrs.h:177
const std::vector< std::shared_ptr< Node > > & bindings() const
Definition Attrs.h:180
Holds a "." in the language.
Definition Basic.h:126
bool isRecursive() const
Definition Attrs.h:287
ChildVector children() const override
Definition Attrs.h:291
friend class Sema
Definition Attrs.h:276
const SemaAttrs & sema() const
Definition Attrs.h:289
const Misc * rec() const
Definition Attrs.h:285
ExprAttrs(LexerCursorRange Range, std::shared_ptr< Binds > Body, std::shared_ptr< Misc > Rec, SemaAttrs SA)
Definition Attrs.h:279
const Binds * binds() const
Definition Attrs.h:284
bool isLiteral() const
Definition Simple.h:130
const std::string & literal() const
Definition Simple.h:135
Expr(NodeKind Kind, LexerCursorRange Range)
Definition Basic.h:72
const std::shared_ptr< Expr > & expr() const
Definition Attrs.h:160
const std::vector< std::shared_ptr< AttrName > > & names() const
Definition Attrs.h:154
ChildVector children() const override
Definition Attrs.h:162
bool hasExpr()
Definition Attrs.h:158
Inherit(LexerCursorRange Range, std::vector< std::shared_ptr< AttrName > > Names, std::shared_ptr< Expr > E)
Definition Attrs.h:150
${expr} construct
Definition Simple.h:38
Misc node, used for parentheses, keywords, etc.
Definition Basic.h:106
boost::container::small_vector< Node *, 8 > ChildVector
Definition Basic.h:42
LexerCursorRange range() const
Definition Basic.h:35
Node(NodeKind Kind, LexerCursorRange Range)
Definition Basic.h:30
Attribute set after deduplication.
Definition Attrs.h:236
SemaAttrs(std::map< std::string, Attribute > Static, std::vector< Attribute > Dynamic, Misc *Recursive)
Definition Attrs.h:249
friend class Sema
Definition Attrs.h:245
SemaAttrs(Misc *Recursive)
Definition Attrs.h:248
bool isRecursive() const
If the attribute set is rec.
Definition Attrs.h:269
const std::vector< Attribute > & dynamicAttrs() const
Dynamic attributes, require evaluation to get the key.
Definition Attrs.h:264
const std::map< std::string, Attribute > & staticAttrs() const
Static attributes, do not require evaluation to get the key.
Definition Attrs.h:257