mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge branch 'master' of https://github.com/RustPython/RustPython
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@
|
||||
__pycache__
|
||||
**/*.pytest_cache
|
||||
.*sw*
|
||||
.repl_history.txt
|
||||
|
||||
@@ -11,3 +11,4 @@ env_logger="0.5.10"
|
||||
clap = "2.31.2"
|
||||
rustpython_parser = {path = "parser"}
|
||||
rustpython_vm = {path = "vm"}
|
||||
rustyline = "2.1.0"
|
||||
|
||||
@@ -17,7 +17,7 @@ Or use the interactive shell:
|
||||
|
||||
$ cargo run
|
||||
Welcome to rustpython
|
||||
>>>>> 2+2
|
||||
>>> 2+2
|
||||
4
|
||||
|
||||
<!-- Or use pip to install extra modules:
|
||||
|
||||
51
src/main.rs
51
src/main.rs
@@ -6,6 +6,7 @@ extern crate env_logger;
|
||||
extern crate log;
|
||||
extern crate rustpython_parser;
|
||||
extern crate rustpython_vm;
|
||||
extern crate rustyline;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use rustpython_parser::parser;
|
||||
@@ -14,8 +15,8 @@ use rustpython_vm::print_exception;
|
||||
use rustpython_vm::pyobject::{PyObjectRef, PyResult};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
use rustpython_vm::{compile, import};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::Editor;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
@@ -146,23 +147,30 @@ fn run_shell(vm: &mut VirtualMachine) -> PyResult {
|
||||
|
||||
// Read a single line:
|
||||
let mut input = String::new();
|
||||
let mut rl = Editor::<()>::new();
|
||||
|
||||
// TODO: Store the history in a proper XDG directory
|
||||
let repl_history_path = ".repl_history.txt";
|
||||
if rl.load_history(repl_history_path).is_err() {
|
||||
println!("No previous history.");
|
||||
}
|
||||
|
||||
loop {
|
||||
// TODO: modules dont support getattr / setattr yet
|
||||
//let prompt = match vm.get_attribute(vm.sys_module.clone(), "ps1") {
|
||||
// Ok(value) => objstr::get_value(&value),
|
||||
// Err(_) => ">>>>> ".to_string(),
|
||||
//};
|
||||
print!(">>>>> ");
|
||||
|
||||
io::stdout().flush().expect("Could not flush stdout");
|
||||
match io::stdin().read_line(&mut input) {
|
||||
Ok(0) => {
|
||||
break;
|
||||
}
|
||||
Ok(_) => {
|
||||
match rl.readline(">>> ") {
|
||||
Ok(line) => {
|
||||
input.push_str(&line);
|
||||
input.push_str("\n");
|
||||
|
||||
debug!("You entered {:?}", input);
|
||||
if shell_exec(vm, &input, vars.clone()) {
|
||||
// Line was complete.
|
||||
rl.add_history_entry(input.as_ref());
|
||||
input = String::new();
|
||||
} else {
|
||||
loop {
|
||||
@@ -171,16 +179,11 @@ fn run_shell(vm: &mut VirtualMachine) -> PyResult {
|
||||
// Ok(value) => objstr::get_value(&value),
|
||||
// Err(_) => "..... ".to_string(),
|
||||
//};
|
||||
print!("..... ");
|
||||
io::stdout().flush().expect("Could not flush stdout");
|
||||
let mut line = String::new();
|
||||
match io::stdin().read_line(&mut line) {
|
||||
Ok(_) => {
|
||||
line = line
|
||||
.trim_right_matches(|c| c == '\r' || c == '\n')
|
||||
.to_string();
|
||||
match rl.readline("... ") {
|
||||
Ok(line) => {
|
||||
if line.len() == 0 {
|
||||
if shell_exec(vm, &input, vars.clone()) {
|
||||
rl.add_history_entry(input.as_ref());
|
||||
input = String::new();
|
||||
break;
|
||||
}
|
||||
@@ -194,9 +197,21 @@ fn run_shell(vm: &mut VirtualMachine) -> PyResult {
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(msg) => panic!("Error: {:?}", msg),
|
||||
Err(ReadlineError::Interrupted) => {
|
||||
// TODO: Raise a real KeyboardInterrupt exception
|
||||
println!("^C");
|
||||
break;
|
||||
}
|
||||
Err(ReadlineError::Eof) => {
|
||||
break;
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Error: {:?}", err);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
rl.save_history(repl_history_path).unwrap();
|
||||
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
23
tests/snippets/builtin_ord.py
Normal file
23
tests/snippets/builtin_ord.py
Normal file
@@ -0,0 +1,23 @@
|
||||
assert ord("a") == 97
|
||||
assert ord("é") == 233
|
||||
assert ord("🤡") == 129313
|
||||
try:
|
||||
ord()
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
assert False, "TypeError not raised when ord() is called with no argument"
|
||||
|
||||
try:
|
||||
ord("")
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
assert False, "TypeError not raised when ord() is called with an empty string"
|
||||
|
||||
try:
|
||||
ord("ab")
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
assert False, "TypeError not raised when ord() is called with more than one character"
|
||||
@@ -293,9 +293,36 @@ fn builtin_map(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.ctx.new_list(elements))
|
||||
}
|
||||
|
||||
// builtin_max
|
||||
fn builtin_max(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(x, None), (y, None)]);
|
||||
|
||||
let order = vm.call_method(x, "__gt__", vec![y.clone()])?;
|
||||
|
||||
if objbool::get_value(&order) {
|
||||
Ok(x.clone())
|
||||
} else {
|
||||
Ok(y.clone())
|
||||
}
|
||||
}
|
||||
|
||||
// builtin_memoryview
|
||||
// builtin_min
|
||||
|
||||
fn builtin_min(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(x, Some(vm.ctx.int_type())), (y, Some(vm.ctx.int_type()))]
|
||||
);
|
||||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
let order = x.cmp(y);
|
||||
|
||||
match order {
|
||||
Ordering::Less | Ordering::Equal => Ok(x.clone()),
|
||||
_ => Ok(y.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
fn builtin_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
@@ -323,7 +350,27 @@ fn builtin_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
// builtin_object
|
||||
// builtin_oct
|
||||
// builtin_open
|
||||
// builtin_ord
|
||||
|
||||
fn builtin_ord(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(string, Some(vm.ctx.str_type()))]);
|
||||
let string = objstr::get_value(string);
|
||||
let string_len = string.chars().count();
|
||||
if string_len > 1 {
|
||||
return Err(vm.new_type_error(
|
||||
format!(
|
||||
"ord() expected a character, but string of length {} found",
|
||||
string_len
|
||||
)
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
match string.chars().next() {
|
||||
Some(character) => Ok(vm.context().new_int(character as i32)),
|
||||
None => Err(vm.new_type_error(
|
||||
"ord() could not guess the integer representing this character".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn builtin_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
@@ -454,6 +501,12 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
dict.insert(String::from("list"), ctx.list_type());
|
||||
dict.insert(String::from("locals"), ctx.new_rustfunc(builtin_locals));
|
||||
dict.insert(String::from("map"), ctx.new_rustfunc(builtin_map));
|
||||
|
||||
dict.insert(String::from("max"), ctx.new_rustfunc(builtin_max));
|
||||
dict.insert(String::from("min"), ctx.new_rustfunc(builtin_min));
|
||||
|
||||
dict.insert(String::from("ord"), ctx.new_rustfunc(builtin_ord));
|
||||
|
||||
dict.insert(String::from("next"), ctx.new_rustfunc(builtin_next));
|
||||
dict.insert(String::from("pow"), ctx.new_rustfunc(builtin_pow));
|
||||
dict.insert(String::from("print"), ctx.new_rustfunc(builtin_print));
|
||||
|
||||
Reference in New Issue
Block a user