blob: cc807a33bc47e4136159c4572c28ff1f5f3d830c [file] [log] [blame]
Ethan Nicholasfc994162019-06-06 10:04:27 -04001/*
2 * Copyright 2019 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SKSL_ASTNODE
9#define SKSL_ASTNODE
10
11#include "src/sksl/SkSLLexer.h"
12#include "src/sksl/SkSLString.h"
13#include "src/sksl/ir/SkSLModifiers.h"
14
Brian Osman5f46a272020-09-24 15:25:57 -040015#include <algorithm>
Ethan Nicholasfc994162019-06-06 10:04:27 -040016#include <vector>
17
18namespace SkSL {
19
Ethan Nicholasfc994162019-06-06 10:04:27 -040020/**
21 * Represents a node in the abstract syntax tree (AST). The AST is based directly on the parse tree;
22 * it is a parsed-but-not-yet-analyzed version of the program.
23 */
24struct ASTNode {
25 class ID {
26 public:
27 static ID Invalid() {
28 return ID();
29 }
30
31 bool operator==(const ID& other) {
32 return fValue == other.fValue;
33 }
34
35 bool operator!=(const ID& other) {
36 return fValue != other.fValue;
37 }
38
39 operator bool() const { return fValue >= 0; }
40
41 private:
42 ID()
43 : fValue(-1) {}
44
45 ID(int value)
46 : fValue(value) {}
47
48 int fValue;
49
50 friend struct ASTFile;
51 friend struct ASTNode;
52 friend class Parser;
53 };
54
55 enum class Kind {
56 // data: operator(Token), children: left, right
57 kBinary,
58 // children: statements
59 kBlock,
60 // data: value(bool)
61 kBool,
62 kBreak,
63 // children: target, arg1, arg2...
64 kCall,
65 kContinue,
66 kDiscard,
67 // children: statement, test
68 kDo,
69 // data: name(StringFragment), children: enumCases
70 kEnum,
71 // data: name(StringFragment), children: value?
72 kEnumCase,
73 // data: name(StringFragment)
74 kExtension,
75 // data: field(StringFragment), children: base
76 kField,
77 // children: declarations
78 kFile,
79 // data: value(float)
80 kFloat,
81 // children: init, test, next, statement
82 kFor,
83 // data: FunctionData, children: returnType, parameters, statement?
84 kFunction,
85 // data: name(StringFragment)
86 kIdentifier,
87 // children: base, index?
88 kIndex,
89 // data: isStatic(bool), children: test, ifTrue, ifFalse?
90 kIf,
91 // value(data): int
92 kInt,
93 // data: InterfaceBlockData, children: declaration1, declaration2, ..., size1, size2, ...
94 kInterfaceBlock,
95 // data: Modifiers
96 kModifiers,
97 kNull,
98 // data: ParameterData, children: type, arraySize1, arraySize2, ..., value?
99 kParameter,
100 // data: operator(Token), children: operand
101 kPostfix,
102 // data: operator(Token), children: operand
103 kPrefix,
104 // children: value
105 kReturn,
Brian Osman6518d772020-09-10 16:50:06 -0400106 // data: field(StringFragment), children: base
107 kScope,
Ethan Nicholasfc994162019-06-06 10:04:27 -0400108 // ...
109 kSection,
110 // children: value, statement 1, statement 2...
111 kSwitchCase,
112 // children: value, case 1, case 2...
113 kSwitch,
114 // children: test, ifTrue, ifFalse
115 kTernary,
116 // data: TypeData, children: sizes
117 kType,
118 // data: VarData, children: arraySize1, arraySize2, ..., value?
119 kVarDeclaration,
120 // children: modifiers, type, varDeclaration1, varDeclaration2, ...
121 kVarDeclarations,
122 // children: test, statement
123 kWhile,
124 };
125
126 class iterator {
127 public:
128 iterator operator++() {
129 SkASSERT(fID);
130 fID = (**this).fNext;
131 return *this;
132 }
133
134 iterator operator++(int) {
135 SkASSERT(fID);
136 iterator old = *this;
137 fID = (**this).fNext;
138 return old;
139 }
140
141 iterator operator+=(int count) {
142 SkASSERT(count >= 0);
143 for (; count > 0; --count) {
144 ++(*this);
145 }
146 return *this;
147 }
148
149 iterator operator+(int count) {
150 iterator result(*this);
151 return result += count;
152 }
153
154 bool operator==(const iterator& other) const {
155 return fID == other.fID;
156 }
157
158 bool operator!=(const iterator& other) const {
159 return fID != other.fID;
160 }
161
162 ASTNode& operator*() {
163 SkASSERT(fID);
164 return (*fNodes)[fID.fValue];
165 }
166
167 ASTNode* operator->() {
168 SkASSERT(fID);
169 return &(*fNodes)[fID.fValue];
170 }
171
172 private:
173 iterator(std::vector<ASTNode>* nodes, ID id)
174 : fNodes(nodes)
175 , fID(id) {}
176
177 std::vector<ASTNode>* fNodes;
178
179 ID fID;
180
181 friend struct ASTNode;
182 };
183
184 struct TypeData {
185 TypeData() {}
186
187 TypeData(StringFragment name, bool isStructDeclaration, bool isNullable)
188 : fName(name)
189 , fIsStructDeclaration(isStructDeclaration)
190 , fIsNullable(isNullable) {}
191
192 StringFragment fName;
193 bool fIsStructDeclaration;
194 bool fIsNullable;
195 };
196
197 struct ParameterData {
198 ParameterData() {}
199
John Stilesd39aec92020-12-03 14:37:16 -0500200 ParameterData(Modifiers modifiers, StringFragment name, bool isArray)
Ethan Nicholasfc994162019-06-06 10:04:27 -0400201 : fModifiers(modifiers)
202 , fName(name)
John Stilesd39aec92020-12-03 14:37:16 -0500203 , fIsArray(isArray) {}
Ethan Nicholasfc994162019-06-06 10:04:27 -0400204
205 Modifiers fModifiers;
206 StringFragment fName;
John Stilesd39aec92020-12-03 14:37:16 -0500207 bool fIsArray;
Ethan Nicholasfc994162019-06-06 10:04:27 -0400208 };
209
210 struct VarData {
211 VarData() {}
212
John Stilesd39aec92020-12-03 14:37:16 -0500213 VarData(StringFragment name, bool isArray)
Ethan Nicholasfc994162019-06-06 10:04:27 -0400214 : fName(name)
John Stilesd39aec92020-12-03 14:37:16 -0500215 , fIsArray(isArray) {}
Ethan Nicholasfc994162019-06-06 10:04:27 -0400216
217 StringFragment fName;
John Stilesd39aec92020-12-03 14:37:16 -0500218 bool fIsArray;
Ethan Nicholasfc994162019-06-06 10:04:27 -0400219 };
220
221 struct FunctionData {
222 FunctionData() {}
223
224 FunctionData(Modifiers modifiers, StringFragment name, size_t parameterCount)
225 : fModifiers(modifiers)
226 , fName(name)
227 , fParameterCount(parameterCount) {}
228
229 Modifiers fModifiers;
230 StringFragment fName;
231 size_t fParameterCount;
232 };
233
234 struct InterfaceBlockData {
235 InterfaceBlockData() {}
236
237 InterfaceBlockData(Modifiers modifiers, StringFragment typeName, size_t declarationCount,
John Stilesd39aec92020-12-03 14:37:16 -0500238 StringFragment instanceName, bool isArray)
Ethan Nicholasfc994162019-06-06 10:04:27 -0400239 : fModifiers(modifiers)
240 , fTypeName(typeName)
241 , fDeclarationCount(declarationCount)
242 , fInstanceName(instanceName)
John Stilesd39aec92020-12-03 14:37:16 -0500243 , fIsArray(isArray) {}
Ethan Nicholasfc994162019-06-06 10:04:27 -0400244
245 Modifiers fModifiers;
246 StringFragment fTypeName;
247 size_t fDeclarationCount;
248 StringFragment fInstanceName;
John Stilesd39aec92020-12-03 14:37:16 -0500249 bool fIsArray;
Ethan Nicholasfc994162019-06-06 10:04:27 -0400250 };
251
252 struct SectionData {
253 SectionData() {}
254
255 SectionData(StringFragment name, StringFragment argument, StringFragment text)
256 : fName(name)
257 , fArgument(argument)
258 , fText(text) {}
259
260 StringFragment fName;
261 StringFragment fArgument;
262 StringFragment fText;
263 };
264
265 struct NodeData {
Ethan Nicholasc8d9c8e2020-09-22 15:05:37 -0400266 char fBytes[std::max({sizeof(Token),
267 sizeof(StringFragment),
268 sizeof(bool),
269 sizeof(SKSL_INT),
270 sizeof(SKSL_FLOAT),
271 sizeof(Modifiers),
272 sizeof(TypeData),
273 sizeof(FunctionData),
274 sizeof(ParameterData),
275 sizeof(VarData),
276 sizeof(InterfaceBlockData),
277 sizeof(SectionData)})];
Ethan Nicholasfc994162019-06-06 10:04:27 -0400278
279 enum class Kind {
280 kToken,
281 kStringFragment,
282 kBool,
283 kInt,
284 kFloat,
285 kModifiers,
286 kTypeData,
287 kFunctionData,
288 kParameterData,
289 kVarData,
290 kInterfaceBlockData,
291 kSectionData
292 } fKind;
293
294 NodeData() = default;
295
296 NodeData(Token data)
297 : fKind(Kind::kToken) {
298 memcpy(fBytes, &data, sizeof(data));
299 }
300
301 NodeData(StringFragment data)
302 : fKind(Kind::kStringFragment) {
303 memcpy(fBytes, &data, sizeof(data));
304 }
305
306 NodeData(bool data)
307 : fKind(Kind::kBool) {
308 memcpy(fBytes, &data, sizeof(data));
309 }
310
311 NodeData(SKSL_INT data)
312 : fKind(Kind::kInt) {
313 memcpy(fBytes, &data, sizeof(data));
314 }
315
316 NodeData(SKSL_FLOAT data)
317 : fKind(Kind::kFloat) {
318 memcpy(fBytes, &data, sizeof(data));
319 }
320
321 NodeData(Modifiers data)
322 : fKind(Kind::kModifiers) {
323 memcpy(fBytes, &data, sizeof(data));
324 }
325
326 NodeData(TypeData data)
327 : fKind(Kind::kTypeData) {
328 memcpy(fBytes, &data, sizeof(data));
329 }
330
331 NodeData(FunctionData data)
332 : fKind(Kind::kFunctionData) {
333 memcpy(fBytes, &data, sizeof(data));
334 }
335
336 NodeData(VarData data)
337 : fKind(Kind::kVarData) {
338 memcpy(fBytes, &data, sizeof(data));
339 }
340
341 NodeData(ParameterData data)
342 : fKind(Kind::kParameterData) {
343 memcpy(fBytes, &data, sizeof(data));
344 }
345
346 NodeData(InterfaceBlockData data)
347 : fKind(Kind::kInterfaceBlockData) {
348 memcpy(fBytes, &data, sizeof(data));
349 }
350
351 NodeData(SectionData data)
352 : fKind(Kind::kSectionData) {
353 memcpy(fBytes, &data, sizeof(data));
354 }
355 };
356
357 ASTNode()
358 : fOffset(-1)
359 , fKind(Kind::kNull) {}
360
361 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind)
362 : fNodes(nodes)
363 , fOffset(offset)
364 , fKind(kind) {
365 switch (kind) {
366 case Kind::kBinary:
367 case Kind::kPostfix:
368 case Kind::kPrefix:
369 fData.fKind = NodeData::Kind::kToken;
370 break;
371
372 case Kind::kBool:
373 case Kind::kIf:
374 case Kind::kSwitch:
375 fData.fKind = NodeData::Kind::kBool;
376 break;
377
378 case Kind::kEnum:
379 case Kind::kEnumCase:
380 case Kind::kExtension:
381 case Kind::kField:
382 case Kind::kIdentifier:
Brian Osman6518d772020-09-10 16:50:06 -0400383 case Kind::kScope:
Ethan Nicholasfc994162019-06-06 10:04:27 -0400384 fData.fKind = NodeData::Kind::kStringFragment;
385 break;
386
387 case Kind::kFloat:
388 fData.fKind = NodeData::Kind::kFloat;
389 break;
390
391 case Kind::kFunction:
392 fData.fKind = NodeData::Kind::kFunctionData;
393 break;
394
395 case Kind::kInt:
396 fData.fKind = NodeData::Kind::kInt;
397 break;
398
399 case Kind::kInterfaceBlock:
400 fData.fKind = NodeData::Kind::kInterfaceBlockData;
401 break;
402
403 case Kind::kModifiers:
404 fData.fKind = NodeData::Kind::kModifiers;
405 break;
406
407 case Kind::kParameter:
408 fData.fKind = NodeData::Kind::kParameterData;
409 break;
410
411 case Kind::kVarDeclaration:
412 fData.fKind = NodeData::Kind::kVarData;
413 break;
414
415 case Kind::kType:
416 fData.fKind = NodeData::Kind::kTypeData;
417 break;
418
419 default:
420 break;
421 }
422 }
423
424 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, Token t)
425 : fNodes(nodes)
426 , fData(t)
427 , fOffset(offset)
428 , fKind(kind) {}
429
430 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, StringFragment s)
431 : fNodes(nodes)
432 , fData(s)
433 , fOffset(offset)
434 , fKind(kind) {}
435
436 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, const char* s)
437 : fNodes(nodes)
438 , fData(StringFragment(s))
439 , fOffset(offset)
440 , fKind(kind) {}
441
442 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, bool b)
443 : fNodes(nodes)
444 , fData(b)
445 , fOffset(offset)
446 , fKind(kind) {}
447
448 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SKSL_INT i)
449 : fNodes(nodes)
450 , fData(i)
451 , fOffset(offset)
452 , fKind(kind) {}
453
454 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SKSL_FLOAT f)
455 : fNodes(nodes)
456 , fData(f)
457 , fOffset(offset)
458 , fKind(kind) {}
459
460 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, Modifiers m)
461 : fNodes(nodes)
462 , fData(m)
463 , fOffset(offset)
464 , fKind(kind) {}
465
466 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, TypeData td)
467 : fNodes(nodes)
468 , fData(td)
469 , fOffset(offset)
470 , fKind(kind) {}
471
472 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SectionData s)
473 : fNodes(nodes)
474 , fData(s)
475 , fOffset(offset)
476 , fKind(kind) {}
477
478 operator bool() const {
479 return fKind != Kind::kNull;
480 }
481
482 Token getToken() const {
483 SkASSERT(fData.fKind == NodeData::Kind::kToken);
484 Token result;
485 memcpy(&result, fData.fBytes, sizeof(result));
486 return result;
487 }
488
489 bool getBool() const {
490 SkASSERT(fData.fKind == NodeData::Kind::kBool);
491 bool result;
492 memcpy(&result, fData.fBytes, sizeof(result));
493 return result;
494 }
495
496 SKSL_INT getInt() const {
497 SkASSERT(fData.fKind == NodeData::Kind::kInt);
498 SKSL_INT result;
499 memcpy(&result, fData.fBytes, sizeof(result));
500 return result;
501 }
502
503 SKSL_FLOAT getFloat() const {
504 SkASSERT(fData.fKind == NodeData::Kind::kFloat);
505 SKSL_FLOAT result;
506 memcpy(&result, fData.fBytes, sizeof(result));
507 return result;
508 }
509
510 StringFragment getString() const {
511 SkASSERT(fData.fKind == NodeData::Kind::kStringFragment);
512 StringFragment result;
513 memcpy(&result, fData.fBytes, sizeof(result));
514 return result;
515 }
516
517 Modifiers getModifiers() const {
518 SkASSERT(fData.fKind == NodeData::Kind::kModifiers);
519 Modifiers result;
520 memcpy(&result, fData.fBytes, sizeof(result));
521 return result;
522 }
523
524 void setModifiers(const Modifiers& m) {
525 memcpy(fData.fBytes, &m, sizeof(m));
526 }
527
528 TypeData getTypeData() const {
529 SkASSERT(fData.fKind == NodeData::Kind::kTypeData);
530 TypeData result;
531 memcpy(&result, fData.fBytes, sizeof(result));
532 return result;
533 }
534
535 void setTypeData(const ASTNode::TypeData& td) {
536 SkASSERT(fData.fKind == NodeData::Kind::kTypeData);
537 memcpy(fData.fBytes, &td, sizeof(td));
538 }
539
540 ParameterData getParameterData() const {
541 SkASSERT(fData.fKind == NodeData::Kind::kParameterData);
542 ParameterData result;
543 memcpy(&result, fData.fBytes, sizeof(result));
544 return result;
545 }
546
547 void setParameterData(const ASTNode::ParameterData& pd) {
548 SkASSERT(fData.fKind == NodeData::Kind::kParameterData);
549 memcpy(fData.fBytes, &pd, sizeof(pd));
550 }
551
552 VarData getVarData() const {
553 SkASSERT(fData.fKind == NodeData::Kind::kVarData);
554 VarData result;
555 memcpy(&result, fData.fBytes, sizeof(result));
556 return result;
557 }
558
559 void setVarData(const ASTNode::VarData& vd) {
560 SkASSERT(fData.fKind == NodeData::Kind::kVarData);
561 memcpy(fData.fBytes, &vd, sizeof(vd));
562 }
563
564 FunctionData getFunctionData() const {
565 SkASSERT(fData.fKind == NodeData::Kind::kFunctionData);
566 FunctionData result;
567 memcpy(&result, fData.fBytes, sizeof(result));
568 return result;
569 }
570
571 void setFunctionData(const ASTNode::FunctionData& fd) {
572 SkASSERT(fData.fKind == NodeData::Kind::kFunctionData);
573 memcpy(fData.fBytes, &fd, sizeof(fd));
574 }
575
576 InterfaceBlockData getInterfaceBlockData() const {
577 SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlockData);
578 InterfaceBlockData result;
579 memcpy(&result, fData.fBytes, sizeof(result));
580 return result;
581 }
582
583 void setInterfaceBlockData(const ASTNode::InterfaceBlockData& id) {
584 SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlockData);
585 memcpy(fData.fBytes, &id, sizeof(id));
586 }
587
588 SectionData getSectionData() const {
589 SkASSERT(fData.fKind == NodeData::Kind::kSectionData);
590 SectionData result;
591 memcpy(&result, fData.fBytes, sizeof(result));
592 return result;
593 }
594
595 void addChild(ID id) {
596 SkASSERT(!(*fNodes)[id.fValue].fNext);
597 if (fLastChild) {
598 SkASSERT(!(*fNodes)[fLastChild.fValue].fNext);
599 (*fNodes)[fLastChild.fValue].fNext = id;
600 } else {
601 fFirstChild = id;
602 }
603 fLastChild = id;
604 SkASSERT(!(*fNodes)[fLastChild.fValue].fNext);
605 }
606
607 iterator begin() const {
608 return iterator(fNodes, fFirstChild);
609 }
610
611 iterator end() const {
612 return iterator(fNodes, ID(-1));
613 }
614
Ethan Nicholas2a099da2020-01-02 14:40:54 -0500615#ifdef SK_DEBUG
Ethan Nicholasfc994162019-06-06 10:04:27 -0400616 String description() const;
Ethan Nicholas2a099da2020-01-02 14:40:54 -0500617#endif
Ethan Nicholasfc994162019-06-06 10:04:27 -0400618
619 std::vector<ASTNode>* fNodes;
620
621 NodeData fData;
622
623 int fOffset;
624
625 Kind fKind;
626
627 ID fFirstChild;
628
629 ID fLastChild;
630
631 ID fNext;
632};
633
John Stilesa6841be2020-08-06 14:11:56 -0400634} // namespace SkSL
Ethan Nicholasfc994162019-06-06 10:04:27 -0400635
636#endif