AST.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. /*
  2. * Copyright (c) 2021, Itamar S. <itamar8910@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "AST.h"
  7. namespace Cpp {
  8. static void print_indent(int indent)
  9. {
  10. for (int i = 0; i < indent * 2; ++i)
  11. out(" ");
  12. }
  13. void ASTNode::dump(size_t indent) const
  14. {
  15. print_indent(indent);
  16. outln("{}[{}:{}->{}:{}]", class_name(), start().line, start().column, end().line, end().column);
  17. }
  18. void TranslationUnit::dump(size_t indent) const
  19. {
  20. ASTNode::dump(indent);
  21. for (const auto& child : m_declarations) {
  22. child.dump(indent + 1);
  23. }
  24. }
  25. void FunctionDeclaration::dump(size_t indent) const
  26. {
  27. ASTNode::dump(indent);
  28. String qualifiers_string;
  29. if (!m_qualifiers.is_empty()) {
  30. print_indent(indent + 1);
  31. outln("[{}]", String::join(" ", m_qualifiers));
  32. }
  33. m_return_type->dump(indent + 1);
  34. if (!m_name.is_null()) {
  35. print_indent(indent + 1);
  36. outln("{}", m_name);
  37. }
  38. print_indent(indent + 1);
  39. outln("(");
  40. for (const auto& arg : m_parameters) {
  41. arg.dump(indent + 1);
  42. }
  43. print_indent(indent + 1);
  44. outln(")");
  45. if (!m_definition.is_null()) {
  46. m_definition->dump(indent + 1);
  47. }
  48. }
  49. NonnullRefPtrVector<Declaration> FunctionDeclaration::declarations() const
  50. {
  51. NonnullRefPtrVector<Declaration> declarations;
  52. for (auto& arg : m_parameters) {
  53. declarations.append(arg);
  54. }
  55. return declarations;
  56. }
  57. void Type::dump(size_t indent) const
  58. {
  59. ASTNode::dump(indent);
  60. print_indent(indent + 1);
  61. outln("{}", to_string());
  62. }
  63. String Type::to_string() const
  64. {
  65. String qualifiers_string;
  66. if (!m_qualifiers.is_empty())
  67. qualifiers_string = String::formatted("[{}] ", String::join(" ", m_qualifiers));
  68. String name;
  69. if (m_is_auto)
  70. name = "auto";
  71. else
  72. name = m_name.is_null() ? "" : m_name->full_name();
  73. return String::formatted("{}{}", qualifiers_string, name);
  74. }
  75. String Pointer::to_string() const
  76. {
  77. if (!m_pointee)
  78. return {};
  79. StringBuilder builder;
  80. builder.append(m_pointee->to_string());
  81. builder.append("*");
  82. return builder.to_string();
  83. }
  84. void Parameter::dump(size_t indent) const
  85. {
  86. ASTNode::dump(indent);
  87. if (m_is_ellipsis) {
  88. print_indent(indent + 1);
  89. outln("...");
  90. }
  91. if (!m_name.is_null()) {
  92. print_indent(indent);
  93. outln("{}", m_name);
  94. }
  95. if (m_type)
  96. m_type->dump(indent + 1);
  97. }
  98. void FunctionDefinition::dump(size_t indent) const
  99. {
  100. ASTNode::dump(indent);
  101. print_indent(indent);
  102. outln("{{");
  103. for (const auto& statement : m_statements) {
  104. statement.dump(indent + 1);
  105. }
  106. print_indent(indent);
  107. outln("}}");
  108. }
  109. NonnullRefPtrVector<Declaration> FunctionDefinition::declarations() const
  110. {
  111. NonnullRefPtrVector<Declaration> declarations;
  112. for (auto& statement : m_statements) {
  113. declarations.append(statement.declarations());
  114. }
  115. return declarations;
  116. }
  117. void VariableDeclaration::dump(size_t indent) const
  118. {
  119. ASTNode::dump(indent);
  120. if (m_type)
  121. m_type->dump(indent + 1);
  122. print_indent(indent + 1);
  123. outln("{}", m_name);
  124. if (m_initial_value)
  125. m_initial_value->dump(indent + 1);
  126. }
  127. void Identifier::dump(size_t indent) const
  128. {
  129. ASTNode::dump(indent);
  130. print_indent(indent);
  131. outln("{}", m_name);
  132. }
  133. void NumericLiteral::dump(size_t indent) const
  134. {
  135. ASTNode::dump(indent);
  136. print_indent(indent);
  137. outln("{}", m_value);
  138. }
  139. void BinaryExpression::dump(size_t indent) const
  140. {
  141. ASTNode::dump(indent);
  142. const char* op_string = nullptr;
  143. switch (m_op) {
  144. case BinaryOp::Addition:
  145. op_string = "+";
  146. break;
  147. case BinaryOp::Subtraction:
  148. op_string = "-";
  149. break;
  150. case BinaryOp::Multiplication:
  151. op_string = "*";
  152. break;
  153. case BinaryOp::Division:
  154. op_string = "/";
  155. break;
  156. case BinaryOp::Modulo:
  157. op_string = "%";
  158. break;
  159. case BinaryOp::GreaterThan:
  160. op_string = ">";
  161. break;
  162. case BinaryOp::GreaterThanEquals:
  163. op_string = ">=";
  164. break;
  165. case BinaryOp::LessThan:
  166. op_string = "<";
  167. break;
  168. case BinaryOp::LessThanEquals:
  169. op_string = "<=";
  170. break;
  171. case BinaryOp::BitwiseAnd:
  172. op_string = "&";
  173. break;
  174. case BinaryOp::BitwiseOr:
  175. op_string = "|";
  176. break;
  177. case BinaryOp::BitwiseXor:
  178. op_string = "^";
  179. break;
  180. case BinaryOp::LeftShift:
  181. op_string = "<<";
  182. break;
  183. case BinaryOp::RightShift:
  184. op_string = ">>";
  185. break;
  186. case BinaryOp::EqualsEquals:
  187. op_string = "==";
  188. break;
  189. case BinaryOp::NotEqual:
  190. op_string = "!=";
  191. break;
  192. case BinaryOp::LogicalOr:
  193. op_string = "||";
  194. break;
  195. case BinaryOp::LogicalAnd:
  196. op_string = "&&";
  197. break;
  198. case BinaryOp::Arrow:
  199. op_string = "->";
  200. break;
  201. }
  202. m_lhs->dump(indent + 1);
  203. print_indent(indent + 1);
  204. VERIFY(op_string);
  205. outln("{}", op_string);
  206. m_rhs->dump(indent + 1);
  207. }
  208. void AssignmentExpression::dump(size_t indent) const
  209. {
  210. ASTNode::dump(indent);
  211. const char* op_string = nullptr;
  212. switch (m_op) {
  213. case AssignmentOp::Assignment:
  214. op_string = "=";
  215. break;
  216. case AssignmentOp::AdditionAssignment:
  217. op_string = "+=";
  218. break;
  219. case AssignmentOp::SubtractionAssignment:
  220. op_string = "-=";
  221. break;
  222. }
  223. m_lhs->dump(indent + 1);
  224. print_indent(indent + 1);
  225. VERIFY(op_string);
  226. outln("{}", op_string);
  227. m_rhs->dump(indent + 1);
  228. }
  229. void FunctionCall::dump(size_t indent) const
  230. {
  231. ASTNode::dump(indent);
  232. m_callee->dump(indent + 1);
  233. for (const auto& arg : m_arguments) {
  234. arg.dump(indent + 1);
  235. }
  236. }
  237. void StringLiteral::dump(size_t indent) const
  238. {
  239. ASTNode::dump(indent);
  240. print_indent(indent + 1);
  241. outln("{}", m_value);
  242. }
  243. void ReturnStatement::dump(size_t indent) const
  244. {
  245. ASTNode::dump(indent);
  246. if (m_value)
  247. m_value->dump(indent + 1);
  248. }
  249. void EnumDeclaration::dump(size_t indent) const
  250. {
  251. ASTNode::dump(indent);
  252. print_indent(indent);
  253. outln("{}", m_name);
  254. for (auto& entry : m_entries) {
  255. print_indent(indent + 1);
  256. outln("{}", entry);
  257. }
  258. }
  259. void StructOrClassDeclaration::dump(size_t indent) const
  260. {
  261. ASTNode::dump(indent);
  262. print_indent(indent);
  263. outln("{}", m_name);
  264. for (auto& member : m_members) {
  265. member.dump(indent + 1);
  266. }
  267. }
  268. NonnullRefPtrVector<Declaration> StructOrClassDeclaration::declarations() const
  269. {
  270. NonnullRefPtrVector<Declaration> declarations;
  271. for (auto& member : m_members)
  272. declarations.append(member);
  273. return declarations;
  274. }
  275. void MemberDeclaration::dump(size_t indent) const
  276. {
  277. ASTNode::dump(indent);
  278. m_type->dump(indent + 1);
  279. print_indent(indent + 1);
  280. outln("{}", m_name);
  281. if (m_initial_value) {
  282. m_initial_value->dump(indent + 2);
  283. }
  284. }
  285. void UnaryExpression::dump(size_t indent) const
  286. {
  287. ASTNode::dump(indent);
  288. const char* op_string = nullptr;
  289. switch (m_op) {
  290. case UnaryOp::BitwiseNot:
  291. op_string = "~";
  292. break;
  293. case UnaryOp::Not:
  294. op_string = "!";
  295. break;
  296. case UnaryOp::Plus:
  297. op_string = "+";
  298. break;
  299. case UnaryOp::Minus:
  300. op_string = "-";
  301. break;
  302. case UnaryOp::PlusPlus:
  303. op_string = "++";
  304. break;
  305. case UnaryOp::Address:
  306. op_string = "&";
  307. break;
  308. default:
  309. op_string = "<invalid>";
  310. }
  311. VERIFY(op_string);
  312. print_indent(indent + 1);
  313. outln("{}", op_string);
  314. m_lhs->dump(indent + 1);
  315. }
  316. void BooleanLiteral::dump(size_t indent) const
  317. {
  318. ASTNode::dump(indent);
  319. print_indent(indent + 1);
  320. outln("{}", m_value ? "true" : "false");
  321. }
  322. void Pointer::dump(size_t indent) const
  323. {
  324. ASTNode::dump(indent);
  325. if (!m_pointee.is_null()) {
  326. m_pointee->dump(indent + 1);
  327. }
  328. }
  329. void MemberExpression::dump(size_t indent) const
  330. {
  331. ASTNode::dump(indent);
  332. m_object->dump(indent + 1);
  333. m_property->dump(indent + 1);
  334. }
  335. void BlockStatement::dump(size_t indent) const
  336. {
  337. ASTNode::dump(indent);
  338. for (auto& statement : m_statements) {
  339. statement.dump(indent + 1);
  340. }
  341. }
  342. void ForStatement::dump(size_t indent) const
  343. {
  344. ASTNode::dump(indent);
  345. if (m_init)
  346. m_init->dump(indent + 1);
  347. if (m_test)
  348. m_test->dump(indent + 1);
  349. if (m_update)
  350. m_update->dump(indent + 1);
  351. if (m_body)
  352. m_body->dump(indent + 1);
  353. }
  354. NonnullRefPtrVector<Declaration> Statement::declarations() const
  355. {
  356. if (is_declaration()) {
  357. NonnullRefPtrVector<Declaration> vec;
  358. const auto& decl = static_cast<const Declaration&>(*this);
  359. vec.empend(const_cast<Declaration&>(decl));
  360. return vec;
  361. }
  362. return {};
  363. }
  364. NonnullRefPtrVector<Declaration> ForStatement::declarations() const
  365. {
  366. NonnullRefPtrVector<Declaration> declarations;
  367. if (m_init)
  368. declarations.append(m_init->declarations());
  369. if (m_body)
  370. declarations.append(m_body->declarations());
  371. return declarations;
  372. }
  373. NonnullRefPtrVector<Declaration> BlockStatement::declarations() const
  374. {
  375. NonnullRefPtrVector<Declaration> declarations;
  376. for (auto& statement : m_statements) {
  377. declarations.append(statement.declarations());
  378. }
  379. return declarations;
  380. }
  381. void IfStatement::dump(size_t indent) const
  382. {
  383. ASTNode::dump(indent);
  384. if (m_predicate) {
  385. print_indent(indent + 1);
  386. outln("Predicate:");
  387. m_predicate->dump(indent + 1);
  388. }
  389. if (m_then) {
  390. print_indent(indent + 1);
  391. outln("Then:");
  392. m_then->dump(indent + 1);
  393. }
  394. if (m_else) {
  395. print_indent(indent + 1);
  396. outln("Else:");
  397. m_else->dump(indent + 1);
  398. }
  399. }
  400. NonnullRefPtrVector<Declaration> IfStatement::declarations() const
  401. {
  402. NonnullRefPtrVector<Declaration> declarations;
  403. if (m_predicate)
  404. declarations.append(m_predicate->declarations());
  405. if (m_then)
  406. declarations.append(m_then->declarations());
  407. if (m_else)
  408. declarations.append(m_else->declarations());
  409. return declarations;
  410. }
  411. void NamespaceDeclaration::dump(size_t indent) const
  412. {
  413. ASTNode::dump(indent);
  414. print_indent(indent + 1);
  415. outln("{}", m_name);
  416. for (auto& decl : m_declarations)
  417. decl.dump(indent + 1);
  418. }
  419. void NullPointerLiteral::dump(size_t indent) const
  420. {
  421. ASTNode::dump(indent);
  422. }
  423. void Name::dump(size_t indent) const
  424. {
  425. ASTNode::dump(indent);
  426. print_indent(indent);
  427. outln("{}", full_name());
  428. }
  429. String Name::full_name() const
  430. {
  431. StringBuilder builder;
  432. if (!m_scope.is_empty()) {
  433. for (auto& scope : m_scope) {
  434. builder.appendff("{}::", scope.m_name);
  435. }
  436. }
  437. return String::formatted("{}{}", builder.to_string(), m_name.is_null() ? "" : m_name->m_name);
  438. }
  439. String TemplatizedName::full_name() const
  440. {
  441. StringBuilder name;
  442. name.append(Name::full_name());
  443. name.append('<');
  444. for (auto& type : m_template_arguments) {
  445. name.append(type.to_string());
  446. }
  447. name.append('>');
  448. return name.to_string();
  449. }
  450. void CppCastExpression::dump(size_t indent) const
  451. {
  452. ASTNode::dump(indent);
  453. print_indent(indent);
  454. outln("{}", m_cast_type);
  455. print_indent(indent + 1);
  456. outln("<");
  457. if (m_type)
  458. m_type->dump(indent + 1);
  459. print_indent(indent + 1);
  460. outln(">");
  461. if (m_expression)
  462. m_expression->dump(indent + 1);
  463. }
  464. void SizeofExpression::dump(size_t indent) const
  465. {
  466. ASTNode::dump(indent);
  467. if (m_type)
  468. m_type->dump(indent + 1);
  469. }
  470. void BracedInitList::dump(size_t indent) const
  471. {
  472. ASTNode::dump(indent);
  473. for (auto& exp : m_expressions) {
  474. exp.dump(indent + 1);
  475. }
  476. }
  477. void CStyleCastExpression::dump(size_t indent) const
  478. {
  479. ASTNode::dump(indent);
  480. if (m_type)
  481. m_type->dump(indent + 1);
  482. if (m_expression)
  483. m_expression->dump(indent + 1);
  484. }
  485. }