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:
parent
174c01b80e
commit
6be539aab5
Notes:
git
2024-07-20 02:25:44 +00:00
20
ast.c
20
ast.c
@ -333,6 +333,24 @@ dump_array(VALUE ast_value, const struct RNode_LIST *node)
|
|||||||
return ary;
|
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
|
static VALUE
|
||||||
var_name(ID id)
|
var_name(ID id)
|
||||||
{
|
{
|
||||||
@ -577,7 +595,7 @@ node_children(VALUE ast_value, const NODE *node)
|
|||||||
case NODE_VALIAS:
|
case NODE_VALIAS:
|
||||||
return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node)->nd_alias), ID2SYM(RNODE_VALIAS(node)->nd_orig));
|
return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node)->nd_alias), ID2SYM(RNODE_VALIAS(node)->nd_orig));
|
||||||
case NODE_UNDEF:
|
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:
|
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);
|
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:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_UNDEF:{
|
case NODE_UNDEF:{
|
||||||
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
|
const rb_parser_ary_t *ary = RNODE_UNDEF(node)->nd_undefs;
|
||||||
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
|
|
||||||
CHECK(COMPILE(ret, "undef arg", RNODE_UNDEF(node)->nd_undef));
|
for (long i = 0; i < ary->len; i++) {
|
||||||
ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2));
|
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) {
|
if (popped) {
|
||||||
ADD_INSN(ret, node, pop);
|
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);
|
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
|
static void
|
||||||
free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
|
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:
|
case NODE_IMAGINARY:
|
||||||
xfree(RNODE_IMAGINARY(node)->val);
|
xfree(RNODE_IMAGINARY(node)->val);
|
||||||
break;
|
break;
|
||||||
|
case NODE_UNDEF:
|
||||||
|
parser_nodes_free(ast, RNODE_UNDEF(node)->nd_undefs);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
29
node_dump.c
29
node_dump.c
@ -92,6 +92,9 @@
|
|||||||
#define F_NODE2(name, n, ann) \
|
#define F_NODE2(name, n, ann) \
|
||||||
COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, n);}
|
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) \
|
#define ANN(ann) \
|
||||||
if (comment) { \
|
if (comment) { \
|
||||||
A_INDENT; A("| # " ann "\n"); \
|
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");
|
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
|
static void
|
||||||
dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
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:
|
case NODE_UNDEF:
|
||||||
ANN("method undef statement");
|
ANN("method undef statement");
|
||||||
ANN("format: undef [nd_undef]");
|
ANN("format: undef [nd_undefs]");
|
||||||
ANN("example: undef foo");
|
ANN("example: undef foo");
|
||||||
LAST_NODE;
|
LAST_NODE;
|
||||||
F_NODE(nd_undef, RNODE_UNDEF, "old name");
|
F_ARRAY(nd_undefs, RNODE_UNDEF, "nd_undefs");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case NODE_CLASS:
|
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);
|
memcmp(ptr1, ptr2, len1) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef RIPPER
|
|
||||||
static void
|
static void
|
||||||
rb_parser_ary_extend(rb_parser_t *p, rb_parser_ary_t *ary, long len)
|
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.
|
* 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 *
|
static rb_parser_ary_t *
|
||||||
parser_ary_new_capa(rb_parser_t *p, long len)
|
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;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef RIPPER
|
||||||
static rb_parser_ary_t *
|
static rb_parser_ary_t *
|
||||||
rb_parser_ary_new_capa_for_script_line(rb_parser_t *p, long len)
|
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;
|
ary->data_type = PARSER_ARY_DATA_AST_TOKEN;
|
||||||
return ary;
|
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.
|
* 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 *
|
static rb_parser_ary_t *
|
||||||
parser_ary_push(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_ary_data val)
|
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;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef RIPPER
|
||||||
static rb_parser_ary_t *
|
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)
|
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);
|
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
|
static void
|
||||||
rb_parser_ast_token_free(rb_parser_t *p, rb_parser_ast_token_t *token)
|
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:
|
case PARSER_ARY_DATA_SCRIPT_LINE:
|
||||||
foreach_ary(data) {rb_parser_string_free(p, *data);}
|
foreach_ary(data) {rb_parser_string_free(p, *data);}
|
||||||
break;
|
break;
|
||||||
|
case PARSER_ARY_DATA_NODE:
|
||||||
|
/* Do nothing because nodes are freed when rb_ast_t is freed */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type);
|
rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type);
|
||||||
break;
|
break;
|
||||||
@ -3774,8 +3798,8 @@ undef_list : fitem
|
|||||||
}
|
}
|
||||||
| undef_list ',' {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
|
| undef_list ',' {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
|
||||||
{
|
{
|
||||||
NODE *undef = NEW_UNDEF($4, &@4);
|
nd_set_last_loc($1, @4.end_pos);
|
||||||
$$ = block_append(p, $1, undef);
|
rb_parser_ary_push_node(p, RNODE_UNDEF($1)->nd_undefs, $4);
|
||||||
/*% ripper: rb_ary_push($:1, $: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_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);
|
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;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,8 @@ typedef void* rb_parser_ary_data;
|
|||||||
|
|
||||||
enum rb_parser_ary_data_type {
|
enum rb_parser_ary_data_type {
|
||||||
PARSER_ARY_DATA_AST_TOKEN = 1,
|
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 {
|
typedef struct rb_parser_ary {
|
||||||
@ -885,7 +886,7 @@ typedef struct RNode_VALIAS {
|
|||||||
typedef struct RNode_UNDEF {
|
typedef struct RNode_UNDEF {
|
||||||
NODE node;
|
NODE node;
|
||||||
|
|
||||||
struct RNode *nd_undef;
|
rb_parser_ary_t *nd_undefs;
|
||||||
} rb_node_undef_t;
|
} rb_node_undef_t;
|
||||||
|
|
||||||
typedef struct RNode_CLASS {
|
typedef struct RNode_CLASS {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user