mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Change eval compile to statement
This commit is contained in:
1 parent
5783133565
commit
36bef81ceb
7 files changed
+47
-13
No files matched your search
@@ -12,6 +12,13 @@ To test RustPython, do the following:
|
||||
$ cargo run demo.py
|
||||
42
|
||||
|
||||
Or use the interactive shell:
|
||||
|
||||
$ cargo run
|
||||
Welcome to rustpython
|
||||
>>>>> 2+2
|
||||
4
|
||||
|
||||
Or use pip to install extra modules:
|
||||
|
||||
$ cargo run -m pip install requests
|
||||
|
||||
+13
-3
@@ -157,7 +157,7 @@ impl<'input> Lexer<'input> {
|
||||
|
||||
fn is_char(&self) -> bool {
|
||||
match self.chr0 {
|
||||
Some('a'...'z') => return true,
|
||||
Some('a'...'z') | Some('A'...'Z') => return true,
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
@@ -226,8 +226,7 @@ impl<'input> Lexer<'input> {
|
||||
|
||||
match self.chr0 {
|
||||
Some('0'...'9') => return Some(self.lex_number()),
|
||||
// TODO: 'A'...'Z'
|
||||
Some('a'...'z') => return Some(self.lex_identifier()),
|
||||
Some('a'...'z') | Some('A'...'Z') => return Some(self.lex_identifier()),
|
||||
Some('#') => {
|
||||
self.lex_comment();
|
||||
continue;
|
||||
@@ -370,6 +369,17 @@ impl<'input> Lexer<'input> {
|
||||
_ => return Some(Ok((tok_start, Tok::At, self.location + 1))),
|
||||
}
|
||||
}
|
||||
Some('!') => {
|
||||
let tok_start = self.location;
|
||||
self.next_char();
|
||||
match self.chr0 {
|
||||
Some('=') => {
|
||||
self.next_char();
|
||||
return Some(Ok((tok_start, Tok::NotEqual, self.location + 1)));
|
||||
},
|
||||
_ => panic!("Invalid token '!'"),
|
||||
}
|
||||
}
|
||||
Some('~') => {
|
||||
self.next_char();
|
||||
return Some(Ok((0, Tok::Tilde, 0)));
|
||||
|
||||
+10
-2
@@ -46,6 +46,14 @@ pub fn parse_program(source: &String) -> Result<ast::Program, String> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_statement(source: &String) -> Result<ast::Statement, String> {
|
||||
let lxr = lexer::Lexer::new(&source);
|
||||
match python::StatementParser::new().parse(lxr) {
|
||||
Err(why) => Err(String::from(format!("{:?}", why))),
|
||||
Ok(p) => Ok(p),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_expression(source: &String) -> Result<ast::Expression, String> {
|
||||
let lxr = lexer::Lexer::new(&source);
|
||||
match python::ExpressionParser::new().parse(lxr) {
|
||||
@@ -56,7 +64,7 @@ pub fn parse_expression(source: &String) -> Result<ast::Expression, String> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::parse_source;
|
||||
use super::parse_program;
|
||||
use super::ast;
|
||||
|
||||
#[test]
|
||||
@@ -87,7 +95,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_parse_print_2() {
|
||||
let source = String::from("print('Hello world', 2)\n");
|
||||
let parse_ast = parse_source(&source).unwrap();
|
||||
let parse_ast = parse_program(&source).unwrap();
|
||||
assert_eq!(
|
||||
parse_ast,
|
||||
ast::Program {
|
||||
|
||||
@@ -20,7 +20,7 @@ Suite: Vec<ast::Statement> = {
|
||||
"\n" indent <s:Statement+> dedent => s,
|
||||
};
|
||||
|
||||
Statement: ast::Statement = {
|
||||
pub Statement: ast::Statement = {
|
||||
SimpleStatement,
|
||||
CompoundStatement,
|
||||
};
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ fn run_shell() {
|
||||
print!(">>>>> "); // Use 5 items. pypy has 4, cpython has 3.
|
||||
io::stdout().flush().ok().expect("Could not flush stdout");
|
||||
io::stdin().read_line(&mut input);
|
||||
input = input.trim().to_string();
|
||||
// input = input.trim().to_string();
|
||||
debug!("You entered {:?}", input);
|
||||
let result = eval(&mut vm, &input);
|
||||
match result {
|
||||
|
||||
+13
-4
@@ -26,9 +26,17 @@ pub fn compile(source: &String, mode: Mode) -> Result<CodeObject, String> {
|
||||
}
|
||||
}
|
||||
Mode::Eval => {
|
||||
match parser::parse_expression(source) {
|
||||
Ok(ast) => {
|
||||
compiler.compile_expression(ast);
|
||||
match parser::parse_statement(source) {
|
||||
Ok(statement) => {
|
||||
let need_none = if let &ast::Statement::Expression { expression: _ } = &statement {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
};
|
||||
compiler.compile_statement(statement);
|
||||
if need_none {
|
||||
compiler.emit(Instruction::LoadConst { value: bytecode::Constant::None });
|
||||
}
|
||||
compiler.emit(Instruction::ReturnValue);
|
||||
Ok(compiler.pop_code_object())
|
||||
}
|
||||
@@ -90,7 +98,8 @@ impl Compiler {
|
||||
self.compile_expression(expression);
|
||||
|
||||
// Pop result of stack, since we not use it:
|
||||
self.emit(Instruction::Pop);
|
||||
// TODO: do we need to clean the stack here?
|
||||
// self.emit(Instruction::Pop);
|
||||
}
|
||||
ast::Statement::If { test, body } => {
|
||||
self.compile_expression(test);
|
||||
|
||||
+2
-2
@@ -295,7 +295,7 @@ impl VirtualMachine {
|
||||
fn _eq(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
|
||||
let b2 = &*b.borrow();
|
||||
let a2 = &*a.borrow();
|
||||
let result_bool = a == b;
|
||||
let result_bool = a2 == b2;
|
||||
let result = self.ctx.new_bool(result_bool);
|
||||
Ok(result)
|
||||
}
|
||||
@@ -303,7 +303,7 @@ impl VirtualMachine {
|
||||
fn _ne(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
|
||||
let b2 = &*b.borrow();
|
||||
let a2 = &*a.borrow();
|
||||
let result_bool = a != b;
|
||||
let result_bool = a2 != b2;
|
||||
let result = self.ctx.new_bool(result_bool);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user