AST.cpp 13 KB

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