diff --git a/.travis.yml b/.travis.yml index d99dadcf5..89617c45c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,3 +39,16 @@ matrix: env: - TRAVIS_RUST_VERSION=beta script: tests/.travis-runner.sh + - name: rustfmt + language: rust + rust: nightly + cache: cargo + before_script: + - rustup component add rustfmt-preview + script: + # Code references the generated python.rs, so put something in + # place to make `cargo fmt` happy. (We use `echo` rather than + # `touch` because rustfmt complains about the empty file touch + # creates.) + - echo > parser/src/python.rs + - cargo fmt --all -- --check diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs index 1961e2a6a..f1e386463 100644 --- a/parser/src/lexer.rs +++ b/parser/src/lexer.rs @@ -119,11 +119,8 @@ impl<'input> Lexer<'input> { Some('\r') => { return; } - Some(_) => { - } - None => { - return - } + Some(_) => {} + None => return, } } } @@ -150,12 +147,8 @@ impl<'input> Lexer<'input> { Some('\\') => { string_content.push('\\'); } - Some('\'') => { - string_content.push('\'') - } - Some('\"') => { - string_content.push('\"') - } + Some('\'') => string_content.push('\''), + Some('\"') => string_content.push('\"'), Some('\n') => { // Ignore Unix EOL character } @@ -170,27 +163,17 @@ impl<'input> Lexer<'input> { } } } - Some('a') => { - string_content.push('\x07') - } - Some('b') => { - string_content.push('\x08') - } - Some('f') => { - string_content.push('\x0c') - } + Some('a') => string_content.push('\x07'), + Some('b') => string_content.push('\x08'), + Some('f') => string_content.push('\x0c'), Some('n') => { string_content.push('\n'); } - Some('r') => { - string_content.push('\r') - }, + Some('r') => string_content.push('\r'), Some('t') => { string_content.push('\t'); } - Some('v') => { - string_content.push('\x0b') - } + Some('v') => string_content.push('\x0b'), Some(c) => { string_content.push('\\'); string_content.push(c); diff --git a/parser/src/parser.rs b/parser/src/parser.rs index 39dc0919a..8ccbac11b 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -43,8 +43,10 @@ pub fn parse(filename: &Path) -> Result { pub fn parse_program(source: &String) -> Result { let lxr = lexer::Lexer::new(&source); match python::ProgramParser::new().parse(lxr) { - Err(lalrpop_util::ParseError::UnrecognizedToken{token: None, expected: _}) => - Err(String::from("Unexpected end of input.")), + Err(lalrpop_util::ParseError::UnrecognizedToken { + token: None, + expected: _, + }) => Err(String::from("Unexpected end of input.")), Err(why) => Err(String::from(format!("{:?}", why))), Ok(p) => Ok(p), } @@ -76,12 +78,7 @@ mod tests { fn test_parse_empty() { let parse_ast = parse_program(&String::from("\n")); - assert_eq!( - parse_ast, - Ok(ast::Program { - statements: vec![] - }) - ) + assert_eq!(parse_ast, Ok(ast::Program { statements: vec![] })) } #[test] @@ -91,20 +88,16 @@ mod tests { assert_eq!( parse_ast, ast::Program { - statements: vec![ - ast::Statement::Expression { - expression: ast::Expression::Call { - function: Box::new(ast::Expression::Identifier { - name: String::from("print"), - }), - args: vec![ - ast::Expression::String { - value: String::from("Hello world"), - }, - ], - }, + statements: vec![ast::Statement::Expression { + expression: ast::Expression::Call { + function: Box::new(ast::Expression::Identifier { + name: String::from("print"), + }), + args: vec![ast::Expression::String { + value: String::from("Hello world"), + },], }, - ], + },], } ); } @@ -116,21 +109,19 @@ mod tests { assert_eq!( parse_ast, ast::Program { - statements: vec![ - ast::Statement::Expression { - expression: ast::Expression::Call { - function: Box::new(ast::Expression::Identifier { - name: String::from("print"), - }), - args: vec![ - ast::Expression::String { - value: String::from("Hello world"), - }, - ast::Expression::Number { value: 2 }, - ], - }, + statements: vec![ast::Statement::Expression { + expression: ast::Expression::Call { + function: Box::new(ast::Expression::Identifier { + name: String::from("print"), + }), + args: vec![ + ast::Expression::String { + value: String::from("Hello world"), + }, + ast::Expression::Number { value: 2 }, + ], }, - ], + },], } ); } @@ -143,26 +134,18 @@ mod tests { parse_ast, ast::Statement::If { test: ast::Expression::Number { value: 1 }, - body: vec![ - ast::Statement::Expression { - expression: ast::Expression::Number { value: 10 }, - }, - ], - orelse: Some(vec![ - ast::Statement::If { - test: ast::Expression::Number { value: 2 }, - body: vec![ - ast::Statement::Expression { - expression: ast::Expression::Number { value: 20 }, - }, - ], - orelse: Some(vec![ - ast::Statement::Expression { - expression: ast::Expression::Number { value: 30 }, - }, - ]), - }, - ]), + body: vec![ast::Statement::Expression { + expression: ast::Expression::Number { value: 10 }, + },], + orelse: Some(vec![ast::Statement::If { + test: ast::Expression::Number { value: 2 }, + body: vec![ast::Statement::Expression { + expression: ast::Expression::Number { value: 20 }, + },], + orelse: Some(vec![ast::Statement::Expression { + expression: ast::Expression::Number { value: 30 }, + },]), + },]), } ); } @@ -176,17 +159,16 @@ mod tests { Ok(ast::Statement::Expression { expression: ast::Expression::Lambda { args: vec![String::from("x"), String::from("y")], - body: - Box::new(ast::Expression::Binop { - a: Box::new(ast::Expression::Identifier { - name: String::from("x"), - }), - op: ast::Operator::Mult, - b: Box::new(ast::Expression::Identifier { - name: String::from("y"), - }) + body: Box::new(ast::Expression::Binop { + a: Box::new(ast::Expression::Identifier { + name: String::from("x"), + }), + op: ast::Operator::Mult, + b: Box::new(ast::Expression::Identifier { + name: String::from("y"), }) - } + }) + } }) ) } @@ -198,13 +180,11 @@ mod tests { parse_statement(&source), Ok(ast::Statement::ClassDef { name: String::from("Foo"), - body: vec![ - ast::Statement::FunctionDef { - name: String::from("__init__"), - args: vec![String::from("self")], - body: vec![ast::Statement::Pass], - } - ], + body: vec![ast::Statement::FunctionDef { + name: String::from("__init__"), + args: vec![String::from("self")], + body: vec![ast::Statement::Pass], + }], }) ) } diff --git a/parser/src/token.rs b/parser/src/token.rs index e6e30b4e1..4b3c22a5e 100644 --- a/parser/src/token.rs +++ b/parser/src/token.rs @@ -1,7 +1,5 @@ - // Loosely based on token.h from CPython source: -#[derive(Debug)] -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum Tok { Name { name: String }, Number { value: i32 }, @@ -21,7 +19,7 @@ pub enum Tok { Star, Slash, Vbar, // '|' - Amper, // '&' + Amper, // '&' Less, Greater, Equal, @@ -38,18 +36,18 @@ pub enum Tok { LeftShift, RightShift, DoubleStar, - DoubleStarEqual, // '**=' + DoubleStarEqual, // '**=' PlusEqual, MinusEqual, StarEqual, SlashEqual, PercentEqual, - AmperEqual, // '&=' + AmperEqual, // '&=' VbarEqual, - CircumflexEqual, // '^=' + CircumflexEqual, // '^=' LeftShiftEqual, RightShiftEqual, - DoubleSlash, // '//' + DoubleSlash, // '//' DoubleSlashEqual, At, AtEqual, @@ -57,7 +55,6 @@ pub enum Tok { Ellipsis, // Keywords (alphabetically): - False, None, True, diff --git a/src/main.rs b/src/main.rs index 843459b8b..698e248ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,8 @@ extern crate rustpython_vm; use clap::{App, Arg}; use rustpython_parser::parser; -use rustpython_vm::VirtualMachine; use rustpython_vm::compile; +use rustpython_vm::VirtualMachine; use std::io; use std::io::prelude::*; use std::path::Path; @@ -29,14 +29,12 @@ fn main() { .short("v") .multiple(true) .help("Give the verbosity"), - ) - .arg( + ).arg( Arg::with_name("c") .short("c") .takes_value(true) .help("run the given string as a program"), - ) - .get_matches(); + ).get_matches(); // Figure out if a -c option was given: if let Some(command) = matches.value_of("c") { @@ -95,7 +93,7 @@ fn shell_exec(vm: &mut VirtualMachine, source: &String, scope: PyObjectRef) -> b } Err(msg) => { println!("Error: {:?}", msg); - }, + } } } Err(msg) => { @@ -140,6 +138,7 @@ fn run_shell() { let mut vm = VirtualMachine::new(); let builtins = vm.get_builtin_scope(); let vars = vm.context().new_scope(Some(builtins)); // Keep track of local variables + // Read a single line: let mut input = String::new(); loop { @@ -162,15 +161,11 @@ fn run_shell() { Ok(_) => { shell_exec(&mut vm, &input, vars.clone()); } - Err(msg) => { - panic!("Error: {:?}", msg) - } + Err(msg) => panic!("Error: {:?}", msg), } } } - Err(msg) => { - panic!("Error: {:?}", msg) - } + Err(msg) => panic!("Error: {:?}", msg), }; } } diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 2de1c9cff..cd1e589b9 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -3,11 +3,12 @@ use std::collections::HashMap; use std::io::{self, Write}; use super::compile; -use super::pyobject::DictProtocol; -use super::pyobject::{PyContext, PyObject, PyObjectKind, PyObjectRef, PyResult, Scope, IdProtocol, PyFuncArgs}; -use super::vm::VirtualMachine; use super::objbool; - +use super::pyobject::DictProtocol; +use super::pyobject::{ + IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult, Scope, +}; +use super::vm::VirtualMachine; fn get_locals(vm: &mut VirtualMachine) -> PyObjectRef { let mut d = vm.new_dict(); @@ -56,7 +57,7 @@ fn builtin_any(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { fn builtin_compile(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { if args.args.len() < 1 { - return Err(vm.new_exception("Expected more arguments".to_string())) + return Err(vm.new_exception("Expected more arguments".to_string())); } // TODO: let mode = compile::Mode::Eval; @@ -93,24 +94,27 @@ fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { let args = args.args; if args.len() > 3 { - return Err(vm.new_exception("Expected at maximum of 3 arguments".to_string())) + return Err(vm.new_exception("Expected at maximum of 3 arguments".to_string())); } else if args.len() > 2 { // TODO: handle optional global and locals } else { - return Err(vm.new_exception("Expected at least one argument".to_string())) + return Err(vm.new_exception("Expected at least one argument".to_string())); } let source = args[0].clone(); let _globals = args[1].clone(); let locals = args[2].clone(); - let code_obj = source; // if source.borrow().kind + let code_obj = source; // if source.borrow().kind // Construct new scope: let scope_inner = Scope { locals: locals, parent: None, }; - let scope = PyObject { kind: PyObjectKind::Scope { scope: scope_inner }, typ: None }.into_ref(); + let scope = PyObject { + kind: PyObjectKind::Scope { scope: scope_inner }, + typ: None, + }.into_ref(); // Run the source: vm.run_code_obj(code_obj, scope) @@ -130,7 +134,7 @@ fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { fn builtin_id(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { if args.args.len() != 1 { - return Err(vm.new_exception("Expected only one argument".to_string())) + return Err(vm.new_exception("Expected only one argument".to_string())); } Ok(vm.context().new_int(args.args[0].get_id() as i32)) @@ -152,7 +156,8 @@ fn builtin_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { PyObjectKind::Tuple { ref elements } => elements.len(), PyObjectKind::String { ref value } => value.len(), _ => { - return Err(vm.context() + return Err(vm + .context() .new_str("TypeError: object of this type has no len()".to_string())) } }; @@ -226,9 +231,10 @@ fn builtin_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { args.args[0].borrow().str() } _ => { - return Err(vm.context() - .new_str("TypeError: object of this type cannot be converted to str".to_string())) - }, + return Err(vm + .context() + .new_str("TypeError: object of this type cannot be converted to str".to_string())) + } }; Ok(vm.new_str(s)) } @@ -261,7 +267,15 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef { dict.insert(String::from("tuple"), ctx.tuple_type.clone()); dict.insert(String::from("type"), ctx.type_type.clone()); let d2 = PyObject::new(PyObjectKind::Dict { elements: dict }, ctx.type_type.clone()); - let scope = PyObject::new(PyObjectKind::Scope { scope: Scope { locals: d2, parent: None} }, ctx.type_type.clone()); + let scope = PyObject::new( + PyObjectKind::Scope { + scope: Scope { + locals: d2, + parent: None, + }, + }, + ctx.type_type.clone(), + ); let obj = PyObject::new( PyObjectKind::Module { name: "__builtins__".to_string(), @@ -281,6 +295,11 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResu }; let new_dict = vm.new_dict(); - &vm.invoke(function, PyFuncArgs { args: vec![ new_dict.clone() ] }); + &vm.invoke( + function, + PyFuncArgs { + args: vec![new_dict.clone()], + }, + ); Ok(vm.new_class(name.to_string(), new_dict)) } diff --git a/vm/src/bytecode.rs b/vm/src/bytecode.rs index 6b13409b4..9b90e0977 100644 --- a/vm/src/bytecode.rs +++ b/vm/src/bytecode.rs @@ -21,7 +21,7 @@ pub struct CodeObject { } impl CodeObject { - pub fn new(arg_names : Vec) -> CodeObject { + pub fn new(arg_names: Vec) -> CodeObject { CodeObject { instructions: Vec::new(), label_map: HashMap::new(), @@ -38,35 +38,72 @@ pub enum Instruction { name: String, symbol: Option, }, - LoadName { name: String }, - StoreName { name: String }, + LoadName { + name: String, + }, + StoreName { + name: String, + }, StoreSubscript, - StoreAttr { name: String }, - LoadConst { value: Constant }, - UnaryOperation { op: UnaryOperator }, - BinaryOperation { op: BinaryOperator }, - LoadAttr { name: String }, - CompareOperation { op: ComparisonOperator }, + StoreAttr { + name: String, + }, + LoadConst { + value: Constant, + }, + UnaryOperation { + op: UnaryOperator, + }, + BinaryOperation { + op: BinaryOperator, + }, + LoadAttr { + name: String, + }, + CompareOperation { + op: ComparisonOperator, + }, Pop, - Rotate { amount: usize }, + Rotate { + amount: usize, + }, Duplicate, GetIter, Pass, Continue, Break, - Jump { target: Label }, - JumpIf { target: Label }, + Jump { + target: Label, + }, + JumpIf { + target: Label, + }, MakeFunction, - CallFunction { count: usize }, + CallFunction { + count: usize, + }, ForIter, ReturnValue, - SetupLoop { start: Label, end: Label }, + SetupLoop { + start: Label, + end: Label, + }, PopBlock, - Raise { argc: usize }, - BuildTuple { size: usize }, - BuildList { size: usize }, - BuildMap { size: usize }, - BuildSlice { size: usize }, + Raise { + argc: usize, + }, + BuildTuple { + size: usize, + }, + BuildList { + size: usize, + }, + BuildMap { + size: usize, + }, + BuildSlice { + size: usize, + }, PrintExpr, LoadBuildClass, StoreLocals, @@ -132,7 +169,8 @@ pub enum BlockType { impl fmt::Debug for CodeObject { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let inst_str = self.instructions + let inst_str = self + .instructions .iter() .enumerate() .map(|(i, inst)| format!("Inst {}: {:?}", i, inst)) diff --git a/vm/src/compile.rs b/vm/src/compile.rs index e49fb6969..e96de6a91 100644 --- a/vm/src/compile.rs +++ b/vm/src/compile.rs @@ -14,7 +14,11 @@ struct Compiler { nxt_label: usize, } -pub fn compile(vm: &mut VirtualMachine, source: &String, mode: Mode) -> Result { +pub fn compile( + vm: &mut VirtualMachine, + source: &String, + mode: Mode, +) -> Result { let mut compiler = Compiler::new(); compiler.push_new_code_object(); match mode { @@ -46,7 +50,7 @@ pub fn compile(vm: &mut VirtualMachine, source: &String, mode: Mode) -> Result

{ self.emit(Instruction::LoadBuildClass); - self.code_object_stack.push( - CodeObject::new(vec![String::from("__locals__")])); + self.code_object_stack + .push(CodeObject::new(vec![String::from("__locals__")])); self.emit(Instruction::LoadName { - name: String::from("__locals__")}); + name: String::from("__locals__"), + }); self.emit(Instruction::StoreLocals); self.compile_statements(body); self.emit(Instruction::LoadConst { @@ -378,7 +383,7 @@ impl Compiler { ast::Expression::Attribute { value, name } => { self.compile_expression(value); self.emit(Instruction::StoreAttr { - name: name.to_string() + name: name.to_string(), }); } _ => { @@ -423,7 +428,8 @@ impl Compiler { panic!("Not impl"); } }, - _ => { // If all else fail, fall back to simple checking of boolean value: + _ => { + // If all else fail, fall back to simple checking of boolean value: self.compile_expression(expression); self.emit(Instruction::UnaryOperation { op: bytecode::UnaryOperator::Not, @@ -450,17 +456,17 @@ impl Compiler { self.compile_test(expression, not_label); // Load const True self.emit(Instruction::LoadConst { - value: bytecode::Constant::Boolean { value: true}, + value: bytecode::Constant::Boolean { value: true }, }); self.emit(Instruction::Jump { target: end_label }); self.set_label(not_label); // Load const False self.emit(Instruction::LoadConst { - value: bytecode::Constant::Boolean { value: false}, + value: bytecode::Constant::Boolean { value: false }, }); self.set_label(end_label); - }, + } ast::Expression::Binop { a, op, b } => { self.compile_expression(&*a); self.compile_expression(&*b); @@ -546,12 +552,12 @@ impl Compiler { } ast::Expression::True => { self.emit(Instruction::LoadConst { - value: bytecode::Constant::Boolean { value: true}, + value: bytecode::Constant::Boolean { value: true }, }); } ast::Expression::False => { self.emit(Instruction::LoadConst { - value: bytecode::Constant::Boolean { value: false}, + value: bytecode::Constant::Boolean { value: false }, }); } ast::Expression::None => { diff --git a/vm/src/eval.rs b/vm/src/eval.rs index 76496fa1f..cb0f1a021 100644 --- a/vm/src/eval.rs +++ b/vm/src/eval.rs @@ -18,8 +18,8 @@ pub fn eval(vm: &mut VirtualMachine, source: &String, scope: PyObjectRef) -> PyR #[cfg(test)] mod tests { - use super::VirtualMachine; use super::eval; + use super::VirtualMachine; #[test] fn test_print_42() { diff --git a/vm/src/frame.rs b/vm/src/frame.rs index cdc91fcc6..96a26c158 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -36,10 +36,7 @@ pub fn copy_code(code_obj: PyObjectRef) -> bytecode::CodeObject { } impl Frame { - pub fn new( - code: PyObjectRef, - globals: PyObjectRef, - ) -> Frame { + pub fn new(code: PyObjectRef, globals: PyObjectRef) -> Frame { //populate the globals and locals //TODO: This is wrong, check https://github.com/nedbat/byterun/blob/31e6c4a8212c35b5157919abff43a7daa0f377c6/byterun/pyvm2.py#L95 /* @@ -106,12 +103,14 @@ impl Frame { impl fmt::Debug for Frame { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let stack_str = self.stack + let stack_str = self + .stack .iter() .map(|elem| format!("\n > {}", elem.borrow_mut().str())) .collect::>() .join(""); - let block_str = self.blocks + let block_str = self + .blocks .iter() .map(|elem| format!("\n > {:?}", elem)) .collect::>() diff --git a/vm/src/import.rs b/vm/src/import.rs index ed5551122..314a5c28f 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -10,7 +10,7 @@ use std::path::PathBuf; use self::rustpython_parser::parser; use super::compile; -use super::pyobject::{PyObject, PyObjectKind, PyResult, DictProtocol}; +use super::pyobject::{DictProtocol, PyObject, PyObjectKind, PyResult}; use super::vm::VirtualMachine; fn import_module(vm: &mut VirtualMachine, module: &String) -> PyResult { @@ -64,10 +64,16 @@ pub fn import(vm: &mut VirtualMachine, module: &String, symbol: &Option) fn find_source(name: &String) -> io::Result { let suffixes = [".py", "/__init__.py"]; - let filepaths = suffixes.iter().map(|suffix| format!("{}{}", name, suffix)).map(|filename| PathBuf::from(filename)); + let filepaths = suffixes + .iter() + .map(|suffix| format!("{}{}", name, suffix)) + .map(|filename| PathBuf::from(filename)); match filepaths.filter(|p| p.exists()).next() { Some(path) => Ok(path.to_path_buf()), - None => Err(io::Error::new(NotFound, format!("Module ({}) could not be found.", name))) + None => Err(io::Error::new( + NotFound, + format!("Module ({}) could not be found.", name), + )), } } diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 40190a12f..7625802e1 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -11,13 +11,13 @@ pub mod compile; pub mod eval; mod frame; mod import; +mod objbool; mod objdict; mod objint; mod objlist; mod objsequence; mod objstr; mod objtype; -mod objbool; pub mod pyobject; mod sysmodule; mod vm; diff --git a/vm/src/objbool.rs b/vm/src/objbool.rs index 73e4d429c..eca7829ff 100644 --- a/vm/src/objbool.rs +++ b/vm/src/objbool.rs @@ -1,4 +1,3 @@ - use super::pyobject::{PyObjectKind, PyObjectRef}; pub fn boolval(o: PyObjectRef) -> bool { diff --git a/vm/src/objint.rs b/vm/src/objint.rs index a238c2b43..ea99e7fe8 100644 --- a/vm/src/objint.rs +++ b/vm/src/objint.rs @@ -1,4 +1,4 @@ -use super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyFuncArgs}; +use super::pyobject::{PyFuncArgs, PyObject, PyObjectKind, PyObjectRef}; use super::vm::VirtualMachine; use std::collections::HashMap; @@ -25,7 +25,7 @@ pub fn create_type(type_type: PyObjectRef) -> PyObjectRef { let typ = PyObject::new( PyObjectKind::Class { name: "int".to_string(), - dict: PyObject::new(PyObjectKind::Dict { elements: dict }, type_type.clone() ), + dict: PyObject::new(PyObjectKind::Dict { elements: dict }, type_type.clone()), }, type_type.clone(), ); diff --git a/vm/src/objtype.rs b/vm/src/objtype.rs index 5193f1f18..a3848f29b 100644 --- a/vm/src/objtype.rs +++ b/vm/src/objtype.rs @@ -11,11 +11,13 @@ pub fn create_type() -> PyObjectRef { let dict = PyObject::new( PyObjectKind::Dict { elements: HashMap::new(), - }, typ.clone()); + }, + typ.clone(), + ); (*typ.borrow_mut()).kind = PyObjectKind::Class { - name: String::from("type"), - dict: dict, - }; + name: String::from("type"), + dict: dict, + }; (*typ.borrow_mut()).typ = Some(typ.clone()); typ } diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index da64ba0ef..892f10a39 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -1,13 +1,13 @@ use super::bytecode; use super::objint; use super::objtype; +use super::vm::VirtualMachine; use std::cell::RefCell; use std::cmp::Ordering; use std::collections::HashMap; use std::fmt; -use std::ops::{Add, Div, Mul, Sub, Rem}; +use std::ops::{Add, Div, Mul, Rem, Sub}; use std::rc::Rc; -use super::vm::VirtualMachine; /* Python objects and references. @@ -53,8 +53,8 @@ pub struct PyContext { */ #[derive(Debug)] pub struct Scope { - pub locals: PyObjectRef, // Variables - pub parent: Option, // Parent scope + pub locals: PyObjectRef, // Variables + pub parent: Option, // Parent scope } // Basic objects: @@ -121,7 +121,10 @@ impl PyContext { locals: locals, parent: parent, }; - PyObject { kind: PyObjectKind::Scope { scope: scope }, typ: None }.into_ref() + PyObject { + kind: PyObjectKind::Scope { scope: scope }, + typ: None, + }.into_ref() } pub fn new_module(&self, name: &String, scope: PyObjectRef) -> PyObjectRef { @@ -142,10 +145,13 @@ impl PyContext { } pub fn new_class(&self, name: String, namespace: PyObjectRef) -> PyObjectRef { - PyObject::new(PyObjectKind::Class { - name: name, - dict: namespace.clone() - }, self.type_type.clone()) + PyObject::new( + PyObjectKind::Class { + name: name, + dict: namespace.clone(), + }, + self.type_type.clone(), + ) } /* TODO: something like this? @@ -225,8 +231,7 @@ impl AttributeProtocol for PyObjectRef { 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), + PyObjectKind::Instance { ref mut dict } => dict.set_item(attr_name, value), ref kind => unimplemented!("load_attr unimplemented for: {:?}", kind), }; } @@ -263,11 +268,14 @@ impl DictProtocol for PyObjectRef { elements: ref mut el, } => { el.insert(k.to_string(), v); - }, - PyObjectKind::Module { name: _, ref mut dict } => dict.set_item(k, v), + } + PyObjectKind::Module { + name: _, + ref mut dict, + } => dict.set_item(k, v), PyObjectKind::Scope { ref mut scope } => { scope.locals.set_item(k, v); - }, + } _ => panic!("TODO"), }; } @@ -342,7 +350,7 @@ pub enum PyObjectKind { dict: PyObjectRef, }, Instance { - dict: PyObjectRef + dict: PyObjectRef, }, RustFunction { function: RustPyFunc, @@ -359,8 +367,15 @@ impl fmt::Debug for PyObjectKind { &PyObjectKind::List { elements: _ } => write!(f, "list"), &PyObjectKind::Tuple { elements: _ } => write!(f, "tuple"), &PyObjectKind::Dict { elements: _ } => write!(f, "dict"), - &PyObjectKind::Iterator { position: _, iterated_obj: _ } => write!(f, "iterator"), - &PyObjectKind::Slice { start: _, stop: _, step: _ } => write!(f, "slice"), + &PyObjectKind::Iterator { + position: _, + iterated_obj: _, + } => write!(f, "iterator"), + &PyObjectKind::Slice { + start: _, + stop: _, + step: _, + } => write!(f, "slice"), &PyObjectKind::NameError { name: _ } => write!(f, "NameError"), &PyObjectKind::Code { ref code } => write!(f, "code: {:?}", code), &PyObjectKind::Function { code: _, scope: _ } => write!(f, "function"), @@ -427,10 +442,11 @@ impl PyObject { .join(", ") ), PyObjectKind::None => String::from("None"), - PyObjectKind::Class { ref name, dict: ref _dict } => - format!("", name), - PyObjectKind::Instance { dict: _ } => - format!(""), + PyObjectKind::Class { + ref name, + dict: ref _dict, + } => format!("", name), + PyObjectKind::Instance { dict: _ } => format!(""), PyObjectKind::Code { code: _ } => format!(""), PyObjectKind::Function { code: _, scope: _ } => format!(""), PyObjectKind::RustFunction { function: _ } => format!(""), diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 6f18094f7..8891c9b87 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -103,7 +103,9 @@ impl VirtualMachine { let a2 = &*self.builtins.borrow(); match a2.kind { PyObjectKind::Module { name: _, ref dict } => dict.clone(), - _ => { panic!("OMG"); } + _ => { + panic!("OMG"); + } } } @@ -136,10 +138,8 @@ impl VirtualMachine { loop { let block = self.pop_block(); match block { - Some(Block::Loop { start: _, end: __ }) => { - break block.unwrap() - }, - Some(Block::TryExcept {}) => {}, + Some(Block::Loop { start: _, end: __ }) => break block.unwrap(), + Some(Block::TryExcept {}) => {} None => panic!("No block to break / continue"), } } @@ -150,15 +150,15 @@ impl VirtualMachine { loop { let block = self.pop_block(); match block { - Some(Block::TryExcept { }) => { + Some(Block::TryExcept {}) => { // Exception handled? // TODO: how do we know if the exception is handled? let is_handled = true; if is_handled { return None; } - }, - Some(_) => {}, + } + Some(_) => {} None => break, } } @@ -194,7 +194,7 @@ impl VirtualMachine { if scope.contains_key(name) { let obj = scope.get_item(name); self.push_value(obj); - break None + break None; } else if scope.has_parent() { scope = scope.get_parent(); } else { @@ -204,7 +204,7 @@ impl VirtualMachine { }, self.get_type(), ); - break Some(Err(name_error)) + break Some(Err(name_error)); } } } @@ -223,7 +223,7 @@ impl VirtualMachine { Some(Err(exception)) => { // unwind block stack on exception and find any handlers. match self.unwind_exception(exception) { - None => {}, + None => {} Some(exception) => break Err(exception), } } @@ -463,7 +463,7 @@ impl VirtualMachine { fn new_instance(&mut self, type_ref: PyObjectRef, args: PyFuncArgs) -> PyResult { // more or less __new__ operator let dict = self.new_dict(); - let obj = PyObject::new(PyObjectKind::Instance{dict: dict}, type_ref.clone()); + let obj = PyObject::new(PyObjectKind::Instance { dict: dict }, type_ref.clone()); let init = type_ref.get_attr(&String::from("__init__")); let mut self_args = PyFuncArgs { args: args.args }; self_args.args.insert(0, obj.clone()); @@ -477,7 +477,10 @@ impl VirtualMachine { match f.kind { PyObjectKind::RustFunction { function: _ } => f.call(self, args), - PyObjectKind::Function { ref code, ref scope } => { + PyObjectKind::Function { + ref code, + ref scope, + } => { let mut scope = self.ctx.new_scope(Some(scope.clone())); let code_object = copy_code(code.clone()); for (name, value) in code_object.arg_names.iter().zip(args.args) { @@ -486,8 +489,7 @@ impl VirtualMachine { let frame = Frame::new(code.clone(), scope); self.run_frame(frame) } - PyObjectKind::Class { name: _, dict: _ } => - self.new_instance(func_ref.clone(), args), + PyObjectKind::Class { name: _, dict: _ } => self.new_instance(func_ref.clone(), args), ref kind => { unimplemented!("invoke unimplemented for: {:?}", kind); } @@ -608,8 +610,7 @@ impl VirtualMachine { PyObjectKind::Integer { value } => Some(value), PyObjectKind::None => None, _ => panic!("Expect Int or None as BUILD_SLICE arguments, got {:?}", x), - }) - .collect(); + }).collect(); let start = out[0]; let stop = out[1]; @@ -691,16 +692,20 @@ impl VirtualMachine { // pop argc arguments // argument: name, args, globals let scope = self.current_frame().locals.clone(); - let obj = PyObject::new(PyObjectKind::Function { code: code_obj, scope: scope }, self.get_type()); + let obj = PyObject::new( + PyObjectKind::Function { + code: code_obj, + scope: scope, + }, + self.get_type(), + ); self.push_value(obj); None } bytecode::Instruction::CallFunction { count } => { let args: Vec = self.pop_multiple(*count); // TODO: kwargs - let args = PyFuncArgs { - args: args - }; + let args = PyFuncArgs { args: args }; let func_ref = self.pop_value(); // Call function: @@ -773,8 +778,7 @@ impl VirtualMachine { bytecode::Instruction::PrintExpr => { let expr = self.pop_value(); match expr.borrow().kind { - PyObjectKind::None => - (), + PyObjectKind::None => (), _ => { builtins::builtin_print( self, @@ -789,9 +793,9 @@ impl VirtualMachine { bytecode::Instruction::LoadBuildClass => { let rustfunc = PyObject::new( PyObjectKind::RustFunction { - function: builtins::builtin_build_class_ + function: builtins::builtin_build_class_, }, - objtype::create_type() + objtype::create_type(), ); self.push_value(rustfunc); None @@ -803,11 +807,10 @@ impl VirtualMachine { PyObjectKind::Scope { ref mut scope } => { scope.locals = locals; } - _ => - panic!("We really expect our scope to be a scope!") + _ => panic!("We really expect our scope to be a scope!"), } None - }, + } _ => panic!("NOT IMPL {:?}", instruction), } }