blob: 66360a9035243d52a1a293ba921ab05cc64bd643 [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
Brian Osmancaca7bf2020-12-23 14:30:04 -0500187 TypeData(StringFragment name, bool isStructDeclaration)
Ethan Nicholasfc994162019-06-06 10:04:27 -0400188 : fName(name)
Brian Osmancaca7bf2020-12-23 14:30:04 -0500189 , fIsStructDeclaration(isStructDeclaration) {}
Ethan Nicholasfc994162019-06-06 10:04:27 -0400190
191 StringFragment fName;
192 bool fIsStructDeclaration;
Ethan Nicholasfc994162019-06-06 10:04:27 -0400193 };
194
195 struct ParameterData {
196 ParameterData() {}
197
John Stilesd39aec92020-12-03 14:37:16 -0500198 ParameterData(Modifiers modifiers, StringFragment name, bool isArray)
Ethan Nicholasfc994162019-06-06 10:04:27 -0400199 : fModifiers(modifiers)
200 , fName(name)
John Stilesd39aec92020-12-03 14:37:16 -0500201 , fIsArray(isArray) {}
Ethan Nicholasfc994162019-06-06 10:04:27 -0400202
203 Modifiers fModifiers;
204 StringFragment fName;
John Stilesd39aec92020-12-03 14:37:16 -0500205 bool fIsArray;
Ethan Nicholasfc994162019-06-06 10:04:27 -0400206 };
207
208 struct VarData {
209 VarData() {}
210
John Stilesd39aec92020-12-03 14:37:16 -0500211 VarData(StringFragment name, bool isArray)
Ethan Nicholasfc994162019-06-06 10:04:27 -0400212 : fName(name)
John Stilesd39aec92020-12-03 14:37:16 -0500213 , fIsArray(isArray) {}
Ethan Nicholasfc994162019-06-06 10:04:27 -0400214
215 StringFragment fName;
John Stilesd39aec92020-12-03 14:37:16 -0500216 bool fIsArray;
Ethan Nicholasfc994162019-06-06 10:04:27 -0400217 };
218
219 struct FunctionData {
220 FunctionData() {}
221
222 FunctionData(Modifiers modifiers, StringFragment name, size_t parameterCount)
223 : fModifiers(modifiers)
224 , fName(name)
225 , fParameterCount(parameterCount) {}
226
227 Modifiers fModifiers;
228 StringFragment fName;
229 size_t fParameterCount;
230 };
231
232 struct InterfaceBlockData {
233 InterfaceBlockData() {}
234
235 InterfaceBlockData(Modifiers modifiers, StringFragment typeName, size_t declarationCount,
John Stilesd39aec92020-12-03 14:37:16 -0500236 StringFragment instanceName, bool isArray)
Ethan Nicholasfc994162019-06-06 10:04:27 -0400237 : fModifiers(modifiers)
238 , fTypeName(typeName)
239 , fDeclarationCount(declarationCount)
240 , fInstanceName(instanceName)
John Stilesd39aec92020-12-03 14:37:16 -0500241 , fIsArray(isArray) {}
Ethan Nicholasfc994162019-06-06 10:04:27 -0400242
243 Modifiers fModifiers;
244 StringFragment fTypeName;
245 size_t fDeclarationCount;
246 StringFragment fInstanceName;
John Stilesd39aec92020-12-03 14:37:16 -0500247 bool fIsArray;
Ethan Nicholasfc994162019-06-06 10:04:27 -0400248 };
249
250 struct SectionData {
251 SectionData() {}
252
253 SectionData(StringFragment name, StringFragment argument, StringFragment text)
254 : fName(name)
255 , fArgument(argument)
256 , fText(text) {}
257
258 StringFragment fName;
259 StringFragment fArgument;
260 StringFragment fText;
261 };
262
263 struct NodeData {
Ethan Nicholasc8d9c8e2020-09-22 15:05:37 -0400264 char fBytes[std::max({sizeof(Token),
265 sizeof(StringFragment),
266 sizeof(bool),
267 sizeof(SKSL_INT),
268 sizeof(SKSL_FLOAT),
269 sizeof(Modifiers),
270 sizeof(TypeData),
271 sizeof(FunctionData),
272 sizeof(ParameterData),
273 sizeof(VarData),
274 sizeof(InterfaceBlockData),
275 sizeof(SectionData)})];
Ethan Nicholasfc994162019-06-06 10:04:27 -0400276
277 enum class Kind {
278 kToken,
279 kStringFragment,
280 kBool,
281 kInt,
282 kFloat,
283 kModifiers,
284 kTypeData,
285 kFunctionData,
286 kParameterData,
287 kVarData,
288 kInterfaceBlockData,
289 kSectionData
290 } fKind;
291
292 NodeData() = default;
293
294 NodeData(Token data)
295 : fKind(Kind::kToken) {
296 memcpy(fBytes, &data, sizeof(data));
297 }
298
299 NodeData(StringFragment data)
300 : fKind(Kind::kStringFragment) {
301 memcpy(fBytes, &data, sizeof(data));
302 }
303
304 NodeData(bool data)
305 : fKind(Kind::kBool) {
306 memcpy(fBytes, &data, sizeof(data));
307 }
308
309 NodeData(SKSL_INT data)
310 : fKind(Kind::kInt) {
311 memcpy(fBytes, &data, sizeof(data));
312 }
313
314 NodeData(SKSL_FLOAT data)
315 : fKind(Kind::kFloat) {
316 memcpy(fBytes, &data, sizeof(data));
317 }
318
319 NodeData(Modifiers data)
320 : fKind(Kind::kModifiers) {
321 memcpy(fBytes, &data, sizeof(data));
322 }
323
324 NodeData(TypeData data)
325 : fKind(Kind::kTypeData) {
326 memcpy(fBytes, &data, sizeof(data));
327 }
328
329 NodeData(FunctionData data)
330 : fKind(Kind::kFunctionData) {
331 memcpy(fBytes, &data, sizeof(data));
332 }
333
334 NodeData(VarData data)
335 : fKind(Kind::kVarData) {
336 memcpy(fBytes, &data, sizeof(data));
337 }
338
339 NodeData(ParameterData data)
340 : fKind(Kind::kParameterData) {
341 memcpy(fBytes, &data, sizeof(data));
342 }
343
344 NodeData(InterfaceBlockData data)
345 : fKind(Kind::kInterfaceBlockData) {
346 memcpy(fBytes, &data, sizeof(data));
347 }
348
349 NodeData(SectionData data)
350 : fKind(Kind::kSectionData) {
351 memcpy(fBytes, &data, sizeof(data));
352 }
353 };
354
355 ASTNode()
356 : fOffset(-1)
357 , fKind(Kind::kNull) {}
358
359 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind)
360 : fNodes(nodes)
361 , fOffset(offset)
362 , fKind(kind) {
363 switch (kind) {
364 case Kind::kBinary:
365 case Kind::kPostfix:
366 case Kind::kPrefix:
367 fData.fKind = NodeData::Kind::kToken;
368 break;
369
370 case Kind::kBool:
371 case Kind::kIf:
372 case Kind::kSwitch:
373 fData.fKind = NodeData::Kind::kBool;
374 break;
375
376 case Kind::kEnum:
377 case Kind::kEnumCase:
378 case Kind::kExtension:
379 case Kind::kField:
380 case Kind::kIdentifier:
Brian Osman6518d772020-09-10 16:50:06 -0400381 case Kind::kScope:
Ethan Nicholasfc994162019-06-06 10:04:27 -0400382 fData.fKind = NodeData::Kind::kStringFragment;
383 break;
384
385 case Kind::kFloat:
386 fData.fKind = NodeData::Kind::kFloat;
387 break;
388
389 case Kind::kFunction:
390 fData.fKind = NodeData::Kind::kFunctionData;
391 break;
392
393 case Kind::kInt:
394 fData.fKind = NodeData::Kind::kInt;
395 break;
396
397 case Kind::kInterfaceBlock:
398 fData.fKind = NodeData::Kind::kInterfaceBlockData;
399 break;
400
401 case Kind::kModifiers:
402 fData.fKind = NodeData::Kind::kModifiers;
403 break;
404
405 case Kind::kParameter:
406 fData.fKind = NodeData::Kind::kParameterData;
407 break;
408
409 case Kind::kVarDeclaration:
410 fData.fKind = NodeData::Kind::kVarData;
411 break;
412
413 case Kind::kType:
414 fData.fKind = NodeData::Kind::kTypeData;
415 break;
416
417 default:
418 break;
419 }
420 }
421
422 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, Token t)
423 : fNodes(nodes)
424 , fData(t)
425 , fOffset(offset)
426 , fKind(kind) {}
427
428 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, StringFragment s)
429 : fNodes(nodes)
430 , fData(s)
431 , fOffset(offset)
432 , fKind(kind) {}
433
434 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, const char* s)
435 : fNodes(nodes)
436 , fData(StringFragment(s))
437 , fOffset(offset)
438 , fKind(kind) {}
439
440 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, bool b)
441 : fNodes(nodes)
442 , fData(b)
443 , fOffset(offset)
444 , fKind(kind) {}
445
446 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SKSL_INT i)
447 : fNodes(nodes)
448 , fData(i)
449 , fOffset(offset)
450 , fKind(kind) {}
451
452 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SKSL_FLOAT f)
453 : fNodes(nodes)
454 , fData(f)
455 , fOffset(offset)
456 , fKind(kind) {}
457
458 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, Modifiers m)
459 : fNodes(nodes)
460 , fData(m)
461 , fOffset(offset)
462 , fKind(kind) {}
463
464 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, TypeData td)
465 : fNodes(nodes)
466 , fData(td)
467 , fOffset(offset)
468 , fKind(kind) {}
469
470 ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SectionData s)
471 : fNodes(nodes)
472 , fData(s)
473 , fOffset(offset)
474 , fKind(kind) {}
475
476 operator bool() const {
477 return fKind != Kind::kNull;
478 }
479
480 Token getToken() const {
481 SkASSERT(fData.fKind == NodeData::Kind::kToken);
482 Token result;
483 memcpy(&result, fData.fBytes, sizeof(result));
484 return result;
485 }
486
487 bool getBool() const {
488 SkASSERT(fData.fKind == NodeData::Kind::kBool);
489 bool result;
490 memcpy(&result, fData.fBytes, sizeof(result));
491 return result;
492 }
493
494 SKSL_INT getInt() const {
495 SkASSERT(fData.fKind == NodeData::Kind::kInt);
496 SKSL_INT result;
497 memcpy(&result, fData.fBytes, sizeof(result));
498 return result;
499 }
500
501 SKSL_FLOAT getFloat() const {
502 SkASSERT(fData.fKind == NodeData::Kind::kFloat);
503 SKSL_FLOAT result;
504 memcpy(&result, fData.fBytes, sizeof(result));
505 return result;
506 }
507
508 StringFragment getString() const {
509 SkASSERT(fData.fKind == NodeData::Kind::kStringFragment);
510 StringFragment result;
511 memcpy(&result, fData.fBytes, sizeof(result));
512 return result;
513 }
514
515 Modifiers getModifiers() const {
516 SkASSERT(fData.fKind == NodeData::Kind::kModifiers);
517 Modifiers result;
518 memcpy(&result, fData.fBytes, sizeof(result));
519 return result;
520 }
521
522 void setModifiers(const Modifiers& m) {
523 memcpy(fData.fBytes, &m, sizeof(m));
524 }
525
526 TypeData getTypeData() const {
527 SkASSERT(fData.fKind == NodeData::Kind::kTypeData);
528 TypeData result;
529 memcpy(&result, fData.fBytes, sizeof(result));
530 return result;
531 }
532
533 void setTypeData(const ASTNode::TypeData& td) {
534 SkASSERT(fData.fKind == NodeData::Kind::kTypeData);
535 memcpy(fData.fBytes, &td, sizeof(td));
536 }
537
538 ParameterData getParameterData() const {
539 SkASSERT(fData.fKind == NodeData::Kind::kParameterData);
540 ParameterData result;
541 memcpy(&result, fData.fBytes, sizeof(result));
542 return result;
543 }
544
545 void setParameterData(const ASTNode::ParameterData& pd) {
546 SkASSERT(fData.fKind == NodeData::Kind::kParameterData);
547 memcpy(fData.fBytes, &pd, sizeof(pd));
548 }
549
550 VarData getVarData() const {
551 SkASSERT(fData.fKind == NodeData::Kind::kVarData);
552 VarData result;
553 memcpy(&result, fData.fBytes, sizeof(result));
554 return result;
555 }
556
557 void setVarData(const ASTNode::VarData& vd) {
558 SkASSERT(fData.fKind == NodeData::Kind::kVarData);
559 memcpy(fData.fBytes, &vd, sizeof(vd));
560 }
561
562 FunctionData getFunctionData() const {
563 SkASSERT(fData.fKind == NodeData::Kind::kFunctionData);
564 FunctionData result;
565 memcpy(&result, fData.fBytes, sizeof(result));
566 return result;
567 }
568
569 void setFunctionData(const ASTNode::FunctionData& fd) {
570 SkASSERT(fData.fKind == NodeData::Kind::kFunctionData);
571 memcpy(fData.fBytes, &fd, sizeof(fd));
572 }
573
574 InterfaceBlockData getInterfaceBlockData() const {
575 SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlockData);
576 InterfaceBlockData result;
577 memcpy(&result, fData.fBytes, sizeof(result));
578 return result;
579 }
580
581 void setInterfaceBlockData(const ASTNode::InterfaceBlockData& id) {
582 SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlockData);
583 memcpy(fData.fBytes, &id, sizeof(id));
584 }
585
586 SectionData getSectionData() const {
587 SkASSERT(fData.fKind == NodeData::Kind::kSectionData);
588 SectionData result;
589 memcpy(&result, fData.fBytes, sizeof(result));
590 return result;
591 }
592
593 void addChild(ID id) {
594 SkASSERT(!(*fNodes)[id.fValue].fNext);
595 if (fLastChild) {
596 SkASSERT(!(*fNodes)[fLastChild.fValue].fNext);
597 (*fNodes)[fLastChild.fValue].fNext = id;
598 } else {
599 fFirstChild = id;
600 }
601 fLastChild = id;
602 SkASSERT(!(*fNodes)[fLastChild.fValue].fNext);
603 }
604
605 iterator begin() const {
606 return iterator(fNodes, fFirstChild);
607 }
608
609 iterator end() const {
610 return iterator(fNodes, ID(-1));
611 }
612
Ethan Nicholas2a099da2020-01-02 14:40:54 -0500613#ifdef SK_DEBUG
Ethan Nicholasfc994162019-06-06 10:04:27 -0400614 String description() const;
Ethan Nicholas2a099da2020-01-02 14:40:54 -0500615#endif
Ethan Nicholasfc994162019-06-06 10:04:27 -0400616
617 std::vector<ASTNode>* fNodes;
618
619 NodeData fData;
620
621 int fOffset;
622
623 Kind fKind;
624
625 ID fFirstChild;
626
627 ID fLastChild;
628
629 ID fNext;
630};
631
John Stilesa6841be2020-08-06 14:11:56 -0400632} // namespace SkSL
Ethan Nicholasfc994162019-06-06 10:04:27 -0400633
634#endif