1 /**********************************************************************
3 node.c - ruby node tree
6 created at: 09/12/06 21:23:44 JST
8 Copyright (C) 2009 Yusuke Endoh
10 **********************************************************************/
13 #include "internal/hash.h"
14 #include "internal/variable.h"
15 #include "ruby/ruby.h"
18 #define NODE_BUF_DEFAULT_LEN 16
20 #define A(str) rb_str_cat2(buf, (str))
21 #define AR(str) rb_str_concat(buf, (str))
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_NODE_HEADER(node, term) \
31 rb_str_catf(buf, "@ %s (id: %d, line: %d, location: (%d,%d)-(%d,%d))%s"term, \
32 ruby_node_name(nd_type(node)), nd_node_id(node), nd_line(node), \
33 nd_first_lineno(node), nd_first_column(node), \
34 nd_last_lineno(node), nd_last_column(node), \
35 (node->flags & NODE_FL_NEWLINE ? "*" : ""))
36 #define A_FIELD_HEADER(len, name, term) \
37 rb_str_catf(buf, "+- %.*s:"term, (len), (name))
38 #define D_FIELD_HEADER(len, name, term) (A_INDENT, A_FIELD_HEADER(len, name, term))
40 #define D_NULL_NODE (A_INDENT, A("(null node)\n"))
41 #define D_NODE_HEADER(node) (A_INDENT, A_NODE_HEADER(node, "\n"))
43 #define COMPOUND_FIELD(len, name) \
44 FIELD_BLOCK((D_FIELD_HEADER((len), (name), "\n"), D_INDENT), D_DEDENT)
46 #define COMPOUND_FIELD1(name, ann) \
47 COMPOUND_FIELD(FIELD_NAME_LEN(name, ann), \
48 FIELD_NAME_DESC(name, ann))
50 #define FIELD_NAME_DESC(name, ann) name " (" ann ")"
51 #define FIELD_NAME_LEN(name, ann) (int)( \
53 rb_strlen_lit(FIELD_NAME_DESC(name, ann)) : \
55 #define SIMPLE_FIELD(len, name) \
56 FIELD_BLOCK(D_FIELD_HEADER((len), (name), " "), A("\n"))
58 #define FIELD_BLOCK(init, reset) \
59 for (init, field_flag = 1; \
60 field_flag; /* should be optimized away */ \
61 reset, field_flag = 0)
63 #define SIMPLE_FIELD1(name, ann) SIMPLE_FIELD(FIELD_NAME_LEN(name, ann), FIELD_NAME_DESC(name, ann))
64 #define F_CUSTOM1(name, ann) SIMPLE_FIELD1(#name, ann)
65 #define F_ID(name, ann) SIMPLE_FIELD1(#name, ann) A_ID(node->name)
66 #define F_GENTRY(name, ann) SIMPLE_FIELD1(#name, ann) A_ID(node->name)
67 #define F_INT(name, ann) SIMPLE_FIELD1(#name, ann) A_INT(node->name)
68 #define F_LONG(name, ann) SIMPLE_FIELD1(#name, ann) A_LONG(node->name)
69 #define F_LIT(name, ann) SIMPLE_FIELD1(#name, ann) A_LIT(node->name)
70 #define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
72 #define F_NODE(name, ann) \
73 COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, node->name);}
77 A_INDENT; A("| # " ann "\n"); \
80 #define LAST_NODE (next_indent = " ")
83 rb_dump_literal(VALUE lit
)
85 if (!RB_SPECIAL_CONST_P(lit
)) {
87 switch (RB_BUILTIN_TYPE(lit
)) {
88 case T_CLASS
: case T_MODULE
: case T_ICLASS
:
89 str
= rb_class_path(lit
);
90 if (FL_TEST(lit
, FL_SINGLETON
)) {
91 str
= rb_sprintf("<%"PRIsVALUE
">", str
);
98 return rb_inspect(lit
);
102 add_indent(VALUE buf
, VALUE indent
)
108 add_id(VALUE buf
, ID id
)
114 VALUE str
= rb_id2str(id
);
119 rb_str_catf(buf
, "(internal variable: 0x%"PRIsVALUE
")", id
);
124 struct add_option_arg
{
129 static void dump_node(VALUE
, VALUE
, int, const NODE
*);
130 static const char default_indent
[] = "| ";
133 dump_array(VALUE buf
, VALUE indent
, int comment
, const NODE
*node
)
136 const char *next_indent
= default_indent
;
137 F_LONG(nd_alen
, "length");
138 F_NODE(nd_head
, "element");
139 while (node
->nd_next
&& nd_type_p(node
->nd_next
, NODE_LIST
)) {
140 node
= node
->nd_next
;
141 F_NODE(nd_head
, "element");
144 F_NODE(nd_next
, "next element");
148 dump_node(VALUE buf
, VALUE indent
, int comment
, const NODE
* node
)
152 const char *next_indent
= default_indent
;
162 type
= nd_type(node
);
165 ANN("statement sequence");
166 ANN("format: [nd_head]; ...; [nd_next]");
167 ANN("example: foo; bar");
171 rb_str_catf(buf
, "+- nd_head (%s%d):\n",
172 comment
? "statement #" : "", ++i
);
173 if (!node
->nd_next
) LAST_NODE
;
175 dump_node(buf
, indent
, comment
, node
->nd_head
);
177 } while (node
->nd_next
&&
178 nd_type_p(node
->nd_next
, NODE_BLOCK
) &&
179 (node
= node
->nd_next
, 1));
182 F_NODE(nd_next
, "next block");
188 ANN("format: if [nd_cond] then [nd_body] else [nd_else] end");
189 ANN("example: if x == 1 then foo else bar end");
190 F_NODE(nd_cond
, "condition expr");
191 F_NODE(nd_body
, "then clause");
193 F_NODE(nd_else
, "else clause");
197 ANN("unless statement");
198 ANN("format: unless [nd_cond] then [nd_body] else [nd_else] end");
199 ANN("example: unless x == 1 then foo else bar end");
200 F_NODE(nd_cond
, "condition expr");
201 F_NODE(nd_body
, "then clause");
203 F_NODE(nd_else
, "else clause");
207 ANN("case statement");
208 ANN("format: case [nd_head]; [nd_body]; end");
209 ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
210 F_NODE(nd_head
, "case expr");
212 F_NODE(nd_body
, "when clauses");
215 ANN("case statement with no head");
216 ANN("format: case; [nd_body]; end");
217 ANN("example: case; when 1; foo; when 2; bar; else baz; end");
218 F_NODE(nd_head
, "case expr");
220 F_NODE(nd_body
, "when clauses");
223 ANN("case statement (pattern matching)");
224 ANN("format: case [nd_head]; [nd_body]; end");
225 ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
226 F_NODE(nd_head
, "case expr");
228 F_NODE(nd_body
, "in clauses");
233 ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
234 ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
235 F_NODE(nd_head
, "when value");
236 F_NODE(nd_body
, "when body");
238 F_NODE(nd_next
, "next when clause");
243 ANN("format: in [nd_head]; [nd_body]; (in or else) [nd_next]");
244 ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
245 F_NODE(nd_head
, "in pattern");
246 F_NODE(nd_body
, "in body");
248 F_NODE(nd_next
, "next in clause");
252 ANN("while statement");
253 ANN("format: while [nd_cond]; [nd_body]; end");
254 ANN("example: while x == 1; foo; end");
257 ANN("until statement");
258 ANN("format: until [nd_cond]; [nd_body]; end");
259 ANN("example: until x == 1; foo; end");
261 F_CUSTOM1(nd_state
, "begin-end-while?") {
262 A_INT((int)node
->nd_state
);
263 A((node
->nd_state
== 1) ? " (while-end)" : " (begin-end-while)");
265 F_NODE(nd_cond
, "condition");
267 F_NODE(nd_body
, "body");
271 ANN("method call with block");
272 ANN("format: [nd_iter] { [nd_body] }");
273 ANN("example: 3.times { foo }");
276 ANN("for statement");
277 ANN("format: for * in [nd_iter] do [nd_body] end");
278 ANN("example: for i in 1..3 do foo end");
280 F_NODE(nd_iter
, "iteration receiver");
282 F_NODE(nd_body
, "body");
286 ANN("vars of for statement with masgn");
287 ANN("format: for [nd_var] in ... do ... end");
288 ANN("example: for x, y in 1..3 do foo end");
290 F_NODE(nd_var
, "var");
294 ANN("break statement");
295 ANN("format: break [nd_stts]");
296 ANN("example: break 1");
299 ANN("next statement");
300 ANN("format: next [nd_stts]");
301 ANN("example: next 1");
304 ANN("return statement");
305 ANN("format: return [nd_stts]");
306 ANN("example: return 1");
309 F_NODE(nd_stts
, "value");
313 ANN("redo statement");
315 ANN("example: redo");
319 ANN("retry statement");
320 ANN("format: retry");
321 ANN("example: retry");
325 ANN("begin statement");
326 ANN("format: begin; [nd_body]; end");
327 ANN("example: begin; 1; end");
329 F_NODE(nd_body
, "body");
333 ANN("rescue clause");
334 ANN("format: begin; [nd_body]; (rescue) [nd_resq]; else [nd_else]; end");
335 ANN("example: begin; foo; rescue; bar; else; baz; end");
336 F_NODE(nd_head
, "body");
337 F_NODE(nd_resq
, "rescue clause list");
339 F_NODE(nd_else
, "rescue else clause");
343 ANN("rescue clause (cont'd)");
344 ANN("format: rescue [nd_args]; [nd_body]; (rescue) [nd_head]");
345 ANN("example: begin; foo; rescue; bar; else; baz; end");
346 F_NODE(nd_args
, "rescue exceptions");
347 F_NODE(nd_body
, "rescue clause");
349 F_NODE(nd_head
, "next rescue clause");
353 ANN("ensure clause");
354 ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
355 ANN("example: begin; foo; ensure; bar; end");
356 F_NODE(nd_head
, "body");
358 F_NODE(nd_ensr
, "ensure clause");
363 ANN("format: [nd_1st] && [nd_2nd]");
364 ANN("example: foo && bar");
368 ANN("format: [nd_1st] || [nd_2nd]");
369 ANN("example: foo || bar");
372 F_NODE(nd_1st
, "left expr");
373 if (!node
->nd_2nd
|| !nd_type_p(node
->nd_2nd
, type
))
378 F_NODE(nd_2nd
, "right expr");
382 ANN("multiple assignment");
383 ANN("format: [nd_head], [nd_args] = [nd_value]");
384 ANN("example: a, b = foo");
385 F_NODE(nd_value
, "rhsn");
386 F_NODE(nd_head
, "lhsn");
387 if (NODE_NAMED_REST_P(node
->nd_args
)) {
389 F_NODE(nd_args
, "splatn");
392 F_MSG(nd_args
, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
397 ANN("local variable assignment");
398 ANN("format: [nd_vid](lvar) = [nd_value]");
399 ANN("example: x = foo");
400 F_ID(nd_vid
, "local variable");
401 if (NODE_REQUIRED_KEYWORD_P(node
)) {
402 F_MSG(nd_value
, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
406 F_NODE(nd_value
, "rvalue");
410 ANN("dynamic variable assignment");
411 ANN("format: [nd_vid](dvar) = [nd_value]");
412 ANN("example: x = nil; 1.times { x = foo }");
413 ANN("example: 1.times { x = foo }");
414 F_ID(nd_vid
, "local variable");
415 if (NODE_REQUIRED_KEYWORD_P(node
)) {
416 F_MSG(nd_value
, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
420 F_NODE(nd_value
, "rvalue");
424 ANN("instance variable assignment");
425 ANN("format: [nd_vid](ivar) = [nd_value]");
426 ANN("example: @x = foo");
427 F_ID(nd_vid
, "instance variable");
429 F_NODE(nd_value
, "rvalue");
432 ANN("class variable assignment");
433 ANN("format: [nd_vid](cvar) = [nd_value]");
434 ANN("example: @@x = foo");
435 F_ID(nd_vid
, "class variable");
437 F_NODE(nd_value
, "rvalue");
440 ANN("global variable assignment");
441 ANN("format: [nd_entry](gvar) = [nd_value]");
442 ANN("example: $x = foo");
443 F_GENTRY(nd_entry
, "global variable");
445 F_NODE(nd_value
, "rvalue");
449 ANN("constant declaration");
450 ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
451 ANN("example: X = foo");
453 F_ID(nd_vid
, "constant");
454 F_MSG(nd_else
, "extension", "not used");
457 F_MSG(nd_vid
, "constant", "0 (see extension field)");
458 F_NODE(nd_else
, "extension");
461 F_NODE(nd_value
, "rvalue");
465 ANN("array assignment with operator");
466 ANN("format: [nd_recv] [ [nd_args->nd_head] ] [nd_mid]= [nd_args->nd_body]");
467 ANN("example: ary[1] += foo");
468 F_NODE(nd_recv
, "receiver");
469 F_ID(nd_mid
, "operator");
470 F_NODE(nd_args
->nd_head
, "index");
472 F_NODE(nd_args
->nd_body
, "rvalue");
476 ANN("attr assignment with operator");
477 ANN("format: [nd_recv].[attr] [nd_next->nd_mid]= [nd_value]");
478 ANN(" where [attr]: [nd_next->nd_vid]");
479 ANN("example: struct.field += foo");
480 F_NODE(nd_recv
, "receiver");
481 F_CUSTOM1(nd_next
->nd_vid
, "attr") {
482 if (node
->nd_next
->nd_aid
) A("? ");
483 A_ID(node
->nd_next
->nd_vid
);
485 F_ID(nd_next
->nd_mid
, "operator");
487 F_NODE(nd_value
, "rvalue");
490 case NODE_OP_ASGN_AND
:
491 ANN("assignment with && operator");
492 ANN("format: [nd_head] &&= [nd_value]");
493 ANN("example: foo &&= bar");
495 case NODE_OP_ASGN_OR
:
496 ANN("assignment with || operator");
497 ANN("format: [nd_head] ||= [nd_value]");
498 ANN("example: foo ||= bar");
500 F_NODE(nd_head
, "variable");
502 F_NODE(nd_value
, "rvalue");
506 ANN("constant declaration with operator");
507 ANN("format: [nd_head](constant) [nd_aid]= [nd_value]");
508 ANN("example: A::B ||= 1");
509 F_NODE(nd_head
, "constant");
510 F_ID(nd_aid
, "operator");
512 F_NODE(nd_value
, "rvalue");
516 ANN("method invocation");
517 ANN("format: [nd_recv].[nd_mid]([nd_args])");
518 ANN("example: obj.foo(1)");
519 F_ID(nd_mid
, "method id");
520 F_NODE(nd_recv
, "receiver");
522 F_NODE(nd_args
, "arguments");
526 ANN("method invocation");
527 ANN("format: [nd_recv] [nd_mid] [nd_args]");
528 ANN("example: foo + bar");
529 F_ID(nd_mid
, "method id");
530 F_NODE(nd_recv
, "receiver");
532 F_NODE(nd_args
, "arguments");
536 ANN("function call");
537 ANN("format: [nd_mid]([nd_args])");
538 ANN("example: foo(1)");
539 F_ID(nd_mid
, "method id");
541 F_NODE(nd_args
, "arguments");
545 ANN("function call with no argument");
546 ANN("format: [nd_mid]");
548 F_ID(nd_mid
, "method id");
552 ANN("safe method invocation");
553 ANN("format: [nd_recv]&.[nd_mid]([nd_args])");
554 ANN("example: obj&.foo(1)");
555 F_ID(nd_mid
, "method id");
556 F_NODE(nd_recv
, "receiver");
558 F_NODE(nd_args
, "arguments");
562 ANN("super invocation");
563 ANN("format: super [nd_args]");
564 ANN("example: super 1");
566 F_NODE(nd_args
, "arguments");
570 ANN("super invocation with no argument");
571 ANN("format: super");
572 ANN("example: super");
576 ANN("list constructor");
577 ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
578 ANN("example: [1, 2, 3]");
581 ANN("return arguments");
582 ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
583 ANN("example: return 1, 2, 3");
585 dump_array(buf
, indent
, comment
, node
);
589 ANN("empty list constructor");
595 if (!node
->nd_brace
) {
596 ANN("keyword arguments");
597 ANN("format: nd_head");
598 ANN("example: a: 1, b: 2");
601 ANN("hash constructor");
602 ANN("format: { [nd_head] }");
603 ANN("example: { 1 => 2, 3 => 4 }");
605 F_CUSTOM1(nd_brace
, "keyword arguments or hash literal") {
606 switch (node
->nd_brace
) {
607 case 0: A("0 (keyword argument)"); break;
608 case 1: A("1 (hash literal)"); break;
612 F_NODE(nd_head
, "contents");
616 ANN("yield invocation");
617 ANN("format: yield [nd_head]");
618 ANN("example: yield 1");
620 F_NODE(nd_head
, "arguments");
624 ANN("local variable reference");
625 ANN("format: [nd_vid](lvar)");
627 F_ID(nd_vid
, "local variable");
630 ANN("dynamic variable reference");
631 ANN("format: [nd_vid](dvar)");
632 ANN("example: 1.times { x = 1; x }");
633 F_ID(nd_vid
, "local variable");
636 ANN("instance variable reference");
637 ANN("format: [nd_vid](ivar)");
639 F_ID(nd_vid
, "instance variable");
642 ANN("constant reference");
643 ANN("format: [nd_vid](constant)");
645 F_ID(nd_vid
, "constant");
648 ANN("class variable reference");
649 ANN("format: [nd_vid](cvar)");
651 F_ID(nd_vid
, "class variable");
655 ANN("global variable reference");
656 ANN("format: [nd_entry](gvar)");
658 F_GENTRY(nd_entry
, "global variable");
662 ANN("nth special variable reference");
663 ANN("format: $[nd_nth]");
664 ANN("example: $1, $2, ..");
665 F_CUSTOM1(nd_nth
, "variable") { A("$"); A_LONG(node
->nd_nth
); }
669 ANN("back special variable reference");
670 ANN("format: $[nd_nth]");
671 ANN("example: $&, $`, $', $+");
672 F_CUSTOM1(nd_nth
, "variable") {
674 name
[1] = (char)node
->nd_nth
;
680 ANN("match expression (against $_ implicitly)");
681 ANN("format: [nd_lit] (in condition)");
682 ANN("example: if /foo/; foo; end");
683 F_LIT(nd_lit
, "regexp");
687 ANN("match expression (regexp first)");
688 ANN("format: [nd_recv] =~ [nd_value]");
689 ANN("example: /foo/ =~ 'foo'");
690 F_NODE(nd_recv
, "regexp (receiver)");
691 if (!node
->nd_args
) LAST_NODE
;
692 F_NODE(nd_value
, "string (argument)");
695 F_NODE(nd_args
, "named captures");
700 ANN("match expression (regexp second)");
701 ANN("format: [nd_recv] =~ [nd_value]");
702 ANN("example: 'foo' =~ /foo/");
703 F_NODE(nd_recv
, "string (receiver)");
705 F_NODE(nd_value
, "regexp (argument)");
710 ANN("format: [nd_lit]");
711 ANN("example: 1, /foo/");
714 ANN("string literal");
715 ANN("format: [nd_lit]");
716 ANN("example: 'foo'");
719 ANN("xstring literal");
720 ANN("format: [nd_lit]");
721 ANN("example: `foo`");
723 F_LIT(nd_lit
, "literal");
727 ANN("once evaluation");
728 ANN("format: [nd_body]");
729 ANN("example: /foo#{ bar }baz/o");
731 F_NODE(nd_body
, "body");
734 ANN("string literal with interpolation");
735 ANN("format: [nd_lit]");
736 ANN("example: \"foo#{ bar }baz\"");
739 ANN("xstring literal with interpolation");
740 ANN("format: [nd_lit]");
741 ANN("example: `foo#{ bar }baz`");
744 ANN("regexp literal with interpolation");
745 ANN("format: [nd_lit]");
746 ANN("example: /foo#{ bar }baz/");
749 ANN("symbol literal with interpolation");
750 ANN("format: [nd_lit]");
751 ANN("example: :\"foo#{ bar }baz\"");
753 F_LIT(nd_lit
, "preceding string");
754 if (!node
->nd_next
) return;
755 F_NODE(nd_next
->nd_head
, "interpolation");
757 F_NODE(nd_next
->nd_next
, "tailing strings");
761 ANN("interpolation expression");
762 ANN("format: \"..#{ [nd_lit] }..\"");
763 ANN("example: \"foo#{ bar }baz\"");
765 F_NODE(nd_body
, "body");
769 ANN("splat argument following arguments");
770 ANN("format: ..(*[nd_head], [nd_body..])");
771 ANN("example: foo(*ary, post_arg1, post_arg2)");
772 F_NODE(nd_head
, "preceding array");
774 F_NODE(nd_body
, "following array");
778 ANN("splat argument following one argument");
779 ANN("format: ..(*[nd_head], [nd_body])");
780 ANN("example: foo(*ary, post_arg)");
781 F_NODE(nd_head
, "preceding array");
783 F_NODE(nd_body
, "following element");
787 ANN("splat argument");
788 ANN("format: *[nd_head]");
789 ANN("example: foo(*ary)");
791 F_NODE(nd_head
, "splat'ed array");
794 case NODE_BLOCK_PASS
:
795 ANN("arguments with block argument");
796 ANN("format: ..([nd_head], &[nd_body])");
797 ANN("example: foo(x, &blk)");
798 F_NODE(nd_head
, "other arguments");
800 F_NODE(nd_body
, "block argument");
804 ANN("method definition");
805 ANN("format: def [nd_mid] [nd_defn]; end");
806 ANN("example: def foo; bar; end");
807 F_ID(nd_mid
, "method name");
809 F_NODE(nd_defn
, "method definition");
813 ANN("singleton method definition");
814 ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
815 ANN("example: def obj.foo; bar; end");
816 F_NODE(nd_recv
, "receiver");
817 F_ID(nd_mid
, "method name");
819 F_NODE(nd_defn
, "method definition");
823 ANN("method alias statement");
824 ANN("format: alias [nd_1st] [nd_2nd]");
825 ANN("example: alias bar foo");
826 F_NODE(nd_1st
, "new name");
828 F_NODE(nd_2nd
, "old name");
832 ANN("global variable alias statement");
833 ANN("format: alias [nd_alias](gvar) [nd_orig](gvar)");
834 ANN("example: alias $y $x");
835 F_ID(nd_alias
, "new name");
836 F_ID(nd_orig
, "old name");
840 ANN("method undef statement");
841 ANN("format: undef [nd_undef]");
842 ANN("example: undef foo");
844 F_NODE(nd_undef
, "old name");
848 ANN("class definition");
849 ANN("format: class [nd_cpath] < [nd_super]; [nd_body]; end");
850 ANN("example: class C2 < C; ..; end");
851 F_NODE(nd_cpath
, "class path");
852 F_NODE(nd_super
, "superclass");
854 F_NODE(nd_body
, "class definition");
858 ANN("module definition");
859 ANN("format: module [nd_cpath]; [nd_body]; end");
860 ANN("example: module M; ..; end");
861 F_NODE(nd_cpath
, "module path");
863 F_NODE(nd_body
, "module definition");
867 ANN("singleton class definition");
868 ANN("format: class << [nd_recv]; [nd_body]; end");
869 ANN("example: class << obj; ..; end");
870 F_NODE(nd_recv
, "receiver");
872 F_NODE(nd_body
, "singleton class definition");
876 ANN("scoped constant reference");
877 ANN("format: [nd_head]::[nd_mid]");
878 ANN("example: M::C");
879 F_ID(nd_mid
, "constant name");
881 F_NODE(nd_head
, "receiver");
885 ANN("top-level constant reference");
886 ANN("format: ::[nd_mid]");
887 ANN("example: ::Object");
888 F_ID(nd_mid
, "constant name");
892 ANN("range constructor (incl.)");
893 ANN("format: [nd_beg]..[nd_end]");
894 ANN("example: 1..5");
897 ANN("range constructor (excl.)");
898 ANN("format: [nd_beg]...[nd_end]");
899 ANN("example: 1...5");
902 ANN("flip-flop condition (incl.)");
903 ANN("format: [nd_beg]..[nd_end]");
904 ANN("example: if (x==1)..(x==5); foo; end");
907 ANN("flip-flop condition (excl.)");
908 ANN("format: [nd_beg]...[nd_end]");
909 ANN("example: if (x==1)...(x==5); foo; end");
911 F_NODE(nd_beg
, "begin");
913 F_NODE(nd_end
, "end");
919 ANN("example: self");
931 ANN("example: true");
936 ANN("format: false");
937 ANN("example: false");
941 ANN("virtual reference to $!");
942 ANN("format: rescue => id");
943 ANN("example: rescue => id");
947 ANN("defined? expression");
948 ANN("format: defined?([nd_head])");
949 ANN("example: defined?(foo)");
950 F_NODE(nd_head
, "expr");
954 ANN("post-execution");
955 ANN("format: END { [nd_body] }");
956 ANN("example: END { foo }");
958 F_NODE(nd_body
, "END clause");
962 ANN("attr assignment");
963 ANN("format: [nd_recv].[nd_mid] = [nd_args]");
964 ANN("example: struct.field = foo");
965 F_NODE(nd_recv
, "receiver");
966 F_ID(nd_mid
, "method name");
968 F_NODE(nd_args
, "arguments");
972 ANN("lambda expression");
973 ANN("format: -> [nd_body]");
974 ANN("example: -> { foo }");
976 F_NODE(nd_body
, "lambda clause");
980 ANN("optional arguments");
981 ANN("format: def method_name([nd_body=some], [nd_next..])");
982 ANN("example: def foo(a, b=1, c); end");
983 F_NODE(nd_body
, "body");
985 F_NODE(nd_next
, "next");
989 ANN("keyword arguments");
990 ANN("format: def method_name([nd_body=some], [nd_next..])");
991 ANN("example: def foo(a:1, b:2); end");
992 F_NODE(nd_body
, "body");
994 F_NODE(nd_next
, "next");
998 ANN("post arguments");
999 ANN("format: *[nd_1st], [nd_2nd..] = ..");
1000 ANN("example: a, *rest, z = foo");
1001 if (NODE_NAMED_REST_P(node
->nd_1st
)) {
1002 F_NODE(nd_1st
, "rest argument");
1005 F_MSG(nd_1st
, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1008 F_NODE(nd_2nd
, "post arguments");
1012 ANN("method parameters");
1013 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])");
1014 ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, kw: 1, **kwrest, &blk); end");
1015 F_INT(nd_ainfo
->pre_args_num
, "count of mandatory (pre-)arguments");
1016 F_NODE(nd_ainfo
->pre_init
, "initialization of (pre-)arguments");
1017 F_INT(nd_ainfo
->post_args_num
, "count of mandatory post-arguments");
1018 F_NODE(nd_ainfo
->post_init
, "initialization of post-arguments");
1019 F_ID(nd_ainfo
->first_post_arg
, "first post argument");
1020 F_CUSTOM1(nd_ainfo
->rest_arg
, "rest argument") {
1021 if (node
->nd_ainfo
->rest_arg
== NODE_SPECIAL_EXCESSIVE_COMMA
) {
1022 A("1 (excessed comma)");
1025 A_ID(node
->nd_ainfo
->rest_arg
);
1028 F_ID(nd_ainfo
->block_arg
, "block argument");
1029 F_NODE(nd_ainfo
->opt_args
, "optional arguments");
1030 F_NODE(nd_ainfo
->kw_args
, "keyword arguments");
1032 F_NODE(nd_ainfo
->kw_rest_arg
, "keyword rest argument");
1037 ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
1038 F_CUSTOM1(nd_tbl
, "local table") {
1039 rb_ast_id_table_t
*tbl
= node
->nd_tbl
;
1041 int size
= tbl
? tbl
->size
: 0;
1042 if (size
== 0) A("(empty)");
1043 for (i
= 0; i
< size
; i
++) {
1044 A_ID(tbl
->ids
[i
]); if (i
< size
- 1) A(",");
1047 F_NODE(nd_args
, "arguments");
1049 F_NODE(nd_body
, "body");
1053 ANN("array pattern");
1054 ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
1055 F_NODE(nd_pconst
, "constant");
1056 F_NODE(nd_apinfo
->pre_args
, "pre arguments");
1057 if (NODE_NAMED_REST_P(node
->nd_apinfo
->rest_arg
)) {
1058 F_NODE(nd_apinfo
->rest_arg
, "rest argument");
1061 F_MSG(nd_apinfo
->rest_arg
, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1064 F_NODE(nd_apinfo
->post_args
, "post arguments");
1068 ANN("find pattern");
1069 ANN("format: [nd_pconst](*[pre_rest_arg], args, ..., *[post_rest_arg])");
1070 F_NODE(nd_pconst
, "constant");
1071 if (NODE_NAMED_REST_P(node
->nd_fpinfo
->pre_rest_arg
)) {
1072 F_NODE(nd_fpinfo
->pre_rest_arg
, "pre rest argument");
1075 F_MSG(nd_fpinfo
->pre_rest_arg
, "pre rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1077 F_NODE(nd_fpinfo
->args
, "arguments");
1080 if (NODE_NAMED_REST_P(node
->nd_fpinfo
->post_rest_arg
)) {
1081 F_NODE(nd_fpinfo
->post_rest_arg
, "post rest argument");
1084 F_MSG(nd_fpinfo
->post_rest_arg
, "post rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1089 ANN("hash pattern");
1090 ANN("format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])");
1091 F_NODE(nd_pconst
, "constant");
1092 F_NODE(nd_pkwargs
, "keyword arguments");
1094 if (node
->nd_pkwrestarg
== NODE_SPECIAL_NO_REST_KEYWORD
) {
1095 F_MSG(nd_pkwrestarg
, "keyword rest argument", "NODE_SPECIAL_NO_REST_KEYWORD (**nil)");
1098 F_NODE(nd_pkwrestarg
, "keyword rest argument");
1107 rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node
)));
1111 rb_parser_dump_tree(const NODE
*node
, int comment
)
1113 VALUE buf
= rb_str_new_cstr(
1114 "###########################################################\n"
1115 "## Do NOT use this node dump for any purpose other than ##\n"
1116 "## debug and research. Compatibility is not guaranteed. ##\n"
1117 "###########################################################\n\n"
1119 dump_node(buf
, rb_str_new_cstr("# "), comment
, node
);
1123 /* Setup NODE structure.
1124 * NODE is not an object managed by GC, but it imitates an object
1125 * so that it can work with `RB_TYPE_P(obj, T_NODE)`.
1126 * This dirty hack is needed because Ripper jumbles NODEs and other type
1130 rb_node_init(NODE
*n
, enum node_type type
, VALUE a0
, VALUE a1
, VALUE a2
)
1133 nd_init_type(n
, type
);
1137 n
->nd_loc
.beg_pos
.lineno
= 0;
1138 n
->nd_loc
.beg_pos
.column
= 0;
1139 n
->nd_loc
.end_pos
.lineno
= 0;
1140 n
->nd_loc
.end_pos
.column
= 0;
1143 typedef struct node_buffer_elem_struct
{
1144 struct node_buffer_elem_struct
*next
;
1146 NODE buf
[FLEX_ARY_LEN
];
1147 } node_buffer_elem_t
;
1151 node_buffer_elem_t
*head
;
1152 node_buffer_elem_t
*last
;
1153 } node_buffer_list_t
;
1155 struct node_buffer_struct
{
1156 node_buffer_list_t unmarkable
;
1157 node_buffer_list_t markable
;
1158 struct rb_ast_local_table_link
*local_tables
;
1163 init_node_buffer_list(node_buffer_list_t
* nb
, node_buffer_elem_t
*head
)
1166 nb
->len
= NODE_BUF_DEFAULT_LEN
;
1167 nb
->head
= nb
->last
= head
;
1168 nb
->head
->len
= nb
->len
;
1169 nb
->head
->next
= NULL
;
1172 static node_buffer_t
*
1173 rb_node_buffer_new(void)
1175 const size_t bucket_size
= offsetof(node_buffer_elem_t
, buf
) + NODE_BUF_DEFAULT_LEN
* sizeof(NODE
);
1176 const size_t alloc_size
= sizeof(node_buffer_t
) + (bucket_size
* 2);
1179 offsetof(node_buffer_elem_t
, buf
) + NODE_BUF_DEFAULT_LEN
* sizeof(NODE
)
1180 > sizeof(node_buffer_t
) + 2 * sizeof(node_buffer_elem_t
));
1181 node_buffer_t
*nb
= ruby_xmalloc(alloc_size
);
1182 init_node_buffer_list(&nb
->unmarkable
, (node_buffer_elem_t
*)&nb
[1]);
1183 init_node_buffer_list(&nb
->markable
, (node_buffer_elem_t
*)((size_t)nb
->unmarkable
.head
+ bucket_size
));
1184 nb
->local_tables
= 0;
1185 nb
->mark_hash
= Qnil
;
1190 node_buffer_list_free(node_buffer_list_t
* nb
)
1192 node_buffer_elem_t
*nbe
= nb
->head
;
1194 while (nbe
!= nb
->last
) {
1201 struct rb_ast_local_table_link
{
1202 struct rb_ast_local_table_link
*next
;
1203 // struct rb_ast_id_table {
1205 ID ids
[FLEX_ARY_LEN
];
1210 rb_node_buffer_free(node_buffer_t
*nb
)
1212 node_buffer_list_free(&nb
->unmarkable
);
1213 node_buffer_list_free(&nb
->markable
);
1214 struct rb_ast_local_table_link
*local_table
= nb
->local_tables
;
1215 while (local_table
) {
1216 struct rb_ast_local_table_link
*next_table
= local_table
->next
;
1218 local_table
= next_table
;
1224 ast_newnode_in_bucket(node_buffer_list_t
*nb
)
1226 if (nb
->idx
>= nb
->len
) {
1227 long n
= nb
->len
* 2;
1228 node_buffer_elem_t
*nbe
;
1229 nbe
= rb_xmalloc_mul_add(n
, sizeof(NODE
), offsetof(node_buffer_elem_t
, buf
));
1233 nbe
->next
= nb
->head
;
1236 return &nb
->head
->buf
[nb
->idx
++];
1241 nodetype_markable_p(enum node_type type
)
1262 rb_ast_newnode(rb_ast_t
*ast
, enum node_type type
)
1264 node_buffer_t
*nb
= ast
->node_buffer
;
1265 node_buffer_list_t
*bucket
=
1266 (nodetype_markable_p(type
) ? &nb
->markable
: &nb
->unmarkable
);
1267 return ast_newnode_in_bucket(bucket
);
1271 rb_ast_node_type_change(NODE
*n
, enum node_type type
)
1273 enum node_type old_type
= nd_type(n
);
1274 if (nodetype_markable_p(old_type
) != nodetype_markable_p(type
)) {
1275 rb_bug("node type changed: %s -> %s",
1276 ruby_node_name(old_type
), ruby_node_name(type
));
1281 rb_ast_new_local_table(rb_ast_t
*ast
, int size
)
1283 size_t alloc_size
= sizeof(struct rb_ast_local_table_link
) + size
* sizeof(ID
);
1284 struct rb_ast_local_table_link
*link
= ruby_xmalloc(alloc_size
);
1285 link
->next
= ast
->node_buffer
->local_tables
;
1286 ast
->node_buffer
->local_tables
= link
;
1289 return (rb_ast_id_table_t
*) &link
->size
;
1293 rb_ast_resize_latest_local_table(rb_ast_t
*ast
, int size
)
1295 struct rb_ast_local_table_link
*link
= ast
->node_buffer
->local_tables
;
1296 size_t alloc_size
= sizeof(struct rb_ast_local_table_link
) + size
* sizeof(ID
);
1297 link
= ruby_xrealloc(link
, alloc_size
);
1298 ast
->node_buffer
->local_tables
= link
;
1301 return (rb_ast_id_table_t
*) &link
->size
;
1305 rb_ast_delete_node(rb_ast_t
*ast
, NODE
*n
)
1309 /* should we implement freelist? */
1315 node_buffer_t
*nb
= rb_node_buffer_new();
1316 rb_ast_t
*ast
= (rb_ast_t
*)rb_imemo_new(imemo_ast
, 0, 0, 0, (VALUE
)nb
);
1320 typedef void node_itr_t(void *ctx
, NODE
* node
);
1323 iterate_buffer_elements(node_buffer_elem_t
*nbe
, long len
, node_itr_t
*func
, void *ctx
)
1326 for (cursor
= 0; cursor
< len
; cursor
++) {
1327 func(ctx
, &nbe
->buf
[cursor
]);
1332 iterate_node_values(node_buffer_list_t
*nb
, node_itr_t
* func
, void *ctx
)
1334 node_buffer_elem_t
*nbe
= nb
->head
;
1336 /* iterate over the head first because it's not full */
1337 iterate_buffer_elements(nbe
, nb
->idx
, func
, ctx
);
1341 iterate_buffer_elements(nbe
, nbe
->len
, func
, ctx
);
1347 mark_ast_value(void *ctx
, NODE
* node
)
1349 switch (nd_type(node
)) {
1352 struct rb_args_info
*args
= node
->nd_ainfo
;
1353 rb_gc_mark_movable(args
->imemo
);
1364 rb_gc_mark_movable(node
->nd_lit
);
1368 rb_gc_mark_movable(node
->nd_rval
);
1371 rb_bug("unreachable node %s", ruby_node_name(nd_type(node
)));
1376 update_ast_value(void *ctx
, NODE
* node
)
1378 switch (nd_type(node
)) {
1381 struct rb_args_info
*args
= node
->nd_ainfo
;
1382 args
->imemo
= rb_gc_location(args
->imemo
);
1393 node
->nd_lit
= rb_gc_location(node
->nd_lit
);
1397 node
->nd_rval
= rb_gc_location(node
->nd_rval
);
1400 rb_bug("unreachable");
1405 rb_ast_update_references(rb_ast_t
*ast
)
1407 if (ast
->node_buffer
) {
1408 node_buffer_t
*nb
= ast
->node_buffer
;
1410 iterate_node_values(&nb
->markable
, update_ast_value
, NULL
);
1415 rb_ast_mark(rb_ast_t
*ast
)
1417 if (ast
->node_buffer
) rb_gc_mark(ast
->node_buffer
->mark_hash
);
1418 if (ast
->body
.compile_option
) rb_gc_mark(ast
->body
.compile_option
);
1419 if (ast
->node_buffer
) {
1420 node_buffer_t
*nb
= ast
->node_buffer
;
1422 iterate_node_values(&nb
->markable
, mark_ast_value
, NULL
);
1424 if (ast
->body
.script_lines
) rb_gc_mark(ast
->body
.script_lines
);
1428 rb_ast_free(rb_ast_t
*ast
)
1430 if (ast
->node_buffer
) {
1431 rb_node_buffer_free(ast
->node_buffer
);
1432 ast
->node_buffer
= 0;
1437 buffer_list_size(node_buffer_list_t
*nb
)
1440 node_buffer_elem_t
*nbe
= nb
->head
;
1441 while (nbe
!= nb
->last
) {
1443 size
+= offsetof(node_buffer_elem_t
, buf
) + nb
->len
* sizeof(NODE
);
1449 rb_ast_memsize(const rb_ast_t
*ast
)
1452 node_buffer_t
*nb
= ast
->node_buffer
;
1455 size
+= sizeof(node_buffer_t
) + offsetof(node_buffer_elem_t
, buf
) + NODE_BUF_DEFAULT_LEN
* sizeof(NODE
);
1456 size
+= buffer_list_size(&nb
->unmarkable
);
1457 size
+= buffer_list_size(&nb
->markable
);
1463 rb_ast_dispose(rb_ast_t
*ast
)
1469 rb_ast_add_mark_object(rb_ast_t
*ast
, VALUE obj
)
1471 if (NIL_P(ast
->node_buffer
->mark_hash
)) {
1472 RB_OBJ_WRITE(ast
, &ast
->node_buffer
->mark_hash
, rb_ident_hash_new());
1474 rb_hash_aset(ast
->node_buffer
->mark_hash
, obj
, Qtrue
);