Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
node.c
Go to the documentation of this file.
1/**********************************************************************
2
3 node.c - 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 "ruby/ruby.h"
13#include "vm_core.h"
14
15#define NODE_BUF_DEFAULT_LEN 16
16
17#define A(str) rb_str_cat2(buf, (str))
18#define AR(str) rb_str_concat(buf, (str))
19
20#define A_INDENT add_indent(buf, indent)
21#define D_INDENT rb_str_cat2(indent, next_indent)
22#define D_DEDENT rb_str_resize(indent, RSTRING_LEN(indent) - 4)
23#define A_ID(id) add_id(buf, (id))
24#define A_INT(val) rb_str_catf(buf, "%d", (val))
25#define A_LONG(val) rb_str_catf(buf, "%ld", (val))
26#define A_LIT(lit) AR(rb_inspect(lit))
27#define A_NODE_HEADER(node, term) \
28 rb_str_catf(buf, "@ %s (line: %d, location: (%d,%d)-(%d,%d))%s"term, \
29 ruby_node_name(nd_type(node)), nd_line(node), \
30 nd_first_lineno(node), nd_first_column(node), \
31 nd_last_lineno(node), nd_last_column(node), \
32 (node->flags & NODE_FL_NEWLINE ? "*" : ""))
33#define A_FIELD_HEADER(len, name, term) \
34 rb_str_catf(buf, "+- %.*s:"term, (len), (name))
35#define D_FIELD_HEADER(len, name, term) (A_INDENT, A_FIELD_HEADER(len, name, term))
36
37#define D_NULL_NODE (A_INDENT, A("(null node)\n"))
38#define D_NODE_HEADER(node) (A_INDENT, A_NODE_HEADER(node, "\n"))
39
40#define COMPOUND_FIELD(len, name) \
41 FIELD_BLOCK((D_FIELD_HEADER((len), (name), "\n"), D_INDENT), D_DEDENT)
42
43#define COMPOUND_FIELD1(name, ann) \
44 COMPOUND_FIELD(FIELD_NAME_LEN(name, ann), \
45 FIELD_NAME_DESC(name, ann))
46
47#define FIELD_NAME_DESC(name, ann) name " (" ann ")"
48#define FIELD_NAME_LEN(name, ann) (int)( \
49 comment ? \
50 rb_strlen_lit(FIELD_NAME_DESC(name, ann)) : \
51 rb_strlen_lit(name))
52#define SIMPLE_FIELD(len, name) \
53 FIELD_BLOCK(D_FIELD_HEADER((len), (name), " "), A("\n"))
54
55#define FIELD_BLOCK(init, reset) \
56 for (init, field_flag = 1; \
57 field_flag; /* should be optimized away */ \
58 reset, field_flag = 0)
59
60#define SIMPLE_FIELD1(name, ann) SIMPLE_FIELD(FIELD_NAME_LEN(name, ann), FIELD_NAME_DESC(name, ann))
61#define F_CUSTOM1(name, ann) SIMPLE_FIELD1(#name, ann)
62#define F_ID(name, ann) SIMPLE_FIELD1(#name, ann) A_ID(node->name)
63#define F_GENTRY(name, ann) SIMPLE_FIELD1(#name, ann) A_ID((node->name)->id)
64#define F_INT(name, ann) SIMPLE_FIELD1(#name, ann) A_INT(node->name)
65#define F_LONG(name, ann) SIMPLE_FIELD1(#name, ann) A_LONG(node->name)
66#define F_LIT(name, ann) SIMPLE_FIELD1(#name, ann) A_LIT(node->name)
67#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
68
69#define F_NODE(name, ann) \
70 COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, node->name);}
71
72#define ANN(ann) \
73 if (comment) { \
74 A_INDENT; A("| # " ann "\n"); \
75 }
76
77#define LAST_NODE (next_indent = " ")
78
79static void
80add_indent(VALUE buf, VALUE indent)
81{
82 AR(indent);
83}
84
85static void
86add_id(VALUE buf, ID id)
87{
88 if (id == 0) {
89 A("(null)");
90 }
91 else {
92 VALUE str = rb_id2str(id);
93 if (str) {
94 A(":"); AR(str);
95 }
96 else {
97 rb_str_catf(buf, "(internal variable: 0x%"PRIsVALUE")", id);
98 }
99 }
100}
101
105};
106
107static void dump_node(VALUE, VALUE, int, const NODE *);
108static const char default_indent[] = "| ";
109
110static void
111dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
112{
113 int field_flag;
114 const char *next_indent = default_indent;
115 F_LONG(nd_alen, "length");
116 F_NODE(nd_head, "element");
117 while (node->nd_next && nd_type(node->nd_next) == NODE_LIST) {
118 node = node->nd_next;
119 F_NODE(nd_head, "element");
120 }
121 LAST_NODE;
122 F_NODE(nd_next, "next element");
123}
124
125static void
126dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
127{
128 int field_flag;
129 int i;
130 const char *next_indent = default_indent;
131 enum node_type type;
132
133 if (!node) {
135 return;
136 }
137
138 D_NODE_HEADER(node);
139
140 type = nd_type(node);
141 switch (type) {
142 case NODE_BLOCK:
143 ANN("statement sequence");
144 ANN("format: [nd_head]; ...; [nd_next]");
145 ANN("example: foo; bar");
146 i = 0;
147 do {
148 A_INDENT;
149 rb_str_catf(buf, "+- nd_head (%s%d):\n",
150 comment ? "statement #" : "", ++i);
151 if (!node->nd_next) LAST_NODE;
152 D_INDENT;
153 dump_node(buf, indent, comment, node->nd_head);
154 D_DEDENT;
155 } while (node->nd_next &&
156 nd_type(node->nd_next) == NODE_BLOCK &&
157 (node = node->nd_next, 1));
158 if (node->nd_next) {
159 LAST_NODE;
160 F_NODE(nd_next, "next block");
161 }
162 return;
163
164 case NODE_IF:
165 ANN("if statement");
166 ANN("format: if [nd_cond] then [nd_body] else [nd_else] end");
167 ANN("example: if x == 1 then foo else bar end");
168 F_NODE(nd_cond, "condition expr");
169 F_NODE(nd_body, "then clause");
170 LAST_NODE;
171 F_NODE(nd_else, "else clause");
172 return;
173
174 case NODE_UNLESS:
175 ANN("unless statement");
176 ANN("format: unless [nd_cond] then [nd_body] else [nd_else] end");
177 ANN("example: unless x == 1 then foo else bar end");
178 F_NODE(nd_cond, "condition expr");
179 F_NODE(nd_body, "then clause");
180 LAST_NODE;
181 F_NODE(nd_else, "else clause");
182 return;
183
184 case NODE_CASE:
185 ANN("case statement");
186 ANN("format: case [nd_head]; [nd_body]; end");
187 ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
188 F_NODE(nd_head, "case expr");
189 LAST_NODE;
190 F_NODE(nd_body, "when clauses");
191 return;
192 case NODE_CASE2:
193 ANN("case statement with no head");
194 ANN("format: case; [nd_body]; end");
195 ANN("example: case; when 1; foo; when 2; bar; else baz; end");
196 F_NODE(nd_head, "case expr");
197 LAST_NODE;
198 F_NODE(nd_body, "when clauses");
199 return;
200 case NODE_CASE3:
201 ANN("case statement (pattern matching)");
202 ANN("format: case [nd_head]; [nd_body]; end");
203 ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
204 F_NODE(nd_head, "case expr");
205 LAST_NODE;
206 F_NODE(nd_body, "in clauses");
207 return;
208
209 case NODE_WHEN:
210 ANN("when clause");
211 ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
212 ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
213 F_NODE(nd_head, "when value");
214 F_NODE(nd_body, "when body");
215 LAST_NODE;
216 F_NODE(nd_next, "next when clause");
217 return;
218
219 case NODE_IN:
220 ANN("in clause");
221 ANN("format: in [nd_head]; [nd_body]; (in or else) [nd_next]");
222 ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
223 F_NODE(nd_head, "in pattern");
224 F_NODE(nd_body, "in body");
225 LAST_NODE;
226 F_NODE(nd_next, "next in clause");
227 return;
228
229 case NODE_WHILE:
230 ANN("while statement");
231 ANN("format: while [nd_cond]; [nd_body]; end");
232 ANN("example: while x == 1; foo; end");
233 goto loop;
234 case NODE_UNTIL:
235 ANN("until statement");
236 ANN("format: until [nd_cond]; [nd_body]; end");
237 ANN("example: until x == 1; foo; end");
238 loop:
239 F_CUSTOM1(nd_state, "begin-end-while?") {
240 A_INT((int)node->nd_state);
241 A((node->nd_state == 1) ? " (while-end)" : " (begin-end-while)");
242 }
243 F_NODE(nd_cond, "condition");
244 LAST_NODE;
245 F_NODE(nd_body, "body");
246 return;
247
248 case NODE_ITER:
249 ANN("method call with block");
250 ANN("format: [nd_iter] { [nd_body] }");
251 ANN("example: 3.times { foo }");
252 goto iter;
253 case NODE_FOR:
254 ANN("for statement");
255 ANN("format: for * in [nd_iter] do [nd_body] end");
256 ANN("example: for i in 1..3 do foo end");
257 iter:
258 F_NODE(nd_iter, "iteration receiver");
259 LAST_NODE;
260 F_NODE(nd_body, "body");
261 return;
262
263 case NODE_FOR_MASGN:
264 ANN("vars of for statement with masgn");
265 ANN("format: for [nd_var] in ... do ... end");
266 ANN("example: for x, y in 1..3 do foo end");
267 LAST_NODE;
268 F_NODE(nd_var, "var");
269 return;
270
271 case NODE_BREAK:
272 ANN("break statement");
273 ANN("format: break [nd_stts]");
274 ANN("example: break 1");
275 goto jump;
276 case NODE_NEXT:
277 ANN("next statement");
278 ANN("format: next [nd_stts]");
279 ANN("example: next 1");
280 goto jump;
281 case NODE_RETURN:
282 ANN("return statement");
283 ANN("format: return [nd_stts]");
284 ANN("example: return 1");
285 jump:
286 LAST_NODE;
287 F_NODE(nd_stts, "value");
288 return;
289
290 case NODE_REDO:
291 ANN("redo statement");
292 ANN("format: redo");
293 ANN("example: redo");
294 return;
295
296 case NODE_RETRY:
297 ANN("retry statement");
298 ANN("format: retry");
299 ANN("example: retry");
300 return;
301
302 case NODE_BEGIN:
303 ANN("begin statement");
304 ANN("format: begin; [nd_body]; end");
305 ANN("example: begin; 1; end");
306 LAST_NODE;
307 F_NODE(nd_body, "body");
308 return;
309
310 case NODE_RESCUE:
311 ANN("rescue clause");
312 ANN("format: begin; [nd_body]; (rescue) [nd_resq]; else [nd_else]; end");
313 ANN("example: begin; foo; rescue; bar; else; baz; end");
314 F_NODE(nd_head, "body");
315 F_NODE(nd_resq, "rescue clause list");
316 LAST_NODE;
317 F_NODE(nd_else, "rescue else clause");
318 return;
319
320 case NODE_RESBODY:
321 ANN("rescue clause (cont'd)");
322 ANN("format: rescue [nd_args]; [nd_body]; (rescue) [nd_head]");
323 ANN("example: begin; foo; rescue; bar; else; baz; end");
324 F_NODE(nd_args, "rescue exceptions");
325 F_NODE(nd_body, "rescue clause");
326 LAST_NODE;
327 F_NODE(nd_head, "next rescue clause");
328 return;
329
330 case NODE_ENSURE:
331 ANN("ensure clause");
332 ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
333 ANN("example: begin; foo; ensure; bar; end");
334 F_NODE(nd_head, "body");
335 LAST_NODE;
336 F_NODE(nd_ensr, "ensure clause");
337 return;
338
339 case NODE_AND:
340 ANN("&& operator");
341 ANN("format: [nd_1st] && [nd_2nd]");
342 ANN("example: foo && bar");
343 goto andor;
344 case NODE_OR:
345 ANN("|| operator");
346 ANN("format: [nd_1st] || [nd_2nd]");
347 ANN("example: foo || bar");
348 andor:
349 while (1) {
350 F_NODE(nd_1st, "left expr");
351 if (!node->nd_2nd || nd_type(node->nd_2nd) != (int)type)
352 break;
353 node = node->nd_2nd;
354 }
355 LAST_NODE;
356 F_NODE(nd_2nd, "right expr");
357 return;
358
359 case NODE_MASGN:
360 ANN("multiple assignment");
361 ANN("format: [nd_head], [nd_args] = [nd_value]");
362 ANN("example: a, b = foo");
363 F_NODE(nd_value, "rhsn");
364 F_NODE(nd_head, "lhsn");
365 if (NODE_NAMED_REST_P(node->nd_args)) {
366 LAST_NODE;
367 F_NODE(nd_args, "splatn");
368 }
369 else {
370 F_MSG(nd_args, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
371 }
372 return;
373
374 case NODE_LASGN:
375 ANN("local variable assignment");
376 ANN("format: [nd_vid](lvar) = [nd_value]");
377 ANN("example: x = foo");
378 F_ID(nd_vid, "local variable");
379 if (NODE_REQUIRED_KEYWORD_P(node)) {
380 F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
381 }
382 else {
383 LAST_NODE;
384 F_NODE(nd_value, "rvalue");
385 }
386 return;
387 case NODE_DASGN:
388 ANN("dynamic variable assignment (out of current scope)");
389 ANN("format: [nd_vid](dvar) = [nd_value]");
390 ANN("example: x = nil; 1.times { x = foo }");
391 F_ID(nd_vid, "local variable");
392 LAST_NODE;
393 F_NODE(nd_value, "rvalue");
394 return;
395 case NODE_DASGN_CURR:
396 ANN("dynamic variable assignment (in current scope)");
397 ANN("format: [nd_vid](current dvar) = [nd_value]");
398 ANN("example: 1.times { x = foo }");
399 F_ID(nd_vid, "local variable");
400 if (NODE_REQUIRED_KEYWORD_P(node)) {
401 F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
402 }
403 else {
404 LAST_NODE;
405 F_NODE(nd_value, "rvalue");
406 }
407 return;
408 case NODE_IASGN:
409 ANN("instance variable assignment");
410 ANN("format: [nd_vid](ivar) = [nd_value]");
411 ANN("example: @x = foo");
412 F_ID(nd_vid, "instance variable");
413 LAST_NODE;
414 F_NODE(nd_value, "rvalue");
415 return;
416 case NODE_CVASGN:
417 ANN("class variable assignment");
418 ANN("format: [nd_vid](cvar) = [nd_value]");
419 ANN("example: @@x = foo");
420 F_ID(nd_vid, "class variable");
421 LAST_NODE;
422 F_NODE(nd_value, "rvalue");
423 return;
424 case NODE_GASGN:
425 ANN("global variable assignment");
426 ANN("format: [nd_entry](gvar) = [nd_value]");
427 ANN("example: $x = foo");
428 F_GENTRY(nd_entry, "global variable");
429 LAST_NODE;
430 F_NODE(nd_value, "rvalue");
431 return;
432
433 case NODE_CDECL:
434 ANN("constant declaration");
435 ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
436 ANN("example: X = foo");
437 if (node->nd_vid) {
438 F_ID(nd_vid, "constant");
439 F_MSG(nd_else, "extension", "not used");
440 }
441 else {
442 F_MSG(nd_vid, "constant", "0 (see extension field)");
443 F_NODE(nd_else, "extension");
444 }
445 LAST_NODE;
446 F_NODE(nd_value, "rvalue");
447 return;
448
449 case NODE_OP_ASGN1:
450 ANN("array assignment with operator");
451 ANN("format: [nd_recv] [ [nd_args->nd_head] ] [nd_mid]= [nd_args->nd_body]");
452 ANN("example: ary[1] += foo");
453 F_NODE(nd_recv, "receiver");
454 F_ID(nd_mid, "operator");
455 F_NODE(nd_args->nd_head, "index");
456 LAST_NODE;
457 F_NODE(nd_args->nd_body, "rvalue");
458 return;
459
460 case NODE_OP_ASGN2:
461 ANN("attr assignment with operator");
462 ANN("format: [nd_recv].[attr] [nd_next->nd_mid]= [nd_value]");
463 ANN(" where [attr]: [nd_next->nd_vid]");
464 ANN("example: struct.field += foo");
465 F_NODE(nd_recv, "receiver");
466 F_CUSTOM1(nd_next->nd_vid, "attr") {
467 if (node->nd_next->nd_aid) A("? ");
468 A_ID(node->nd_next->nd_vid);
469 }
470 F_ID(nd_next->nd_mid, "operator");
471 LAST_NODE;
472 F_NODE(nd_value, "rvalue");
473 return;
474
475 case NODE_OP_ASGN_AND:
476 ANN("assignment with && operator");
477 ANN("format: [nd_head] &&= [nd_value]");
478 ANN("example: foo &&= bar");
479 goto asgn_andor;
480 case NODE_OP_ASGN_OR:
481 ANN("assignment with || operator");
482 ANN("format: [nd_head] ||= [nd_value]");
483 ANN("example: foo ||= bar");
484 asgn_andor:
485 F_NODE(nd_head, "variable");
486 LAST_NODE;
487 F_NODE(nd_value, "rvalue");
488 return;
489
490 case NODE_OP_CDECL:
491 ANN("constant declaration with operator");
492 ANN("format: [nd_head](constant) [nd_aid]= [nd_value]");
493 ANN("example: A::B ||= 1");
494 F_NODE(nd_head, "constant");
495 F_ID(nd_aid, "operator");
496 LAST_NODE;
497 F_NODE(nd_value, "rvalue");
498 return;
499
500 case NODE_CALL:
501 ANN("method invocation");
502 ANN("format: [nd_recv].[nd_mid]([nd_args])");
503 ANN("example: obj.foo(1)");
504 F_ID(nd_mid, "method id");
505 F_NODE(nd_recv, "receiver");
506 LAST_NODE;
507 F_NODE(nd_args, "arguments");
508 return;
509
510 case NODE_OPCALL:
511 ANN("method invocation");
512 ANN("format: [nd_recv] [nd_mid] [nd_args]");
513 ANN("example: foo + bar");
514 F_ID(nd_mid, "method id");
515 F_NODE(nd_recv, "receiver");
516 LAST_NODE;
517 F_NODE(nd_args, "arguments");
518 return;
519
520 case NODE_FCALL:
521 ANN("function call");
522 ANN("format: [nd_mid]([nd_args])");
523 ANN("example: foo(1)");
524 F_ID(nd_mid, "method id");
525 LAST_NODE;
526 F_NODE(nd_args, "arguments");
527 return;
528
529 case NODE_VCALL:
530 ANN("function call with no argument");
531 ANN("format: [nd_mid]");
532 ANN("example: foo");
533 F_ID(nd_mid, "method id");
534 return;
535
536 case NODE_QCALL:
537 ANN("safe method invocation");
538 ANN("format: [nd_recv]&.[nd_mid]([nd_args])");
539 ANN("example: obj&.foo(1)");
540 F_ID(nd_mid, "method id");
541 F_NODE(nd_recv, "receiver");
542 LAST_NODE;
543 F_NODE(nd_args, "arguments");
544 return;
545
546 case NODE_SUPER:
547 ANN("super invocation");
548 ANN("format: super [nd_args]");
549 ANN("example: super 1");
550 LAST_NODE;
551 F_NODE(nd_args, "arguments");
552 return;
553
554 case NODE_ZSUPER:
555 ANN("super invocation with no argument");
556 ANN("format: super");
557 ANN("example: super");
558 return;
559
560 case NODE_LIST:
561 ANN("list constructor");
562 ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
563 ANN("example: [1, 2, 3]");
564 goto ary;
565 case NODE_VALUES:
566 ANN("return arguments");
567 ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
568 ANN("example: return 1, 2, 3");
569 ary:
570 dump_array(buf, indent, comment, node);
571 return;
572
573 case NODE_ZLIST:
574 ANN("empty list constructor");
575 ANN("format: []");
576 ANN("example: []");
577 return;
578
579 case NODE_HASH:
580 if (!node->nd_brace) {
581 ANN("keyword arguments");
582 ANN("format: nd_head");
583 ANN("example: a: 1, b: 2");
584 }
585 else {
586 ANN("hash constructor");
587 ANN("format: { [nd_head] }");
588 ANN("example: { 1 => 2, 3 => 4 }");
589 }
590 F_CUSTOM1(nd_brace, "keyword arguments or hash literal") {
591 switch (node->nd_brace) {
592 case 0: A("0 (keyword argument)"); break;
593 case 1: A("1 (hash literal)"); break;
594 }
595 }
596 LAST_NODE;
597 F_NODE(nd_head, "contents");
598 return;
599
600 case NODE_YIELD:
601 ANN("yield invocation");
602 ANN("format: yield [nd_head]");
603 ANN("example: yield 1");
604 LAST_NODE;
605 F_NODE(nd_head, "arguments");
606 return;
607
608 case NODE_LVAR:
609 ANN("local variable reference");
610 ANN("format: [nd_vid](lvar)");
611 ANN("example: x");
612 F_ID(nd_vid, "local variable");
613 return;
614 case NODE_DVAR:
615 ANN("dynamic variable reference");
616 ANN("format: [nd_vid](dvar)");
617 ANN("example: 1.times { x = 1; x }");
618 F_ID(nd_vid, "local variable");
619 return;
620 case NODE_IVAR:
621 ANN("instance variable reference");
622 ANN("format: [nd_vid](ivar)");
623 ANN("example: @x");
624 F_ID(nd_vid, "instance variable");
625 return;
626 case NODE_CONST:
627 ANN("constant reference");
628 ANN("format: [nd_vid](constant)");
629 ANN("example: X");
630 F_ID(nd_vid, "constant");
631 return;
632 case NODE_CVAR:
633 ANN("class variable reference");
634 ANN("format: [nd_vid](cvar)");
635 ANN("example: @@x");
636 F_ID(nd_vid, "class variable");
637 return;
638
639 case NODE_GVAR:
640 ANN("global variable reference");
641 ANN("format: [nd_entry](gvar)");
642 ANN("example: $x");
643 F_GENTRY(nd_entry, "global variable");
644 return;
645
646 case NODE_NTH_REF:
647 ANN("nth special variable reference");
648 ANN("format: $[nd_nth]");
649 ANN("example: $1, $2, ..");
650 F_CUSTOM1(nd_nth, "variable") { A("$"); A_LONG(node->nd_nth); }
651 return;
652
653 case NODE_BACK_REF:
654 ANN("back special variable reference");
655 ANN("format: $[nd_nth]");
656 ANN("example: $&, $`, $', $+");
657 F_CUSTOM1(nd_nth, "variable") {
658 char name[3];
659 name[0] = '$';
660 name[1] = (char)node->nd_nth;
661 name[2] = '\0';
662 A(name);
663 }
664 return;
665
666 case NODE_MATCH:
667 ANN("match expression (against $_ implicitly)");
668 ANN("format: [nd_lit] (in condition)");
669 ANN("example: if /foo/; foo; end");
670 F_LIT(nd_lit, "regexp");
671 return;
672
673 case NODE_MATCH2:
674 ANN("match expression (regexp first)");
675 ANN("format: [nd_recv] =~ [nd_value]");
676 ANN("example: /foo/ =~ 'foo'");
677 F_NODE(nd_recv, "regexp (receiver)");
678 if (!node->nd_args) LAST_NODE;
679 F_NODE(nd_value, "string (argument)");
680 if (node->nd_args) {
681 LAST_NODE;
682 F_NODE(nd_args, "named captures");
683 }
684 return;
685
686 case NODE_MATCH3:
687 ANN("match expression (regexp second)");
688 ANN("format: [nd_recv] =~ [nd_value]");
689 ANN("example: 'foo' =~ /foo/");
690 F_NODE(nd_recv, "string (receiver)");
691 LAST_NODE;
692 F_NODE(nd_value, "regexp (argument)");
693 return;
694
695 case NODE_LIT:
696 ANN("literal");
697 ANN("format: [nd_lit]");
698 ANN("example: 1, /foo/");
699 goto lit;
700 case NODE_STR:
701 ANN("string literal");
702 ANN("format: [nd_lit]");
703 ANN("example: 'foo'");
704 goto lit;
705 case NODE_XSTR:
706 ANN("xstring literal");
707 ANN("format: [nd_lit]");
708 ANN("example: `foo`");
709 lit:
710 F_LIT(nd_lit, "literal");
711 return;
712
713 case NODE_ONCE:
714 ANN("once evaluation");
715 ANN("format: [nd_body]");
716 ANN("example: /foo#{ bar }baz/o");
717 LAST_NODE;
718 F_NODE(nd_body, "body");
719 return;
720 case NODE_DSTR:
721 ANN("string literal with interpolation");
722 ANN("format: [nd_lit]");
723 ANN("example: \"foo#{ bar }baz\"");
724 goto dlit;
725 case NODE_DXSTR:
726 ANN("xstring literal with interpolation");
727 ANN("format: [nd_lit]");
728 ANN("example: `foo#{ bar }baz`");
729 goto dlit;
730 case NODE_DREGX:
731 ANN("regexp literal with interpolation");
732 ANN("format: [nd_lit]");
733 ANN("example: /foo#{ bar }baz/");
734 goto dlit;
735 case NODE_DSYM:
736 ANN("symbol literal with interpolation");
737 ANN("format: [nd_lit]");
738 ANN("example: :\"foo#{ bar }baz\"");
739 dlit:
740 F_LIT(nd_lit, "preceding string");
741 F_NODE(nd_next->nd_head, "interpolation");
742 LAST_NODE;
743 F_NODE(nd_next->nd_next, "tailing strings");
744 return;
745
746 case NODE_EVSTR:
747 ANN("interpolation expression");
748 ANN("format: \"..#{ [nd_lit] }..\"");
749 ANN("example: \"foo#{ bar }baz\"");
750 LAST_NODE;
751 F_NODE(nd_body, "body");
752 return;
753
754 case NODE_ARGSCAT:
755 ANN("splat argument following arguments");
756 ANN("format: ..(*[nd_head], [nd_body..])");
757 ANN("example: foo(*ary, post_arg1, post_arg2)");
758 F_NODE(nd_head, "preceding array");
759 LAST_NODE;
760 F_NODE(nd_body, "following array");
761 return;
762
763 case NODE_ARGSPUSH:
764 ANN("splat argument following one argument");
765 ANN("format: ..(*[nd_head], [nd_body])");
766 ANN("example: foo(*ary, post_arg)");
767 F_NODE(nd_head, "preceding array");
768 LAST_NODE;
769 F_NODE(nd_body, "following element");
770 return;
771
772 case NODE_SPLAT:
773 ANN("splat argument");
774 ANN("format: *[nd_head]");
775 ANN("example: foo(*ary)");
776 LAST_NODE;
777 F_NODE(nd_head, "splat'ed array");
778 return;
779
780 case NODE_BLOCK_PASS:
781 ANN("arguments with block argument");
782 ANN("format: ..([nd_head], &[nd_body])");
783 ANN("example: foo(x, &blk)");
784 F_NODE(nd_head, "other arguments");
785 LAST_NODE;
786 F_NODE(nd_body, "block argument");
787 return;
788
789 case NODE_DEFN:
790 ANN("method definition");
791 ANN("format: def [nd_mid] [nd_defn]; end");
792 ANN("example: def foo; bar; end");
793 F_ID(nd_mid, "method name");
794 LAST_NODE;
795 F_NODE(nd_defn, "method definition");
796 return;
797
798 case NODE_DEFS:
799 ANN("singleton method definition");
800 ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
801 ANN("example: def obj.foo; bar; end");
802 F_NODE(nd_recv, "receiver");
803 F_ID(nd_mid, "method name");
804 LAST_NODE;
805 F_NODE(nd_defn, "method definition");
806 return;
807
808 case NODE_ALIAS:
809 ANN("method alias statement");
810 ANN("format: alias [nd_1st] [nd_2nd]");
811 ANN("example: alias bar foo");
812 F_NODE(nd_1st, "new name");
813 LAST_NODE;
814 F_NODE(nd_2nd, "old name");
815 return;
816
817 case NODE_VALIAS:
818 ANN("global variable alias statement");
819 ANN("format: alias [nd_alias](gvar) [nd_orig](gvar)");
820 ANN("example: alias $y $x");
821 F_ID(nd_alias, "new name");
822 F_ID(nd_orig, "old name");
823 return;
824
825 case NODE_UNDEF:
826 ANN("method undef statement");
827 ANN("format: undef [nd_undef]");
828 ANN("example: undef foo");
829 LAST_NODE;
830 F_NODE(nd_undef, "old name");
831 return;
832
833 case NODE_CLASS:
834 ANN("class definition");
835 ANN("format: class [nd_cpath] < [nd_super]; [nd_body]; end");
836 ANN("example: class C2 < C; ..; end");
837 F_NODE(nd_cpath, "class path");
838 F_NODE(nd_super, "superclass");
839 LAST_NODE;
840 F_NODE(nd_body, "class definition");
841 return;
842
843 case NODE_MODULE:
844 ANN("module definition");
845 ANN("format: module [nd_cpath]; [nd_body]; end");
846 ANN("example: module M; ..; end");
847 F_NODE(nd_cpath, "module path");
848 LAST_NODE;
849 F_NODE(nd_body, "module definition");
850 return;
851
852 case NODE_SCLASS:
853 ANN("singleton class definition");
854 ANN("format: class << [nd_recv]; [nd_body]; end");
855 ANN("example: class << obj; ..; end");
856 F_NODE(nd_recv, "receiver");
857 LAST_NODE;
858 F_NODE(nd_body, "singleton class definition");
859 return;
860
861 case NODE_COLON2:
862 ANN("scoped constant reference");
863 ANN("format: [nd_head]::[nd_mid]");
864 ANN("example: M::C");
865 F_ID(nd_mid, "constant name");
866 LAST_NODE;
867 F_NODE(nd_head, "receiver");
868 return;
869
870 case NODE_COLON3:
871 ANN("top-level constant reference");
872 ANN("format: ::[nd_mid]");
873 ANN("example: ::Object");
874 F_ID(nd_mid, "constant name");
875 return;
876
877 case NODE_DOT2:
878 ANN("range constructor (incl.)");
879 ANN("format: [nd_beg]..[nd_end]");
880 ANN("example: 1..5");
881 goto dot;
882 case NODE_DOT3:
883 ANN("range constructor (excl.)");
884 ANN("format: [nd_beg]...[nd_end]");
885 ANN("example: 1...5");
886 goto dot;
887 case NODE_FLIP2:
888 ANN("flip-flop condition (incl.)");
889 ANN("format: [nd_beg]..[nd_end]");
890 ANN("example: if (x==1)..(x==5); foo; end");
891 goto dot;
892 case NODE_FLIP3:
893 ANN("flip-flop condition (excl.)");
894 ANN("format: [nd_beg]...[nd_end]");
895 ANN("example: if (x==1)...(x==5); foo; end");
896 dot:
897 F_NODE(nd_beg, "begin");
898 LAST_NODE;
899 F_NODE(nd_end, "end");
900 return;
901
902 case NODE_SELF:
903 ANN("self");
904 ANN("format: self");
905 ANN("example: self");
906 return;
907
908 case NODE_NIL:
909 ANN("nil");
910 ANN("format: nil");
911 ANN("example: nil");
912 return;
913
914 case NODE_TRUE:
915 ANN("true");
916 ANN("format: true");
917 ANN("example: true");
918 return;
919
920 case NODE_FALSE:
921 ANN("false");
922 ANN("format: false");
923 ANN("example: false");
924 return;
925
926 case NODE_ERRINFO:
927 ANN("virtual reference to $!");
928 ANN("format: rescue => id");
929 ANN("example: rescue => id");
930 return;
931
932 case NODE_DEFINED:
933 ANN("defined? expression");
934 ANN("format: defined?([nd_head])");
935 ANN("example: defined?(foo)");
936 F_NODE(nd_head, "expr");
937 return;
938
939 case NODE_POSTEXE:
940 ANN("post-execution");
941 ANN("format: END { [nd_body] }");
942 ANN("example: END { foo }");
943 LAST_NODE;
944 F_NODE(nd_body, "END clause");
945 return;
946
947 case NODE_ATTRASGN:
948 ANN("attr assignment");
949 ANN("format: [nd_recv].[nd_mid] = [nd_args]");
950 ANN("example: struct.field = foo");
951 F_NODE(nd_recv, "receiver");
952 F_ID(nd_mid, "method name");
953 LAST_NODE;
954 F_NODE(nd_args, "arguments");
955 return;
956
957 case NODE_LAMBDA:
958 ANN("lambda expression");
959 ANN("format: -> [nd_body]");
960 ANN("example: -> { foo }");
961 LAST_NODE;
962 F_NODE(nd_body, "lambda clause");
963 return;
964
965 case NODE_OPT_ARG:
966 ANN("optional arguments");
967 ANN("format: def method_name([nd_body=some], [nd_next..])");
968 ANN("example: def foo(a, b=1, c); end");
969 F_NODE(nd_body, "body");
970 LAST_NODE;
971 F_NODE(nd_next, "next");
972 return;
973
974 case NODE_KW_ARG:
975 ANN("keyword arguments");
976 ANN("format: def method_name([nd_body=some], [nd_next..])");
977 ANN("example: def foo(a:1, b:2); end");
978 F_NODE(nd_body, "body");
979 LAST_NODE;
980 F_NODE(nd_next, "next");
981 return;
982
983 case NODE_POSTARG:
984 ANN("post arguments");
985 ANN("format: *[nd_1st], [nd_2nd..] = ..");
986 ANN("example: a, *rest, z = foo");
987 if (NODE_NAMED_REST_P(node->nd_1st)) {
988 F_NODE(nd_1st, "rest argument");
989 }
990 else {
991 F_MSG(nd_1st, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
992 }
993 LAST_NODE;
994 F_NODE(nd_2nd, "post arguments");
995 return;
996
997 case NODE_ARGS:
998 ANN("method parameters");
999 ANN("format: def method_name(.., [nd_opt=some], *[nd_rest], [nd_pid], .., &[nd_body])");
1000 ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, &blk); end");
1001 F_INT(nd_ainfo->pre_args_num, "count of mandatory (pre-)arguments");
1002 F_NODE(nd_ainfo->pre_init, "initialization of (pre-)arguments");
1003 F_INT(nd_ainfo->post_args_num, "count of mandatory post-arguments");
1004 F_NODE(nd_ainfo->post_init, "initialization of post-arguments");
1005 F_ID(nd_ainfo->first_post_arg, "first post argument");
1006 F_CUSTOM1(nd_ainfo->rest_arg, "rest argument") {
1007 if (node->nd_ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) {
1008 A("1 (excessed comma)");
1009 }
1010 else {
1011 A_ID(node->nd_ainfo->rest_arg);
1012 }
1013 }
1014 F_ID(nd_ainfo->block_arg, "block argument");
1015 F_NODE(nd_ainfo->opt_args, "optional arguments");
1016 F_NODE(nd_ainfo->kw_args, "keyword arguments");
1017 LAST_NODE;
1018 F_NODE(nd_ainfo->kw_rest_arg, "keyword rest argument");
1019 return;
1020
1021 case NODE_SCOPE:
1022 ANN("new scope");
1023 ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
1024 F_CUSTOM1(nd_tbl, "local table") {
1025 ID *tbl = node->nd_tbl;
1026 int i;
1027 int size = tbl ? (int)*tbl++ : 0;
1028 if (size == 0) A("(empty)");
1029 for (i = 0; i < size; i++) {
1030 A_ID(tbl[i]); if (i < size - 1) A(",");
1031 }
1032 }
1033 F_NODE(nd_args, "arguments");
1034 LAST_NODE;
1035 F_NODE(nd_body, "body");
1036 return;
1037
1038 case NODE_ARYPTN:
1039 ANN("array pattern");
1040 ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
1041 F_NODE(nd_pconst, "constant");
1042 F_NODE(nd_apinfo->pre_args, "pre arguments");
1043 if (NODE_NAMED_REST_P(node->nd_apinfo->rest_arg)) {
1044 F_NODE(nd_apinfo->rest_arg, "rest argument");
1045 }
1046 else {
1047 F_MSG(nd_apinfo->rest_arg, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1048 }
1049 LAST_NODE;
1050 F_NODE(nd_apinfo->post_args, "post arguments");
1051 return;
1052
1053 case NODE_HSHPTN:
1054 ANN("hash pattern");
1055 ANN("format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])");
1056 F_NODE(nd_pconst, "constant");
1057 F_NODE(nd_pkwargs, "keyword arguments");
1058 LAST_NODE;
1059 if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
1060 F_MSG(nd_pkwrestarg, "keyword rest argument", "NODE_SPECIAL_NO_REST_KEYWORD (**nil)");
1061 }
1062 else {
1063 F_NODE(nd_pkwrestarg, "keyword rest argument");
1064 }
1065 return;
1066
1067 case NODE_ARGS_AUX:
1068 case NODE_LAST:
1069 break;
1070 }
1071
1072 rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
1073}
1074
1075VALUE
1076rb_parser_dump_tree(const NODE *node, int comment)
1077{
1079 "###########################################################\n"
1080 "## Do NOT use this node dump for any purpose other than ##\n"
1081 "## debug and research. Compatibility is not guaranteed. ##\n"
1082 "###########################################################\n\n"
1083 );
1084 dump_node(buf, rb_str_new_cstr("# "), comment, node);
1085 return buf;
1086}
1087
1088/* Setup NODE structure.
1089 * NODE is not an object managed by GC, but it imitates an object
1090 * so that it can work with `RB_TYPE_P(obj, T_NODE)`.
1091 * This dirty hack is needed because Ripper jumbles NODEs and other type
1092 * objects.
1093 */
1094void
1096{
1097 n->flags = T_NODE;
1098 nd_set_type(n, type);
1099 n->u1.value = a0;
1100 n->u2.value = a1;
1101 n->u3.value = a2;
1102 n->nd_loc.beg_pos.lineno = 0;
1103 n->nd_loc.beg_pos.column = 0;
1104 n->nd_loc.end_pos.lineno = 0;
1105 n->nd_loc.end_pos.column = 0;
1106}
1107
1110 long len;
1113
1114typedef struct {
1115 long idx, len;
1119
1125};
1126
1127static void
1128init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head)
1129{
1130 nb->idx = 0;
1132 nb->head = nb->last = head;
1133 nb->head->len = nb->len;
1134 nb->head->next = NULL;
1135}
1136
1137static node_buffer_t *
1138rb_node_buffer_new(void)
1139{
1140 const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
1141 const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
1143 integer_overflow,
1145 > sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
1146 node_buffer_t *nb = ruby_xmalloc(alloc_size);
1147 init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1]);
1148 init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size));
1149 nb->local_tables = 0;
1150 nb->mark_hash = Qnil;
1151 return nb;
1152}
1153
1154static void
1155node_buffer_list_free(node_buffer_list_t * nb)
1156{
1157 node_buffer_elem_t *nbe = nb->head;
1158
1159 while (nbe != nb->last) {
1160 void *buf = nbe;
1161 nbe = nbe->next;
1162 xfree(buf);
1163 }
1164}
1165
1166static void
1167rb_node_buffer_free(node_buffer_t *nb)
1168{
1169 node_buffer_list_free(&nb->unmarkable);
1170 node_buffer_list_free(&nb->markable);
1171 ID * local_table = nb->local_tables;
1172 while (local_table) {
1173 unsigned int size = (unsigned int)*local_table;
1174 ID * next_table = (ID *)local_table[size + 1];
1175 xfree(local_table);
1176 local_table = next_table;
1177 }
1178 xfree(nb);
1179}
1180
1181static NODE *
1182ast_newnode_in_bucket(node_buffer_list_t *nb)
1183{
1184 if (nb->idx >= nb->len) {
1185 long n = nb->len * 2;
1186 node_buffer_elem_t *nbe;
1188 nbe->len = n;
1189 nb->idx = 0;
1190 nb->len = n;
1191 nbe->next = nb->head;
1192 nb->head = nbe;
1193 }
1194 return &nb->head->buf[nb->idx++];
1195}
1196
1197NODE *
1199{
1200 node_buffer_t *nb = ast->node_buffer;
1201 switch (type) {
1202 case NODE_MATCH:
1203 case NODE_LIT:
1204 case NODE_STR:
1205 case NODE_XSTR:
1206 case NODE_DSTR:
1207 case NODE_DXSTR:
1208 case NODE_DREGX:
1209 case NODE_DSYM:
1210 case NODE_ARGS:
1211 case NODE_ARYPTN:
1212 return ast_newnode_in_bucket(&nb->markable);
1213 default:
1214 return ast_newnode_in_bucket(&nb->unmarkable);
1215 }
1216}
1217
1218void
1220{
1221 unsigned int size = (unsigned int)*buf;
1222 buf[size + 1] = (ID)ast->node_buffer->local_tables;
1224}
1225
1226void
1228{
1229 (void)ast;
1230 (void)n;
1231 /* should we implement freelist? */
1232}
1233
1234rb_ast_t *
1236{
1237 node_buffer_t *nb = rb_node_buffer_new();
1238 rb_ast_t *ast = (rb_ast_t *)rb_imemo_new(imemo_ast, 0, 0, 0, (VALUE)nb);
1239 return ast;
1240}
1241
1242typedef void node_itr_t(void *ctx, NODE * node);
1243
1244static void
1245iterate_buffer_elements(node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
1246{
1247 long cursor;
1248 for (cursor = 0; cursor < len; cursor++) {
1249 func(ctx, &nbe->buf[cursor]);
1250 }
1251}
1252
1253static void
1254iterate_node_values(node_buffer_list_t *nb, node_itr_t * func, void *ctx)
1255{
1256 node_buffer_elem_t *nbe = nb->head;
1257
1258 /* iterate over the head first because it's not full */
1259 iterate_buffer_elements(nbe, nb->idx, func, ctx);
1260
1261 nbe = nbe->next;
1262 while (nbe) {
1263 iterate_buffer_elements(nbe, nbe->len, func, ctx);
1264 nbe = nbe->next;
1265 }
1266}
1267
1268static void
1269mark_ast_value(void *ctx, NODE * node)
1270{
1271 switch (nd_type(node)) {
1272 case NODE_ARYPTN:
1273 {
1274 struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
1275 rb_gc_mark_movable(apinfo->imemo);
1276 break;
1277 }
1278 case NODE_ARGS:
1279 {
1280 struct rb_args_info *args = node->nd_ainfo;
1282 break;
1283 }
1284 case NODE_MATCH:
1285 case NODE_LIT:
1286 case NODE_STR:
1287 case NODE_XSTR:
1288 case NODE_DSTR:
1289 case NODE_DXSTR:
1290 case NODE_DREGX:
1291 case NODE_DSYM:
1292 rb_gc_mark_movable(node->nd_lit);
1293 break;
1294 default:
1295 rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
1296 }
1297}
1298
1299static void
1300update_ast_value(void *ctx, NODE * node)
1301{
1302 switch (nd_type(node)) {
1303 case NODE_ARYPTN:
1304 {
1305 struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
1306 apinfo->imemo = rb_gc_location(apinfo->imemo);
1307 break;
1308 }
1309 case NODE_ARGS:
1310 {
1311 struct rb_args_info *args = node->nd_ainfo;
1312 args->imemo = rb_gc_location(args->imemo);
1313 break;
1314 }
1315 case NODE_LIT:
1316 case NODE_STR:
1317 case NODE_XSTR:
1318 case NODE_DSTR:
1319 case NODE_DXSTR:
1320 case NODE_DREGX:
1321 case NODE_DSYM:
1322 node->nd_lit = rb_gc_location(node->nd_lit);
1323 break;
1324 default:
1325 rb_bug("unreachable");
1326 }
1327}
1328
1329void
1331{
1332 if (ast->node_buffer) {
1333 node_buffer_t *nb = ast->node_buffer;
1334
1335 iterate_node_values(&nb->markable, update_ast_value, NULL);
1336 }
1337}
1338
1339void
1341{
1344 if (ast->node_buffer) {
1345 node_buffer_t *nb = ast->node_buffer;
1346
1347 iterate_node_values(&nb->markable, mark_ast_value, NULL);
1348 }
1349}
1350
1351void
1353{
1354 if (ast->node_buffer) {
1355 rb_node_buffer_free(ast->node_buffer);
1356 ast->node_buffer = 0;
1357 }
1358}
1359
1360static size_t
1361buffer_list_size(node_buffer_list_t *nb)
1362{
1363 size_t size = 0;
1364 node_buffer_elem_t *nbe = nb->head;
1365 while (nbe != nb->last) {
1366 nbe = nbe->next;
1367 size += offsetof(node_buffer_elem_t, buf) + nb->len * sizeof(NODE);
1368 }
1369 return size;
1370}
1371
1372size_t
1374{
1375 size_t size = 0;
1376 node_buffer_t *nb = ast->node_buffer;
1377
1378 if (nb) {
1380 size += buffer_list_size(&nb->unmarkable);
1381 size += buffer_list_size(&nb->markable);
1382 }
1383 return size;
1384}
1385
1386void
1388{
1389 rb_ast_free(ast);
1390}
1391
1392void
1394{
1395 if (NIL_P(ast->node_buffer->mark_hash)) {
1397 }
1399}
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
void rb_bug(const char *fmt,...)
Definition: error.c:636
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
const char * name
Definition: nkf.c:208
void rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
Definition: node.c:1095
#define F_NODE(name, ann)
Definition: node.c:69
VALUE rb_parser_dump_tree(const NODE *node, int comment)
Definition: node.c:1076
#define F_CUSTOM1(name, ann)
Definition: node.c:61
void rb_ast_dispose(rb_ast_t *ast)
Definition: node.c:1387
struct node_buffer_elem_struct node_buffer_elem_t
#define D_NODE_HEADER(node)
Definition: node.c:38
rb_ast_t * rb_ast_new(void)
Definition: node.c:1235
#define A_ID(id)
Definition: node.c:23
#define F_LONG(name, ann)
Definition: node.c:65
void rb_ast_add_mark_object(rb_ast_t *ast, VALUE obj)
Definition: node.c:1393
#define A_INDENT
Definition: node.c:20
NODE * rb_ast_newnode(rb_ast_t *ast, enum node_type type)
Definition: node.c:1198
#define A_LONG(val)
Definition: node.c:25
void rb_ast_add_local_table(rb_ast_t *ast, ID *buf)
Definition: node.c:1219
#define D_DEDENT
Definition: node.c:22
#define F_ID(name, ann)
Definition: node.c:62
void rb_ast_update_references(rb_ast_t *ast)
Definition: node.c:1330
#define F_GENTRY(name, ann)
Definition: node.c:63
void rb_ast_mark(rb_ast_t *ast)
Definition: node.c:1340
#define A(str)
Definition: node.c:17
size_t rb_ast_memsize(const rb_ast_t *ast)
Definition: node.c:1373
#define F_INT(name, ann)
Definition: node.c:64
void node_itr_t(void *ctx, NODE *node)
Definition: node.c:1242
#define NODE_BUF_DEFAULT_LEN
Definition: node.c:15
#define F_LIT(name, ann)
Definition: node.c:66
#define A_INT(val)
Definition: node.c:24
#define D_NULL_NODE
Definition: node.c:37
void rb_ast_free(rb_ast_t *ast)
Definition: node.c:1352
#define AR(str)
Definition: node.c:18
#define ANN(ann)
Definition: node.c:72
#define D_INDENT
Definition: node.c:21
#define LAST_NODE
Definition: node.c:77
#define F_MSG(name, ann, desc)
Definition: node.c:67
void rb_ast_delete_node(rb_ast_t *ast, NODE *n)
Definition: node.c:1227
#define nd_pkwrestarg
#define NULL
#define nd_state
#define nd_var
#define nd_cond
#define nd_pkwargs
#define offsetof(TYPE, MEMBER)
#define xfree
#define nd_set_type(n, t)
const VALUE VALUE obj
#define nd_vid
#define nd_mid
struct RNode NODE
VALUE rb_ident_hash_new(void)
Definition: hash.c:4278
#define nd_ensr
#define NIL_P(v)
#define nd_resq
#define nd_end
const char size_t n
#define nd_iter
#define nd_recv
unsigned long VALUE
#define nd_ainfo
#define T_NODE
#define nd_1st
#define nd_brace
#define nd_alias
#define nd_2nd
uint32_t i
#define char
__inline__ const void *__restrict__ size_t len
#define nd_nth
#define nd_entry
#define STATIC_ASSERT(name, expr)
void * rb_xmalloc_mul_add(size_t, size_t, size_t) __attribute__((__malloc__))
Definition: gc.c:10189
#define NODE_NAMED_REST_P(node)
#define nd_stts
#define RB_OBJ_WRITE(a, slot, b)
VALUE rb_gc_location(VALUE)
Definition: gc.c:8127
#define nd_pconst
#define PRIsVALUE
struct node_buffer_struct node_buffer_t
#define nd_args
void rb_gc_mark(VALUE)
Definition: gc.c:5228
VALUE rb_str_catf(VALUE, const char *,...) __attribute__((format(printf
const char * ruby_node_name(int node)
Definition: iseq.c:2534
unsigned int size
#define nd_cpath
#define Qtrue
struct rb_call_cache buf
#define FLEX_ARY_LEN
#define nd_else
#define NODE_SPECIAL_NO_REST_KEYWORD
#define Qnil
#define nd_alen
#define nd_lit
st_data_t st_index_t
#define nd_undef
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
Definition: gc.c:2321
#define nd_head
void rb_gc_mark_movable(VALUE)
Definition: gc.c:5222
#define NODE_REQUIRED_KEYWORD_P(node)
__inline__ int
#define nd_beg
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
Definition: hash.c:2852
#define nd_type(n)
#define nd_apinfo
#define nd_super
unsigned long ID
#define nd_body
#define nd_value
#define nd_defn
#define NODE_SPECIAL_EXCESSIVE_COMMA
#define nd_next
#define nd_tbl
#define nd_aid
#define rb_str_new_cstr(str)
#define nd_orig
void * ruby_xmalloc(size_t) __attribute__((__malloc__)) __attribute__((__returns_nonnull__)) __attribute__((alloc_size(1)))
Definition: gc.c:12008
st_index_t count
Definition: node.c:104
VALUE indent
Definition: node.c:103
VALUE buf
Definition: node.c:103
struct node_buffer_elem_struct * next
Definition: node.c:1109
NODE buf[FLEX_ARY_LEN]
Definition: node.c:1111
node_buffer_elem_t * last
Definition: node.c:1117
node_buffer_elem_t * head
Definition: node.c:1116
node_buffer_list_t markable
Definition: node.c:1122
ID * local_tables
Definition: node.c:1123
VALUE mark_hash
Definition: node.c:1124
node_buffer_list_t unmarkable
Definition: node.c:1121
node_buffer_t * node_buffer
#define next_table
#define rb_id2str(id)
Definition: vm_backtrace.c:30