diff --git a/compiler/erg_common/env.rs b/compiler/erg_common/env.rs new file mode 100644 index 00000000..d1decce5 --- /dev/null +++ b/compiler/erg_common/env.rs @@ -0,0 +1,15 @@ +use std::path::PathBuf; + +pub fn erg_path() -> Option { + option_env!("ERG_PATH") + .or_else(|| option_env!("CARGO_ERG_PATH")) + .map(PathBuf::from) +} + +pub fn erg_std_path() -> Option { + erg_path().map(|path| path.join("lib").join("std")) +} + +pub fn erg_external_lib_path() -> Option { + erg_path().map(|path| path.join("lib").join("external")) +} diff --git a/compiler/erg_common/lib.rs b/compiler/erg_common/lib.rs index 8c27b7af..e2571147 100644 --- a/compiler/erg_common/lib.rs +++ b/compiler/erg_common/lib.rs @@ -7,6 +7,7 @@ pub mod color; pub mod config; pub mod datetime; pub mod dict; +pub mod env; pub mod error; pub mod fxhash; pub mod help_messages; diff --git a/compiler/erg_compiler/build.rs b/compiler/erg_compiler/build.rs index 89460ee7..e5af207e 100644 --- a/compiler/erg_compiler/build.rs +++ b/compiler/erg_compiler/build.rs @@ -14,20 +14,36 @@ fn main() -> std::io::Result<()> { + "/.erg"; if !path::Path::new(&erg_path).exists() { fs::create_dir(&erg_path)?; - fs::create_dir(format!("{erg_path}/std"))?; } println!("cargo:rustc-env=CARGO_ERG_PATH={erg_path}"); - // println!("cargo:rustc-env=CARGO_ERG_STD_PATH={erg_path}/std"); // create a std library in ".erg" - for res in fs::read_dir("std")? { + copy_dir(&erg_path, "lib")?; + Ok(()) +} + +fn copy_dir(erg_path: &str, path: &str) -> std::io::Result<()> { + let full_path = format!("{erg_path}/{path}"); + if !path::Path::new(&full_path).exists() { + fs::create_dir(&full_path)?; + } + let mut dirs = vec![]; + for res in fs::read_dir(path)? { let entry = res?; - let path = entry.path(); - let filename = path - .file_name() - .expect("this is not a file") - .to_str() - .unwrap(); - fs::copy(&path, format!("{erg_path}/std/{filename}"))?; + let entry_path = entry.path(); + if entry_path.is_dir() { + dirs.push(entry); + } else { + let filename = entry_path + .file_name() + .expect("this is not a file") + .to_str() + .unwrap(); + let filename = format!("{full_path}/{filename}"); + fs::copy(&entry_path, filename)?; + } + } + for dir in dirs { + copy_dir(erg_path, dir.path().to_str().unwrap())?; } Ok(()) } diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index c3485ddc..edaf5f59 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -8,6 +8,7 @@ use crate::ty::codeobj::{CodeObj, CodeObjFlags}; use erg_common::astr::AtomicStr; use erg_common::cache::CacheSet; use erg_common::config::{ErgConfig, Input}; +use erg_common::env::erg_std_path; use erg_common::error::{ErrorDisplay, Location}; use erg_common::opcode::Opcode; use erg_common::traits::{Locational, Stream}; @@ -2052,8 +2053,7 @@ impl CodeGenerator { } fn load_prelude_py(&mut self) { - if let Some(erg_path) = option_env!("ERG_PATH").or_else(|| option_env!("CARGO_ERG_PATH")) { - let std_path = std::path::Path::new(erg_path).join("std"); + if let Some(std_path) = erg_std_path() { self.emit_global_import_items( Identifier::public("sys"), vec![( diff --git a/compiler/erg_compiler/std/_erg_std_prelude.py b/compiler/erg_compiler/lib/std/_erg_std_prelude.py similarity index 100% rename from compiler/erg_compiler/std/_erg_std_prelude.py rename to compiler/erg_compiler/lib/std/_erg_std_prelude.py diff --git a/compiler/erg_compiler/std/_prelude.er b/compiler/erg_compiler/lib/std/_prelude.er similarity index 100% rename from compiler/erg_compiler/std/_prelude.er rename to compiler/erg_compiler/lib/std/_prelude.er diff --git a/compiler/erg_compiler/std/prelude.er b/compiler/erg_compiler/lib/std/prelude.er similarity index 100% rename from compiler/erg_compiler/std/prelude.er rename to compiler/erg_compiler/lib/std/prelude.er