From 2d0e4efecf0d5b1171b473bd70bb088c29795244 Mon Sep 17 00:00:00 2001 From: Shing Lyu Date: Mon, 11 Jun 2018 22:29:09 +0200 Subject: [PATCH] Make the main program parse from parser and run with vm --- Cargo.toml | 5 ++- parser/Cargo.toml | 7 +-- parser/src/compiler/compile_py_code_object.rs | 33 ++++++++++++++ parser/src/compiler/mod.rs | 2 +- parser/src/lib.rs | 2 +- parser/src/main.rs | 1 - py_code_object/src/lib.rs | 11 +++++ src/main.rs | 44 ++++++++++++++++++- vm/RustPython/src/lib.rs | 1 + 9 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 parser/src/compiler/compile_py_code_object.rs diff --git a/Cargo.toml b/Cargo.toml index b64bb456c..5b52c3220 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,11 @@ [package] name = "rustpython" -version = "0.1.0" +version = "0.0.1" authors = ["Windel Bouwman", "Shing Lyu "] [dependencies] +log="0.4.1" +env_logger="0.5.10" +clap = "2.31.2" rustpython_parser = {path = "parser"} rustpython_vm = {path = "vm/RustPython"} diff --git a/parser/Cargo.toml b/parser/Cargo.toml index c2e84b5d7..3908ae751 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -9,8 +9,9 @@ lalrpop="0.15.1" [dependencies] clap="2.20.0" -lalrpop-util="0.15.1" -regex="0.2.2" -log="0.4.1" env_logger="0.5.10" +lalrpop-util="0.15.1" +log="0.4.1" +py_code_object = { path = "../py_code_object" } +regex="0.2.2" diff --git a/parser/src/compiler/compile_py_code_object.rs b/parser/src/compiler/compile_py_code_object.rs new file mode 100644 index 000000000..12325cdec --- /dev/null +++ b/parser/src/compiler/compile_py_code_object.rs @@ -0,0 +1,33 @@ +/* + * Take an AST and transform it into py_code_object compatiable bytecode + */ +extern crate py_code_object; + +use super::ast; +use self::py_code_object::{PyCodeObject}; + +struct Compiler { + code_object: PyCodeObject, + nxt_label: usize, +} + +pub fn compile(p: ast::Program) -> PyCodeObject { + let mut compiler = Compiler::new(); + compiler.compile_program(p); + compiler.code_object +} + +type Label = usize; + +impl Compiler { + fn new() -> Self { + Compiler { + code_object: PyCodeObject::new(), + nxt_label: 0, + } + } + + fn compile_program(&mut self, program: ast::Program) { + return; + } +} diff --git a/parser/src/compiler/mod.rs b/parser/src/compiler/mod.rs index 9c210f48f..b31af13fb 100644 --- a/parser/src/compiler/mod.rs +++ b/parser/src/compiler/mod.rs @@ -6,13 +6,13 @@ mod ast; mod token; mod lexer; mod compile; +pub mod compile_py_code_object; mod bytecode; mod builtins; mod pyobject; mod vm; pub use self::parser::parse; -pub use self::compile::compile; pub use self::vm::evaluate; diff --git a/parser/src/lib.rs b/parser/src/lib.rs index d8cba2c32..c3e886ddc 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -1,4 +1,4 @@ #[macro_use] extern crate log; -mod compiler; +pub mod compiler; diff --git a/parser/src/main.rs b/parser/src/main.rs index 9afac3f50..5ea21c448 100644 --- a/parser/src/main.rs +++ b/parser/src/main.rs @@ -1,4 +1,3 @@ - extern crate clap; #[macro_use] extern crate log; diff --git a/py_code_object/src/lib.rs b/py_code_object/src/lib.rs index 06e41cbf2..006ec4234 100644 --- a/py_code_object/src/lib.rs +++ b/py_code_object/src/lib.rs @@ -33,6 +33,17 @@ pub struct PyCodeObject { pub co_varnames: Vec, } +impl PyCodeObject { + pub fn new() -> PyCodeObject { + PyCodeObject { + co_consts: Vec::::new(), + co_names: Vec::::new(), + co_code: Vec::<(usize, String, Option)>::new(), //size, name, args + co_varnames: Vec::::new(), + } + } +} + #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] pub struct Function { pub code: PyCodeObject diff --git a/src/main.rs b/src/main.rs index 1d6419107..66a5ccc1e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,48 @@ //extern crate rustpython_parser; +#[macro_use] +extern crate clap; +extern crate env_logger; +#[macro_use] +extern crate log; +extern crate rustpython_parser; extern crate rustpython_vm; +use clap::{Arg, App}; +use std::path::Path; +use rustpython_parser::compiler; +use rustpython_vm::VirtualMachine; + + fn main() { - unimplemented!(); + env_logger::init(); + let matches = App::new("RustPython") + .version(crate_version!()) + .author(crate_authors!()) + .about("Rust implementation of the Python language") + .arg(Arg::with_name("script") + .required(true) + .index(1)) + .arg(Arg::with_name("v") + .short("v") + .multiple(true) + .help("Give the verbosity")) + .get_matches(); + + // Figure out the filename: + let script_file = matches.value_of("script").unwrap_or("foo"); + debug!("Running file {}", script_file); + + // Parse an ast from it: + let filepath = Path::new(script_file); + match compiler::parse(filepath) { + Ok(program) => { + debug!("Got ast: {:?}", program); + let bytecode = compiler::compile_py_code_object::compile(program); + debug!("Code object: {:?}", bytecode); + let mut vm = VirtualMachine::new(); + vm.run_code(bytecode); + }, + Err(msg) => error!("Parsing went horribly wrong: {}", msg), + } } + diff --git a/vm/RustPython/src/lib.rs b/vm/RustPython/src/lib.rs index fa8a341a8..0e857ea65 100644 --- a/vm/RustPython/src/lib.rs +++ b/vm/RustPython/src/lib.rs @@ -145,6 +145,7 @@ impl VirtualMachine { //while curr_frame.lasti < curr_frame.code.co_code.len() { let op_code = { let curr_frame = self.curr_frame(); + if curr_frame.code.co_code.len() == 0 { panic!("Trying to run an empty frame. Check if the bytecode is empty"); } let op_code = curr_frame.code.co_code[curr_frame.lasti].clone(); curr_frame.lasti += 1; op_code