diff --git a/Lib/operator.py b/Lib/operator.py new file mode 100644 index 000000000..f21920064 --- /dev/null +++ b/Lib/operator.py @@ -0,0 +1,15 @@ + + +# Comparison operations: + +def eq(a, b): + return a == b + + +def ne(a, b): + return a != b + + +def ge(a, b): + return a >= b + diff --git a/README.md b/README.md index 465b03807..cc1f6cbd2 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,11 @@ Or use pip to install extra modules: $ cargo run -m pip install requests +# Goals + +- Full python environment entirely in Rust (not CPython bindings) +- A clean implementation without compatibility hacks + # Code organization - parser: python lexing, parsing and ast diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 92c827cbd..b5da37bb4 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -65,7 +65,7 @@ pub fn len(args: Vec>) -> NativeType { } */ -pub fn fill_scope() -> PyObjectRef { +pub fn make_module() -> PyObjectRef { // scope[String::from("print")] = print; let obj = PyObject::new(PyObjectKind::Module); obj.borrow_mut().dict.insert(String::from("print"), PyObject::new(PyObjectKind::RustFunction { function: print })); diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 3638ff030..627503f1a 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -10,6 +10,7 @@ pub mod bytecode; mod builtins; mod vm; mod objint; +mod objtype; pub mod compile; pub use self::vm::VirtualMachine; diff --git a/vm/src/objint.rs b/vm/src/objint.rs index eaff0748e..a3f8cc75c 100644 --- a/vm/src/objint.rs +++ b/vm/src/objint.rs @@ -15,7 +15,7 @@ fn set_attr(a: &mut PyObjectRef, name: String, b: PyObjectRef) { } */ -fn create_type() -> PyObjectRef { +pub fn create_type() -> PyObjectRef { let mut typ = PyObject::new(PyObjectKind::Type); typ.borrow_mut().dict.insert("__str__".to_string(), PyObject::new(PyObjectKind::RustFunction { function: str })); typ diff --git a/vm/src/objtype.rs b/vm/src/objtype.rs new file mode 100644 index 000000000..e8f9a1181 --- /dev/null +++ b/vm/src/objtype.rs @@ -0,0 +1,12 @@ + +/* + * The magical type type + */ + +use super::pyobject::{PyObject, PyObjectRef, PyObjectKind}; + +pub fn create_type() -> PyObjectRef { + let mut typ = PyObject::new(PyObjectKind::Type); + // typ.borrow_mut().dict.insert("__str__".to_string(), PyObject::new(PyObjectKind::RustFunction { function: str })); + typ +} diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index fb90e8d7e..4f4428ded 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -4,6 +4,8 @@ use std::cell::RefCell; use std::collections::HashMap; use std::ops::{Add, Mul, Sub}; use super::bytecode; +use super::objint; +use super::objtype; /* Python objects and references. @@ -33,6 +35,23 @@ impl fmt::Display for PyObjectRef { } }*/ +pub struct Context { + int_type: PyObjectRef, +} + +// Basic objects: +impl Context { + fn new() -> Context { + let type_type = objint::create_type(); + let int_type = objint::create_type(); + // let str_type = objstr::make_type(); + Context { + // type_type: type_type, + int_type: int_type, + } + } +} + #[derive(Debug)] pub struct PyObject { pub kind: PyObjectKind, @@ -95,6 +114,7 @@ impl PyObject { pub fn new(kind: PyObjectKind) -> PyObjectRef { PyObject { kind: kind, + // typ: PyO dict: HashMap::new(), }.into_ref() } @@ -172,6 +192,10 @@ impl PyObject { pub fn new_int(i: i32) -> PyObjectRef { PyObject::new(PyObjectKind::Integer { value: i }) } + + pub fn new_str(s: String) -> PyObjectRef { + PyObject::new(PyObjectKind::String { value: s }) + } } impl<'a> Add<&'a PyObject> for &'a PyObject { diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 4e28676b6..a0ef5b326 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -45,6 +45,7 @@ struct Frame { pub struct VirtualMachine { frames: Vec, + builtins: PyObjectRef, } impl Frame { @@ -58,9 +59,6 @@ impl Frame { let mut locals = globals; locals.extend(callargs); - //TODO: move this into the __builtin__ module when we have a module type - locals.insert(String::from("print"), PyObject::new(PyObjectKind::RustFunction { function: builtins::print })); - // locals.insert("print".to_string(), Rc::new(NativeType::NativeFunction(builtins::print))); // locals.insert("len".to_string(), Rc::new(NativeType::NativeFunction(builtins::len))); Frame { code: code, @@ -88,6 +86,7 @@ impl VirtualMachine { pub fn new() -> VirtualMachine { VirtualMachine { frames: vec![], + builtins: builtins::make_module(), } } @@ -298,7 +297,6 @@ impl VirtualMachine { debug!("Got ast: {:?}", program); let bytecode = compile(program); debug!("Code object: {:?}", bytecode); - // let obj = PyObject::new(PyObjectKind::Code { code: bytecode }); let obj = PyObject::new(PyObjectKind::Module); // As a sort of hack, create a frame and run code in it @@ -366,6 +364,10 @@ impl VirtualMachine { let obj = self.current_frame().locals[name].clone(); self.push_value(obj); None + } else if self.builtins.borrow().dict.contains_key(name) { + let obj = self.builtins.borrow().dict[name].clone(); + self.push_value(obj); + None } else { let name_error = PyObject::new(PyObjectKind::NameError { name: name.to_string() }); Some(Err(name_error))