mruby-compiler: migrate NODE_LVAR and NODE_ARG to variable-sized nodes

Convert NODE_LVAR and NODE_ARG from cons-list to variable-sized nodes.
Remove new_lvar wrapper and use new_xvar directly. Update parser
semantic functions and cleanup gen_assignment. Rename codegen_lvar
to gen_lvar for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-09-11 22:43:47 +09:00
parent b2aba341f5
commit 3fd59d336e
3 changed files with 1115 additions and 1120 deletions
+24 -23
View File
@@ -2930,8 +2930,6 @@ gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val)
int type = node_to_int(tree->car);
switch (type) {
case NODE_ARG:
case NODE_LVAR:
case NODE_NIL:
if (rhs) {
codegen(s, rhs, VAL);
@@ -2979,6 +2977,27 @@ gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val)
case NODE_MASGN:
gen_masgn_var(s, tree->cdr, rhs, sp, val);
return;
case NODE_LVAR:
case NODE_ARG:
{
mrb_sym sym = VAR_NODE_SYMBOL(tree->cdr);
if (rhs) {
codegen(s, rhs, VAL);
pop();
sp = cursp();
}
idx = lv_idx(s, sym);
if (idx > 0) {
if (idx != sp) {
gen_move(s, idx, sp, val);
}
break;
}
else {
gen_setupvar(s, sp, sym);
}
}
break;
default:
codegen_error(s, "unsupported variable-sized lhs");
break;
@@ -2995,20 +3014,6 @@ gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val)
tree = tree->cdr;
switch (type) {
case NODE_ARG:
case NODE_LVAR:
idx = lv_idx(s, node_to_sym(tree));
if (idx > 0) {
if (idx != sp) {
gen_move(s, idx, sp, val);
}
break;
}
else { /* upvar */
gen_setupvar(s, sp, node_to_sym(tree));
}
break;
case NODE_CALL:
case NODE_SCALL:
{
@@ -3372,7 +3377,7 @@ gen_blkmove(codegen_scope *s, uint16_t ainfo, int lv)
}
static void
codegen_lvar(codegen_scope *s, mrb_sym sym, int val)
gen_lvar(codegen_scope *s, mrb_sym sym, int val)
{
if (!val) return;
int idx = lv_idx(s, sym);
@@ -5294,7 +5299,7 @@ gen_dvar_var(codegen_scope *s, node *varnode, int val)
struct mrb_ast_dvar_node *n = (struct mrb_ast_dvar_node*)varnode;
// DVAR nodes are not currently used in mruby, but provide basic implementation
if (val) {
codegen_lvar(s, n->name, val);
gen_lvar(s, n->name, val);
}
}
@@ -5766,7 +5771,7 @@ codegen_variable_node(codegen_scope *s, node *varnode, int val)
return TRUE;
case NODE_LVAR:
codegen_lvar(s, VAR_NODE_SYMBOL(varnode), val);
gen_lvar(s, VAR_NODE_SYMBOL(varnode), val);
return TRUE;
case NODE_GVAR:
@@ -6108,10 +6113,6 @@ codegen(codegen_scope *s, node *tree, int val)
codegen_scall(s, tree, val);
break;
case NODE_LVAR:
codegen_lvar(s, node_to_sym(tree), val);
break;
case NODE_DEF:
codegen_def(s, tree, val);
break;
+33 -36
View File
@@ -1244,16 +1244,6 @@ new_strsym(parser_state *p, node* str)
return mrb_intern(p->mrb, s, len);
}
/* (:lvar . a) */
static node*
new_lvar(parser_state *p, mrb_sym sym)
{
if (p->var_nodes_enabled) {
return new_xvar(p, sym, NODE_LVAR);
}
return cons_head((node*)NODE_LVAR, sym_to_node(sym));
}
/* (:nvar . a) */
static node*
new_nvar(parser_state *p, int num)
@@ -1423,7 +1413,7 @@ defs_setup(parser_state *p, node *d, node *a, node *b)
static node*
new_arg(parser_state *p, mrb_sym sym)
{
return cons_head((node*)NODE_ARG, sym_to_node(sym));
return new_xvar(p, sym, NODE_ARG);
}
static void
@@ -2163,25 +2153,32 @@ ret_args(parser_state *p, node *n)
static void
assignable(parser_state *p, node *lhs)
{
switch (node_to_int(lhs->car)) {
case NODE_LVAR:
local_add(p, node_to_sym(lhs->cdr));
break;
case NODE_CONST:
if (p->in_def)
yyerror(NULL, p, "dynamic constant assignment");
break;
if (node_to_int(lhs->car) == NODE_VARIABLE) {
node *var_node = lhs->cdr;
switch (VAR_NODE_TYPE(var_node)) {
case NODE_LVAR:
local_add(p, VAR_NODE_SYMBOL(var_node));
break;
case NODE_CONST:
if (p->in_def)
yyerror(NULL, p, "dynamic constant assignment");
break;
}
}
}
static node*
var_reference(parser_state *p, node *lhs)
{
if (node_to_int(lhs->car) == NODE_LVAR) {
if (!local_var_p(p, node_to_sym(lhs->cdr))) {
node *n = new_fcall(p, node_to_sym(lhs->cdr), 0);
cons_free(lhs);
return n;
if (node_to_int(lhs->car) == NODE_VARIABLE) {
node *var_node = lhs->cdr;
if (VAR_NODE_TYPE(var_node) == NODE_LVAR) {
mrb_sym sym = VAR_NODE_SYMBOL(var_node);
if (!local_var_p(p, sym)) {
node *n = new_fcall(p, sym, 0);
/* Don't free variable-sized nodes - they're managed by the parser allocator */
return n;
}
}
}
return lhs;
@@ -2193,7 +2190,7 @@ label_reference(parser_state *p, mrb_sym sym)
const char *name = mrb_sym_name(p->mrb, sym);
if (local_var_p(p, sym)) {
return new_lvar(p, sym);
return new_xvar(p, sym, NODE_LVAR);
}
else if (ISUPPER(name[0])) {
return new_const(p, sym);
@@ -2656,7 +2653,7 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
}
| arg tASSOC tIDENTIFIER
{
node *lhs = new_lvar(p, $3);
node *lhs = new_xvar(p, $3, NODE_LVAR);
assignable(p, lhs);
$$ = new_asgn(p, lhs, $1);
}
@@ -3400,9 +3397,9 @@ paren_args : '(' opt_call_args ')'
mrb_sym r = intern_op(mul);
mrb_sym k = intern_op(pow);
mrb_sym b = intern_op(and);
$$ = new_callargs(p, push($2, new_splat(p, new_lvar(p, r))),
new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))),
new_block_arg(p, new_lvar(p, b)));
$$ = new_callargs(p, push($2, new_splat(p, new_xvar(p, r, NODE_LVAR))),
new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_xvar(p, k, NODE_LVAR)))),
new_block_arg(p, new_xvar(p, b, NODE_LVAR)));
}
| '(' tBDOT3 rparen
{
@@ -3410,9 +3407,9 @@ paren_args : '(' opt_call_args ')'
mrb_sym k = intern_op(pow);
mrb_sym b = intern_op(and);
if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) {
$$ = new_callargs(p, list1(new_splat(p, new_lvar(p, r))),
new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))),
new_block_arg(p, new_lvar(p, b)));
$$ = new_callargs(p, list1(new_splat(p, new_xvar(p, r, NODE_LVAR))),
new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_xvar(p, k, NODE_LVAR)))),
new_block_arg(p, new_xvar(p, b, NODE_LVAR)));
}
else {
yyerror(&@1, p, "unexpected argument forwarding ...");
@@ -3505,7 +3502,7 @@ args : arg
}
| tSTAR
{
$$ = list1(new_splat(p, new_lvar(p, intern_op(mul))));
$$ = list1(new_splat(p, new_xvar(p, intern_op(mul), NODE_LVAR)));
}
| tSTAR arg
{
@@ -3518,7 +3515,7 @@ args : arg
}
| args comma tSTAR
{
$$ = push($1, new_splat(p, new_lvar(p, intern_op(mul))));
$$ = push($1, new_splat(p, new_xvar(p, intern_op(mul), NODE_LVAR)));
}
| args comma tSTAR arg
{
@@ -4417,7 +4414,7 @@ numeric : tINTEGER
variable : tIDENTIFIER
{
$$ = new_lvar(p, $1);
$$ = new_xvar(p, $1, NODE_LVAR);
}
| tIVAR
{
@@ -4939,7 +4936,7 @@ assoc : arg tASSOC arg
}
| tDSTAR
{
$$ = cons(new_kw_rest_args(p, 0), new_lvar(p, intern_op(pow)));
$$ = cons(new_kw_rest_args(p, 0), new_xvar(p, intern_op(pow), NODE_LVAR));
}
;
File diff suppressed because it is too large Load Diff