1 /* 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 #include "src/sksl/SkSLASTNode.h" 9 #include "src/sksl/SkSLCompiler.h" 10 #include "src/sksl/SkSLString.h" 11 12 namespace SkSL { 13 description() const14String ASTNode::description() const { 15 switch (fKind) { 16 case Kind::kNull: return ""; 17 case Kind::kBinary: 18 return "(" + this->begin()->description() + " " + 19 Compiler::OperatorName(getToken().fKind) + " " + 20 (this->begin() + 1)->description() + ")"; 21 case Kind::kBlock: { 22 String result = "{\n"; 23 for (const auto& c : *this) { 24 result += c.description(); 25 result += "\n"; 26 } 27 result += "}"; 28 return result; 29 } 30 case Kind::kBool: 31 return getBool() ? "true" : "false"; 32 case Kind::kBreak: 33 return "break"; 34 case Kind::kCall: { 35 auto iter = this->begin(); 36 String result = iter->description(); 37 result += "("; 38 const char* separator = ""; 39 while (iter != this->end()) { 40 result += separator; 41 result += (iter++)->description(); 42 separator = ","; 43 } 44 result += ")"; 45 return result; 46 } 47 case Kind::kContinue: 48 return "continue"; 49 case Kind::kDiscard: 50 return "discard"; 51 case Kind::kDo: 52 return "do " + this->begin()->description() + " while (" + 53 (this->begin() + 1)->description() + ")"; 54 case Kind::kEnum: { 55 String result = "enum "; 56 result += getString(); 57 result += " {\n"; 58 for (const auto& c : *this) { 59 result += c.description(); 60 result += "\n"; 61 } 62 result += "};"; 63 return result; 64 } 65 case Kind::kEnumCase: 66 if (this->begin() != this->end()) { 67 return String(getString()) + " = " + this->begin()->description(); 68 } 69 return getString(); 70 case Kind::kExtension: 71 return "#extension " + getString(); 72 case Kind::kField: 73 return this->begin()->description() + "." + getString(); 74 case Kind::kFile: { 75 String result; 76 for (const auto& c : *this) { 77 result += c.description(); 78 result += "\n"; 79 } 80 return result; 81 } 82 case Kind::kFloat: 83 return to_string(getFloat()); 84 case Kind::kFor: 85 return "for (" + this->begin()->description() + "; " + 86 (this->begin() + 1)->description() + "; " + (this->begin() + 2)->description() + 87 ") " + (this->begin() + 3)->description(); 88 case Kind::kFunction: { 89 FunctionData fd = getFunctionData(); 90 String result = fd.fModifiers.description(); 91 if (result.size()) { 92 result += " "; 93 } 94 auto iter = this->begin(); 95 result += (iter++)->description() + " " + fd.fName + "("; 96 const char* separator = ""; 97 for (size_t i = 0; i < fd.fParameterCount; ++i) { 98 result += separator; 99 result += (iter++)->description(); 100 separator = ", "; 101 } 102 result += ")"; 103 if (iter != this->end()) { 104 result += " " + (iter++)->description(); 105 SkASSERT(iter == this->end()); 106 } 107 else { 108 result += ";"; 109 } 110 return result; 111 } 112 case Kind::kIdentifier: 113 return getString(); 114 case Kind::kIndex: 115 return this->begin()->description() + "[" + (this->begin() + 1)->description() + "]"; 116 case Kind::kIf: { 117 String result; 118 if (getBool()) { 119 result = "@"; 120 } 121 auto iter = this->begin(); 122 result += "if (" + (iter++)->description() + ") "; 123 result += (iter++)->description(); 124 if (iter != this->end()) { 125 result += " else " + (iter++)->description(); 126 SkASSERT(iter == this->end()); 127 } 128 return result; 129 } 130 case Kind::kInt: 131 return to_string(getInt()); 132 case Kind::kInterfaceBlock: { 133 InterfaceBlockData id = getInterfaceBlockData(); 134 String result = id.fModifiers.description() + " " + id.fTypeName + " {\n"; 135 auto iter = this->begin(); 136 for (size_t i = 0; i < id.fDeclarationCount; ++i) { 137 result += (iter++)->description() + "\n"; 138 } 139 result += "} "; 140 result += id.fInstanceName; 141 for (size_t i = 0; i < id.fSizeCount; ++i) { 142 result += "[" + (iter++)->description() + "]"; 143 } 144 SkASSERT(iter == this->end()); 145 result += ";"; 146 return result; 147 } 148 case Kind::kModifiers: 149 return getModifiers().description(); 150 case Kind::kParameter: { 151 ParameterData pd = getParameterData(); 152 auto iter = this->begin(); 153 String result = (iter++)->description() + " " + pd.fName; 154 for (size_t i = 0; i < pd.fSizeCount; ++i) { 155 result += "[" + (iter++)->description() + "]"; 156 } 157 if (iter != this->end()) { 158 result += " = " + (iter++)->description(); 159 SkASSERT(iter == this->end()); 160 } 161 return result; 162 } 163 case Kind::kPostfix: 164 return this->begin()->description() + Compiler::OperatorName(getToken().fKind); 165 case Kind::kPrefix: 166 return Compiler::OperatorName(getToken().fKind) + this->begin()->description(); 167 case Kind::kReturn: 168 if (this->begin() != this->end()) { 169 return "return " + this->begin()->description() + ";"; 170 } 171 return "return;"; 172 case Kind::kSection: 173 return "@section { ... }"; 174 case Kind::kSwitchCase: { 175 auto iter = this->begin(); 176 String result; 177 if (*iter) { 178 result.appendf("case %s:\n", iter->description().c_str()); 179 } else { 180 result = "default:\n"; 181 } 182 for (++iter; iter != this->end(); ++iter) { 183 result += "\n" + iter->description(); 184 } 185 return result; 186 } 187 case Kind::kSwitch: { 188 auto iter = this->begin(); 189 String result; 190 if (getBool()) { 191 result = "@"; 192 } 193 result += "switch (" + (iter++)->description() + ") {"; 194 for (; iter != this->end(); ++iter) { 195 result += iter->description() + "\n"; 196 } 197 result += "}"; 198 return result; 199 } 200 case Kind::kTernary: 201 return "(" + this->begin()->description() + " ? " + (this->begin() + 1)->description() + 202 " : " + (this->begin() + 2)->description() + ")"; 203 case Kind::kType: 204 return String(getTypeData().fName); 205 case Kind::kVarDeclaration: { 206 VarData vd = getVarData(); 207 String result = vd.fName; 208 auto iter = this->begin(); 209 for (size_t i = 0; i < vd.fSizeCount; ++i) { 210 result += "[" + (iter++)->description() + "]"; 211 } 212 if (iter != this->end()) { 213 result += " = " + (iter++)->description(); 214 SkASSERT(iter == this->end()); 215 } 216 return result; 217 } 218 case Kind::kVarDeclarations: { 219 auto iter = this->begin(); 220 String result = (iter++)->description(); 221 if (result.size()) { 222 result += " "; 223 } 224 result += (iter++)->description(); 225 const char* separator = " "; 226 for (; iter != this->end(); ++iter) { 227 result += separator + iter->description(); 228 separator = ", "; 229 } 230 return result; 231 } 232 default: 233 SkASSERT(false); 234 return "<error>"; 235 } 236 } 237 238 } // namespace 239