AST.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /*
  2. * Copyright (c) 2021, Itamar S. <itamar8910@gmail.com>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "AST.h"
  27. namespace Cpp {
  28. static void print_indent(int indent)
  29. {
  30. for (int i = 0; i < indent * 2; ++i)
  31. out(" ");
  32. }
  33. void ASTNode::dump(size_t indent) const
  34. {
  35. print_indent(indent);
  36. outln("{}[{}:{}->{}:{}]", class_name(), start().line, start().column, end().line, end().column);
  37. }
  38. void TranslationUnit::dump(size_t indent) const
  39. {
  40. ASTNode::dump(indent);
  41. for (const auto& child : m_declarations) {
  42. child.dump(indent + 1);
  43. }
  44. }
  45. void FunctionDeclaration::dump(size_t indent) const
  46. {
  47. ASTNode::dump(indent);
  48. String qualifiers_string;
  49. if (!m_qualifiers.is_empty()) {
  50. print_indent(indent+1);
  51. outln("[{}]", String::join(" ", m_qualifiers));
  52. }
  53. m_return_type->dump(indent + 1);
  54. if (!m_name.is_null()) {
  55. print_indent(indent + 1);
  56. outln("{}", m_name);
  57. }
  58. print_indent(indent + 1);
  59. outln("(");
  60. for (const auto& arg : m_parameters) {
  61. arg.dump(indent + 1);
  62. }
  63. print_indent(indent + 1);
  64. outln(")");
  65. if (!m_definition.is_null()) {
  66. m_definition->dump(indent + 1);
  67. }
  68. }
  69. NonnullRefPtrVector<Declaration> FunctionDeclaration::declarations() const
  70. {
  71. NonnullRefPtrVector<Declaration> declarations;
  72. for (auto& arg : m_parameters) {
  73. declarations.append(arg);
  74. }
  75. return declarations;
  76. }
  77. void Type::dump(size_t indent) const
  78. {
  79. ASTNode::dump(indent);
  80. print_indent(indent + 1);
  81. String qualifiers_string;
  82. if (!m_qualifiers.is_empty())
  83. qualifiers_string = String::formatted("[{}] ", String::join(" ", m_qualifiers));
  84. outln("{}{}", qualifiers_string, m_name);
  85. }
  86. void Parameter::dump(size_t indent) const
  87. {
  88. ASTNode::dump(indent);
  89. if (m_is_ellipsis) {
  90. print_indent(indent + 1);
  91. outln("...");
  92. }
  93. if (!m_name.is_null()) {
  94. print_indent(indent);
  95. outln("{}", m_name);
  96. }
  97. if (m_type)
  98. m_type->dump(indent + 1);
  99. }
  100. void FunctionDefinition::dump(size_t indent) const
  101. {
  102. ASTNode::dump(indent);
  103. print_indent(indent);
  104. outln("{{");
  105. for (const auto& statement : m_statements) {
  106. statement.dump(indent + 1);
  107. }
  108. print_indent(indent);
  109. outln("}}");
  110. }
  111. NonnullRefPtrVector<Declaration> FunctionDefinition::declarations() const
  112. {
  113. NonnullRefPtrVector<Declaration> declarations;
  114. for (auto& statement : m_statements) {
  115. declarations.append(statement.declarations());
  116. }
  117. return declarations;
  118. }
  119. void VariableDeclaration::dump(size_t indent) const
  120. {
  121. ASTNode::dump(indent);
  122. if (m_type)
  123. m_type->dump(indent + 1);
  124. print_indent(indent + 1);
  125. outln("{}", m_name);
  126. if (m_initial_value)
  127. m_initial_value->dump(indent + 1);
  128. }
  129. void Identifier::dump(size_t indent) const
  130. {
  131. ASTNode::dump(indent);
  132. print_indent(indent);
  133. outln("{}", m_name);
  134. }
  135. void NumericLiteral::dump(size_t indent) const
  136. {
  137. ASTNode::dump(indent);
  138. print_indent(indent);
  139. outln("{}", m_value);
  140. }
  141. void BinaryExpression::dump(size_t indent) const
  142. {
  143. ASTNode::dump(indent);
  144. const char* op_string = nullptr;
  145. switch (m_op) {
  146. case BinaryOp::Addition:
  147. op_string = "+";
  148. break;
  149. case BinaryOp::Subtraction:
  150. op_string = "-";
  151. break;
  152. case BinaryOp::Multiplication:
  153. op_string = "*";
  154. break;
  155. case BinaryOp::Division:
  156. op_string = "/";
  157. break;
  158. case BinaryOp::Modulo:
  159. op_string = "%";
  160. break;
  161. case BinaryOp::GreaterThan:
  162. op_string = ">";
  163. break;
  164. case BinaryOp::GreaterThanEquals:
  165. op_string = ">=";
  166. break;
  167. case BinaryOp::LessThan:
  168. op_string = "<";
  169. break;
  170. case BinaryOp::LessThanEquals:
  171. op_string = "<=";
  172. break;
  173. case BinaryOp::BitwiseAnd:
  174. op_string = "&";
  175. break;
  176. case BinaryOp::BitwiseOr:
  177. op_string = "|";
  178. break;
  179. case BinaryOp::BitwiseXor:
  180. op_string = "^";
  181. break;
  182. case BinaryOp::LeftShift:
  183. op_string = "<<";
  184. break;
  185. case BinaryOp::RightShift:
  186. op_string = ">>";
  187. break;
  188. }
  189. m_lhs->dump(indent + 1);
  190. print_indent(indent + 1);
  191. VERIFY(op_string);
  192. outln("{}", op_string);
  193. m_rhs->dump(indent + 1);
  194. }
  195. void AssignmentExpression::dump(size_t indent) const
  196. {
  197. ASTNode::dump(indent);
  198. const char* op_string = nullptr;
  199. switch (m_op) {
  200. case AssignmentOp::Assignment:
  201. op_string = "=";
  202. break;
  203. case AssignmentOp::AdditionAssignment:
  204. op_string = "+=";
  205. break;
  206. case AssignmentOp::SubtractionAssignment:
  207. op_string = "-=";
  208. break;
  209. }
  210. m_lhs->dump(indent + 1);
  211. print_indent(indent + 1);
  212. VERIFY(op_string);
  213. outln("{}", op_string);
  214. m_rhs->dump(indent + 1);
  215. }
  216. void FunctionCall::dump(size_t indent) const
  217. {
  218. ASTNode::dump(indent);
  219. print_indent(indent);
  220. outln("{}", m_name);
  221. for (const auto& arg : m_arguments) {
  222. arg.dump(indent + 1);
  223. }
  224. }
  225. void StringLiteral::dump(size_t indent) const
  226. {
  227. ASTNode::dump(indent);
  228. print_indent(indent + 1);
  229. outln("{}", m_value);
  230. }
  231. void ReturnStatement::dump(size_t indent) const
  232. {
  233. ASTNode::dump(indent);
  234. if(m_value)
  235. m_value->dump(indent + 1);
  236. }
  237. void EnumDeclaration::dump(size_t indent) const
  238. {
  239. ASTNode::dump(indent);
  240. print_indent(indent);
  241. outln("{}", m_name);
  242. for (auto& entry : m_entries) {
  243. print_indent(indent + 1);
  244. outln("{}", entry);
  245. }
  246. }
  247. void StructOrClassDeclaration::dump(size_t indent) const
  248. {
  249. ASTNode::dump(indent);
  250. print_indent(indent);
  251. outln("{}", m_name);
  252. for (auto& member : m_members) {
  253. member.dump(indent + 1);
  254. }
  255. }
  256. void MemberDeclaration::dump(size_t indent) const
  257. {
  258. ASTNode::dump(indent);
  259. m_type->dump(indent + 1);
  260. print_indent(indent + 1);
  261. outln("{}", m_name);
  262. if (m_initial_value) {
  263. m_initial_value->dump(indent + 2);
  264. }
  265. }
  266. void UnaryExpression::dump(size_t indent) const
  267. {
  268. ASTNode::dump(indent);
  269. const char* op_string = nullptr;
  270. switch (m_op) {
  271. case UnaryOp::BitwiseNot:
  272. op_string = "~";
  273. break;
  274. case UnaryOp::Not:
  275. op_string = "!";
  276. break;
  277. case UnaryOp::Plus:
  278. op_string = "+";
  279. break;
  280. case UnaryOp::Minus:
  281. op_string = "-";
  282. break;
  283. case UnaryOp::PlusPlus:
  284. op_string = "++";
  285. break;
  286. default:
  287. op_string = "<invalid>";
  288. }
  289. VERIFY(op_string);
  290. print_indent(indent + 1);
  291. outln("{}", op_string);
  292. m_lhs->dump(indent + 1);
  293. }
  294. void BooleanLiteral::dump(size_t indent) const
  295. {
  296. ASTNode::dump(indent);
  297. print_indent(indent + 1);
  298. outln("{}", m_value ? "true" : "false");
  299. }
  300. void Pointer::dump(size_t indent) const
  301. {
  302. ASTNode::dump(indent);
  303. if (!m_pointee.is_null()) {
  304. m_pointee->dump(indent + 1);
  305. }
  306. }
  307. void MemberExpression::dump(size_t indent) const
  308. {
  309. ASTNode::dump(indent);
  310. m_object->dump(indent + 1);
  311. m_property->dump(indent + 1);
  312. }
  313. void BlockStatement::dump(size_t indent) const
  314. {
  315. ASTNode::dump(indent);
  316. for (auto& statement : m_statements) {
  317. statement.dump(indent + 1);
  318. }
  319. }
  320. void ForStatement::dump(size_t indent) const
  321. {
  322. ASTNode::dump(indent);
  323. if (m_init)
  324. m_init->dump(indent + 1);
  325. if (m_test)
  326. m_test->dump(indent + 1);
  327. if (m_update)
  328. m_update->dump(indent + 1);
  329. if (m_body)
  330. m_body->dump(indent + 1);
  331. }
  332. NonnullRefPtrVector<Declaration> Statement::declarations() const
  333. {
  334. if (is_declaration()) {
  335. NonnullRefPtrVector<Declaration> vec;
  336. const auto& decl = static_cast<const Declaration&>(*this);
  337. vec.empend(const_cast<Declaration&>(decl));
  338. return vec;
  339. }
  340. return {};
  341. }
  342. NonnullRefPtrVector<Declaration> ForStatement::declarations() const
  343. {
  344. auto declarations = m_init->declarations();
  345. declarations.append(m_body->declarations());
  346. return declarations;
  347. }
  348. NonnullRefPtrVector<Declaration> BlockStatement::declarations() const
  349. {
  350. NonnullRefPtrVector<Declaration> declarations;
  351. for (auto& statement : m_statements) {
  352. declarations.append(statement.declarations());
  353. }
  354. return declarations;
  355. }
  356. void IfStatement::dump(size_t indent) const
  357. {
  358. ASTNode::dump(indent);
  359. if (m_predicate) {
  360. print_indent(indent + 1);
  361. outln("Predicate:");
  362. m_predicate->dump(indent + 1);
  363. }
  364. if (m_then) {
  365. print_indent(indent + 1);
  366. outln("Then:");
  367. m_then->dump(indent + 1);
  368. }
  369. if (m_else) {
  370. print_indent(indent + 1);
  371. outln("Else:");
  372. m_else->dump(indent + 1);
  373. }
  374. }
  375. NonnullRefPtrVector<Declaration> IfStatement::declarations() const
  376. {
  377. NonnullRefPtrVector<Declaration> declarations;
  378. if (m_predicate)
  379. declarations.append(m_predicate->declarations());
  380. if (m_then)
  381. declarations.append(m_then->declarations());
  382. if (m_else)
  383. declarations.append(m_else->declarations());
  384. return declarations;
  385. }
  386. void NamespaceDeclaration::dump(size_t indent) const
  387. {
  388. ASTNode::dump(indent);
  389. print_indent(indent + 1);
  390. outln("{}", m_name);
  391. for (auto& decl : m_declarations)
  392. decl.dump(indent + 1);
  393. }
  394. }