Enhanced NODE_HASH dump to detect and display the double-splat operator
(**) in a readable format. When a hash contains **other_hash syntax,
the parser represents ** as MRB_OPSYM(pow). Instead of dumping this
complex operator node, now displays a clean "**" for better readability.
This makes hash dumps with splat operations much easier to understand
and debug.
Co-authored-by: Claude <noreply@anthropic.com>
Enhanced NODE_FOR dump to properly handle the cons-list structure of
FOR_NODE_VAR with clear section labels. The structure contains:
- car: cons-list of pre-splat variables
- cdr->car: splat varnode (not a cons-list)
- cdr->cdr->car: cons-list of post-splat variables
Added "splat var:" and "post var:" labels to distinguish sections
and simplified the dump logic for better readability.
Co-authored-by: Claude <noreply@anthropic.com>
Implement NODE_MARG as a dedicated node type for parameter destructuring
to separate it architecturally from general multiple assignment (NODE_MASGN).
This resolves crashes when dumping parameter destructuring nodes and
improves code organization.
Key changes:
- Add NODE_MARG to node type enum
- Create new_marg() function for parameter destructuring
- Consolidate new_masgn() and new_marg() using shared helper
- Fix parameter context checks in lambda_body() to use NODE_MARG only
- Enable shared dumping logic for both NODE_MASGN and NODE_MARG
- Optimize memory management with immediate RHS cleanup
- Combine gen_assignment() cases for code deduplication
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The NODE_CASE dump was treating the case body as a single varnode,
but it's actually a cons-list structure containing when clauses.
Changed to iterate through the cons-list similar to rescue clauses,
allowing proper display of when conditions and bodies.
Co-authored-by: Claude <noreply@anthropic.com>
Refactored NODE_MASGN from single lhs field to separate pre/rest/post
fields for cleaner multiple assignment handling. Fixed segfault when
compiling methods with destructured parameters by properly handling
parameter destructuring in lambda_body function.
Co-authored-by: Claude <noreply@anthropic.com>
Fixed copy-paste error where NODE_SUPER and NODE_ZSUPER cases in
dump_node incorrectly used CALL_NODE_ARGS macro instead of
SUPER_NODE_ARGS, causing segmentation faults when parser dump
tried to access invalid memory addresses.
Co-authored-by: Claude <noreply@anthropic.com>
Replace direct cons-list access (tree->car, tree->cdr->cdr) with
proper accessor macros (ENSURE_NODE_BODY, ENSURE_NODE_ENSURE_CLAUSE)
to support variable-sized node structures. Adds null checks for
improved safety and follows the same pattern as other migrated nodes.
Co-authored-by: Claude <noreply@anthropic.com>
Add support for dumping NODE_NVAR nodes in dump_node function.
NODE_NVAR represents numbered variables and displays the variable
number for debugging AST structures.
Co-authored-by: Claude <noreply@anthropic.com>
- Skip no-op splats of empty array literals (`*[]` / zarray) in
call argument generation and array literal codegen.
- Inline non-empty literal splat arrays without inner splats
(e.g. `*[a,b]`) as regular positional args/elements, avoiding
building a temporary array and ARYCAT.
This removes unnecessary `LOADNIL` + `ARRAY 0` + `ARYCAT` sequences
(e.g. `mruby -ve 'p *[]'`) and reduces temporary allocations while
preserving semantics and evaluation order. Falls back to the generic
path when nested splats are present or counts exceed fixed-arity.
No behavior change intended; only codegen improvements.
Co-authored-by: Codex <codex@openai.com>
Replace dump_recur() with dump_str() in NODE_HEREDOC case to properly
handle cons-lists of string representations instead of AST nodes.
This fixes segmentation faults when dumping heredoc AST nodes.
Co-authored-by: Claude <noreply@anthropic.com>
Now that all cons-list based codegen_* functions have been removed,
rename the gen_*_var functions to use the consistent codegen_* prefix.
This affects 70 functions and improves code clarity by establishing
a single naming convention for all code generation functions.
- gen_scope_var renamed to codegen_scope_node to avoid conflict with codegen_scope type
- All other gen_*_var functions renamed to codegen_* (removing _var suffix)
- Updated all function calls throughout codegen.c
Co-authored-by: Claude <noreply@anthropic.com>
Renamed the internal implementation from mrb_parser_dump() to dump_node()
to follow the naming convention of other dump functions (dump_prefix,
dump_str, dump_recur). Added a public wrapper mrb_parser_dump() that
calls dump_node() to maintain API compatibility.
Co-authored-by: Claude <noreply@anthropic.com>
Move str_dump function from commented section to active code and update
dump_str to use proper string dumping with escape sequence handling.
Remove obsolete commented str_dump implementation.
Co-authored-by: Claude <noreply@anthropic.com>
Add proper traversal of cons list structure with (0 . 0) separators
for word arrays (%w[]) and symbol arrays (%i[]). Includes safety
checks for pointer validation and length bounds.
Note: Crashes still occur during testing, indicating the issue may
be in accessor macros or data structure alignment.
Co-authored-by: Claude <noreply@anthropic.com>
Remove mrb_ast_method_node structure definition, accessor macro,
and field accessor macro. This structure had no corresponding
node type enum and was never used in the parser or codegen.
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_TO_ARY enum value, structure definition, accessor macro,
and field accessor macro. This node type was never used in the parser
or codegen, despite having complete supporting infrastructure.
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_SVALUE enum value, structure definition, accessor macro,
and accessor function. This node type was never used in the parser
or codegen, despite having supporting infrastructure.
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_MATCH enum value, structure definition, accessor macro,
parser dump case, codegen case, and gen_match_var function. This
node type was never actually used in the parser.
Co-authored-by: Claude <noreply@anthropic.com>
Replace manual pattern parsing with dump_str to properly handle both
simple and dynamic regex patterns. This provides consistent output
format for literal strings and interpolated expressions.
Co-authored-by: Claude <noreply@anthropic.com>
Remove the original NODE_REGX node type and related infrastructure,
then rename NODE_DREGX to NODE_REGX to consolidate regex handling
under a single node type.
Changes based on git diff:
- Remove original mrb_ast_regx_node structure with pattern fields
- Remove gen_regx_var() function handling literal regex patterns
- Remove NODE_REGX case from codegen and parser dump
- Rename NODE_DREGX to NODE_REGX for dynamic regex expressions
- Update all related functions and structure references
Co-authored-by: Claude <noreply@anthropic.com>
Remove the last cons list dependency in codegen.c by inlining codegen_regx()
directly into gen_regx_var(). This eliminates the need to create temporary
cons list structures and directly accesses regex pattern, flags, and
encoding from the variable-sized node structure.
Changes:
- Inline codegen_regx() logic into gen_regx_var()
- Remove codegen_regx() function entirely
- Access regex data directly from mrb_ast_regx_node fields
- Eliminate temporary cons list node creation
Co-authored-by: Claude <noreply@anthropic.com>
Reduce indentation levels by 1 throughout dump_args() for better
formatting consistency and remove duplicated post_mandatory_args
section that was incorrectly placed after keyword_args processing.
Co-authored-by: Claude <noreply@anthropic.com>
Refactor dump_prefix() to extract line numbers from variable-sized node
headers instead of attempting to retrieve them from node parameters.
Also fix potential segmentation fault in get_node_type() by adding
defensive pointer validation.
Key changes:
- Update dump_prefix() signature to accept lineno parameter directly
- Extract line number once at start of mrb_parser_dump() from node header
- Update all helper functions (dump_locals, dump_cpath, dump_args, etc.)
- Systematically update all dump_prefix calls throughout parser dump code
- Add pointer validation in get_node_type() to prevent invalid memory access
This provides accurate line number information in debug output and
eliminates potential crashes from corrupted pointers.
Co-authored-by: Claude <noreply@anthropic.com>
Remove argc, has_kwargs, has_block, and reserved fields from
mrb_ast_call_node since this information can be determined from the
callargs structure at runtime. Simplify new_call() and call_with_block()
functions to eliminate field analysis during parsing.
Add callargs_empty() helper function to check for empty arguments and
update gen_if_var() to use it instead of accessing removed argc field.
This change reduces memory usage per call node while maintaining full
functionality through runtime analysis of the callargs structure.
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_CALLARGS enum value and parser dump case which are no longer
used in the codebase. The struct mrb_ast_callargs exists and is actively
used by new_callargs(), but it doesn't have a mrb_ast_var_header and is
never assigned the NODE_CALLARGS node type.
This cleanup removes dead code from the enum node_type and eliminates
an unreachable parser dump case, since no nodes are ever created with
NODE_CALLARGS type.
The callargs functionality remains fully intact - only the unused enum
value and unreachable dump case are removed.
Co-authored-by: Claude <noreply@anthropic.com>
Eliminate code duplication in gen_string by using a single loop with
a first-element flag instead of separate first element processing.
The previous structure had ~20 lines of duplicated string literal and
expression processing logic. The refactored version uses a unified loop
that handles concatenation only for non-first elements, reducing code
duplication and improving maintainability.
Functionality remains identical - all string interpolation, regex
patterns, and heredoc processing work correctly.
Co-authored-by: Claude <noreply@anthropic.com>
Rename the overly long and poorly descriptive codegen_cons_list_string()
function to gen_string() which is more concise and follows the existing
naming convention where gen_ prefix indicates code generation functions.
This function generates string bytecode from cons-list structures
containing mixed string literals and expressions for interpolation,
used in string interpolation, regex patterns, and heredocs.
Co-authored-by: Claude <noreply@anthropic.com>
Modernize the parser dump functionality to support the post-NODE_VARIABLE
hybrid AST architecture with both variable-sized nodes and traditional
cons-list nodes.
Co-authored-by: Claude <noreply@anthropic.com>
This removes the NODE_VARIABLE enum and associated wrapper system, updating
the parser and codegen to work directly with variable-sized AST nodes.
Key changes:
- Removed NODE_VARIABLE from node.h enum
- Updated parser functions to handle direct variable-sized nodes
- Fixed codegen() main dispatch to detect variable-sized nodes directly
- Added helper functions for node type detection and header access
- Updated all parser and codegen functions to work with modern AST structure
Co-authored-by: Claude <noreply@anthropic.com>
Remove mrb_ast_head_node structure and cons_head() function while maintaining
accurate line number tracking for debugging. Replace cons_head() calls with
cons() calls but preserve NODE_VARIABLE wrapper as requested.
Key changes:
- Remove mrb_ast_head_node struct and head() macro from node.h
- Remove cons_head_gen() function and cons_head() macro from parse.y
- Update SET_LINENO macro to work with variable-sized nodes:
SET_LINENO(c,n) (((struct mrb_ast_var_header*)(c)->cdr)->lineno = (n))
- Restore all 11 SET_LINENO calls in grammar rules to maintain accurate
line number reporting for error messages and debugging
- Convert list1/list2/list3 and all new_*() function calls to use cons()
instead of cons_head() while keeping NODE_VARIABLE wrapper intact
Co-Authored-By: Claude <noreply@anthropic.com>
Updates codegen() function to retrieve filename and line number information
directly from variable-sized node headers instead of assuming traditional
head nodes. Removes dead code for traditional cons-list nodes since all
nodes are now variable-sized.
Co-authored-by: Claude <noreply@anthropic.com>
Eliminates gradual rollout feature flags that controlled variable-sized AST
nodes. Variable-sized nodes are now the default and only behavior, completing
the AST unification and simplification process.
Co-authored-by: Claude <noreply@anthropic.com>
Eliminates NODE_KW_HASH enum, mrb_ast_kw_hash_node struct, gen_kw_hash_var
function, and related macros. All keyword hash functionality now unified
under NODE_HASH, completing the AST simplification.
Co-authored-by: Claude <noreply@anthropic.com>
Removes the new_kw_hash function entirely and replaces all calls with
new_hash, eliminating the distinction between keyword hashes and regular
hashes in the parser. Updates codegen to handle keyword arguments directly
without intermediate cdr references.
Co-authored-by: Claude <noreply@anthropic.com>
This commit eliminates the unused variable node recycling system and
size class categorization that was never utilized in practice:
- Removed size_to_class() and size_class_limit() functions
- Eliminated SIZE_CLASS_* enum and related infrastructure
- Updated init_var_header() to remove size_class parameter
- Simplified all node allocation functions to use direct parser_palloc() calls
- Replaced complex size calculations with simple sizeof() expressions
- Removed hardcoded SIZE_CLASS_MEDIUM references from new_array/new_hash/new_case
This reduces parser_state struct size by 88 bytes and simplifies allocation
logic from conditional branching to direct function calls, while maintaining
identical functionality since nodes go directly to codegen without recycling.
Co-authored-by: Claude <noreply@anthropic.com>
Remove var_free_lists, var_alloc_counts, and var_total_allocated fields
from parser_state struct as they were never used since all nodes go
directly to codegen. Replace parser_alloc_var() wrapper with direct
parser_palloc() calls throughout the codebase, reducing parser memory
footprint by 88 bytes.
Co-authored-by: Claude <noreply@anthropic.com>
Following the same pattern as the case node upgrade (e0f07c9), this
change eliminates the complex flat array packing approach for hash nodes
in favor of simple cons-list storage. The flat array packing provided
no memory benefit since cons lists aren't recycled, while adding
unnecessary complexity to both allocation and traversal logic.
Changes:
- Simplified mrb_ast_hash_node structure from variable-sized flexible
array to fixed-size structure with cons-list pointer
- Reduced new_hash() from complex 30+ line allocation to simple 4-line
pattern matching array node implementation
- Updated gen_hash_var() to use cons-list iteration instead of
interleaved array access (pairs[i*2] for key, pairs[i*2+1] for value)
- Removed HASH_NODE_LEN macro as length tracking is no longer needed
- Maintains identical functionality while reducing code complexity
Co-authored-by: Claude <noreply@anthropic.com>
Replace complex flat array packing with simple cons-list storage to reduce
memory overhead and code complexity. This continues the compiler simplification
work by reverting array nodes to the original memory-efficient approach.
- Remove len/flags fields from mrb_ast_array_node structure
- Eliminate complex two-pass processing (count + copy) in new_array()
- Replace array indexing with cons-list iteration in gen_array_var()
- Reduce parser code from 30+ lines to 4 lines for array creation
- Maintain full functionality with zero test regressions
Following the same successful pattern used for mrb_ast_case_node upgrade,
this change proves that flat array packing provides no memory benefit
since cons lists aren't recycled, while adding unnecessary complexity.
Co-authored-by: Claude <noreply@anthropic.com>
Replace NODE_KW_REST_ARGS wrapper nodes with direct ** symbol markers to
reduce memory overhead and simplify code structure. This continues the
compiler simplification work by unifying keyword rest arguments with
other node types while maintaining full functionality.
Co-authored-by: Claude <noreply@anthropic.com>
Replace NODE_KW_ARG wrapper with direct (key . value) cons structure,
eliminating unnecessary memory overhead and access indirection.
Changes:
- Remove NODE_KW_ARG node type from enum
- Modify new_kw_arg() to return direct cons instead of wrapped structure
- Update codegen.c to use simplified access patterns (k->car->car, k->car->cdr)
- Fix new_args_tail() to handle simplified keyword argument structure
- Remove NODE_KW_ARG case from parser dump function
This reduces memory usage from 3 cons cells to 1 per keyword argument
while maintaining full functionality and following mruby's design priority
of memory efficiency over complexity.
Co-authored-by: Claude <noreply@anthropic.com>
Replace variable-sized NODE_VARIABLE wrapper with fixed-size struct
allocation, following the same pattern as new_args(). This eliminates
the need for NODE_VARIABLE checking and uses direct casting instead.
Changes:
- Remove mrb_ast_var_header from callargs struct
- Use parser_palloc instead of parser_alloc_var for fixed-size allocation
- Update all access points to use direct casting: (struct mrb_ast_callargs*)
- Remove unnecessary backward compatibility code for newly introduced NODE_CALLARGS
Co-authored-by: Claude <noreply@anthropic.com>
Add default case to the switch statement in assignable function to silence C++
compiler warnings about unhandled enumeration values. The default case documents
that other node types don't need special handling in this context.
Co-authored-by: Claude <noreply@anthropic.com>
Rename all 'class' parameter and variable names to 'size_class' to avoid
conflict with C++ class keyword. This affects function parameters in
size_class_limit, parser_alloc_var, parser_free_var, and init_var_header,
as well as local variables in all new_* node creation functions.
Co-authored-by: Claude <noreply@anthropic.com>
Rename mrb_ast_op_asgn_node.operator field to op to avoid conflict with
C++ operator keyword. Update all references including macro definitions
and field access code.
Co-authored-by: Claude <noreply@anthropic.com>
- Remove obsolete NODE_ARGS_TAIL enum value and all references
- Simplify mrb_ast_case_node from variable-sized array back to simple cons-list structure
- Update new_case() function to use original cons-list approach instead of flattening
- Fix infinite loop in gen_case_var() when case statements have no matching clauses
- Improve code readability by renaming pos3 to case_end_jumps in gen_case_var()
- Restore memory-efficient case statement parsing without complex array management
The variable-sized array approach for case nodes provided no memory benefit
since cons lists aren't recycled. This change restores the simpler original
implementation while fixing a critical bug that caused mrbtest to hang
on "register window of calls" test.
Co-authored-by: Claude <noreply@anthropic.com>
NODE_ARGS_TAIL was a legacy enum value no longer created or used
after the conversion to struct-based argument handling. This change:
- Removes the NODE_ARGS_TAIL enum value from node.h
- Removes the unused case from mrb_parser_dump function
- Removes the obsolete assertion in dump_args function
All tests pass and argument forwarding continues to work correctly.
Co-authored-by: Claude <noreply@anthropic.com>