blob: 5842c8ae6706c9db853ad0c7a2db07f4cc6897f7 [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
Ethan Nicholasdaed2592021-03-04 14:30:25 -05008#include "include/private/SkSLString.h"
Ethan Nicholasfc994162019-06-06 10:04:27 -04009#include "src/sksl/SkSLASTNode.h"
Brian Osman00185012021-02-04 16:07:11 -050010#include "src/sksl/SkSLOperators.h"
Ethan Nicholasfc994162019-06-06 10:04:27 -040011
12namespace SkSL {
13
Ethan Nicholas2a099da2020-01-02 14:40:54 -050014#ifdef SK_DEBUG
Ethan Nicholasfc994162019-06-06 10:04:27 -040015String ASTNode::description() const {
16 switch (fKind) {
17 case Kind::kNull: return "";
18 case Kind::kBinary:
19 return "(" + this->begin()->description() + " " +
John Stiles45990502021-02-16 10:55:27 -050020 getOperator().operatorName() + " " +
Ethan Nicholasfc994162019-06-06 10:04:27 -040021 (this->begin() + 1)->description() + ")";
22 case Kind::kBlock: {
23 String result = "{\n";
24 for (const auto& c : *this) {
25 result += c.description();
26 result += "\n";
27 }
28 result += "}";
29 return result;
30 }
31 case Kind::kBool:
32 return getBool() ? "true" : "false";
33 case Kind::kBreak:
34 return "break";
35 case Kind::kCall: {
36 auto iter = this->begin();
Ethan Nicholas70728ef2020-05-28 07:09:00 -040037 String result = (iter++)->description();
Ethan Nicholasfc994162019-06-06 10:04:27 -040038 result += "(";
39 const char* separator = "";
40 while (iter != this->end()) {
41 result += separator;
42 result += (iter++)->description();
43 separator = ",";
44 }
45 result += ")";
46 return result;
47 }
48 case Kind::kContinue:
49 return "continue";
50 case Kind::kDiscard:
51 return "discard";
52 case Kind::kDo:
53 return "do " + this->begin()->description() + " while (" +
54 (this->begin() + 1)->description() + ")";
Ethan Nicholasfc994162019-06-06 10:04:27 -040055 case Kind::kExtension:
Ethan Nicholas962dec42021-06-10 13:06:39 -040056 return "#extension " + getStringView();
Ethan Nicholasfc994162019-06-06 10:04:27 -040057 case Kind::kField:
Ethan Nicholas962dec42021-06-10 13:06:39 -040058 return this->begin()->description() + "." + getStringView();
Ethan Nicholasfc994162019-06-06 10:04:27 -040059 case Kind::kFile: {
60 String result;
61 for (const auto& c : *this) {
62 result += c.description();
63 result += "\n";
64 }
65 return result;
66 }
67 case Kind::kFloat:
68 return to_string(getFloat());
69 case Kind::kFor:
70 return "for (" + this->begin()->description() + "; " +
71 (this->begin() + 1)->description() + "; " + (this->begin() + 2)->description() +
72 ") " + (this->begin() + 3)->description();
73 case Kind::kFunction: {
John Stilesece1bf02021-03-08 11:15:55 -050074 const FunctionData& fd = getFunctionData();
Ethan Nicholasfc994162019-06-06 10:04:27 -040075 String result = fd.fModifiers.description();
76 if (result.size()) {
77 result += " ";
78 }
79 auto iter = this->begin();
80 result += (iter++)->description() + " " + fd.fName + "(";
81 const char* separator = "";
82 for (size_t i = 0; i < fd.fParameterCount; ++i) {
83 result += separator;
84 result += (iter++)->description();
85 separator = ", ";
86 }
87 result += ")";
88 if (iter != this->end()) {
89 result += " " + (iter++)->description();
90 SkASSERT(iter == this->end());
91 }
92 else {
93 result += ";";
94 }
95 return result;
96 }
97 case Kind::kIdentifier:
Ethan Nicholas962dec42021-06-10 13:06:39 -040098 return String(getStringView());
Ethan Nicholasfc994162019-06-06 10:04:27 -040099 case Kind::kIndex:
100 return this->begin()->description() + "[" + (this->begin() + 1)->description() + "]";
101 case Kind::kIf: {
102 String result;
103 if (getBool()) {
104 result = "@";
105 }
106 auto iter = this->begin();
107 result += "if (" + (iter++)->description() + ") ";
108 result += (iter++)->description();
109 if (iter != this->end()) {
110 result += " else " + (iter++)->description();
111 SkASSERT(iter == this->end());
112 }
113 return result;
114 }
115 case Kind::kInt:
116 return to_string(getInt());
117 case Kind::kInterfaceBlock: {
John Stilesece1bf02021-03-08 11:15:55 -0500118 const InterfaceBlockData& id = getInterfaceBlockData();
Ethan Nicholasfc994162019-06-06 10:04:27 -0400119 String result = id.fModifiers.description() + " " + id.fTypeName + " {\n";
120 auto iter = this->begin();
121 for (size_t i = 0; i < id.fDeclarationCount; ++i) {
122 result += (iter++)->description() + "\n";
123 }
124 result += "} ";
125 result += id.fInstanceName;
John Stilesd39aec92020-12-03 14:37:16 -0500126 if (id.fIsArray) {
Ethan Nicholasfc994162019-06-06 10:04:27 -0400127 result += "[" + (iter++)->description() + "]";
128 }
129 SkASSERT(iter == this->end());
130 result += ";";
131 return result;
132 }
133 case Kind::kModifiers:
134 return getModifiers().description();
135 case Kind::kParameter: {
John Stilesece1bf02021-03-08 11:15:55 -0500136 const ParameterData& pd = getParameterData();
Ethan Nicholasfc994162019-06-06 10:04:27 -0400137 auto iter = this->begin();
138 String result = (iter++)->description() + " " + pd.fName;
John Stilesd39aec92020-12-03 14:37:16 -0500139 if (pd.fIsArray) {
Ethan Nicholasfc994162019-06-06 10:04:27 -0400140 result += "[" + (iter++)->description() + "]";
141 }
142 if (iter != this->end()) {
143 result += " = " + (iter++)->description();
144 SkASSERT(iter == this->end());
145 }
146 return result;
147 }
148 case Kind::kPostfix:
John Stiles45990502021-02-16 10:55:27 -0500149 return this->begin()->description() + getOperator().operatorName();
Ethan Nicholasfc994162019-06-06 10:04:27 -0400150 case Kind::kPrefix:
John Stiles45990502021-02-16 10:55:27 -0500151 return getOperator().operatorName() + this->begin()->description();
Ethan Nicholasfc994162019-06-06 10:04:27 -0400152 case Kind::kReturn:
153 if (this->begin() != this->end()) {
154 return "return " + this->begin()->description() + ";";
155 }
156 return "return;";
Ethan Nicholasfc994162019-06-06 10:04:27 -0400157 case Kind::kSwitchCase: {
158 auto iter = this->begin();
159 String result;
160 if (*iter) {
161 result.appendf("case %s:\n", iter->description().c_str());
162 } else {
163 result = "default:\n";
164 }
165 for (++iter; iter != this->end(); ++iter) {
166 result += "\n" + iter->description();
167 }
168 return result;
169 }
170 case Kind::kSwitch: {
171 auto iter = this->begin();
172 String result;
173 if (getBool()) {
174 result = "@";
175 }
176 result += "switch (" + (iter++)->description() + ") {";
177 for (; iter != this->end(); ++iter) {
178 result += iter->description() + "\n";
179 }
180 result += "}";
181 return result;
182 }
183 case Kind::kTernary:
184 return "(" + this->begin()->description() + " ? " + (this->begin() + 1)->description() +
185 " : " + (this->begin() + 2)->description() + ")";
186 case Kind::kType:
Ethan Nicholas962dec42021-06-10 13:06:39 -0400187 return String(getStringView());
Ethan Nicholasfc994162019-06-06 10:04:27 -0400188 case Kind::kVarDeclaration: {
John Stilesece1bf02021-03-08 11:15:55 -0500189 const VarData& vd = getVarData();
Ethan Nicholasd2e09602021-06-10 11:21:59 -0400190 String result(vd.fName);
Ethan Nicholasfc994162019-06-06 10:04:27 -0400191 auto iter = this->begin();
John Stilesd39aec92020-12-03 14:37:16 -0500192 if (vd.fIsArray) {
Ethan Nicholasfc994162019-06-06 10:04:27 -0400193 result += "[" + (iter++)->description() + "]";
194 }
195 if (iter != this->end()) {
196 result += " = " + (iter++)->description();
197 SkASSERT(iter == this->end());
198 }
199 return result;
200 }
201 case Kind::kVarDeclarations: {
202 auto iter = this->begin();
203 String result = (iter++)->description();
204 if (result.size()) {
205 result += " ";
206 }
207 result += (iter++)->description();
208 const char* separator = " ";
209 for (; iter != this->end(); ++iter) {
210 result += separator + iter->description();
211 separator = ", ";
212 }
213 return result;
214 }
Ethan Nicholas70728ef2020-05-28 07:09:00 -0400215 case Kind::kWhile: {
216 return "while (" + this->begin()->description() + ") " +
217 (this->begin() + 1)->description();
218
219 }
Ethan Nicholasfc994162019-06-06 10:04:27 -0400220 default:
John Stilesece1bf02021-03-08 11:15:55 -0500221 SkDEBUGFAIL("unrecognized AST node kind");
Ethan Nicholasfc994162019-06-06 10:04:27 -0400222 return "<error>";
223 }
224}
Ethan Nicholas2a099da2020-01-02 14:40:54 -0500225#endif
Ethan Nicholasfc994162019-06-06 10:04:27 -0400226
John Stilesa6841be2020-08-06 14:11:56 -0400227} // namespace SkSL