summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast.c20
-rw-r--r--compile.c16
-rw-r--r--node.c11
-rw-r--r--node_dump.c29
-rw-r--r--parse.y37
-rw-r--r--rubyparser.h5
6 files changed, 103 insertions, 15 deletions
diff --git a/ast.c b/ast.c
index cc4bca1a1a..2f346cb727 100644
--- a/ast.c
+++ b/ast.c
@@ -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:
diff --git a/compile.c b/compile.c
index 9d112055be..3efdc64dd2 100644
--- a/compile.c
+++ b/compile.c
@@ -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);
diff --git a/node.c b/node.c
index 2efcd6eba8..1a52fbba3d 100644
--- a/node.c
+++ b/node.c
@@ -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:
diff --git a/parse.y b/parse.y
index c121ddd9e8..ed9ca66f88 100644
--- a/parse.y
+++ b/parse.y
@@ -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 {