Try to make it simpler to switch dict storage types.

This commit is contained in:
Windel Bouwman committed 2018-12-13 20:38:09 +01:00
1 parent 521f664e16
commit 62c53d8e5d
4 files changed
+61 -15

No files matched your search

+9 -5
View File
@@ -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::<Vec<_>>()
.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::<Vec<_>>()
.join("")
}
ref unexpected => panic!(
"locals unexpectedly not wrapping a dict! instead: {:?}",
unexpected
+44 -1
View File
@@ -13,6 +13,7 @@ use std::ops::{Deref, DerefMut};
// pub type DictContentType = HashMap<usize, Vec<(PyObjectRef, PyObjectRef)>>;
// pub type DictContentType = HashMap<String, PyObjectRef>;
pub type DictContentType = HashMap<String, (PyObjectRef, PyObjectRef)>;
// pub type DictContentType = HashMap<String, Vec<(PyObjectRef, PyObjectRef)>>;
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<PyObjectRef> {
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<PyObjectRef> {
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<PyObjectRef> {
// 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()))
}
+6 -4
View File
@@ -225,18 +225,20 @@ pub fn get_attributes(obj: &PyObjectRef) -> HashMap<String, PyObjectRef> {
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
+2 -5
View File
@@ -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<PyObjectRef> {
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"),