AST.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. /*
  2. * Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Badge.h>
  8. #include <AK/RefCounted.h>
  9. #include <AK/RefPtr.h>
  10. #include <AK/Vector.h>
  11. #include "Forward.h"
  12. namespace JSSpecCompiler {
  13. template<typename T>
  14. RefPtr<T> as(NullableTree const& tree)
  15. {
  16. return dynamic_cast<T*>(tree.ptr());
  17. }
  18. class NodeSubtreePointer {
  19. public:
  20. NodeSubtreePointer(Tree* tree_ptr)
  21. : m_tree_ptr(tree_ptr)
  22. {
  23. }
  24. NodeSubtreePointer(NullableTree* tree_ptr)
  25. : m_tree_ptr(tree_ptr)
  26. {
  27. }
  28. NodeSubtreePointer(VariableRef* tree_ptr)
  29. : m_tree_ptr(tree_ptr)
  30. {
  31. }
  32. Tree get(Badge<RecursiveASTVisitor>);
  33. void replace_subtree(Badge<RecursiveASTVisitor>, NullableTree replacement);
  34. private:
  35. Variant<Tree*, NullableTree*, VariableRef*> m_tree_ptr;
  36. };
  37. class VariableDeclaration : public RefCounted<VariableDeclaration> {
  38. public:
  39. virtual ~VariableDeclaration() = default;
  40. };
  41. class NamedVariableDeclaration : public VariableDeclaration {
  42. public:
  43. NamedVariableDeclaration(StringView name)
  44. : m_name(name)
  45. {
  46. }
  47. StringView m_name;
  48. };
  49. class SSAVariableDeclaration : public VariableDeclaration {
  50. public:
  51. SSAVariableDeclaration(u64 version)
  52. : m_version(version)
  53. {
  54. }
  55. size_t m_index = 0;
  56. u64 m_version;
  57. };
  58. class Node : public RefCounted<Node> {
  59. public:
  60. virtual ~Node() = default;
  61. void format_tree(StringBuilder& builder);
  62. // For expressions, order must be the same as the evaluation order.
  63. virtual Vector<NodeSubtreePointer> subtrees() { return {}; }
  64. virtual bool is_list() const { return false; }
  65. virtual bool is_statement() { VERIFY_NOT_REACHED(); }
  66. protected:
  67. template<typename... Parameters>
  68. void dump_node(StringBuilder& builder, AK::CheckedFormatString<Parameters...>&& fmtstr, Parameters const&... parameters);
  69. virtual void dump_tree(StringBuilder& builder) = 0;
  70. };
  71. // Although both statements and expressions are allowed to return value, CFG building differentiates
  72. // between them. Expressions are not allowed to change control flow, while statements are. Special
  73. // handling required if a statement turns out to be a descendant of an expression. Roughly speaking,
  74. // from the CFG standpoint, something like `a = ({ b + ({ c }) }) + ({ d })` will look like
  75. // ```
  76. // auto tmp1 = c;
  77. // auto tmp2 = b + tmp1;
  78. // auto tmp3 = d;
  79. // a = tmp1 + tmp2;
  80. // ```.
  81. class Statement : public Node {
  82. public:
  83. bool is_statement() override { return true; }
  84. };
  85. class Expression : public Node {
  86. public:
  87. bool is_statement() override { return false; }
  88. };
  89. class ControlFlowOperator : public Statement {
  90. public:
  91. bool is_statement() override { return false; }
  92. virtual Vector<BasicBlockRef*> references() = 0;
  93. };
  94. class ErrorNode : public Expression {
  95. public:
  96. ErrorNode(StringView error = ""sv)
  97. : m_error(error)
  98. {
  99. }
  100. StringView m_error;
  101. protected:
  102. void dump_tree(StringBuilder& builder) override;
  103. };
  104. class WellKnownNode : public Expression {
  105. public:
  106. enum Type {
  107. ZeroArgumentFunctionCall,
  108. // Update WellKnownNode::dump_tree after adding an entry here
  109. };
  110. WellKnownNode(Type type)
  111. : m_type(type)
  112. {
  113. }
  114. protected:
  115. void dump_tree(StringBuilder& builder) override;
  116. private:
  117. Type m_type;
  118. };
  119. inline Tree const error_tree = make_ref_counted<ErrorNode>();
  120. inline Tree const zero_argument_function_call = make_ref_counted<WellKnownNode>(WellKnownNode::ZeroArgumentFunctionCall);
  121. class ControlFlowFunctionReturn : public ControlFlowOperator {
  122. public:
  123. ControlFlowFunctionReturn(VariableRef return_value)
  124. : m_return_value(move(return_value))
  125. {
  126. }
  127. VariableRef m_return_value;
  128. Vector<NodeSubtreePointer> subtrees() override { return { { &m_return_value } }; }
  129. Vector<BasicBlockRef*> references() override { return {}; }
  130. protected:
  131. void dump_tree(StringBuilder& builder) override;
  132. };
  133. class ControlFlowJump : public ControlFlowOperator {
  134. public:
  135. ControlFlowJump(BasicBlockRef block)
  136. : m_block(block)
  137. {
  138. }
  139. Vector<BasicBlockRef*> references() override;
  140. BasicBlockRef m_block;
  141. protected:
  142. void dump_tree(StringBuilder& builder) override;
  143. };
  144. // This should be invalid enough to crash program on use.
  145. inline NonnullRefPtr<ControlFlowOperator> const invalid_continuation = make_ref_counted<ControlFlowJump>(nullptr);
  146. class ControlFlowBranch : public ControlFlowOperator {
  147. public:
  148. ControlFlowBranch(Tree condition, BasicBlockRef then, BasicBlockRef else_)
  149. : m_condition(move(condition))
  150. , m_then(then)
  151. , m_else(else_)
  152. {
  153. }
  154. Vector<NodeSubtreePointer> subtrees() override { return { { &m_condition } }; }
  155. Vector<BasicBlockRef*> references() override;
  156. Tree m_condition;
  157. BasicBlockRef m_then;
  158. BasicBlockRef m_else;
  159. protected:
  160. void dump_tree(StringBuilder& builder) override;
  161. };
  162. class MathematicalConstant : public Expression {
  163. public:
  164. MathematicalConstant(i64 number)
  165. : m_number(number)
  166. {
  167. }
  168. // TODO: This should be able to hold arbitrary number
  169. i64 m_number;
  170. protected:
  171. void dump_tree(StringBuilder& builder) override;
  172. };
  173. class StringLiteral : public Expression {
  174. public:
  175. StringLiteral(StringView literal)
  176. : m_literal(literal)
  177. {
  178. }
  179. StringView m_literal;
  180. protected:
  181. void dump_tree(StringBuilder& builder) override;
  182. };
  183. #define ENUMERATE_UNARY_OPERATORS(F) \
  184. F(Invalid) \
  185. F(Minus) \
  186. F(AssertCompletion)
  187. #define ENUMERATE_BINARY_OPERATORS(F) \
  188. F(Invalid) \
  189. F(CompareLess) \
  190. F(CompareGreater) \
  191. F(CompareNotEqual) \
  192. F(CompareEqual) \
  193. F(Assignment) \
  194. F(Declaration) \
  195. F(Plus) \
  196. F(Minus) \
  197. F(Multiplication) \
  198. F(Division) \
  199. F(Comma) \
  200. F(MemberAccess) \
  201. F(FunctionCall) \
  202. F(ArraySubscript)
  203. #define NAME(name) name,
  204. #define STRINGIFY(name) #name##sv,
  205. enum class UnaryOperator {
  206. ENUMERATE_UNARY_OPERATORS(NAME)
  207. };
  208. inline constexpr StringView unary_operator_names[] = {
  209. ENUMERATE_UNARY_OPERATORS(STRINGIFY)
  210. };
  211. enum class BinaryOperator {
  212. #define NAME(name) name,
  213. ENUMERATE_BINARY_OPERATORS(NAME)
  214. };
  215. inline constexpr StringView binary_operator_names[] = {
  216. ENUMERATE_BINARY_OPERATORS(STRINGIFY)
  217. };
  218. #undef NAME
  219. #undef STRINGIFY
  220. class BinaryOperation : public Expression {
  221. public:
  222. BinaryOperation(BinaryOperator operation, Tree left, Tree right)
  223. : m_operation(operation)
  224. , m_left(move(left))
  225. , m_right(move(right))
  226. {
  227. }
  228. Vector<NodeSubtreePointer> subtrees() override;
  229. BinaryOperator m_operation;
  230. Tree m_left;
  231. Tree m_right;
  232. protected:
  233. void dump_tree(StringBuilder& builder) override;
  234. };
  235. class UnaryOperation : public Expression {
  236. public:
  237. UnaryOperation(UnaryOperator operation, Tree operand)
  238. : m_operation(operation)
  239. , m_operand(move(operand))
  240. {
  241. }
  242. Vector<NodeSubtreePointer> subtrees() override;
  243. UnaryOperator m_operation;
  244. Tree m_operand;
  245. protected:
  246. void dump_tree(StringBuilder& builder) override;
  247. };
  248. class IsOneOfOperation : public Expression {
  249. public:
  250. IsOneOfOperation(Tree operand, Vector<Tree>&& compare_values)
  251. : m_operand(move(operand))
  252. , m_compare_values(move(compare_values))
  253. {
  254. }
  255. Vector<NodeSubtreePointer> subtrees() override;
  256. Tree m_operand;
  257. Vector<Tree> m_compare_values;
  258. protected:
  259. void dump_tree(StringBuilder& builder) override;
  260. };
  261. class UnresolvedReference : public Expression {
  262. public:
  263. UnresolvedReference(StringView name)
  264. : m_name(name)
  265. {
  266. }
  267. StringView m_name;
  268. protected:
  269. void dump_tree(StringBuilder& builder) override;
  270. };
  271. class ReturnNode : public Node {
  272. public:
  273. ReturnNode(Tree return_value)
  274. : m_return_value(move(return_value))
  275. {
  276. }
  277. Vector<NodeSubtreePointer> subtrees() override;
  278. Tree m_return_value;
  279. protected:
  280. void dump_tree(StringBuilder& builder) override;
  281. };
  282. // Although assert might seems a good candidate for ControlFlowOperator, we are not interested in
  283. // tracking control flow after a failed assertion.
  284. class AssertExpression : public Expression {
  285. public:
  286. AssertExpression(Tree condition)
  287. : m_condition(move(condition))
  288. {
  289. }
  290. Vector<NodeSubtreePointer> subtrees() override;
  291. Tree m_condition;
  292. protected:
  293. void dump_tree(StringBuilder& builder) override;
  294. };
  295. class IfBranch : public Node {
  296. public:
  297. IfBranch(Tree condition, Tree branch)
  298. : m_condition(move(condition))
  299. , m_branch(move(branch))
  300. {
  301. }
  302. Vector<NodeSubtreePointer> subtrees() override;
  303. Tree m_condition;
  304. Tree m_branch;
  305. protected:
  306. void dump_tree(StringBuilder& builder) override;
  307. };
  308. class ElseIfBranch : public Node {
  309. public:
  310. ElseIfBranch(NullableTree condition, Tree branch)
  311. : m_condition(move(condition))
  312. , m_branch(move(branch))
  313. {
  314. }
  315. Vector<NodeSubtreePointer> subtrees() override;
  316. NullableTree m_condition;
  317. Tree m_branch;
  318. protected:
  319. void dump_tree(StringBuilder& builder) override;
  320. };
  321. class IfElseIfChain : public Statement {
  322. public:
  323. IfElseIfChain(Vector<Tree>&& conditions, Vector<Tree>&& branches, NullableTree else_branch)
  324. : m_conditions(move(conditions))
  325. , m_branches(move(branches))
  326. , m_else_branch(move(else_branch))
  327. {
  328. VERIFY(m_branches.size() == m_conditions.size());
  329. }
  330. Vector<NodeSubtreePointer> subtrees() override;
  331. // Excluding else branch, if one is present
  332. size_t branches_count() const { return m_branches.size(); }
  333. Vector<Tree> m_conditions;
  334. Vector<Tree> m_branches;
  335. NullableTree m_else_branch;
  336. protected:
  337. void dump_tree(StringBuilder& builder) override;
  338. };
  339. class TreeList : public Statement {
  340. public:
  341. TreeList(Vector<Tree>&& trees);
  342. Vector<NodeSubtreePointer> subtrees() override;
  343. bool is_list() const override { return true; }
  344. Vector<Tree> m_trees;
  345. protected:
  346. void dump_tree(StringBuilder& builder) override;
  347. };
  348. class RecordDirectListInitialization : public Expression {
  349. public:
  350. struct Argument {
  351. Tree name;
  352. Tree value;
  353. };
  354. RecordDirectListInitialization(Tree type_reference, Vector<Argument>&& arguments)
  355. : m_type_reference(move(type_reference))
  356. , m_arguments(move(arguments))
  357. {
  358. }
  359. Vector<NodeSubtreePointer> subtrees() override;
  360. Tree m_type_reference;
  361. Vector<Argument> m_arguments;
  362. protected:
  363. void dump_tree(StringBuilder& builder) override;
  364. };
  365. class FunctionCall : public Expression {
  366. public:
  367. FunctionCall(Tree name, Vector<Tree>&& arguments)
  368. : m_name(move(name))
  369. , m_arguments(move(arguments))
  370. {
  371. }
  372. Vector<NodeSubtreePointer> subtrees() override;
  373. Tree m_name;
  374. Vector<Tree> m_arguments;
  375. protected:
  376. void dump_tree(StringBuilder& builder) override;
  377. };
  378. class SlotName : public Expression {
  379. public:
  380. SlotName(StringView member_name)
  381. : m_member_name(member_name)
  382. {
  383. }
  384. StringView m_member_name;
  385. protected:
  386. void dump_tree(StringBuilder& builder) override;
  387. };
  388. class Variable : public Expression {
  389. public:
  390. Variable(NamedVariableDeclarationRef name)
  391. : m_name(move(name))
  392. {
  393. }
  394. NamedVariableDeclarationRef m_name;
  395. SSAVariableDeclarationRef m_ssa;
  396. String name() const;
  397. protected:
  398. void dump_tree(StringBuilder& builder) override;
  399. };
  400. class FunctionPointer : public Expression {
  401. public:
  402. FunctionPointer(FunctionDeclarationRef declaration)
  403. : m_declaration(declaration)
  404. {
  405. }
  406. FunctionDeclarationRef m_declaration;
  407. protected:
  408. void dump_tree(StringBuilder& builder) override;
  409. };
  410. }
  411. namespace AK {
  412. template<>
  413. struct Formatter<JSSpecCompiler::Tree> : Formatter<StringView> {
  414. ErrorOr<void> format(FormatBuilder& builder, JSSpecCompiler::Tree const& tree)
  415. {
  416. tree->format_tree(builder.builder());
  417. return {};
  418. }
  419. };
  420. }