HashMap and HashSet for AutoVM
Overview
HashMap and HashSet are now fully implemented in AutoVM using Rust's standard library collections (std::collections::HashMap and std::collections::HashSet).
Files Created
1. Type Definitions
stdlib/auto/hashmap.at (3.1 KB)
- Complete type definition for
HashMap<K, V> - All public methods with
#[vm]annotations - Comprehensive documentation and usage examples
stdlib/auto/hashset.at (2.2 KB)
- Complete type definition for
HashSet<T> - All public methods with
#[vm]annotations - Comprehensive documentation and usage examples
2. Prelude Integration
stdlib/auto/prelude.at (updated)
- Added
use auto.hashmap: HashMap - Added
use auto.hashset: HashSet - HashMap and HashSet now available without explicit imports
3. Test Suite
crates/auto-lang/src/vm/tests_collections.rs (new)
- 12 comprehensive tests covering:
- Basic insertion and retrieval
- Integer keys
- Contains/missing keys
- Size tracking
- Remove operations
- Clear operations
- Tests for both HashMap and HashSet
Implementation Pattern
This follows the canonical AutoVM pattern for Rust-backed types:
// 1. Data Wrapper (vm/collections.rs)
pub struct HashMapData {
pub data: StdHashMap<String, Value>, // Rust's HashMap!
}
// 2. VM Method Signature
pub fn hash_map_insert(
_evaler: &mut Evaler, // VM context
instance: &mut Value, // The HashMap instance
args: Vec<Value> // Method arguments
) -> Value
// 3. Type Definition (.at file)
type HashMap<K, V> {
#[vm, pub]
static fn new() HashMap<K, V>
#[vm, pub]
fn insert_str(key str, value V)
// ... more methods
}
// 4. Registration (vm.rs)
hashmap_type.methods.insert(
"insert_str".into(),
collections::hash_map_insert_str as VmMethod,
);
Available Methods
HashMap<K, V>
Static Methods:
HashMap.new()- Create empty map
Insertion:
insert_str(key, value)- Insert with string keyinsert_int(key, value)- Insert with integer key
Lookup:
get_str(key)- Get value by string key (returns nil if not found)get_int(key)- Get value by integer key (returns nil if not found)contains(key)- Check if key exists (returns bool)
Modification:
remove(key)- Remove key-value pairclear()- Clear all entries
Query:
size()- Get number of entries
Lifecycle:
drop()- Free resources
HashSet
Static Methods:
HashSet.new()- Create empty set
Modification:
insert(value)- Insert elementremove(value)- Remove elementclear()- Clear all elements
Query:
contains(value)- Check membership (returns bool)size()- Get number of elements
Lifecycle:
drop()- Free resources
Usage Examples
HashMap Example
// Create a new HashMap
let map = HashMap.new()
// Insert key-value pairs
map.insert_str("name", "Alice")
map.insert_str("age", 30)
map.insert_str("city", "NYC")
// Get values
let name = map.get_str("name") // Returns "Alice"
let age = map.get_str("age") // Returns 30
let missing = map.get_str("missing") // Returns nil
// Check if key exists
let has_age = map.contains("age") // Returns true
let has_zip = map.contains("zip") // Returns false
// Get size
let count = map.size() // Returns 3
// Remove entry
map.remove("city")
let count_after = map.size() // Returns 2
// Clear all entries
map.clear()
let count_final = map.size() // Returns 0
// Clean up
map.drop()
HashSet Example
// Create a new HashSet
let set = HashSet.new()
// Insert elements
set.insert("apple")
set.insert("banana")
set.insert("cherry")
// Check membership
let has_apple = set.contains("apple") // Returns true
let has_grape = set.contains("grape") // Returns false
// Get size
let count = set.size() // Returns 3
// Remove element
set.remove("banana")
let count_after = set.size() // Returns 2
// Clear all elements
set.clear()
let count_final = set.size() // Returns 0
// Clean up
set.drop()
Integration with Existing Code
HashMap and HashSet integrate seamlessly with existing AutoVM infrastructure:
- Memory Management: Uses VM reference counting via
universe - Type System: Values can be any AutoLang type (int, str, bool, List, etc.)
- Method Dispatch: Registered in VM registry for fast lookup
- Storage: Backed by Rust's efficient
std::collections::HashMap
Future Enhancements
Potential improvements for future work:
- Generic Keys: Currently uses String keys, could support generic key types
- Iterators: Add
keys(),values(),iter()methods - Additional Methods:
is_empty(),reserve(),shrink_to_fit() - Entry API:
entry()method for more efficient insert-or-update - Merge Operations:
extend()to merge multiple maps/sets
Testing
Run the test suite:
cargo test -p auto-lang vm::tests_collections
Tests cover:
- ✅ Basic insertion and retrieval
- ✅ Integer keys (for HashMap)
- ✅ Contains/missing keys
- ✅ Size tracking
- ✅ Remove operations
- ✅ Clear operations
Architecture Benefits
This implementation demonstrates the strength of AutoVM's architecture:
- Zero-Cost Abstraction: Direct use of Rust's optimized collections
- Type Safety: Rust's type system ensures memory safety
- Performance: O(1) average case for all operations
- Simplicity: Clean separation between AutoLang types and Rust implementations
- Extensibility: Easy to add new collection types following this pattern
Related Files
- Implementation:
crates/auto-lang/src/vm/collections.rs(371 lines) - Registration:
crates/auto-lang/src/vm.rs(init_collections_module) - Storage:
crates/auto-lang/src/universe.rs(VmRefData enum) - Similar Types:
stdlib/auto/list.at- List<T, S> with pluggable storagestdlib/auto/storage.at- Storage strategies