From 286051383e73d79a162e3ff98c1c6875a97649b3 Mon Sep 17 00:00:00 2001 From: coolreader18 <33094578+coolreader18@users.noreply.github.com> Date: Sun, 11 Aug 2019 22:15:07 -0500 Subject: [PATCH] impl std::str::FromStr for compile::Mode --- compiler/src/compile.rs | 29 +++++++++++++++++++++++++++++ derive/src/compile_bytecode.rs | 12 +++++------- vm/src/builtins.rs | 5 +++-- vm/src/eval.rs | 11 ----------- vm/src/stdlib/symtable.rs | 5 +++-- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/compiler/src/compile.rs b/compiler/src/compile.rs index f6f0e1cb0..9b0ad46fd 100644 --- a/compiler/src/compile.rs +++ b/compiler/src/compile.rs @@ -109,6 +109,35 @@ pub enum Mode { Single, } +impl std::str::FromStr for Mode { + type Err = ModeParseError; + fn from_str(s: &str) -> Result { + match s { + "exec" => Ok(Mode::Exec), + "eval" => Ok(Mode::Eval), + "single" => Ok(Mode::Single), + _ => Err(ModeParseError { _priv: () }), + } + } +} + +#[derive(Debug)] +pub struct ModeParseError { + _priv: (), +} + +impl std::fmt::Display for ModeParseError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, r#"mode should be "exec", "eval", or "single""#) + } +} + +#[derive(Clone, Copy)] +enum EvalContext { + Statement, + Expression, +} + pub(crate) type Label = usize; impl Default for Compiler diff --git a/derive/src/compile_bytecode.rs b/derive/src/compile_bytecode.rs index c37e5b3f9..cf772fe28 100644 --- a/derive/src/compile_bytecode.rs +++ b/derive/src/compile_bytecode.rs @@ -169,15 +169,13 @@ impl PyCompileInput { for meta in &self.metas { if let Meta::NameValue(name_value) = meta { if name_value.ident == "mode" { - mode = Some(match &name_value.lit { - Lit::Str(s) => match s.value().as_str() { - "exec" => compile::Mode::Exec, - "eval" => compile::Mode::Eval, - "single" => compile::Mode::Single, - _ => bail_span!(s, "mode must be exec, eval, or single"), + match &name_value.lit { + Lit::Str(s) => match s.value().parse() { + Ok(mode_val) => mode = Some(mode_val), + Err(e) => bail_span!(s, "{}", e), }, _ => bail_span!(name_value.lit, "mode must be a string"), - }) + } } else if name_value.ident == "module_name" { module_name = Some(match &name_value.lit { Lit::Str(s) => s.value(), diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 956322c59..0032cc10e 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -21,7 +21,6 @@ use crate::obj::objtype::{self, PyClassRef}; #[cfg(feature = "rustpython-compiler")] use rustpython_compiler::compile; -use crate::eval::get_compile_mode; use crate::function::{single_or_tuple_any, Args, KwArgs, OptionalArg, PyFuncArgs}; use crate::pyobject::{ Either, IdProtocol, IntoPyObject, ItemProtocol, PyIterable, PyObjectRef, PyResult, PyValue, @@ -125,7 +124,9 @@ fn builtin_compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult str::from_utf8(&bytes).unwrap().to_string(), }; - let mode = get_compile_mode(vm, &args.mode.value)?; + let mode = args.mode.as_str().parse().map_err(|_| { + vm.new_value_error("compile() mode must be 'exec', 'eval' or 'single'".to_owned()) + })?; vm.compile(&source, mode, args.filename.value.to_string()) .map_err(|err| vm.new_syntax_error(&err)) diff --git a/vm/src/eval.rs b/vm/src/eval.rs index c00d77fc1..8feeb8741 100644 --- a/vm/src/eval.rs +++ b/vm/src/eval.rs @@ -13,17 +13,6 @@ pub fn eval(vm: &VirtualMachine, source: &str, scope: Scope, source_path: &str) } } -pub fn get_compile_mode(vm: &VirtualMachine, mode: &str) -> PyResult { - match mode { - "exec" => Ok(compile::Mode::Exec), - "eval" => Ok(compile::Mode::Eval), - "single" => Ok(compile::Mode::Single), - _ => { - Err(vm.new_value_error("compile() mode must be 'exec', 'eval' or 'single'".to_string())) - } - } -} - #[cfg(test)] mod tests { use super::eval; diff --git a/vm/src/stdlib/symtable.rs b/vm/src/stdlib/symtable.rs index 692e1ce3b..320fc3c99 100644 --- a/vm/src/stdlib/symtable.rs +++ b/vm/src/stdlib/symtable.rs @@ -1,4 +1,3 @@ -use crate::eval::get_compile_mode; use crate::obj::objstr::PyStringRef; use crate::obj::objtype::PyClassRef; use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue}; @@ -28,7 +27,9 @@ fn symtable_symtable( mode: PyStringRef, vm: &VirtualMachine, ) -> PyResult { - let mode = get_compile_mode(vm, &mode.value)?; + let mode = mode.as_str().parse().map_err(|_| { + vm.new_value_error("symtable() arg 3 must be 'exec' or 'eval' or 'single'".to_owned()) + })?; let symtable = source_to_symtable(&source.value, mode).map_err(|err| vm.new_syntax_error(&err))?;