Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
35 changes: 9 additions & 26 deletions parser/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,8 @@ impl<'input> Lexer<'input> {
Some('\r') => {
return;
}
Some(_) => {
}
None => {
return
}
Some(_) => {}
None => return,
}
}
}
Expand All @@ -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
}
Expand All @@ -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);
Expand Down
124 changes: 52 additions & 72 deletions parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
Expand Down Expand Up @@ -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]
Expand All @@ -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"),
},],
},
],
},],
}
);
}
Expand All @@ -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 },
],
},
],
},],
}
);
}
Expand All @@ -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 },
},]),
},]),
}
);
}
Expand All @@ -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"),
})
}
})
}
})
)
}
Expand All @@ -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],
}],
})
)
}
Expand Down
15 changes: 6 additions & 9 deletions parser/src/token.rs
Original file line number Diff line number Diff line change
@@ -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 },
Expand All @@ -21,7 +19,7 @@ pub enum Tok {
Star,
Slash,
Vbar, // '|'
Amper, // '&'
Amper, // '&'
Less,
Greater,
Equal,
Expand All @@ -38,26 +36,25 @@ 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,
Rarrow,
Ellipsis,

// Keywords (alphabetically):

False,
None,
True,
Expand Down
19 changes: 7 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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") {
Expand Down Expand Up @@ -95,7 +93,7 @@ fn shell_exec(vm: &mut VirtualMachine, source: &String, scope: PyObjectRef) -> b
}
Err(msg) => {
println!("Error: {:?}", msg);
},
}
}
}
Err(msg) => {
Expand Down Expand Up @@ -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 {
Expand All @@ -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),
};
}
}
Loading