diff --git a/aaa-stdlib/src/map.rs b/aaa-stdlib/src/map.rs index 03eba7d5..40416671 100644 --- a/aaa-stdlib/src/map.rs +++ b/aaa-stdlib/src/map.rs @@ -1,6 +1,6 @@ use std::{ cell::RefCell, - collections::hash_map::DefaultHasher, + collections::HashMap, fmt::{Display, Formatter, Result}, hash::{Hash, Hasher}, rc::Rc, @@ -8,16 +8,12 @@ use std::{ use crate::var::UserType; -type MapBuckets = Vec>; - pub struct Map where K: UserType, V: UserType, { - buckets: Rc>>, - bucket_count: usize, - size: usize, + inner: HashMap, iterator_count: Rc>, } @@ -27,40 +23,14 @@ where V: UserType, { pub fn new() -> Self { - let bucket_count = 16; Self { - buckets: Rc::new(RefCell::new(vec![vec![]; bucket_count])), - size: 0, - bucket_count, + inner: HashMap::new(), iterator_count: Rc::new(RefCell::new(0)), } } - fn get_bucket_id(&self, key: &K, bucket_count: usize) -> usize { - let mut hasher = DefaultHasher::new(); - key.hash(&mut hasher); - let hash = hasher.finish(); - hash as usize % bucket_count - } - - fn find_in_bucket(&self, bucket_id: usize, key: &K) -> Option { - let bucket = &self.buckets.borrow()[bucket_id]; - - for (k, v) in bucket.iter() { - if key == k { - return Some(v.clone()); - } - } - None - } - - fn load_factor(&self) -> f64 { - self.len() as f64 / self.bucket_count as f64 - } - pub fn get(&self, key: &K) -> Option { - let bucket_id = self.get_bucket_id(key, self.bucket_count); - self.find_in_bucket(bucket_id, key) + self.inner.get(key).cloned() } pub fn contains_key(&self, key: &K) -> bool { @@ -69,77 +39,29 @@ where pub fn insert(&mut self, key: K, value: V) { self.detect_invalid_change(); - let bucket_id = self.get_bucket_id(&key, self.bucket_count); - - { - let bucket = &mut self.buckets.borrow_mut()[bucket_id]; - - for (k, v) in bucket.iter_mut() { - if key == *k { - *v = value; - return; - } - } - - bucket.push((key, value)); - self.size += 1; - } - - if self.load_factor() > 0.75 { - self.rehash(2 * self.bucket_count) - } - } - - pub fn rehash(&mut self, new_bucket_count: usize) { - let mut new_buckets = vec![vec![]; new_bucket_count]; - - for bucket in self.buckets.borrow().iter() { - for (key, value) in bucket.iter() { - let index = self.get_bucket_id(key, new_bucket_count); - new_buckets[index].push((key.clone(), value.clone())); - } - } - - *self.buckets.borrow_mut() = new_buckets; - self.bucket_count = new_bucket_count; + self.inner.insert(key, value); } pub fn len(&self) -> usize { - self.size + self.inner.len() } pub fn is_empty(&self) -> bool { - self.size == 0 + self.inner.is_empty() } pub fn clear(&mut self) { self.detect_invalid_change(); - - for bucket in self.buckets.borrow_mut().iter_mut() { - bucket.clear(); - } - self.size = 0; + self.inner.clear(); } pub fn remove_entry(&mut self, key: &K) -> Option<(K, V)> { self.detect_invalid_change(); - - let bucket_id = self.get_bucket_id(key, self.bucket_count); - let bucket = &mut self.buckets.borrow_mut()[bucket_id]; - - let position = bucket.iter().position(|(k, _v)| k == key); - - match position { - Some(index) => { - self.size -= 1; - Some(bucket.remove(index)) - } - None => None, - } + self.inner.remove_entry(key) } - pub fn iter(&self) -> HashTableIterator { - HashTableIterator::new(self.buckets.clone(), self.iterator_count.clone()) + pub fn iter(&self) -> MapIterator { + MapIterator::new(self.inner.clone().into_iter(), self.iterator_count.clone()) } fn detect_invalid_change(&self) { @@ -152,10 +74,8 @@ where pub fn fmt_as_set(&self) -> String { let mut parts = vec![]; - for bucket in self.buckets.borrow().iter() { - for (k, _) in bucket.iter() { - parts.push(format!("{k:?}")); - } + for (item, _) in self.iter() { + parts.push(format!("{item:?}")); } format!("{{{}}}", parts.join(",")) } @@ -167,22 +87,7 @@ where V: UserType, { fn eq(&self, other: &Self) -> bool { - if self.len() != other.len() { - return false; - } - - for (key, value) in self.iter() { - match other.get(&key) { - None => return false, - Some(v) => { - if v != value { - return false; - } - } - } - } - - true + return self.inner == other.inner; } } @@ -200,10 +105,8 @@ where { fn fmt(&self, f: &mut Formatter<'_>) -> Result { let mut parts = vec![]; - for bucket in self.buckets.borrow().iter() { - for (k, v) in bucket.iter() { - parts.push(format!("{k:?}: {v:?}")); - } + for (k, v) in self.iter() { + parts.push(format!("{k:?}: {v:?}")); } write!(f, "{{{}}}", parts.join(", ")) } @@ -244,37 +147,34 @@ where } } -pub struct HashTableIterator +pub struct MapIterator where K: UserType, V: UserType, { - buckets: Rc>>, + iterator: std::collections::hash_map::IntoIter, iterator_count: Rc>, - bucket_id: usize, - offset_in_bucket: usize, } -pub type MapIterator = HashTableIterator; - -impl HashTableIterator +impl MapIterator where K: UserType, V: UserType, { - pub fn new(buckets: Rc>>, iterator_count: Rc>) -> Self { + pub fn new( + iterator: std::collections::hash_map::IntoIter, + iterator_count: Rc>, + ) -> Self { *iterator_count.borrow_mut() += 1; Self { - buckets, + iterator, iterator_count, - bucket_id: 0, - offset_in_bucket: 0, } } } -impl Iterator for HashTableIterator +impl Iterator for MapIterator where K: UserType, V: UserType, @@ -282,27 +182,11 @@ where type Item = (K, V); fn next(&mut self) -> Option { - let buckets = self.buckets.borrow(); - - loop { - match buckets.get(self.bucket_id) { - Some(bucket) => match bucket.get(self.offset_in_bucket) { - Some((k, v)) => { - self.offset_in_bucket += 1; - return Some((k.clone(), v.clone())); - } - None => { - self.bucket_id += 1; - self.offset_in_bucket = 0; - } - }, - None => return None, - } - } + self.iterator.next() } } -impl Drop for HashTableIterator +impl Drop for MapIterator where K: UserType, V: UserType, diff --git a/aaa-stdlib/src/set.rs b/aaa-stdlib/src/set.rs index b06b7288..b5131770 100644 --- a/aaa-stdlib/src/set.rs +++ b/aaa-stdlib/src/set.rs @@ -4,12 +4,12 @@ use std::{ }; use crate::{ - map::{HashTableIterator, Map}, + map::{Map, MapIterator}, var::UserType, }; // Can't use unit type `()` as it does not implement Display, Hash or UserType -#[derive(Clone, Debug, Hash, PartialEq)] +#[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct SetValue; impl Display for SetValue { @@ -30,4 +30,4 @@ impl UserType for SetValue { pub type Set = Map; -pub type SetIterator = HashTableIterator; +pub type SetIterator = MapIterator; diff --git a/aaa-stdlib/src/var.rs b/aaa-stdlib/src/var.rs index db3f6ebd..74c03185 100644 --- a/aaa-stdlib/src/var.rs +++ b/aaa-stdlib/src/var.rs @@ -15,7 +15,7 @@ use crate::{ vector::{Vector, VectorIterator}, }; -pub trait UserType: Clone + Debug + Display + Hash + PartialEq { +pub trait UserType: Clone + Debug + Display + Hash + PartialEq + Eq { fn kind(&self) -> String; fn clone_recursive(&self) -> Self; } diff --git a/aaa-stdlib/src/vector.rs b/aaa-stdlib/src/vector.rs index 03a45b65..84bed0a7 100644 --- a/aaa-stdlib/src/vector.rs +++ b/aaa-stdlib/src/vector.rs @@ -6,7 +6,7 @@ pub struct Vector where T: UserType, { - vec: Rc>>, + inner: Vec, iterator_count: Rc>, // vector can only be modified if no iterators exist } @@ -16,45 +16,45 @@ where { pub fn new() -> Self { Self { - vec: Rc::new(RefCell::new(vec![])), + inner: vec![], iterator_count: Rc::new(RefCell::new(0)), } } pub fn push(&mut self, item: T) { self.detect_invalid_change(); - self.vec.borrow_mut().push(item); + self.inner.push(item); } pub fn pop(&mut self) -> Option { self.detect_invalid_change(); - self.vec.borrow_mut().pop() + self.inner.pop() } pub fn len(&self) -> usize { - self.vec.borrow().len() + self.inner.len() } pub fn is_empty(&self) -> bool { - self.vec.borrow().is_empty() + self.inner.is_empty() } pub fn clear(&mut self) { self.detect_invalid_change(); - self.vec.borrow_mut().clear(); + self.inner.clear(); } pub fn iter(&self) -> VectorIterator { - VectorIterator::new(self.vec.clone(), self.iterator_count.clone()) + VectorIterator::new(self.inner.clone().into_iter(), self.iterator_count.clone()) } pub fn get(&self, index: usize) -> T { - self.vec.borrow()[index].clone() + self.inner[index].clone() } pub fn set(&mut self, index: usize, item: T) { self.detect_invalid_change(); - self.vec.borrow_mut()[index] = item; + self.inner[index] = item; } fn detect_invalid_change(&self) { @@ -69,15 +69,8 @@ where T: UserType, { fn from(value: Vec) -> Self { - let vec = Self::new(); - - { - let mut inner = vec.vec.borrow_mut(); - for item in value { - inner.push(item); - } - } // be sure borrow ends here - + let mut vec = Self::new(); + vec.inner = value; vec } } @@ -100,7 +93,7 @@ where T: UserType, { fn eq(&self, other: &Self) -> bool { - self.vec == other.vec + self.inner == other.inner } } @@ -143,22 +136,20 @@ pub struct VectorIterator where T: UserType, { - vector: Rc>>, + iterator: std::vec::IntoIter, iterator_count: Rc>, - offset: usize, } impl VectorIterator where T: UserType, { - fn new(vector: Rc>>, iterator_count: Rc>) -> Self { + fn new(iterator: std::vec::IntoIter, iterator_count: Rc>) -> Self { *iterator_count.borrow_mut() += 1; Self { - vector, + iterator, iterator_count, - offset: 0, } } } @@ -170,11 +161,7 @@ where type Item = T; fn next(&mut self) -> Option { - let vector = self.vector.borrow(); - let item = vector.get(self.offset).cloned(); - self.offset += 1; - - item + self.iterator.next() } } diff --git a/aaa/transpiler/transpiler.py b/aaa/transpiler/transpiler.py index c9c21aeb..126f7367 100644 --- a/aaa/transpiler/transpiler.py +++ b/aaa/transpiler/transpiler.py @@ -134,6 +134,7 @@ def _generate_file(self) -> Code: code.add(self._generate_enum_Debug_impl(enum)) code.add(self._generate_enum_Hash_impl(enum)) code.add(self._generate_enum_PartialEq_impl(enum)) + code.add(self._generate_enum_Eq_impl(enum)) for struct in self.structs.values(): code.add(self._generate_struct(struct)) @@ -143,6 +144,7 @@ def _generate_file(self) -> Code: code.add(self._generate_struct_Debug_impl(struct)) code.add(self._generate_struct_Hash_impl(struct)) code.add(self._generate_struct_PartialEq_impl(struct)) + code.add(self._generate_struct_Eq_impl(struct)) for function in self.functions.values(): code.add(self._generate_function(function)) @@ -824,6 +826,17 @@ def _generate_enum_PartialEq_impl(self, enum: Enum) -> Code: code.add("") return code + def _generate_enum_Eq_impl(self, enum: Enum) -> Code: + if enum.position.file == self.builtins_path: + return Code() + + rust_struct_name = self._generate_type_name(enum) + + code = Code(f"impl Eq for {rust_struct_name} {{", indent=1) + code.add("}", unindent=1) + code.add("") + return code + def _generate_enum_Hash_impl(self, enum: Enum) -> Code: if enum.position.file == self.builtins_path: return Code() @@ -951,7 +964,7 @@ def _generate_zero_expression(self, type: VariableType | FunctionPointer) -> str ) def _generate_UserTypeEnum(self) -> Code: - code = Code("#[derive(Clone, Hash, PartialEq)]") + code = Code("#[derive(Clone, Hash, PartialEq, Eq)]") code.add("enum UserTypeEnum {", indent=1) for (file, name), struct in self.structs.items(): @@ -1309,6 +1322,17 @@ def _generate_struct_PartialEq_impl(self, struct: Struct) -> Code: code.add("") return code + def _generate_struct_Eq_impl(self, struct: Struct) -> Code: + if struct.position.file == self.builtins_path: + return Code() + + rust_struct_name = self._generate_type_name(struct) + + code = Code(f"impl Eq for {rust_struct_name} {{", indent=1) + code.add("}", unindent=1) + code.add("") + return code + def _generate_use_block_code(self, use_block: UseBlock) -> Code: code = Code("{", indent=1)