1 /* indent-tabs-mode: nil */
3 #include "internal/ruby_parser.h"
4 #include "internal/symbol.h"
5 #include "internal/warnings.h"
9 #include "ruby/encoding.h"
10 #include "ruby/util.h"
16 static VALUE rb_cNode
;
24 node_gc_mark(void *ptr
)
26 struct ASTNodeData
*data
= (struct ASTNodeData
*)ptr
;
27 rb_gc_mark(data
->ast_value
);
31 node_memsize(const void *ptr
)
33 struct ASTNodeData
*data
= (struct ASTNodeData
*)ptr
;
34 rb_ast_t
*ast
= rb_ruby_ast_data_get(data
->ast_value
);
36 return sizeof(struct ASTNodeData
) + rb_ast_memsize(ast
);
39 static const rb_data_type_t rb_node_type
= {
41 {node_gc_mark
, RUBY_TYPED_DEFAULT_FREE
, node_memsize
,},
43 RUBY_TYPED_FREE_IMMEDIATELY
,
46 static VALUE
rb_ast_node_alloc(VALUE klass
);
49 setup_node(VALUE obj
, VALUE ast_value
, const NODE
*node
)
51 struct ASTNodeData
*data
;
53 TypedData_Get_Struct(obj
, struct ASTNodeData
, &rb_node_type
, data
);
54 data
->ast_value
= ast_value
;
59 ast_new_internal(VALUE ast_value
, const NODE
*node
)
63 obj
= rb_ast_node_alloc(rb_cNode
);
64 setup_node(obj
, ast_value
, node
);
69 static VALUE
rb_ast_parse_str(VALUE str
, VALUE keep_script_lines
, VALUE error_tolerant
, VALUE keep_tokens
);
70 static VALUE
rb_ast_parse_file(VALUE path
, VALUE keep_script_lines
, VALUE error_tolerant
, VALUE keep_tokens
);
75 return rb_parser_set_context(rb_parser_new(), NULL
, 0);
79 ast_parse_done(VALUE ast_value
)
81 rb_ast_t
*ast
= rb_ruby_ast_data_get(ast_value
);
83 if (!ast
->body
.root
) {
85 rb_exc_raise(GET_EC()->errinfo
);
88 return ast_new_internal(ast_value
, (NODE
*)ast
->body
.root
);
92 ast_s_parse(rb_execution_context_t
*ec
, VALUE module
, VALUE str
, VALUE keep_script_lines
, VALUE error_tolerant
, VALUE keep_tokens
)
94 return rb_ast_parse_str(str
, keep_script_lines
, error_tolerant
, keep_tokens
);
98 rb_ast_parse_str(VALUE str
, VALUE keep_script_lines
, VALUE error_tolerant
, VALUE keep_tokens
)
103 VALUE vparser
= ast_parse_new();
104 if (RTEST(keep_script_lines
)) rb_parser_set_script_lines(vparser
);
105 if (RTEST(error_tolerant
)) rb_parser_error_tolerant(vparser
);
106 if (RTEST(keep_tokens
)) rb_parser_keep_tokens(vparser
);
107 ast_value
= rb_parser_compile_string_path(vparser
, Qnil
, str
, 1);
108 return ast_parse_done(ast_value
);
112 ast_s_parse_file(rb_execution_context_t
*ec
, VALUE module
, VALUE path
, VALUE keep_script_lines
, VALUE error_tolerant
, VALUE keep_tokens
)
114 return rb_ast_parse_file(path
, keep_script_lines
, error_tolerant
, keep_tokens
);
118 rb_ast_parse_file(VALUE path
, VALUE keep_script_lines
, VALUE error_tolerant
, VALUE keep_tokens
)
121 VALUE ast_value
= Qnil
;
122 rb_encoding
*enc
= rb_utf8_encoding();
124 f
= rb_file_open_str(path
, "r");
125 rb_funcall(f
, rb_intern("set_encoding"), 2, rb_enc_from_encoding(enc
), rb_str_new_cstr("-"));
126 VALUE vparser
= ast_parse_new();
127 if (RTEST(keep_script_lines
)) rb_parser_set_script_lines(vparser
);
128 if (RTEST(error_tolerant
)) rb_parser_error_tolerant(vparser
);
129 if (RTEST(keep_tokens
)) rb_parser_keep_tokens(vparser
);
130 ast_value
= rb_parser_compile_file_path(vparser
, Qnil
, f
, 1);
132 return ast_parse_done(ast_value
);
136 rb_ast_parse_array(VALUE array
, VALUE keep_script_lines
, VALUE error_tolerant
, VALUE keep_tokens
)
138 VALUE ast_value
= Qnil
;
140 array
= rb_check_array_type(array
);
141 VALUE vparser
= ast_parse_new();
142 if (RTEST(keep_script_lines
)) rb_parser_set_script_lines(vparser
);
143 if (RTEST(error_tolerant
)) rb_parser_error_tolerant(vparser
);
144 if (RTEST(keep_tokens
)) rb_parser_keep_tokens(vparser
);
145 ast_value
= rb_parser_compile_array(vparser
, Qnil
, array
, 1);
146 return ast_parse_done(ast_value
);
149 static VALUE
node_children(VALUE
, const NODE
*);
152 node_find(VALUE self
, const int node_id
)
156 struct ASTNodeData
*data
;
157 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
159 if (nd_node_id(data
->node
) == node_id
) return self
;
161 ary
= node_children(data
->ast_value
, data
->node
);
163 for (i
= 0; i
< RARRAY_LEN(ary
); i
++) {
164 VALUE child
= RARRAY_AREF(ary
, i
);
166 if (CLASS_OF(child
) == rb_cNode
) {
167 VALUE result
= node_find(child
, node_id
);
168 if (RTEST(result
)) return result
;
175 extern VALUE rb_e_script
;
178 node_id_for_backtrace_location(rb_execution_context_t
*ec
, VALUE module
, VALUE location
)
182 if (!rb_frame_info_p(location
)) {
183 rb_raise(rb_eTypeError
, "Thread::Backtrace::Location object expected");
186 node_id
= rb_get_node_id_from_frame_info(location
);
191 return INT2NUM(node_id
);
195 ast_s_of(rb_execution_context_t
*ec
, VALUE module
, VALUE body
, VALUE keep_script_lines
, VALUE error_tolerant
, VALUE keep_tokens
)
197 VALUE node
, lines
= Qnil
;
198 const rb_iseq_t
*iseq
;
201 if (rb_frame_info_p(body
)) {
202 iseq
= rb_get_iseq_from_frame_info(body
);
203 node_id
= rb_get_node_id_from_frame_info(body
);
208 if (rb_obj_is_proc(body
)) {
209 iseq
= vm_proc_iseq(body
);
211 if (!rb_obj_is_iseq((VALUE
)iseq
)) return Qnil
;
214 iseq
= rb_method_iseq(body
);
217 node_id
= ISEQ_BODY(iseq
)->location
.node_id
;
225 if (ISEQ_BODY(iseq
)->prism
) {
226 rb_raise(rb_eRuntimeError
, "cannot get AST for ISEQ compiled by prism");
229 lines
= ISEQ_BODY(iseq
)->variable
.script_lines
;
231 VALUE path
= rb_iseq_path(iseq
);
232 int e_option
= RSTRING_LEN(path
) == 2 && memcmp(RSTRING_PTR(path
), "-e", 2) == 0;
234 if (NIL_P(lines
) && rb_iseq_from_eval_p(iseq
) && !e_option
) {
235 rb_raise(rb_eArgError
, "cannot get AST for method defined in eval");
239 node
= rb_ast_parse_array(lines
, keep_script_lines
, error_tolerant
, keep_tokens
);
242 node
= rb_ast_parse_str(rb_e_script
, keep_script_lines
, error_tolerant
, keep_tokens
);
245 node
= rb_ast_parse_file(path
, keep_script_lines
, error_tolerant
, keep_tokens
);
248 return node_find(node
, node_id
);
252 rb_ast_node_alloc(VALUE klass
)
254 struct ASTNodeData
*data
;
255 VALUE obj
= TypedData_Make_Struct(klass
, struct ASTNodeData
, &rb_node_type
, data
);
261 node_type_to_str(const NODE
*node
)
263 return (ruby_node_name(nd_type(node
)) + rb_strlen_lit("NODE_"));
267 ast_node_type(rb_execution_context_t
*ec
, VALUE self
)
269 struct ASTNodeData
*data
;
270 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
272 return rb_sym_intern_ascii_cstr(node_type_to_str(data
->node
));
276 ast_node_node_id(rb_execution_context_t
*ec
, VALUE self
)
278 struct ASTNodeData
*data
;
279 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
281 return INT2FIX(nd_node_id(data
->node
));
284 #define NEW_CHILD(ast_value, node) (node ? ast_new_internal(ast_value, node) : Qnil)
287 rb_ary_new_from_node_args(VALUE ast_value
, long n
, ...)
293 ary
= rb_ary_new2(n
);
296 for (i
=0; i
<n
; i
++) {
298 node
= va_arg(ar
, NODE
*);
299 rb_ary_push(ary
, NEW_CHILD(ast_value
, node
));
306 dump_block(VALUE ast_value
, const struct RNode_BLOCK
*node
)
308 VALUE ary
= rb_ary_new();
310 rb_ary_push(ary
, NEW_CHILD(ast_value
, node
->nd_head
));
311 } while (node
->nd_next
&&
312 nd_type_p(node
->nd_next
, NODE_BLOCK
) &&
313 (node
= RNODE_BLOCK(node
->nd_next
), 1));
315 rb_ary_push(ary
, NEW_CHILD(ast_value
, node
->nd_next
));
322 dump_array(VALUE ast_value
, const struct RNode_LIST
*node
)
324 VALUE ary
= rb_ary_new();
325 rb_ary_push(ary
, NEW_CHILD(ast_value
, node
->nd_head
));
327 while (node
->nd_next
&& nd_type_p(node
->nd_next
, NODE_LIST
)) {
328 node
= RNODE_LIST(node
->nd_next
);
329 rb_ary_push(ary
, NEW_CHILD(ast_value
, node
->nd_head
));
331 rb_ary_push(ary
, NEW_CHILD(ast_value
, node
->nd_next
));
339 if (!id
) return Qnil
;
340 if (!rb_id2str(id
)) return Qnil
;
348 CONST_ID(rest
, "NODE_SPECIAL_NO_NAME_REST");
353 rest_arg(VALUE ast_value
, const NODE
*rest_arg
)
355 return NODE_NAMED_REST_P(rest_arg
) ? NEW_CHILD(ast_value
, rest_arg
) : no_name_rest();
359 node_children(VALUE ast_value
, const NODE
*node
)
361 char name
[sizeof("$") + DECIMAL_SIZE_OF(long)];
363 enum node_type type
= nd_type(node
);
366 return dump_block(ast_value
, RNODE_BLOCK(node
));
368 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_IF(node
)->nd_cond
, RNODE_IF(node
)->nd_body
, RNODE_IF(node
)->nd_else
);
370 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_UNLESS(node
)->nd_cond
, RNODE_UNLESS(node
)->nd_body
, RNODE_UNLESS(node
)->nd_else
);
372 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_CASE(node
)->nd_head
, RNODE_CASE(node
)->nd_body
);
374 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_CASE2(node
)->nd_head
, RNODE_CASE2(node
)->nd_body
);
376 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_CASE3(node
)->nd_head
, RNODE_CASE3(node
)->nd_body
);
378 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_WHEN(node
)->nd_head
, RNODE_WHEN(node
)->nd_body
, RNODE_WHEN(node
)->nd_next
);
380 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_IN(node
)->nd_head
, RNODE_IN(node
)->nd_body
, RNODE_IN(node
)->nd_next
);
383 return rb_ary_push(rb_ary_new_from_node_args(ast_value
, 2, RNODE_WHILE(node
)->nd_cond
, RNODE_WHILE(node
)->nd_body
),
384 RBOOL(RNODE_WHILE(node
)->nd_state
));
387 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_ITER(node
)->nd_iter
, RNODE_ITER(node
)->nd_body
);
389 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_FOR_MASGN(node
)->nd_var
);
391 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_BREAK(node
)->nd_stts
);
393 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_NEXT(node
)->nd_stts
);
395 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_RETURN(node
)->nd_stts
);
397 return rb_ary_new_from_node_args(ast_value
, 0);
399 return rb_ary_new_from_node_args(ast_value
, 0);
401 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_BEGIN(node
)->nd_body
);
403 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_RESCUE(node
)->nd_head
, RNODE_RESCUE(node
)->nd_resq
, RNODE_RESCUE(node
)->nd_else
);
405 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_RESBODY(node
)->nd_args
, RNODE_RESBODY(node
)->nd_body
, RNODE_RESBODY(node
)->nd_next
);
407 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_ENSURE(node
)->nd_head
, RNODE_ENSURE(node
)->nd_ensr
);
411 VALUE ary
= rb_ary_new();
414 rb_ary_push(ary
, NEW_CHILD(ast_value
, RNODE_AND(node
)->nd_1st
));
415 if (!RNODE_AND(node
)->nd_2nd
|| !nd_type_p(RNODE_AND(node
)->nd_2nd
, type
))
417 node
= RNODE_AND(node
)->nd_2nd
;
419 rb_ary_push(ary
, NEW_CHILD(ast_value
, RNODE_AND(node
)->nd_2nd
));
423 if (NODE_NAMED_REST_P(RNODE_MASGN(node
)->nd_args
)) {
424 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_MASGN(node
)->nd_value
, RNODE_MASGN(node
)->nd_head
, RNODE_MASGN(node
)->nd_args
);
427 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_MASGN(node
)->nd_value
),
428 NEW_CHILD(ast_value
, RNODE_MASGN(node
)->nd_head
),
432 if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node
)->nd_value
)) {
433 return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node
)->nd_vid
), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
435 return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node
)->nd_vid
), NEW_CHILD(ast_value
, RNODE_LASGN(node
)->nd_value
));
437 if (NODE_REQUIRED_KEYWORD_P(RNODE_DASGN(node
)->nd_value
)) {
438 return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node
)->nd_vid
), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
440 return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node
)->nd_vid
), NEW_CHILD(ast_value
, RNODE_DASGN(node
)->nd_value
));
442 return rb_ary_new_from_args(2, var_name(RNODE_IASGN(node
)->nd_vid
), NEW_CHILD(ast_value
, RNODE_IASGN(node
)->nd_value
));
444 return rb_ary_new_from_args(2, var_name(RNODE_CVASGN(node
)->nd_vid
), NEW_CHILD(ast_value
, RNODE_CVASGN(node
)->nd_value
));
446 return rb_ary_new_from_args(2, var_name(RNODE_GASGN(node
)->nd_vid
), NEW_CHILD(ast_value
, RNODE_GASGN(node
)->nd_value
));
448 if (RNODE_CDECL(node
)->nd_vid
) {
449 return rb_ary_new_from_args(2, ID2SYM(RNODE_CDECL(node
)->nd_vid
), NEW_CHILD(ast_value
, RNODE_CDECL(node
)->nd_value
));
451 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_CDECL(node
)->nd_else
), ID2SYM(RNODE_COLON2(RNODE_CDECL(node
)->nd_else
)->nd_mid
), NEW_CHILD(ast_value
, RNODE_CDECL(node
)->nd_value
));
453 return rb_ary_new_from_args(4, NEW_CHILD(ast_value
, RNODE_OP_ASGN1(node
)->nd_recv
),
454 ID2SYM(RNODE_OP_ASGN1(node
)->nd_mid
),
455 NEW_CHILD(ast_value
, RNODE_OP_ASGN1(node
)->nd_index
),
456 NEW_CHILD(ast_value
, RNODE_OP_ASGN1(node
)->nd_rvalue
));
458 return rb_ary_new_from_args(5, NEW_CHILD(ast_value
, RNODE_OP_ASGN2(node
)->nd_recv
),
459 RBOOL(RNODE_OP_ASGN2(node
)->nd_aid
),
460 ID2SYM(RNODE_OP_ASGN2(node
)->nd_vid
),
461 ID2SYM(RNODE_OP_ASGN2(node
)->nd_mid
),
462 NEW_CHILD(ast_value
, RNODE_OP_ASGN2(node
)->nd_value
));
463 case NODE_OP_ASGN_AND
:
464 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_OP_ASGN_AND(node
)->nd_head
), ID2SYM(idANDOP
),
465 NEW_CHILD(ast_value
, RNODE_OP_ASGN_AND(node
)->nd_value
));
466 case NODE_OP_ASGN_OR
:
467 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_OP_ASGN_OR(node
)->nd_head
), ID2SYM(idOROP
),
468 NEW_CHILD(ast_value
, RNODE_OP_ASGN_OR(node
)->nd_value
));
470 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_OP_CDECL(node
)->nd_head
),
471 ID2SYM(RNODE_OP_CDECL(node
)->nd_aid
),
472 NEW_CHILD(ast_value
, RNODE_OP_CDECL(node
)->nd_value
));
474 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_CALL(node
)->nd_recv
),
475 ID2SYM(RNODE_CALL(node
)->nd_mid
),
476 NEW_CHILD(ast_value
, RNODE_CALL(node
)->nd_args
));
478 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_OPCALL(node
)->nd_recv
),
479 ID2SYM(RNODE_OPCALL(node
)->nd_mid
),
480 NEW_CHILD(ast_value
, RNODE_OPCALL(node
)->nd_args
));
482 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_QCALL(node
)->nd_recv
),
483 ID2SYM(RNODE_QCALL(node
)->nd_mid
),
484 NEW_CHILD(ast_value
, RNODE_QCALL(node
)->nd_args
));
486 return rb_ary_new_from_args(2, ID2SYM(RNODE_FCALL(node
)->nd_mid
),
487 NEW_CHILD(ast_value
, RNODE_FCALL(node
)->nd_args
));
489 return rb_ary_new_from_args(1, ID2SYM(RNODE_VCALL(node
)->nd_mid
));
491 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_SUPER(node
)->nd_args
);
493 return rb_ary_new_from_node_args(ast_value
, 0);
495 return dump_array(ast_value
, RNODE_LIST(node
));
497 return rb_ary_new_from_node_args(ast_value
, 0);
499 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_HASH(node
)->nd_head
);
501 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_YIELD(node
)->nd_head
);
503 return rb_ary_new_from_args(1, var_name(RNODE_LVAR(node
)->nd_vid
));
505 return rb_ary_new_from_args(1, var_name(RNODE_DVAR(node
)->nd_vid
));
507 return rb_ary_new_from_args(1, ID2SYM(RNODE_IVAR(node
)->nd_vid
));
509 return rb_ary_new_from_args(1, ID2SYM(RNODE_CONST(node
)->nd_vid
));
511 return rb_ary_new_from_args(1, ID2SYM(RNODE_CVAR(node
)->nd_vid
));
513 return rb_ary_new_from_args(1, ID2SYM(RNODE_GVAR(node
)->nd_vid
));
515 snprintf(name
, sizeof(name
), "$%ld", RNODE_NTH_REF(node
)->nd_nth
);
516 return rb_ary_new_from_args(1, ID2SYM(rb_intern(name
)));
519 name
[1] = (char)RNODE_BACK_REF(node
)->nd_nth
;
521 return rb_ary_new_from_args(1, ID2SYM(rb_intern(name
)));
523 return rb_ary_new_from_args(1, rb_node_regx_string_val(node
));
525 if (RNODE_MATCH2(node
)->nd_args
) {
526 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_MATCH2(node
)->nd_recv
, RNODE_MATCH2(node
)->nd_value
, RNODE_MATCH2(node
)->nd_args
);
528 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_MATCH2(node
)->nd_recv
, RNODE_MATCH2(node
)->nd_value
);
530 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_MATCH3(node
)->nd_recv
, RNODE_MATCH3(node
)->nd_value
);
533 return rb_ary_new_from_args(1, rb_node_str_string_val(node
));
535 return rb_ary_new_from_args(1, rb_node_integer_literal_val(node
));
537 return rb_ary_new_from_args(1, rb_node_float_literal_val(node
));
539 return rb_ary_new_from_args(1, rb_node_rational_literal_val(node
));
541 return rb_ary_new_from_args(1, rb_node_imaginary_literal_val(node
));
543 return rb_ary_new_from_args(1, rb_node_regx_string_val(node
));
545 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_ONCE(node
)->nd_body
);
551 struct RNode_LIST
*n
= RNODE_DSTR(node
)->nd_next
;
552 VALUE head
= Qnil
, next
= Qnil
;
554 head
= NEW_CHILD(ast_value
, n
->nd_head
);
555 next
= NEW_CHILD(ast_value
, n
->nd_next
);
557 return rb_ary_new_from_args(3, rb_node_dstr_string_val(node
), head
, next
);
560 return rb_ary_new_from_args(1, rb_node_sym_string_val(node
));
562 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_EVSTR(node
)->nd_body
);
564 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_ARGSCAT(node
)->nd_head
, RNODE_ARGSCAT(node
)->nd_body
);
566 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_ARGSPUSH(node
)->nd_head
, RNODE_ARGSPUSH(node
)->nd_body
);
568 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_SPLAT(node
)->nd_head
);
569 case NODE_BLOCK_PASS
:
570 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_BLOCK_PASS(node
)->nd_head
, RNODE_BLOCK_PASS(node
)->nd_body
);
572 return rb_ary_new_from_args(2, ID2SYM(RNODE_DEFN(node
)->nd_mid
), NEW_CHILD(ast_value
, RNODE_DEFN(node
)->nd_defn
));
574 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_DEFS(node
)->nd_recv
), ID2SYM(RNODE_DEFS(node
)->nd_mid
), NEW_CHILD(ast_value
, RNODE_DEFS(node
)->nd_defn
));
576 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_ALIAS(node
)->nd_1st
, RNODE_ALIAS(node
)->nd_2nd
);
578 return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node
)->nd_alias
), ID2SYM(RNODE_VALIAS(node
)->nd_orig
));
580 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_UNDEF(node
)->nd_undef
);
582 return rb_ary_new_from_node_args(ast_value
, 3, RNODE_CLASS(node
)->nd_cpath
, RNODE_CLASS(node
)->nd_super
, RNODE_CLASS(node
)->nd_body
);
584 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_MODULE(node
)->nd_cpath
, RNODE_MODULE(node
)->nd_body
);
586 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_SCLASS(node
)->nd_recv
, RNODE_SCLASS(node
)->nd_body
);
588 return rb_ary_new_from_args(2, NEW_CHILD(ast_value
, RNODE_COLON2(node
)->nd_head
), ID2SYM(RNODE_COLON2(node
)->nd_mid
));
590 return rb_ary_new_from_args(1, ID2SYM(RNODE_COLON3(node
)->nd_mid
));
595 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_DOT2(node
)->nd_beg
, RNODE_DOT2(node
)->nd_end
);
597 return rb_ary_new_from_node_args(ast_value
, 0);
599 return rb_ary_new_from_node_args(ast_value
, 0);
601 return rb_ary_new_from_node_args(ast_value
, 0);
603 return rb_ary_new_from_node_args(ast_value
, 0);
605 return rb_ary_new_from_node_args(ast_value
, 0);
607 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_DEFINED(node
)->nd_head
);
609 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_POSTEXE(node
)->nd_body
);
611 return rb_ary_new_from_args(3, NEW_CHILD(ast_value
, RNODE_ATTRASGN(node
)->nd_recv
), ID2SYM(RNODE_ATTRASGN(node
)->nd_mid
), NEW_CHILD(ast_value
, RNODE_ATTRASGN(node
)->nd_args
));
613 return rb_ary_new_from_node_args(ast_value
, 1, RNODE_LAMBDA(node
)->nd_body
);
615 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_OPT_ARG(node
)->nd_body
, RNODE_OPT_ARG(node
)->nd_next
);
617 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_KW_ARG(node
)->nd_body
, RNODE_KW_ARG(node
)->nd_next
);
619 if (NODE_NAMED_REST_P(RNODE_POSTARG(node
)->nd_1st
)) {
620 return rb_ary_new_from_node_args(ast_value
, 2, RNODE_POSTARG(node
)->nd_1st
, RNODE_POSTARG(node
)->nd_2nd
);
622 return rb_ary_new_from_args(2, no_name_rest(),
623 NEW_CHILD(ast_value
, RNODE_POSTARG(node
)->nd_2nd
));
626 struct rb_args_info
*ainfo
= &RNODE_ARGS(node
)->nd_ainfo
;
627 return rb_ary_new_from_args(10,
628 INT2NUM(ainfo
->pre_args_num
),
629 NEW_CHILD(ast_value
, ainfo
->pre_init
),
630 NEW_CHILD(ast_value
, (NODE
*)ainfo
->opt_args
),
631 var_name(ainfo
->first_post_arg
),
632 INT2NUM(ainfo
->post_args_num
),
633 NEW_CHILD(ast_value
, ainfo
->post_init
),
634 (ainfo
->rest_arg
== NODE_SPECIAL_EXCESSIVE_COMMA
635 ? ID2SYM(rb_intern("NODE_SPECIAL_EXCESSIVE_COMMA"))
636 : var_name(ainfo
->rest_arg
)),
637 (ainfo
->no_kwarg
? Qfalse
: NEW_CHILD(ast_value
, (NODE
*)ainfo
->kw_args
)),
638 (ainfo
->no_kwarg
? Qfalse
: NEW_CHILD(ast_value
, ainfo
->kw_rest_arg
)),
639 var_name(ainfo
->block_arg
));
643 rb_ast_id_table_t
*tbl
= RNODE_SCOPE(node
)->nd_tbl
;
644 int i
, size
= tbl
? tbl
->size
: 0;
645 VALUE locals
= rb_ary_new_capa(size
);
646 for (i
= 0; i
< size
; i
++) {
647 rb_ary_push(locals
, var_name(tbl
->ids
[i
]));
649 return rb_ary_new_from_args(3, locals
, NEW_CHILD(ast_value
, (NODE
*)RNODE_SCOPE(node
)->nd_args
), NEW_CHILD(ast_value
, RNODE_SCOPE(node
)->nd_body
));
653 VALUE rest
= rest_arg(ast_value
, RNODE_ARYPTN(node
)->rest_arg
);
654 return rb_ary_new_from_args(4,
655 NEW_CHILD(ast_value
, RNODE_ARYPTN(node
)->nd_pconst
),
656 NEW_CHILD(ast_value
, RNODE_ARYPTN(node
)->pre_args
),
658 NEW_CHILD(ast_value
, RNODE_ARYPTN(node
)->post_args
));
662 VALUE pre_rest
= rest_arg(ast_value
, RNODE_FNDPTN(node
)->pre_rest_arg
);
663 VALUE post_rest
= rest_arg(ast_value
, RNODE_FNDPTN(node
)->post_rest_arg
);
664 return rb_ary_new_from_args(4,
665 NEW_CHILD(ast_value
, RNODE_FNDPTN(node
)->nd_pconst
),
667 NEW_CHILD(ast_value
, RNODE_FNDPTN(node
)->args
),
672 VALUE kwrest
= RNODE_HSHPTN(node
)->nd_pkwrestarg
== NODE_SPECIAL_NO_REST_KEYWORD
? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) :
673 NEW_CHILD(ast_value
, RNODE_HSHPTN(node
)->nd_pkwrestarg
);
675 return rb_ary_new_from_args(3,
676 NEW_CHILD(ast_value
, RNODE_HSHPTN(node
)->nd_pconst
),
677 NEW_CHILD(ast_value
, RNODE_HSHPTN(node
)->nd_pkwargs
),
681 return rb_ary_new_from_args(1, rb_node_line_lineno_val(node
));
683 return rb_ary_new_from_args(1, rb_node_file_path_val(node
));
685 return rb_ary_new_from_args(1, rb_node_encoding_val(node
));
687 return rb_ary_new_from_node_args(ast_value
, 0);
693 rb_bug("node_children: unknown node: %s", ruby_node_name(type
));
697 ast_node_children(rb_execution_context_t
*ec
, VALUE self
)
699 struct ASTNodeData
*data
;
700 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
702 return node_children(data
->ast_value
, data
->node
);
706 ast_node_first_lineno(rb_execution_context_t
*ec
, VALUE self
)
708 struct ASTNodeData
*data
;
709 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
711 return INT2NUM(nd_first_lineno(data
->node
));
715 ast_node_first_column(rb_execution_context_t
*ec
, VALUE self
)
717 struct ASTNodeData
*data
;
718 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
720 return INT2NUM(nd_first_column(data
->node
));
724 ast_node_last_lineno(rb_execution_context_t
*ec
, VALUE self
)
726 struct ASTNodeData
*data
;
727 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
729 return INT2NUM(nd_last_lineno(data
->node
));
733 ast_node_last_column(rb_execution_context_t
*ec
, VALUE self
)
735 struct ASTNodeData
*data
;
736 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
738 return INT2NUM(nd_last_column(data
->node
));
742 ast_node_all_tokens(rb_execution_context_t
*ec
, VALUE self
)
745 struct ASTNodeData
*data
;
747 rb_parser_ary_t
*parser_tokens
;
748 rb_parser_ast_token_t
*parser_token
;
749 VALUE str
, loc
, token
, all_tokens
;
751 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
752 ast
= rb_ruby_ast_data_get(data
->ast_value
);
754 parser_tokens
= ast
->node_buffer
->tokens
;
755 if (parser_tokens
== NULL
) {
759 all_tokens
= rb_ary_new2(parser_tokens
->len
);
760 for (i
= 0; i
< parser_tokens
->len
; i
++) {
761 parser_token
= parser_tokens
->data
[i
];
762 str
= rb_str_new(parser_token
->str
->ptr
, parser_token
->str
->len
);
763 loc
= rb_ary_new_from_args(4,
764 INT2FIX(parser_token
->loc
.beg_pos
.lineno
),
765 INT2FIX(parser_token
->loc
.beg_pos
.column
),
766 INT2FIX(parser_token
->loc
.end_pos
.lineno
),
767 INT2FIX(parser_token
->loc
.end_pos
.column
)
769 token
= rb_ary_new_from_args(4, INT2FIX(parser_token
->id
), ID2SYM(rb_intern(parser_token
->type_name
)), str
, loc
);
770 rb_ary_push(all_tokens
, token
);
772 rb_obj_freeze(all_tokens
);
778 ast_node_inspect(rb_execution_context_t
*ec
, VALUE self
)
782 struct ASTNodeData
*data
;
783 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
785 cname
= rb_class_path(rb_obj_class(self
));
786 str
= rb_str_new2("#<");
788 rb_str_append(str
, cname
);
789 rb_str_catf(str
, ":%s@%d:%d-%d:%d>",
790 node_type_to_str(data
->node
),
791 nd_first_lineno(data
->node
), nd_first_column(data
->node
),
792 nd_last_lineno(data
->node
), nd_last_column(data
->node
));
798 ast_node_script_lines(rb_execution_context_t
*ec
, VALUE self
)
800 struct ASTNodeData
*data
;
802 TypedData_Get_Struct(self
, struct ASTNodeData
, &rb_node_type
, data
);
803 ast
= rb_ruby_ast_data_get(data
->ast_value
);
804 rb_parser_ary_t
*ret
= ast
->body
.script_lines
;
805 return rb_parser_build_script_lines_from(ret
);
813 rb_mAST
= rb_define_module_under(rb_cRubyVM
, "AbstractSyntaxTree");
814 rb_cNode
= rb_define_class_under(rb_mAST
, "Node", rb_cObject
);
815 rb_undef_alloc_func(rb_cNode
);