mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: implement variable-sized nodes for operators and expressions
Implements variable-sized nodes for operators and expressions (NODE_NEGATE, NODE_COLON2, NODE_COLON3) with optimized memory allocation. These nodes now use compact variable-sized structures instead of fixed-size headers, reducing AST memory usage. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5724,6 +5724,63 @@ gen_match_var(codegen_scope *s, node *varnode, int val)
|
||||
}
|
||||
}
|
||||
|
||||
// Group 11: Operators and Expressions
|
||||
static void
|
||||
gen_not_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_not_node *n = (struct mrb_ast_not_node*)varnode;
|
||||
// NOT nodes are rarely used - generate method call to !
|
||||
if (val) {
|
||||
codegen(s, n->operand, TRUE);
|
||||
pop();
|
||||
mrb_sym sym = new_sym(s, mrb_intern_lit(s->mrb, "!"));
|
||||
genop_3(s, OP_SEND, cursp(), sym, 0);
|
||||
push();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gen_negate_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_negate_node *n = (struct mrb_ast_negate_node*)varnode;
|
||||
codegen_negate(s, n->operand, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_colon2_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_colon2_node *n = (struct mrb_ast_colon2_node*)varnode;
|
||||
// Generate COLON2 (::) access manually
|
||||
int sym = new_sym(s, n->name);
|
||||
codegen(s, n->base, VAL);
|
||||
pop();
|
||||
genop_2(s, OP_GETMCNST, cursp(), sym);
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
static void
|
||||
gen_colon3_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_colon3_node *n = (struct mrb_ast_colon3_node*)varnode;
|
||||
// Generate COLON3 (::Name) access manually
|
||||
int sym = new_sym(s, n->name);
|
||||
genop_2(s, OP_OCLASS, cursp(), sym);
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gen_defined_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
// DEFINED nodes are rarely used - generate basic implementation
|
||||
(void)varnode; // suppress unused warning
|
||||
if (val) {
|
||||
// For now, just return nil (defined? is complex to implement correctly)
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
push();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gen_args_tail_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
@@ -5972,6 +6029,26 @@ codegen_variable_node(codegen_scope *s, node *varnode, int val)
|
||||
gen_match_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_NOT:
|
||||
gen_not_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_NEGATE:
|
||||
gen_negate_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_COLON2:
|
||||
gen_colon2_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_COLON3:
|
||||
gen_colon3_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_DEFINED:
|
||||
gen_defined_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE; /* Not handled, fall through to main codegen */
|
||||
}
|
||||
|
||||
@@ -787,4 +787,44 @@ struct mrb_ast_match_node {
|
||||
#define DVAR_NODE_NAME(n) (dvar_node(n)->name)
|
||||
#define MATCH_NODE_PATTERN(n) (match_node(n)->pattern)
|
||||
|
||||
// Group 11: Operators and Expressions
|
||||
struct mrb_ast_not_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *operand;
|
||||
};
|
||||
|
||||
struct mrb_ast_negate_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *operand;
|
||||
};
|
||||
|
||||
struct mrb_ast_colon2_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *base;
|
||||
mrb_sym name;
|
||||
};
|
||||
|
||||
struct mrb_ast_colon3_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
mrb_sym name;
|
||||
};
|
||||
|
||||
struct mrb_ast_defined_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *expr;
|
||||
};
|
||||
|
||||
#define not_node(n) ((struct mrb_ast_not_node*)(n))
|
||||
#define negate_node(n) ((struct mrb_ast_negate_node*)(n))
|
||||
#define colon2_node(n) ((struct mrb_ast_colon2_node*)(n))
|
||||
#define colon3_node(n) ((struct mrb_ast_colon3_node*)(n))
|
||||
#define defined_node(n) ((struct mrb_ast_defined_node*)(n))
|
||||
|
||||
#define NOT_NODE_OPERAND(n) (not_node(n)->operand)
|
||||
#define NEGATE_NODE_OPERAND(n) (negate_node(n)->operand)
|
||||
#define COLON2_NODE_BASE(n) (colon2_node(n)->base)
|
||||
#define COLON2_NODE_NAME(n) (colon2_node(n)->name)
|
||||
#define COLON3_NODE_NAME(n) (colon3_node(n)->name)
|
||||
#define DEFINED_NODE_EXPR(n) (defined_node(n)->expr)
|
||||
|
||||
#endif /* MRUBY_COMPILER_NODE_H */
|
||||
|
||||
@@ -1535,14 +1535,35 @@ static node*
|
||||
new_colon2(parser_state *p, node *b, mrb_sym c)
|
||||
{
|
||||
void_expr_error(p, b);
|
||||
return cons_head((node*)NODE_COLON2, cons(b, sym_to_node(c)));
|
||||
if (!p->var_nodes_enabled) {
|
||||
return cons_head((node*)NODE_COLON2, cons(b, sym_to_node(c)));
|
||||
}
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_colon2_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_colon2_node *colon2_node = (struct mrb_ast_colon2_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&colon2_node->hdr, p, NODE_COLON2, class);
|
||||
colon2_node->base = b;
|
||||
colon2_node->name = c;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)colon2_node);
|
||||
}
|
||||
|
||||
/* (:colon3 . c) */
|
||||
static node*
|
||||
new_colon3(parser_state *p, mrb_sym c)
|
||||
{
|
||||
return cons_head((node*)NODE_COLON3, sym_to_node(c));
|
||||
if (!p->var_nodes_enabled) {
|
||||
return cons_head((node*)NODE_COLON3, sym_to_node(c));
|
||||
}
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_colon3_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_colon3_node *colon3_node = (struct mrb_ast_colon3_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&colon3_node->hdr, p, NODE_COLON3, class);
|
||||
colon3_node->name = c;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)colon3_node);
|
||||
}
|
||||
|
||||
/* (:and a b) */
|
||||
@@ -2502,9 +2523,20 @@ call_with_block(parser_state *p, node *a, node *b)
|
||||
static node*
|
||||
new_negate(parser_state *p, node *n)
|
||||
{
|
||||
return cons_head((node*)NODE_NEGATE, n);
|
||||
if (!p->var_nodes_enabled) {
|
||||
return cons_head((node*)NODE_NEGATE, n);
|
||||
}
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_negate_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_negate_node *negate_node = (struct mrb_ast_negate_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&negate_node->hdr, p, NODE_NEGATE, class);
|
||||
negate_node->operand = n;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)negate_node);
|
||||
}
|
||||
|
||||
|
||||
static node*
|
||||
cond(node *n)
|
||||
{
|
||||
|
||||
+1886
-1854
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user