Set and retrieve attributes on instances.

This commit is contained in:
Adam Kelly
2018-08-08 07:58:16 +01:00
parent 13313e44e8
commit 9df841b38b
4 changed files with 26 additions and 2 deletions

View File

@@ -38,6 +38,7 @@ pub enum Instruction {
LoadName { name: String },
StoreName { name: String },
StoreSubscript,
StoreAttr { name: String },
LoadConst { value: Constant },
UnaryOperation { op: UnaryOperator },
BinaryOperation { op: BinaryOperator },

View File

@@ -351,8 +351,14 @@ impl Compiler {
self.compile_expression(b);
self.emit(Instruction::StoreSubscript);
}
ast::Expression::Attribute { value, name } => {
self.compile_expression(value);
self.emit(Instruction::StoreAttr {
name: name.to_string()
});
}
_ => {
panic!("WTF");
panic!("WTF: {:?}", target);
}
}
}

View File

@@ -210,6 +210,7 @@ impl ParentProtocol for PyObjectRef {
pub trait AttributeProtocol {
fn get_attr(&self, attr_name: &String) -> PyObjectRef;
fn set_attr(&self, attr_name: &String, value: PyObjectRef);
}
impl AttributeProtocol for PyObjectRef {
@@ -221,6 +222,14 @@ impl AttributeProtocol for PyObjectRef {
ref kind => unimplemented!("load_attr unimplemented for: {:?}", kind),
}
}
fn set_attr(&self, attr_name: &String, value: PyObjectRef) {
match self.borrow_mut().kind {
PyObjectKind::Instance { ref mut dict } =>
dict.set_item(attr_name, value),
ref kind => unimplemented!("load_attr unimplemented for: {:?}", kind),
};
}
}
pub trait DictProtocol {

View File

@@ -483,7 +483,7 @@ impl VirtualMachine {
let init = type_ref.get_attr(&String::from("__init__"));
let mut self_args = PyFuncArgs { args: args.args };
self_args.args.insert(0, obj.clone());
self.invoke(init, self_args);
self.invoke(init, self_args).unwrap();
Ok(obj)
}
@@ -527,6 +527,13 @@ impl VirtualMachine {
None
}
fn store_attr(&mut self, attr_name: &String) -> Option<PyResult> {
let parent = self.pop_value();
let value = self.pop_value();
parent.set_attr(attr_name, value);
None
}
// Execute a single instruction:
fn execute_instruction(&mut self) -> Option<PyResult> {
let instruction = self.current_frame().fetch_instruction();
@@ -629,6 +636,7 @@ impl VirtualMachine {
}
bytecode::Instruction::BinaryOperation { ref op } => self.execute_binop(op),
bytecode::Instruction::LoadAttr { ref name } => self.load_attr(name),
bytecode::Instruction::StoreAttr { ref name } => self.store_attr(name),
bytecode::Instruction::UnaryOperation { ref op } => self.execute_unop(op),
bytecode::Instruction::CompareOperation { ref op } => self.execute_compare(op),
bytecode::Instruction::ReturnValue => {