natalie_parser 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,842 @@
1
+ #pragma once
2
+
3
+ #include "tm/macros.hpp"
4
+ #include "tm/optional.hpp"
5
+ #include "tm/shared_ptr.hpp"
6
+ #include "tm/string.hpp"
7
+
8
+ namespace NatalieParser {
9
+
10
+ using namespace TM;
11
+
12
+ class Token {
13
+ public:
14
+ enum class Type {
15
+ Invalid, // must be first
16
+ InvalidCharacterEscape,
17
+ InvalidUnicodeEscape,
18
+ AliasKeyword,
19
+ Ampersand,
20
+ AmpersandAmpersand,
21
+ AmpersandEqual,
22
+ AmpersandAmpersandEqual,
23
+ AndKeyword,
24
+ Arrow,
25
+ BackRef,
26
+ BareName,
27
+ BeginKeyword,
28
+ BEGINKeyword,
29
+ Bignum,
30
+ BreakKeyword,
31
+ Caret,
32
+ CaretEqual,
33
+ CaseKeyword,
34
+ ClassKeyword,
35
+ ClassVariable,
36
+ Comma,
37
+ Comment,
38
+ Comparison,
39
+ Constant,
40
+ ConstantResolution,
41
+ DefinedKeyword,
42
+ DefKeyword,
43
+ Doc,
44
+ DoKeyword,
45
+ Dot,
46
+ DotDot,
47
+ DotDotDot,
48
+ ElseKeyword,
49
+ ElsifKeyword,
50
+ ENCODINGKeyword,
51
+ EndKeyword,
52
+ ENDKeyword,
53
+ EnsureKeyword,
54
+ Eof,
55
+ Equal,
56
+ EqualEqual,
57
+ EqualEqualEqual,
58
+ EvaluateToStringBegin,
59
+ EvaluateToStringEnd,
60
+ FalseKeyword,
61
+ FILEKeyword,
62
+ Fixnum,
63
+ Float,
64
+ ForKeyword,
65
+ GlobalVariable,
66
+ GreaterThan,
67
+ GreaterThanOrEqual,
68
+ HashRocket,
69
+ IfKeyword,
70
+ InKeyword,
71
+ InstanceVariable,
72
+ InterpolatedHeredocBegin,
73
+ InterpolatedHeredocEnd,
74
+ InterpolatedRegexpBegin,
75
+ InterpolatedRegexpEnd,
76
+ InterpolatedShellBegin,
77
+ InterpolatedShellEnd,
78
+ InterpolatedStringBegin,
79
+ InterpolatedStringEnd,
80
+ InterpolatedSymbolBegin,
81
+ InterpolatedSymbolEnd,
82
+ InterpolatedStringSymbolKey,
83
+ LCurlyBrace,
84
+ LBracket,
85
+ LBracketRBracket,
86
+ LBracketRBracketEqual,
87
+ LeftShift,
88
+ LeftShiftEqual,
89
+ LessThan,
90
+ LessThanOrEqual,
91
+ LINEKeyword,
92
+ LParen,
93
+ Match,
94
+ Minus,
95
+ MinusEqual,
96
+ ModuleKeyword,
97
+ Newline,
98
+ NextKeyword,
99
+ NilKeyword,
100
+ Not,
101
+ NotEqual,
102
+ NotKeyword,
103
+ NotMatch,
104
+ NthRef,
105
+ OrKeyword,
106
+ Percent,
107
+ PercentEqual,
108
+ PercentLowerI,
109
+ PercentLowerW,
110
+ PercentUpperI,
111
+ PercentUpperW,
112
+ Pipe,
113
+ PipeEqual,
114
+ PipePipe,
115
+ PipePipeEqual,
116
+ Plus,
117
+ PlusEqual,
118
+ RCurlyBrace,
119
+ RBracket,
120
+ RedoKeyword,
121
+ RescueKeyword,
122
+ RetryKeyword,
123
+ ReturnKeyword,
124
+ RightShift,
125
+ RightShiftEqual,
126
+ RParen,
127
+ SafeNavigation,
128
+ SelfKeyword,
129
+ Semicolon,
130
+ Slash,
131
+ SlashEqual,
132
+ Star,
133
+ StarEqual,
134
+ StarStar,
135
+ StarStarEqual,
136
+ String,
137
+ SuperKeyword,
138
+ Symbol,
139
+ SymbolKey,
140
+ TernaryColon,
141
+ TernaryQuestion,
142
+ ThenKeyword,
143
+ Tilde,
144
+ TrueKeyword,
145
+ UndefKeyword,
146
+ UnlessKeyword,
147
+ UnterminatedRegexp,
148
+ UnterminatedString,
149
+ UnterminatedWordArray,
150
+ UntilKeyword,
151
+ WhenKeyword,
152
+ WhileKeyword,
153
+ YieldKeyword,
154
+ };
155
+
156
+ Token() { }
157
+
158
+ Token(Type type, SharedPtr<String> file, size_t line, size_t column)
159
+ : m_type { type }
160
+ , m_file { file }
161
+ , m_line { line }
162
+ , m_column { column } {
163
+ assert(file);
164
+ }
165
+
166
+ Token(Type type, const char *literal, SharedPtr<String> file, size_t line, size_t column)
167
+ : m_type { type }
168
+ , m_literal { new String(literal) }
169
+ , m_file { file }
170
+ , m_line { line }
171
+ , m_column { column } {
172
+ assert(literal);
173
+ assert(file);
174
+ }
175
+
176
+ Token(Type type, SharedPtr<String> literal, SharedPtr<String> file, size_t line, size_t column)
177
+ : m_type { type }
178
+ , m_literal { literal }
179
+ , m_file { file }
180
+ , m_line { line }
181
+ , m_column { column } {
182
+ assert(literal);
183
+ assert(file);
184
+ }
185
+
186
+ Token(Type type, char literal, SharedPtr<String> file, size_t line, size_t column)
187
+ : m_type { type }
188
+ , m_literal { new String(literal) }
189
+ , m_file { file }
190
+ , m_line { line }
191
+ , m_column { column } {
192
+ assert(file);
193
+ }
194
+
195
+ Token(Type type, long long fixnum, SharedPtr<String> file, size_t line, size_t column)
196
+ : m_type { type }
197
+ , m_fixnum { fixnum }
198
+ , m_file { file }
199
+ , m_line { line }
200
+ , m_column { column } {
201
+ assert(file);
202
+ }
203
+
204
+ Token(Type type, double dbl, SharedPtr<String> file, size_t line, size_t column)
205
+ : m_type { type }
206
+ , m_double { dbl }
207
+ , m_file { file }
208
+ , m_line { line }
209
+ , m_column { column } {
210
+ assert(file);
211
+ }
212
+
213
+ static Token &invalid() {
214
+ if (!s_invalid)
215
+ s_invalid = new Token {};
216
+ return *s_invalid;
217
+ }
218
+
219
+ operator bool() const { return is_valid(); }
220
+
221
+ Type type() const { return m_type; }
222
+ void set_type(Token::Type type) { m_type = type; }
223
+
224
+ const char *literal() const {
225
+ if (!m_literal)
226
+ return nullptr;
227
+ return m_literal.value()->c_str();
228
+ }
229
+
230
+ const char *literal_or_blank() const {
231
+ if (!m_literal)
232
+ return "";
233
+ return m_literal.value()->c_str();
234
+ }
235
+
236
+ SharedPtr<String> literal_string() const {
237
+ assert(m_literal);
238
+ return m_literal.value();
239
+ }
240
+
241
+ bool has_literal() const {
242
+ return !!m_literal;
243
+ }
244
+
245
+ const char *type_value() const {
246
+ switch (m_type) {
247
+ case Type::AliasKeyword:
248
+ return "alias";
249
+ case Type::Ampersand:
250
+ return "&";
251
+ case Type::AmpersandAmpersand:
252
+ return "&&";
253
+ case Type::AmpersandAmpersandEqual:
254
+ return "&&=";
255
+ case Type::AmpersandEqual:
256
+ return "&=";
257
+ case Type::AndKeyword:
258
+ return "and";
259
+ case Type::Arrow:
260
+ return "->";
261
+ case Type::BackRef:
262
+ return "back_ref";
263
+ case Type::BareName:
264
+ return "name";
265
+ case Type::BeginKeyword:
266
+ return "begin";
267
+ case Type::BEGINKeyword:
268
+ return "BEGIN";
269
+ case Type::Bignum:
270
+ return "bignum";
271
+ case Type::BreakKeyword:
272
+ return "break";
273
+ case Type::Caret:
274
+ return "^";
275
+ case Type::CaretEqual:
276
+ return "^=";
277
+ case Type::CaseKeyword:
278
+ return "case";
279
+ case Type::ClassKeyword:
280
+ return "class";
281
+ case Type::ClassVariable:
282
+ return "cvar";
283
+ case Type::Comma:
284
+ return ",";
285
+ case Type::Comment:
286
+ return "comment";
287
+ case Type::Comparison:
288
+ return "<=>";
289
+ case Type::ConstantResolution:
290
+ return "::";
291
+ case Type::Constant:
292
+ return "constant";
293
+ case Type::DefinedKeyword:
294
+ return "defined?";
295
+ case Type::DefKeyword:
296
+ return "def";
297
+ case Type::Doc:
298
+ return "doc";
299
+ case Type::DoKeyword:
300
+ return "do";
301
+ case Type::DotDotDot:
302
+ return "...";
303
+ case Type::DotDot:
304
+ return "..";
305
+ case Type::Dot:
306
+ return ".";
307
+ case Type::ElseKeyword:
308
+ return "else";
309
+ case Type::ElsifKeyword:
310
+ return "elsif";
311
+ case Type::ENCODINGKeyword:
312
+ return "__ENCODING__";
313
+ case Type::EndKeyword:
314
+ return "end";
315
+ case Type::ENDKeyword:
316
+ return "END";
317
+ case Type::EnsureKeyword:
318
+ return "ensure";
319
+ case Type::Eof:
320
+ return "EOF";
321
+ case Type::Newline:
322
+ return "\n";
323
+ case Type::EqualEqualEqual:
324
+ return "===";
325
+ case Type::EqualEqual:
326
+ return "==";
327
+ case Type::Equal:
328
+ return "=";
329
+ case Type::EvaluateToStringBegin:
330
+ return "evstr";
331
+ case Type::EvaluateToStringEnd:
332
+ return "evstrend";
333
+ case Type::FalseKeyword:
334
+ return "false";
335
+ case Type::FILEKeyword:
336
+ return "__FILE__";
337
+ case Type::Float:
338
+ return "float";
339
+ case Type::ForKeyword:
340
+ return "for";
341
+ case Type::GlobalVariable:
342
+ return "gvar";
343
+ case Type::GreaterThanOrEqual:
344
+ return ">=";
345
+ case Type::GreaterThan:
346
+ return ">";
347
+ case Type::HashRocket:
348
+ return "=>";
349
+ case Type::IfKeyword:
350
+ return "if";
351
+ case Type::InKeyword:
352
+ return "in";
353
+ case Type::InstanceVariable:
354
+ return "ivar";
355
+ case Type::Fixnum:
356
+ return "fixnum";
357
+ case Type::InterpolatedRegexpBegin:
358
+ return "dregx";
359
+ case Type::InterpolatedRegexpEnd:
360
+ return "dregxend";
361
+ case Type::InterpolatedShellBegin:
362
+ return "dxstr";
363
+ case Type::InterpolatedShellEnd:
364
+ return "dxstrend";
365
+ case Type::InterpolatedHeredocBegin:
366
+ case Type::InterpolatedStringBegin:
367
+ return "dstr";
368
+ case Type::InterpolatedHeredocEnd:
369
+ case Type::InterpolatedStringEnd:
370
+ return "dstrend";
371
+ case Type::InterpolatedSymbolBegin:
372
+ return "dsym";
373
+ case Type::InterpolatedSymbolEnd:
374
+ return "dsymend";
375
+ case Type::InterpolatedStringSymbolKey:
376
+ return "dstr_symbol_key";
377
+ case Type::Invalid:
378
+ case Type::InvalidCharacterEscape:
379
+ case Type::InvalidUnicodeEscape:
380
+ return nullptr;
381
+ case Type::LCurlyBrace:
382
+ return "{";
383
+ case Type::LBracket:
384
+ return "[";
385
+ case Type::LBracketRBracket:
386
+ return "[]";
387
+ case Type::LBracketRBracketEqual:
388
+ return "[]=";
389
+ case Type::LeftShift:
390
+ return "<<";
391
+ case Type::LeftShiftEqual:
392
+ return "<<=";
393
+ case Type::LessThanOrEqual:
394
+ return "<=";
395
+ case Type::LessThan:
396
+ return "<";
397
+ case Type::LINEKeyword:
398
+ return "__LINE__";
399
+ case Type::LParen:
400
+ return "(";
401
+ case Type::Match:
402
+ return "=~";
403
+ case Type::MinusEqual:
404
+ return "-=";
405
+ case Type::Minus:
406
+ return "-";
407
+ case Type::ModuleKeyword:
408
+ return "module";
409
+ case Type::NextKeyword:
410
+ return "next";
411
+ case Type::NilKeyword:
412
+ return "nil";
413
+ case Type::NotEqual:
414
+ return "!=";
415
+ case Type::NotKeyword:
416
+ return "not";
417
+ case Type::NotMatch:
418
+ return "!~";
419
+ case Type::Not:
420
+ return "!";
421
+ case Type::NthRef:
422
+ return "nth_ref";
423
+ case Type::OrKeyword:
424
+ return "or";
425
+ case Type::Percent:
426
+ return "%";
427
+ case Type::PercentEqual:
428
+ return "%=";
429
+ case Type::PercentLowerI:
430
+ return "%i[";
431
+ case Type::PercentLowerW:
432
+ return "%w[";
433
+ case Type::PercentUpperI:
434
+ return "%I[";
435
+ case Type::PercentUpperW:
436
+ return "%W[";
437
+ case Type::Pipe:
438
+ return "|";
439
+ case Type::PipeEqual:
440
+ return "|=";
441
+ case Type::PipePipe:
442
+ return "||";
443
+ case Type::PipePipeEqual:
444
+ return "||=";
445
+ case Type::PlusEqual:
446
+ return "+=";
447
+ case Type::Plus:
448
+ return "+";
449
+ case Type::RCurlyBrace:
450
+ return "}";
451
+ case Type::RBracket:
452
+ return "]";
453
+ case Type::RedoKeyword:
454
+ return "redo";
455
+ case Type::RescueKeyword:
456
+ return "rescue";
457
+ case Type::RetryKeyword:
458
+ return "retry";
459
+ case Type::ReturnKeyword:
460
+ return "return";
461
+ case Type::RightShift:
462
+ return ">>";
463
+ case Type::RightShiftEqual:
464
+ return ">>=";
465
+ case Type::RParen:
466
+ return ")";
467
+ case Type::SafeNavigation:
468
+ return "&.";
469
+ case Type::SelfKeyword:
470
+ return "self";
471
+ case Type::Semicolon:
472
+ return ";";
473
+ case Type::Slash:
474
+ return "/";
475
+ case Type::SlashEqual:
476
+ return "/=";
477
+ case Type::Star:
478
+ return "*";
479
+ case Type::StarEqual:
480
+ return "*=";
481
+ case Type::StarStar:
482
+ return "**";
483
+ case Type::StarStarEqual:
484
+ return "**=";
485
+ case Type::String:
486
+ return "string";
487
+ case Type::SuperKeyword:
488
+ return "super";
489
+ case Type::SymbolKey:
490
+ return "symbol_key";
491
+ case Type::Symbol:
492
+ return "symbol";
493
+ case Type::TernaryColon:
494
+ return ":";
495
+ case Type::TernaryQuestion:
496
+ return "?";
497
+ case Type::ThenKeyword:
498
+ return "then";
499
+ case Type::Tilde:
500
+ return "~";
501
+ case Type::TrueKeyword:
502
+ return "true";
503
+ case Type::UndefKeyword:
504
+ return "undef";
505
+ case Type::UnlessKeyword:
506
+ return "unless";
507
+ case Type::UnterminatedRegexp:
508
+ case Type::UnterminatedString:
509
+ case Type::UnterminatedWordArray:
510
+ return nullptr;
511
+ case Type::UntilKeyword:
512
+ return "until";
513
+ case Type::WhenKeyword:
514
+ return "when";
515
+ case Type::WhileKeyword:
516
+ return "while";
517
+ case Type::YieldKeyword:
518
+ return "yield";
519
+ }
520
+ TM_UNREACHABLE();
521
+ }
522
+
523
+ bool is_assignable() const {
524
+ switch (m_type) {
525
+ case Type::BareName:
526
+ case Type::ClassVariable:
527
+ case Type::Constant:
528
+ case Type::ConstantResolution:
529
+ case Type::GlobalVariable:
530
+ case Type::InstanceVariable:
531
+ return true;
532
+ default:
533
+ return false;
534
+ }
535
+ }
536
+
537
+ bool is_keyword() const {
538
+ switch (m_type) {
539
+ case Type::AliasKeyword:
540
+ case Type::AndKeyword:
541
+ case Type::BeginKeyword:
542
+ case Type::BEGINKeyword:
543
+ case Type::BreakKeyword:
544
+ case Type::CaseKeyword:
545
+ case Type::ClassKeyword:
546
+ case Type::DefinedKeyword:
547
+ case Type::DefKeyword:
548
+ case Type::DoKeyword:
549
+ case Type::ElseKeyword:
550
+ case Type::ElsifKeyword:
551
+ case Type::ENCODINGKeyword:
552
+ case Type::EndKeyword:
553
+ case Type::ENDKeyword:
554
+ case Type::EnsureKeyword:
555
+ case Type::FalseKeyword:
556
+ case Type::FILEKeyword:
557
+ case Type::ForKeyword:
558
+ case Type::IfKeyword:
559
+ case Type::InKeyword:
560
+ case Type::LINEKeyword:
561
+ case Type::ModuleKeyword:
562
+ case Type::NextKeyword:
563
+ case Type::NilKeyword:
564
+ case Type::NotKeyword:
565
+ case Type::OrKeyword:
566
+ case Type::RedoKeyword:
567
+ case Type::RescueKeyword:
568
+ case Type::RetryKeyword:
569
+ case Type::ReturnKeyword:
570
+ case Type::SelfKeyword:
571
+ case Type::SuperKeyword:
572
+ case Type::ThenKeyword:
573
+ case Type::TrueKeyword:
574
+ case Type::UndefKeyword:
575
+ case Type::UnlessKeyword:
576
+ case Type::UntilKeyword:
577
+ case Type::WhenKeyword:
578
+ case Type::WhileKeyword:
579
+ case Type::YieldKeyword:
580
+ return true;
581
+ default:
582
+ return false;
583
+ }
584
+ }
585
+
586
+ bool is_operator() const {
587
+ switch (m_type) {
588
+ case Token::Type::Ampersand:
589
+ case Token::Type::Caret:
590
+ case Token::Type::Comparison:
591
+ case Token::Type::EqualEqual:
592
+ case Token::Type::EqualEqualEqual:
593
+ case Token::Type::GreaterThan:
594
+ case Token::Type::GreaterThanOrEqual:
595
+ case Token::Type::LBracketRBracket:
596
+ case Token::Type::LBracketRBracketEqual:
597
+ case Token::Type::LeftShift:
598
+ case Token::Type::LessThan:
599
+ case Token::Type::LessThanOrEqual:
600
+ case Token::Type::Match:
601
+ case Token::Type::Minus:
602
+ case Token::Type::NotEqual:
603
+ case Token::Type::NotMatch:
604
+ case Token::Type::Percent:
605
+ case Token::Type::Pipe:
606
+ case Token::Type::Plus:
607
+ case Token::Type::RightShift:
608
+ case Token::Type::Slash:
609
+ case Token::Type::Star:
610
+ case Token::Type::StarStar:
611
+ case Token::Type::Tilde:
612
+ return true;
613
+ default:
614
+ return false;
615
+ }
616
+ }
617
+
618
+ bool is_bare_name() const { return m_type == Type::BareName; }
619
+ bool is_block_arg_delimiter() const { return m_type == Type::Pipe; }
620
+ bool is_closing_token() const { return m_type == Type::RBracket || m_type == Type::RCurlyBrace || m_type == Type::RParen; }
621
+ bool is_comma() const { return m_type == Type::Comma; }
622
+ bool is_comment() const { return m_type == Type::Comment; }
623
+ bool is_def_keyword() const { return m_type == Type::DefKeyword; }
624
+ bool is_doc() const { return m_type == Type::Doc; }
625
+ bool is_dot() const { return m_type == Type::Dot; }
626
+ bool is_else_keyword() const { return m_type == Type::ElseKeyword; }
627
+ bool is_elsif_keyword() const { return m_type == Type::ElsifKeyword; }
628
+ bool is_end_keyword() const { return m_type == Type::EndKeyword; }
629
+ bool is_end_of_expression() const { return m_type == Type::EndKeyword || m_type == Type::RCurlyBrace || m_type == Type::Newline || m_type == Type::Semicolon || m_type == Type::Eof || is_expression_modifier(); }
630
+ bool is_eof() const { return m_type == Type::Eof; }
631
+ bool is_end_of_line() const { return m_type == Type::Newline || m_type == Type::Semicolon; }
632
+ bool is_equal() const { return m_type == Type::Equal; }
633
+ bool is_expression_modifier() const { return m_type == Type::IfKeyword || m_type == Type::UnlessKeyword || m_type == Type::WhileKeyword || m_type == Type::UntilKeyword; }
634
+ bool is_hash_rocket() const { return m_type == Type::HashRocket; }
635
+ bool is_lparen() const { return m_type == Type::LParen; }
636
+ bool is_newline() const { return m_type == Type::Newline; }
637
+ bool is_rbracket() const { return m_type == Type::RBracket; }
638
+ bool is_rparen() const { return m_type == Type::RParen; }
639
+ bool is_semicolon() const { return m_type == Type::Semicolon; }
640
+ bool is_splat() const { return m_type == Type::Star || m_type == Type::StarStar; }
641
+ bool is_symbol_key() const { return m_type == Type::SymbolKey; }
642
+ bool is_when_keyword() const { return m_type == Type::WhenKeyword; }
643
+
644
+ bool is_valid() const {
645
+ return !!type_value();
646
+ }
647
+
648
+ bool can_follow_collapsible_newline() const {
649
+ switch (m_type) {
650
+ case Token::Type::Dot:
651
+ case Token::Type::RCurlyBrace:
652
+ case Token::Type::RBracket:
653
+ case Token::Type::RParen:
654
+ case Token::Type::SafeNavigation:
655
+ case Token::Type::TernaryColon:
656
+ return true;
657
+ default:
658
+ return false;
659
+ }
660
+ }
661
+
662
+ bool can_precede_collapsible_newline() const {
663
+ switch (m_type) {
664
+ case Token::Type::AmpersandAmpersand:
665
+ case Token::Type::AndKeyword:
666
+ case Token::Type::Arrow:
667
+ case Token::Type::Ampersand:
668
+ case Token::Type::Caret:
669
+ case Token::Type::CaseKeyword:
670
+ case Token::Type::Comma:
671
+ case Token::Type::Comparison:
672
+ case Token::Type::ConstantResolution:
673
+ case Token::Type::Dot:
674
+ case Token::Type::DotDot:
675
+ case Token::Type::Equal:
676
+ case Token::Type::EqualEqual:
677
+ case Token::Type::EqualEqualEqual:
678
+ case Token::Type::GreaterThan:
679
+ case Token::Type::GreaterThanOrEqual:
680
+ case Token::Type::HashRocket:
681
+ case Token::Type::InKeyword:
682
+ case Token::Type::LCurlyBrace:
683
+ case Token::Type::LBracket:
684
+ case Token::Type::LeftShift:
685
+ case Token::Type::LessThan:
686
+ case Token::Type::LessThanOrEqual:
687
+ case Token::Type::LParen:
688
+ case Token::Type::Match:
689
+ case Token::Type::Minus:
690
+ case Token::Type::MinusEqual:
691
+ case Token::Type::Not:
692
+ case Token::Type::NotEqual:
693
+ case Token::Type::NotMatch:
694
+ case Token::Type::OrKeyword:
695
+ case Token::Type::Percent:
696
+ case Token::Type::PercentEqual:
697
+ case Token::Type::Pipe:
698
+ case Token::Type::PipePipe:
699
+ case Token::Type::Plus:
700
+ case Token::Type::PlusEqual:
701
+ case Token::Type::RightShift:
702
+ case Token::Type::SafeNavigation:
703
+ case Token::Type::Slash:
704
+ case Token::Type::SlashEqual:
705
+ case Token::Type::Star:
706
+ case Token::Type::StarEqual:
707
+ case Token::Type::StarStar:
708
+ case Token::Type::StarStarEqual:
709
+ case Token::Type::TernaryColon:
710
+ case Token::Type::TernaryQuestion:
711
+ case Token::Type::Tilde:
712
+ return true;
713
+ default:
714
+ return false;
715
+ }
716
+ }
717
+
718
+ bool can_have_doc() const {
719
+ switch (m_type) {
720
+ case Token::Type::ClassKeyword:
721
+ case Token::Type::DefKeyword:
722
+ case Token::Type::ModuleKeyword:
723
+ return true;
724
+ default:
725
+ return false;
726
+ }
727
+ }
728
+
729
+ bool can_be_first_arg_of_implicit_call() const {
730
+ switch (m_type) {
731
+ case Token::Type::Arrow:
732
+ case Token::Type::BareName:
733
+ case Token::Type::BeginKeyword:
734
+ case Token::Type::Bignum:
735
+ case Token::Type::ClassVariable:
736
+ case Token::Type::Constant:
737
+ case Token::Type::ConstantResolution:
738
+ case Token::Type::DefKeyword:
739
+ case Token::Type::DefinedKeyword:
740
+ case Token::Type::DoKeyword:
741
+ case Token::Type::ENCODINGKeyword:
742
+ case Token::Type::FalseKeyword:
743
+ case Token::Type::FILEKeyword:
744
+ case Token::Type::Fixnum:
745
+ case Token::Type::Float:
746
+ case Token::Type::GlobalVariable:
747
+ case Token::Type::InstanceVariable:
748
+ case Token::Type::InterpolatedRegexpBegin:
749
+ case Token::Type::InterpolatedShellBegin:
750
+ case Token::Type::InterpolatedStringBegin:
751
+ case Token::Type::InterpolatedSymbolBegin:
752
+ case Token::Type::LCurlyBrace:
753
+ case Token::Type::LBracket:
754
+ case Token::Type::LBracketRBracket:
755
+ case Token::Type::LINEKeyword:
756
+ case Token::Type::LParen:
757
+ case Token::Type::NilKeyword:
758
+ case Token::Type::Not:
759
+ case Token::Type::NotKeyword:
760
+ case Token::Type::PercentLowerI:
761
+ case Token::Type::PercentLowerW:
762
+ case Token::Type::PercentUpperI:
763
+ case Token::Type::PercentUpperW:
764
+ case Token::Type::SelfKeyword:
765
+ case Token::Type::Star:
766
+ case Token::Type::String:
767
+ case Token::Type::SuperKeyword:
768
+ case Token::Type::Symbol:
769
+ case Token::Type::SymbolKey:
770
+ case Token::Type::Tilde:
771
+ case Token::Type::TrueKeyword:
772
+ case Token::Type::YieldKeyword:
773
+ return true;
774
+ default:
775
+ return false;
776
+ }
777
+ }
778
+
779
+ bool can_precede_heredoc_that_looks_like_left_shift_operator() const {
780
+ switch (m_type) {
781
+ case Token::Type::Equal:
782
+ case Token::Type::LBracket:
783
+ return true;
784
+ default:
785
+ if (is_operator())
786
+ return true;
787
+ return false;
788
+ }
789
+ }
790
+
791
+ bool can_precede_symbol_key() const {
792
+ switch (m_type) {
793
+ case Type::BareName:
794
+ case Type::Comma:
795
+ case Type::Constant:
796
+ case Type::LBracket:
797
+ case Type::LCurlyBrace:
798
+ case Type::LParen:
799
+ case Type::Pipe:
800
+ case Type::PipePipe:
801
+ return true;
802
+ default:
803
+ return false;
804
+ }
805
+ }
806
+
807
+ void set_literal(const char *literal) { m_literal = new String(literal); }
808
+ void set_literal(SharedPtr<String> literal) { m_literal = literal; }
809
+ void set_literal(String literal) { m_literal = new String(literal); }
810
+
811
+ Optional<SharedPtr<String>> doc() const { return m_doc; }
812
+ void set_doc(SharedPtr<String> doc) { m_doc = doc; }
813
+
814
+ long long get_fixnum() const { return m_fixnum; }
815
+ double get_double() const { return m_double; }
816
+
817
+ SharedPtr<String> file() const { return m_file; }
818
+
819
+ size_t line() const { return m_line; }
820
+ void set_line(size_t line) { m_line = line; }
821
+
822
+ size_t column() const { return m_column; }
823
+ void set_column(size_t column) { m_column = column; }
824
+
825
+ bool whitespace_precedes() const { return m_whitespace_precedes; }
826
+ void set_whitespace_precedes(bool whitespace_precedes) { m_whitespace_precedes = whitespace_precedes; }
827
+
828
+ void validate();
829
+
830
+ private:
831
+ Type m_type { Type::Invalid };
832
+ Optional<SharedPtr<String>> m_literal {};
833
+ Optional<SharedPtr<String>> m_doc {};
834
+ long long m_fixnum { 0 };
835
+ double m_double { 0 };
836
+ SharedPtr<String> m_file;
837
+ size_t m_line { 0 };
838
+ size_t m_column { 0 };
839
+ bool m_whitespace_precedes { false };
840
+ static inline Token *s_invalid { nullptr };
841
+ };
842
+ }