driver.hh 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #ifndef RUBY_PARSER_DRIVER_HH
  2. #define RUBY_PARSER_DRIVER_HH
  3. #include <memory>
  4. #include "diagnostic.hh"
  5. #include "lexer.hh"
  6. #include "node.hh"
  7. namespace ruby_parser {
  8. struct builder;
  9. using ForeignPtr = const void *;
  10. using SelfPtr = const void *;
  11. struct node_list {
  12. node_list() = default;
  13. node_list(ForeignPtr node) {
  14. nodes.emplace_back(node);
  15. }
  16. node_list &operator=(const ForeignPtr &other) = delete;
  17. node_list &operator=(ForeignPtr &&other) = delete;
  18. inline size_t size() const {
  19. return nodes.size();
  20. }
  21. inline void emplace_back(const ForeignPtr &ptr) {
  22. nodes.emplace_back(ptr);
  23. }
  24. inline void push_front(const ForeignPtr &ptr) {
  25. nodes.insert(nodes.begin(), ptr);
  26. }
  27. inline ForeignPtr &at(size_t n) {
  28. return nodes.at(n);
  29. }
  30. inline void concat(node_list *other) {
  31. nodes.insert(nodes.end(), std::make_move_iterator(other->nodes.begin()),
  32. std::make_move_iterator(other->nodes.end()));
  33. }
  34. protected:
  35. std::vector<ForeignPtr> nodes;
  36. };
  37. struct delimited_node_list {
  38. delimited_node_list() = default;
  39. delimited_node_list(const token_t &begin, node_list *inner, const token_t &end)
  40. : begin(begin), inner(inner), end(end) {}
  41. token_t begin = nullptr;
  42. node_list *inner = nullptr;
  43. token_t end = nullptr;
  44. };
  45. struct delimited_block {
  46. delimited_block() = default;
  47. delimited_block(const token_t &begin, ForeignPtr args, ForeignPtr body, const token_t &end)
  48. : begin(begin), args(args), body(body), end(end) {}
  49. token_t begin = nullptr;
  50. ForeignPtr args = nullptr;
  51. ForeignPtr body = nullptr;
  52. token_t end = nullptr;
  53. };
  54. struct node_with_token {
  55. node_with_token() = default;
  56. node_with_token(const token_t &token_, ForeignPtr node_) : tok(token_), nod(node_) {}
  57. token_t tok = nullptr;
  58. ForeignPtr nod = nullptr;
  59. };
  60. struct case_body {
  61. case_body() = default;
  62. case_body(node_with_token *else_) : els(else_) {}
  63. node_list whens;
  64. node_with_token *els = nullptr;
  65. };
  66. class mempool {
  67. pool<ruby_parser::node_list, 16> _node_list;
  68. pool<ruby_parser::delimited_node_list, 32> _delimited_node_list;
  69. pool<ruby_parser::delimited_block, 32> _delimited_block;
  70. pool<ruby_parser::node_with_token, 32> _node_with_token;
  71. pool<ruby_parser::case_body, 32> _case_body;
  72. pool<ruby_parser::state_stack, 8> _stacks;
  73. friend class base_driver;
  74. public:
  75. mempool() = default;
  76. template <typename... Args> ruby_parser::node_list *node_list(Args &&... args) {
  77. return _node_list.alloc(std::forward<Args>(args)...);
  78. }
  79. template <typename... Args> ruby_parser::delimited_node_list *delimited_node_list(Args &&... args) {
  80. return _delimited_node_list.alloc(std::forward<Args>(args)...);
  81. }
  82. template <typename... Args> ruby_parser::delimited_block *delimited_block(Args &&... args) {
  83. return _delimited_block.alloc(std::forward<Args>(args)...);
  84. }
  85. template <typename... Args> ruby_parser::node_with_token *node_with_token(Args &&... args) {
  86. return _node_with_token.alloc(std::forward<Args>(args)...);
  87. }
  88. template <typename... Args> ruby_parser::case_body *case_body(Args &&... args) {
  89. return _case_body.alloc(std::forward<Args>(args)...);
  90. }
  91. };
  92. class base_driver {
  93. public:
  94. diagnostics_t diagnostics;
  95. const builder &build;
  96. lexer lex;
  97. mempool alloc;
  98. bool pending_error;
  99. size_t def_level;
  100. ForeignPtr ast;
  101. token_t last_token;
  102. base_driver(ruby_version version, const std::string &source, const struct builder &builder);
  103. virtual ~base_driver() {}
  104. virtual ForeignPtr parse(SelfPtr self) = 0;
  105. bool valid_kwarg_name(const token *name) {
  106. char c = name->string().at(0);
  107. return !(c >= 'A' && c <= 'Z');
  108. }
  109. ruby_parser::state_stack *copy_stack() {
  110. return alloc._stacks.alloc(lex.cmdarg);
  111. }
  112. void replace_stack(ruby_parser::state_stack *stack) {
  113. lex.cmdarg = *stack;
  114. }
  115. void external_diagnostic(dlevel lvl, dclass cls, size_t begin, size_t end, const std::string &msg) {
  116. diagnostics.emplace_back(lvl, cls, diagnostic::range(begin, end), msg);
  117. if (lvl == dlevel::ERROR) {
  118. pending_error = true;
  119. }
  120. }
  121. };
  122. class typedruby25 : public base_driver {
  123. public:
  124. typedruby25(const std::string &source, const struct builder &builder);
  125. virtual ForeignPtr parse(SelfPtr self);
  126. ~typedruby25() {}
  127. };
  128. } // namespace ruby_parser
  129. #endif