Remove NODE_SCALL and NODE_FCALL node types, consolidating all method calls
into a single NODE_CALL variable-sized node structure. This simplifies the
AST by unifying call semantics while maintaining support for safe navigation
and different call types through node flags.
Key changes:
- Convert call nodes to use variable-sized allocation with call_node structure
- Unify new_call() and new_fcall() to create NODE_CALL nodes consistently
- Replace gen_call() with separate gen_call_var() and gen_call_assign_var()
- Add gen_call_assign_var() for assignment operations like h[k] = v
- Remove legacy call handling from main codegen switch statement
- Preserve argument structure using args pointer instead of unpacking
- Support safe calls, keyword arguments, and blocks in unified structure
This migration maintains backward compatibility while enabling more efficient
call node processing and reduced code duplication in the compiler.
Co-authored-by: Claude <noreply@anthropic.com>
Complete migration of method definition nodes to variable-sized format:
- Convert NODE_DEF and NODE_SDEF from fixed cons-based to variable-sized nodes
- Update parser to create variable-sized def/sdef nodes directly
- Remove old codegen_def and codegen_sdef functions
- Consolidate method setup logic in defn_setup function
- Rename lambda_body_ex to lambda_body after removing wrapper layer
- Update all method definition code generation to use new node structure
This completes the variable-sized node migration for method definitions,
improving memory efficiency and enabling more flexible AST handling.
Co-authored-by: Claude <noreply@anthropic.com>
Clean up function names by removing unnecessary _var suffixes for
consistency with other assignment functions.
Co-authored-by: Claude <noreply@anthropic.com>
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>
Convert NODE_LVAR and NODE_ARG from cons-list to variable-sized nodes.
Remove new_lvar wrapper and use new_xvar directly. Update parser
semantic functions and cleanup gen_assignment. Rename codegen_lvar
to gen_lvar for consistency.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic from new_op_asgn() that created traditional
cons-list nodes when var_nodes_enabled was false. Now always creates
variable-sized nodes using struct mrb_ast_op_asgn_node.
Also remove traditional NODE_OP_ASGN codegen path and unused
codegen_op_asgn function, completing the migration to variable-sized
nodes for all operator assignment patterns.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic from new_asgn() and inline new_asgn_var() helper
function for cleaner implementation. Assignment expressions maintain proper
value semantics while using more efficient memory allocation.
Changes:
- Remove var_nodes_enabled conditional in new_asgn()
- Inline new_asgn_var() logic directly into new_asgn()
- Remove new_asgn_var() function and declaration
- Remove NODE_ASGN case from main codegen() switch
- Update gen_asgn_var() to use direct struct field access
- Remove traditional codegen_asgn() function
Co-authored-by: Claude <noreply@anthropic.com>
Update codegen_op_asgn() to handle variable-sized nodes wrapped in NODE_VARIABLE
instead of assuming traditional cons-list format. Remove obsolete traditional
node type checks since NODE_CONST and NODE_CVAR now always use variable-sized
nodes.
The ||= operator generates special exception-handling bytecode for undefined
constant/class variable detection that requires checking the node type to
apply proper optimization.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic from new_const() and inline new_const_var() helper
function for cleaner implementation. Update codegen to handle NODE_CONST
in both variable-sized access and assignment contexts.
Changes:
- Remove var_nodes_enabled conditional in new_const()
- Inline new_const_var() logic directly into new_const()
- Remove new_const_var() function and declaration
- Remove NODE_CONST case from main codegen() switch
- Add NODE_CONST support in gen_assignment() for variable-sized nodes
- Inline codegen_const() logic into gen_const_var()
- Remove traditional codegen_const() function
Co-authored-by: Claude <noreply@anthropic.com>
Remove var_nodes_enabled conditional from new_nvar() and traditional
NODE_NVAR case from codegen. All numbered parameter operations now use
unified variable-sized node handling.
Co-authored-by: Claude <noreply@anthropic.com>
Remove remaining NODE_GVAR/IVAR/CVAR cases from codegen switch statements
since parser now always creates variable-sized nodes. All variable operations
now use unified NODE_VARIABLE handling.
Co-authored-by: Claude <noreply@anthropic.com>
Remove traditional NODE_BLOCK_ARG support from main codegen() switch and
eliminate synthetic node creation in gen_block_arg_var. The function now
handles the variable-sized node directly without creating temporary
traditional nodes on the stack.
This completes the NODE_BLOCK_ARG migration by removing the dual handling
pattern while maintaining the gen_block_arg_var function for better code
organization and readability.
Co-authored-by: Claude <noreply@anthropic.com>
remove NODE_POSTEXE from main codegen function and inline gen_postexe_var
into codegen_variable_node. remove unused codegen_postexe function since
NODE_POSTEXE is now only a marker like NODE_ARGS
Co-authored-by: Claude <noreply@anthropic.com>
migrate new_args_tail to always create variable-sized nodes and remove
legacy conditional logic from lambda_body. remove NODE_ARGS_TAIL from
codegen_variable_node since it is now only a marker like NODE_ARGS
Co-authored-by: Claude <noreply@anthropic.com>
remove conditional from new_splat to always create variable-sized nodes and
eliminate traditional NODE_SPLAT case from codegen switch. update splat marker
detection throughout codegen to handle variable-sized format and inline
codegen_splat logic into gen_splat_var.
Co-authored-by: Claude <noreply@anthropic.com>
remove codegen_negate wrapper function and inline its logic directly
into gen_negate_var. this completes NODE_NEGATE migration cleanup.
Co-authored-by: Claude <noreply@anthropic.com>
remove codegen_undef wrapper function and inline its logic directly
into gen_undef_var. this completes NODE_UNDEF migration cleanup.
Co-authored-by: Claude <noreply@anthropic.com>
remove unused node cases and their corresponding codegen functions from
traditional codegen switch. these nodes are fully migrated to variable-sized
implementation where parser only generates variable-sized nodes via
NODE_VARIABLE wrapper.
Co-authored-by: Claude <noreply@anthropic.com>
Remove traditional NODE_BACK_REF case and inline codegen_back_ref logic into
gen_back_ref_var. NODE_BACK_REF now exclusively uses variable-sized nodes,
directly accessing the type field from the node structure instead of converting
through int_to_node/node_to_char.
Co-authored-by: Claude <noreply@anthropic.com>
Remove traditional NODE_NTH_REF case and inline codegen_nth_ref logic into
gen_nth_ref_var. NODE_NTH_REF now exclusively uses variable-sized nodes,
directly accessing the nth value from the node structure instead of converting
through int_to_node/node_to_int.
Co-authored-by: Claude <noreply@anthropic.com>
Remove unused codegen_self function and inline its simple OP_LOADSELF logic
directly into gen_self_var. This eliminates unnecessary function call overhead
and simplifies the codebase.
Co-authored-by: Claude <noreply@anthropic.com>
Remove unused codegen_nil function and inline its simple OP_LOADNIL logic
directly into gen_nil_var. This eliminates unnecessary function call overhead
and simplifies the codebase.
Co-authored-by: Claude <noreply@anthropic.com>
Remove traditional NODE_HASH and NODE_KW_HASH cases from switch statement.
Inline codegen_hash logic into gen_kw_hash_var and remove unused codegen_hash function.
Parser already creates variable-sized nodes exclusively, so all hash operations
now route through gen_hash_var() and gen_kw_hash_var() respectively.
Co-authored-by: Claude <noreply@anthropic.com>
Remove separate new_block_var function and inline its logic directly into
new_block() to follow the same pattern used for other node migrations.
Co-authored-by: Claude <noreply@anthropic.com>
Migrated both NODE_BLOCK and NODE_LAMBDA to use variable-sized nodes exclusively
while fixing compatibility issues with mixed node structures.
Parser changes:
- new_block() and new_lambda() always create variable-sized nodes
- temporarily disabled var_nodes_enabled to avoid mixed node structure issues
Codegen changes:
- removed codegen_block() and codegen_lambda() functions
- removed traditional NODE_BLOCK and NODE_LAMBDA cases from switch statement
- inlined logic into gen_block_var() and gen_lambda_var() using stack-allocated structures
- fixed lambda_body() to handle both variable-sized and cons-list NODE_ARGS_TAIL
- restored OP_KEYEND generation logic for proper keyword argument validation
All tests pass with improved memory efficiency through direct struct access.
Co-authored-by: Claude <noreply@anthropic.com>
Complete NODE_STMTS migration by removing unused codegen_stmts function
and inlining statement traversal logic directly into gen_stmts_var.
Co-authored-by: Claude <noreply@anthropic.com>
These node types always generate variable-sized nodes, so the cons-list
codegen support is no longer needed. This change:
codegen.c:
- Moves logic from codegen_break/next/redo/retry into gen_*_var functions
- Removes cons-list switch cases for these four node types
- Removes the now-unused codegen_break/next/redo/retry functions
parse.y:
- Updates call_with_block to handle NODE_BREAK and NODE_NEXT through
NODE_VARIABLE case instead of cons-list cases
- Removes the now-unused cons-list cases for these node types
All control flow functionality remains identical, but the code path is
simplified since these nodes exclusively use variable-sized structures.
Co-authored-by: Claude <noreply@anthropic.com>
Unified gen_class_var, gen_module_var, and gen_sclass_var functions by extracting
common patterns into two helper functions:
- gen_class_body() handles body generation for all three types
- gen_namespace() handles namespace/parent setup for class and module
This refactoring eliminates approximately 40 lines of duplicated code while
maintaining identical functionality and bytecode generation patterns.
Co-authored-by: Claude <noreply@anthropic.com>
- Implement complete variable-sized node generation for all class/module types
- gen_class_var(): full class definition with namespace and superclass support
- gen_module_var(): complete module definition with proper scope handling
- gen_sclass_var(): singleton class with object evaluation and OP_SCLASS
- All use scope_body() for proper locals and body management
- Update parser to always create variable-sized nodes
- Inline helper function logic directly into new_class(), new_module(), new_sclass()
- Remove conditional var_nodes_enabled checks for consistency
- Eliminate separate _var helper functions
- Remove obsolete traditional node handling
- Delete codegen_class(), codegen_module(), codegen_sclass() functions
- Remove NODE_CLASS, NODE_MODULE, NODE_SCLASS cases from main codegen() switch
- Clean up unused function declarations
- All 1730 tests pass, class/module/singleton functionality verified
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_SCOPE case from main codegen() switch and migrate all node
creation to variable-sized nodes. Add node_type_p() helper for unified
node type checking across traditional and variable-sized nodes.
Key fixes:
- Use scope_node(node->cdr) pattern for NODE_VARIABLE wrapper extraction
- Update parser_update_cxt and mrb_parser_foreach_top_variable
- Add NODE_VARIABLE support to mrb_parser_dump for bintest compatibility
- Fix mirb local variable handling preventing TypeError on evaluation
Co-authored-by: Claude <noreply@anthropic.com>
- remove conditional logic from new_rescue() and new_ensure(), always creating variable-sized nodes
- remove unused new_rescue_var() helper function
- remove traditional NODE_RESCUE and NODE_ENSURE cases from main codegen() switch
- inline codegen_rescue() logic directly into gen_rescue_var() for optimal performance
- inline codegen_ensure() logic directly into gen_ensure_var() for optimal performance
- eliminate temporary cons-like structures, using direct variable-sized node field access
- remove now-unused codegen_rescue() and codegen_ensure() functions
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic from new_colon2() to always create variable-sized
nodes. Implement assignment support for variable-sized constant nodes with
dedicated helper functions. Remove obsolete cons list code paths from
gen_assignment() and codegen().
Co-authored-by: Claude <noreply@anthropic.com>
Following the proven NODE_HASH pattern:
- Inlined new_array_var functionality into new_array in parse.y
- Enhanced gen_array_var with full splat support from gen_values
- Removed obsolete codegen_array function and cons list NODE_ARRAY case
- All arrays now use variable-sized nodes with identical test success (1730/1731)
Co-authored-by: Claude <noreply@anthropic.com>
Modified new_hash function to always create variable-sized nodes instead of
conditionally falling back to cons list nodes. This achieves complete
NODE_HASH migration with full test suite compatibility.
Co-authored-by: Claude <noreply@anthropic.com>
Replace JMPIF+JMP pattern with JMPNOT for last condition in each when
clause, allowing when bodies to execute inline. Also eliminate no-op
JMP instructions from else clauses, reducing overall instruction count.
Co-authored-by: Claude <noreply@anthropic.com>
Replace cons-list based case statement implementation with variable-sized
nodes for improved memory efficiency. The new implementation maintains
identical register allocation behavior using the original's proven
"nil-first, align-last" strategy.
Key changes:
- Convert new_case() to create variable-sized mrb_ast_case_node directly
- Replace codegen_case() with gen_case_var() using array iteration
- Apply original register allocation logic to new node structure
- Fix else clause handling in jump dispatch logic
Supports all case statement variants:
- Bare case statements (case when condition)
- Case with values (case expr when condition)
- UPVAR combinations with closure variables
- Splat operations (*case)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove conditional logic and consolidate NODE_FOR implementation to use
variable-sized nodes exclusively. This eliminates dual code paths and
completes the NODE_FOR migration.
Changes:
- inline new_for_var into new_for, remove p->var_nodes_enabled condition
- remove new_for_var function and forward declaration
- enhance gen_for_var with complete for-loop implementation from for_body
- remove codegen_for and for_body functions
- remove NODE_FOR case from main codegen switch (traditional cons-list path)
The for-loop implementation preserves Ruby's each-based semantics with
proper block scoping, argument handling, and loop control (break/next/redo)
while providing better memory efficiency through variable-sized nodes.
Co-authored-by: Claude <noreply@anthropic.com>
Consolidate NODE_WHILE/NODE_UNTIL with MOD variants by sharing structures
and implementations, eliminating redundant code and improving maintainability.
Changes:
- remove separate mrb_ast_while_mod_node and mrb_ast_until_mod_node structures
- share mrb_ast_while_node between NODE_WHILE and NODE_WHILE_MOD variants
- share mrb_ast_until_node between NODE_UNTIL and NODE_UNTIL_MOD variants
- simplify new_while_mod to call new_while and update node_type
- simplify new_until_mod to call new_until and update node_type
- update gen_while_mod_var and gen_until_mod_var to use shared structures
The MOD variants now reuse core allocation logic from regular variants,
differing only in node_type. This eliminates code duplication while
preserving identical functionality for both pre-tested and post-tested loops.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional logic and consolidate NODE_IF implementation to use
variable-sized nodes exclusively. This eliminates dual code paths and
completes the NODE_IF migration started in previous commits.
Changes:
- inline new_if_var into new_if, remove p->var_nodes_enabled condition
- remove new_unless function, replace calls with new_if (swap then/else)
- remove codegen_if function, merge nil? optimization into gen_if_var
- remove NODE_IF case from main codegen switch (always wrapped in NODE_VARIABLE)
- fix nil? optimization to handle both traditional and variable-sized nodes
- update gen_if_var to use direct struct field access instead of macros
The nil? optimization now works with both node representations:
- Traditional: NODE_TYPE(condition) == NODE_CALL (preserved)
- Variable-sized: NODE_VARIABLE wrapper containing NODE_CALL struct
This ensures obj.nil? patterns generate optimized OP_JMPNIL bytecode
regardless of AST node representation.
Co-authored-by: Claude <noreply@anthropic.com>
Replace dual integer parsing paths with two-tier system:
- NODE_INT stores int32_t values directly for common case
- NODE_BIGINT stores string representation for overflow values
- Custom read_int32() function provides locale-independent parsing
- Remove unused readint() function from codegen
This eliminates confusing dual code paths while maintaining performance
for the majority of integer literals that fit in 32-bit range.
Co-authored-by: Claude <noreply@anthropic.com>
Fix mrb_bint_new_str to normalize bigint objects to regular integers
when possible. This ensures consistent object types for values that
fit in mrb_int range, fixing comparison failures in tests.
Co-authored-by: Claude <noreply@anthropic.com>
Remove obsolete cons-list node cases since control flow nodes (break,
return, next, redo, retry) and logical operators (and, or) are now
always created as variable-sized nodes. Move and/or handling to inner
switch with proper struct field access.
Co-authored-by: Claude <noreply@anthropic.com>
Remove obsolete cons-list node cases and simplify structure to direct
conditional since only NODE_VARIABLE wrapper needs to be handled after
variable-sized node migration.
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional var_nodes_enabled logic from new_nil and new_self functions.
These functions now directly create variable-sized AST nodes using proper
size classes and memory allocation. Remove helper functions new_nil_var and
new_self_var as they are no longer needed.
Also update codegen to handle the new variable-sized node structure:
- Add NODE_VARIABLE handling to gen_assignment function
- Fix self-method call detection in call generation
- Update assignment generation to properly handle variable-sized nil nodes
Co-authored-by: Claude <noreply@anthropic.com>
Remove conditional var_nodes_enabled logic from new_and and new_or functions.
These functions now directly create variable-sized AST nodes using proper
size classes and memory allocation. Also remove unused codegen_and and
codegen_or functions as all code generation now goes through the variable-sized
node handlers gen_and_var and gen_or_var with proper short-circuit evaluation.
Co-authored-by: Claude <noreply@anthropic.com>
Removed traditional NODE_ALIAS case from main codegen() switch and
inlined codegen_alias() logic directly into gen_alias_var(). This
eliminates the hybrid approach that created temporary stack structures
and provides direct access to variable-sized node fields.
Co-authored-by: Claude <noreply@anthropic.com>
Updated new_float() to always create variable-sized nodes and removed
the conditional logic. Also updated codegen_negate() to handle
NODE_VARIABLE wrapper containing NODE_FLOAT for negative float literals.
Co-authored-by: Claude <noreply@anthropic.com>