Ruby: node_dump.c Source File

Ruby 3.4.3p32 (2025-04-14 revision d0b7e5b6a04bde21ca483d20a1546b28b401c2d4)

node_dump.c
1/**********************************************************************
2
3 node_dump.c - dump ruby node tree
4
5 $Author: mame $
6 created at: 09/12/06 21:23:44 JST
7
8 Copyright (C) 2009 Yusuke Endoh
9
10**********************************************************************/
11
12#include "internal.h"
13#include "internal/class.h"
14#include "internal/hash.h"
15#include "internal/ruby_parser.h"
16#include "internal/variable.h"
17#include "ruby/ruby.h"
18#include "vm_core.h"
19
20#define A(str) rb_str_cat2(buf, (str))
21#define AR(str) rb_str_concat(buf, (str))
22
23#define A_INDENT add_indent(buf, indent)
24#define D_INDENT rb_str_cat2(indent, next_indent)
25#define D_DEDENT rb_str_resize(indent, RSTRING_LEN(indent) - 4)
26#define A_ID(id) add_id(buf, (id))
27#define A_INT(val) rb_str_catf(buf, "%d", (val))
28#define A_LONG(val) rb_str_catf(buf, "%ld", (val))
29#define A_LIT(lit) AR(rb_dump_literal(lit))
30#define A_LOC(loc) \
31 rb_str_catf(buf, "(%d,%d)-(%d,%d)", \
32 loc.beg_pos.lineno, loc.beg_pos.column, \
33 loc.end_pos.lineno, loc.end_pos.column)
34#define A_NODE_HEADER(node, term) \
35 rb_str_catf(buf, "@ %s (id: %d, line: %d, location: (%d,%d)-(%d,%d))%s"term, \
36 ruby_node_name(nd_type(node)), nd_node_id(node), nd_line(node), \
37 nd_first_lineno(node), nd_first_column(node), \
38 nd_last_lineno(node), nd_last_column(node), \
39 (nd_fl_newline(node) ? "*" : ""))
40#define A_FIELD_HEADER(len, name, term) \
41 rb_str_catf(buf, "+- %.*s:"term, (len), (name))
42#define D_FIELD_HEADER(len, name, term) (A_INDENT, A_FIELD_HEADER(len, name, term))
43
44#define D_NULL_NODE (A_INDENT, A("(null node)\n"))
45#define D_NODE_HEADER(node) (A_INDENT, A_NODE_HEADER(node, "\n"))
46
47#define COMPOUND_FIELD(len, name) \
48 FIELD_BLOCK((D_FIELD_HEADER((len), (name), "\n"), D_INDENT), D_DEDENT)
49
50#define COMPOUND_FIELD1(name, ann) \
51 COMPOUND_FIELD(FIELD_NAME_LEN(name, ann), \
52 FIELD_NAME_DESC(name, ann))
53
54#define FIELD_NAME_DESC(name, ann) name " (" ann ")"
55#define FIELD_NAME_LEN(name, ann) (int)( \
56 comment ? \
57 rb_strlen_lit(FIELD_NAME_DESC(name, ann)) : \
58 rb_strlen_lit(name))
59#define SIMPLE_FIELD(len, name) \
60 FIELD_BLOCK(D_FIELD_HEADER((len), (name), " "), A("\n"))
61
62#define FIELD_BLOCK(init, reset) \
63 for (init, field_flag = 1; \
64 field_flag; /* should be optimized away */ \
65 reset, field_flag = 0)
66
67#define A_SHAREABILITY(shareability) \
68 switch (shareability) { \
69 case rb_parser_shareable_none: \
70 rb_str_cat_cstr(buf, "none"); \
71 break; \
72 case rb_parser_shareable_literal: \
73 rb_str_cat_cstr(buf, "literal"); \
74 break; \
75 case rb_parser_shareable_copy: \
76 rb_str_cat_cstr(buf, "experimental_copy"); \
77 break; \
78 case rb_parser_shareable_everything: \
79 rb_str_cat_cstr(buf, "experimental_everything"); \
80 break; \
81 }
82
83#define SIMPLE_FIELD1(name, ann) SIMPLE_FIELD(FIELD_NAME_LEN(name, ann), FIELD_NAME_DESC(name, ann))
84#define F_CUSTOM1(name, ann) SIMPLE_FIELD1(#name, ann)
85#define F_ID(name, type, ann) SIMPLE_FIELD1(#name, ann) A_ID(type(node)->name)
86#define F_INT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_INT(type(node)->name)
87#define F_LONG(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LONG(type(node)->name)
88#define F_LIT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LIT(type(node)->name)
89#define F_VALUE(name, val, ann) SIMPLE_FIELD1(#name, ann) A_LIT(val)
90#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
91#define F_LOC(name, type) SIMPLE_FIELD1(#name, "") A_LOC(type(node)->name)
92#define F_SHAREABILITY(name, type, ann) SIMPLE_FIELD1(#name, ann) A_SHAREABILITY(type(node)->name)
93
94#define F_NODE(name, type, ann) \
95 COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, RNODE(type(node)->name));}
96
97#define F_NODE2(name, n, ann) \
98 COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, n);}
99
100#define F_ARRAY(name, type, ann) \
101 COMPOUND_FIELD1(#name, ann) {dump_parser_array(buf, indent, comment, type(node)->name);}
102
103#define ANN(ann) \
104 if (comment) { \
105 A_INDENT; A("| # " ann "\n"); \
106 }
107
108#define LAST_NODE (next_indent = " ")
109
110 VALUE
111rb_dump_literal(VALUE lit)
112{
113 if (!RB_SPECIAL_CONST_P(lit)) {
114 VALUE str;
115 switch (RB_BUILTIN_TYPE(lit)) {
116 case T_CLASS: case T_MODULE: case T_ICLASS:
117 str = rb_class_path(lit);
118 if (RCLASS_SINGLETON_P(lit)) {
119 str = rb_sprintf("<%"PRIsVALUE">", str);
120 }
121 return str;
122 default:
123 break;
124 }
125 }
126 return rb_inspect(lit);
127}
128
129static void
130add_indent(VALUE buf, VALUE indent)
131{
132 AR(indent);
133}
134
135static void
136add_id(VALUE buf, ID id)
137{
138 if (id == 0) {
139 A("(null)");
140 }
141 else {
142 VALUE str = rb_id2str(id);
143 if (str) {
144 A(":"); AR(str);
145 }
146 else {
147 rb_str_catf(buf, "(internal variable: 0x%"PRIsVALUE")", id);
148 }
149 }
150}
151
152 struct add_option_arg {
153 VALUE buf, indent;
154 st_index_t count;
155};
156
157static void dump_node(VALUE, VALUE, int, const NODE *);
158static const char default_indent[] = "| ";
159
160static void
161dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
162{
163 int field_flag;
164 const char *next_indent = default_indent;
165 F_LONG(as.nd_alen, RNODE_LIST, "length");
166 F_NODE(nd_head, RNODE_LIST, "element");
167 while (RNODE_LIST(node)->nd_next && nd_type_p(RNODE_LIST(node)->nd_next, NODE_LIST)) {
168 node = RNODE_LIST(node)->nd_next;
169 F_NODE(nd_head, RNODE_LIST, "element");
170 }
171 LAST_NODE;
172 F_NODE(nd_next, RNODE_LIST, "next element");
173}
174
175static void
176dump_parser_array(VALUE buf, VALUE indent, int comment, const rb_parser_ary_t *ary)
177{
178 int field_flag;
179 const char *next_indent = default_indent;
180
181 if (ary->data_type != PARSER_ARY_DATA_NODE) {
182 rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type);
183 }
184
185 F_CUSTOM1(length, "length") { A_LONG(ary->len); }
186 for (long i = 0; i < ary->len; i++) {
187 if (i == ary->len - 1) LAST_NODE;
188 A_INDENT;
189 rb_str_catf(buf, "+- element (%s%ld):\n",
190 comment ? "statement #" : "", i);
191 D_INDENT;
192 dump_node(buf, indent, comment, ary->data[i]);
193 D_DEDENT;
194 }
195}
196
197static void
198dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
199{
200 int field_flag;
201 int i;
202 const char *next_indent = default_indent;
203 enum node_type type;
204
205 if (!node) {
206 D_NULL_NODE;
207 return;
208 }
209
210 D_NODE_HEADER(node);
211
212 type = nd_type(node);
213 switch (type) {
214 case NODE_BLOCK:
215 ANN("statement sequence");
216 ANN("format: [nd_head]; ...; [nd_next]");
217 ANN("example: foo; bar");
218 i = 0;
219 do {
220 A_INDENT;
221 rb_str_catf(buf, "+- nd_head (%s%d):\n",
222 comment ? "statement #" : "", ++i);
223 if (!RNODE_BLOCK(node)->nd_next) LAST_NODE;
224 D_INDENT;
225 dump_node(buf, indent, comment, RNODE_BLOCK(node)->nd_head);
226 D_DEDENT;
227 } while (RNODE_BLOCK(node)->nd_next &&
228 nd_type_p(RNODE_BLOCK(node)->nd_next, NODE_BLOCK) &&
229 (node = RNODE_BLOCK(node)->nd_next, 1));
230 if (RNODE_BLOCK(node)->nd_next) {
231 LAST_NODE;
232 F_NODE(nd_next, RNODE_BLOCK, "next block");
233 }
234 return;
235
236 case NODE_IF:
237 ANN("if statement");
238 ANN("format: if [nd_cond] then [nd_body] else [nd_else] end");
239 ANN("example: if x == 1 then foo else bar end");
240 F_NODE(nd_cond, RNODE_IF, "condition expr");
241 F_NODE(nd_body, RNODE_IF, "then clause");
242 LAST_NODE;
243 F_NODE(nd_else, RNODE_IF, "else clause");
244 return;
245
246 case NODE_UNLESS:
247 ANN("unless statement");
248 ANN("format: unless [nd_cond] then [nd_body] else [nd_else] end");
249 ANN("example: unless x == 1 then foo else bar end");
250 F_NODE(nd_cond, RNODE_UNLESS, "condition expr");
251 F_NODE(nd_body, RNODE_UNLESS, "then clause");
252 F_NODE(nd_else, RNODE_UNLESS, "else clause");
253 F_LOC(keyword_loc, RNODE_UNLESS);
254 F_LOC(then_keyword_loc, RNODE_UNLESS);
255 LAST_NODE;
256 F_LOC(end_keyword_loc, RNODE_UNLESS);
257 return;
258
259 case NODE_CASE:
260 ANN("case statement");
261 ANN("format: case [nd_head]; [nd_body]; end");
262 ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
263 F_NODE(nd_head, RNODE_CASE, "case expr");
264 F_NODE(nd_body, RNODE_CASE, "when clauses");
265 F_LOC(case_keyword_loc, RNODE_CASE);
266 LAST_NODE;
267 F_LOC(end_keyword_loc, RNODE_CASE);
268 return;
269 case NODE_CASE2:
270 ANN("case statement with no head");
271 ANN("format: case; [nd_body]; end");
272 ANN("example: case; when 1; foo; when 2; bar; else baz; end");
273 F_NODE(nd_head, RNODE_CASE2, "case expr");
274 F_NODE(nd_body, RNODE_CASE2, "when clauses");
275 F_LOC(case_keyword_loc, RNODE_CASE2);
276 LAST_NODE;
277 F_LOC(end_keyword_loc, RNODE_CASE2);
278 return;
279 case NODE_CASE3:
280 ANN("case statement (pattern matching)");
281 ANN("format: case [nd_head]; [nd_body]; end");
282 ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
283 F_NODE(nd_head, RNODE_CASE3, "case expr");
284 F_NODE(nd_body, RNODE_CASE3, "in clauses");
285 F_LOC(case_keyword_loc, RNODE_CASE3);
286 LAST_NODE;
287 F_LOC(end_keyword_loc, RNODE_CASE3);
288 return;
289
290 case NODE_WHEN:
291 ANN("when clause");
292 ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
293 ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
294 F_NODE(nd_head, RNODE_WHEN, "when value");
295 F_NODE(nd_body, RNODE_WHEN, "when body");
296 LAST_NODE;
297 F_NODE(nd_next, RNODE_WHEN, "next when clause");
298 F_LOC(keyword_loc, RNODE_WHEN);
299 LAST_NODE;
300 F_LOC(then_keyword_loc, RNODE_WHEN);
301 return;
302
303 case NODE_IN:
304 ANN("in clause");
305 ANN("format: in [nd_head]; [nd_body]; (in or else) [nd_next]");
306 ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
307 F_NODE(nd_head, RNODE_IN, "in pattern");
308 F_NODE(nd_body, RNODE_IN, "in body");
309 LAST_NODE;
310 F_NODE(nd_next, RNODE_IN, "next in clause");
311 return;
312
313 case NODE_WHILE:
314 ANN("while statement");
315 ANN("format: while [nd_cond]; [nd_body]; end");
316 ANN("example: while x == 1; foo; end");
317 goto loop;
318 case NODE_UNTIL:
319 ANN("until statement");
320 ANN("format: until [nd_cond]; [nd_body]; end");
321 ANN("example: until x == 1; foo; end");
322 loop:
323 F_CUSTOM1(nd_state, "begin-end-while?") {
324 A_INT((int)RNODE_WHILE(node)->nd_state);
325 A((RNODE_WHILE(node)->nd_state == 1) ? " (while-end)" : " (begin-end-while)");
326 }
327 F_NODE(nd_cond, RNODE_WHILE, "condition");
328 F_NODE(nd_body, RNODE_WHILE, "body");
329 F_LOC(keyword_loc, RNODE_WHILE);
330 LAST_NODE;
331 F_LOC(closing_loc, RNODE_WHILE);
332 return;
333
334 case NODE_ITER:
335 ANN("method call with block");
336 ANN("format: [nd_iter] { [nd_body] }");
337 ANN("example: 3.times { foo }");
338 goto iter;
339 case NODE_FOR:
340 ANN("for statement");
341 ANN("format: for * in [nd_iter] do [nd_body] end");
342 ANN("example: for i in 1..3 do foo end");
343 iter:
344 F_NODE(nd_iter, RNODE_ITER, "iteration receiver");
345 LAST_NODE;
346 F_NODE(nd_body, RNODE_ITER, "body");
347 return;
348
349 case NODE_FOR_MASGN:
350 ANN("vars of for statement with masgn");
351 ANN("format: for [nd_var] in ... do ... end");
352 ANN("example: for x, y in 1..3 do foo end");
353 LAST_NODE;
354 F_NODE(nd_var, RNODE_FOR_MASGN, "var");
355 return;
356
357 case NODE_BREAK:
358 ANN("break statement");
359 ANN("format: break [nd_stts]");
360 ANN("example: break 1");
361 F_NODE(nd_stts, RNODE_BREAK, "value");
362 LAST_NODE;
363 F_LOC(keyword_loc, RNODE_BREAK);
364 return;
365 case NODE_NEXT:
366 ANN("next statement");
367 ANN("format: next [nd_stts]");
368 ANN("example: next 1");
369 F_NODE(nd_stts, RNODE_NEXT, "value");
370 LAST_NODE;
371 F_LOC(keyword_loc, RNODE_NEXT);
372 return;
373 case NODE_RETURN:
374 ANN("return statement");
375 ANN("format: return [nd_stts]");
376 ANN("example: return 1");
377 F_NODE(nd_stts, RNODE_RETURN, "value");
378 LAST_NODE;
379 F_LOC(keyword_loc, RNODE_RETURN);
380 return;
381
382 case NODE_REDO:
383 ANN("redo statement");
384 ANN("format: redo");
385 ANN("example: redo");
386 F_LOC(keyword_loc, RNODE_REDO);
387 return;
388
389 case NODE_RETRY:
390 ANN("retry statement");
391 ANN("format: retry");
392 ANN("example: retry");
393 return;
394
395 case NODE_BEGIN:
396 ANN("begin statement");
397 ANN("format: begin; [nd_body]; end");
398 ANN("example: begin; 1; end");
399 LAST_NODE;
400 F_NODE(nd_body, RNODE_BEGIN, "body");
401 return;
402
403 case NODE_RESCUE:
404 ANN("rescue clause");
405 ANN("format: begin; [nd_body]; (rescue) [nd_resq]; else [nd_else]; end");
406 ANN("example: begin; foo; rescue; bar; else; baz; end");
407 F_NODE(nd_head, RNODE_RESCUE, "body");
408 F_NODE(nd_resq, RNODE_RESCUE, "rescue clause list");
409 LAST_NODE;
410 F_NODE(nd_else, RNODE_RESCUE, "rescue else clause");
411 return;
412
413 case NODE_RESBODY:
414 ANN("rescue clause (cont'd)");
415 ANN("format: rescue [nd_args] (=> [nd_exc_var]); [nd_body]; (rescue) [nd_next]");
416 ANN("example: begin; foo; rescue; bar; else; baz; end");
417 F_NODE(nd_args, RNODE_RESBODY, "rescue exceptions");
418 F_NODE(nd_exc_var, RNODE_RESBODY, "exception variable");
419 F_NODE(nd_body, RNODE_RESBODY, "rescue clause");
420 LAST_NODE;
421 F_NODE(nd_next, RNODE_RESBODY, "next rescue clause");
422 return;
423
424 case NODE_ENSURE:
425 ANN("ensure clause");
426 ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
427 ANN("example: begin; foo; ensure; bar; end");
428 F_NODE(nd_head, RNODE_ENSURE, "body");
429 LAST_NODE;
430 F_NODE(nd_ensr, RNODE_ENSURE, "ensure clause");
431 return;
432
433 case NODE_AND:
434 ANN("&& operator");
435 ANN("format: [nd_1st] && [nd_2nd]");
436 ANN("example: foo && bar");
437 goto andor;
438 case NODE_OR:
439 ANN("|| operator");
440 ANN("format: [nd_1st] || [nd_2nd]");
441 ANN("example: foo || bar");
442 andor:
443 while (1) {
444 F_NODE(nd_1st, RNODE_AND, "left expr");
445 if (!RNODE_AND(node)->nd_2nd || !nd_type_p(RNODE_AND(node)->nd_2nd, type))
446 break;
447 node = RNODE_AND(node)->nd_2nd;
448 }
449 F_NODE(nd_2nd, RNODE_AND, "right expr");
450 LAST_NODE;
451 F_LOC(operator_loc, RNODE_AND);
452 return;
453
454 case NODE_MASGN:
455 ANN("multiple assignment");
456 ANN("format: [nd_head], [nd_args] = [nd_value]");
457 ANN("example: a, b = foo");
458 F_NODE(nd_value, RNODE_MASGN, "rhsn");
459 F_NODE(nd_head, RNODE_MASGN, "lhsn");
460 if (NODE_NAMED_REST_P(RNODE_MASGN(node)->nd_args)) {
461 LAST_NODE;
462 F_NODE(nd_args, RNODE_MASGN, "splatn");
463 }
464 else {
465 F_MSG(nd_args, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
466 }
467 return;
468
469 case NODE_LASGN:
470 ANN("local variable assignment");
471 ANN("format: [nd_vid](lvar) = [nd_value]");
472 ANN("example: x = foo");
473 F_ID(nd_vid, RNODE_LASGN, "local variable");
474 if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node)->nd_value)) {
475 F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
476 }
477 else {
478 LAST_NODE;
479 F_NODE(nd_value, RNODE_LASGN, "rvalue");
480 }
481 return;
482 case NODE_DASGN:
483 ANN("dynamic variable assignment");
484 ANN("format: [nd_vid](dvar) = [nd_value]");
485 ANN("example: x = nil; 1.times { x = foo }");
486 ANN("example: 1.times { x = foo }");
487 F_ID(nd_vid, RNODE_DASGN, "local variable");
488 if (NODE_REQUIRED_KEYWORD_P(RNODE_DASGN(node)->nd_value)) {
489 F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
490 }
491 else {
492 LAST_NODE;
493 F_NODE(nd_value, RNODE_DASGN, "rvalue");
494 }
495 return;
496 case NODE_IASGN:
497 ANN("instance variable assignment");
498 ANN("format: [nd_vid](ivar) = [nd_value]");
499 ANN("example: @x = foo");
500 F_ID(nd_vid, RNODE_IASGN, "instance variable");
501 LAST_NODE;
502 F_NODE(nd_value, RNODE_IASGN, "rvalue");
503 return;
504 case NODE_CVASGN:
505 ANN("class variable assignment");
506 ANN("format: [nd_vid](cvar) = [nd_value]");
507 ANN("example: @@x = foo");
508 F_ID(nd_vid, RNODE_CVASGN, "class variable");
509 LAST_NODE;
510 F_NODE(nd_value, RNODE_CVASGN, "rvalue");
511 return;
512 case NODE_GASGN:
513 ANN("global variable assignment");
514 ANN("format: [nd_vid](gvar) = [nd_value]");
515 ANN("example: $x = foo");
516 F_ID(nd_vid, RNODE_GASGN, "global variable");
517 LAST_NODE;
518 F_NODE(nd_value, RNODE_GASGN, "rvalue");
519 return;
520
521 case NODE_CDECL:
522 ANN("constant declaration");
523 ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
524 ANN("example: X = foo");
525 if (RNODE_CDECL(node)->nd_vid) {
526 F_ID(nd_vid, RNODE_CDECL, "constant");
527 F_MSG(nd_else, "extension", "not used");
528 }
529 else {
530 F_MSG(nd_vid, "constant", "0 (see extension field)");
531 F_NODE(nd_else, RNODE_CDECL, "extension");
532 }
533 F_SHAREABILITY(shareability, RNODE_CDECL, "shareability");
534 LAST_NODE;
535 F_NODE(nd_value, RNODE_CDECL, "rvalue");
536 return;
537
538 case NODE_OP_ASGN1:
539 ANN("array assignment with operator");
540 ANN("format: [nd_recv] [ [nd_index] ] [nd_mid]= [nd_rvalue]");
541 ANN("example: ary[1] += foo");
542 F_NODE(nd_recv, RNODE_OP_ASGN1, "receiver");
543 F_ID(nd_mid, RNODE_OP_ASGN1, "operator");
544 F_NODE(nd_index, RNODE_OP_ASGN1, "index");
545 F_NODE(nd_rvalue, RNODE_OP_ASGN1, "rvalue");
546 F_LOC(call_operator_loc, RNODE_OP_ASGN1);
547 F_LOC(opening_loc, RNODE_OP_ASGN1);
548 F_LOC(closing_loc, RNODE_OP_ASGN1);
549 LAST_NODE;
550 F_LOC(binary_operator_loc, RNODE_OP_ASGN1);
551 return;
552
553 case NODE_OP_ASGN2:
554 ANN("attr assignment with operator");
555 ANN("format: [nd_recv].[nd_vid] [nd_mid]= [nd_value]");
556 ANN("example: struct.field += foo");
557 F_NODE(nd_recv, RNODE_OP_ASGN2, "receiver");
558 F_CUSTOM1(nd_vid, "attr") {
559 if (RNODE_OP_ASGN2(node)->nd_aid) A("? ");
560 A_ID(RNODE_OP_ASGN2(node)->nd_vid);
561 }
562 F_ID(nd_mid, RNODE_OP_ASGN2, "operator");
563 F_NODE(nd_value, RNODE_OP_ASGN2, "rvalue");
564 F_LOC(call_operator_loc, RNODE_OP_ASGN2);
565 F_LOC(message_loc, RNODE_OP_ASGN2);
566 LAST_NODE;
567 F_LOC(binary_operator_loc, RNODE_OP_ASGN2);
568 return;
569
570 case NODE_OP_ASGN_AND:
571 ANN("assignment with && operator");
572 ANN("format: [nd_head] &&= [nd_value]");
573 ANN("example: foo &&= bar");
574 goto asgn_andor;
575 case NODE_OP_ASGN_OR:
576 ANN("assignment with || operator");
577 ANN("format: [nd_head] ||= [nd_value]");
578 ANN("example: foo ||= bar");
579 asgn_andor:
580 F_NODE(nd_head, RNODE_OP_ASGN_AND, "variable");
581 LAST_NODE;
582 F_NODE(nd_value, RNODE_OP_ASGN_AND, "rvalue");
583 return;
584
585 case NODE_OP_CDECL:
586 ANN("constant declaration with operator");
587 ANN("format: [nd_head](constant) [nd_aid]= [nd_value]");
588 ANN("example: A::B ||= 1");
589 F_NODE(nd_head, RNODE_OP_CDECL, "constant");
590 F_ID(nd_aid, RNODE_OP_CDECL, "operator");
591 F_SHAREABILITY(shareability, RNODE_OP_CDECL, "shareability");
592 LAST_NODE;
593 F_NODE(nd_value, RNODE_OP_CDECL, "rvalue");
594 return;
595
596 case NODE_CALL:
597 ANN("method invocation");
598 ANN("format: [nd_recv].[nd_mid]([nd_args])");
599 ANN("example: obj.foo(1)");
600 F_ID(nd_mid, RNODE_CALL, "method id");
601 F_NODE(nd_recv, RNODE_CALL, "receiver");
602 LAST_NODE;
603 F_NODE(nd_args, RNODE_CALL, "arguments");
604 return;
605
606 case NODE_OPCALL:
607 ANN("method invocation");
608 ANN("format: [nd_recv] [nd_mid] [nd_args]");
609 ANN("example: foo + bar");
610 F_ID(nd_mid, RNODE_OPCALL, "method id");
611 F_NODE(nd_recv, RNODE_OPCALL, "receiver");
612 LAST_NODE;
613 F_NODE(nd_args, RNODE_OPCALL, "arguments");
614 return;
615
616 case NODE_FCALL:
617 ANN("function call");
618 ANN("format: [nd_mid]([nd_args])");
619 ANN("example: foo(1)");
620 F_ID(nd_mid, RNODE_FCALL, "method id");
621 LAST_NODE;
622 F_NODE(nd_args, RNODE_FCALL, "arguments");
623 return;
624
625 case NODE_VCALL:
626 ANN("function call with no argument");
627 ANN("format: [nd_mid]");
628 ANN("example: foo");
629 F_ID(nd_mid, RNODE_VCALL, "method id");
630 return;
631
632 case NODE_QCALL:
633 ANN("safe method invocation");
634 ANN("format: [nd_recv]&.[nd_mid]([nd_args])");
635 ANN("example: obj&.foo(1)");
636 F_ID(nd_mid, RNODE_QCALL, "method id");
637 F_NODE(nd_recv, RNODE_QCALL, "receiver");
638 LAST_NODE;
639 F_NODE(nd_args, RNODE_QCALL, "arguments");
640 return;
641
642 case NODE_SUPER:
643 ANN("super invocation");
644 ANN("format: super [nd_args]");
645 ANN("example: super 1");
646 LAST_NODE;
647 F_NODE(nd_args, RNODE_SUPER, "arguments");
648 return;
649
650 case NODE_ZSUPER:
651 ANN("super invocation with no argument");
652 ANN("format: super");
653 ANN("example: super");
654 return;
655
656 case NODE_LIST:
657 ANN("list constructor");
658 ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
659 ANN("example: [1, 2, 3]");
660 dump_array(buf, indent, comment, node);
661 return;
662
663 case NODE_ZLIST:
664 ANN("empty list constructor");
665 ANN("format: []");
666 ANN("example: []");
667 return;
668
669 case NODE_HASH:
670 if (!RNODE_HASH(node)->nd_brace) {
671 ANN("keyword arguments");
672 ANN("format: [nd_head]");
673 ANN("example: a: 1, b: 2");
674 }
675 else {
676 ANN("hash constructor");
677 ANN("format: { [nd_head] }");
678 ANN("example: { 1 => 2, 3 => 4 }");
679 }
680 F_CUSTOM1(nd_brace, "keyword arguments or hash literal") {
681 switch (RNODE_HASH(node)->nd_brace) {
682 case 0: A("0 (keyword argument)"); break;
683 case 1: A("1 (hash literal)"); break;
684 }
685 }
686 LAST_NODE;
687 F_NODE(nd_head, RNODE_HASH, "contents");
688 return;
689
690 case NODE_YIELD:
691 ANN("yield invocation");
692 ANN("format: yield [nd_head]");
693 ANN("example: yield 1");
694 LAST_NODE;
695 F_NODE(nd_head, RNODE_YIELD, "arguments");
696 return;
697
698 case NODE_LVAR:
699 ANN("local variable reference");
700 ANN("format: [nd_vid](lvar)");
701 ANN("example: x");
702 F_ID(nd_vid, RNODE_LVAR, "local variable");
703 return;
704 case NODE_DVAR:
705 ANN("dynamic variable reference");
706 ANN("format: [nd_vid](dvar)");
707 ANN("example: 1.times { x = 1; x }");
708 F_ID(nd_vid, RNODE_DVAR, "local variable");
709 return;
710 case NODE_IVAR:
711 ANN("instance variable reference");
712 ANN("format: [nd_vid](ivar)");
713 ANN("example: @x");
714 F_ID(nd_vid, RNODE_IVAR, "instance variable");
715 return;
716 case NODE_CONST:
717 ANN("constant reference");
718 ANN("format: [nd_vid](constant)");
719 ANN("example: X");
720 F_ID(nd_vid, RNODE_CONST, "constant");
721 return;
722 case NODE_CVAR:
723 ANN("class variable reference");
724 ANN("format: [nd_vid](cvar)");
725 ANN("example: @@x");
726 F_ID(nd_vid, RNODE_CVAR, "class variable");
727 return;
728
729 case NODE_GVAR:
730 ANN("global variable reference");
731 ANN("format: [nd_vid](gvar)");
732 ANN("example: $x");
733 F_ID(nd_vid, RNODE_GVAR, "global variable");
734 return;
735
736 case NODE_NTH_REF:
737 ANN("nth special variable reference");
738 ANN("format: $[nd_nth]");
739 ANN("example: $1, $2, ..");
740 F_CUSTOM1(nd_nth, "variable") { A("$"); A_LONG(RNODE_NTH_REF(node)->nd_nth); }
741 return;
742
743 case NODE_BACK_REF:
744 ANN("back special variable reference");
745 ANN("format: $[nd_nth]");
746 ANN("example: $&, $`, $', $+");
747 F_CUSTOM1(nd_nth, "variable") {
748 char name[3] = "$ ";
749 name[1] = (char)RNODE_BACK_REF(node)->nd_nth;
750 A(name);
751 }
752 return;
753
754 case NODE_MATCH:
755 ANN("match expression (against $_ implicitly)");
756 ANN("format: [nd_lit] (in condition)");
757 ANN("example: if /foo/; foo; end");
758 LAST_NODE;
759 F_VALUE(string, rb_node_regx_string_val(node), "string");
760 return;
761
762 case NODE_MATCH2:
763 ANN("match expression (regexp first)");
764 ANN("format: [nd_recv] =~ [nd_value]");
765 ANN("example: /foo/ =~ 'foo'");
766 F_NODE(nd_recv, RNODE_MATCH2, "regexp (receiver)");
767 if (!RNODE_MATCH2(node)->nd_args) LAST_NODE;
768 F_NODE(nd_value, RNODE_MATCH2, "string (argument)");
769 if (RNODE_MATCH2(node)->nd_args) {
770 LAST_NODE;
771 F_NODE(nd_args, RNODE_MATCH2, "named captures");
772 }
773 return;
774
775 case NODE_MATCH3:
776 ANN("match expression (regexp second)");
777 ANN("format: [nd_recv] =~ [nd_value]");
778 ANN("example: 'foo' =~ /foo/");
779 F_NODE(nd_recv, RNODE_MATCH3, "string (receiver)");
780 LAST_NODE;
781 F_NODE(nd_value, RNODE_MATCH3, "regexp (argument)");
782 return;
783
784 case NODE_STR:
785 ANN("string literal");
786 ANN("format: [nd_lit]");
787 ANN("example: 'foo'");
788 goto str;
789 case NODE_XSTR:
790 ANN("xstring literal");
791 ANN("format: [nd_lit]");
792 ANN("example: `foo`");
793 str:
794 F_VALUE(string, rb_node_str_string_val(node), "literal");
795 return;
796
797 case NODE_INTEGER:
798 ANN("integer literal");
799 ANN("format: [val]");
800 ANN("example: 1");
801 F_VALUE(val, rb_node_integer_literal_val(node), "val");
802 return;
803
804 case NODE_FLOAT:
805 ANN("float literal");
806 ANN("format: [val]");
807 ANN("example: 1.2");
808 F_VALUE(val, rb_node_float_literal_val(node), "val");
809 return;
810
811 case NODE_RATIONAL:
812 ANN("rational number literal");
813 ANN("format: [val]");
814 ANN("example: 1r");
815 F_VALUE(val, rb_node_rational_literal_val(node), "val");
816 return;
817
818 case NODE_IMAGINARY:
819 ANN("complex number literal");
820 ANN("format: [val]");
821 ANN("example: 1i");
822 F_VALUE(val, rb_node_imaginary_literal_val(node), "val");
823 return;
824
825 case NODE_REGX:
826 ANN("regexp literal");
827 ANN("format: [string]");
828 ANN("example: /foo/");
829 LAST_NODE;
830 F_VALUE(string, rb_node_regx_string_val(node), "string");
831 return;
832
833 case NODE_ONCE:
834 ANN("once evaluation");
835 ANN("format: [nd_body]");
836 ANN("example: /foo#{ bar }baz/o");
837 LAST_NODE;
838 F_NODE(nd_body, RNODE_ONCE, "body");
839 return;
840
841 case NODE_DSTR:
842 ANN("string literal with interpolation");
843 ANN("format: [nd_lit]");
844 ANN("example: \"foo#{ bar }baz\"");
845 goto dlit;
846 case NODE_DXSTR:
847 ANN("xstring literal with interpolation");
848 ANN("format: [nd_lit]");
849 ANN("example: `foo#{ bar }baz`");
850 goto dlit;
851 case NODE_DREGX:
852 ANN("regexp literal with interpolation");
853 ANN("format: [nd_lit]");
854 ANN("example: /foo#{ bar }baz/");
855 goto dlit;
856 case NODE_DSYM:
857 ANN("symbol literal with interpolation");
858 ANN("format: [nd_lit]");
859 ANN("example: :\"foo#{ bar }baz\"");
860 dlit:
861 F_VALUE(string, rb_node_dstr_string_val(node), "preceding string");
862 if (!RNODE_DSTR(node)->nd_next) return;
863 F_NODE(nd_next->nd_head, RNODE_DSTR, "interpolation");
864 LAST_NODE;
865 F_NODE(nd_next->nd_next, RNODE_DSTR, "tailing strings");
866 return;
867
868 case NODE_SYM:
869 ANN("symbol literal");
870 ANN("format: [string]");
871 ANN("example: :foo");
872 F_VALUE(string, rb_node_sym_string_val(node), "string");
873 return;
874
875 case NODE_EVSTR:
876 ANN("interpolation expression");
877 ANN("format: \"..#{ [nd_body] }..\"");
878 ANN("example: \"foo#{ bar }baz\"");
879 LAST_NODE;
880 F_NODE(nd_body, RNODE_EVSTR, "body");
881 return;
882
883 case NODE_ARGSCAT:
884 ANN("splat argument following arguments");
885 ANN("format: ..(*[nd_head], [nd_body..])");
886 ANN("example: foo(*ary, post_arg1, post_arg2)");
887 F_NODE(nd_head, RNODE_ARGSCAT, "preceding array");
888 LAST_NODE;
889 F_NODE(nd_body, RNODE_ARGSCAT, "following array");
890 return;
891
892 case NODE_ARGSPUSH:
893 ANN("splat argument following one argument");
894 ANN("format: ..(*[nd_head], [nd_body])");
895 ANN("example: foo(*ary, post_arg)");
896 F_NODE(nd_head, RNODE_ARGSPUSH, "preceding array");
897 LAST_NODE;
898 F_NODE(nd_body, RNODE_ARGSPUSH, "following element");
899 return;
900
901 case NODE_SPLAT:
902 ANN("splat argument");
903 ANN("format: *[nd_head]");
904 ANN("example: foo(*ary)");
905 F_NODE(nd_head, RNODE_SPLAT, "splat'ed array");
906 LAST_NODE;
907 F_LOC(operator_loc, RNODE_SPLAT);
908 return;
909
910 case NODE_BLOCK_PASS:
911 ANN("arguments with block argument");
912 ANN("format: ..([nd_head], &[nd_body])");
913 ANN("example: foo(x, &blk)");
914 F_CUSTOM1(forwarding, "arguments forwarding or not") {
915 switch (RNODE_BLOCK_PASS(node)->forwarding) {
916 case 0: A("0 (no forwarding)"); break;
917 case 1: A("1 (forwarding)"); break;
918 }
919 }
920 F_NODE(nd_head, RNODE_BLOCK_PASS, "other arguments");
921 F_NODE(nd_body, RNODE_BLOCK_PASS, "block argument");
922 LAST_NODE;
923 F_LOC(operator_loc, RNODE_BLOCK_PASS);
924 return;
925
926 case NODE_DEFN:
927 ANN("method definition");
928 ANN("format: def [nd_mid] [nd_defn]; end");
929 ANN("example: def foo; bar; end");
930 F_ID(nd_mid, RNODE_DEFN, "method name");
931 LAST_NODE;
932 F_NODE(nd_defn, RNODE_DEFN, "method definition");
933 return;
934
935 case NODE_DEFS:
936 ANN("singleton method definition");
937 ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
938 ANN("example: def obj.foo; bar; end");
939 F_NODE(nd_recv, RNODE_DEFS, "receiver");
940 F_ID(nd_mid, RNODE_DEFS, "method name");
941 LAST_NODE;
942 F_NODE(nd_defn, RNODE_DEFS, "method definition");
943 return;
944
945 case NODE_ALIAS:
946 ANN("method alias statement");
947 ANN("format: alias [nd_1st] [nd_2nd]");
948 ANN("example: alias bar foo");
949 F_NODE(nd_1st, RNODE_ALIAS, "new name");
950 F_NODE(nd_2nd, RNODE_ALIAS, "old name");
951 LAST_NODE;
952 F_LOC(keyword_loc, RNODE_ALIAS);
953 return;
954
955 case NODE_VALIAS:
956 ANN("global variable alias statement");
957 ANN("format: alias [nd_alias](gvar) [nd_orig](gvar)");
958 ANN("example: alias $y $x");
959 F_ID(nd_alias, RNODE_VALIAS, "new name");
960 F_ID(nd_orig, RNODE_VALIAS, "old name");
961 F_LOC(keyword_loc, RNODE_VALIAS);
962 return;
963
964 case NODE_UNDEF:
965 ANN("method undef statement");
966 ANN("format: undef [nd_undefs]");
967 ANN("example: undef foo");
968 LAST_NODE;
969 F_ARRAY(nd_undefs, RNODE_UNDEF, "nd_undefs");
970 F_LOC(keyword_loc, RNODE_UNDEF);
971 return;
972
973 case NODE_CLASS:
974 ANN("class definition");
975 ANN("format: class [nd_cpath] < [nd_super]; [nd_body]; end");
976 ANN("example: class C2 < C; ..; end");
977 F_NODE(nd_cpath, RNODE_CLASS, "class path");
978 F_NODE(nd_super, RNODE_CLASS, "superclass");
979 LAST_NODE;
980 F_NODE(nd_body, RNODE_CLASS, "class definition");
981 return;
982
983 case NODE_MODULE:
984 ANN("module definition");
985 ANN("format: module [nd_cpath]; [nd_body]; end");
986 ANN("example: module M; ..; end");
987 F_NODE(nd_cpath, RNODE_MODULE, "module path");
988 LAST_NODE;
989 F_NODE(nd_body, RNODE_MODULE, "module definition");
990 return;
991
992 case NODE_SCLASS:
993 ANN("singleton class definition");
994 ANN("format: class << [nd_recv]; [nd_body]; end");
995 ANN("example: class << obj; ..; end");
996 F_NODE(nd_recv, RNODE_SCLASS, "receiver");
997 LAST_NODE;
998 F_NODE(nd_body, RNODE_SCLASS, "singleton class definition");
999 return;
1000
1001 case NODE_COLON2:
1002 ANN("scoped constant reference");
1003 ANN("format: [nd_head]::[nd_mid]");
1004 ANN("example: M::C");
1005 F_ID(nd_mid, RNODE_COLON2, "constant name");
1006 LAST_NODE;
1007 F_NODE(nd_head, RNODE_COLON2, "receiver");
1008 return;
1009
1010 case NODE_COLON3:
1011 ANN("top-level constant reference");
1012 ANN("format: ::[nd_mid]");
1013 ANN("example: ::Object");
1014 F_ID(nd_mid, RNODE_COLON3, "constant name");
1015 return;
1016
1017 case NODE_DOT2:
1018 ANN("range constructor (incl.)");
1019 ANN("format: [nd_beg]..[nd_end]");
1020 ANN("example: 1..5");
1021 goto dot;
1022 case NODE_DOT3:
1023 ANN("range constructor (excl.)");
1024 ANN("format: [nd_beg]...[nd_end]");
1025 ANN("example: 1...5");
1026 goto dot;
1027 case NODE_FLIP2:
1028 ANN("flip-flop condition (incl.)");
1029 ANN("format: [nd_beg]..[nd_end]");
1030 ANN("example: if (x==1)..(x==5); foo; end");
1031 goto dot;
1032 case NODE_FLIP3:
1033 ANN("flip-flop condition (excl.)");
1034 ANN("format: [nd_beg]...[nd_end]");
1035 ANN("example: if (x==1)...(x==5); foo; end");
1036 dot:
1037 F_NODE(nd_beg, RNODE_DOT2, "begin");
1038 LAST_NODE;
1039 F_NODE(nd_end, RNODE_DOT2, "end");
1040 return;
1041
1042 case NODE_SELF:
1043 ANN("self");
1044 ANN("format: self");
1045 ANN("example: self");
1046 F_CUSTOM1(nd_state, "nd_state") {
1047 A_INT((int)RNODE_SELF(node)->nd_state);
1048 }
1049 return;
1050
1051 case NODE_NIL:
1052 ANN("nil");
1053 ANN("format: nil");
1054 ANN("example: nil");
1055 return;
1056
1057 case NODE_TRUE:
1058 ANN("true");
1059 ANN("format: true");
1060 ANN("example: true");
1061 return;
1062
1063 case NODE_FALSE:
1064 ANN("false");
1065 ANN("format: false");
1066 ANN("example: false");
1067 return;
1068
1069 case NODE_ERRINFO:
1070 ANN("virtual reference to $!");
1071 ANN("format: rescue => id");
1072 ANN("example: rescue => id");
1073 return;
1074
1075 case NODE_DEFINED:
1076 ANN("defined? expression");
1077 ANN("format: defined?([nd_head])");
1078 ANN("example: defined?(foo)");
1079 LAST_NODE;
1080 F_NODE(nd_head, RNODE_DEFINED, "expr");
1081 return;
1082
1083 case NODE_POSTEXE:
1084 ANN("post-execution");
1085 ANN("format: END { [nd_body] }");
1086 ANN("example: END { foo }");
1087 LAST_NODE;
1088 F_NODE(nd_body, RNODE_POSTEXE, "END clause");
1089 return;
1090
1091 case NODE_ATTRASGN:
1092 ANN("attr assignment");
1093 ANN("format: [nd_recv].[nd_mid] = [nd_args]");
1094 ANN("example: struct.field = foo");
1095 F_NODE(nd_recv, RNODE_ATTRASGN, "receiver");
1096 F_ID(nd_mid, RNODE_ATTRASGN, "method name");
1097 LAST_NODE;
1098 F_NODE(nd_args, RNODE_ATTRASGN, "arguments");
1099 return;
1100
1101 case NODE_LAMBDA:
1102 ANN("lambda expression");
1103 ANN("format: -> [nd_body]");
1104 ANN("example: -> { foo }");
1105 LAST_NODE;
1106 F_NODE(nd_body, RNODE_LAMBDA, "lambda clause");
1107 return;
1108
1109 case NODE_OPT_ARG:
1110 ANN("optional arguments");
1111 ANN("format: def method_name([nd_body=some], [nd_next..])");
1112 ANN("example: def foo(a, b=1, c); end");
1113 F_NODE(nd_body, RNODE_OPT_ARG, "body");
1114 LAST_NODE;
1115 F_NODE(nd_next, RNODE_OPT_ARG, "next");
1116 return;
1117
1118 case NODE_KW_ARG:
1119 ANN("keyword arguments");
1120 ANN("format: def method_name([nd_body=some], [nd_next..])");
1121 ANN("example: def foo(a:1, b:2); end");
1122 F_NODE(nd_body, RNODE_KW_ARG, "body");
1123 LAST_NODE;
1124 F_NODE(nd_next, RNODE_KW_ARG, "next");
1125 return;
1126
1127 case NODE_POSTARG:
1128 ANN("post arguments");
1129 ANN("format: *[nd_1st], [nd_2nd..] = ..");
1130 ANN("example: a, *rest, z = foo");
1131 if (NODE_NAMED_REST_P(RNODE_POSTARG(node)->nd_1st)) {
1132 F_NODE(nd_1st, RNODE_POSTARG, "rest argument");
1133 }
1134 else {
1135 F_MSG(nd_1st, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1136 }
1137 LAST_NODE;
1138 F_NODE(nd_2nd, RNODE_POSTARG, "post arguments");
1139 return;
1140
1141 case NODE_ARGS:
1142 ANN("method parameters");
1143 ANN("format: def method_name(.., [nd_ainfo.nd_optargs], *[nd_ainfo.rest_arg], [nd_ainfo.first_post_arg], .., [nd_ainfo.kw_args], **[nd_ainfo.kw_rest_arg], &[nd_ainfo.block_arg])");
1144 ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, kw: 1, **kwrest, &blk); end");
1145 F_CUSTOM1(nd_ainfo.forwarding, "arguments forwarding or not") {
1146 switch (RNODE_ARGS(node)->nd_ainfo.forwarding) {
1147 case 0: A("0 (no forwarding)"); break;
1148 case 1: A("1 (forwarding)"); break;
1149 }
1150 }
1151 F_INT(nd_ainfo.pre_args_num, RNODE_ARGS, "count of mandatory (pre-)arguments");
1152 F_NODE(nd_ainfo.pre_init, RNODE_ARGS, "initialization of (pre-)arguments");
1153 F_INT(nd_ainfo.post_args_num, RNODE_ARGS, "count of mandatory post-arguments");
1154 F_NODE(nd_ainfo.post_init, RNODE_ARGS, "initialization of post-arguments");
1155 F_ID(nd_ainfo.first_post_arg, RNODE_ARGS, "first post argument");
1156 F_CUSTOM1(nd_ainfo.rest_arg, "rest argument") {
1157 if (RNODE_ARGS(node)->nd_ainfo.rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) {
1158 A("1 (excessed comma)");
1159 }
1160 else {
1161 A_ID(RNODE_ARGS(node)->nd_ainfo.rest_arg);
1162 }
1163 }
1164 F_ID(nd_ainfo.block_arg, RNODE_ARGS, "block argument");
1165 F_NODE(nd_ainfo.opt_args, RNODE_ARGS, "optional arguments");
1166 F_NODE(nd_ainfo.kw_args, RNODE_ARGS, "keyword arguments");
1167 LAST_NODE;
1168 F_NODE(nd_ainfo.kw_rest_arg, RNODE_ARGS, "keyword rest argument");
1169 return;
1170
1171 case NODE_SCOPE:
1172 ANN("new scope");
1173 ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
1174 F_CUSTOM1(nd_tbl, "local table") {
1175 rb_ast_id_table_t *tbl = RNODE_SCOPE(node)->nd_tbl;
1176 int i;
1177 int size = tbl ? tbl->size : 0;
1178 if (size == 0) A("(empty)");
1179 for (i = 0; i < size; i++) {
1180 A_ID(tbl->ids[i]); if (i < size - 1) A(",");
1181 }
1182 }
1183 F_NODE(nd_args, RNODE_SCOPE, "arguments");
1184 LAST_NODE;
1185 F_NODE(nd_body, RNODE_SCOPE, "body");
1186 return;
1187
1188 case NODE_ARYPTN:
1189 ANN("array pattern");
1190 ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
1191 F_NODE(nd_pconst, RNODE_ARYPTN, "constant");
1192 F_NODE(pre_args, RNODE_ARYPTN, "pre arguments");
1193 if (NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg)) {
1194 F_NODE(rest_arg, RNODE_ARYPTN, "rest argument");
1195 }
1196 else {
1197 F_MSG(rest_arg, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1198 }
1199 LAST_NODE;
1200 F_NODE(post_args, RNODE_ARYPTN, "post arguments");
1201 return;
1202
1203 case NODE_FNDPTN:
1204 ANN("find pattern");
1205 ANN("format: [nd_pconst](*[pre_rest_arg], args, ..., *[post_rest_arg])");
1206 F_NODE(nd_pconst, RNODE_FNDPTN, "constant");
1207 if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->pre_rest_arg)) {
1208 F_NODE(pre_rest_arg, RNODE_FNDPTN, "pre rest argument");
1209 }
1210 else {
1211 F_MSG(pre_rest_arg, "pre rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1212 }
1213 F_NODE(args, RNODE_FNDPTN, "arguments");
1214
1215 LAST_NODE;
1216 if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->post_rest_arg)) {
1217 F_NODE(post_rest_arg, RNODE_FNDPTN, "post rest argument");
1218 }
1219 else {
1220 F_MSG(post_rest_arg, "post rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1221 }
1222 return;
1223
1224 case NODE_HSHPTN:
1225 ANN("hash pattern");
1226 ANN("format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])");
1227 F_NODE(nd_pconst, RNODE_HSHPTN, "constant");
1228 F_NODE(nd_pkwargs, RNODE_HSHPTN, "keyword arguments");
1229 LAST_NODE;
1230 if (RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
1231 F_MSG(nd_pkwrestarg, "keyword rest argument", "NODE_SPECIAL_NO_REST_KEYWORD (**nil)");
1232 }
1233 else {
1234 F_NODE(nd_pkwrestarg, RNODE_HSHPTN, "keyword rest argument");
1235 }
1236 return;
1237
1238 case NODE_LINE:
1239 ANN("line");
1240 ANN("format: [lineno]");
1241 ANN("example: __LINE__");
1242 return;
1243
1244 case NODE_FILE:
1245 ANN("line");
1246 ANN("format: [path]");
1247 ANN("example: __FILE__");
1248 F_VALUE(path, rb_node_file_path_val(node), "path");
1249 return;
1250
1251 case NODE_ENCODING:
1252 ANN("encoding");
1253 ANN("format: [enc]");
1254 ANN("example: __ENCODING__");
1255 F_VALUE(enc, rb_node_encoding_val(node), "enc");
1256 return;
1257
1258 case NODE_ERROR:
1259 ANN("Broken input recovered by Error Tolerant mode");
1260 return;
1261
1262 case NODE_ARGS_AUX:
1263 case NODE_LAST:
1264 break;
1265 }
1266
1267 rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
1268}
1269
1270 VALUE
1271rb_parser_dump_tree(const NODE *node, int comment)
1272{
1273 VALUE buf = rb_str_new_cstr(
1274 "###########################################################\n"
1275 "## Do NOT use this node dump for any purpose other than ##\n"
1276 "## debug and research. Compatibility is not guaranteed. ##\n"
1277 "###########################################################\n\n"
1278 );
1279 dump_node(buf, rb_str_new_cstr("# "), comment, node);
1280 return buf;
1281}
T_MODULE
#define T_MODULE
Old name of RUBY_T_MODULE.
Definition value_type.h:70
T_ICLASS
#define T_ICLASS
Old name of RUBY_T_ICLASS.
Definition value_type.h:66
T_CLASS
#define T_CLASS
Old name of RUBY_T_CLASS.
Definition value_type.h:58
rb_inspect
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
Definition object.c:680
rb_str_new_cstr
#define rb_str_new_cstr(str)
Identical to rb_str_new, except it assumes the passed pointer is a pointer to a C string.
Definition string.h:1514
rb_class_path
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
Definition variable.c:373
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition cxxanyargs.hpp:56
ruby.h
RB_SPECIAL_CONST_P
static bool RB_SPECIAL_CONST_P(VALUE obj)
Checks if the given object is of enum ruby_special_consts.
Definition special_consts.h:327
add_option_arg
Definition node_dump.c:152
ID
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition value.h:52
VALUE
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40
RB_BUILTIN_TYPE
static enum ruby_value_type RB_BUILTIN_TYPE(VALUE obj)
Queries the type of the object.
Definition value_type.h:182