mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: refactor lambda_body to take individual parameters
created lambda_body_ex that takes locals, args, and body as separate parameters instead of a cons structure. this eliminates complex cons cell navigation and makes the interface cleaner for variable-sized nodes. updated all call sites (gen_def_var, gen_sdef_var, gen_block_var, gen_lambda_var) to use lambda_body_ex directly. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2305,11 +2305,11 @@ search_upvar(codegen_scope *s, mrb_sym id, int *idx)
|
||||
* @return The index of the newly created `mrb_irep` in the parent scope's `reps` array.
|
||||
*/
|
||||
static int
|
||||
lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
lambda_body_ex(codegen_scope *s, node *locals, node *args, node *body, int blk)
|
||||
{
|
||||
codegen_scope *parent = s;
|
||||
/* Create a new scope for the lambda/block body. */
|
||||
s = scope_new(s->mrb, s, tree->car);
|
||||
s = scope_new(s->mrb, s, locals);
|
||||
|
||||
/* `mscope` is false for blocks, true for lambdas/methods. */
|
||||
s->mscope = !blk;
|
||||
@@ -2319,10 +2319,9 @@ lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
struct loopinfo *lp = loop_push(s, LOOP_BLOCK);
|
||||
lp->pc0 = new_label(s); /* Mark entry point for potential retry/redo. */
|
||||
}
|
||||
tree = tree->cdr;
|
||||
|
||||
/* Argument processing */
|
||||
if (tree->car == NULL) { /* No arguments */
|
||||
if (args == NULL) { /* No arguments */
|
||||
genop_W(s, OP_ENTER, 0); /* Generate OP_ENTER with no argument specification. */
|
||||
s->ainfo = 0;
|
||||
}
|
||||
@@ -2335,17 +2334,17 @@ lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
node *tail;
|
||||
|
||||
/* mandatory arguments */
|
||||
ma = node_len(tree->car->car);
|
||||
margs = tree->car->car;
|
||||
tail = tree->car->cdr->cdr->cdr->cdr;
|
||||
ma = node_len(args->car);
|
||||
margs = args->car;
|
||||
tail = args->cdr->cdr->cdr->cdr;
|
||||
|
||||
/* optional arguments */
|
||||
oa = node_len(tree->car->cdr->car);
|
||||
oa = node_len(args->cdr->car);
|
||||
/* rest argument? */
|
||||
ra = tree->car->cdr->cdr->car ? 1 : 0;
|
||||
ra = args->cdr->cdr->car ? 1 : 0;
|
||||
/* mandatory arguments after rest argument */
|
||||
pa = node_len(tree->car->cdr->cdr->cdr->car);
|
||||
pargs = tree->car->cdr->cdr->cdr->car;
|
||||
pa = node_len(args->cdr->cdr->cdr->car);
|
||||
pargs = args->cdr->cdr->cdr->car;
|
||||
/* keyword arguments */
|
||||
if (tail) {
|
||||
/* Handle variable-sized NODE_ARGS_TAIL */
|
||||
@@ -2384,7 +2383,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
if (oa > 0) {
|
||||
genjmp_0(s, OP_JMP); /* Jump to skip all default assignments if all optional args are provided. */
|
||||
}
|
||||
opt = tree->car->cdr->car; /* AST node for optional arguments. */
|
||||
opt = args->cdr->car; /* AST node for optional arguments. */
|
||||
i = 0;
|
||||
while (opt) { /* Iterate through optional arguments. */
|
||||
int idx;
|
||||
@@ -2500,7 +2499,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
}
|
||||
|
||||
/* Generate code for the actual body of the lambda/block. */
|
||||
codegen(s, tree->cdr->car, VAL);
|
||||
codegen(s, body, VAL);
|
||||
pop(); /* Pop the result of the body. */
|
||||
|
||||
/* Implicit return of the last evaluated expression. */
|
||||
@@ -2515,6 +2514,18 @@ lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
return parent->irep->rlen - 1; /* Return the index of this IREP in the parent's REP list. */
|
||||
}
|
||||
|
||||
static int
|
||||
lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
{
|
||||
/* Extract locals, args, and body from the cons structure */
|
||||
node *locals = tree->car;
|
||||
node *args = tree->cdr ? tree->cdr->car : NULL;
|
||||
node *body = (tree->cdr && tree->cdr->cdr) ? tree->cdr->cdr->car : NULL;
|
||||
|
||||
/* Call the new lambda_body_ex with individual parameters */
|
||||
return lambda_body_ex(s, locals, args, body, blk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates code for a new lexical scope, typically for class/module definitions
|
||||
* or the top-level script.
|
||||
@@ -4330,16 +4341,19 @@ static void
|
||||
gen_def_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_def_node *def_n = def_node(varnode);
|
||||
node *body = DEF_NODE_BODY(def_n);
|
||||
int sym = new_sym(s, def_n->name);
|
||||
|
||||
/* For now, generate simple method definition - this can be optimized later */
|
||||
if (body) {
|
||||
codegen(s, body, val);
|
||||
}
|
||||
else if (val) {
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
push();
|
||||
}
|
||||
/* Call lambda_body_ex directly with individual parameters */
|
||||
/* For NODE_DEF, args should contain the full locals structure from defn_setup */
|
||||
int idx = lambda_body_ex(s, NULL, def_n->args, def_n->body, 0);
|
||||
|
||||
genop_1(s, OP_TCLASS, cursp());
|
||||
push();
|
||||
genop_2(s, OP_METHOD, cursp(), idx);
|
||||
push(); pop();
|
||||
pop();
|
||||
genop_2(s, OP_DEF, cursp(), sym);
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
/* Helper function for generating class/module/singleton class body */
|
||||
@@ -5089,18 +5103,8 @@ gen_block_var(codegen_scope *s, node *varnode, int val)
|
||||
|
||||
struct mrb_ast_block_node *n = block_node(varnode);
|
||||
|
||||
// Create stack-allocated node structure for lambda_body call
|
||||
struct mrb_ast_node stack_nodes[4];
|
||||
stack_nodes[0].car = (node*)NODE_BLOCK;
|
||||
stack_nodes[0].cdr = &stack_nodes[1];
|
||||
stack_nodes[1].car = n->locals;
|
||||
stack_nodes[1].cdr = &stack_nodes[2];
|
||||
stack_nodes[2].car = n->args;
|
||||
stack_nodes[2].cdr = &stack_nodes[3];
|
||||
stack_nodes[3].car = n->body;
|
||||
stack_nodes[3].cdr = NULL;
|
||||
|
||||
int idx = lambda_body(s, &stack_nodes[1], 1);
|
||||
/* Call lambda_body_ex directly with individual parameters */
|
||||
int idx = lambda_body_ex(s, n->locals, n->args, n->body, 1);
|
||||
genop_2(s, OP_BLOCK, cursp(), idx);
|
||||
push();
|
||||
}
|
||||
@@ -5532,18 +5536,8 @@ gen_lambda_var(codegen_scope *s, node *varnode, int val)
|
||||
|
||||
struct mrb_ast_lambda_node *n = lambda_node(varnode);
|
||||
|
||||
// Create stack-allocated node structure for lambda_body call
|
||||
struct mrb_ast_node stack_nodes[4];
|
||||
stack_nodes[0].car = (node*)NODE_LAMBDA;
|
||||
stack_nodes[0].cdr = &stack_nodes[1];
|
||||
stack_nodes[1].car = n->locals;
|
||||
stack_nodes[1].cdr = &stack_nodes[2];
|
||||
stack_nodes[2].car = n->args;
|
||||
stack_nodes[2].cdr = &stack_nodes[3];
|
||||
stack_nodes[3].car = n->body;
|
||||
stack_nodes[3].cdr = NULL;
|
||||
|
||||
int idx = lambda_body(s, &stack_nodes[1], 1);
|
||||
/* Call lambda_body_ex directly with individual parameters */
|
||||
int idx = lambda_body_ex(s, n->locals, n->args, n->body, 1);
|
||||
genop_2(s, OP_LAMBDA, cursp(), idx);
|
||||
push();
|
||||
}
|
||||
@@ -5719,15 +5713,12 @@ static void
|
||||
gen_sdef_var(codegen_scope *s, const node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_sdef_node *sdef = sdef_node(varnode);
|
||||
|
||||
// Extract components and call codegen_sdef logic directly
|
||||
node *recv = sdef->obj;
|
||||
mrb_sym method_sym = sdef->name;
|
||||
node *args_body = sdef->args;
|
||||
node *body = sdef->body;
|
||||
int sym = new_sym(s, sdef->name);
|
||||
|
||||
int sym = new_sym(s, method_sym);
|
||||
int idx = lambda_body(s, args_body ? args_body : body, 0);
|
||||
/* Call lambda_body_ex directly with individual parameters */
|
||||
/* For NODE_SDEF, args should contain the full locals structure from defs_setup */
|
||||
int idx = lambda_body_ex(s, NULL, sdef->args, sdef->body, 0);
|
||||
|
||||
codegen(s, recv, VAL);
|
||||
pop();
|
||||
|
||||
Reference in New Issue
Block a user