Implement simple dict literals

This commit is contained in:
Daniel Watkins committed 2018-08-07 23:49:42 -04:00
1 parent 1b259d5d61
commit d1acf5e7db
4 files changed
+37 -11

No files matched your search

+13 -1
View File
@@ -323,12 +323,24 @@ Atom: ast::Expression = {
}
}
},
"{" "}" => ast::Expression::Dict { elements: Vec::new() },
"{" <e:TestDict?> "}" => ast::Expression::Dict { elements: e.unwrap_or(Vec::new()) },
"True" => ast::Expression::True,
"False" => ast::Expression::False,
"None" => ast::Expression::None,
};
TestDict: Vec<(ast::Expression, ast::Expression)> = {
<e1:DictEntry> <e2:("," DictEntry)*> => {
let mut d = vec![e1];
d.extend(e2.into_iter().map(|x| x.1));
d
}
};
DictEntry: (ast::Expression, ast::Expression) = {
<e1: Test> ":" <e2: Test> => (e1, e2),
};
ExpressionList: Vec<ast::Expression> = {
<e: Comma<Expression>> => e,
};
+4
View File
@@ -1,2 +1,6 @@
assert len(dict()) == 0
assert len({}) == 0
assert len({"a": "b"}) == 1
assert len({"a": "b", "b": 1}) == 2
assert len({"a": "b", "b": 1, "a" + "b": 2*2}) == 3
+6 -1
View File
@@ -466,7 +466,12 @@ impl Compiler {
self.emit(Instruction::BuildTuple { size: size });
}
ast::Expression::Dict { elements } => {
self.emit(Instruction::BuildMap { size: 0 });
let size = elements.len();
for (key, value) in elements {
self.compile_expression(key);
self.compile_expression(value);
}
self.emit(Instruction::BuildMap { size: size });
}
ast::Expression::Slice { elements } => {
let size = elements.len();
+14 -9
View File
@@ -563,18 +563,23 @@ impl VirtualMachine {
None
}
bytecode::Instruction::BuildMap { size } => {
let mut elements = Vec::new();
let mut elements = HashMap::new();
for _x in 0..*size {
let key = self.pop_value();
let obj = self.pop_value();
elements.push((key, obj));
// XXX: Currently, we only support String keys, so we have to unwrap the
// PyObject (and ensure it is a String).
let key_pyobj = self.pop_value();
let key = match key_pyobj.borrow().kind {
PyObjectKind::String { ref value } => value.clone(),
ref kind => unimplemented!(
"Only strings can be used as dict keys, we saw: {:?}",
kind
),
};
elements.insert(key, obj);
}
let map_obj = PyObject::new(
PyObjectKind::Dict {
elements: HashMap::new(),
},
self.get_type(),
);
let map_obj =
PyObject::new(PyObjectKind::Dict { elements: elements }, self.get_type());
self.push_value(map_obj);
None
}