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