SkSLASTNode.cpp 8.3 KB

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