From 62bb15faef12bf90e8e0c7ef3132590f3e08bf80 Mon Sep 17 00:00:00 2001 From: cgm616 Date: Mon, 15 Oct 2018 01:02:56 -0400 Subject: [PATCH 1/4] Add max and min builtins --- vm/src/builtins.rs | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 4c4c936e7..b49ab8d28 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -293,9 +293,41 @@ 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, Some(vm.ctx.int_type())), (y, Some(vm.ctx.int_type()))] + ); + + use std::cmp::Ordering; + + let order = x.cmp(y); + + match order { + Ordering::Greater | Ordering::Equal => Ok(x.clone()), + _ => 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!( @@ -454,6 +486,8 @@ 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("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)); From 2ca0a39a4ce0b94989b12b416fe7b5ea6d431bc8 Mon Sep 17 00:00:00 2001 From: cgm616 Date: Mon, 15 Oct 2018 18:06:06 -0400 Subject: [PATCH 2/4] Add tests for new max and min --- vm/src/builtins.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index b49ab8d28..7928a1a8e 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -294,19 +294,14 @@ fn builtin_map(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { } fn builtin_max(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(x, Some(vm.ctx.int_type())), (y, Some(vm.ctx.int_type()))] - ); + arg_check!(vm, args, required = [(x, None), (y, None)]); - use std::cmp::Ordering; + let order = vm.call_method(x, "__gt__", vec![y.clone()])?; - let order = x.cmp(y); - - match order { - Ordering::Greater | Ordering::Equal => Ok(x.clone()), - _ => Ok(y.clone()), + if objbool::get_value(&order) { + Ok(x.clone()) + } else { + Ok(y.clone()) } } From 3e7f1683599fa6715b5328e8e3206afe34c60779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Tue, 16 Oct 2018 17:19:43 +0200 Subject: [PATCH 3/4] builtin ord basic implementation. Fixes #151 --- tests/snippets/builtin_ord.py | 23 +++++++++++++++++++++++ vm/src/builtins.rs | 23 ++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/snippets/builtin_ord.py diff --git a/tests/snippets/builtin_ord.py b/tests/snippets/builtin_ord.py new file mode 100644 index 000000000..2dd03f91a --- /dev/null +++ b/tests/snippets/builtin_ord.py @@ -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" diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 4c4c936e7..85eb80a10 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -323,7 +323,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 +474,7 @@ 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("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)); From 4e72c5204f04b9f0cef81735eacb67ba3ae653dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Tue, 16 Oct 2018 20:34:00 +0200 Subject: [PATCH 4/4] Basic repl based on rustyline --- .gitignore | 1 + Cargo.toml | 1 + README.md | 2 +- src/main.rs | 51 +++++++++++++++++++++++++++++++++------------------ 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 46e6418de..3050f18d2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__ **/*.pytest_cache .*sw* +.repl_history.txt diff --git a/Cargo.toml b/Cargo.toml index 5554deb92..2bd834312 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/README.md b/README.md index 36ba0212c..df2ec53cc 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Or use the interactive shell: $ cargo run Welcome to rustpython - >>>>> 2+2 + >>> 2+2 4