node.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   node.c - ruby node tree
00004 
00005   $Author: mame $
00006   created at: 09/12/06 21:23:44 JST
00007 
00008   Copyright (C) 2009 Yusuke Endoh
00009 
00010 **********************************************************************/
00011 
00012 #include "ruby/ruby.h"
00013 #include "vm_core.h"
00014 
00015 #define A(str) rb_str_cat2(buf, (str))
00016 #define AR(str) rb_str_concat(buf, (str))
00017 
00018 #define A_INDENT add_indent(buf, indent)
00019 #define A_ID(id) add_id(buf, (id))
00020 #define A_INT(val) rb_str_catf(buf, "%d", (val))
00021 #define A_LONG(val) rb_str_catf(buf, "%ld", (val))
00022 #define A_LIT(lit) AR(rb_inspect(lit))
00023 #define A_NODE_HEADER(node) \
00024     rb_str_catf(buf, "@ %s (line: %d)", ruby_node_name(nd_type(node)), nd_line(node))
00025 #define A_FIELD_HEADER(name) \
00026     rb_str_catf(buf, "+- %s:", (name))
00027 
00028 #define D_NULL_NODE A_INDENT; A("(null node)"); A("\n");
00029 #define D_NODE_HEADER(node) A_INDENT; A_NODE_HEADER(node); A("\n");
00030 
00031 #define COMPOUND_FIELD(name, name2, block) \
00032     do { \
00033         A_INDENT; A_FIELD_HEADER(comment ? (name2) : (name)); A("\n"); \
00034         rb_str_cat2(indent, next_indent); \
00035         block; \
00036         rb_str_resize(indent, RSTRING_LEN(indent) - 4); \
00037     } while (0)
00038 
00039 #define SIMPLE_FIELD(name, name2, block) \
00040     do { \
00041         A_INDENT; A_FIELD_HEADER(comment ? (name2) : (name)); A(" "); block; A("\n"); \
00042     } while (0)
00043 
00044 #define F_CUSTOM1(name, ann, block) SIMPLE_FIELD(#name, #name " (" ann ")", block)
00045 #define F_ID(name, ann)             SIMPLE_FIELD(#name, #name " (" ann ")", A_ID(node->name))
00046 #define F_GENTRY(name, ann)         SIMPLE_FIELD(#name, #name " (" ann ")", A_ID((node->name)->id))
00047 #define F_INT(name, ann)            SIMPLE_FIELD(#name, #name " (" ann ")", A_INT(node->name))
00048 #define F_LONG(name, ann)           SIMPLE_FIELD(#name, #name " (" ann ")", A_LONG(node->name))
00049 #define F_LIT(name, ann)            SIMPLE_FIELD(#name, #name " (" ann ")", A_LIT(node->name))
00050 #define F_MSG(name, ann, desc)      SIMPLE_FIELD(#name, #name " (" ann ")", A(desc))
00051 
00052 #define F_CUSTOM2(name, ann, block) \
00053     COMPOUND_FIELD(#name, #name " (" ann ")", block)
00054 
00055 #define F_NODE(name, ann) \
00056     COMPOUND_FIELD(#name, #name " (" ann ")", dump_node(buf, indent, comment, node->name))
00057 
00058 #define ANN(ann) \
00059     if (comment) { \
00060         A_INDENT; A("| # "); A(ann); A("\n"); \
00061     }
00062 
00063 #define LAST_NODE (next_indent = "    ")
00064 
00065 static void
00066 add_indent(VALUE buf, VALUE indent)
00067 {
00068     AR(indent);
00069 }
00070 
00071 static void
00072 add_id(VALUE buf, ID id)
00073 {
00074     if (id == 0) {
00075         A("(null)");
00076     }
00077     else {
00078         VALUE str = rb_id2str(id);
00079         if (str) {
00080             A(":"); AR(str);
00081         }
00082         else {
00083             A("(internal variable)");
00084         }
00085     }
00086 }
00087 
00088 static void
00089 dump_node(VALUE buf, VALUE indent, int comment, NODE *node)
00090 {
00091     const char *next_indent = "|   ";
00092 
00093     if (!node) {
00094         D_NULL_NODE;
00095         return;
00096     }
00097 
00098     D_NODE_HEADER(node);
00099 
00100     switch (nd_type(node)) {
00101       case NODE_BLOCK:
00102         ANN("statement sequence");
00103         ANN("format: [nd_head]; [nd_next]");
00104         ANN("example: foo; bar");
00105         F_NODE(nd_head, "current statement");
00106         LAST_NODE;
00107         F_NODE(nd_next, "next block");
00108         break;
00109 
00110       case NODE_IF:
00111         ANN("if statement");
00112         ANN("format: if [nd_cond] then [nd_body] else [nd_else] end");
00113         ANN("example: if x == 1 then foo else bar end");
00114         F_NODE(nd_cond, "condition expr");
00115         F_NODE(nd_body, "then clause");
00116         LAST_NODE;
00117         F_NODE(nd_else, "else clause");
00118         break;
00119 
00120       case NODE_CASE:
00121         ANN("case statement");
00122         ANN("format: case [nd_head]; [nd_body]; end");
00123         ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
00124         F_NODE(nd_head, "case expr");
00125         LAST_NODE;
00126         F_NODE(nd_body, "when clauses");
00127         break;
00128 
00129       case NODE_WHEN:
00130         ANN("if statement");
00131         ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
00132         ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
00133         F_NODE(nd_head, "when value");
00134         F_NODE(nd_body, "when clause");
00135         LAST_NODE;
00136         F_NODE(nd_next, "next when clause");
00137         break;
00138 
00139       case NODE_OPT_N:
00140         ANN("wrapper for -n option");
00141         ANN("format: ruby -ne '[nd_body]' (nd_cond is `gets')");
00142         ANN("example: ruby -ne 'p $_'");
00143         goto loop;
00144       case NODE_WHILE:
00145         ANN("while statement");
00146         ANN("format: while [nd_cond]; [nd_body]; end");
00147         ANN("example: while x == 1; foo; end");
00148         goto loop;
00149       case NODE_UNTIL:
00150         ANN("until statement");
00151         ANN("format: until [nd_cond]; [nd_body]; end");
00152         ANN("example: until x == 1; foo; end");
00153       loop:
00154         F_CUSTOM1(nd_state, "begin-end-while?", {
00155            A_INT((int)node->nd_state);
00156            A((node->nd_state == 1) ? " (while-end)" : " (begin-end-while)");
00157         });
00158         F_NODE(nd_cond, "condition");
00159         LAST_NODE;
00160         F_NODE(nd_body, "body");
00161         break;
00162 
00163       case NODE_ITER:
00164         ANN("method call with block");
00165         ANN("format: [nd_iter] { [nd_body] }");
00166         ANN("example: 3.times { foo }");
00167         goto iter;
00168       case NODE_FOR:
00169         ANN("for statement");
00170         ANN("format: for * in [nd_iter] do [nd_body] end");
00171         ANN("example: for i in 1..3 do foo end");
00172         iter:
00173         F_NODE(nd_iter, "iteration receiver");
00174         LAST_NODE;
00175         F_NODE(nd_body, "body");
00176         break;
00177 
00178       case NODE_BREAK:
00179         ANN("for statement");
00180         ANN("format: break [nd_stts]");
00181         ANN("example: break 1");
00182         goto jump;
00183       case NODE_NEXT:
00184         ANN("next statement");
00185         ANN("format: next [nd_stts]");
00186         ANN("example: next 1");
00187         goto jump;
00188       case NODE_RETURN:
00189         ANN("return statement");
00190         ANN("format: return [nd_stts]");
00191         ANN("example: return 1");
00192         jump:
00193         LAST_NODE;
00194         F_NODE(nd_stts, "value");
00195         break;
00196 
00197       case NODE_REDO:
00198         ANN("redo statement");
00199         ANN("format: redo");
00200         ANN("example: redo");
00201         break;
00202 
00203       case NODE_RETRY:
00204         ANN("retry statement");
00205         ANN("format: retry");
00206         ANN("example: retry");
00207         break;
00208 
00209       case NODE_BEGIN:
00210         ANN("begin statement");
00211         ANN("format: begin; [nd_body]; end");
00212         ANN("example: begin; 1; end");
00213         LAST_NODE;
00214         F_NODE(nd_body, "body");
00215         break;
00216 
00217       case NODE_RESCUE:
00218         ANN("rescue clause");
00219         ANN("format: begin; [nd_body]; (rescue) [nd_resq]; else [nd_else]; end");
00220         ANN("example: begin; foo; rescue; bar; else; baz; end");
00221         F_NODE(nd_head, "body");
00222         F_NODE(nd_resq, "rescue clause list");
00223         LAST_NODE;
00224         F_NODE(nd_else, "rescue else clause");
00225         break;
00226 
00227       case NODE_RESBODY:
00228         ANN("rescue clause (cont'd)");
00229         ANN("format: rescue [nd_args]; [nd_body]; (rescue) [nd_head]");
00230         ANN("example: begin; foo; rescue; bar; else; baz; end");
00231         F_NODE(nd_args, "rescue exceptions");
00232         F_NODE(nd_body, "rescue clause");
00233         LAST_NODE;
00234         F_NODE(nd_head, "next rescue clause");
00235         break;
00236 
00237       case NODE_ENSURE:
00238         ANN("ensure clause");
00239         ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
00240         ANN("example: begin; foo; ensure; bar; end");
00241         F_NODE(nd_head, "body");
00242         LAST_NODE;
00243         F_NODE(nd_ensr, "ensure clause");
00244         break;
00245 
00246       case NODE_AND:
00247         ANN("&& operator");
00248         ANN("format: [nd_1st] && [nd_2nd]");
00249         ANN("example: foo && bar");
00250         goto andor;
00251       case NODE_OR:
00252         ANN("|| operator");
00253         ANN("format: [nd_1st] || [nd_2nd]");
00254         ANN("example: foo && bar");
00255         andor:
00256         F_NODE(nd_1st, "left expr");
00257         LAST_NODE;
00258         F_NODE(nd_2nd, "right expr");
00259         break;
00260 
00261       case NODE_MASGN:
00262         ANN("multiple assignment");
00263         ANN("format: [nd_head], [nd_args] = [nd_value]");
00264         ANN("example: a, b = foo");
00265         F_NODE(nd_value, "rhsn");
00266         F_NODE(nd_head, "lhsn");
00267         if ((VALUE)node->nd_args != (VALUE)-1) {
00268             LAST_NODE;
00269             F_NODE(nd_args, "splatn");
00270         }
00271         else {
00272             F_MSG(nd_args, "splatn", "-1 (rest argument without name)");
00273         }
00274         break;
00275 
00276       case NODE_LASGN:
00277         ANN("local variable assignment");
00278         ANN("format: [nd_vid](lvar) = [nd_value]");
00279         ANN("example: x = foo");
00280         goto asgn;
00281       case NODE_DASGN:
00282         ANN("dynamic variable assignment (out of current scope)");
00283         ANN("format: [nd_vid](dvar) = [nd_value]");
00284         ANN("example: x = nil; 1.times { x = foo }");
00285         goto asgn;
00286       case NODE_DASGN_CURR:
00287         ANN("dynamic variable assignment (in current scope)");
00288         ANN("format: [nd_vid](current dvar) = [nd_value]");
00289         ANN("example: 1.times { x = foo }");
00290         goto asgn;
00291       case NODE_IASGN:
00292         ANN("instance variable assignment");
00293         ANN("format: [nd_vid](ivar) = [nd_value]");
00294         ANN("example: @x = foo");
00295         goto asgn;
00296       case NODE_CVASGN:
00297         ANN("class variable assignment");
00298         ANN("format: [nd_vid](cvar) = [nd_value]");
00299         ANN("example: @@x = foo");
00300         asgn:
00301         F_ID(nd_vid, "variable");
00302         LAST_NODE;
00303         if (node->nd_value == (NODE *)-1) {
00304             F_MSG(nd_value, "rvalue", "(required keyword argument)");
00305         }
00306         else {
00307             F_NODE(nd_value, "rvalue");
00308         }
00309         break;
00310 
00311       case NODE_GASGN:
00312         ANN("global variable assignment");
00313         ANN("format: [nd_entry](gvar) = [nd_value]");
00314         ANN("example: $x = foo");
00315         F_GENTRY(nd_entry, "global variable");
00316         LAST_NODE;
00317         F_NODE(nd_value, "rvalue");
00318         break;
00319 
00320       case NODE_CDECL:
00321         ANN("constant declaration");
00322         ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
00323         ANN("example: X = foo");
00324         if (node->nd_vid) {
00325            F_ID(nd_vid, "variable");
00326            F_MSG(nd_else, "extension", "not used");
00327         }
00328         else {
00329            F_MSG(nd_vid, "variable", "0 (see extension field)");
00330            F_NODE(nd_else, "extension");
00331         }
00332         LAST_NODE;
00333         F_NODE(nd_value, "rvalue");
00334         break;
00335 
00336       case NODE_OP_ASGN1:
00337         ANN("array assignment with operator");
00338         ANN("format: [nd_value] [ [nd_args->nd_body] ] [nd_vid]= [nd_args->nd_head]");
00339         ANN("example: ary[1] += foo");
00340         F_NODE(nd_recv, "receiver");
00341         F_ID(nd_vid, "operator");
00342         F_NODE(nd_args->nd_body, "index");
00343         LAST_NODE;
00344         F_NODE(nd_args->nd_head, "rvalue");
00345         break;
00346 
00347       case NODE_OP_ASGN2:
00348         ANN("attr assignment with operator");
00349         ANN("format: [nd_value].[attr] [nd_next->nd_mid]= [nd_value]");
00350         ANN("          where [attr] reader: [nd_next->nd_vid]");
00351         ANN("                [attr] writer: [nd_next->nd_aid]");
00352         ANN("example: struct.field += foo");
00353         F_NODE(nd_recv, "receiver");
00354         F_ID(nd_next->nd_vid, "reader");
00355         F_ID(nd_next->nd_aid, "writer");
00356         F_CUSTOM1(nd_next->nd_mid, "operator", {
00357            switch (node->nd_next->nd_mid) {
00358            case 0: A("0 (||)"); break;
00359            case 1: A("1 (&&)"); break;
00360            default: A_ID(node->nd_next->nd_mid);
00361            }
00362         });
00363         LAST_NODE;
00364         F_NODE(nd_value, "rvalue");
00365         break;
00366 
00367       case NODE_OP_ASGN_AND:
00368         ANN("assignment with && operator");
00369         ANN("format: [nd_head] &&= [nd_value]");
00370         ANN("example: foo &&= bar");
00371         goto asgn_andor;
00372       case NODE_OP_ASGN_OR:
00373         ANN("assignment with || operator");
00374         ANN("format: [nd_head] ||= [nd_value]");
00375         ANN("example: foo ||= bar");
00376         asgn_andor:
00377         F_NODE(nd_head, "variable");
00378         LAST_NODE;
00379         F_NODE(nd_value, "rvalue");
00380         break;
00381 
00382       case NODE_CALL:
00383         ANN("method invocation");
00384         ANN("format: [nd_recv].[nd_mid]([nd_args])");
00385         ANN("example: obj.foo(1)");
00386         F_ID(nd_mid, "method id");
00387         F_NODE(nd_recv, "receiver");
00388         LAST_NODE;
00389         F_NODE(nd_args, "arguments");
00390         break;
00391 
00392       case NODE_FCALL:
00393         ANN("function call");
00394         ANN("format: [nd_mid]([nd_args])");
00395         ANN("example: foo(1)");
00396         F_ID(nd_mid, "method id");
00397         LAST_NODE;
00398         F_NODE(nd_args, "arguments");
00399         break;
00400 
00401       case NODE_VCALL:
00402         ANN("function call with no argument");
00403         ANN("format: [nd_mid]");
00404         ANN("example: foo");
00405         F_ID(nd_mid, "method id");
00406         break;
00407 
00408       case NODE_SUPER:
00409         ANN("super invocation");
00410         ANN("format: super [nd_args]");
00411         ANN("example: super 1");
00412         LAST_NODE;
00413         F_NODE(nd_args, "arguments");
00414         break;
00415 
00416       case NODE_ZSUPER:
00417         ANN("super invocation with no argument");
00418         ANN("format: super");
00419         ANN("example: super");
00420         break;
00421 
00422       case NODE_ARRAY:
00423         ANN("array constructor");
00424         ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
00425         ANN("example: [1, 2, 3]");
00426         goto ary;
00427       case NODE_VALUES:
00428         ANN("return arguments");
00429         ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
00430         ANN("example: return 1, 2, 3");
00431         ary:
00432         F_LONG(nd_alen, "length");
00433         F_NODE(nd_head, "element");
00434         LAST_NODE;
00435         F_NODE(nd_next, "next element");
00436         break;
00437 
00438       case NODE_ZARRAY:
00439         ANN("empty array constructor");
00440         ANN("format: []");
00441         ANN("example: []");
00442         break;
00443 
00444       case NODE_HASH:
00445         ANN("hash constructor");
00446         ANN("format: { [nd_head] }");
00447         ANN("example: { 1 => 2, 3 => 4 }");
00448         LAST_NODE;
00449         F_NODE(nd_head, "contents");
00450         break;
00451 
00452       case NODE_YIELD:
00453         ANN("yield invocation");
00454         ANN("format: yield [nd_head]");
00455         ANN("example: yield 1");
00456         LAST_NODE;
00457         F_NODE(nd_head, "arguments");
00458         break;
00459 
00460       case NODE_LVAR:
00461         ANN("local variable reference");
00462         ANN("format: [nd_vid](lvar)");
00463         ANN("example: x");
00464         goto var;
00465       case NODE_DVAR:
00466         ANN("dynamic variable reference");
00467         ANN("format: [nd_vid](dvar)");
00468         ANN("example: 1.times { x = 1; x }");
00469         goto var;
00470       case NODE_IVAR:
00471         ANN("instance variable reference");
00472         ANN("format: [nd_vid](ivar)");
00473         ANN("example: @x");
00474         goto var;
00475       case NODE_CONST:
00476         ANN("constant reference");
00477         ANN("format: [nd_vid](constant)");
00478         ANN("example: X");
00479         goto var;
00480       case NODE_CVAR:
00481         ANN("class variable reference");
00482         ANN("format: [nd_vid](cvar)");
00483         ANN("example: @@x");
00484         var:
00485         F_ID(nd_vid, "local variable");
00486         break;
00487 
00488       case NODE_GVAR:
00489         ANN("global variable reference");
00490         ANN("format: [nd_entry](gvar)");
00491         ANN("example: $x");
00492         F_GENTRY(nd_entry, "global variable");
00493         break;
00494 
00495       case NODE_NTH_REF:
00496         ANN("nth special variable reference");
00497         ANN("format: $[nd_nth]");
00498         ANN("example: $1, $2, ..");
00499         F_CUSTOM1(nd_nth, "variable", { A("$"); A_LONG(node->nd_nth); });
00500         break;
00501 
00502       case NODE_BACK_REF:
00503         ANN("back special variable reference");
00504         ANN("format: $[nd_nth]");
00505         ANN("example: $&, $`, $', $+");
00506         F_CUSTOM1(nd_nth, "variable", {
00507            char name[3];
00508            name[0] = '$';
00509            name[1] = (char)node->nd_nth;
00510            name[2] = '\0';
00511            A(name);
00512         });
00513         break;
00514 
00515       case NODE_MATCH:
00516         ANN("match expression (against $_ implicitly)");
00517         ANN("format: [nd_lit] (in condition)");
00518         ANN("example: if /foo/; foo; end");
00519         F_LIT(nd_lit, "regexp");
00520         break;
00521 
00522       case NODE_MATCH2:
00523         ANN("match expression (regexp first)");
00524         ANN("format: [nd_recv] =~ [nd_value]");
00525         ANN("example: /foo/ =~ 'foo'");
00526         F_NODE(nd_recv, "regexp (receiver)");
00527         LAST_NODE;
00528         F_NODE(nd_value, "string (argument)");
00529         break;
00530 
00531       case NODE_MATCH3:
00532         ANN("match expression (regexp second)");
00533         ANN("format: [nd_recv] =~ [nd_value]");
00534         ANN("example: 'foo' =~ /foo/");
00535         F_NODE(nd_recv, "string (receiver)");
00536         LAST_NODE;
00537         F_NODE(nd_value, "regexp (argument)");
00538         break;
00539 
00540       case NODE_LIT:
00541         ANN("literal");
00542         ANN("format: [nd_lit]");
00543         ANN("example: 1, /foo/");
00544         goto lit;
00545       case NODE_STR:
00546         ANN("string literal");
00547         ANN("format: [nd_lit]");
00548         ANN("example: 'foo'");
00549         goto lit;
00550       case NODE_XSTR:
00551         ANN("xstring literal");
00552         ANN("format: [nd_lit]");
00553         ANN("example: `foo`");
00554         lit:
00555         F_LIT(nd_lit, "literal");
00556         break;
00557 
00558       case NODE_DSTR:
00559         ANN("string literal with interpolation");
00560         ANN("format: [nd_lit]");
00561         ANN("example: \"foo#{ bar }baz\"");
00562         goto dlit;
00563       case NODE_DXSTR:
00564         ANN("xstring literal with interpolation");
00565         ANN("format: [nd_lit]");
00566         ANN("example: `foo#{ bar }baz`");
00567         goto dlit;
00568       case NODE_DREGX:
00569         ANN("regexp literal with interpolation");
00570         ANN("format: [nd_lit]");
00571         ANN("example: /foo#{ bar }baz/");
00572         goto dlit;
00573       case NODE_DREGX_ONCE:
00574         ANN("regexp literal with interpolation and once flag");
00575         ANN("format: [nd_lit]");
00576         ANN("example: /foo#{ bar }baz/o");
00577         goto dlit;
00578       case NODE_DSYM:
00579         ANN("symbol literal with interpolation");
00580         ANN("format: [nd_lit]");
00581         ANN("example: :\"foo#{ bar }baz\"");
00582         dlit:
00583         F_LIT(nd_lit, "literal");
00584         F_NODE(nd_next->nd_head, "preceding string");
00585         LAST_NODE;
00586         F_NODE(nd_next->nd_next, "interpolation");
00587         break;
00588 
00589       case NODE_EVSTR:
00590         ANN("interpolation expression");
00591         ANN("format: \"..#{ [nd_lit] }..\"");
00592         ANN("example: \"foo#{ bar }baz\"");
00593         LAST_NODE;
00594         F_NODE(nd_body, "body");
00595         break;
00596 
00597       case NODE_ARGSCAT:
00598         ANN("splat argument following arguments");
00599         ANN("format: ..(*[nd_head], [nd_body..])");
00600         ANN("example: foo(*ary, post_arg1, post_arg2)");
00601         F_NODE(nd_head, "preceding array");
00602         LAST_NODE;
00603         F_NODE(nd_body, "following array");
00604         break;
00605 
00606       case NODE_ARGSPUSH:
00607         ANN("splat argument following one argument");
00608         ANN("format: ..(*[nd_head], [nd_body])");
00609         ANN("example: foo(*ary, post_arg)");
00610         F_NODE(nd_head, "preceding array");
00611         LAST_NODE;
00612         F_NODE(nd_body, "following element");
00613         break;
00614 
00615       case NODE_SPLAT:
00616         ANN("splat argument");
00617         ANN("format: *[nd_head]");
00618         ANN("example: foo(*ary)");
00619         LAST_NODE;
00620         F_NODE(nd_head, "splat'ed array");
00621         break;
00622 
00623       case NODE_BLOCK_PASS:
00624         ANN("arguments with block argument");
00625         ANN("format: ..([nd_head], &[nd_body])");
00626         ANN("example: foo(x, &blk)");
00627         F_NODE(nd_head, "other arguments");
00628         LAST_NODE;
00629         F_NODE(nd_body, "block argument");
00630         break;
00631 
00632       case NODE_DEFN:
00633         ANN("method definition");
00634         ANN("format: def [nd_mid] [nd_defn]; end");
00635         ANN("example; def foo; bar; end");
00636         F_ID(nd_mid, "method name");
00637         LAST_NODE;
00638         F_NODE(nd_defn, "method definition");
00639         break;
00640 
00641       case NODE_DEFS:
00642         ANN("singleton method definition");
00643         ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
00644         ANN("example; def obj.foo; bar; end");
00645         F_NODE(nd_recv, "receiver");
00646         F_ID(nd_mid, "method name");
00647         LAST_NODE;
00648         F_NODE(nd_defn, "method definition");
00649         break;
00650 
00651       case NODE_ALIAS:
00652         ANN("method alias statement");
00653         ANN("format: alias [u1.node] [u2.node]");
00654         ANN("example: alias bar foo");
00655         F_NODE(u1.node, "new name");
00656         LAST_NODE;
00657         F_NODE(u2.node, "old name");
00658         break;
00659 
00660       case NODE_VALIAS:
00661         ANN("global variable alias statement");
00662         ANN("format: alias [u1.id](gvar) [u2.id](gvar)");
00663         ANN("example: alias $y $x");
00664         F_ID(u1.id, "new name");
00665         F_ID(u2.id, "old name");
00666         break;
00667 
00668       case NODE_UNDEF:
00669         ANN("method alias statement");
00670         ANN("format: undef [u2.node]");
00671         ANN("example: undef foo");
00672         LAST_NODE;
00673         F_NODE(u2.node, "old name");
00674         break;
00675 
00676       case NODE_CLASS:
00677         ANN("class definition");
00678         ANN("format: class [nd_cpath] < [nd_super]; [nd_body]; end");
00679         ANN("example: class C2 < C; ..; end");
00680         F_NODE(nd_cpath, "class path");
00681         F_NODE(nd_super, "superclass");
00682         LAST_NODE;
00683         F_NODE(nd_body, "class definition");
00684         break;
00685 
00686       case NODE_MODULE:
00687         ANN("module definition");
00688         ANN("format: module [nd_cpath]; [nd_body]; end");
00689         ANN("example: module M; ..; end");
00690         F_NODE(nd_cpath, "module path");
00691         LAST_NODE;
00692         F_NODE(nd_body, "module definition");
00693         break;
00694 
00695       case NODE_SCLASS:
00696         ANN("singleton class definition");
00697         ANN("format: class << [nd_recv]; [nd_body]; end");
00698         ANN("example: class << obj; ..; end");
00699         F_NODE(nd_recv, "receiver");
00700         LAST_NODE;
00701         F_NODE(nd_body, "singleton class definition");
00702         break;
00703 
00704       case NODE_COLON2:
00705         ANN("scoped constant reference");
00706         ANN("format: [nd_head]::[nd_mid]");
00707         ANN("example: M::C");
00708         F_ID(nd_mid, "constant name");
00709         LAST_NODE;
00710         F_NODE(nd_head, "receiver");
00711         break;
00712 
00713       case NODE_COLON3:
00714         ANN("top-level constant reference");
00715         ANN("format: ::[nd_mid]");
00716         ANN("example: ::Object");
00717         F_ID(nd_mid, "constant name");
00718         break;
00719 
00720       case NODE_DOT2:
00721         ANN("range constructor (incl.)");
00722         ANN("format: [nd_beg]..[nd_end]");
00723         ANN("example: 1..5");
00724         goto dot;
00725       case NODE_DOT3:
00726         ANN("range constructor (excl.)");
00727         ANN("format: [nd_beg]...[nd_end]");
00728         ANN("example: 1...5");
00729         goto dot;
00730       case NODE_FLIP2:
00731         ANN("flip-flop condition (incl.)");
00732         ANN("format: [nd_beg]..[nd_end]");
00733         ANN("example: if (x==1)..(x==5); foo; end");
00734         goto dot;
00735       case NODE_FLIP3:
00736         ANN("flip-flop condition (excl.)");
00737         ANN("format: [nd_beg]...[nd_end]");
00738         ANN("example: if (x==1)...(x==5); foo; end");
00739         dot:
00740         F_NODE(nd_beg, "begin");
00741         LAST_NODE;
00742         F_NODE(nd_end, "end");
00743         break;
00744 
00745       case NODE_SELF:
00746         ANN("self");
00747         ANN("format: self");
00748         ANN("example: self");
00749         break;
00750 
00751       case NODE_NIL:
00752         ANN("nil");
00753         ANN("format: nil");
00754         ANN("example: nil");
00755         break;
00756 
00757       case NODE_TRUE:
00758         ANN("true");
00759         ANN("format: true");
00760         ANN("example: true");
00761         break;
00762 
00763       case NODE_FALSE:
00764         ANN("false");
00765         ANN("format: false");
00766         ANN("example: false");
00767         break;
00768 
00769       case NODE_ERRINFO:
00770         ANN("virtual reference to $!");
00771         ANN("format: rescue => id");
00772         ANN("example: rescue => id");
00773         break;
00774 
00775       case NODE_DEFINED:
00776         ANN("defined? expression");
00777         ANN("format: defined?([nd_head])");
00778         ANN("example: defined?(foo)");
00779         F_NODE(nd_head, "expr");
00780         break;
00781 
00782       case NODE_POSTEXE:
00783         ANN("post-execution");
00784         ANN("format: END { [nd_body] }");
00785         ANN("example: END { foo }");
00786         LAST_NODE;
00787         F_NODE(nd_body, "END clause");
00788         break;
00789 
00790       case NODE_ATTRASGN:
00791         ANN("attr assignment");
00792         ANN("format: [nd_recv].[nd_mid] = [nd_args]");
00793         ANN("example: struct.field = foo");
00794         if (node->nd_recv == (NODE *) 1) {
00795             F_MSG(nd_recv, "receiver", "1 (self)");
00796         }
00797         else {
00798             F_NODE(nd_recv, "receiver");
00799         }
00800         F_ID(nd_mid, "method name");
00801         LAST_NODE;
00802         F_NODE(nd_args, "arguments");
00803         break;
00804 
00805       case NODE_PRELUDE:
00806         ANN("pre-execution");
00807         ANN("format: BEGIN { [nd_head] }; [nd_body]");
00808         ANN("example: bar; BEGIN { foo }");
00809         F_NODE(nd_head, "prelude");
00810         LAST_NODE;
00811         F_NODE(nd_body, "body");
00812         break;
00813 
00814       case NODE_LAMBDA:
00815         ANN("lambda expression");
00816         ANN("format: -> [nd_body]");
00817         ANN("example: -> { foo }");
00818         LAST_NODE;
00819         F_NODE(nd_body, "lambda clause");
00820         break;
00821 
00822       case NODE_OPT_ARG:
00823         ANN("optional arguments");
00824         ANN("format: def method_name([nd_body=some], [nd_next..])");
00825         ANN("example: def foo(a, b=1, c); end");
00826         F_NODE(nd_body, "body");
00827         LAST_NODE;
00828         F_NODE(nd_next, "next");
00829         break;
00830 
00831       case NODE_KW_ARG:
00832         ANN("keyword arguments");
00833         ANN("format: def method_name([nd_body=some], [nd_next..])");
00834         ANN("example: def foo(a:1, b:2); end");
00835         F_NODE(nd_body, "body");
00836         LAST_NODE;
00837         F_NODE(nd_next, "next");
00838         break;
00839 
00840       case NODE_POSTARG:
00841         ANN("post arguments");
00842         ANN("format: *[nd_1st], [nd_2nd..] = ..");
00843         ANN("example: a, *rest, z = foo");
00844         if ((VALUE)node->nd_1st != (VALUE)-1) {
00845             F_NODE(nd_1st, "rest argument");
00846         }
00847         else {
00848             F_MSG(nd_1st, "rest argument", "-1 (rest argument without name)");
00849         }
00850         LAST_NODE;
00851         F_NODE(nd_2nd, "post arguments");
00852         break;
00853 
00854       case NODE_ARGS:
00855         ANN("method parameters");
00856         ANN("format: def method_name(.., [nd_opt=some], *[nd_rest], [nd_pid], .., &[nd_body])");
00857         ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, &blk); end");
00858         F_INT(nd_ainfo->pre_args_num, "count of mandatory (pre-)arguments");
00859         F_NODE(nd_ainfo->pre_init, "initialization of (pre-)arguments");
00860         F_INT(nd_ainfo->post_args_num, "count of mandatory post-arguments");
00861         F_NODE(nd_ainfo->post_init, "initialization of post-arguments");
00862         F_ID(nd_ainfo->first_post_arg, "first post argument");
00863         F_ID(nd_ainfo->rest_arg, "rest argument");
00864         F_ID(nd_ainfo->block_arg, "block argument");
00865         F_NODE(nd_ainfo->opt_args, "optional arguments");
00866         LAST_NODE;
00867         F_NODE(nd_ainfo->kw_args, "keyword arguments");
00868         F_NODE(nd_ainfo->kw_rest_arg, "keyword rest argument");
00869         break;
00870 
00871       case NODE_SCOPE:
00872         ANN("new scope");
00873         ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
00874         F_CUSTOM1(nd_tbl, "local table", {
00875            ID *tbl = node->nd_tbl;
00876            int i;
00877            int size = tbl ? (int)*tbl++ : 0;
00878            if (size == 0) A("(empty)");
00879            for (i = 0; i < size; i++) {
00880                 A_ID(tbl[i]); if (i < size - 1) A(",");
00881            }
00882         });
00883         F_NODE(nd_args, "arguments");
00884         LAST_NODE;
00885         F_NODE(nd_body, "body");
00886         break;
00887 
00888       default:
00889         rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
00890     }
00891 }
00892 
00893 VALUE
00894 rb_parser_dump_tree(NODE *node, int comment)
00895 {
00896     VALUE buf = rb_str_new_cstr(
00897         "###########################################################\n"
00898         "## Do NOT use this node dump for any purpose other than  ##\n"
00899         "## debug and research.  Compatibility is not guaranteed. ##\n"
00900         "###########################################################\n\n"
00901     );
00902     dump_node(buf, rb_str_new_cstr("# "), comment, node);
00903     return buf;
00904 }
00905 

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7