Interpreter: Complete hash operator implementation#196
Merged
Conversation
- Implement HASH_EXISTS, HASH_DELETE, HASH_KEYS, HASH_VALUES opcodes - Add BytecodeCompiler cases for exists, delete, keys, values - Add BytecodeInterpreter execution for hash opcodes - Add SLOWOP_EXISTS and SLOWOP_DELETE with stub implementations - Implement logical NOT (!) operator for interpreter - Progress: hash.t now reaches line 27 (hash element assignment)
- Add hash assignment case in BinaryOperatorNode visit (BytecodeCompiler line ~1100)
- Handle bareword key autoquoting (IdentifierNode -> string literal)
- Emit HASH_SET opcode for {key} = value
- Document opcode architecture decision in dev/interpreter/OPCODES_ARCHITECTURE.md
- Progress: hash.t now gets past line 25, hash assignment works
- Next: Implement hash access (reading) {key}
- Add SLOWOP_DEREF_HASH opcode (35) for dereferencing hash references
- Handle -> operator with HashLiteralNode (hashref access) and ArrayLiteralNode (arrayref access)
- Implement executeDerefHash in SlowOpcodeHandler
- Track currentTokenIndex for proper error reporting with file/line info
- Bareword key autoquoting works for ->{key}
- Test: ./jperl --interpreter -e 'my %h = (k => "v"); my $r = \%h; print $r->{k}, "\n"' ✅ works!
- Use throwCompilerException instead of RuntimeException for proper error formatting - Errors now include file, line number, and code context (e.g., 'at -e line 3, near...') - Track currentTokenIndex properly before throwing exceptions - Add clear error message for hash slices: '@hash{keys} not yet implemented' - Hash slices are next TODO - they use @ sigil instead of $ for multiple values
- Add SLOWOP_HASH_SLICE (36) and SLOWOP_HASH_SLICE_DELETE (37) opcodes - Implement @hash{'key1', 'key2'} hash slice retrieval - Implement delete @hash{'key1', 'key2'} slice delete - Both return RuntimeArray of values - Bareword key autoquoting works in slices - executeHashSlice and executeHashSliceDelete in SlowOpcodeHandler - Test: ./jperl --interpreter -e 'my %h = (a => 1, b => 2); my @s = @h{"a", "b"}; print "@s\n"' ✅ works! - TODO: Fix hashref slice @$hashref{keys} - currently tries DEREF_ARRAY instead of DEREF_HASH
- Handle BinaryOperatorNode for nested hash assignment (autovivification)
- Use SLOWOP_DEREF_HASH for nested access like $hash{outer}{inner}
- Refactor hash access code to handle both OperatorNode and BinaryOperatorNode left sides
- WIP: Still debugging hashref slices and nested read access
- Added SLOWOP_HASH_SLICE_SET (opcode 38) for hash slice assignment - Implemented RuntimeHash.setSlice() method - Added executeHashSliceSet() handler in SlowOpcodeHandler - Fixed exists operator to properly handle %hash instead of - Fixed delete operator to properly handle %hash instead of - Added bareword autoquoting in exists and delete operators - Hash slice assignment: @hash{keys} = values now works - Tests 1-12 of hash.t now pass (12/24) Known issue: - Hashref slices (@{keys}) still need fixing Current behavior: tries DEREF_ARRAY instead of DEREF_HASH To be addressed in follow-up commit
The issue was that BinaryOperatorNode visit method automatically
compiled left and right operands before the switch statement. This
caused @$hashref{keys} to compile the @ operator first, which emitted
SLOWOP_DEREF_ARRAY instead of letting the {} operator handle it properly
with SLOWOP_DEREF_HASH.
Solution:
- Added special handling before automatic operand compilation
- Check if {} operator has @ operator on left side
- Extract handleHashSlice() method to handle hash slices separately
- Prevents @ operator from being compiled prematurely
All 24 tests in hash.t now pass!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Complete implementation of hash operators in the interpreter, building on the array operators from PR #195.
All 24 hash.t tests pass ✅
This PR adds the missing hash operations to make the interpreter fully functional for hash manipulation.
Key Changes
Hash Operators Implemented ✅
Basic Hash Operations
$hash{key} = value$hash{key}References
$hashref->{key}$arrayref->[index]Hash Slices
@hash{'key1', 'key2'}@hash{keys} = values@$hashref{'key1', 'key2'}delete @hash{'key1', 'key2'}Nested Access
$hash{outer}{inner} = value$hash{outer}{inner}Critical Bug Fix
Hashref Slice Compilation: Fixed a subtle compilation issue where hashref slices like
@$hashref{keys}were failing because:Test Results
Hash Tests:
$ref->{key}access and dereference@hash{keys}retrieval, assignment, and delete@$hashref{keys}$hash{outer}{inner}with autovivificationCombined with PR #195:
Files Modified
Compiler:
src/main/java/org/perlonjava/interpreter/BytecodeCompiler.javaInterpreter:
src/main/java/org/perlonjava/interpreter/BytecodeInterpreter.javaSlow Opcodes:
src/main/java/org/perlonjava/interpreter/SlowOpcodeHandler.javaRuntime:
src/main/java/org/perlonjava/runtime/RuntimeHash.javaOpcodes:
src/main/java/org/perlonjava/interpreter/Opcodes.javaCommits
Production Readiness
With this PR, the interpreter now has complete support for both arrays and hashes, making it suitable for:
Dependencies
🤖 Generated with Claude Code