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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +22 -0
- data/Dockerfile +26 -0
- data/Gemfile +10 -0
- data/LICENSE +21 -0
- data/README.md +55 -0
- data/Rakefile +242 -0
- data/ext/natalie_parser/extconf.rb +9 -0
- data/ext/natalie_parser/mri_creator.hpp +139 -0
- data/ext/natalie_parser/natalie_parser.cpp +144 -0
- data/include/natalie_parser/creator/debug_creator.hpp +113 -0
- data/include/natalie_parser/creator.hpp +108 -0
- data/include/natalie_parser/lexer/interpolated_string_lexer.hpp +64 -0
- data/include/natalie_parser/lexer/regexp_lexer.hpp +37 -0
- data/include/natalie_parser/lexer/word_array_lexer.hpp +57 -0
- data/include/natalie_parser/lexer.hpp +135 -0
- data/include/natalie_parser/node/alias_node.hpp +35 -0
- data/include/natalie_parser/node/arg_node.hpp +74 -0
- data/include/natalie_parser/node/array_node.hpp +34 -0
- data/include/natalie_parser/node/array_pattern_node.hpp +28 -0
- data/include/natalie_parser/node/assignment_node.hpp +34 -0
- data/include/natalie_parser/node/back_ref_node.hpp +28 -0
- data/include/natalie_parser/node/begin_block_node.hpp +25 -0
- data/include/natalie_parser/node/begin_node.hpp +52 -0
- data/include/natalie_parser/node/begin_rescue_node.hpp +47 -0
- data/include/natalie_parser/node/bignum_node.hpp +37 -0
- data/include/natalie_parser/node/block_node.hpp +55 -0
- data/include/natalie_parser/node/block_pass_node.hpp +33 -0
- data/include/natalie_parser/node/break_node.hpp +32 -0
- data/include/natalie_parser/node/call_node.hpp +85 -0
- data/include/natalie_parser/node/case_in_node.hpp +40 -0
- data/include/natalie_parser/node/case_node.hpp +52 -0
- data/include/natalie_parser/node/case_when_node.hpp +43 -0
- data/include/natalie_parser/node/class_node.hpp +39 -0
- data/include/natalie_parser/node/colon2_node.hpp +44 -0
- data/include/natalie_parser/node/colon3_node.hpp +34 -0
- data/include/natalie_parser/node/constant_node.hpp +26 -0
- data/include/natalie_parser/node/def_node.hpp +55 -0
- data/include/natalie_parser/node/defined_node.hpp +33 -0
- data/include/natalie_parser/node/encoding_node.hpp +26 -0
- data/include/natalie_parser/node/end_block_node.hpp +25 -0
- data/include/natalie_parser/node/evaluate_to_string_node.hpp +37 -0
- data/include/natalie_parser/node/false_node.hpp +23 -0
- data/include/natalie_parser/node/fixnum_node.hpp +36 -0
- data/include/natalie_parser/node/float_node.hpp +36 -0
- data/include/natalie_parser/node/hash_node.hpp +34 -0
- data/include/natalie_parser/node/hash_pattern_node.hpp +27 -0
- data/include/natalie_parser/node/identifier_node.hpp +123 -0
- data/include/natalie_parser/node/if_node.hpp +43 -0
- data/include/natalie_parser/node/infix_op_node.hpp +46 -0
- data/include/natalie_parser/node/interpolated_node.hpp +33 -0
- data/include/natalie_parser/node/interpolated_regexp_node.hpp +28 -0
- data/include/natalie_parser/node/interpolated_shell_node.hpp +22 -0
- data/include/natalie_parser/node/interpolated_string_node.hpp +31 -0
- data/include/natalie_parser/node/interpolated_symbol_key_node.hpp +18 -0
- data/include/natalie_parser/node/interpolated_symbol_node.hpp +28 -0
- data/include/natalie_parser/node/iter_node.hpp +45 -0
- data/include/natalie_parser/node/keyword_arg_node.hpp +25 -0
- data/include/natalie_parser/node/keyword_splat_node.hpp +38 -0
- data/include/natalie_parser/node/logical_and_node.hpp +40 -0
- data/include/natalie_parser/node/logical_or_node.hpp +40 -0
- data/include/natalie_parser/node/match_node.hpp +38 -0
- data/include/natalie_parser/node/module_node.hpp +32 -0
- data/include/natalie_parser/node/multiple_assignment_arg_node.hpp +32 -0
- data/include/natalie_parser/node/multiple_assignment_node.hpp +37 -0
- data/include/natalie_parser/node/next_node.hpp +37 -0
- data/include/natalie_parser/node/nil_node.hpp +23 -0
- data/include/natalie_parser/node/nil_sexp_node.hpp +23 -0
- data/include/natalie_parser/node/node.hpp +155 -0
- data/include/natalie_parser/node/node_with_args.hpp +47 -0
- data/include/natalie_parser/node/not_match_node.hpp +35 -0
- data/include/natalie_parser/node/not_node.hpp +37 -0
- data/include/natalie_parser/node/nth_ref_node.hpp +27 -0
- data/include/natalie_parser/node/op_assign_accessor_node.hpp +74 -0
- data/include/natalie_parser/node/op_assign_and_node.hpp +34 -0
- data/include/natalie_parser/node/op_assign_node.hpp +47 -0
- data/include/natalie_parser/node/op_assign_or_node.hpp +34 -0
- data/include/natalie_parser/node/pin_node.hpp +33 -0
- data/include/natalie_parser/node/range_node.hpp +52 -0
- data/include/natalie_parser/node/redo_node.hpp +20 -0
- data/include/natalie_parser/node/regexp_node.hpp +36 -0
- data/include/natalie_parser/node/retry_node.hpp +20 -0
- data/include/natalie_parser/node/return_node.hpp +34 -0
- data/include/natalie_parser/node/safe_call_node.hpp +31 -0
- data/include/natalie_parser/node/sclass_node.hpp +37 -0
- data/include/natalie_parser/node/self_node.hpp +23 -0
- data/include/natalie_parser/node/shadow_arg_node.hpp +40 -0
- data/include/natalie_parser/node/shell_node.hpp +32 -0
- data/include/natalie_parser/node/splat_node.hpp +39 -0
- data/include/natalie_parser/node/splat_value_node.hpp +32 -0
- data/include/natalie_parser/node/stabby_proc_node.hpp +29 -0
- data/include/natalie_parser/node/string_node.hpp +42 -0
- data/include/natalie_parser/node/super_node.hpp +44 -0
- data/include/natalie_parser/node/symbol_key_node.hpp +19 -0
- data/include/natalie_parser/node/symbol_node.hpp +30 -0
- data/include/natalie_parser/node/to_array_node.hpp +33 -0
- data/include/natalie_parser/node/true_node.hpp +23 -0
- data/include/natalie_parser/node/unary_op_node.hpp +41 -0
- data/include/natalie_parser/node/undef_node.hpp +31 -0
- data/include/natalie_parser/node/until_node.hpp +21 -0
- data/include/natalie_parser/node/while_node.hpp +52 -0
- data/include/natalie_parser/node/yield_node.hpp +29 -0
- data/include/natalie_parser/node.hpp +89 -0
- data/include/natalie_parser/parser.hpp +218 -0
- data/include/natalie_parser/token.hpp +842 -0
- data/include/tm/defer.hpp +34 -0
- data/include/tm/hashmap.hpp +826 -0
- data/include/tm/macros.hpp +16 -0
- data/include/tm/optional.hpp +223 -0
- data/include/tm/owned_ptr.hpp +186 -0
- data/include/tm/recursion_guard.hpp +156 -0
- data/include/tm/shared_ptr.hpp +259 -0
- data/include/tm/string.hpp +1447 -0
- data/include/tm/tests.hpp +78 -0
- data/include/tm/vector.hpp +796 -0
- data/lib/natalie_parser/sexp.rb +36 -0
- data/lib/natalie_parser/version.rb +5 -0
- data/lib/natalie_parser.rb +3 -0
- data/natalie_parser.gemspec +23 -0
- data/src/lexer/interpolated_string_lexer.cpp +88 -0
- data/src/lexer/regexp_lexer.cpp +95 -0
- data/src/lexer/word_array_lexer.cpp +134 -0
- data/src/lexer.cpp +1703 -0
- data/src/node/alias_node.cpp +11 -0
- data/src/node/assignment_node.cpp +33 -0
- data/src/node/begin_node.cpp +29 -0
- data/src/node/begin_rescue_node.cpp +33 -0
- data/src/node/class_node.cpp +22 -0
- data/src/node/interpolated_regexp_node.cpp +19 -0
- data/src/node/interpolated_shell_node.cpp +25 -0
- data/src/node/interpolated_string_node.cpp +111 -0
- data/src/node/interpolated_symbol_node.cpp +25 -0
- data/src/node/match_node.cpp +14 -0
- data/src/node/module_node.cpp +21 -0
- data/src/node/multiple_assignment_node.cpp +37 -0
- data/src/node/node.cpp +10 -0
- data/src/node/node_with_args.cpp +35 -0
- data/src/node/op_assign_node.cpp +36 -0
- data/src/node/string_node.cpp +33 -0
- data/src/parser.cpp +2972 -0
- data/src/token.cpp +27 -0
- metadata +186 -0
|
@@ -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,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
|
+
}
|