mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #47 from OddBloke/dict
Implement simple dict literals
This commit is contained in:
@@ -124,6 +124,9 @@ pub enum Expression {
|
||||
Tuple {
|
||||
elements: Vec<Expression>,
|
||||
},
|
||||
Dict {
|
||||
elements: Vec<(Expression, Expression)>,
|
||||
},
|
||||
Slice {
|
||||
elements: Vec<Expression>,
|
||||
},
|
||||
|
||||
@@ -323,11 +323,24 @@ Atom: ast::Expression = {
|
||||
}
|
||||
}
|
||||
},
|
||||
"{" <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,
|
||||
};
|
||||
@@ -385,6 +398,8 @@ extern {
|
||||
")" => lexer::Tok::Rpar,
|
||||
"[" => lexer::Tok::Lsqb,
|
||||
"]" => lexer::Tok::Rsqb,
|
||||
"{" => lexer::Tok::Lbrace,
|
||||
"}" => lexer::Tok::Rbrace,
|
||||
"=" => lexer::Tok::Equal,
|
||||
"+=" => lexer::Tok::PlusEqual,
|
||||
"-=" => lexer::Tok::MinusEqual,
|
||||
|
||||
@@ -1 +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
|
||||
|
||||
@@ -465,6 +465,14 @@ impl Compiler {
|
||||
}
|
||||
self.emit(Instruction::BuildTuple { size: size });
|
||||
}
|
||||
ast::Expression::Dict { elements } => {
|
||||
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();
|
||||
for element in elements {
|
||||
|
||||
23
vm/src/vm.rs
23
vm/src/vm.rs
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
use std::cell::RefMut;
|
||||
use std::collections::hash_map::HashMap;
|
||||
use std::ops::Deref;
|
||||
|
||||
use super::builtins;
|
||||
@@ -562,15 +563,25 @@ 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);
|
||||
}
|
||||
panic!("To be implemented!")
|
||||
//let list_obj = PyObject::Tuple { elements: elements }.into_ref();
|
||||
//frame.stack.push(list_obj);
|
||||
let map_obj =
|
||||
PyObject::new(PyObjectKind::Dict { elements: elements }, self.get_type());
|
||||
self.push_value(map_obj);
|
||||
None
|
||||
}
|
||||
bytecode::Instruction::BuildSlice { size } => {
|
||||
assert!(*size == 2 || *size == 3);
|
||||
|
||||
Reference in New Issue
Block a user