Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b30681a

Browse files
committed
Add basic support for Python functions.
It unexpectedly made me fix unmarshalling of code, which made me merge the two unmarshalling passes.
1 parent 22f3a6e commit b30681a

File tree

17 files changed

+467
-243
lines changed

17 files changed

+467
-243
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "pythonvm"
33
version = "0.1.0"
44
authors = ["Valentin Lorentz <[email protected]>"]
5+
build = "build.rs"
56

67
[lib]
78
name = "pythonvm"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ A Python virtual machine, written in Rust.
1212

1313
## Try it
1414

15-
1. Install git, [Rust](https://www.rust-lang.org/downloads.html) and [Cargo](https://crates.io/install)
15+
1. Install Python 3.4 (used as a parser and bytecode compiler), git, [Rust](https://www.rust-lang.org/downloads.html) and [Cargo](https://crates.io/install)
1616
2. `git clone https://github.com/ProgVal/pythonvm-rust.git`
1717
3. `cd pythonvm-rust`
18-
4. `cargo run examples/helloworld.pyc`
18+
4. `cargo run pythonlib/ examples/helloworld.pyc`

build.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use std::process::Command;
2+
3+
fn main() {
4+
Command::new("/usr/bin/env")
5+
.arg("python3")
6+
.arg("-m")
7+
.arg("compileall")
8+
.arg("-b") // old-style bytecode layout
9+
.arg("pythonlib/")
10+
.arg("examples/")
11+
.spawn()
12+
.unwrap()
13+
.wait()
14+
.unwrap();
15+
}

examples/helloworld.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print('hello world')

examples/helloworld.pyc

11 Bytes
Binary file not shown.

pythonlib/builtins.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
def print(value):
2+
__primitives__.write_stdout(value)
3+
__primitives__.write_stdout("\n")

pythonlib/builtins.pyc

261 Bytes
Binary file not shown.

src/bin.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,32 @@ extern crate pythonvm;
22

33
use std::env::args;
44
use std::fs::File;
5+
use std::path::PathBuf;
56

6-
fn parse_args() -> (String, Option<String>) {
7+
fn parse_args() -> (String, Option<(String, String)>) {
78
let mut args = args();
89
let executable = args.next().unwrap();
10+
let libdir = args.next();
911
let filename = args.next();
1012
let extra = args.next();
11-
match (filename, extra) {
12-
(Some(filename), None) => (executable, Some(filename)),
13+
match (libdir, filename, extra) {
14+
(Some(libdir), Some(filename), None) => (executable, Some((libdir, filename))),
1315
_ => (executable, None),
1416
}
1517
}
1618

1719

1820
pub fn main() {
19-
let filename = match parse_args() {
20-
(_, Some(filename)) => filename,
21+
let (libdir, filename) = match parse_args() {
22+
(_, Some((libdir, filename))) => (libdir, filename),
2123
(executable, None) => {
22-
println!("Syntax: {} filename.pyc", executable);
24+
println!("Syntax: {} pythonlib/ filename.pyc", executable);
2325
return
2426
}
2527
};
2628
let mut file = File::open(filename).unwrap();
27-
let env_proxy = pythonvm::RealEnvProxy::new();
29+
let mut path = PathBuf::new();
30+
path.push(&libdir);
31+
let env_proxy = pythonvm::RealEnvProxy::new(path);
2832
let (_processor, _result) = pythonvm::run_module(&mut file, env_proxy).unwrap();
2933
}

src/lib.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ mod objects;
33
mod processor;
44
mod sandbox;
55
mod stack;
6+
mod primitives;
67

78
use std::fmt;
89
use std::io;
910
use processor::Processor;
11+
use std::path::PathBuf;
12+
use std::env;
1013

1114
pub use sandbox::{RealEnvProxy, MockEnvProxy};
1215

@@ -33,15 +36,18 @@ pub fn run_module<R: io::Read, EP: sandbox::EnvProxy>(reader: &mut R, envproxy:
3336
// TODO: do something with the content of the buffer
3437
let mut store = objects::ObjectStore::new();
3538
let module = try!(marshal::read_object(reader, &mut store).map_err(InterpreterError::Unmarshal));
36-
let mut processor = Processor { envproxy: envproxy, store: store, builtin_functions: Processor::get_default_builtins() };
39+
let mut processor = Processor { envproxy: envproxy, store: store, primitives: primitives::get_default_primitives() };
3740
let result = try!(processor.run_code_object(module).map_err(InterpreterError::Processor));
3841
Ok((processor, result))
3942
}
4043

4144
#[test]
42-
fn test_hello_world() {
43-
let mut reader: &[u8] = b"\xee\x0c\r\n\x15j\nW\x15\x00\x00\x00\xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00@\x00\x00\x00s\x0e\x00\x00\x00e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)\x02z\x0bHello worldN)\x01\xda\x05print\xa9\x00r\x02\x00\x00\x00r\x02\x00\x00\x00\xfa\x0b/tmp/foo.py\xda\x08<module>\x01\x00\x00\x00s\x00\x00\x00\x00";
44-
let envproxy = sandbox::MockEnvProxy::new();
45+
fn test_primitive_hello_world() {
46+
let mut reader: &[u8] = b"\xee\x0c\r\n\xb0\x92\x0fW\x15\x00\x00\x00\xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00@\x00\x00\x00s\x0e\x00\x00\x00e\x00\x00d\x00\x00\x83\x01\x00\x01d\x01\x00S)\x02z\x0bHello worldN)\x01\xda\x05print\xa9\x00r\x02\x00\x00\x00r\x02\x00\x00\x00\xfa\x16examples/helloworld.py\xda\x08<module>\x01\x00\x00\x00s\x00\x00\x00\x00";
47+
let mut path = PathBuf::new();
48+
path.push(env::current_dir().unwrap());
49+
path.push("pythonlib/");
50+
let envproxy = sandbox::MockEnvProxy::new(path);
4551
let (processor, result) = run_module(&mut reader, envproxy).unwrap();
4652
println!("{:?}", result);
4753
assert_eq!(*processor.envproxy.stdout_content.lock().unwrap(), b"Hello world\n");

0 commit comments

Comments
 (0)