diff options
-rw-r--r-- | ast.c | 20 | ||||
-rw-r--r-- | compile.c | 16 | ||||
-rw-r--r-- | node.c | 11 | ||||
-rw-r--r-- | node_dump.c | 29 | ||||
-rw-r--r-- | parse.y | 37 | ||||
-rw-r--r-- | rubyparser.h | 5 |
6 files changed, 103 insertions, 15 deletions
@@ -334,6 +334,24 @@ dump_array(VALUE ast_value, const struct RNode_LIST *node) } static VALUE +dump_parser_array(VALUE ast_value, rb_parser_ary_t *p_ary) +{ + VALUE ary; + + if (p_ary->data_type != PARSER_ARY_DATA_NODE) { + rb_bug("unexpected rb_parser_ary_data_type: %d", p_ary->data_type); + } + + ary = rb_ary_new(); + + for (long i = 0; i < p_ary->len; i++) { + rb_ary_push(ary, NEW_CHILD(ast_value, p_ary->data[i])); + } + + return ary; +} + +static VALUE var_name(ID id) { if (!id) return Qnil; @@ -577,7 +595,7 @@ node_children(VALUE ast_value, const NODE *node) case NODE_VALIAS: return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node)->nd_alias), ID2SYM(RNODE_VALIAS(node)->nd_orig)); case NODE_UNDEF: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_UNDEF(node)->nd_undef); + return rb_ary_new_from_args(1, dump_parser_array(ast_value, RNODE_UNDEF(node)->nd_undefs)); case NODE_CLASS: 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); case NODE_MODULE: @@ -10954,10 +10954,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_UNDEF:{ - ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); - ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); - CHECK(COMPILE(ret, "undef arg", RNODE_UNDEF(node)->nd_undef)); - ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2)); + const rb_parser_ary_t *ary = RNODE_UNDEF(node)->nd_undefs; + + for (long i = 0; i < ary->len; i++) { + ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); + ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); + CHECK(COMPILE(ret, "undef arg", ary->data[i])); + ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2)); + + if (i < ary->len - 1) { + ADD_INSN(ret, node, pop); + } + } if (popped) { ADD_INSN(ret, node, pop); @@ -163,6 +163,14 @@ parser_tokens_free(rb_ast_t *ast, rb_parser_ary_t *tokens) } static void +parser_nodes_free(rb_ast_t *ast, rb_parser_ary_t *nodes) +{ + /* Do nothing for nodes because nodes are freed when rb_ast_t is freed */ + xfree(nodes->data); + xfree(nodes); +} + +static void free_ast_value(rb_ast_t *ast, void *ctx, NODE *node) { switch (nd_type(node)) { @@ -206,6 +214,9 @@ free_ast_value(rb_ast_t *ast, void *ctx, NODE *node) case NODE_IMAGINARY: xfree(RNODE_IMAGINARY(node)->val); break; + case NODE_UNDEF: + parser_nodes_free(ast, RNODE_UNDEF(node)->nd_undefs); + break; default: break; } diff --git a/node_dump.c b/node_dump.c index 37abea8441..5656f1d812 100644 --- a/node_dump.c +++ b/node_dump.c @@ -92,6 +92,9 @@ #define F_NODE2(name, n, ann) \ COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, n);} +#define F_ARRAY(name, type, ann) \ + COMPOUND_FIELD1(#name, ann) {dump_parser_array(buf, indent, comment, type(node)->name);} + #define ANN(ann) \ if (comment) { \ A_INDENT; A("| # " ann "\n"); \ @@ -165,6 +168,28 @@ dump_array(VALUE buf, VALUE indent, int comment, const NODE *node) } static void +dump_parser_array(VALUE buf, VALUE indent, int comment, const rb_parser_ary_t *ary) +{ + int field_flag; + const char *next_indent = default_indent; + + if (ary->data_type != PARSER_ARY_DATA_NODE) { + rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type); + } + + F_CUSTOM1(length, "length") { A_LONG(ary->len); } + for (long i = 0; i < ary->len; i++) { + if (i == ary->len - 1) LAST_NODE; + A_INDENT; + rb_str_catf(buf, "+- element (%s%ld):\n", + comment ? "statement #" : "", i); + D_INDENT; + dump_node(buf, indent, comment, ary->data[i]); + D_DEDENT; + } +} + +static void dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) { int field_flag; @@ -896,10 +921,10 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) case NODE_UNDEF: ANN("method undef statement"); - ANN("format: undef [nd_undef]"); + ANN("format: undef [nd_undefs]"); ANN("example: undef foo"); LAST_NODE; - F_NODE(nd_undef, RNODE_UNDEF, "old name"); + F_ARRAY(nd_undefs, RNODE_UNDEF, "nd_undefs"); return; case NODE_CLASS: @@ -2487,7 +2487,6 @@ rb_parser_string_hash_cmp(rb_parser_string_t *str1, rb_parser_string_t *str2) memcmp(ptr1, ptr2, len1) != 0); } -#ifndef RIPPER static void rb_parser_ary_extend(rb_parser_t *p, rb_parser_ary_t *ary, long len) { @@ -2503,7 +2502,7 @@ rb_parser_ary_extend(rb_parser_t *p, rb_parser_ary_t *ary, long len) /* * Do not call this directly. - * Use rb_parser_ary_new_capa_for_script_line() or rb_parser_ary_new_capa_for_ast_token() instead. + * Use rb_parser_ary_new_capa_for_XXX() instead. */ static rb_parser_ary_t * parser_ary_new_capa(rb_parser_t *p, long len) @@ -2524,6 +2523,7 @@ parser_ary_new_capa(rb_parser_t *p, long len) return ary; } +#ifndef RIPPER static rb_parser_ary_t * rb_parser_ary_new_capa_for_script_line(rb_parser_t *p, long len) { @@ -2539,10 +2539,19 @@ rb_parser_ary_new_capa_for_ast_token(rb_parser_t *p, long len) ary->data_type = PARSER_ARY_DATA_AST_TOKEN; return ary; } +#endif + +static rb_parser_ary_t * +rb_parser_ary_new_capa_for_node(rb_parser_t *p, long len) +{ + rb_parser_ary_t *ary = parser_ary_new_capa(p, len); + ary->data_type = PARSER_ARY_DATA_NODE; + return ary; +} /* * Do not call this directly. - * Use rb_parser_ary_push_script_line() or rb_parser_ary_push_ast_token() instead. + * Use rb_parser_ary_push_XXX() instead. */ static rb_parser_ary_t * parser_ary_push(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_ary_data val) @@ -2554,6 +2563,7 @@ parser_ary_push(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_ary_data val) return ary; } +#ifndef RIPPER static rb_parser_ary_t * rb_parser_ary_push_ast_token(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_ast_token_t *val) { @@ -2571,7 +2581,18 @@ rb_parser_ary_push_script_line(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_s } return parser_ary_push(p, ary, val); } +#endif + +static rb_parser_ary_t * +rb_parser_ary_push_node(rb_parser_t *p, rb_parser_ary_t *ary, NODE *val) +{ + if (ary->data_type != PARSER_ARY_DATA_NODE) { + rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type); + } + return parser_ary_push(p, ary, val); +} +#ifndef RIPPER static void rb_parser_ast_token_free(rb_parser_t *p, rb_parser_ast_token_t *token) { @@ -2593,6 +2614,9 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary) case PARSER_ARY_DATA_SCRIPT_LINE: foreach_ary(data) {rb_parser_string_free(p, *data);} break; + case PARSER_ARY_DATA_NODE: + /* Do nothing because nodes are freed when rb_ast_t is freed */ + break; default: rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type); break; @@ -3774,8 +3798,8 @@ undef_list : fitem } | undef_list ',' {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem { - NODE *undef = NEW_UNDEF($4, &@4); - $$ = block_append(p, $1, undef); + nd_set_last_loc($1, @4.end_pos); + rb_parser_ary_push_node(p, RNODE_UNDEF($1)->nd_undefs, $4); /*% ripper: rb_ary_push($:1, $:4) %*/ } ; @@ -12286,7 +12310,8 @@ static rb_node_undef_t * rb_node_undef_new(struct parser_params *p, NODE *nd_undef, const YYLTYPE *loc) { rb_node_undef_t *n = NODE_NEWNODE(NODE_UNDEF, rb_node_undef_t, loc); - n->nd_undef = nd_undef; + n->nd_undefs = rb_parser_ary_new_capa_for_node(p, 1); + rb_parser_ary_push_node(p, n->nd_undefs, nd_undef); return n; } diff --git a/rubyparser.h b/rubyparser.h index d763bd10e7..7dbbd72eb8 100644 --- a/rubyparser.h +++ b/rubyparser.h @@ -225,7 +225,8 @@ typedef void* rb_parser_ary_data; enum rb_parser_ary_data_type { PARSER_ARY_DATA_AST_TOKEN = 1, - PARSER_ARY_DATA_SCRIPT_LINE + PARSER_ARY_DATA_SCRIPT_LINE, + PARSER_ARY_DATA_NODE }; typedef struct rb_parser_ary { @@ -885,7 +886,7 @@ typedef struct RNode_VALIAS { typedef struct RNode_UNDEF { NODE node; - struct RNode *nd_undef; + rb_parser_ary_t *nd_undefs; } rb_node_undef_t; typedef struct RNode_CLASS { |