diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 018fc33c3..b056ded7b 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -1090,11 +1090,15 @@ impl fmt::Debug for Frame { .join(""); let local_str = match self.locals.borrow().kind { PyObjectKind::Scope { ref scope } => match scope.locals.borrow().kind { - PyObjectKind::Dict { ref elements } => elements - .iter() - .map(|elem| format!("\n {} = {}", elem.0, (elem.1).1.borrow().str())) - .collect::>() - .join(""), + PyObjectKind::Dict { ref elements } => { + objdict::get_key_value_pairs_from_content(elements) + .iter() + .map(|elem| { + format!("\n {} = {}", elem.0.borrow().str(), elem.1.borrow().str()) + }) + .collect::>() + .join("") + } ref unexpected => panic!( "locals unexpectedly not wrapping a dict! instead: {:?}", unexpected diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs index f032ae1d4..ef13e0276 100644 --- a/vm/src/obj/objdict.rs +++ b/vm/src/obj/objdict.rs @@ -13,6 +13,7 @@ use std::ops::{Deref, DerefMut}; // pub type DictContentType = HashMap>; // pub type DictContentType = HashMap; pub type DictContentType = HashMap; +// pub type DictContentType = HashMap>; pub fn new(dict_type: PyObjectRef) -> PyObjectRef { PyObject::new( @@ -56,20 +57,62 @@ pub fn set_item_in_content( // XXX: Currently, we only support String keys, so we have to unwrap the // PyObject (and ensure it is a String). + // TODO: invoke __hash__ function here! let needle_str = objstr::get_value(needle); elements.insert(needle_str, (needle.clone(), value.clone())); } pub fn get_key_value_pairs(dict: &PyObjectRef) -> Vec<(PyObjectRef, PyObjectRef)> { let dict_elements = get_elements(dict); + get_key_value_pairs_from_content(&dict_elements) +} + +pub fn get_key_value_pairs_from_content( + dict_content: &DictContentType, +) -> Vec<(PyObjectRef, PyObjectRef)> { let mut pairs: Vec<(PyObjectRef, PyObjectRef)> = Vec::new(); - for (_str_key, pair) in dict_elements.iter() { + for (_str_key, pair) in dict_content.iter() { let (key, obj) = pair; pairs.push((key.clone(), obj.clone())); } pairs } +pub fn get_item(dict: &PyObjectRef, key: &PyObjectRef) -> Option { + let needle_str = objstr::get_value(key); + get_key_str(dict, &needle_str) +} + +// Special case for the case when requesting a str key from a dict: +pub fn get_key_str(dict: &PyObjectRef, key: &str) -> Option { + let elements = get_elements(dict); + content_get_key_str(&elements, key) +} + +/// Retrieve a key from dict contents: +pub fn content_get_key_str(elements: &DictContentType, key: &str) -> Option { + // TODO: let hash: usize = key; + match elements.get(key) { + Some(v) => Some(v.1.clone()), + None => None, + } +} + +pub fn contains_key_str(dict: &PyObjectRef, key: &str) -> bool { + let elements = get_elements(dict); + content_contains_key_str(&elements, key) +} + +pub fn content_contains_key_str(elements: &DictContentType, key: &str) -> bool { + // TODO: let hash: usize = key; + match elements.get(key) { + Some(_) => true, + None => false, + } +} + +// Python dict methods: + fn dict_new(_vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { Ok(new(args.args[0].clone())) } diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index d10affc5e..bc62244ae 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -225,18 +225,20 @@ pub fn get_attributes(obj: &PyObjectRef) -> HashMap { mro: _, } = &bc.borrow().kind { - let elements = objdict::get_elements(dict); + let elements = objdict::get_key_value_pairs(dict); for (name, value) in elements.iter() { - attributes.insert(name.to_string(), value.1.clone()); + let name = objstr::get_value(name); + attributes.insert(name.to_string(), value.clone()); } } } // Get instance attributes: if let PyObjectKind::Instance { dict } = &obj.borrow().kind { - let elements = objdict::get_elements(dict); + let elements = objdict::get_key_value_pairs(dict); for (name, value) in elements.iter() { - attributes.insert(name.to_string(), value.1.clone()); + let name = objstr::get_value(name); + attributes.insert(name.to_string(), value.clone()); } } attributes diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index fe4c30d03..3ef4ab282 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -686,7 +686,7 @@ pub trait DictProtocol { impl DictProtocol for PyObjectRef { fn contains_key(&self, k: &str) -> bool { match self.borrow().kind { - PyObjectKind::Dict { ref elements } => elements.contains_key(k), + PyObjectKind::Dict { ref elements } => objdict::content_contains_key_str(elements, k), PyObjectKind::Module { name: _, ref dict } => dict.contains_key(k), PyObjectKind::Scope { ref scope } => scope.locals.contains_key(k), ref kind => unimplemented!("TODO {:?}", kind), @@ -695,10 +695,7 @@ impl DictProtocol for PyObjectRef { fn get_item(&self, k: &str) -> Option { match self.borrow().kind { - PyObjectKind::Dict { ref elements } => match elements.get(k) { - Some(v) => Some(v.1.clone()), - None => None, - }, + PyObjectKind::Dict { ref elements } => objdict::content_get_key_str(elements, k), PyObjectKind::Module { name: _, ref dict } => dict.get_item(k), PyObjectKind::Scope { ref scope } => scope.locals.get_item(k), _ => panic!("TODO"),