Merge pull request #57 from OddBloke/rustfmt

Format the whole project (and add Travis check to avoid regression)
This commit is contained in:
Windel Bouwman
2018-08-11 10:09:45 +02:00
committed by GitHub
17 changed files with 290 additions and 234 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -43,8 +43,10 @@ pub fn parse(filename: &Path) -> Result<ast::Program, String> {
pub fn parse_program(source: &String) -> Result<ast::Program, String> {
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],
}],
})
)
}

View File

@@ -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,

View File

@@ -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),
};
}
}

View File

@@ -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))
}

View File

@@ -21,7 +21,7 @@ pub struct CodeObject {
}
impl CodeObject {
pub fn new(arg_names : Vec<String>) -> CodeObject {
pub fn new(arg_names: Vec<String>) -> CodeObject {
CodeObject {
instructions: Vec::new(),
label_map: HashMap::new(),
@@ -38,35 +38,72 @@ pub enum Instruction {
name: String,
symbol: Option<String>,
},
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))

View File

@@ -14,7 +14,11 @@ struct Compiler {
nxt_label: usize,
}
pub fn compile(vm: &mut VirtualMachine, source: &String, mode: Mode) -> Result<PyObjectRef, String> {
pub fn compile(
vm: &mut VirtualMachine,
source: &String,
mode: Mode,
) -> Result<PyObjectRef, String> {
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<P
}
}
compiler.emit(Instruction::LoadConst {
value: bytecode::Constant::None
value: bytecode::Constant::None,
});
compiler.emit(Instruction::ReturnValue);
}
@@ -255,10 +259,11 @@ impl Compiler {
}
ast::Statement::ClassDef { name, body } => {
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 => {

View File

@@ -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() {

View File

@@ -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::<Vec<_>>()
.join("");
let block_str = self.blocks
let block_str = self
.blocks
.iter()
.map(|elem| format!("\n > {:?}", elem))
.collect::<Vec<_>>()

View File

@@ -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<String>)
fn find_source(name: &String) -> io::Result<PathBuf> {
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),
)),
}
}

View File

@@ -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;

View File

@@ -1,4 +1,3 @@
use super::pyobject::{PyObjectKind, PyObjectRef};
pub fn boolval(o: PyObjectRef) -> bool {

View File

@@ -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(),
);

View File

@@ -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
}

View File

@@ -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<PyObjectRef>, // Parent scope
pub locals: PyObjectRef, // Variables
pub parent: Option<PyObjectRef>, // 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!("<class '{}'>", name),
PyObjectKind::Instance { dict: _ } =>
format!("<instance>"),
PyObjectKind::Class {
ref name,
dict: ref _dict,
} => format!("<class '{}'>", name),
PyObjectKind::Instance { dict: _ } => format!("<instance>"),
PyObjectKind::Code { code: _ } => format!("<code>"),
PyObjectKind::Function { code: _, scope: _ } => format!("<func>"),
PyObjectKind::RustFunction { function: _ } => format!("<rustfunc>"),

View File

@@ -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<PyObjectRef> = 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),
}
}