mruby-compiler: convert node_heredoc to variable-sized nodes and cleanup

This completes the conversion of NODE_HEREDOC from traditional cons-list
nodes to variable-sized nodes by:

1. Modified new_heredoc to always use variable-sized nodes with embedded
   parser_heredoc_info struct and updated function signature to return
   info pointer via output parameter
2. Fixed parsing_heredoc_info to handle NODE_VARIABLE wrapper detection
   and return address of embedded struct
3. Updated gen_heredoc_var to use embedded info structure for codegen
4. Removed obsolete NODE_HEREDOC case and codegen_heredoc function from
   traditional codegen path
5. Replaced codegen_heredoc_str wrapper with direct codegen_cons_list_string
   calls for cleaner semantic naming

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-09-03 13:59:48 +09:00
parent 1e52b3d421
commit 87de799cd5
4 changed files with 1121 additions and 1120 deletions
+4 -31
View File
@@ -4307,18 +4307,6 @@ codegen_xstr(codegen_scope *s, node *tree, int val)
if (val) push();
}
/* codegen_cons_list_string forward declaration moved to top of file */
static void
codegen_heredoc_str(codegen_scope *s, node *tree, int val)
{
/* Use common cons list string codegen since tree is now in cons list format */
codegen_cons_list_string(s, tree, val);
}
/* Common function to generate bytecode for cons list string representation
* Handles list of elements where each element is either:
* - (len . str) for string literals
@@ -4843,12 +4831,6 @@ codegen_block_arg(codegen_scope *s, node *tree, int val)
}
}
static void
codegen_heredoc(codegen_scope *s, node *tree, int val)
{
tree = ((struct mrb_parser_heredoc_info*)tree)->doc;
codegen_heredoc_str(s, tree, val);
}
static void
codegen_super(codegen_scope *s, node *tree, int val)
@@ -5780,15 +5762,9 @@ gen_dregx_var(codegen_scope *s, node *varnode, int val)
static void
gen_heredoc_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_heredoc_node *n = (struct mrb_ast_heredoc_node*)varnode;
// For heredocs, we need to handle them similar to strings
if (val) {
mrb_int len;
const char *str = mrb_sym2name_len(s->mrb, n->name, &len);
int off = new_lit_str(s, str, (int)len);
genop_2(s, OP_STRING, cursp(), off);
push();
}
struct mrb_ast_heredoc_node *n = heredoc_node(varnode);
// Process heredoc doc field as cons list string
codegen_cons_list_string(s, n->info.doc, val);
}
static void
@@ -6648,12 +6624,9 @@ codegen(codegen_scope *s, node *tree, int val)
codegen_negate(s, tree, val);
break;
case NODE_HEREDOC:
codegen_heredoc(s, tree, val);
break;
case NODE_STR:
codegen_heredoc_str(s, tree, val);
codegen_cons_list_string(s, tree, val);
break;
+1 -1
View File
@@ -700,7 +700,7 @@ struct mrb_ast_dregx_node {
struct mrb_ast_heredoc_node {
struct mrb_ast_var_header hdr;
mrb_sym name;
struct mrb_parser_heredoc_info info;
};
struct mrb_ast_dsym_node {
+23 -9
View File
@@ -12,6 +12,7 @@
#define YYSTACK_USE_ALLOCA 1
#include <ctype.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <mruby.h>
@@ -2245,18 +2246,27 @@ new_nth_ref(parser_state *p, int n)
/* (:heredoc . a) */
static node*
new_heredoc(parser_state *p)
new_heredoc(parser_state *p, struct mrb_parser_heredoc_info **infop)
{
if (!p->var_nodes_enabled) {
parser_heredoc_info *inf = (parser_heredoc_info*)parser_palloc(p, sizeof(parser_heredoc_info));
return cons_head((node*)NODE_HEREDOC, (node*)inf);
}
size_t total_size = sizeof(struct mrb_ast_heredoc_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_heredoc_node *n = (struct mrb_ast_heredoc_node*)parser_alloc_var(p, total_size, class);
init_var_header(&n->hdr, p, NODE_HEREDOC, class);
n->name = 0; // Will be set by heredoc processing
/* Initialize embedded heredoc info struct */
n->info.allow_indent = FALSE;
n->info.remove_indent = FALSE;
n->info.line_head = FALSE;
n->info.indent = 0;
n->info.indented = NULL;
n->info.type = str_not_parsing; // Will be set by heredoc processing
n->info.term = NULL; // Will be set by heredoc processing
n->info.term_len = 0;
n->info.doc = NULL;
/* Return pointer to embedded info if requested */
*infop = &n->info;
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
@@ -2514,6 +2524,11 @@ parsing_heredoc_info(parser_state *p)
node *nd = p->parsing_heredoc;
if (nd == NULL) return NULL;
/* mrb_assert(nd->car->car == NODE_HEREDOC); */
if (nd->car->car == (node*)NODE_VARIABLE) {
/* Variable-sized heredoc node - return address of embedded info struct */
struct mrb_ast_heredoc_node *heredoc = heredoc_node(NODE_VAR_NODE_PTR(nd->car));
return &heredoc->info;
}
return (parser_heredoc_info*)nd->car->cdr;
}
@@ -6339,8 +6354,7 @@ heredoc_identifier(parser_state *p)
pushback(p, c);
}
tokfix(p);
newnode = new_heredoc(p);
info = (parser_heredoc_info*)newnode->cdr;
newnode = new_heredoc(p, &info);
info->term = strndup(tok(p), toklen(p));
info->term_len = toklen(p);
if (! quote)
File diff suppressed because it is too large Load Diff