зеркало из https://github.com/github/ruby.git
Change UNDEF Node structure
Change UNDEF Node to hold their items to keep the original grammar structure. For example: ``` undef a, b ``` Before: ``` @ NODE_BLOCK (id: 4, line: 1, location: (1,6)-(1,10))* +- nd_head (1): | @ NODE_UNDEF (id: 1, line: 1, location: (1,6)-(1,7)) | +- nd_undef: | @ NODE_SYM (id: 0, line: 1, location: (1,6)-(1,7)) | +- string: :a +- nd_head (2): @ NODE_UNDEF (id: 3, line: 1, location: (1,9)-(1,10)) +- nd_undef: @ NODE_SYM (id: 2, line: 1, location: (1,9)-(1,10)) +- string: :b ``` After: ``` @ NODE_UNDEF (id: 1, line: 1, location: (1,6)-(1,10))* +- nd_undefs: +- length: 2 +- element (0): | @ NODE_SYM (id: 0, line: 1, location: (1,6)-(1,7)) | +- string: :a +- element (1): @ NODE_SYM (id: 2, line: 1, location: (1,9)-(1,10)) +- string: :b ```
This commit is contained in:
Родитель
174c01b80e
Коммит
6be539aab5
20
ast.c
20
ast.c
|
@ -333,6 +333,24 @@ dump_array(VALUE ast_value, const struct RNode_LIST *node)
|
|||
return ary;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
|
16
compile.c
16
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);
|
||||
|
|
11
node.c
11
node.c
|
@ -162,6 +162,14 @@ parser_tokens_free(rb_ast_t *ast, rb_parser_ary_t *tokens)
|
|||
xfree(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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
29
node_dump.c
29
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"); \
|
||||
|
@ -164,6 +167,28 @@ dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
|
|||
F_NODE(nd_next, RNODE_LIST, "next element");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
|
37
parse.y
37
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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче