Skip to content

Commit

Permalink
Merge pull request #371 from erg-lang/fix-370
Browse files Browse the repository at this point in the history
Fix #370
  • Loading branch information
mtshiba authored Jan 28, 2023
2 parents 44781cb + e246fad commit 493492d
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 72 deletions.
121 changes: 74 additions & 47 deletions crates/erg_common/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::str::FromStr;
use crate::help_messages::{command_message, mode_message};
use crate::normalize_path;
use crate::python_util::{detect_magic_number, get_python_version, PythonVersion};
use crate::random::random;
use crate::serialize::{get_magic_num_from_bytes, get_ver_from_magic_num};
use crate::stdin::GLOBAL_STDIN;
use crate::{power_assert, read_file};
Expand Down Expand Up @@ -111,18 +112,30 @@ impl DummyStdin {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Input {
File(PathBuf),
REPL,
REPL(u64),
DummyREPL(DummyStdin),
/// same content as cfg.command
Pipe(String),
Pipe(u64, String),
/// from command option | eval
Str(String),
Str(u64, String),
Dummy,
}

impl Input {
pub fn is_repl(&self) -> bool {
matches!(self, Input::REPL | Input::DummyREPL(_))
pub const fn is_repl(&self) -> bool {
matches!(self, Input::REPL(_) | Input::DummyREPL(_))
}

pub fn pipe(src: String) -> Self {
Self::Pipe(random(), src)
}

pub fn str(src: String) -> Self {
Self::Str(random(), src)
}

pub fn repl() -> Self {
Self::REPL(random())
}

pub fn path(&self) -> Option<&Path> {
Expand All @@ -132,40 +145,57 @@ impl Input {
}
}

pub const fn id(&self) -> u64 {
match self {
Input::File(_) | Input::DummyREPL(_) | Input::Dummy => 0,
Input::REPL(id) | Input::Pipe(id, _) | Input::Str(id, _) => *id,
}
}

pub fn enclosed_name(&self) -> &str {
match self {
Self::File(filename) => filename.to_str().unwrap_or("_"),
Self::REPL | Self::DummyREPL(_) | Self::Pipe(_) => "<stdin>",
Self::Str(_) => "<string>",
Self::REPL(_) | Self::DummyREPL(_) | Self::Pipe(_, _) => "<stdin>",
Self::Str(_, _) => "<string>",
Self::Dummy => "<dummy>",
}
}

pub fn full_path(&self) -> &str {
pub fn full_path(&self) -> PathBuf {
match self {
Self::File(filename) => filename.to_str().unwrap_or("_"),
Self::REPL | Self::DummyREPL(_) | Self::Pipe(_) => "stdin",
Self::Str(_) => "string",
Self::Dummy => "dummy",
Self::File(filename) => filename.clone(),
Self::REPL(id) | Self::Pipe(id, _) => PathBuf::from(format!("stdin_{id}")),
Self::DummyREPL(dummy) => PathBuf::from(format!("stdin_{}", dummy.name)),
Self::Str(id, _) => PathBuf::from(format!("string_{id}")),
Self::Dummy => PathBuf::from("dummy"),
}
}

pub fn file_stem(&self) -> &str {
pub fn file_stem(&self) -> String {
match self {
Self::File(filename) => filename.file_stem().and_then(|f| f.to_str()).unwrap_or("_"),
Self::REPL | Self::DummyREPL(_) | Self::Pipe(_) => "stdin",
Self::Str(_) => "string",
Self::Dummy => "dummy",
Self::File(filename) => filename
.file_stem()
.and_then(|f| f.to_str())
.unwrap_or("_")
.to_string(),
Self::REPL(id) | Self::Pipe(id, _) => format!("stdin_{id}"),
Self::DummyREPL(stdin) => format!("stdin_{}", stdin.name),
Self::Str(id, _) => format!("string_{id}"),
Self::Dummy => "dummy".to_string(),
}
}

pub fn filename(&self) -> &str {
pub fn filename(&self) -> String {
match self {
Self::File(filename) => filename.file_name().and_then(|f| f.to_str()).unwrap_or("_"),
Self::REPL | Self::Pipe(_) => "stdin",
Self::DummyREPL(stdin) => &stdin.name,
Self::Str(_) => "string",
Self::Dummy => "dummy",
Self::File(filename) => filename
.file_name()
.and_then(|f| f.to_str())
.unwrap_or("_")
.to_string(),
Self::REPL(id) | Self::Pipe(id, _) => format!("stdin_{id}"),
Self::DummyREPL(stdin) => format!("stdin_{}", stdin.name),
Self::Str(id, _) => format!("string_{id}"),
Self::Dummy => "dummy".to_string(),
}
}

Expand Down Expand Up @@ -193,8 +223,8 @@ impl Input {
}
}
}
Self::Pipe(s) | Self::Str(s) => s.clone(),
Self::REPL => GLOBAL_STDIN.read(),
Self::Pipe(_, s) | Self::Str(_, s) => s.clone(),
Self::REPL(_) => GLOBAL_STDIN.read(),
Self::DummyREPL(dummy) => dummy.read_line().unwrap_or_default(),
Self::Dummy => panic!("cannot read from a dummy file"),
}
Expand Down Expand Up @@ -224,8 +254,8 @@ impl Input {
}
}
}
Self::Pipe(s) | Self::Str(s) => s.clone(),
Self::REPL => GLOBAL_STDIN.read(),
Self::Pipe(_, s) | Self::Str(_, s) => s.clone(),
Self::REPL(_) => GLOBAL_STDIN.read(),
Self::Dummy | Self::DummyREPL(_) => panic!("cannot read from a dummy file"),
}
}
Expand All @@ -244,12 +274,12 @@ impl Input {
}
Err(_) => vec!["<file not found>".into()],
},
Self::Pipe(s) | Self::Str(s) => s.split('\n').collect::<Vec<_>>()
Self::Pipe(_, s) | Self::Str(_, s) => s.split('\n').collect::<Vec<_>>()
[ln_begin - 1..=ln_end - 1]
.iter()
.map(|s| s.to_string())
.collect(),
Self::REPL => GLOBAL_STDIN.reread_lines(ln_begin, ln_end),
Self::REPL(_) => GLOBAL_STDIN.reread_lines(ln_begin, ln_end),
Self::DummyREPL(dummy) => dummy.reread_lines(ln_begin, ln_end),
Self::Dummy => panic!("cannot read lines from a dummy file"),
}
Expand All @@ -258,8 +288,8 @@ impl Input {
pub fn reread(&self) -> String {
match self {
Self::File(_filename) => todo!(),
Self::Pipe(s) | Self::Str(s) => s.clone(),
Self::REPL => GLOBAL_STDIN.reread().trim_end().to_owned(),
Self::Pipe(_, s) | Self::Str(_, s) => s.clone(),
Self::REPL(_) => GLOBAL_STDIN.reread().trim_end().to_owned(),
Self::DummyREPL(dummy) => dummy.reread().unwrap_or_default(),
Self::Dummy => panic!("cannot read from a dummy file"),
}
Expand Down Expand Up @@ -366,7 +396,7 @@ impl Default for ErgConfig {
py_server_timeout: 10,
quiet_repl: false,
show_type: false,
input: Input::REPL,
input: Input::repl(),
output_dir: None,
module: "<module>",
verbose: 1,
Expand All @@ -393,29 +423,26 @@ impl ErgConfig {
self.clone()
}

pub fn dump_path(&self) -> String {
pub fn dump_path(&self) -> PathBuf {
if let Some(output) = &self.output_dir {
format!("{output}/{}", self.input.filename())
PathBuf::from(format!("{output}/{}", self.input.filename()))
} else {
self.input.full_path().to_string()
self.input.full_path()
}
}

pub fn dump_filename(&self) -> String {
if let Some(output) = &self.output_dir {
format!("{output}/{}", self.input.filename())
} else {
self.input.filename().to_string()
self.input.filename()
}
}

pub fn dump_pyc_path(&self) -> String {
let dump_path = self.dump_path();
if dump_path.ends_with(".er") {
dump_path.replace(".er", ".pyc")
} else {
dump_path + ".pyc"
}
pub fn dump_pyc_path(&self) -> PathBuf {
let mut dump_path = self.dump_path();
dump_path.set_extension(".pyc");
dump_path
}

pub fn dump_pyc_filename(&self) -> String {
Expand Down Expand Up @@ -450,7 +477,7 @@ impl ErgConfig {
break;
}
"-c" | "--code" => {
cfg.input = Input::Str(args.next().expect("the value of `-c` is not passed"));
cfg.input = Input::str(args.next().expect("the value of `-c` is not passed"));
}
"--check" => {
cfg.mode = ErgMode::FullCheck;
Expand Down Expand Up @@ -630,15 +657,15 @@ USAGE:
}
}
}
if cfg.input == Input::REPL && cfg.mode != ErgMode::LanguageServer {
if cfg.input.is_repl() && cfg.mode != ErgMode::LanguageServer {
use crate::tty::IsTty;
let is_stdin_piped = !stdin().is_tty();
let input = if is_stdin_piped {
let mut buffer = String::new();
stdin().read_to_string(&mut buffer).unwrap();
Input::Pipe(buffer)
Input::pipe(buffer)
} else {
Input::REPL
Input::repl()
};
cfg.input = input;
}
Expand Down
1 change: 1 addition & 0 deletions crates/erg_common/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub mod opcode308;
pub mod opcode310;
pub mod opcode311;
pub mod python_util;
pub mod random;
pub mod serialize;
pub mod set;
pub mod shared;
Expand Down
7 changes: 7 additions & 0 deletions crates/erg_common/random.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hasher};

pub fn random() -> u64 {
let state = RandomState::new();
state.build_hasher().finish()
}
4 changes: 2 additions & 2 deletions crates/erg_common/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,8 +577,8 @@ pub trait Runnable: Sized + Default {
let mut num_errors = 0;
let mut instance = Self::new(cfg);
let res = match instance.input() {
Input::File(_) | Input::Pipe(_) | Input::Str(_) => instance.exec(),
Input::REPL | Input::DummyREPL(_) => {
Input::File(_) | Input::Pipe(_, _) | Input::Str(_, _) => instance.exec(),
Input::REPL(_) | Input::DummyREPL(_) => {
let output = stdout();
let mut output = BufWriter::new(output.lock());
if !quiet_repl {
Expand Down
2 changes: 1 addition & 1 deletion crates/erg_compiler/build_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl Runnable for HIRBuilder {

impl Buildable for HIRBuilder {
fn inherit(cfg: ErgConfig, shared: SharedCompilerResource) -> Self {
let mod_name = Str::rc(cfg.input.file_stem());
let mod_name = Str::rc(&cfg.input.file_stem());
Self::new_with_cache(cfg, mod_name, shared)
}
fn build(&mut self, src: String, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
Expand Down
Loading

0 comments on commit 493492d

Please sign in to comment.