natalie_parser 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +22 -0
  3. data/Dockerfile +26 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE +21 -0
  6. data/README.md +55 -0
  7. data/Rakefile +242 -0
  8. data/ext/natalie_parser/extconf.rb +9 -0
  9. data/ext/natalie_parser/mri_creator.hpp +139 -0
  10. data/ext/natalie_parser/natalie_parser.cpp +144 -0
  11. data/include/natalie_parser/creator/debug_creator.hpp +113 -0
  12. data/include/natalie_parser/creator.hpp +108 -0
  13. data/include/natalie_parser/lexer/interpolated_string_lexer.hpp +64 -0
  14. data/include/natalie_parser/lexer/regexp_lexer.hpp +37 -0
  15. data/include/natalie_parser/lexer/word_array_lexer.hpp +57 -0
  16. data/include/natalie_parser/lexer.hpp +135 -0
  17. data/include/natalie_parser/node/alias_node.hpp +35 -0
  18. data/include/natalie_parser/node/arg_node.hpp +74 -0
  19. data/include/natalie_parser/node/array_node.hpp +34 -0
  20. data/include/natalie_parser/node/array_pattern_node.hpp +28 -0
  21. data/include/natalie_parser/node/assignment_node.hpp +34 -0
  22. data/include/natalie_parser/node/back_ref_node.hpp +28 -0
  23. data/include/natalie_parser/node/begin_block_node.hpp +25 -0
  24. data/include/natalie_parser/node/begin_node.hpp +52 -0
  25. data/include/natalie_parser/node/begin_rescue_node.hpp +47 -0
  26. data/include/natalie_parser/node/bignum_node.hpp +37 -0
  27. data/include/natalie_parser/node/block_node.hpp +55 -0
  28. data/include/natalie_parser/node/block_pass_node.hpp +33 -0
  29. data/include/natalie_parser/node/break_node.hpp +32 -0
  30. data/include/natalie_parser/node/call_node.hpp +85 -0
  31. data/include/natalie_parser/node/case_in_node.hpp +40 -0
  32. data/include/natalie_parser/node/case_node.hpp +52 -0
  33. data/include/natalie_parser/node/case_when_node.hpp +43 -0
  34. data/include/natalie_parser/node/class_node.hpp +39 -0
  35. data/include/natalie_parser/node/colon2_node.hpp +44 -0
  36. data/include/natalie_parser/node/colon3_node.hpp +34 -0
  37. data/include/natalie_parser/node/constant_node.hpp +26 -0
  38. data/include/natalie_parser/node/def_node.hpp +55 -0
  39. data/include/natalie_parser/node/defined_node.hpp +33 -0
  40. data/include/natalie_parser/node/encoding_node.hpp +26 -0
  41. data/include/natalie_parser/node/end_block_node.hpp +25 -0
  42. data/include/natalie_parser/node/evaluate_to_string_node.hpp +37 -0
  43. data/include/natalie_parser/node/false_node.hpp +23 -0
  44. data/include/natalie_parser/node/fixnum_node.hpp +36 -0
  45. data/include/natalie_parser/node/float_node.hpp +36 -0
  46. data/include/natalie_parser/node/hash_node.hpp +34 -0
  47. data/include/natalie_parser/node/hash_pattern_node.hpp +27 -0
  48. data/include/natalie_parser/node/identifier_node.hpp +123 -0
  49. data/include/natalie_parser/node/if_node.hpp +43 -0
  50. data/include/natalie_parser/node/infix_op_node.hpp +46 -0
  51. data/include/natalie_parser/node/interpolated_node.hpp +33 -0
  52. data/include/natalie_parser/node/interpolated_regexp_node.hpp +28 -0
  53. data/include/natalie_parser/node/interpolated_shell_node.hpp +22 -0
  54. data/include/natalie_parser/node/interpolated_string_node.hpp +31 -0
  55. data/include/natalie_parser/node/interpolated_symbol_key_node.hpp +18 -0
  56. data/include/natalie_parser/node/interpolated_symbol_node.hpp +28 -0
  57. data/include/natalie_parser/node/iter_node.hpp +45 -0
  58. data/include/natalie_parser/node/keyword_arg_node.hpp +25 -0
  59. data/include/natalie_parser/node/keyword_splat_node.hpp +38 -0
  60. data/include/natalie_parser/node/logical_and_node.hpp +40 -0
  61. data/include/natalie_parser/node/logical_or_node.hpp +40 -0
  62. data/include/natalie_parser/node/match_node.hpp +38 -0
  63. data/include/natalie_parser/node/module_node.hpp +32 -0
  64. data/include/natalie_parser/node/multiple_assignment_arg_node.hpp +32 -0
  65. data/include/natalie_parser/node/multiple_assignment_node.hpp +37 -0
  66. data/include/natalie_parser/node/next_node.hpp +37 -0
  67. data/include/natalie_parser/node/nil_node.hpp +23 -0
  68. data/include/natalie_parser/node/nil_sexp_node.hpp +23 -0
  69. data/include/natalie_parser/node/node.hpp +155 -0
  70. data/include/natalie_parser/node/node_with_args.hpp +47 -0
  71. data/include/natalie_parser/node/not_match_node.hpp +35 -0
  72. data/include/natalie_parser/node/not_node.hpp +37 -0
  73. data/include/natalie_parser/node/nth_ref_node.hpp +27 -0
  74. data/include/natalie_parser/node/op_assign_accessor_node.hpp +74 -0
  75. data/include/natalie_parser/node/op_assign_and_node.hpp +34 -0
  76. data/include/natalie_parser/node/op_assign_node.hpp +47 -0
  77. data/include/natalie_parser/node/op_assign_or_node.hpp +34 -0
  78. data/include/natalie_parser/node/pin_node.hpp +33 -0
  79. data/include/natalie_parser/node/range_node.hpp +52 -0
  80. data/include/natalie_parser/node/redo_node.hpp +20 -0
  81. data/include/natalie_parser/node/regexp_node.hpp +36 -0
  82. data/include/natalie_parser/node/retry_node.hpp +20 -0
  83. data/include/natalie_parser/node/return_node.hpp +34 -0
  84. data/include/natalie_parser/node/safe_call_node.hpp +31 -0
  85. data/include/natalie_parser/node/sclass_node.hpp +37 -0
  86. data/include/natalie_parser/node/self_node.hpp +23 -0
  87. data/include/natalie_parser/node/shadow_arg_node.hpp +40 -0
  88. data/include/natalie_parser/node/shell_node.hpp +32 -0
  89. data/include/natalie_parser/node/splat_node.hpp +39 -0
  90. data/include/natalie_parser/node/splat_value_node.hpp +32 -0
  91. data/include/natalie_parser/node/stabby_proc_node.hpp +29 -0
  92. data/include/natalie_parser/node/string_node.hpp +42 -0
  93. data/include/natalie_parser/node/super_node.hpp +44 -0
  94. data/include/natalie_parser/node/symbol_key_node.hpp +19 -0
  95. data/include/natalie_parser/node/symbol_node.hpp +30 -0
  96. data/include/natalie_parser/node/to_array_node.hpp +33 -0
  97. data/include/natalie_parser/node/true_node.hpp +23 -0
  98. data/include/natalie_parser/node/unary_op_node.hpp +41 -0
  99. data/include/natalie_parser/node/undef_node.hpp +31 -0
  100. data/include/natalie_parser/node/until_node.hpp +21 -0
  101. data/include/natalie_parser/node/while_node.hpp +52 -0
  102. data/include/natalie_parser/node/yield_node.hpp +29 -0
  103. data/include/natalie_parser/node.hpp +89 -0
  104. data/include/natalie_parser/parser.hpp +218 -0
  105. data/include/natalie_parser/token.hpp +842 -0
  106. data/include/tm/defer.hpp +34 -0
  107. data/include/tm/hashmap.hpp +826 -0
  108. data/include/tm/macros.hpp +16 -0
  109. data/include/tm/optional.hpp +223 -0
  110. data/include/tm/owned_ptr.hpp +186 -0
  111. data/include/tm/recursion_guard.hpp +156 -0
  112. data/include/tm/shared_ptr.hpp +259 -0
  113. data/include/tm/string.hpp +1447 -0
  114. data/include/tm/tests.hpp +78 -0
  115. data/include/tm/vector.hpp +796 -0
  116. data/lib/natalie_parser/sexp.rb +36 -0
  117. data/lib/natalie_parser/version.rb +5 -0
  118. data/lib/natalie_parser.rb +3 -0
  119. data/natalie_parser.gemspec +23 -0
  120. data/src/lexer/interpolated_string_lexer.cpp +88 -0
  121. data/src/lexer/regexp_lexer.cpp +95 -0
  122. data/src/lexer/word_array_lexer.cpp +134 -0
  123. data/src/lexer.cpp +1703 -0
  124. data/src/node/alias_node.cpp +11 -0
  125. data/src/node/assignment_node.cpp +33 -0
  126. data/src/node/begin_node.cpp +29 -0
  127. data/src/node/begin_rescue_node.cpp +33 -0
  128. data/src/node/class_node.cpp +22 -0
  129. data/src/node/interpolated_regexp_node.cpp +19 -0
  130. data/src/node/interpolated_shell_node.cpp +25 -0
  131. data/src/node/interpolated_string_node.cpp +111 -0
  132. data/src/node/interpolated_symbol_node.cpp +25 -0
  133. data/src/node/match_node.cpp +14 -0
  134. data/src/node/module_node.cpp +21 -0
  135. data/src/node/multiple_assignment_node.cpp +37 -0
  136. data/src/node/node.cpp +10 -0
  137. data/src/node/node_with_args.cpp +35 -0
  138. data/src/node/op_assign_node.cpp +36 -0
  139. data/src/node/string_node.cpp +33 -0
  140. data/src/parser.cpp +2972 -0
  141. data/src/token.cpp +27 -0
  142. metadata +186 -0
@@ -0,0 +1,11 @@
1
+ #include "natalie_parser/node/alias_node.hpp"
2
+
3
+ namespace NatalieParser {
4
+
5
+ void AliasNode::transform(Creator *creator) const {
6
+ creator->set_type("alias");
7
+ creator->append(m_new_name.ref());
8
+ creator->append(m_existing_name.ref());
9
+ }
10
+
11
+ }
@@ -0,0 +1,33 @@
1
+ #include "natalie_parser/node/assignment_node.hpp"
2
+ #include "natalie_parser/node/multiple_assignment_node.hpp"
3
+
4
+ namespace NatalieParser {
5
+
6
+ void AssignmentNode::transform(Creator *creator) const {
7
+ creator->set_line(m_identifier->line());
8
+ creator->set_column(m_identifier->column());
9
+ creator->reset_sexp();
10
+ switch (m_identifier->type()) {
11
+ case Node::Type::MultipleAssignment: {
12
+ auto masgn = m_identifier;
13
+ masgn->transform(creator);
14
+ creator->append(m_value.ref());
15
+ break;
16
+ }
17
+ case Node::Type::Call:
18
+ case Node::Type::Colon2:
19
+ case Node::Type::Colon3:
20
+ case Node::Type::Identifier:
21
+ case Node::Type::SafeCall: {
22
+ creator->with_assignment(true, [&]() {
23
+ m_identifier->transform(creator);
24
+ });
25
+ creator->append(m_value.ref());
26
+ break;
27
+ }
28
+ default:
29
+ TM_UNREACHABLE();
30
+ }
31
+ }
32
+
33
+ }
@@ -0,0 +1,29 @@
1
+ #include "natalie_parser/node/begin_node.hpp"
2
+
3
+ namespace NatalieParser {
4
+
5
+ void BeginNode::transform(Creator *creator) const {
6
+ assert(m_body);
7
+ creator->set_type("rescue");
8
+ if (!m_body->is_empty())
9
+ creator->append(m_body->without_unnecessary_nesting());
10
+ for (auto rescue_node : m_rescue_nodes) {
11
+ creator->append(rescue_node.static_cast_as<Node>());
12
+ }
13
+ if (m_else_body) {
14
+ if (!m_else_body->is_empty())
15
+ creator->append(m_else_body->without_unnecessary_nesting());
16
+ }
17
+ if (m_ensure_body) {
18
+ if (m_rescue_nodes.is_empty())
19
+ creator->set_type("ensure");
20
+ else
21
+ creator->wrap("ensure");
22
+ if (m_ensure_body->is_empty())
23
+ creator->append_nil_sexp();
24
+ else
25
+ creator->append(m_ensure_body->without_unnecessary_nesting());
26
+ }
27
+ }
28
+
29
+ }
@@ -0,0 +1,33 @@
1
+ #include "natalie_parser/node/begin_rescue_node.hpp"
2
+ #include "natalie_parser/node/array_node.hpp"
3
+ #include "natalie_parser/node/assignment_node.hpp"
4
+
5
+ namespace NatalieParser {
6
+
7
+ SharedPtr<Node> BeginRescueNode::name_to_node() const {
8
+ assert(m_name);
9
+ return new AssignmentNode {
10
+ token(),
11
+ m_name.static_cast_as<Node>(),
12
+ new IdentifierNode {
13
+ Token { Token::Type::GlobalVariable, "$!", file(), line(), column() },
14
+ false },
15
+ };
16
+ }
17
+
18
+ void BeginRescueNode::transform(Creator *creator) const {
19
+ creator->set_type("resbody");
20
+ auto array = ArrayNode { token() };
21
+ for (auto exception_node : m_exceptions)
22
+ array.add_node(exception_node);
23
+ if (m_name)
24
+ array.add_node(name_to_node());
25
+ creator->append(array);
26
+ if (m_body->nodes().is_empty())
27
+ creator->append_nil();
28
+ else
29
+ for (auto node : m_body->nodes())
30
+ creator->append(node);
31
+ }
32
+
33
+ }
@@ -0,0 +1,22 @@
1
+ #include "natalie_parser/node/class_node.hpp"
2
+ #include "natalie_parser/node/identifier_node.hpp"
3
+
4
+ namespace NatalieParser {
5
+
6
+ void ClassNode::transform(Creator *creator) const {
7
+ creator->set_type("class");
8
+ auto doc_comment = doc();
9
+ if (doc_comment)
10
+ creator->set_comments(doc_comment.value().ref());
11
+ if (m_name->type() == Node::Type::Identifier) {
12
+ auto identifier = m_name.static_cast_as<IdentifierNode>();
13
+ creator->append_symbol(identifier->name());
14
+ } else {
15
+ creator->append(m_name.ref());
16
+ }
17
+ creator->append(m_superclass.ref());
18
+ for (auto node : m_body->nodes())
19
+ creator->append(node);
20
+ }
21
+
22
+ }
@@ -0,0 +1,19 @@
1
+ #include "natalie_parser/node/interpolated_regexp_node.hpp"
2
+ #include "natalie_parser/node/string_node.hpp"
3
+
4
+ namespace NatalieParser {
5
+
6
+ void InterpolatedRegexpNode::transform(Creator *creator) const {
7
+ creator->set_type("dregx");
8
+ for (size_t i = 0; i < nodes().size(); ++i) {
9
+ auto node = nodes()[i];
10
+ if (i == 0 && node->type() == Node::Type::String)
11
+ creator->append_string(node.static_cast_as<StringNode>()->string());
12
+ else
13
+ creator->append(node);
14
+ }
15
+ if (m_options != 0)
16
+ creator->append_integer(m_options);
17
+ }
18
+
19
+ }
@@ -0,0 +1,25 @@
1
+ #include "natalie_parser/node/interpolated_shell_node.hpp"
2
+ #include "natalie_parser/node/string_node.hpp"
3
+
4
+ namespace NatalieParser {
5
+
6
+ void InterpolatedShellNode::transform(Creator *creator) const {
7
+ creator->set_type("dxstr");
8
+ bool has_starter_string = false;
9
+ for (size_t i = 0; i < m_nodes.size(); ++i) {
10
+ auto node = m_nodes.at(i);
11
+ if (i == 0 && node->type() == Node::Type::String) {
12
+ auto string_node = node.static_cast_as<StringNode>();
13
+ creator->append_string(string_node->string());
14
+ has_starter_string = true;
15
+ } else {
16
+ if (!has_starter_string) {
17
+ creator->append_string("");
18
+ has_starter_string = true;
19
+ }
20
+ creator->append(node);
21
+ }
22
+ }
23
+ }
24
+
25
+ }
@@ -0,0 +1,111 @@
1
+ #include "natalie_parser/node/interpolated_string_node.hpp"
2
+ #include "natalie_parser/node/evaluate_to_string_node.hpp"
3
+ #include "natalie_parser/node/string_node.hpp"
4
+
5
+ namespace NatalieParser {
6
+
7
+ SharedPtr<Node> InterpolatedStringNode::append_string_node(SharedPtr<Node> string2) const {
8
+ SharedPtr<InterpolatedStringNode> copy = new InterpolatedStringNode { *this };
9
+ switch (string2->type()) {
10
+ case Node::Type::String: {
11
+ auto string2_node = string2.static_cast_as<StringNode>();
12
+ assert(!is_empty());
13
+ auto last_node = copy->nodes().last();
14
+ switch (last_node->type()) {
15
+ case Node::Type::String:
16
+ if (m_nodes.size() > 1) {
17
+ // For some reason, RubyParser doesn't append two string nodes
18
+ // if there is an evstr present.
19
+ copy->add_node(string2);
20
+ } else {
21
+ // NOTE: This mutates one of my own nodes, but I don't care.
22
+ last_node.static_cast_as<StringNode>()->string()->append(*string2_node->string());
23
+ }
24
+ break;
25
+ case Node::Type::EvaluateToString:
26
+ copy->add_node(string2);
27
+ break;
28
+ default:
29
+ TM_UNREACHABLE();
30
+ }
31
+ return copy.static_cast_as<Node>();
32
+ }
33
+ case Node::Type::InterpolatedString: {
34
+ auto string2_node = string2.static_cast_as<InterpolatedStringNode>();
35
+ assert(!is_empty());
36
+ assert(!string2_node->is_empty());
37
+ for (auto node : string2_node->nodes()) {
38
+ copy->add_node(node);
39
+ }
40
+ return copy.static_cast_as<Node>();
41
+ }
42
+ default:
43
+ TM_UNREACHABLE();
44
+ }
45
+ }
46
+
47
+ void InterpolatedStringNode::transform(Creator *creator) const {
48
+ creator->set_type("dstr");
49
+
50
+ bool has_starter_string = false;
51
+ bool only_static = true;
52
+
53
+ for (size_t i = 0; i < m_nodes.size(); ++i) {
54
+ auto node = m_nodes.at(i);
55
+
56
+ // the first item is always a literal string
57
+ if (i == 0 && node->type() == Node::Type::String) {
58
+ auto string = node.static_cast_as<StringNode>()->string();
59
+
60
+ // append consecutive static strings to this one
61
+ while (i + 1 < m_nodes.size() && m_nodes.at(i + 1)->type() == Node::Type::String) {
62
+ auto n = m_nodes[++i];
63
+ string = new String(*string);
64
+ string->append(*n.static_cast_as<StringNode>()->string());
65
+ }
66
+
67
+ creator->append_string(string);
68
+ has_starter_string = true;
69
+
70
+ } else {
71
+ only_static = false;
72
+
73
+ // if we don't have a static string to start, append a blank one
74
+ // (this is what RubyParser does and we mimic it)
75
+ if (!has_starter_string) {
76
+ creator->append_string("");
77
+ has_starter_string = true;
78
+ }
79
+
80
+ // if this node is an InterpolatedString having a single
81
+ // EvaluateToString node, then yoink the EvaluateToString
82
+ // for ourselves, and don't bother with the useless wrapper
83
+ //
84
+ // # bad
85
+ // s(:dstr, "", s(:evstr, s(:dstr, "", s(:evstr, s(:lit, 1)))))
86
+ //
87
+ // # good
88
+ // s(:dstr, "", s(:evstr, s(:lit, 1)))
89
+ //
90
+ if (node->type() == Node::Type::EvaluateToString) {
91
+ auto evstr = node.static_cast_as<EvaluateToStringNode>();
92
+ if (evstr->node() && evstr->node()->type() == Node::Type::InterpolatedString) {
93
+ auto dstr = evstr->node().static_cast_as<InterpolatedStringNode>();
94
+ if (dstr->nodes().size() == 1 && dstr->nodes().first()->type() == Node::Type::EvaluateToString) {
95
+ auto n1 = dstr->nodes().first().static_cast_as<EvaluateToStringNode>();
96
+ creator->append(dstr->nodes().first());
97
+ continue;
98
+ }
99
+ }
100
+ }
101
+
102
+ creator->append(node);
103
+ }
104
+ }
105
+
106
+ // if we only appended static strings, then this isn't a dstr
107
+ if (only_static)
108
+ creator->set_type("str");
109
+ }
110
+
111
+ }
@@ -0,0 +1,25 @@
1
+ #include "natalie_parser/node/interpolated_symbol_node.hpp"
2
+ #include "natalie_parser/node/string_node.hpp"
3
+
4
+ namespace NatalieParser {
5
+
6
+ void InterpolatedSymbolNode::transform(Creator *creator) const {
7
+ creator->set_type("dsym");
8
+ bool has_starter_string = false;
9
+ for (size_t i = 0; i < m_nodes.size(); ++i) {
10
+ auto node = m_nodes.at(i);
11
+ if (i == 0 && node->type() == Node::Type::String) {
12
+ auto string_node = node.static_cast_as<StringNode>();
13
+ creator->append_string(string_node->string());
14
+ has_starter_string = true;
15
+ } else {
16
+ if (!has_starter_string) {
17
+ creator->append_string("");
18
+ has_starter_string = true;
19
+ }
20
+ creator->append(node);
21
+ }
22
+ }
23
+ }
24
+
25
+ }
@@ -0,0 +1,14 @@
1
+ #include "natalie_parser/node/match_node.hpp"
2
+
3
+ namespace NatalieParser {
4
+
5
+ void MatchNode::transform(Creator *creator) const {
6
+ if (m_regexp_on_left)
7
+ creator->set_type("match2");
8
+ else
9
+ creator->set_type("match3");
10
+ creator->append(m_regexp.ref());
11
+ creator->append(m_arg.ref());
12
+ }
13
+
14
+ }
@@ -0,0 +1,21 @@
1
+ #include "natalie_parser/node/module_node.hpp"
2
+ #include "natalie_parser/node/identifier_node.hpp"
3
+
4
+ namespace NatalieParser {
5
+
6
+ void ModuleNode::transform(Creator *creator) const {
7
+ creator->set_type("module");
8
+ auto doc_comment = doc();
9
+ if (doc_comment)
10
+ creator->set_comments(doc_comment.value().ref());
11
+ if (m_name->type() == Node::Type::Identifier) {
12
+ auto identifier = m_name.static_cast_as<IdentifierNode>();
13
+ creator->append_symbol(identifier->name());
14
+ } else {
15
+ creator->append(m_name.ref());
16
+ }
17
+ for (auto node : m_body->nodes())
18
+ creator->append(node);
19
+ }
20
+
21
+ }
@@ -0,0 +1,37 @@
1
+ #include "natalie_parser/node/multiple_assignment_node.hpp"
2
+ #include "natalie_parser/node/identifier_node.hpp"
3
+ #include "natalie_parser/node/splat_node.hpp"
4
+
5
+ namespace NatalieParser {
6
+
7
+ void MultipleAssignmentNode::add_locals(TM::Hashmap<TM::String> &locals) {
8
+ for (auto node : m_nodes) {
9
+ switch (node->type()) {
10
+ case Node::Type::Identifier: {
11
+ auto identifier = node.static_cast_as<IdentifierNode>();
12
+ identifier->add_to_locals(locals);
13
+ break;
14
+ }
15
+ case Node::Type::Call:
16
+ case Node::Type::Colon2:
17
+ case Node::Type::Colon3:
18
+ break;
19
+ case Node::Type::Splat: {
20
+ auto splat = node.static_cast_as<SplatNode>();
21
+ if (splat->node() && splat->node()->type() == Node::Type::Identifier) {
22
+ auto identifier = splat->node().static_cast_as<IdentifierNode>();
23
+ identifier->add_to_locals(locals);
24
+ }
25
+ break;
26
+ }
27
+ case Node::Type::MultipleAssignment:
28
+ node.static_cast_as<MultipleAssignmentNode>()->add_locals(locals);
29
+ break;
30
+ default:
31
+ printf("unknown node type %d\n", (int)node->type());
32
+ TM_UNREACHABLE();
33
+ }
34
+ }
35
+ }
36
+
37
+ }
data/src/node/node.cpp ADDED
@@ -0,0 +1,10 @@
1
+ #include "natalie_parser/node.hpp"
2
+
3
+ namespace NatalieParser {
4
+
5
+ BlockNode &Node::as_block_node() {
6
+ assert(type() == Node::Type::Block);
7
+ return *static_cast<BlockNode *>(this);
8
+ }
9
+
10
+ }
@@ -0,0 +1,35 @@
1
+ #include "natalie_parser/node/node_with_args.hpp"
2
+ #include "natalie_parser/node/arg_node.hpp"
3
+ #include "natalie_parser/node/shadow_arg_node.hpp"
4
+
5
+ namespace NatalieParser {
6
+
7
+ void NodeWithArgs::append_method_or_block_args(Creator *creator) const {
8
+ creator->append_sexp([&](Creator *c) {
9
+ c->set_type("args");
10
+ for (auto arg : m_args) {
11
+ switch (arg->type()) {
12
+ case Node::Type::Arg: {
13
+ auto arg_node = arg.static_cast_as<ArgNode>();
14
+ if (arg_node->value())
15
+ c->append(arg);
16
+ else
17
+ arg.static_cast_as<ArgNode>()->append_name(c);
18
+ break;
19
+ }
20
+ case Node::Type::KeywordArg:
21
+ case Node::Type::MultipleAssignmentArg:
22
+ case Node::Type::ShadowArg:
23
+ c->append(arg);
24
+ break;
25
+ case Node::Type::Nil:
26
+ c->append_nil();
27
+ break;
28
+ default:
29
+ TM_UNREACHABLE();
30
+ }
31
+ }
32
+ });
33
+ }
34
+
35
+ }
@@ -0,0 +1,36 @@
1
+ #include "natalie_parser/node/op_assign_node.hpp"
2
+ #include "natalie_parser/node/identifier_node.hpp"
3
+
4
+ namespace NatalieParser {
5
+
6
+ void OpAssignNode::transform(Creator *creator) const {
7
+ assert(m_op);
8
+ switch (m_name->type()) {
9
+ case Node::Type::Identifier: {
10
+ auto identifier_node = m_name.static_cast_as<IdentifierNode>();
11
+ creator->with_assignment(true, [&]() {
12
+ identifier_node->transform(creator);
13
+ });
14
+ auto value = CallNode {
15
+ token(),
16
+ m_name.static_cast_as<Node>(),
17
+ m_op
18
+ };
19
+ value.add_arg(m_value);
20
+ creator->append(value);
21
+ break;
22
+ }
23
+ case Node::Type::Colon2:
24
+ case Node::Type::Colon3:
25
+ creator->set_type("op_asgn");
26
+ creator->append(m_name);
27
+ creator->append_symbol(m_op);
28
+ creator->append(m_value);
29
+ break;
30
+ default:
31
+ printf("got node type %d\n", (int)m_name->type());
32
+ TM_UNREACHABLE();
33
+ }
34
+ }
35
+
36
+ }
@@ -0,0 +1,33 @@
1
+ #include "natalie_parser/node/string_node.hpp"
2
+ #include "natalie_parser/node/interpolated_string_node.hpp"
3
+
4
+ namespace NatalieParser {
5
+
6
+ SharedPtr<Node> StringNode::append_string_node(SharedPtr<Node> string2) const {
7
+ switch (string2->type()) {
8
+ case Node::Type::String: {
9
+ auto string2_node = string2.static_cast_as<StringNode>();
10
+ SharedPtr<String> str = new String { *m_string };
11
+ str->append(*string2_node->string());
12
+ return new StringNode { m_token, str };
13
+ }
14
+ case Node::Type::InterpolatedString: {
15
+ auto string2_node = string2.static_cast_as<InterpolatedStringNode>();
16
+ assert(!string2_node->is_empty());
17
+ if (string2_node->nodes().first()->type() == Node::Type::String) {
18
+ auto n1 = string2_node->nodes().first().static_cast_as<StringNode>();
19
+ n1->string()->prepend(*m_string);
20
+ } else {
21
+ auto copy = new StringNode(m_token, m_string);
22
+ string2_node->prepend_node(copy);
23
+ }
24
+ string2->set_line(line());
25
+ string2->set_column(column());
26
+ return string2;
27
+ }
28
+ default:
29
+ TM_UNREACHABLE();
30
+ }
31
+ }
32
+
33
+ }