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>
- Remove conditional var_nodes_enabled logic from new_return
- Delete unused new_return_var function and forward declaration
- Move NODE_RETURN handling to NODE_VARIABLE branch in call_with_block
- Remove traditional NODE_RETURN case from main codegen function
- Inline codegen_return logic directly into gen_return_var
This completes the modernization of return node handling to exclusively
use variable-sized nodes throughout the compiler pipeline.
Co-authored-by: Claude <noreply@anthropic.com>
- Remove conditional var_nodes_enabled logic from new_yield
- Delete unused new_yield_var function and forward declaration
- Move NODE_YIELD handling to NODE_VARIABLE branch in call_with_block
- Remove traditional NODE_YIELD case from main codegen function
- Inline codegen_yield logic directly into gen_yield_var
This completes the modernization of yield node handling to exclusively
use variable-sized nodes throughout the compiler pipeline.
Co-authored-by: Claude <noreply@anthropic.com>
- update NODE_ZSUPER to use mrb_ast_super_node instead of empty mrb_ast_zsuper_node
- convert new_super and new_zsuper to always create variable-sized nodes
- update call_with_block to handle NODE_SUPER/NODE_ZSUPER wrapped in NODE_VARIABLE
- inline codegen_super and codegen_zsuper into their gen_*_var functions
- remove traditional NODE_SUPER and NODE_ZSUPER cases from codegen
Co-authored-by: Claude <noreply@anthropic.com>
Remove var_nodes_enabled conditions from new_dot2 and new_dot3 functions
and inline variable-sized node creation logic directly. Clean up obsolete
codegen paths by removing case NODE_DOT2 and NODE_DOT3 from traditional
codegen() and removing unused codegen_dot2 and codegen_dot3 functions.
Update gen_dot2_var and gen_dot3_var to use proper DOT2/DOT3_NODE macros
and generate OP_RANGE_INC/EXC instructions directly.
Co-authored-by: Claude <noreply@anthropic.com>
Remove var_nodes_enabled condition from new_sym function and inline
new_sym_var directly. Clean up obsolete codegen paths by removing
case NODE_SYM from traditional codegen() and inlining codegen_sym
into variable-sized node handler. Remove unused new_sym_original
helper function.
Co-authored-by: Claude <noreply@anthropic.com>
Complete the conversion of boolean literal nodes by:
1. Convert new_true to always use variable-sized nodes and inline new_true_var
directly into the function, eliminating function call overhead
2. Remove obsolete NODE_TRUE case from traditional codegen() and inline
codegen_true function into gen_true_var for cleaner code
3. Apply the same optimizations to new_false - inline new_false_var and
remove obsolete NODE_FALSE case and codegen_false function
4. Clean up unused functions and forward declarations
Both true and false literals now always use the variable-sized node path
with direct OP_LOADT/OP_LOADF instruction generation, eliminating
conditional branching and function call overhead.
Co-authored-by: Claude <noreply@anthropic.com>
Temporarily revert new_call to avoid issues with assignment to method calls
like self[idx] = value causing "unknown lhs" errors. The function now always
uses traditional cons-list NODE_CALL/NODE_SCALL nodes instead of variable-sized
nodes to maintain compatibility with existing assignment codegen.
Co-authored-by: Claude <noreply@anthropic.com>
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>
Remove var_nodes_enabled condition from new_dsym function, completing the
transition to variable-sized nodes for dynamic symbol processing.
Fix gen_dsym_var function to properly extract the dsym node using the
dsym_node() macro and simplify the codegen pattern to match traditional
codegen_dsym behavior.
Remove unused codegen_dsym function and its corresponding NODE_DSYM case
from the main codegen switch, cleaning up dead traditional codegen paths.
Co-authored-by: Claude <noreply@anthropic.com>
Remove unused codegen_words and codegen_symbols functions along with their
corresponding cases in the main codegen switch. These became dead code
after converting new_words and new_symbols to always use variable-sized nodes.
Also remove var_nodes_enabled conditions from new_words and new_symbols,
completing the transition to always using variable-sized nodes for word and
symbol arrays.
Co-authored-by: Claude <noreply@anthropic.com>
Add helper functions to simplify string representation creation in cons format:
- new_str_rep(p, str, len): creates cons(length, string_ptr)
- new_str_tok(p): creates string representation from current token
- new_str_empty(p): creates empty string representation
This reduces code duplication and improves readability by replacing
verbose patterns like cons(int_to_node(toklen(p)), (node*)strndup(...))
with cleaner helper function calls.
Co-authored-by: Claude <noreply@anthropic.com>
NODE_LITERAL_DELIM was only used as a marker in literal arrays.
Replace it with a (0 . 0) pattern which cannot conflict with
empty strings (which would be (0 . ptr) with non-NULL ptr).
This allows removing NODE_LITERAL_DELIM from the node type enum.
Co-authored-by: Claude <noreply@anthropic.com>
NODE_DREGX_ONCE was defined but never used in the codebase. No creation
functions, no codegen cases, and no parser rules reference this node type.
Removed:
- NODE_DREGX_ONCE enum value
- struct mrb_ast_dregx_once_node definition
- dregx_once_node() macro
- DREGX_ONCE_NODE_LIST() and DREGX_ONCE_NODE_OPTIONS() macros
Co-authored-by: Claude <noreply@anthropic.com>
Rename NODE_DSTR to NODE_STR and NODE_DXSTR to NODE_XSTR to reflect
that all strings now use dynamic (cons list) representation. Also
rename all associated functions for consistency:
- gen_dstr_var() -> gen_str_var()
- gen_dxstr_var() -> gen_xstr_var()
- codegen_heredoc_dstr() -> codegen_heredoc_str()
- codegen_dxstr() -> codegen_xstr()
The "D" prefix is no longer meaningful since all strings use the
variable-sized cons list format ((len . ptr) (-1 . node)...).
Co-authored-by: Claude <noreply@anthropic.com>
Remove NODE_STR and NODE_XSTR enum values and all associated code as these
traditional node types are no longer used with the new cons list string
representation. The compiler now exclusively uses the cons list format
((len . str) (-1 . node)...) for all string types.
- remove NODE_STR and NODE_XSTR from node_type enum in node.h
- remove NODE_STR and NODE_XSTR cases from codegen.c switch statements
- remove NODE_STR and NODE_XSTR cases from parse.y codedump functions
- remove unused codegen_str(), codegen_xstr(), and gen_xstr_var() functions
- update codegen_dregx() to use cons list string handling instead of
checking for obsolete NODE_STR
- preserve str_dump() function wrapped in #if 0 for future codedump updates
- update comment in node.h to reflect current node types
NODE_DSTR remains available for dynamic string interpolation. All string
functionality continues to work via the cons list representation and
variable-sized node implementations.
Co-authored-by: Claude <noreply@anthropic.com>
- change AST string representation from traditional node list to cons list
format where elements are either (len . str) for literals or (-1 . node)
for expressions
- implement codegen_cons_list_string() to handle new string format across
all string types (heredoc, dstr, xstr, dxstr, literal arrays)
- fix heredoc interpolation producing garbage by wrapping expressions as
(-1 . node) in parse.y heredoc_body rule instead of pushing directly
- fix backtick commands not executing in NOVAL mode by modifying
gen_dxstr_var and codegen_xstr to always generate OP_SSEND calls
- update gen_literal_array() to properly handle cons list format with
NODE_LITERAL_DELIM separators for %w[] and %i[] arrays
- refactor all dstr/dxstr/dregx variable node generators to use new format
- both simple `cmd` and dynamic `cmd #{var}` backticks now execute
correctly even when result is discarded
- all mrbtest cases now pass (1730/1731)
Co-authored-by: Claude <noreply@anthropic.com>
Previously the lexer dynamically called new_regx() and new_str() functions
which created different node types based on the var_nodes_enabled flag,
causing complexity in grammar actions and requiring dynamic dispatch handling.
This change simplifies the architecture by:
- Making lexer always return traditional cons structures:
- tREGEXP: (NODE_REGX . (pattern . (flags . encoding)))
- tSTRING: (NODE_STR . (string . length))
- Moving variable node generation to grammar actions where it belongs
- Simplifying new_dregx() to always receive traditional cons structures
- Updating mrb_ast_dregx_node to store the whole regx structure
This eliminates dynamic dispatch complexity and centralizes variable node
creation in grammar actions, making the code flow cleaner and more predictable.
Co-authored-by: Claude <noreply@anthropic.com>
Remove if (!p->var_nodes_enabled) branch from new_nth_ref function
to use variable-sized nodes exclusively for numbered regex references.
Co-authored-by: Claude <noreply@anthropic.com>
Remove if (!p->var_nodes_enabled) branch from new_back_ref function
to use variable-sized nodes exclusively for regex backreferences.
Co-authored-by: Claude <noreply@anthropic.com>
Remove if (!p->var_nodes_enabled) branch from new_dxstr function
to use variable-sized nodes exclusively for dynamic execution strings.
Co-authored-by: Claude <noreply@anthropic.com>
- Modified new_undef to accept node *syms list instead of single mrb_sym
- Simplified gen_undef_var to directly pass symbol list
- Removed traditional node generation path from new_negate
- Both functions now use variable-sized nodes exclusively
Co-authored-by: Claude <noreply@anthropic.com>
- Update new_undef function signature to accept node list instead of single symbol
- Fix grammar rule to properly construct undef nodes from symbol lists
- Simplify gen_undef_var function to directly pass symbol list to codegen
- Support multiple symbols in single undef statement (e.g., undef foo, bar)
Co-Authored-By: Claude <noreply@anthropic.com>
This removes the legacy `cons` node creation path from several `new_*`
functions, forcing them to use the variable-sized node implementation.
This is a step towards simplifying the parser and unifying the AST
representation.
Co-authored-by: Claude <noreply@anthropic.com>
Removes NODE_METHOD from the node type enum as this node type is not used
in the current parser implementation.
Co-authored-by: Claude <noreply@anthropic.com>
Removes NODE_CDECL, NODE_CVASGN, NODE_CVDECL, NODE_ITER, and NODE_WHEN
from the node type enum as these node types are not used in the current
parser implementation.
Co-authored-by: Claude <noreply@anthropic.com>
Implements variable-sized AST node support for Group 16 declarations and
definitions including NODE_ALIAS, NODE_POSTEXE, NODE_UNDEF, and NODE_SDEF.
This continues the systematic implementation of memory-efficient variable-
sized nodes across the mruby compiler's AST infrastructure.
Co-authored-by: Claude <noreply@anthropic.com>
Successfully implement NODE_SCOPE, NODE_BEGIN, and NODE_ENSURE as
variable-sized nodes. These structural nodes benefit from optimized
memory allocation and improved cache locality while maintaining
compatibility with existing codegen patterns.
Key improvements:
- NODE_SCOPE: Function scope definitions with variable-sized allocation
- NODE_BEGIN: Begin block structures with optimized memory layout
- NODE_ENSURE: Exception handling blocks with efficient storage
- All tests passing (1730/1731) with existing variable-sized nodes
- NODE_STMTS remains traditional to avoid codegen complexity
This extends the variable-sized node optimization to cover the primary
structural elements of the AST while keeping statement list handling
in its proven traditional form.
Co-authored-by: Claude <noreply@anthropic.com>
Add variable-sized node support for containers (array, hash, words, symbols)
and arguments (splat, to_ary, svalue, block_arg) to optimize memory usage
for statement blocks and argument processing.
Co-authored-by: Claude <noreply@anthropic.com>
Add variable-sized node support for containers (array, hash, words, symbols)
and arguments (splat, to_ary, svalue, block_arg) to optimize memory usage
for statement blocks and argument processing.
Co-authored-by: Claude <noreply@anthropic.com>
Implements variable-sized nodes for function calls and special forms
(NODE_FCALL, NODE_ZSUPER, NODE_LAMBDA) 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>
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>
Implements variable-sized nodes for references and variables (NODE_NTH_REF,
NODE_BACK_REF, NODE_DVAR, NODE_NVAR, NODE_MATCH) 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>
added variable-sized nodes for control flow and string/regex variants:
- control flow: break, next, redo, retry, while_mod, until_mod
- string/regex: xstr, dxstr, dregx, heredoc, dsym
- proper integration with existing codegen patterns
- maintains backward compatibility with traditional nodes
- tested with control flow and string interpolation
Co-authored-by: Claude <noreply@anthropic.com>