mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: add variable-sized literal node support
add variable-sized node structures for literal nodes (dstr, regx, dot2/dot3 ranges, float) with conditional usage based on var_nodes_enabled. includes casting macros, value access macros, creation functions, and codegen support that maintains compatibility with existing traditional codegen functions. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5422,6 +5422,76 @@ gen_super_var(codegen_scope *s, node *varnode, int val)
|
||||
codegen_super(s, args, val);
|
||||
}
|
||||
|
||||
/* Variable-sized literal node generation functions */
|
||||
static void
|
||||
gen_dstr_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_dstr_node *dstr_n = dstr_node(varnode->car);
|
||||
node *list = DSTR_NODE_LIST(dstr_n);
|
||||
|
||||
/* Use traditional dstr codegen logic */
|
||||
codegen_heredoc_dstr(s, list, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_regx_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_regx_node *regx_n = regx_node(varnode->car);
|
||||
const char *pattern = REGX_NODE_PATTERN(regx_n);
|
||||
const char *flags = REGX_NODE_FLAGS(regx_n);
|
||||
const char *encoding = REGX_NODE_ENCODING(regx_n);
|
||||
|
||||
/* Create simple list structure like traditional node */
|
||||
node list_node;
|
||||
node flags_node;
|
||||
list_node.car = (node*)pattern;
|
||||
list_node.cdr = &flags_node;
|
||||
flags_node.car = (node*)flags;
|
||||
flags_node.cdr = (node*)encoding;
|
||||
|
||||
codegen_regx(s, &list_node, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_dot2_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_dot2_node *dot2_n = dot2_node(varnode->car);
|
||||
node *left = DOT2_NODE_LEFT(dot2_n);
|
||||
node *right = DOT2_NODE_RIGHT(dot2_n);
|
||||
|
||||
/* Create simple cons structure like traditional node */
|
||||
node range_node;
|
||||
range_node.car = left;
|
||||
range_node.cdr = right;
|
||||
|
||||
codegen_dot2(s, &range_node, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_dot3_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_dot3_node *dot3_n = dot3_node(varnode->car);
|
||||
node *left = DOT3_NODE_LEFT(dot3_n);
|
||||
node *right = DOT3_NODE_RIGHT(dot3_n);
|
||||
|
||||
/* Create simple cons structure like traditional node */
|
||||
node range_node;
|
||||
range_node.car = left;
|
||||
range_node.cdr = right;
|
||||
|
||||
codegen_dot3(s, &range_node, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_float_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_float_node *float_n = float_node(varnode->car);
|
||||
const char *value = FLOAT_NODE_VALUE(float_n);
|
||||
|
||||
/* Use traditional float codegen logic directly */
|
||||
codegen_float(s, (node*)value, val);
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
codegen_variable_node(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
@@ -5543,6 +5613,26 @@ codegen_variable_node(codegen_scope *s, node *varnode, int val)
|
||||
gen_super_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_DSTR:
|
||||
gen_dstr_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_REGX:
|
||||
gen_regx_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_DOT2:
|
||||
gen_dot2_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_DOT3:
|
||||
gen_dot3_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_FLOAT:
|
||||
gen_float_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE; /* Not handled, fall through to main codegen */
|
||||
}
|
||||
|
||||
@@ -517,4 +517,56 @@ struct mrb_ast_super_node {
|
||||
|
||||
#define SUPER_NODE_ARGS(n) (super_node(n)->args)
|
||||
|
||||
/* Variable-sized literal node structures */
|
||||
struct mrb_ast_dstr_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *list;
|
||||
};
|
||||
|
||||
struct mrb_ast_regx_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
const char *pattern;
|
||||
const char *flags;
|
||||
const char *encoding;
|
||||
};
|
||||
|
||||
struct mrb_ast_dot2_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *left;
|
||||
struct mrb_ast_node *right;
|
||||
};
|
||||
|
||||
struct mrb_ast_dot3_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *left;
|
||||
struct mrb_ast_node *right;
|
||||
};
|
||||
|
||||
struct mrb_ast_float_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
/* Literal node casting macros */
|
||||
#define dstr_node(n) ((struct mrb_ast_dstr_node*)(n))
|
||||
#define regx_node(n) ((struct mrb_ast_regx_node*)(n))
|
||||
#define dot2_node(n) ((struct mrb_ast_dot2_node*)(n))
|
||||
#define dot3_node(n) ((struct mrb_ast_dot3_node*)(n))
|
||||
#define float_node(n) ((struct mrb_ast_float_node*)(n))
|
||||
|
||||
/* Literal node value access macros */
|
||||
#define DSTR_NODE_LIST(n) (dstr_node(n)->list)
|
||||
|
||||
#define REGX_NODE_PATTERN(n) (regx_node(n)->pattern)
|
||||
#define REGX_NODE_FLAGS(n) (regx_node(n)->flags)
|
||||
#define REGX_NODE_ENCODING(n) (regx_node(n)->encoding)
|
||||
|
||||
#define DOT2_NODE_LEFT(n) (dot2_node(n)->left)
|
||||
#define DOT2_NODE_RIGHT(n) (dot2_node(n)->right)
|
||||
|
||||
#define DOT3_NODE_LEFT(n) (dot3_node(n)->left)
|
||||
#define DOT3_NODE_RIGHT(n) (dot3_node(n)->right)
|
||||
|
||||
#define FLOAT_NODE_VALUE(n) (float_node(n)->value)
|
||||
|
||||
#endif /* MRUBY_COMPILER_NODE_H */
|
||||
|
||||
@@ -547,6 +547,11 @@ static node* new_or_var(parser_state *p, node *left, node *right);
|
||||
static node* new_return_var(parser_state *p, node *args);
|
||||
static node* new_yield_var(parser_state *p, node *args);
|
||||
static node* new_super_var(parser_state *p, node *args);
|
||||
static node* new_dstr_var(parser_state *p, node *list);
|
||||
static node* new_regx_var(parser_state *p, const char *pattern, const char *flags, const char *encoding);
|
||||
static node* new_dot2_var(parser_state *p, node *left, node *right);
|
||||
static node* new_dot3_var(parser_state *p, node *left, node *right);
|
||||
static node* new_float_var(parser_state *p, const char *value);
|
||||
|
||||
/* (:if cond then else) */
|
||||
static node*
|
||||
@@ -1128,6 +1133,86 @@ new_super_var(parser_state *p, node *args)
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
/* Variable-sized literal node creation functions */
|
||||
static node*
|
||||
new_dstr_var(parser_state *p, node *list)
|
||||
{
|
||||
size_t total_size = sizeof(struct mrb_ast_dstr_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_dstr_node *n = (struct mrb_ast_dstr_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->hdr, p, NODE_DSTR, class);
|
||||
n->list = list;
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
static node*
|
||||
new_regx_var(parser_state *p, const char *pattern, const char *flags, const char *encoding)
|
||||
{
|
||||
size_t total_size = sizeof(struct mrb_ast_regx_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_regx_node *n = (struct mrb_ast_regx_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->hdr, p, NODE_REGX, class);
|
||||
n->pattern = pattern;
|
||||
n->flags = flags;
|
||||
n->encoding = encoding;
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
static node*
|
||||
new_dot2_var(parser_state *p, node *left, node *right)
|
||||
{
|
||||
size_t total_size = sizeof(struct mrb_ast_dot2_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_dot2_node *n = (struct mrb_ast_dot2_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->hdr, p, NODE_DOT2, class);
|
||||
n->left = left;
|
||||
n->right = right;
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
static node*
|
||||
new_dot3_var(parser_state *p, node *left, node *right)
|
||||
{
|
||||
size_t total_size = sizeof(struct mrb_ast_dot3_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_dot3_node *n = (struct mrb_ast_dot3_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->hdr, p, NODE_DOT3, class);
|
||||
n->left = left;
|
||||
n->right = right;
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
static node*
|
||||
new_float_var(parser_state *p, const char *value)
|
||||
{
|
||||
size_t total_size = sizeof(struct mrb_ast_float_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_float_node *n = (struct mrb_ast_float_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->hdr, p, NODE_FLOAT, class);
|
||||
n->value = strdup(value);
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
/* (:fcall self mid args) */
|
||||
static node*
|
||||
new_fcall(parser_state *p, mrb_sym b, node *c)
|
||||
@@ -1216,6 +1301,9 @@ new_retry(parser_state *p)
|
||||
static node*
|
||||
new_dot2(parser_state *p, node *a, node *b)
|
||||
{
|
||||
if (p->var_nodes_enabled) {
|
||||
return new_dot2_var(p, a, b);
|
||||
}
|
||||
return cons_head((node*)NODE_DOT2, cons(a, b));
|
||||
}
|
||||
|
||||
@@ -1223,6 +1311,9 @@ new_dot2(parser_state *p, node *a, node *b)
|
||||
static node*
|
||||
new_dot3(parser_state *p, node *a, node *b)
|
||||
{
|
||||
if (p->var_nodes_enabled) {
|
||||
return new_dot3_var(p, a, b);
|
||||
}
|
||||
return cons_head((node*)NODE_DOT3, cons(a, b));
|
||||
}
|
||||
|
||||
@@ -1791,7 +1882,13 @@ new_int(parser_state *p, const char *s, int base, int suffix)
|
||||
static node*
|
||||
new_float(parser_state *p, const char *s, int suffix)
|
||||
{
|
||||
node* result = cons((node*)NODE_FLOAT, (node*)strdup(s));
|
||||
node* result;
|
||||
if (p->var_nodes_enabled) {
|
||||
result = new_float_var(p, s);
|
||||
}
|
||||
else {
|
||||
result = cons((node*)NODE_FLOAT, (node*)strdup(s));
|
||||
}
|
||||
if (suffix & NUM_SUFFIX_R) {
|
||||
result = new_rational(p, result);
|
||||
}
|
||||
@@ -1853,6 +1950,9 @@ new_str(parser_state *p, const char *s, size_t len)
|
||||
static node*
|
||||
new_dstr(parser_state *p, node *a)
|
||||
{
|
||||
if (p->var_nodes_enabled) {
|
||||
return new_dstr_var(p, a);
|
||||
}
|
||||
return cons_head((node*)NODE_DSTR, a);
|
||||
}
|
||||
|
||||
@@ -1961,6 +2061,9 @@ new_dsym(parser_state *p, node *a)
|
||||
static node*
|
||||
new_regx(parser_state *p, const char *p1, const char* p2, const char* p3)
|
||||
{
|
||||
if (p->var_nodes_enabled) {
|
||||
return new_regx_var(p, p1, p2, p3);
|
||||
}
|
||||
return cons_head((node*)NODE_REGX, cons((node*)p1, cons((node*)p2, (node*)p3)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user