From 9df841b38b86cb02ab3c0848def228bf7e073858 Mon Sep 17 00:00:00 2001 From: Adam Kelly Date: Wed, 8 Aug 2018 07:58:16 +0100 Subject: [PATCH] Set and retrieve attributes on instances. --- vm/src/bytecode.rs | 1 + vm/src/compile.rs | 8 +++++++- vm/src/pyobject.rs | 9 +++++++++ vm/src/vm.rs | 10 +++++++++- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/vm/src/bytecode.rs b/vm/src/bytecode.rs index 96056b699..0d9486d0a 100644 --- a/vm/src/bytecode.rs +++ b/vm/src/bytecode.rs @@ -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 }, diff --git a/vm/src/compile.rs b/vm/src/compile.rs index faa3cacf0..285687b62 100644 --- a/vm/src/compile.rs +++ b/vm/src/compile.rs @@ -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); } } } diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index d46a5d79c..903c4d63e 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -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 { diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 4ef7151c2..fd4b9e100 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -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 { + 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 { 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 => {