From 14df5ce94c43fcc83a8a98cd25393585eb40265f Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Wed, 14 Sep 2022 12:45:04 +0900 Subject: [PATCH] Update `Runnable` API types This change allows Erg to pass information in a thread-safe manner. --- compiler/erg_common/config.rs | 30 ++++++++++++++---------------- compiler/erg_common/stdin.rs | 18 ++++++++---------- compiler/erg_common/traits.rs | 5 ++--- compiler/erg_compiler/compile.rs | 7 +++---- compiler/erg_compiler/lower.rs | 2 +- compiler/erg_parser/lex.rs | 5 ++--- compiler/erg_parser/parse.rs | 4 ++-- src/dummy.rs | 3 +-- 8 files changed, 33 insertions(+), 41 deletions(-) diff --git a/compiler/erg_common/config.rs b/compiler/erg_common/config.rs index 5c362cfb..d30fddf4 100644 --- a/compiler/erg_common/config.rs +++ b/compiler/erg_common/config.rs @@ -7,7 +7,6 @@ use std::io::{stdin, BufRead, BufReader, Read}; use std::process; use crate::stdin::GLOBAL_STDIN; -use crate::Str; use crate::{power_assert, read_file}; pub const SEMVER: &str = env!("CARGO_PKG_VERSION"); @@ -19,12 +18,12 @@ pub const BUILD_DATE: &str = env!("BUILD_DATE"); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Input { /// filename - File(Str), + File(String), REPL, /// same content as cfg.command - Pipe(Str), + Pipe(String), /// from command option | eval - Str(Str), + Str(String), Dummy, } @@ -52,7 +51,7 @@ impl Input { } } - pub fn read(&self) -> Str { + pub fn read(&self) -> String { match self { Self::File(filename) => { let file = match File::open(&filename[..]) { @@ -63,15 +62,14 @@ impl Input { process::exit(code); } }; - let src = match read_file(file) { + match read_file(file) { Ok(s) => s, Err(e) => { let code = e.raw_os_error().unwrap_or(1); println!("cannot read '{filename}': [Errno {code}] {e}"); process::exit(code); } - }; - Str::from(src) + } } Self::Pipe(s) | Self::Str(s) => s.clone(), Self::REPL => GLOBAL_STDIN.read(), @@ -79,7 +77,7 @@ impl Input { } } - pub fn reread_lines(&self, ln_begin: usize, ln_end: usize) -> Vec { + pub fn reread_lines(&self, ln_begin: usize, ln_end: usize) -> Vec { power_assert!(ln_begin, >=, 1); match self { Self::File(filename) => match File::open(&filename[..]) { @@ -87,7 +85,7 @@ impl Input { let mut codes = vec![]; let mut lines = BufReader::new(file).lines().skip(ln_begin - 1); for _ in ln_begin..=ln_end { - codes.push(Str::from(lines.next().unwrap().unwrap())); + codes.push(lines.next().unwrap().unwrap()); } codes } @@ -96,18 +94,18 @@ impl Input { Self::Pipe(s) | Self::Str(s) => s.split('\n').collect::>() [ln_begin - 1..=ln_end - 1] .iter() - .map(|s| Str::rc(*s)) + .map(|s| s.to_string()) .collect(), Self::REPL => GLOBAL_STDIN.reread_lines(ln_begin, ln_end), Self::Dummy => panic!("cannot read lines from a dummy file"), } } - pub fn reread(&self) -> Str { + pub fn reread(&self) -> String { match self { Self::File(_filename) => todo!(), Self::Pipe(s) | Self::Str(s) => s.clone(), - Self::REPL => Str::from(GLOBAL_STDIN.reread().trim_end().to_owned()), + Self::REPL => GLOBAL_STDIN.reread().trim_end().to_owned(), Self::Dummy => panic!("cannot read from a dummy file"), } } @@ -142,7 +140,7 @@ impl Default for ErgConfig { let input = if is_stdin_piped { let mut buffer = String::new(); stdin().read_to_string(&mut buffer).unwrap(); - Input::Pipe(Str::from(buffer)) + Input::Pipe(buffer) } else { Input::REPL }; @@ -174,7 +172,7 @@ impl ErgConfig { while let Some(arg) = args.next() { match &arg[..] { "-c" => { - cfg.input = Input::Str(Str::from(args.next().unwrap())); + cfg.input = Input::Str(args.next().unwrap()); } "--dump-as-pyc" => { cfg.dump_as_pyc = true; @@ -223,7 +221,7 @@ impl ErgConfig { panic!("invalid option: {other}"); } _ => { - cfg.input = Input::File(Str::from(arg)); + cfg.input = Input::File(arg); break; } } diff --git a/compiler/erg_common/stdin.rs b/compiler/erg_common/stdin.rs index 1e1b02a4..06157586 100644 --- a/compiler/erg_common/stdin.rs +++ b/compiler/erg_common/stdin.rs @@ -2,29 +2,27 @@ use std::cell::RefCell; use std::io::{stdin, BufRead, BufReader}; use std::thread::LocalKey; -use crate::Str; - pub struct StdinReader { pub lineno: usize, - buf: Vec, + buf: Vec, } impl StdinReader { - pub fn read(&mut self) -> Str { + pub fn read(&mut self) -> String { let mut buf = "".to_string(); let stdin = stdin(); let mut reader = BufReader::new(stdin.lock()); reader.read_line(&mut buf).unwrap(); self.lineno += 1; - self.buf.push(buf.into()); + self.buf.push(buf); self.buf.last().unwrap().clone() } - pub fn reread(&self) -> Str { + pub fn reread(&self) -> String { self.buf.last().unwrap().clone() } - pub fn reread_lines(&self, ln_begin: usize, ln_end: usize) -> Vec { + pub fn reread_lines(&self, ln_begin: usize, ln_end: usize) -> Vec { self.buf[ln_begin - 1..=ln_end - 1].to_vec() } } @@ -39,15 +37,15 @@ pub struct GlobalStdin(LocalKey>); pub static GLOBAL_STDIN: GlobalStdin = GlobalStdin(READER); impl GlobalStdin { - pub fn read(&'static self) -> Str { + pub fn read(&'static self) -> String { self.0.with(|s| s.borrow_mut().read()) } - pub fn reread(&'static self) -> Str { + pub fn reread(&'static self) -> String { self.0.with(|s| s.borrow().reread()) } - pub fn reread_lines(&'static self, ln_begin: usize, ln_end: usize) -> Vec { + pub fn reread_lines(&'static self, ln_begin: usize, ln_end: usize) -> Vec { self.0 .with(|s| s.borrow_mut().reread_lines(ln_begin, ln_end)) } diff --git a/compiler/erg_common/traits.rs b/compiler/erg_common/traits.rs index a0ddc918..479590dd 100644 --- a/compiler/erg_common/traits.rs +++ b/compiler/erg_common/traits.rs @@ -10,7 +10,6 @@ use std::vec::IntoIter; use crate::config::{ErgConfig, Input, BUILD_DATE, GIT_HASH_SHORT, SEMVER}; use crate::error::{ErrorDisplay, ErrorKind, Location, MultiErrorDisplay}; -use crate::Str; use crate::{addr_eq, chomp, log, switch_unreachable}; pub trait Stream: Sized { @@ -334,7 +333,7 @@ pub trait Runnable: Sized { } fn finish(&mut self); // called when the :exit command is received. fn clear(&mut self); - fn eval(&mut self, src: Str) -> Result; + fn eval(&mut self, src: String) -> Result; fn exec(&mut self) -> Result<(), Self::Errs>; fn ps1(&self) -> String { @@ -395,7 +394,7 @@ pub trait Runnable: Sized { output.flush().unwrap(); continue; } - match instance.eval(mem::take(&mut lines).into()) { + match instance.eval(mem::take(&mut lines)) { Ok(out) => { output.write_all((out + "\n").as_bytes()).unwrap(); output.flush().unwrap(); diff --git a/compiler/erg_compiler/compile.rs b/compiler/erg_compiler/compile.rs index 48edec1a..86d22b1f 100644 --- a/compiler/erg_compiler/compile.rs +++ b/compiler/erg_compiler/compile.rs @@ -7,7 +7,6 @@ use erg_common::config::{ErgConfig, Input}; use erg_common::error::MultiErrorDisplay; use erg_common::log; use erg_common::traits::{Runnable, Stream}; -use erg_common::Str; use erg_type::codeobj::CodeObj; use erg_parser::ParserRunner; @@ -134,7 +133,7 @@ impl Runnable for Compiler { self.compile_and_dump_as_pyc(src, path, "exec") } - fn eval(&mut self, src: Str) -> Result { + fn eval(&mut self, src: String) -> Result { let codeobj = self.compile(src, "eval")?; Ok(codeobj.code_info()) } @@ -150,7 +149,7 @@ impl Compiler { pub fn compile_and_dump_as_pyc>( &mut self, - src: Str, + src: String, path: P, mode: &str, ) -> Result<(), CompileErrors> { @@ -160,7 +159,7 @@ impl Compiler { Ok(()) } - pub fn compile(&mut self, src: Str, mode: &str) -> Result { + pub fn compile(&mut self, src: String, mode: &str) -> Result { log!(info "the compiling process has started."); let mut cfg = self.cfg.copy(); cfg.input = Input::Str(src); diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index f183a91c..df9dc02c 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -82,7 +82,7 @@ impl Runnable for ASTLowererRunner { Ok(()) } - fn eval(&mut self, src: Str) -> Result { + fn eval(&mut self, src: String) -> Result { let ts = Lexer::new(Input::Str(src)) .lex() .map_err(|errs| ParserRunnerErrors::convert(self.input(), errs))?; diff --git a/compiler/erg_parser/lex.rs b/compiler/erg_parser/lex.rs index f3ef15dc..440bb2f9 100644 --- a/compiler/erg_parser/lex.rs +++ b/compiler/erg_parser/lex.rs @@ -5,7 +5,6 @@ use erg_common::cache::CacheSet; use erg_common::config::ErgConfig; use erg_common::config::Input; use erg_common::traits::{Locational, Runnable, Stream}; -use erg_common::Str; use erg_common::{debug_power_assert, fn_name_full, normalize_newline, switch_lang}; use crate::error::{LexError, LexErrors, LexResult, LexerRunnerError, LexerRunnerErrors}; @@ -47,7 +46,7 @@ impl Runnable for LexerRunner { Ok(()) } - fn eval(&mut self, src: Str) -> Result { + fn eval(&mut self, src: String) -> Result { let lexer = Lexer::from_str(src); if cfg!(feature = "debug") { let ts = lexer @@ -97,7 +96,7 @@ impl Lexer /*<'a>*/ { } #[allow(clippy::should_implement_trait)] - pub fn from_str(src: Str) -> Self { + pub fn from_str(src: String) -> Self { let escaped = normalize_newline(&src); Lexer { str_cache: CacheSet::new(), diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index 96307fa3..7adcb024 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -194,7 +194,7 @@ impl Runnable for ParserRunner { Ok(()) } - fn eval(&mut self, src: Str) -> Result { + fn eval(&mut self, src: String) -> Result { let ast = self.parse_with_input(src)?; Ok(format!("{ast}")) } @@ -224,7 +224,7 @@ impl ParserRunner { self_.parse() } - fn parse_with_input(&mut self, src: Str) -> Result { + fn parse_with_input(&mut self, src: String) -> Result { let ts = Lexer::new(Input::Str(src)) .lex() .map_err(|errs| ParserRunnerErrors::convert(self.input(), errs))?; diff --git a/src/dummy.rs b/src/dummy.rs index d796ac68..0f4de3af 100644 --- a/src/dummy.rs +++ b/src/dummy.rs @@ -6,7 +6,6 @@ use std::time::Duration; use erg_common::config::{ErgConfig, Input}; use erg_common::python_util::{exec_py, exec_pyc}; -use erg_common::str::Str; use erg_common::traits::Runnable; use erg_compiler::error::{CompileError, CompileErrors}; @@ -100,7 +99,7 @@ impl Runnable for DummyVM { Ok(()) } - fn eval(&mut self, src: Str) -> Result { + fn eval(&mut self, src: String) -> Result { self.compiler .compile_and_dump_as_pyc(src, "o.pyc", "eval")?; let mut res = match self.stream.as_mut().unwrap().write("load".as_bytes()) {