123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635 |
- /*
- * Copyright 2019 Google LLC
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef SKSL_ASTNODE
- #define SKSL_ASTNODE
- #include "src/sksl/SkSLLexer.h"
- #include "src/sksl/SkSLString.h"
- #include "src/sksl/ir/SkSLModifiers.h"
- #include <vector>
- namespace SkSL {
- // std::max isn't constexpr in some compilers
- static constexpr size_t Max(size_t a, size_t b) {
- return a > b ? a : b;
- }
- /**
- * Represents a node in the abstract syntax tree (AST). The AST is based directly on the parse tree;
- * it is a parsed-but-not-yet-analyzed version of the program.
- */
- struct ASTNode {
- class ID {
- public:
- static ID Invalid() {
- return ID();
- }
- bool operator==(const ID& other) {
- return fValue == other.fValue;
- }
- bool operator!=(const ID& other) {
- return fValue != other.fValue;
- }
- operator bool() const { return fValue >= 0; }
- private:
- ID()
- : fValue(-1) {}
- ID(int value)
- : fValue(value) {}
- int fValue;
- friend struct ASTFile;
- friend struct ASTNode;
- friend class Parser;
- };
- enum class Kind {
- // data: operator(Token), children: left, right
- kBinary,
- // children: statements
- kBlock,
- // data: value(bool)
- kBool,
- kBreak,
- // children: target, arg1, arg2...
- kCall,
- kContinue,
- kDiscard,
- // children: statement, test
- kDo,
- // data: name(StringFragment), children: enumCases
- kEnum,
- // data: name(StringFragment), children: value?
- kEnumCase,
- // data: name(StringFragment)
- kExtension,
- // data: field(StringFragment), children: base
- kField,
- // children: declarations
- kFile,
- // data: value(float)
- kFloat,
- // children: init, test, next, statement
- kFor,
- // data: FunctionData, children: returnType, parameters, statement?
- kFunction,
- // data: name(StringFragment)
- kIdentifier,
- // children: base, index?
- kIndex,
- // data: isStatic(bool), children: test, ifTrue, ifFalse?
- kIf,
- // value(data): int
- kInt,
- // data: InterfaceBlockData, children: declaration1, declaration2, ..., size1, size2, ...
- kInterfaceBlock,
- // data: Modifiers
- kModifiers,
- kNull,
- // data: ParameterData, children: type, arraySize1, arraySize2, ..., value?
- kParameter,
- // data: operator(Token), children: operand
- kPostfix,
- // data: operator(Token), children: operand
- kPrefix,
- // children: value
- kReturn,
- // ...
- kSection,
- // children: value, statement 1, statement 2...
- kSwitchCase,
- // children: value, case 1, case 2...
- kSwitch,
- // children: test, ifTrue, ifFalse
- kTernary,
- // data: TypeData, children: sizes
- kType,
- // data: VarData, children: arraySize1, arraySize2, ..., value?
- kVarDeclaration,
- // children: modifiers, type, varDeclaration1, varDeclaration2, ...
- kVarDeclarations,
- // children: test, statement
- kWhile,
- };
- class iterator {
- public:
- iterator operator++() {
- SkASSERT(fID);
- fID = (**this).fNext;
- return *this;
- }
- iterator operator++(int) {
- SkASSERT(fID);
- iterator old = *this;
- fID = (**this).fNext;
- return old;
- }
- iterator operator+=(int count) {
- SkASSERT(count >= 0);
- for (; count > 0; --count) {
- ++(*this);
- }
- return *this;
- }
- iterator operator+(int count) {
- iterator result(*this);
- return result += count;
- }
- bool operator==(const iterator& other) const {
- return fID == other.fID;
- }
- bool operator!=(const iterator& other) const {
- return fID != other.fID;
- }
- ASTNode& operator*() {
- SkASSERT(fID);
- return (*fNodes)[fID.fValue];
- }
- ASTNode* operator->() {
- SkASSERT(fID);
- return &(*fNodes)[fID.fValue];
- }
- private:
- iterator(std::vector<ASTNode>* nodes, ID id)
- : fNodes(nodes)
- , fID(id) {}
- std::vector<ASTNode>* fNodes;
- ID fID;
- friend struct ASTNode;
- };
- struct TypeData {
- TypeData() {}
- TypeData(StringFragment name, bool isStructDeclaration, bool isNullable)
- : fName(name)
- , fIsStructDeclaration(isStructDeclaration)
- , fIsNullable(isNullable) {}
- StringFragment fName;
- bool fIsStructDeclaration;
- bool fIsNullable;
- };
- struct ParameterData {
- ParameterData() {}
- ParameterData(Modifiers modifiers, StringFragment name, size_t sizeCount)
- : fModifiers(modifiers)
- , fName(name)
- , fSizeCount(sizeCount) {}
- Modifiers fModifiers;
- StringFragment fName;
- size_t fSizeCount;
- };
- struct VarData {
- VarData() {}
- VarData(StringFragment name, size_t sizeCount)
- : fName(name)
- , fSizeCount(sizeCount) {}
- StringFragment fName;
- size_t fSizeCount;
- };
- struct FunctionData {
- FunctionData() {}
- FunctionData(Modifiers modifiers, StringFragment name, size_t parameterCount)
- : fModifiers(modifiers)
- , fName(name)
- , fParameterCount(parameterCount) {}
- Modifiers fModifiers;
- StringFragment fName;
- size_t fParameterCount;
- };
- struct InterfaceBlockData {
- InterfaceBlockData() {}
- InterfaceBlockData(Modifiers modifiers, StringFragment typeName, size_t declarationCount,
- StringFragment instanceName, size_t sizeCount)
- : fModifiers(modifiers)
- , fTypeName(typeName)
- , fDeclarationCount(declarationCount)
- , fInstanceName(instanceName)
- , fSizeCount(sizeCount) {}
- Modifiers fModifiers;
- StringFragment fTypeName;
- size_t fDeclarationCount;
- StringFragment fInstanceName;
- size_t fSizeCount;
- };
- struct SectionData {
- SectionData() {}
- SectionData(StringFragment name, StringFragment argument, StringFragment text)
- : fName(name)
- , fArgument(argument)
- , fText(text) {}
- StringFragment fName;
- StringFragment fArgument;
- StringFragment fText;
- };
- struct NodeData {
- char fBytes[Max(sizeof(Token),
- Max(sizeof(StringFragment),
- Max(sizeof(bool),
- Max(sizeof(SKSL_INT),
- Max(sizeof(SKSL_FLOAT),
- Max(sizeof(Modifiers),
- Max(sizeof(TypeData),
- Max(sizeof(FunctionData),
- Max(sizeof(ParameterData),
- Max(sizeof(VarData),
- Max(sizeof(InterfaceBlockData),
- sizeof(SectionData))))))))))))];
- enum class Kind {
- kToken,
- kStringFragment,
- kBool,
- kInt,
- kFloat,
- kModifiers,
- kTypeData,
- kFunctionData,
- kParameterData,
- kVarData,
- kInterfaceBlockData,
- kSectionData
- } fKind;
- NodeData() = default;
- NodeData(Token data)
- : fKind(Kind::kToken) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(StringFragment data)
- : fKind(Kind::kStringFragment) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(bool data)
- : fKind(Kind::kBool) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(SKSL_INT data)
- : fKind(Kind::kInt) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(SKSL_FLOAT data)
- : fKind(Kind::kFloat) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(Modifiers data)
- : fKind(Kind::kModifiers) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(TypeData data)
- : fKind(Kind::kTypeData) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(FunctionData data)
- : fKind(Kind::kFunctionData) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(VarData data)
- : fKind(Kind::kVarData) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(ParameterData data)
- : fKind(Kind::kParameterData) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(InterfaceBlockData data)
- : fKind(Kind::kInterfaceBlockData) {
- memcpy(fBytes, &data, sizeof(data));
- }
- NodeData(SectionData data)
- : fKind(Kind::kSectionData) {
- memcpy(fBytes, &data, sizeof(data));
- }
- };
- ASTNode()
- : fOffset(-1)
- , fKind(Kind::kNull) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind)
- : fNodes(nodes)
- , fOffset(offset)
- , fKind(kind) {
- switch (kind) {
- case Kind::kBinary:
- case Kind::kPostfix:
- case Kind::kPrefix:
- fData.fKind = NodeData::Kind::kToken;
- break;
- case Kind::kBool:
- case Kind::kIf:
- case Kind::kSwitch:
- fData.fKind = NodeData::Kind::kBool;
- break;
- case Kind::kEnum:
- case Kind::kEnumCase:
- case Kind::kExtension:
- case Kind::kField:
- case Kind::kIdentifier:
- fData.fKind = NodeData::Kind::kStringFragment;
- break;
- case Kind::kFloat:
- fData.fKind = NodeData::Kind::kFloat;
- break;
- case Kind::kFunction:
- fData.fKind = NodeData::Kind::kFunctionData;
- break;
- case Kind::kInt:
- fData.fKind = NodeData::Kind::kInt;
- break;
- case Kind::kInterfaceBlock:
- fData.fKind = NodeData::Kind::kInterfaceBlockData;
- break;
- case Kind::kModifiers:
- fData.fKind = NodeData::Kind::kModifiers;
- break;
- case Kind::kParameter:
- fData.fKind = NodeData::Kind::kParameterData;
- break;
- case Kind::kVarDeclaration:
- fData.fKind = NodeData::Kind::kVarData;
- break;
- case Kind::kType:
- fData.fKind = NodeData::Kind::kTypeData;
- break;
- default:
- break;
- }
- }
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, Token t)
- : fNodes(nodes)
- , fData(t)
- , fOffset(offset)
- , fKind(kind) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, StringFragment s)
- : fNodes(nodes)
- , fData(s)
- , fOffset(offset)
- , fKind(kind) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, const char* s)
- : fNodes(nodes)
- , fData(StringFragment(s))
- , fOffset(offset)
- , fKind(kind) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, bool b)
- : fNodes(nodes)
- , fData(b)
- , fOffset(offset)
- , fKind(kind) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SKSL_INT i)
- : fNodes(nodes)
- , fData(i)
- , fOffset(offset)
- , fKind(kind) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SKSL_FLOAT f)
- : fNodes(nodes)
- , fData(f)
- , fOffset(offset)
- , fKind(kind) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, Modifiers m)
- : fNodes(nodes)
- , fData(m)
- , fOffset(offset)
- , fKind(kind) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, TypeData td)
- : fNodes(nodes)
- , fData(td)
- , fOffset(offset)
- , fKind(kind) {}
- ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, SectionData s)
- : fNodes(nodes)
- , fData(s)
- , fOffset(offset)
- , fKind(kind) {}
- operator bool() const {
- return fKind != Kind::kNull;
- }
- Token getToken() const {
- SkASSERT(fData.fKind == NodeData::Kind::kToken);
- Token result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- bool getBool() const {
- SkASSERT(fData.fKind == NodeData::Kind::kBool);
- bool result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- SKSL_INT getInt() const {
- SkASSERT(fData.fKind == NodeData::Kind::kInt);
- SKSL_INT result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- SKSL_FLOAT getFloat() const {
- SkASSERT(fData.fKind == NodeData::Kind::kFloat);
- SKSL_FLOAT result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- StringFragment getString() const {
- SkASSERT(fData.fKind == NodeData::Kind::kStringFragment);
- StringFragment result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- Modifiers getModifiers() const {
- SkASSERT(fData.fKind == NodeData::Kind::kModifiers);
- Modifiers result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- void setModifiers(const Modifiers& m) {
- memcpy(fData.fBytes, &m, sizeof(m));
- }
- TypeData getTypeData() const {
- SkASSERT(fData.fKind == NodeData::Kind::kTypeData);
- TypeData result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- void setTypeData(const ASTNode::TypeData& td) {
- SkASSERT(fData.fKind == NodeData::Kind::kTypeData);
- memcpy(fData.fBytes, &td, sizeof(td));
- }
- ParameterData getParameterData() const {
- SkASSERT(fData.fKind == NodeData::Kind::kParameterData);
- ParameterData result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- void setParameterData(const ASTNode::ParameterData& pd) {
- SkASSERT(fData.fKind == NodeData::Kind::kParameterData);
- memcpy(fData.fBytes, &pd, sizeof(pd));
- }
- VarData getVarData() const {
- SkASSERT(fData.fKind == NodeData::Kind::kVarData);
- VarData result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- void setVarData(const ASTNode::VarData& vd) {
- SkASSERT(fData.fKind == NodeData::Kind::kVarData);
- memcpy(fData.fBytes, &vd, sizeof(vd));
- }
- FunctionData getFunctionData() const {
- SkASSERT(fData.fKind == NodeData::Kind::kFunctionData);
- FunctionData result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- void setFunctionData(const ASTNode::FunctionData& fd) {
- SkASSERT(fData.fKind == NodeData::Kind::kFunctionData);
- memcpy(fData.fBytes, &fd, sizeof(fd));
- }
- InterfaceBlockData getInterfaceBlockData() const {
- SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlockData);
- InterfaceBlockData result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- void setInterfaceBlockData(const ASTNode::InterfaceBlockData& id) {
- SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlockData);
- memcpy(fData.fBytes, &id, sizeof(id));
- }
- SectionData getSectionData() const {
- SkASSERT(fData.fKind == NodeData::Kind::kSectionData);
- SectionData result;
- memcpy(&result, fData.fBytes, sizeof(result));
- return result;
- }
- void addChild(ID id) {
- SkASSERT(!(*fNodes)[id.fValue].fNext);
- if (fLastChild) {
- SkASSERT(!(*fNodes)[fLastChild.fValue].fNext);
- (*fNodes)[fLastChild.fValue].fNext = id;
- } else {
- fFirstChild = id;
- }
- fLastChild = id;
- SkASSERT(!(*fNodes)[fLastChild.fValue].fNext);
- }
- iterator begin() const {
- return iterator(fNodes, fFirstChild);
- }
- iterator end() const {
- return iterator(fNodes, ID(-1));
- }
- String description() const;
- std::vector<ASTNode>* fNodes;
- NodeData fData;
- int fOffset;
- Kind fKind;
- ID fFirstChild;
- ID fLastChild;
- ID fNext;
- };
- } // namespace
- #endif
|